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