xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrBackendTextureImageGenerator.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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