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