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