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 protected: setGLRTFBOIDIs0()93 void setGLRTFBOIDIs0() { 94 SkASSERT(!this->requiresManualMSAAResolve()); 95 SkASSERT(!this->asTexture()); 96 SkASSERT(this->asRenderTarget()); 97 fSurfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0; 98 } glRTFBOIDis0()99 bool glRTFBOIDis0() const { 100 return fSurfaceFlags & GrInternalSurfaceFlags::kGLRTFBOIDIs0; 101 } 102 setRequiresManualMSAAResolve()103 void setRequiresManualMSAAResolve() { 104 SkASSERT(!this->glRTFBOIDis0()); 105 SkASSERT(this->asRenderTarget()); 106 fSurfaceFlags |= GrInternalSurfaceFlags::kRequiresManualMSAAResolve; 107 } requiresManualMSAAResolve()108 bool requiresManualMSAAResolve() const { 109 return fSurfaceFlags & GrInternalSurfaceFlags::kRequiresManualMSAAResolve; 110 } 111 setReadOnly()112 void setReadOnly() { 113 SkASSERT(!this->asRenderTarget()); 114 fSurfaceFlags |= GrInternalSurfaceFlags::kReadOnly; 115 } 116 setVkRTSupportsInputAttachment()117 void setVkRTSupportsInputAttachment() { 118 SkASSERT(this->asRenderTarget()); 119 fSurfaceFlags |= GrInternalSurfaceFlags::kVkRTSupportsInputAttachment; 120 } 121 GrSurface(GrGpu * gpu,const SkISize & dimensions,GrProtected isProtected)122 GrSurface(GrGpu* gpu, const SkISize& dimensions, GrProtected isProtected) 123 : INHERITED(gpu) 124 , fDimensions(dimensions) 125 , fSurfaceFlags(GrInternalSurfaceFlags::kNone) 126 , fIsProtected(isProtected) {} 127 ~GrSurface()128 ~GrSurface() override { 129 // check that invokeReleaseProc has been called (if needed) 130 SkASSERT(!fReleaseHelper); 131 } 132 133 void onRelease() override; 134 void onAbandon() override; 135 136 private: getResourceType()137 const char* getResourceType() const override { return "Surface"; } 138 139 // Unmanaged backends (e.g. Vulkan) may want to specially handle the release proc in order to 140 // ensure it isn't called until GPU work related to the resource is completed. onSetRelease(sk_sp<GrRefCntedCallback>)141 virtual void onSetRelease(sk_sp<GrRefCntedCallback>) {} 142 invokeReleaseProc()143 void invokeReleaseProc() { 144 // Depending on the ref count of fReleaseHelper this may or may not actually trigger the 145 // ReleaseProc to be called. 146 fReleaseHelper.reset(); 147 } 148 149 SkISize fDimensions; 150 GrInternalSurfaceFlags fSurfaceFlags; 151 GrProtected fIsProtected; 152 sk_sp<GrRefCntedCallback> fReleaseHelper; 153 154 using INHERITED = GrGpuResource; 155 }; 156 157 #endif 158