• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
GrRenderTargetProxy(const GrCaps & caps,const GrBackendFormat & format,SkISize dimensions,int sampleCount,SkBackingFit fit,SkBudgeted budgeted,GrProtected isProtected,GrInternalSurfaceFlags surfaceFlags,UseAllocator useAllocator)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         , fWrapsVkSecondaryCB(WrapsVkSecondaryCB::kNo) {}
39 
40 // Lazy-callback version
GrRenderTargetProxy(LazyInstantiateCallback && callback,const GrBackendFormat & format,SkISize dimensions,int sampleCount,SkBackingFit fit,SkBudgeted budgeted,GrProtected isProtected,GrInternalSurfaceFlags surfaceFlags,UseAllocator useAllocator,WrapsVkSecondaryCB wrapsVkSecondaryCB)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         , fWrapsVkSecondaryCB(wrapsVkSecondaryCB) {}
55 
56 // Wrapped version
GrRenderTargetProxy(sk_sp<GrSurface> surf,UseAllocator useAllocator,WrapsVkSecondaryCB wrapsVkSecondaryCB)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         , 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     SkASSERT(!(this->numSamples() <= 1 ||
70                fTarget->getContext()->priv().caps()->msaaResolvesAutomatically()) ||
71              !this->requiresManualMSAAResolve());
72 }
73 
maxWindowRectangles(const GrCaps & caps) const74 int GrRenderTargetProxy::maxWindowRectangles(const GrCaps& caps) const {
75     return this->glRTFBOIDIs0() ? 0 : caps.maxWindowRectangles();
76 }
77 
instantiate(GrResourceProvider * resourceProvider)78 bool GrRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
79     if (this->isLazy()) {
80         return false;
81     }
82     if (!this->instantiateImpl(resourceProvider, fSampleCnt, GrRenderable::kYes, GrMipmapped::kNo,
83                                nullptr)) {
84         return false;
85     }
86 
87     SkASSERT(this->peekRenderTarget());
88     SkASSERT(!this->peekTexture());
89     return true;
90 }
91 
canUseStencil(const GrCaps & caps) const92 bool GrRenderTargetProxy::canUseStencil(const GrCaps& caps) const {
93     if (caps.avoidStencilBuffers() || this->wrapsVkSecondaryCB()) {
94         return false;
95     }
96     if (!this->isInstantiated()) {
97         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             return SkToBool(this->asTextureProxy());
104         } else {
105             // Otherwise the target will definitely not be wrapped. Ganesh is free to attach
106             // stencils on internal render targets.
107             return true;
108         }
109     }
110     // Just ask the actual target if we can use stencil.
111     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     bool useMSAASurface = rt->numSamples() > 1;
115     return rt->getStencilAttachment(useMSAASurface) ||
116            rt->canAttemptStencilAttachment(useMSAASurface);
117 }
118 
createSurface(GrResourceProvider * resourceProvider) const119 sk_sp<GrSurface> GrRenderTargetProxy::createSurface(GrResourceProvider* resourceProvider) const {
120     sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, fSampleCnt,
121                                                        GrRenderable::kYes, GrMipmapped::kNo);
122     if (!surface) {
123         return nullptr;
124     }
125     SkASSERT(surface->asRenderTarget());
126     SkASSERT(!surface->asTexture());
127     return surface;
128 }
129 
onUninstantiatedGpuMemorySize() const130 size_t GrRenderTargetProxy::onUninstantiatedGpuMemorySize() const {
131     int colorSamplesPerPixel = this->numSamples();
132     if (colorSamplesPerPixel > 1) {
133         // Add one for the resolve buffer.
134         ++colorSamplesPerPixel;
135     }
136 
137     // TODO: do we have enough information to improve this worst case estimate?
138     return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
139                                   colorSamplesPerPixel, GrMipmapped::kNo, !this->priv().isExact());
140 }
141 
refsWrappedObjects() const142 bool GrRenderTargetProxy::refsWrappedObjects() const {
143     if (!this->isInstantiated()) {
144         return false;
145     }
146 
147     GrSurface* surface = this->peekSurface();
148     return surface->resourcePriv().refsWrappedObjects();
149 }
150 
callbackDesc() const151 GrSurfaceProxy::LazySurfaceDesc GrRenderTargetProxy::callbackDesc() const {
152     // We only expect exactly sized lazy RT proxies.
153     SkASSERT(!this->isFullyLazy());
154     SkASSERT(this->isFunctionallyExact());
155     return {
156             this->dimensions(),
157             SkBackingFit::kExact,
158             GrRenderable::kYes,
159             GrMipmapped::kNo,
160             this->numSamples(),
161             this->backendFormat(),
162             GrTextureType::kNone,
163             this->isProtected(),
164             this->isBudgeted(),
165     };
166 }
167 
168 #ifdef SK_DEBUG
onValidateSurface(const GrSurface * surface)169 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     SkASSERT(surface->asRenderTarget());
175     SkASSERT(surface->asRenderTarget()->numSamples() == this->numSamples());
176 
177     GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
178     GrInternalSurfaceFlags surfaceFlags = surface->flags();
179     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         surfaceFlags |= GrInternalSurfaceFlags::kGLRTFBOIDIs0;
185     }
186     SkASSERT(((int)proxyFlags & kGrInternalRenderTargetFlagsMask) ==
187              ((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     if (proxyFlags & GrInternalSurfaceFlags::kVkRTSupportsInputAttachment) {
193         SkASSERT(surfaceFlags & GrInternalSurfaceFlags::kVkRTSupportsInputAttachment);
194     }
195 }
196 #endif
197