2 * Copyright 2017 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
7 #ifndef GrBackendTextureImageGenerator_DEFINED
8 #define GrBackendTextureImageGenerator_DEFINED
10 #include "include/core/SkImageGenerator.h"
11 #include "include/gpu/GrBackendSurface.h"
12 #include "include/gpu/GrDirectContext.h"
13 #include "include/private/SkMutex.h"
14 #include "src/gpu/ResourceKey.h"
15 #include "src/gpu/ganesh/GrTexture.h"
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
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.
31 class GrBackendTextureImageGenerator : public SkImageGenerator {
33 static std::unique_ptr<SkImageGenerator> Make(sk_sp<GrTexture>, GrSurfaceOrigin,
34 std::unique_ptr<GrSemaphore>, SkColorType,
35 SkAlphaType, sk_sp<SkColorSpace>);
37 ~GrBackendTextureImageGenerator() override;
40 bool onIsValid(GrRecordingContext* context) const override {
41 if (context && context->abandoned()) {
47 GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&, const SkIPoint&,
48 GrMipmapped mipmapped, GrImageTexGenPolicy) override;
51 GrBackendTextureImageGenerator(const SkColorInfo&,
54 GrDirectContext::DirectContextID owningContextID,
55 std::unique_ptr<GrSemaphore>);
57 static void ReleaseRefHelper_TextureReleaseProc(void* ctx);
59 class RefHelper : public SkNVRefCnt<RefHelper> {
61 RefHelper(sk_sp<GrTexture>,
62 GrDirectContext::DirectContextID owningContextID,
63 std::unique_ptr<GrSemaphore>);
67 sk_sp<GrTexture> fOriginalTexture;
68 GrDirectContext::DirectContextID fOwningContextID;
70 // We use this key so that we don't rewrap the GrBackendTexture in a GrTexture for each
71 // proxy created from this generator for a particular borrowing context.
72 skgpu::UniqueKey fBorrowedTextureKey;
73 // There is no ref associated with this pointer. We rely on our atomic bookkeeping with the
74 // context ID to know when this pointer is valid and safe to use. This is used to make sure
75 // all uses of the wrapped texture are finished on the borrowing context before we open
76 // this back up to other contexts. In general a ref to this release proc is owned by all
77 // proxies and gpu uses of the backend texture.
78 skgpu::RefCntedCallback* fBorrowingContextReleaseProc;
79 GrDirectContext::DirectContextID fBorrowingContextID;
81 std::unique_ptr<GrSemaphore> fSemaphore;
84 RefHelper* fRefHelper;
85 // This Mutex is used to guard the borrowing of the texture to one GrContext at a time as well
86 // as the creation of the fBorrowingContextReleaseProc. The latter happening if two threads with
87 // the same consuming GrContext try to generate a texture at the same time.
88 SkMutex fBorrowingMutex;
90 GrBackendTexture fBackendTexture;
91 GrSurfaceOrigin fSurfaceOrigin;
93 using INHERITED = SkImageGenerator;
95 #endif // GrBackendTextureImageGenerator_DEFINED