• 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/GrResourceKey.h"
14 #include "include/private/SkMutex.h"
15 #include "src/gpu/GrTexture.h"
16 
17 class GrSemaphore;
18 
19 /*
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
24  * semaphore).
25  *
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.
30  */
31 class GrBackendTextureImageGenerator : public SkImageGenerator {
32 public:
33     static std::unique_ptr<SkImageGenerator> Make(sk_sp<GrTexture>, GrSurfaceOrigin,
34                                                   std::unique_ptr<GrSemaphore>, SkColorType,
35                                                   SkAlphaType, sk_sp<SkColorSpace>);
36 
37     ~GrBackendTextureImageGenerator() override;
38 
39 protected:
onIsValid(GrRecordingContext * context)40     bool onIsValid(GrRecordingContext* context) const override {
41         if (context && context->abandoned()) {
42             return false;
43         }
44         return true;
45     }
46 
47     GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&, const SkIPoint&,
48                                          GrMipmapped mipMapped, GrImageTexGenPolicy) override;
49 
50 private:
51     GrBackendTextureImageGenerator(const SkImageInfo& info,
52                                    GrTexture*,
53                                    GrSurfaceOrigin,
54                                    GrDirectContext::DirectContextID owningContextID,
55                                    std::unique_ptr<GrSemaphore>,
56                                    const GrBackendTexture&);
57 
58     static void ReleaseRefHelper_TextureReleaseProc(void* ctx);
59 
60     class RefHelper : public SkNVRefCnt<RefHelper> {
61     public:
62         RefHelper(GrTexture*,
63                   GrDirectContext::DirectContextID owningContextID,
64                   std::unique_ptr<GrSemaphore>);
65 
66         ~RefHelper();
67 
68         GrTexture*                       fOriginalTexture;
69         GrDirectContext::DirectContextID fOwningContextID;
70 
71         // We use this key so that we don't rewrap the GrBackendTexture in a GrTexture for each
72         // proxy created from this generator for a particular borrowing context.
73         GrUniqueKey                      fBorrowedTextureKey;
74         // There is no ref associated with this pointer. We rely on our atomic bookkeeping with the
75         // context ID to know when this pointer is valid and safe to use. This is used to make sure
76         // all uses of the wrapped texture are finished on the borrowing context before we open
77         // this back up to other contexts. In general a ref to this release proc is owned by all
78         // proxies and gpu uses of the backend texture.
79         GrRefCntedCallback*              fBorrowingContextReleaseProc;
80         GrDirectContext::DirectContextID fBorrowingContextID;
81 
82         std::unique_ptr<GrSemaphore>     fSemaphore;
83     };
84 
85     RefHelper*       fRefHelper;
86     // This Mutex is used to guard the borrowing of the texture to one GrContext at a time as well
87     // as the creation of the fBorrowingContextReleaseProc. The latter happening if two threads with
88     // the same consuming GrContext try to generate a texture at the same time.
89     SkMutex          fBorrowingMutex;
90 
91     GrBackendTexture fBackendTexture;
92     GrSurfaceOrigin  fSurfaceOrigin;
93 
94     using INHERITED = SkImageGenerator;
95 };
96 #endif  // GrBackendTextureImageGenerator_DEFINED
97