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/GrGpuResource.h" 15 #include "include/gpu/GrTypes.h" 16 17 class GrRenderTarget; 18 class GrSurfacePriv; 19 class GrTexture; 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 setRelease(sk_sp<GrRefCntedCallback> releaseHelper)45 SK_API void setRelease(sk_sp<GrRefCntedCallback> releaseHelper) { 46 this->onSetRelease(releaseHelper); 47 fReleaseHelper = std::move(releaseHelper); 48 } 49 50 // These match the definitions in SkImage, from whence they came. 51 // TODO: Remove Chrome's need to call this on a GrTexture 52 typedef void* ReleaseCtx; 53 typedef void (*ReleaseProc)(ReleaseCtx); setRelease(ReleaseProc proc,ReleaseCtx ctx)54 SK_API void setRelease(ReleaseProc proc, ReleaseCtx ctx) { 55 sk_sp<GrRefCntedCallback> helper(new GrRefCntedCallback(proc, ctx)); 56 this->setRelease(std::move(helper)); 57 } 58 59 /** 60 * @return the texture associated with the surface, may be null. 61 */ asTexture()62 virtual GrTexture* asTexture() { return nullptr; } asTexture()63 virtual const GrTexture* asTexture() const { return nullptr; } 64 65 /** 66 * @return the render target underlying this surface, may be null. 67 */ asRenderTarget()68 virtual GrRenderTarget* asRenderTarget() { return nullptr; } asRenderTarget()69 virtual const GrRenderTarget* asRenderTarget() const { return nullptr; } 70 71 /** Access methods that are only to be used within Skia code. */ 72 inline GrSurfacePriv surfacePriv(); 73 inline const GrSurfacePriv surfacePriv() const; 74 75 static size_t ComputeSize(const GrCaps&, const GrBackendFormat&, SkISize dimensions, 76 int colorSamplesPerPixel, GrMipMapped, bool binSize = false); 77 78 /** 79 * The pixel values of this surface cannot be modified (e.g. doesn't support write pixels or 80 * MIP map level regen). 81 */ readOnly()82 bool readOnly() const { return fSurfaceFlags & GrInternalSurfaceFlags::kReadOnly; } 83 framebufferOnly()84 bool framebufferOnly() const { 85 return fSurfaceFlags & GrInternalSurfaceFlags::kFramebufferOnly; 86 } 87 88 // Returns true if we are working with protected content. isProtected()89 bool isProtected() const { return fIsProtected == GrProtected::kYes; } 90 setFramebufferOnly()91 void setFramebufferOnly() { 92 SkASSERT(this->asRenderTarget()); 93 fSurfaceFlags |= GrInternalSurfaceFlags::kFramebufferOnly; 94 } 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 121 // Provides access to methods that should be public within Skia code. 122 friend class GrSurfacePriv; 123 GrSurface(GrGpu * gpu,const SkISize & dimensions,GrProtected isProtected)124 GrSurface(GrGpu* gpu, const SkISize& dimensions, GrProtected isProtected) 125 : INHERITED(gpu) 126 , fDimensions(dimensions) 127 , fSurfaceFlags(GrInternalSurfaceFlags::kNone) 128 , fIsProtected(isProtected) {} 129 ~GrSurface()130 ~GrSurface() override { 131 // check that invokeReleaseProc has been called (if needed) 132 SkASSERT(!fReleaseHelper); 133 } 134 135 void onRelease() override; 136 void onAbandon() override; 137 138 private: getResourceType()139 const char* getResourceType() const override { return "Surface"; } 140 141 // Unmanaged backends (e.g. Vulkan) may want to specially handle the release proc in order to 142 // ensure it isn't called until GPU work related to the resource is completed. onSetRelease(sk_sp<GrRefCntedCallback>)143 virtual void onSetRelease(sk_sp<GrRefCntedCallback>) {} 144 invokeReleaseProc()145 void invokeReleaseProc() { 146 // Depending on the ref count of fReleaseHelper this may or may not actually trigger the 147 // ReleaseProc to be called. 148 fReleaseHelper.reset(); 149 } 150 151 SkISize fDimensions; 152 GrInternalSurfaceFlags fSurfaceFlags; 153 GrProtected fIsProtected; 154 sk_sp<GrRefCntedCallback> fReleaseHelper; 155 156 typedef GrGpuResource INHERITED; 157 }; 158 159 #endif 160