• 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 "SkImageGenerator.h"
11 
12 #include "GrBackendSurface.h"
13 #include "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>,
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 
42 #if SK_SUPPORT_GPU
onCanGenerateTexture()43     TexGenType onCanGenerateTexture() const override { return TexGenType::kCheap; }
44     sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&, const SkIPoint&,
45                                             SkTransferFunctionBehavior,
46                                             bool willNeedMipMaps) override;
47 #endif
48 
49 private:
50     GrBackendTextureImageGenerator(const SkImageInfo& info, GrTexture*, GrSurfaceOrigin,
51                                    uint32_t owningContextID, sk_sp<GrSemaphore>,
52                                    const GrBackendTexture&);
53 
54     static void ReleaseRefHelper_TextureReleaseProc(void* ctx);
55 
56     class RefHelper : public SkNVRefCnt<RefHelper> {
57     public:
RefHelper(GrTexture * texture,uint32_t owningContextID)58         RefHelper(GrTexture* texture, uint32_t owningContextID)
59             : fOriginalTexture(texture)
60             , fOwningContextID(owningContextID)
61             , fBorrowedTexture(nullptr)
62             , fBorrowingContextReleaseProc(nullptr)
63             , fBorrowingContextID(SK_InvalidGenID) {}
64 
65         ~RefHelper();
66 
67         GrTexture*          fOriginalTexture;
68         uint32_t            fOwningContextID;
69 
70         // There is never a ref associated with this pointer. We rely on our atomic bookkeeping
71         // with the context ID to know when this pointer is valid and safe to use. This lets us
72         // avoid releasing a ref from another thread, or get into races during context shutdown.
73         GrTexture*           fBorrowedTexture;
74         // For the same reason as the fBorrowedTexture, there is no ref associated with this
75         // pointer. The fBorrowingContextReleaseProc is used to make sure all uses of the wrapped
76         // texture are finished on the borrowing context before we open this back up to other
77         // contexts. In general a ref to this release proc is owned by all proxies and gpu uses of
78         // the backend texture.
79         GrReleaseProcHelper* fBorrowingContextReleaseProc;
80         uint32_t             fBorrowingContextID;
81     };
82 
83     RefHelper*           fRefHelper;
84     // This Mutex is used to guard the borrowing of the texture to one GrContext at a time as well
85     // as the creation of the fBorrowingContextReleaseProc. The latter happening if two threads with
86     // the same consuming GrContext try to generate a texture at the same time.
87     SkMutex              fBorrowingMutex;
88 
89     sk_sp<GrSemaphore>   fSemaphore;
90 
91     GrBackendTexture     fBackendTexture;
92     GrPixelConfig        fConfig;
93     GrSurfaceOrigin      fSurfaceOrigin;
94 
95     typedef SkImageGenerator INHERITED;
96 };
97 #endif  // GrBackendTextureImageGenerator_DEFINED
98