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