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 "GrTextureRenderTargetProxy.h" 16 #include "SkMathPriv.h" 17 18 // Deferred version 19 // TODO: we can probably munge the 'desc' in both the wrapped and deferred 20 // cases to make the sampleConfig/numSamples stuff more rational. 21 GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc, 22 SkBackingFit fit, SkBudgeted budgeted, uint32_t flags) 23 : INHERITED(desc, fit, budgeted, flags) 24 , fSampleCnt(desc.fSampleCnt) 25 , fNeedsStencil(false) 26 , fRenderTargetFlags(GrRenderTargetFlags::kNone) { 27 // Since we know the newly created render target will be internal, we are able to precompute 28 // what the flags will ultimately end up being. 29 if (caps.usesMixedSamples() && fSampleCnt > 1) { 30 fRenderTargetFlags |= GrRenderTargetFlags::kMixedSampled; 31 } 32 if (caps.maxWindowRectangles() > 0) { 33 fRenderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport; 34 } 35 } 36 37 // Lazy-callback version 38 GrRenderTargetProxy::GrRenderTargetProxy(LazyInstantiateCallback&& callback, 39 const GrSurfaceDesc& desc, 40 SkBackingFit fit, SkBudgeted budgeted, 41 uint32_t flags) 42 : INHERITED(std::move(callback), desc, fit, budgeted, flags) 43 , fSampleCnt(desc.fSampleCnt) 44 , fNeedsStencil(false) 45 , fRenderTargetFlags(GrRenderTargetFlags::kNone) { 46 SkASSERT(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags)); 47 } 48 49 // Wrapped version 50 GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface> surf, GrSurfaceOrigin origin) 51 : INHERITED(std::move(surf), origin, SkBackingFit::kExact) 52 , fSampleCnt(fTarget->asRenderTarget()->numStencilSamples()) 53 , fNeedsStencil(false) 54 , fRenderTargetFlags(fTarget->asRenderTarget()->renderTargetPriv().flags()) { 55 } 56 57 int GrRenderTargetProxy::maxWindowRectangles(const GrCaps& caps) const { 58 return (fRenderTargetFlags & GrRenderTargetFlags::kWindowRectsSupport) 59 ? caps.maxWindowRectangles() 60 : 0; 61 } 62 63 bool GrRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) { 64 if (LazyState::kNot != this->lazyInstantiationState()) { 65 return false; 66 } 67 static constexpr GrSurfaceFlags kFlags = kRenderTarget_GrSurfaceFlag; 68 69 if (!this->instantiateImpl(resourceProvider, fSampleCnt, fNeedsStencil, kFlags, 70 GrMipMapped::kNo, 71 SkDestinationSurfaceColorMode::kLegacy, nullptr)) { 72 return false; 73 } 74 SkASSERT(fTarget->asRenderTarget()); 75 SkASSERT(!fTarget->asTexture()); 76 // Check that our a priori computation matched the ultimate reality 77 SkASSERT(fRenderTargetFlags == fTarget->asRenderTarget()->renderTargetPriv().flags()); 78 79 return true; 80 } 81 82 sk_sp<GrSurface> GrRenderTargetProxy::createSurface(GrResourceProvider* resourceProvider) const { 83 static constexpr GrSurfaceFlags kFlags = kRenderTarget_GrSurfaceFlag; 84 85 sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, fSampleCnt, fNeedsStencil, 86 kFlags, GrMipMapped::kNo, 87 SkDestinationSurfaceColorMode::kLegacy); 88 if (!surface) { 89 return nullptr; 90 } 91 SkASSERT(surface->asRenderTarget()); 92 SkASSERT(!surface->asTexture()); 93 // Check that our a priori computation matched the ultimate reality 94 SkASSERT(fRenderTargetFlags == surface->asRenderTarget()->renderTargetPriv().flags()); 95 96 return surface; 97 } 98 99 size_t GrRenderTargetProxy::onUninstantiatedGpuMemorySize() const { 100 int colorSamplesPerPixel = this->numColorSamples(); 101 if (colorSamplesPerPixel > 1) { 102 // Add one for the resolve buffer. 103 ++colorSamplesPerPixel; 104 } 105 106 // TODO: do we have enough information to improve this worst case estimate? 107 return GrSurface::ComputeSize(this->config(), this->width(), this->height(), 108 colorSamplesPerPixel, GrMipMapped::kNo, !this->priv().isExact()); 109 } 110 111 bool GrRenderTargetProxy::refsWrappedObjects() const { 112 if (!fTarget) { 113 return false; 114 } 115 116 return fTarget->resourcePriv().refsWrappedObjects(); 117 } 118