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