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