• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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