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.
GrRenderTargetProxy(const GrCaps & caps,const GrBackendFormat & format,const GrSurfaceDesc & desc,GrSurfaceOrigin origin,SkBackingFit fit,SkBudgeted budgeted,GrInternalSurfaceFlags surfaceFlags)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
GrRenderTargetProxy(LazyInstantiateCallback && callback,LazyInstantiationType lazyType,const GrBackendFormat & format,const GrSurfaceDesc & desc,GrSurfaceOrigin origin,SkBackingFit fit,SkBudgeted budgeted,GrInternalSurfaceFlags surfaceFlags)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
GrRenderTargetProxy(sk_sp<GrSurface> surf,GrSurfaceOrigin origin,WrapsVkSecondaryCB wrapsVkSecondaryCB)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
maxWindowRectangles(const GrCaps & caps) const60 int GrRenderTargetProxy::maxWindowRectangles(const GrCaps& caps) const {
61 return this->glRTFBOIDIs0() ? 0 : caps.maxWindowRectangles();
62 }
63
instantiate(GrResourceProvider * resourceProvider)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
createSurface(GrResourceProvider * resourceProvider) const79 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
onUninstantiatedGpuMemorySize() const92 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
refsWrappedObjects() const104 bool GrRenderTargetProxy::refsWrappedObjects() const {
105 if (!fTarget) {
106 return false;
107 }
108
109 return fTarget->resourcePriv().refsWrappedObjects();
110 }
111
112 #ifdef SK_DEBUG
onValidateSurface(const GrSurface * surface)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