/src/skia/src/gpu/GrRenderTargetProxy.cpp
Line | Count | Source (jump to first uncovered line) |
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 "src/gpu/GrRenderTargetProxy.h" |
9 | | |
10 | | #include "src/core/SkMathPriv.h" |
11 | | #include "src/gpu/GrCaps.h" |
12 | | #include "src/gpu/GrGpuResourcePriv.h" |
13 | | #include "src/gpu/GrRenderTarget.h" |
14 | | #include "src/gpu/GrResourceProvider.h" |
15 | | #include "src/gpu/GrSurface.h" |
16 | | #include "src/gpu/GrSurfaceProxyPriv.h" |
17 | | #include "src/gpu/GrTextureRenderTargetProxy.h" |
18 | | |
19 | | #ifdef SK_DEBUG |
20 | | #include "include/gpu/GrDirectContext.h" |
21 | | #include "src/gpu/GrDirectContextPriv.h" |
22 | | #endif |
23 | | |
24 | | // Deferred version |
25 | | // TODO: we can probably munge the 'desc' in both the wrapped and deferred |
26 | | // cases to make the sampleConfig/numSamples stuff more rational. |
27 | | GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, |
28 | | const GrBackendFormat& format, |
29 | | SkISize dimensions, |
30 | | int sampleCount, |
31 | | SkBackingFit fit, |
32 | | SkBudgeted budgeted, |
33 | | GrProtected isProtected, |
34 | | GrInternalSurfaceFlags surfaceFlags, |
35 | | UseAllocator useAllocator) |
36 | | : INHERITED(format, dimensions, fit, budgeted, isProtected, surfaceFlags, useAllocator) |
37 | | , fSampleCnt(sampleCount) |
38 | 63.5k | , fWrapsVkSecondaryCB(WrapsVkSecondaryCB::kNo) {} GrRenderTargetProxy::GrRenderTargetProxy(GrCaps const&, GrBackendFormat const&, SkISize, int, SkBackingFit, SkBudgeted, GrProtected, GrInternalSurfaceFlags, GrSurfaceProxy::UseAllocator) Line | Count | Source | 38 | 63.5k | , fWrapsVkSecondaryCB(WrapsVkSecondaryCB::kNo) {} |
Unexecuted instantiation: GrRenderTargetProxy::GrRenderTargetProxy(GrCaps const&, GrBackendFormat const&, SkISize, int, SkBackingFit, SkBudgeted, GrProtected, GrInternalSurfaceFlags, GrSurfaceProxy::UseAllocator) |
39 | | |
40 | | // Lazy-callback version |
41 | | GrRenderTargetProxy::GrRenderTargetProxy(LazyInstantiateCallback&& callback, |
42 | | const GrBackendFormat& format, |
43 | | SkISize dimensions, |
44 | | int sampleCount, |
45 | | SkBackingFit fit, |
46 | | SkBudgeted budgeted, |
47 | | GrProtected isProtected, |
48 | | GrInternalSurfaceFlags surfaceFlags, |
49 | | UseAllocator useAllocator, |
50 | | WrapsVkSecondaryCB wrapsVkSecondaryCB) |
51 | | : INHERITED(std::move(callback), format, dimensions, fit, budgeted, isProtected, |
52 | | surfaceFlags, useAllocator) |
53 | | , fSampleCnt(sampleCount) |
54 | 74 | , fWrapsVkSecondaryCB(wrapsVkSecondaryCB) {} GrRenderTargetProxy::GrRenderTargetProxy(std::__1::function<GrSurfaceProxy::LazyCallbackResult (GrResourceProvider*, GrSurfaceProxy::LazySurfaceDesc const&)>&&, GrBackendFormat const&, SkISize, int, SkBackingFit, SkBudgeted, GrProtected, GrInternalSurfaceFlags, GrSurfaceProxy::UseAllocator, GrRenderTargetProxy::WrapsVkSecondaryCB) Line | Count | Source | 54 | 74 | , fWrapsVkSecondaryCB(wrapsVkSecondaryCB) {} |
Unexecuted instantiation: GrRenderTargetProxy::GrRenderTargetProxy(std::__1::function<GrSurfaceProxy::LazyCallbackResult (GrResourceProvider*, GrSurfaceProxy::LazySurfaceDesc const&)>&&, GrBackendFormat const&, SkISize, int, SkBackingFit, SkBudgeted, GrProtected, GrInternalSurfaceFlags, GrSurfaceProxy::UseAllocator, GrRenderTargetProxy::WrapsVkSecondaryCB) |
55 | | |
56 | | // Wrapped version |
57 | | GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface> surf, |
58 | | UseAllocator useAllocator, |
59 | | WrapsVkSecondaryCB wrapsVkSecondaryCB) |
60 | | : INHERITED(std::move(surf), SkBackingFit::kExact, useAllocator) |
61 | | , fSampleCnt(fTarget->asRenderTarget()->numSamples()) |
62 | 3 | , fWrapsVkSecondaryCB(wrapsVkSecondaryCB) { |
63 | | // The kRequiresManualMSAAResolve flag better not be set if we are not multisampled or if |
64 | | // MSAA resolve should happen automatically. |
65 | | // |
66 | | // From the other side, we don't know enough about the wrapped surface to assert when |
67 | | // kRequiresManualMSAAResolve *should* be set. e.g., The caller might be wrapping a backend |
68 | | // texture as a render target at this point but we wouldn't know it. |
69 | 3 | SkASSERT(!(this->numSamples() <= 1 || |
70 | 3 | fTarget->getContext()->priv().caps()->msaaResolvesAutomatically()) || |
71 | 3 | !this->requiresManualMSAAResolve()); |
72 | 3 | } GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceProxy::UseAllocator, GrRenderTargetProxy::WrapsVkSecondaryCB) Line | Count | Source | 62 | 3 | , fWrapsVkSecondaryCB(wrapsVkSecondaryCB) { | 63 | | // The kRequiresManualMSAAResolve flag better not be set if we are not multisampled or if | 64 | | // MSAA resolve should happen automatically. | 65 | | // | 66 | | // From the other side, we don't know enough about the wrapped surface to assert when | 67 | | // kRequiresManualMSAAResolve *should* be set. e.g., The caller might be wrapping a backend | 68 | | // texture as a render target at this point but we wouldn't know it. | 69 | 3 | SkASSERT(!(this->numSamples() <= 1 || | 70 | 3 | fTarget->getContext()->priv().caps()->msaaResolvesAutomatically()) || | 71 | 3 | !this->requiresManualMSAAResolve()); | 72 | 3 | } |
Unexecuted instantiation: GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceProxy::UseAllocator, GrRenderTargetProxy::WrapsVkSecondaryCB) Unexecuted instantiation: GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceProxy::UseAllocator, GrRenderTargetProxy::WrapsVkSecondaryCB) |
73 | | |
74 | 12.8k | int GrRenderTargetProxy::maxWindowRectangles(const GrCaps& caps) const { |
75 | 12.8k | return this->glRTFBOIDIs0() ? 0 : caps.maxWindowRectangles(); |
76 | 12.8k | } |
77 | | |
78 | 0 | bool GrRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) { |
79 | 0 | if (this->isLazy()) { |
80 | 0 | return false; |
81 | 0 | } |
82 | 0 | if (!this->instantiateImpl(resourceProvider, fSampleCnt, GrRenderable::kYes, GrMipmapped::kNo, |
83 | 0 | nullptr)) { |
84 | 0 | return false; |
85 | 0 | } |
86 | | |
87 | 0 | SkASSERT(this->peekRenderTarget()); |
88 | 0 | SkASSERT(!this->peekTexture()); |
89 | 0 | return true; |
90 | 0 | } Unexecuted instantiation: GrRenderTargetProxy::instantiate(GrResourceProvider*) Unexecuted instantiation: GrRenderTargetProxy::instantiate(GrResourceProvider*) |
91 | | |
92 | 23.9k | bool GrRenderTargetProxy::canUseStencil(const GrCaps& caps) const { |
93 | 23.9k | if (caps.avoidStencilBuffers() || this->wrapsVkSecondaryCB()) { |
94 | 0 | return false; |
95 | 0 | } |
96 | 23.9k | if (!this->isInstantiated()) { |
97 | 22.9k | if (this->isLazy() && this->backendFormat().backend() == GrBackendApi::kOpenGL) { |
98 | | // It's possible for wrapped GL render targets to not have stencil. We don't currently |
99 | | // have an exact way of knowing whether the target will be able to use stencil, so we do |
100 | | // the best we can: if a lazy GL proxy doesn't have a texture, then it might be a |
101 | | // wrapped target without stencil, so we conservatively block stencil. |
102 | | // FIXME: skbug.com/11943: SkSurfaceCharacterization needs a "canUseStencil" flag. |
103 | 0 | return SkToBool(this->asTextureProxy()); |
104 | 22.9k | } else { |
105 | | // Otherwise the target will definitely not be wrapped. Ganesh is free to attach |
106 | | // stencils on internal render targets. |
107 | 22.9k | return true; |
108 | 22.9k | } |
109 | 1.06k | } |
110 | | // Just ask the actual target if we can use stencil. |
111 | 1.06k | GrRenderTarget* rt = this->peekRenderTarget(); |
112 | | // The dmsaa attachment (if any) always supports stencil. The real question is whether the |
113 | | // non-dmsaa attachment supports stencil. |
114 | 1.06k | bool useMSAASurface = rt->numSamples() > 1; |
115 | 1.06k | return rt->getStencilAttachment(useMSAASurface) || |
116 | 974 | rt->canAttemptStencilAttachment(useMSAASurface); |
117 | 1.06k | } |
118 | | |
119 | 0 | sk_sp<GrSurface> GrRenderTargetProxy::createSurface(GrResourceProvider* resourceProvider) const { |
120 | 0 | sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, fSampleCnt, |
121 | 0 | GrRenderable::kYes, GrMipmapped::kNo); |
122 | 0 | if (!surface) { |
123 | 0 | return nullptr; |
124 | 0 | } |
125 | 0 | SkASSERT(surface->asRenderTarget()); |
126 | 0 | SkASSERT(!surface->asTexture()); |
127 | 0 | return surface; |
128 | 0 | } Unexecuted instantiation: GrRenderTargetProxy::createSurface(GrResourceProvider*) const Unexecuted instantiation: GrRenderTargetProxy::createSurface(GrResourceProvider*) const |
129 | | |
130 | 0 | size_t GrRenderTargetProxy::onUninstantiatedGpuMemorySize() const { |
131 | 0 | int colorSamplesPerPixel = this->numSamples(); |
132 | 0 | if (colorSamplesPerPixel > 1) { |
133 | | // Add one for the resolve buffer. |
134 | 0 | ++colorSamplesPerPixel; |
135 | 0 | } |
136 | | |
137 | | // TODO: do we have enough information to improve this worst case estimate? |
138 | 0 | return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(), |
139 | 0 | colorSamplesPerPixel, GrMipmapped::kNo, !this->priv().isExact()); |
140 | 0 | } |
141 | | |
142 | 15 | bool GrRenderTargetProxy::refsWrappedObjects() const { |
143 | 15 | if (!this->isInstantiated()) { |
144 | 3 | return false; |
145 | 3 | } |
146 | | |
147 | 12 | GrSurface* surface = this->peekSurface(); |
148 | 12 | return surface->resourcePriv().refsWrappedObjects(); |
149 | 12 | } |
150 | | |
151 | 0 | GrSurfaceProxy::LazySurfaceDesc GrRenderTargetProxy::callbackDesc() const { |
152 | | // We only expect exactly sized lazy RT proxies. |
153 | 0 | SkASSERT(!this->isFullyLazy()); |
154 | 0 | SkASSERT(this->isFunctionallyExact()); |
155 | 0 | return { |
156 | 0 | this->dimensions(), |
157 | 0 | SkBackingFit::kExact, |
158 | 0 | GrRenderable::kYes, |
159 | 0 | GrMipmapped::kNo, |
160 | 0 | this->numSamples(), |
161 | 0 | this->backendFormat(), |
162 | 0 | GrTextureType::kNone, |
163 | 0 | this->isProtected(), |
164 | 0 | this->isBudgeted(), |
165 | 0 | }; |
166 | 0 | } Unexecuted instantiation: GrRenderTargetProxy::callbackDesc() const Unexecuted instantiation: GrRenderTargetProxy::callbackDesc() const |
167 | | |
168 | | #ifdef SK_DEBUG |
169 | 0 | void GrRenderTargetProxy::onValidateSurface(const GrSurface* surface) { |
170 | | // We do not check that surface->asTexture returns null since, when replaying DDLs we |
171 | | // can fulfill a renderTarget-only proxy w/ a textureRenderTarget. |
172 | | |
173 | | // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version |
174 | 0 | SkASSERT(surface->asRenderTarget()); |
175 | 0 | SkASSERT(surface->asRenderTarget()->numSamples() == this->numSamples()); |
176 | |
|
177 | 0 | GrInternalSurfaceFlags proxyFlags = fSurfaceFlags; |
178 | 0 | GrInternalSurfaceFlags surfaceFlags = surface->flags(); |
179 | 0 | if (proxyFlags & GrInternalSurfaceFlags::kGLRTFBOIDIs0 && this->numSamples() == 1) { |
180 | | // Ganesh never internally creates FBO0 proxies or surfaces so this must be a wrapped |
181 | | // proxy. In this case, with no MSAA, rendering to FBO0 is strictly more limited than |
182 | | // rendering to an arbitrary surface so we allow a non-FBO0 surface to be matched with |
183 | | // the proxy. |
184 | 0 | surfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0; |
185 | 0 | } |
186 | 0 | SkASSERT(((int)proxyFlags & kGrInternalRenderTargetFlagsMask) == |
187 | 0 | ((int)surfaceFlags & kGrInternalRenderTargetFlagsMask)); |
188 | | |
189 | | // We manually check the kVkRTSupportsInputAttachment since we only require it on the surface if |
190 | | // the proxy has it set. If the proxy doesn't have the flag it is legal for the surface to |
191 | | // have the flag. |
192 | 0 | if (proxyFlags & GrInternalSurfaceFlags::kVkRTSupportsInputAttachment) { |
193 | 0 | SkASSERT(surfaceFlags & GrInternalSurfaceFlags::kVkRTSupportsInputAttachment); |
194 | 0 | } |
195 | 0 | } |
196 | | #endif |