blob: e0237748b5be38ad86586797bd311a72083c556e [file] [log] [blame]
Robert Phillips84a81202016-11-04 11:59:10 -04001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "src/gpu/GrTextureRenderTargetProxy.h"
Robert Phillips84a81202016-11-04 11:59:10 -04009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "src/gpu/GrCaps.h"
Brian Salomon201cdbb2019-08-14 17:00:30 -040011#include "src/gpu/GrRenderTarget.h"
Brian Salomonf7f54332020-07-28 09:23:35 -040012#include "src/gpu/GrSurface.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/gpu/GrSurfaceProxyPriv.h"
Greg Daniel456f9b52020-03-05 19:14:18 +000014#include "src/gpu/GrTexture.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/gpu/GrTextureProxyPriv.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070016
Robert Phillips4e105e22020-07-16 09:18:50 -040017#ifdef SK_DEBUG
18#include "include/gpu/GrDirectContext.h"
19#include "src/gpu/GrContextPriv.h"
20#endif
21
Robert Phillips84a81202016-11-04 11:59:10 -040022// Deferred version
Robert Phillipsc787e492017-02-28 11:26:32 -050023// This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
Robert Phillips84a81202016-11-04 11:59:10 -040024// GrRenderTargetProxy) so its constructor must be explicitly called.
25GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps,
Greg Daniel4065d452018-11-16 15:43:41 -050026 const GrBackendFormat& format,
Brian Salomona56a7462020-02-07 14:17:25 -050027 SkISize dimensions,
Brian Salomon27b4d8d2019-07-22 14:23:45 -040028 int sampleCnt,
Brian Salomon7e67dca2020-07-21 09:27:25 -040029 GrMipmapped mipMapped,
Brian Salomona6db5102020-07-21 09:56:23 -040030 GrMipmapStatus mipmapStatus,
Robert Phillips84a81202016-11-04 11:59:10 -040031 SkBackingFit fit,
Robert Phillipsc787e492017-02-28 11:26:32 -050032 SkBudgeted budgeted,
Brian Salomone8a766b2019-07-19 14:24:36 -040033 GrProtected isProtected,
Brian Salomonbeb7f522019-08-30 16:19:42 -040034 GrInternalSurfaceFlags surfaceFlags,
Robert Phillipsf10b2a52020-05-15 10:20:04 -040035 UseAllocator useAllocator,
36 GrDDLProvider creatingProvider)
Brian Salomondf1bd6d2020-03-26 20:37:01 -040037 : GrSurfaceProxy(format, dimensions, fit, budgeted, isProtected, surfaceFlags, useAllocator)
Chris Dalton706a6ff2017-11-29 22:01:06 -070038 // for now textures w/ data are always wrapped
Brian Salomondf1bd6d2020-03-26 20:37:01 -040039 , GrRenderTargetProxy(caps, format, dimensions, sampleCnt, fit, budgeted, isProtected,
40 surfaceFlags, useAllocator)
Brian Salomona6db5102020-07-21 09:56:23 -040041 , GrTextureProxy(format, dimensions, mipMapped, mipmapStatus, fit, budgeted, isProtected,
Robert Phillipsf10b2a52020-05-15 10:20:04 -040042 surfaceFlags, useAllocator, creatingProvider) {
Chris Dalton3f7932e2019-08-19 00:39:13 -060043 this->initSurfaceFlags(caps);
44}
Chris Dalton706a6ff2017-11-29 22:01:06 -070045
46// Lazy-callback version
Chris Dalton3f7932e2019-08-19 00:39:13 -060047GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps,
48 LazyInstantiateCallback&& callback,
Greg Daniel4065d452018-11-16 15:43:41 -050049 const GrBackendFormat& format,
Brian Salomona56a7462020-02-07 14:17:25 -050050 SkISize dimensions,
Brian Salomon27b4d8d2019-07-22 14:23:45 -040051 int sampleCnt,
Brian Salomon7e67dca2020-07-21 09:27:25 -040052 GrMipmapped mipMapped,
Brian Salomona6db5102020-07-21 09:56:23 -040053 GrMipmapStatus mipmapStatus,
Greg Daniel65fa8ca2018-01-10 17:06:31 -050054 SkBackingFit fit,
55 SkBudgeted budgeted,
Brian Salomone8a766b2019-07-19 14:24:36 -040056 GrProtected isProtected,
Brian Salomonbeb7f522019-08-30 16:19:42 -040057 GrInternalSurfaceFlags surfaceFlags,
Robert Phillipsf10b2a52020-05-15 10:20:04 -040058 UseAllocator useAllocator,
59 GrDDLProvider creatingProvider)
Brian Salomondf1bd6d2020-03-26 20:37:01 -040060 : GrSurfaceProxy(std::move(callback), format, dimensions, fit, budgeted, isProtected,
61 surfaceFlags, useAllocator)
Chris Dalton706a6ff2017-11-29 22:01:06 -070062 // Since we have virtual inheritance, we initialize GrSurfaceProxy directly. Send null
63 // callbacks to the texture and RT proxies simply to route to the appropriate constructors.
Brian Salomondf1bd6d2020-03-26 20:37:01 -040064 , GrRenderTargetProxy(LazyInstantiateCallback(), format, dimensions, sampleCnt, fit,
65 budgeted, isProtected, surfaceFlags, useAllocator,
Greg Danielbaf8d992019-10-29 14:14:32 -040066 WrapsVkSecondaryCB::kNo)
Brian Salomona6db5102020-07-21 09:56:23 -040067 , GrTextureProxy(LazyInstantiateCallback(), format, dimensions, mipMapped, mipmapStatus,
Robert Phillipsf10b2a52020-05-15 10:20:04 -040068 fit, budgeted, isProtected, surfaceFlags, useAllocator,
69 creatingProvider) {
Chris Dalton3f7932e2019-08-19 00:39:13 -060070 this->initSurfaceFlags(caps);
71}
Robert Phillips84a81202016-11-04 11:59:10 -040072
73// Wrapped version
Robert Phillipsc787e492017-02-28 11:26:32 -050074// This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
Robert Phillips84a81202016-11-04 11:59:10 -040075// GrRenderTargetProxy) so its constructor must be explicitly called.
Robert Phillips066f0202017-07-25 10:16:35 -040076GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(sk_sp<GrSurface> surf,
Robert Phillipsf10b2a52020-05-15 10:20:04 -040077 UseAllocator useAllocator,
78 GrDDLProvider creatingProvider)
Brian Salomondf1bd6d2020-03-26 20:37:01 -040079 : GrSurfaceProxy(surf, SkBackingFit::kExact, useAllocator)
80 , GrRenderTargetProxy(surf, useAllocator)
Robert Phillipsf10b2a52020-05-15 10:20:04 -040081 , GrTextureProxy(surf, useAllocator, creatingProvider) {
Robert Phillips37430132016-11-09 06:50:43 -050082 SkASSERT(surf->asTexture());
83 SkASSERT(surf->asRenderTarget());
Brian Salomonf7f54332020-07-28 09:23:35 -040084 SkASSERT(fSurfaceFlags == fTarget->flags());
Chris Dalton3f7932e2019-08-19 00:39:13 -060085 SkASSERT((this->numSamples() <= 1 ||
86 fTarget->getContext()->priv().caps()->msaaResolvesAutomatically()) !=
87 this->requiresManualMSAAResolve());
88}
89
90void GrTextureRenderTargetProxy::initSurfaceFlags(const GrCaps& caps) {
Jim Van Verth5fab9092019-11-25 21:23:53 +000091 // FBO 0 should never be wrapped as a texture render target.
Greg Daniel10c42132020-08-26 11:59:14 -040092 SkASSERT(!this->glRTFBOIDIs0());
Chris Dalton3f7932e2019-08-19 00:39:13 -060093 if (this->numSamples() > 1 && !caps.msaaResolvesAutomatically()) {
94 // MSAA texture-render-targets always require manual resolve if we are not using a
95 // multisampled-render-to-texture extension.
96 //
97 // NOTE: This is the only instance where we need to set the manual resolve flag on a proxy.
Brian Salomon30c9b4c2020-10-09 17:19:25 -040098 // Any other proxies that require manual resolve (e.g., wrapRenderableBackendTexture() with
99 // a sample count) will be wrapped, and the wrapped version of the GrSurface constructor
100 // will automatically get the manual resolve flag when copying the target GrSurface's flags.
Chris Dalton3f7932e2019-08-19 00:39:13 -0600101 fSurfaceFlags |= GrInternalSurfaceFlags::kRequiresManualMSAAResolve;
102 }
Robert Phillips84a81202016-11-04 11:59:10 -0400103}
104
Greg Daniel0eca74c2020-10-01 13:46:00 -0400105size_t GrTextureRenderTargetProxy::onUninstantiatedGpuMemorySize() const {
Chris Dalton6ce447a2019-06-23 18:07:38 -0600106 int colorSamplesPerPixel = this->numSamples();
Brian Salomonbdecacf2018-02-02 20:32:49 -0500107 if (colorSamplesPerPixel > 1) {
108 // Add one to account for the resolve buffer.
Greg Danielf6f7b672018-02-15 13:06:26 -0500109 ++colorSamplesPerPixel;
Brian Salomonbdecacf2018-02-02 20:32:49 -0500110 }
Brian Salomonbb5711a2017-05-17 13:49:59 -0400111
Robert Phillips84a81202016-11-04 11:59:10 -0400112 // TODO: do we have enough information to improve this worst case estimate?
Greg Daniel0eca74c2020-10-01 13:46:00 -0400113 return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(),
Brian Salomon8c82a872020-07-21 12:09:58 -0400114 colorSamplesPerPixel, this->proxyMipmapped(),
Greg Daniel3b2ebbb2018-02-09 10:49:23 -0500115 !this->priv().isExact());
Robert Phillips84a81202016-11-04 11:59:10 -0400116}
117
Robert Phillips10d17212019-04-24 14:09:10 -0400118bool GrTextureRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
Brian Salomonbeb7f522019-08-30 16:19:42 -0400119 if (this->isLazy()) {
Greg Daniel0a375db2018-02-01 12:21:39 -0500120 return false;
121 }
Brian Salomonbb5711a2017-05-17 13:49:59 -0400122
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400123 const GrUniqueKey& key = this->getUniqueKey();
124
Chris Dalton0b68dda2019-11-07 21:08:03 -0700125 if (!this->instantiateImpl(resourceProvider, this->numSamples(), GrRenderable::kYes,
Brian Salomon8c82a872020-07-21 12:09:58 -0400126 this->mipmapped(), key.isValid() ? &key : nullptr)) {
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400127 return false;
Brian Salomonbb5711a2017-05-17 13:49:59 -0400128 }
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400129 if (key.isValid()) {
130 SkASSERT(key == this->getUniqueKey());
131 }
132
Robert Phillipsb5204762019-06-19 14:12:13 -0400133 SkASSERT(this->peekRenderTarget());
134 SkASSERT(this->peekTexture());
Brian Salomonbb5711a2017-05-17 13:49:59 -0400135
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400136 return true;
Brian Salomonbb5711a2017-05-17 13:49:59 -0400137}
Robert Phillips5af44de2017-07-18 14:49:38 -0400138
139sk_sp<GrSurface> GrTextureRenderTargetProxy::createSurface(
140 GrResourceProvider* resourceProvider) const {
Chris Dalton0b68dda2019-11-07 21:08:03 -0700141 sk_sp<GrSurface> surface = this->createSurfaceImpl(resourceProvider, this->numSamples(),
Brian Salomon8c82a872020-07-21 12:09:58 -0400142 GrRenderable::kYes, this->mipmapped());
Robert Phillips5af44de2017-07-18 14:49:38 -0400143 if (!surface) {
144 return nullptr;
145 }
146 SkASSERT(surface->asRenderTarget());
147 SkASSERT(surface->asTexture());
148
149 return surface;
150}
151
Brian Salomon63410e92020-03-23 18:32:50 -0400152GrSurfaceProxy::LazySurfaceDesc GrTextureRenderTargetProxy::callbackDesc() const {
153 SkISize dims;
154 SkBackingFit fit;
155 if (this->isFullyLazy()) {
156 fit = SkBackingFit::kApprox;
157 dims = {-1, -1};
158 } else {
159 fit = this->isFunctionallyExact() ? SkBackingFit::kExact : SkBackingFit::kApprox;
160 dims = this->dimensions();
161 }
162 return {
163 dims,
164 fit,
165 GrRenderable::kYes,
Brian Salomon8c82a872020-07-21 12:09:58 -0400166 this->mipmapped(),
Brian Salomon63410e92020-03-23 18:32:50 -0400167 this->numSamples(),
168 this->backendFormat(),
169 this->isProtected(),
170 this->isBudgeted(),
171 };
172}
173
Chris Dalton706a6ff2017-11-29 22:01:06 -0700174#ifdef SK_DEBUG
Greg Daniel849dce12018-04-24 14:32:53 -0400175void GrTextureRenderTargetProxy::onValidateSurface(const GrSurface* surface) {
Robert Phillipse8fabb22018-02-04 14:33:21 -0500176 // Anything checked here should also be checking the GrTextureProxy version
177 SkASSERT(surface->asTexture());
Brian Salomon8c82a872020-07-21 12:09:58 -0400178 SkASSERT(GrMipmapped::kNo == this->proxyMipmapped() ||
Brian Salomon4cfae3b2020-07-23 10:33:24 -0400179 GrMipmapped::kYes == surface->asTexture()->mipmapped());
Robert Phillipse8fabb22018-02-04 14:33:21 -0500180
181 // Anything checked here should also be checking the GrRenderTargetProxy version
182 SkASSERT(surface->asRenderTarget());
Chris Dalton6ce447a2019-06-23 18:07:38 -0600183 SkASSERT(surface->asRenderTarget()->numSamples() == this->numSamples());
Greg Daniel849dce12018-04-24 14:32:53 -0400184
Brian Salomon4cfae3b2020-07-23 10:33:24 -0400185 SkASSERT(surface->asTexture()->textureType() == this->textureType());
Brian Salomonc67c31c2018-12-06 10:00:03 -0500186
Greg Daniel849dce12018-04-24 14:32:53 -0400187 GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
Brian Salomonf7f54332020-07-28 09:23:35 -0400188 GrInternalSurfaceFlags surfaceFlags = surface->flags();
Brian Salomonc67c31c2018-12-06 10:00:03 -0500189
190 // Only non-RT textures can be read only.
191 SkASSERT(!(proxyFlags & GrInternalSurfaceFlags::kReadOnly));
192 SkASSERT(!(surfaceFlags & GrInternalSurfaceFlags::kReadOnly));
193
Chris Dalton3f7932e2019-08-19 00:39:13 -0600194 SkASSERT(((int)proxyFlags & kGrInternalTextureRenderTargetFlagsMask) ==
195 ((int)surfaceFlags & kGrInternalTextureRenderTargetFlagsMask));
Greg Daniel638b2e82020-08-27 14:29:00 -0400196
197 // We manually check the kVkRTSupportsInputAttachment since we only require it on the surface if
198 // the proxy has it set. If the proxy doesn't have the flag it is legal for the surface to
199 // have the flag.
200 if (proxyFlags & GrInternalSurfaceFlags::kVkRTSupportsInputAttachment) {
201 SkASSERT(surfaceFlags & GrInternalSurfaceFlags::kVkRTSupportsInputAttachment);
202 }
Chris Dalton706a6ff2017-11-29 22:01:06 -0700203}
204#endif
205