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