1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2017 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci#ifndef GrBackendTextureImageGenerator_DEFINED 8cb93a386Sopenharmony_ci#define GrBackendTextureImageGenerator_DEFINED 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/core/SkImageGenerator.h" 11cb93a386Sopenharmony_ci#include "include/gpu/GrBackendSurface.h" 12cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 13cb93a386Sopenharmony_ci#include "include/private/GrResourceKey.h" 14cb93a386Sopenharmony_ci#include "include/private/SkMutex.h" 15cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h" 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ciclass GrSemaphore; 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci/* 20cb93a386Sopenharmony_ci * This ImageGenerator is used to wrap a texture in one GrContext and can then be used as a source 21cb93a386Sopenharmony_ci * in another GrContext. It holds onto a semaphore which the producing GrContext will signal and the 22cb93a386Sopenharmony_ci * consuming GrContext will wait on before using the texture. Only one GrContext can ever be used 23cb93a386Sopenharmony_ci * as a consumer (this is mostly because Vulkan can't allow multiple things to wait on the same 24cb93a386Sopenharmony_ci * semaphore). 25cb93a386Sopenharmony_ci * 26cb93a386Sopenharmony_ci * In practice, this capability is used by clients to create backend-specific texture resources in 27cb93a386Sopenharmony_ci * one thread (with, say, GrContext-A) and then ship them over to another GrContext (say, 28cb93a386Sopenharmony_ci * GrContext-B) which will then use the texture as a source for draws. GrContext-A uses the 29cb93a386Sopenharmony_ci * semaphore to notify GrContext-B when the shared texture is ready to use. 30cb93a386Sopenharmony_ci */ 31cb93a386Sopenharmony_ciclass GrBackendTextureImageGenerator : public SkImageGenerator { 32cb93a386Sopenharmony_cipublic: 33cb93a386Sopenharmony_ci static std::unique_ptr<SkImageGenerator> Make(sk_sp<GrTexture>, GrSurfaceOrigin, 34cb93a386Sopenharmony_ci std::unique_ptr<GrSemaphore>, SkColorType, 35cb93a386Sopenharmony_ci SkAlphaType, sk_sp<SkColorSpace>); 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci ~GrBackendTextureImageGenerator() override; 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ciprotected: 40cb93a386Sopenharmony_ci bool onIsValid(GrRecordingContext* context) const override { 41cb93a386Sopenharmony_ci if (context && context->abandoned()) { 42cb93a386Sopenharmony_ci return false; 43cb93a386Sopenharmony_ci } 44cb93a386Sopenharmony_ci return true; 45cb93a386Sopenharmony_ci } 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&, const SkIPoint&, 48cb93a386Sopenharmony_ci GrMipmapped mipMapped, GrImageTexGenPolicy) override; 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ciprivate: 51cb93a386Sopenharmony_ci GrBackendTextureImageGenerator(const SkImageInfo& info, 52cb93a386Sopenharmony_ci GrTexture*, 53cb93a386Sopenharmony_ci GrSurfaceOrigin, 54cb93a386Sopenharmony_ci GrDirectContext::DirectContextID owningContextID, 55cb93a386Sopenharmony_ci std::unique_ptr<GrSemaphore>, 56cb93a386Sopenharmony_ci const GrBackendTexture&); 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci static void ReleaseRefHelper_TextureReleaseProc(void* ctx); 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci class RefHelper : public SkNVRefCnt<RefHelper> { 61cb93a386Sopenharmony_ci public: 62cb93a386Sopenharmony_ci RefHelper(GrTexture*, 63cb93a386Sopenharmony_ci GrDirectContext::DirectContextID owningContextID, 64cb93a386Sopenharmony_ci std::unique_ptr<GrSemaphore>); 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci ~RefHelper(); 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci GrTexture* fOriginalTexture; 69cb93a386Sopenharmony_ci GrDirectContext::DirectContextID fOwningContextID; 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci // We use this key so that we don't rewrap the GrBackendTexture in a GrTexture for each 72cb93a386Sopenharmony_ci // proxy created from this generator for a particular borrowing context. 73cb93a386Sopenharmony_ci GrUniqueKey fBorrowedTextureKey; 74cb93a386Sopenharmony_ci // There is no ref associated with this pointer. We rely on our atomic bookkeeping with the 75cb93a386Sopenharmony_ci // context ID to know when this pointer is valid and safe to use. This is used to make sure 76cb93a386Sopenharmony_ci // all uses of the wrapped texture are finished on the borrowing context before we open 77cb93a386Sopenharmony_ci // this back up to other contexts. In general a ref to this release proc is owned by all 78cb93a386Sopenharmony_ci // proxies and gpu uses of the backend texture. 79cb93a386Sopenharmony_ci GrRefCntedCallback* fBorrowingContextReleaseProc; 80cb93a386Sopenharmony_ci GrDirectContext::DirectContextID fBorrowingContextID; 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci std::unique_ptr<GrSemaphore> fSemaphore; 83cb93a386Sopenharmony_ci }; 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci RefHelper* fRefHelper; 86cb93a386Sopenharmony_ci // This Mutex is used to guard the borrowing of the texture to one GrContext at a time as well 87cb93a386Sopenharmony_ci // as the creation of the fBorrowingContextReleaseProc. The latter happening if two threads with 88cb93a386Sopenharmony_ci // the same consuming GrContext try to generate a texture at the same time. 89cb93a386Sopenharmony_ci SkMutex fBorrowingMutex; 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_ci GrBackendTexture fBackendTexture; 92cb93a386Sopenharmony_ci GrSurfaceOrigin fSurfaceOrigin; 93cb93a386Sopenharmony_ci 94cb93a386Sopenharmony_ci using INHERITED = SkImageGenerator; 95cb93a386Sopenharmony_ci}; 96cb93a386Sopenharmony_ci#endif // GrBackendTextureImageGenerator_DEFINED 97