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