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/GrTextureRenderTargetProxy.h"
9
10 #include "include/gpu/GrTexture.h"
11 #include "src/gpu/GrCaps.h"
12 #include "src/gpu/GrContextPriv.h"
13 #include "src/gpu/GrRenderTarget.h"
14 #include "src/gpu/GrRenderTargetProxyPriv.h"
15 #include "src/gpu/GrSurfacePriv.h"
16 #include "src/gpu/GrSurfaceProxyPriv.h"
17 #include "src/gpu/GrTexturePriv.h"
18 #include "src/gpu/GrTextureProxyPriv.h"
19
20 // Deferred version
21 // This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
22 // GrRenderTargetProxy) so its constructor must be explicitly called.
GrTextureRenderTargetProxy(const GrCaps & caps,const GrBackendFormat & format,const GrSurfaceDesc & desc,int sampleCnt,GrSurfaceOrigin origin,GrMipMapped mipMapped,GrMipMapsStatus mipMapsStatus,const GrSwizzle & texSwizzle,const GrSwizzle & outSwizzle,SkBackingFit fit,SkBudgeted budgeted,GrProtected isProtected,GrInternalSurfaceFlags surfaceFlags,UseAllocator useAllocator)23 GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps,
24 const GrBackendFormat& format,
25 const GrSurfaceDesc& desc,
26 int sampleCnt,
27 GrSurfaceOrigin origin,
28 GrMipMapped mipMapped,
29 GrMipMapsStatus mipMapsStatus,
30 const GrSwizzle& texSwizzle,
31 const GrSwizzle& outSwizzle,
32 SkBackingFit fit,
33 SkBudgeted budgeted,
34 GrProtected isProtected,
35 GrInternalSurfaceFlags surfaceFlags,
36 UseAllocator useAllocator)
37 : GrSurfaceProxy(format, desc, GrRenderable::kYes, origin, texSwizzle, fit, budgeted,
38 isProtected, surfaceFlags, useAllocator)
39 // for now textures w/ data are always wrapped
40 , GrRenderTargetProxy(caps, format, desc, sampleCnt, origin, texSwizzle, outSwizzle, fit,
41 budgeted, isProtected, surfaceFlags, useAllocator)
42 , GrTextureProxy(format, desc, origin, mipMapped, mipMapsStatus, texSwizzle, fit, budgeted,
43 isProtected, surfaceFlags, useAllocator) {
44 this->initSurfaceFlags(caps);
45 }
46
47 // Lazy-callback version
GrTextureRenderTargetProxy(const GrCaps & caps,LazyInstantiateCallback && callback,const GrBackendFormat & format,const GrSurfaceDesc & desc,int sampleCnt,GrSurfaceOrigin origin,GrMipMapped mipMapped,GrMipMapsStatus mipMapsStatus,const GrSwizzle & texSwizzle,const GrSwizzle & outSwizzle,SkBackingFit fit,SkBudgeted budgeted,GrProtected isProtected,GrInternalSurfaceFlags surfaceFlags,UseAllocator useAllocator)48 GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps,
49 LazyInstantiateCallback&& callback,
50 const GrBackendFormat& format,
51 const GrSurfaceDesc& desc,
52 int sampleCnt,
53 GrSurfaceOrigin origin,
54 GrMipMapped mipMapped,
55 GrMipMapsStatus mipMapsStatus,
56 const GrSwizzle& texSwizzle,
57 const GrSwizzle& outSwizzle,
58 SkBackingFit fit,
59 SkBudgeted budgeted,
60 GrProtected isProtected,
61 GrInternalSurfaceFlags surfaceFlags,
62 UseAllocator useAllocator)
63 : GrSurfaceProxy(std::move(callback), format, desc, GrRenderable::kYes, origin, texSwizzle,
64 fit, budgeted, isProtected, surfaceFlags, useAllocator)
65 // Since we have virtual inheritance, we initialize GrSurfaceProxy directly. Send null
66 // callbacks to the texture and RT proxies simply to route to the appropriate constructors.
67 , GrRenderTargetProxy(LazyInstantiateCallback(), format, desc, sampleCnt, origin,
68 texSwizzle, outSwizzle, fit, budgeted, isProtected, surfaceFlags,
69 useAllocator, WrapsVkSecondaryCB::kNo)
70 , GrTextureProxy(LazyInstantiateCallback(), format, desc, origin, mipMapped, mipMapsStatus,
71 texSwizzle, fit, budgeted, isProtected, surfaceFlags, useAllocator) {
72 this->initSurfaceFlags(caps);
73 }
74
75 // Wrapped version
76 // This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
77 // GrRenderTargetProxy) so its constructor must be explicitly called.
GrTextureRenderTargetProxy(sk_sp<GrSurface> surf,GrSurfaceOrigin origin,const GrSwizzle & texSwizzle,const GrSwizzle & outSwizzle,UseAllocator useAllocator)78 GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(sk_sp<GrSurface> surf,
79 GrSurfaceOrigin origin,
80 const GrSwizzle& texSwizzle,
81 const GrSwizzle& outSwizzle,
82 UseAllocator useAllocator)
83 : GrSurfaceProxy(surf, origin, texSwizzle, SkBackingFit::kExact, useAllocator)
84 , GrRenderTargetProxy(surf, origin, texSwizzle, outSwizzle, useAllocator)
85 , GrTextureProxy(surf, origin, texSwizzle, useAllocator) {
86 SkASSERT(surf->asTexture());
87 SkASSERT(surf->asRenderTarget());
88 SkASSERT(fSurfaceFlags == fTarget->surfacePriv().flags());
89 SkASSERT((this->numSamples() <= 1 ||
90 fTarget->getContext()->priv().caps()->msaaResolvesAutomatically()) !=
91 this->requiresManualMSAAResolve());
92 }
93
initSurfaceFlags(const GrCaps & caps)94 void GrTextureRenderTargetProxy::initSurfaceFlags(const GrCaps& caps) {
95 // FBO 0 should never be wrapped as a texture render target.
96 SkASSERT(!this->rtPriv().glRTFBOIDIs0());
97 if (this->numSamples() > 1 && !caps.msaaResolvesAutomatically()) {
98 // MSAA texture-render-targets always require manual resolve if we are not using a
99 // multisampled-render-to-texture extension.
100 //
101 // NOTE: This is the only instance where we need to set the manual resolve flag on a proxy.
102 // Any other proxies that require manual resolve (e.g., wrapBackendTextureAsRenderTarget())
103 // will be wrapped, and the wrapped version of the GrSurface constructor will automatically
104 // get the manual resolve flag when copying the target GrSurface's flags.
105 fSurfaceFlags |= GrInternalSurfaceFlags::kRequiresManualMSAAResolve;
106 }
107 }
108
onUninstantiatedGpuMemorySize(const GrCaps & caps) const109 size_t GrTextureRenderTargetProxy::onUninstantiatedGpuMemorySize(const GrCaps& caps) const {
110 int colorSamplesPerPixel = this->numSamples();
111 if (colorSamplesPerPixel > 1) {
112 // Add one to account for the resolve buffer.
113 ++colorSamplesPerPixel;
114 }
115
116 // TODO: do we have enough information to improve this worst case estimate?
117 return GrSurface::ComputeSize(caps, this->backendFormat(), this->width(), this->height(),
118 colorSamplesPerPixel, this->proxyMipMapped(),
119 !this->priv().isExact());
120 }
121
instantiate(GrResourceProvider * resourceProvider)122 bool GrTextureRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
123 if (this->isLazy()) {
124 return false;
125 }
126
127 const GrUniqueKey& key = this->getUniqueKey();
128
129 if (!this->instantiateImpl(resourceProvider, this->numSamples(), this->numStencilSamples(),
130 GrRenderable::kYes, this->mipMapped(),
131 key.isValid() ? &key : nullptr)) {
132 return false;
133 }
134 if (key.isValid()) {
135 SkASSERT(key == this->getUniqueKey());
136 }
137
138 SkASSERT(this->peekRenderTarget());
139 SkASSERT(this->peekTexture());
140
141 return true;
142 }
143
createSurface(GrResourceProvider * resourceProvider) const144 sk_sp<GrSurface> GrTextureRenderTargetProxy::createSurface(
145 GrResourceProvider* resourceProvider) const {
146 sk_sp<GrSurface> surface =
147 this->createSurfaceImpl(resourceProvider, this->numSamples(), this->numStencilSamples(),
148 GrRenderable::kYes, this->mipMapped());
149 if (!surface) {
150 return nullptr;
151 }
152 SkASSERT(surface->asRenderTarget());
153 SkASSERT(surface->asTexture());
154
155 return surface;
156 }
157
158 #ifdef SK_DEBUG
onValidateSurface(const GrSurface * surface)159 void GrTextureRenderTargetProxy::onValidateSurface(const GrSurface* surface) {
160 // Anything checked here should also be checking the GrTextureProxy version
161 SkASSERT(surface->asTexture());
162 SkASSERT(GrMipMapped::kNo == this->proxyMipMapped() ||
163 GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped());
164
165 // Anything checked here should also be checking the GrRenderTargetProxy version
166 SkASSERT(surface->asRenderTarget());
167 SkASSERT(surface->asRenderTarget()->numSamples() == this->numSamples());
168
169 SkASSERT(surface->asTexture()->texturePriv().textureType() == this->textureType());
170
171 GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
172 GrInternalSurfaceFlags surfaceFlags = surface->surfacePriv().flags();
173
174 // Only non-RT textures can be read only.
175 SkASSERT(!(proxyFlags & GrInternalSurfaceFlags::kReadOnly));
176 SkASSERT(!(surfaceFlags & GrInternalSurfaceFlags::kReadOnly));
177
178 SkASSERT(((int)proxyFlags & kGrInternalTextureRenderTargetFlagsMask) ==
179 ((int)surfaceFlags & kGrInternalTextureRenderTargetFlagsMask));
180 }
181 #endif
182
183