• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 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 
8 #ifndef GrSurface_DEFINED
9 #define GrSurface_DEFINED
10 
11 #include "include/core/SkImageInfo.h"
12 #include "include/core/SkRect.h"
13 #include "include/gpu/GrTypes.h"
14 #include "src/gpu/RefCntedCallback.h"
15 #include "src/gpu/ganesh/GrGpuResource.h"
16 
17 class GrRenderTarget;
18 class GrTexture;
19 class GrBackendFormat;
20 
21 class GrSurface : public GrGpuResource {
22 public:
23     /**
24      * Retrieves the dimensions of the surface.
25      */
dimensions()26     SkISize dimensions() const { return fDimensions; }
27 
28     /**
29      * Retrieves the width of the surface.
30      */
width()31     int width() const { return fDimensions.width(); }
32 
33     /**
34      * Retrieves the height of the surface.
35      */
height()36     int height() const { return fDimensions.height(); }
37 
38     /**
39      * Helper that gets the width and height of the surface as a bounding rectangle.
40      */
getBoundsRect()41     SkRect getBoundsRect() const { return SkRect::Make(this->dimensions()); }
42 
43     virtual GrBackendFormat backendFormat() const = 0;
44 
45     void setRelease(sk_sp<skgpu::RefCntedCallback> releaseHelper);
46 
47     // These match the definitions in SkImage, from whence they came.
48     // TODO: Remove Chrome's need to call this on a GrTexture
49     typedef void* ReleaseCtx;
50     typedef void (*ReleaseProc)(ReleaseCtx);
setRelease(ReleaseProc proc,ReleaseCtx ctx)51     void setRelease(ReleaseProc proc, ReleaseCtx ctx) {
52         this->setRelease(skgpu::RefCntedCallback::Make(proc, ctx));
53     }
54 
55     /**
56      * @return the texture associated with the surface, may be null.
57      */
asTexture()58     virtual GrTexture* asTexture() { return nullptr; }
asTexture()59     virtual const GrTexture* asTexture() const { return nullptr; }
60 
61     /**
62      * @return the render target underlying this surface, may be null.
63      */
asRenderTarget()64     virtual GrRenderTarget* asRenderTarget() { return nullptr; }
asRenderTarget()65     virtual const GrRenderTarget* asRenderTarget() const { return nullptr; }
66 
flags()67     GrInternalSurfaceFlags flags() const { return fSurfaceFlags; }
68 
69     static size_t ComputeSize(const GrBackendFormat&, SkISize dimensions, int colorSamplesPerPixel,
70                               GrMipmapped, bool binSize = false);
71 
72     /**
73      * The pixel values of this surface cannot be modified (e.g. doesn't support write pixels or
74      * MIP map level regen).
75      */
readOnly()76     bool readOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kReadOnly; }
77 
framebufferOnly()78     bool framebufferOnly() const {
79         return fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly;
80     }
81 
82     // Returns true if we are working with protected content.
isProtected()83     bool isProtected() const { return fIsProtected == GrProtected::kYes; }
84 
setFramebufferOnly()85     void setFramebufferOnly() {
86         SkASSERT(this->asRenderTarget());
87         fSurfaceFlags |= GrInternalSurfaceFlags::kFramebufferOnly;
88     }
89 
90     class RefCntedReleaseProc : public SkNVRefCnt<RefCntedReleaseProc> {
91     public:
92         RefCntedReleaseProc(sk_sp<skgpu::RefCntedCallback> callback,
93                             sk_sp<GrDirectContext> directContext);
94 
95         ~RefCntedReleaseProc();
96 
97     private:
98         sk_sp<skgpu::RefCntedCallback> fCallback;
99         sk_sp<GrDirectContext> fDirectContext;
100     };
101 
102 protected:
setGLRTFBOIDIs0()103     void setGLRTFBOIDIs0() {
104         SkASSERT(!this->requiresManualMSAAResolve());
105         SkASSERT(!this->asTexture());
106         SkASSERT(this->asRenderTarget());
107         fSurfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0;
108     }
glRTFBOIDis0()109     bool glRTFBOIDis0() const {
110         return fSurfaceFlags & GrInternalSurfaceFlags::kGLRTFBOIDIs0;
111     }
112 
setRequiresManualMSAAResolve()113     void setRequiresManualMSAAResolve() {
114         SkASSERT(!this->glRTFBOIDis0());
115         SkASSERT(this->asRenderTarget());
116         fSurfaceFlags |= GrInternalSurfaceFlags::kRequiresManualMSAAResolve;
117     }
requiresManualMSAAResolve()118     bool requiresManualMSAAResolve() const {
119         return fSurfaceFlags & GrInternalSurfaceFlags::kRequiresManualMSAAResolve;
120     }
121 
setReadOnly()122     void setReadOnly() {
123         SkASSERT(!this->asRenderTarget());
124         fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly;
125     }
126 
setVkRTSupportsInputAttachment()127     void setVkRTSupportsInputAttachment() {
128         SkASSERT(this->asRenderTarget());
129         fSurfaceFlags |= GrInternalSurfaceFlags::kVkRTSupportsInputAttachment;
130     }
131 
GrSurface(GrGpu * gpu,const SkISize & dimensions,GrProtected isProtected,std::string_view label)132     GrSurface(GrGpu* gpu,
133               const SkISize& dimensions,
134               GrProtected isProtected,
135               std::string_view label)
136             : INHERITED(gpu, label)
137             , fDimensions(dimensions)
138             , fSurfaceFlags(GrInternalSurfaceFlags::kNone)
139             , fIsProtected(isProtected) {}
140 
~GrSurface()141     ~GrSurface() override {
142         // check that invokeReleaseProc has been called (if needed)
143         SkASSERT(!fReleaseHelper);
144     }
145 
146     void onRelease() override;
147     void onAbandon() override;
148 
149 private:
getResourceType()150     const char* getResourceType() const override { return "Surface"; }
151 
152     // Unmanaged backends (e.g. Vulkan) may want to specially handle the release proc in order to
153     // ensure it isn't called until GPU work related to the resource is completed.
onSetRelease(sk_sp<RefCntedReleaseProc>)154     virtual void onSetRelease(sk_sp<RefCntedReleaseProc>) {}
155 
invokeReleaseProc()156     void invokeReleaseProc() {
157         // Depending on the ref count of fReleaseHelper this may or may not actually trigger the
158         // ReleaseProc to be called.
159         fReleaseHelper.reset();
160     }
161 
162     SkISize                    fDimensions;
163     GrInternalSurfaceFlags     fSurfaceFlags;
164     GrProtected                fIsProtected;
165     sk_sp<RefCntedReleaseProc> fReleaseHelper;
166 
167     using INHERITED = GrGpuResource;
168 };
169 
170 #endif
171