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