1 /* 2 * Copyright 2016 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 GrRenderTargetProxy_DEFINED 9 #define GrRenderTargetProxy_DEFINED 10 11 #include "include/private/GrTypesPriv.h" 12 #include "src/gpu/GrCaps.h" 13 #include "src/gpu/GrNativeRect.h" 14 #include "src/gpu/GrSurfaceProxy.h" 15 #include "src/gpu/GrSwizzle.h" 16 17 class GrResourceProvider; 18 class GrRenderTargetProxyPriv; 19 20 // This class delays the acquisition of RenderTargets until they are actually 21 // required 22 // Beware: the uniqueID of the RenderTargetProxy will usually be different than 23 // the uniqueID of the RenderTarget it represents! 24 class GrRenderTargetProxy : virtual public GrSurfaceProxy { 25 public: asRenderTargetProxy()26 GrRenderTargetProxy* asRenderTargetProxy() override { return this; } asRenderTargetProxy()27 const GrRenderTargetProxy* asRenderTargetProxy() const override { return this; } 28 29 // Actually instantiate the backing rendertarget, if necessary. 30 bool instantiate(GrResourceProvider*) override; 31 canUseMixedSamples(const GrCaps & caps)32 bool canUseMixedSamples(const GrCaps& caps) const { 33 return caps.mixedSamplesSupport() && !this->glRTFBOIDIs0() && 34 caps.internalMultisampleCount(this->backendFormat()) > 0 && 35 this->canChangeStencilAttachment(); 36 } 37 38 /* 39 * Indicate that a draw to this proxy requires stencil, and how many stencil samples it needs. 40 * The number of stencil samples on this proxy will be equal to the largest sample count passed 41 * to this method. 42 */ setNeedsStencil(int8_t numStencilSamples)43 void setNeedsStencil(int8_t numStencilSamples) { 44 SkASSERT(numStencilSamples >= fSampleCnt); 45 fNumStencilSamples = std::max(numStencilSamples, fNumStencilSamples); 46 } 47 48 /** 49 * Returns the number of stencil samples this proxy will use, or 0 if it does not use stencil. 50 */ numStencilSamples()51 int numStencilSamples() const { return fNumStencilSamples; } 52 53 /** 54 * Returns the number of samples/pixel in the color buffer (One if non-MSAA). 55 */ numSamples()56 int numSamples() const { return fSampleCnt; } 57 58 int maxWindowRectangles(const GrCaps& caps) const; 59 wrapsVkSecondaryCB()60 bool wrapsVkSecondaryCB() const { return fWrapsVkSecondaryCB == WrapsVkSecondaryCB::kYes; } 61 markMSAADirty(const SkIRect & dirtyRect,GrSurfaceOrigin origin)62 void markMSAADirty(const SkIRect& dirtyRect, GrSurfaceOrigin origin) { 63 SkASSERT(SkIRect::MakeSize(this->dimensions()).contains(dirtyRect)); 64 SkASSERT(this->requiresManualMSAAResolve()); 65 auto nativeRect = GrNativeRect::MakeRelativeTo( 66 origin, this->backingStoreDimensions().height(), dirtyRect); 67 fMSAADirtyRect.join(nativeRect.asSkIRect()); 68 } markMSAAResolved()69 void markMSAAResolved() { 70 SkASSERT(this->requiresManualMSAAResolve()); 71 fMSAADirtyRect.setEmpty(); 72 } isMSAADirty()73 bool isMSAADirty() const { 74 SkASSERT(fMSAADirtyRect.isEmpty() || this->requiresManualMSAAResolve()); 75 return this->requiresManualMSAAResolve() && !fMSAADirtyRect.isEmpty(); 76 } msaaDirtyRect()77 const SkIRect& msaaDirtyRect() const { 78 SkASSERT(this->requiresManualMSAAResolve()); 79 return fMSAADirtyRect; 80 } 81 82 // TODO: move this to a priv class! 83 bool refsWrappedObjects() const; 84 85 // Provides access to special purpose functions. 86 GrRenderTargetProxyPriv rtPriv(); 87 const GrRenderTargetProxyPriv rtPriv() const; 88 89 protected: 90 friend class GrProxyProvider; // for ctors 91 friend class GrRenderTargetProxyPriv; 92 93 // Deferred version 94 GrRenderTargetProxy(const GrCaps&, 95 const GrBackendFormat&, 96 SkISize, 97 int sampleCount, 98 const GrSwizzle& textureSwizzle, 99 SkBackingFit, 100 SkBudgeted, 101 GrProtected, 102 GrInternalSurfaceFlags, 103 UseAllocator); 104 105 enum class WrapsVkSecondaryCB : bool { kNo = false, kYes = true }; 106 107 // Lazy-callback version 108 // There are two main use cases for lazily-instantiated proxies: 109 // basic knowledge - width, height, config, samples, origin are known 110 // minimal knowledge - only config is known. 111 // 112 // The basic knowledge version is used for DDL where we know the type of proxy we are going to 113 // use, but we don't have access to the GPU yet to instantiate it. 114 // 115 // The minimal knowledge version is used for CCPR where we are generating an atlas but we do not 116 // know the final size until flush time. 117 GrRenderTargetProxy(LazyInstantiateCallback&&, 118 const GrBackendFormat&, 119 SkISize, 120 int sampleCount, 121 const GrSwizzle& textureSwizzle, 122 SkBackingFit, 123 SkBudgeted, 124 GrProtected, 125 GrInternalSurfaceFlags, 126 UseAllocator, 127 WrapsVkSecondaryCB); 128 129 // Wrapped version 130 GrRenderTargetProxy(sk_sp<GrSurface>, 131 const GrSwizzle& textureSwizzle, 132 UseAllocator, 133 WrapsVkSecondaryCB = WrapsVkSecondaryCB::kNo); 134 135 sk_sp<GrSurface> createSurface(GrResourceProvider*) const override; 136 137 private: setGLRTFBOIDIs0()138 void setGLRTFBOIDIs0() { 139 fSurfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0; 140 } glRTFBOIDIs0()141 bool glRTFBOIDIs0() const { 142 return fSurfaceFlags & GrInternalSurfaceFlags::kGLRTFBOIDIs0; 143 } 144 bool canChangeStencilAttachment() const; 145 146 size_t onUninstantiatedGpuMemorySize(const GrCaps&) const override; 147 SkDEBUGCODE(void onValidateSurface(const GrSurface*) override;) 148 149 // WARNING: Be careful when adding or removing fields here. ASAN is likely to trigger warnings 150 // when instantiating GrTextureRenderTargetProxy. The std::function in GrSurfaceProxy makes 151 // each class in the diamond require 16 byte alignment. Clang appears to layout the fields for 152 // each class to achieve the necessary alignment. However, ASAN checks the alignment of 'this' 153 // in the constructors, and always looks for the full 16 byte alignment, even if the fields in 154 // that particular class don't require it. Changing the size of this object can move the start 155 // address of other types, leading to this problem. 156 int8_t fSampleCnt; 157 int8_t fNumStencilSamples = 0; 158 WrapsVkSecondaryCB fWrapsVkSecondaryCB; 159 SkIRect fMSAADirtyRect = SkIRect::MakeEmpty(); 160 // This is to fix issue in large comment above. Without the padding we can end up with the 161 // GrTextureProxy starting 8 byte aligned by not 16. This happens when the RT ends at bytes 1-8. 162 // Note: with the virtual inheritance an 8 byte pointer is at the start of GrRenderTargetProxy. 163 // 164 // In the current world we end the RT proxy at 12 bytes. Technically any padding between 0-4 165 // will work, but we use 4 to be more explicit about getting it to 16 byte alignment. 166 char fDummyPadding[4]; 167 168 typedef GrSurfaceProxy INHERITED; 169 }; 170 171 #endif 172