| /* | 
 |  * Copyright 2017 Google Inc. | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 | #ifndef GrBackendTextureImageGenerator_DEFINED | 
 | #define GrBackendTextureImageGenerator_DEFINED | 
 |  | 
 | #include "include/core/SkImageGenerator.h" | 
 | #include "include/gpu/GrBackendSurface.h" | 
 | #include "include/gpu/GrDirectContext.h" | 
 | #include "include/private/GrResourceKey.h" | 
 | #include "include/private/SkMutex.h" | 
 | #include "src/gpu/GrTexture.h" | 
 |  | 
 | class GrSemaphore; | 
 |  | 
 | /* | 
 |  * This ImageGenerator is used to wrap a texture in one GrContext and can then be used as a source | 
 |  * in another GrContext. It holds onto a semaphore which the producing GrContext will signal and the | 
 |  * consuming GrContext will wait on before using the texture. Only one GrContext can ever be used | 
 |  * as a consumer (this is mostly because Vulkan can't allow multiple things to wait on the same | 
 |  * semaphore). | 
 |  * | 
 |  * In practice, this capability is used by clients to create backend-specific texture resources in | 
 |  * one thread (with, say, GrContext-A) and then ship them over to another GrContext (say, | 
 |  * GrContext-B) which will then use the texture as a source for draws. GrContext-A uses the | 
 |  * semaphore to notify GrContext-B when the shared texture is ready to use. | 
 |  */ | 
 | class GrBackendTextureImageGenerator : public SkImageGenerator { | 
 | public: | 
 |     static std::unique_ptr<SkImageGenerator> Make(sk_sp<GrTexture>, GrSurfaceOrigin, | 
 |                                                   std::unique_ptr<GrSemaphore>, SkColorType, | 
 |                                                   SkAlphaType, sk_sp<SkColorSpace>); | 
 |  | 
 |     ~GrBackendTextureImageGenerator() override; | 
 |  | 
 | protected: | 
 |     bool onIsValid(GrRecordingContext* context) const override { | 
 |         if (context && context->abandoned()) { | 
 |             return false; | 
 |         } | 
 |         return true; | 
 |     } | 
 |  | 
 |     GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&, const SkIPoint&, | 
 |                                          GrMipmapped mipMapped, GrImageTexGenPolicy) override; | 
 |  | 
 | private: | 
 |     GrBackendTextureImageGenerator(const SkImageInfo& info, | 
 |                                    GrTexture*, | 
 |                                    GrSurfaceOrigin, | 
 |                                    GrDirectContext::DirectContextID owningContextID, | 
 |                                    std::unique_ptr<GrSemaphore>, | 
 |                                    const GrBackendTexture&); | 
 |  | 
 |     static void ReleaseRefHelper_TextureReleaseProc(void* ctx); | 
 |  | 
 |     class RefHelper : public SkNVRefCnt<RefHelper> { | 
 |     public: | 
 |         RefHelper(GrTexture*, | 
 |                   GrDirectContext::DirectContextID owningContextID, | 
 |                   std::unique_ptr<GrSemaphore>); | 
 |  | 
 |         ~RefHelper(); | 
 |  | 
 |         GrTexture*                       fOriginalTexture; | 
 |         GrDirectContext::DirectContextID fOwningContextID; | 
 |  | 
 |         // We use this key so that we don't rewrap the GrBackendTexture in a GrTexture for each | 
 |         // proxy created from this generator for a particular borrowing context. | 
 |         GrUniqueKey                      fBorrowedTextureKey; | 
 |         // There is no ref associated with this pointer. We rely on our atomic bookkeeping with the | 
 |         // context ID to know when this pointer is valid and safe to use. This is used to make sure | 
 |         // all uses of the wrapped texture are finished on the borrowing context before we open | 
 |         // this back up to other contexts. In general a ref to this release proc is owned by all | 
 |         // proxies and gpu uses of the backend texture. | 
 |         GrRefCntedCallback*              fBorrowingContextReleaseProc; | 
 |         GrDirectContext::DirectContextID fBorrowingContextID; | 
 |  | 
 |         std::unique_ptr<GrSemaphore>     fSemaphore; | 
 |     }; | 
 |  | 
 |     RefHelper*       fRefHelper; | 
 |     // This Mutex is used to guard the borrowing of the texture to one GrContext at a time as well | 
 |     // as the creation of the fBorrowingContextReleaseProc. The latter happening if two threads with | 
 |     // the same consuming GrContext try to generate a texture at the same time. | 
 |     SkMutex          fBorrowingMutex; | 
 |  | 
 |     GrBackendTexture fBackendTexture; | 
 |     GrSurfaceOrigin  fSurfaceOrigin; | 
 |  | 
 |     using INHERITED = SkImageGenerator; | 
 | }; | 
 | #endif  // GrBackendTextureImageGenerator_DEFINED |