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 #include "GrRenderTargetProxy.h" 9 10 #include "GrCaps.h" 11 #include "GrGpuResourcePriv.h" 12 #include "GrRenderTargetOpList.h" 13 #include "GrRenderTargetPriv.h" 14 #include "GrResourceProvider.h" 15 #include "GrSurfacePriv.h" 16 #include "GrTextureRenderTargetProxy.h" 17 #include "SkMathPriv.h" 18 19 // Deferred version 20 // TODO: we can probably munge the 'desc' in both the wrapped and deferred 21 // cases to make the sampleConfig/numSamples stuff more rational. 22 GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrBackendFormat& format, 23 const GrSurfaceDesc& desc, GrSurfaceOrigin origin, 24 SkBackingFit fit, SkBudgeted budgeted, 25 GrInternalSurfaceFlags surfaceFlags) 26 : INHERITED(format, desc, origin, fit, budgeted, surfaceFlags) 27 , fSampleCnt(desc.fSampleCnt) 28 , fNeedsStencil(false) 29 , fWrapsVkSecondaryCB(WrapsVkSecondaryCB::kNo) { 30 // Since we know the newly created render target will be internal, we are able to precompute 31 // what the flags will ultimately end up being. 32 if (caps.usesMixedSamples() && fSampleCnt > 1) { 33 this->setHasMixedSamples(); 34 } 35 } 36 37 // Lazy-callback version 38 GrRenderTargetProxy::GrRenderTargetProxy(LazyInstantiateCallback&& callback, 39 LazyInstantiationType lazyType, 40 const GrBackendFormat& format, const GrSurfaceDesc& desc, 41 GrSurfaceOrigin origin, SkBackingFit fit, 42 SkBudgeted budgeted, GrInternalSurfaceFlags surfaceFlags) 43 : INHERITED(std::move(callback), lazyType, format, desc, origin, fit, budgeted, 44 surfaceFlags) 45 , fSampleCnt(desc.fSampleCnt) 46 , fNeedsStencil(false) 47 , fWrapsVkSecondaryCB(WrapsVkSecondaryCB::kNo) { 48 SkASSERT(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags)); 49 } 50 51 // Wrapped version 52 GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface> surf, GrSurfaceOrigin origin, 53 WrapsVkSecondaryCB wrapsVkSecondaryCB) 54 : INHERITED(std::move(surf), origin, SkBackingFit::kExact) 55 , fSampleCnt(fTarget->asRenderTarget()->numStencilSamples()) 56 , fNeedsStencil(false) 57 , fWrapsVkSecondaryCB(wrapsVkSecondaryCB) { 58 } 59 60 int GrRenderTargetProxy::maxWindowRectangles(const GrCaps& caps) const { 61 return this->glRTFBOIDIs0() ? 0 : caps.maxWindowRectangles(); 62 } 63 64 bool GrRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) { 65 if (LazyState::kNot != this->lazyInstantiationState()) { 66 return false; 67 } 68 static constexpr GrSurfaceDescFlags kDescFlags = kRenderTarget_GrSurfaceFlag; 69 70 if (!this->instantiateImpl(resourceProvider, fSampleCnt, fNeedsStencil, kDescFlags, 71 GrMipMapped::kNo, nullptr)) { 72 return false; 73 } 74 SkASSERT(fTarget->asRenderTarget()); 75 SkASSERT(!fTarget->asTexture()); 76 return true; 77 } 78 79 sk_sp<GrSurface> GrRenderTargetProxy::createSurface(GrResourceProvider* resourceProvider) const { 80 static constexpr GrSurfaceDescFlags kDescFlags = kRenderTarget_GrSurfaceFlag; 81 82 sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, fSampleCnt, fNeedsStencil, 83 kDescFlags, GrMipMapped::kNo); 84 if (!surface) { 85 return nullptr; 86 } 87 SkASSERT(surface->asRenderTarget()); 88 SkASSERT(!surface->asTexture()); 89 return surface; 90 } 91 92 size_t GrRenderTargetProxy::onUninstantiatedGpuMemorySize() const { 93 int colorSamplesPerPixel = this->numColorSamples(); 94 if (colorSamplesPerPixel > 1) { 95 // Add one for the resolve buffer. 96 ++colorSamplesPerPixel; 97 } 98 99 // TODO: do we have enough information to improve this worst case estimate? 100 return GrSurface::ComputeSize(this->config(), this->width(), this->height(), 101 colorSamplesPerPixel, GrMipMapped::kNo, !this->priv().isExact()); 102 } 103 104 bool GrRenderTargetProxy::refsWrappedObjects() const { 105 if (!fTarget) { 106 return false; 107 } 108 109 return fTarget->resourcePriv().refsWrappedObjects(); 110 } 111 112 #ifdef SK_DEBUG 113 void GrRenderTargetProxy::onValidateSurface(const GrSurface* surface) { 114 // We do not check that surface->asTexture returns null since, when replaying DDLs we 115 // can fulfill a renderTarget-only proxy w/ a textureRenderTarget. 116 117 // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version 118 SkASSERT(surface->asRenderTarget()); 119 SkASSERT(surface->asRenderTarget()->numStencilSamples() == this->numStencilSamples()); 120 121 GrInternalSurfaceFlags proxyFlags = fSurfaceFlags; 122 GrInternalSurfaceFlags surfaceFlags = surface->surfacePriv().flags(); 123 SkASSERT((proxyFlags & GrInternalSurfaceFlags::kRenderTargetMask) == 124 (surfaceFlags & GrInternalSurfaceFlags::kRenderTargetMask)); 125 } 126 #endif 127