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,WrapsVkSecondaryCB wrapsVkSecondaryCB)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                                          WrapsVkSecondaryCB wrapsVkSecondaryCB)
44         : INHERITED(std::move(callback), lazyType, format, desc, origin, fit, budgeted,
45                     surfaceFlags)
46         , fSampleCnt(desc.fSampleCnt)
47         , fNeedsStencil(false)
48         , fWrapsVkSecondaryCB(wrapsVkSecondaryCB) {
49     SkASSERT(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags));
50 }
51 
52 // Wrapped version
GrRenderTargetProxy(sk_sp<GrSurface> surf,GrSurfaceOrigin origin,WrapsVkSecondaryCB wrapsVkSecondaryCB)53 GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrSurface> surf, GrSurfaceOrigin origin,
54                                          WrapsVkSecondaryCB wrapsVkSecondaryCB)
55         : INHERITED(std::move(surf), origin, SkBackingFit::kExact)
56         , fSampleCnt(fTarget->asRenderTarget()->numStencilSamples())
57         , fNeedsStencil(false)
58         , fWrapsVkSecondaryCB(wrapsVkSecondaryCB) {
59 }
60 
maxWindowRectangles(const GrCaps & caps) const61 int GrRenderTargetProxy::maxWindowRectangles(const GrCaps& caps) const {
62     return this->glRTFBOIDIs0() ? 0 : caps.maxWindowRectangles();
63 }
64 
instantiate(GrResourceProvider * resourceProvider)65 bool GrRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
66     if (LazyState::kNot != this->lazyInstantiationState()) {
67         return false;
68     }
69     static constexpr GrSurfaceDescFlags kDescFlags = kRenderTarget_GrSurfaceFlag;
70 
71     if (!this->instantiateImpl(resourceProvider, fSampleCnt, fNeedsStencil, kDescFlags,
72                                GrMipMapped::kNo, nullptr)) {
73         return false;
74     }
75     SkASSERT(fTarget->asRenderTarget());
76     SkASSERT(!fTarget->asTexture());
77     return true;
78 }
79 
createSurface(GrResourceProvider * resourceProvider) const80 sk_sp<GrSurface> GrRenderTargetProxy::createSurface(GrResourceProvider* resourceProvider) const {
81     static constexpr GrSurfaceDescFlags kDescFlags = kRenderTarget_GrSurfaceFlag;
82 
83     sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, fSampleCnt, fNeedsStencil,
84                                                        kDescFlags, GrMipMapped::kNo);
85     if (!surface) {
86         return nullptr;
87     }
88     SkASSERT(surface->asRenderTarget());
89     SkASSERT(!surface->asTexture());
90     return surface;
91 }
92 
onUninstantiatedGpuMemorySize() const93 size_t GrRenderTargetProxy::onUninstantiatedGpuMemorySize() const {
94     int colorSamplesPerPixel = this->numColorSamples();
95     if (colorSamplesPerPixel > 1) {
96         // Add one for the resolve buffer.
97         ++colorSamplesPerPixel;
98     }
99 
100     // TODO: do we have enough information to improve this worst case estimate?
101     return GrSurface::ComputeSize(this->config(), this->width(), this->height(),
102                                   colorSamplesPerPixel, GrMipMapped::kNo, !this->priv().isExact());
103 }
104 
refsWrappedObjects() const105 bool GrRenderTargetProxy::refsWrappedObjects() const {
106     if (!fTarget) {
107         return false;
108     }
109 
110     return fTarget->resourcePriv().refsWrappedObjects();
111 }
112 
113 #ifdef SK_DEBUG
onValidateSurface(const GrSurface * surface)114 void GrRenderTargetProxy::onValidateSurface(const GrSurface* surface) {
115     // We do not check that surface->asTexture returns null since, when replaying DDLs we
116     // can fulfill a renderTarget-only proxy w/ a textureRenderTarget.
117 
118     // Anything that is checked here should be duplicated in GrTextureRenderTargetProxy's version
119     SkASSERT(surface->asRenderTarget());
120     SkASSERT(surface->asRenderTarget()->numStencilSamples() == this->numStencilSamples());
121 
122     GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
123     GrInternalSurfaceFlags surfaceFlags = surface->surfacePriv().flags();
124     SkASSERT((proxyFlags & GrInternalSurfaceFlags::kRenderTargetMask) ==
125              (surfaceFlags & GrInternalSurfaceFlags::kRenderTargetMask));
126 }
127 #endif
128