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.
GrRenderTargetProxy(const GrCaps & caps,const GrSurfaceDesc & desc,SkBackingFit fit,SkBudgeted budgeted,uint32_t flags)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
GrRenderTargetProxy(LazyInstantiateCallback && callback,const GrSurfaceDesc & desc,SkBackingFit fit,SkBudgeted budgeted,uint32_t flags)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
GrRenderTargetProxy(sk_sp<GrSurface> surf,GrSurfaceOrigin origin)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
maxWindowRectangles(const GrCaps & caps) const57 int GrRenderTargetProxy::maxWindowRectangles(const GrCaps& caps) const {
58 return (fRenderTargetFlags & GrRenderTargetFlags::kWindowRectsSupport)
59 ? caps.maxWindowRectangles()
60 : 0;
61 }
62
instantiate(GrResourceProvider * resourceProvider)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
createSurface(GrResourceProvider * resourceProvider) const82 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
onUninstantiatedGpuMemorySize() const99 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
refsWrappedObjects() const111 bool GrRenderTargetProxy::refsWrappedObjects() const {
112 if (!fTarget) {
113 return false;
114 }
115
116 return fTarget->resourcePriv().refsWrappedObjects();
117 }
118