blob: bada555810c2c66cf5c07f4c5f30bcfab431ad44 [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 "include/gpu/GrTexture.h"
11#include "src/gpu/GrCaps.h"
Chris Dalton3f7932e2019-08-19 00:39:13 -060012#include "src/gpu/GrContextPriv.h"
Brian Salomon201cdbb2019-08-14 17:00:30 -040013#include "src/gpu/GrRenderTarget.h"
Chris Dalton3f7932e2019-08-19 00:39:13 -060014#include "src/gpu/GrRenderTargetProxyPriv.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/gpu/GrSurfacePriv.h"
16#include "src/gpu/GrSurfaceProxyPriv.h"
17#include "src/gpu/GrTexturePriv.h"
18#include "src/gpu/GrTextureProxyPriv.h"
Chris Dalton706a6ff2017-11-29 22:01:06 -070019
Robert Phillips84a81202016-11-04 11:59:10 -040020// Deferred version
Robert Phillipsc787e492017-02-28 11:26:32 -050021// This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
Robert Phillips84a81202016-11-04 11:59:10 -040022// GrRenderTargetProxy) so its constructor must be explicitly called.
23GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps,
Greg Daniel4065d452018-11-16 15:43:41 -050024 const GrBackendFormat& format,
Robert Phillips84a81202016-11-04 11:59:10 -040025 const GrSurfaceDesc& desc,
Brian Salomon27b4d8d2019-07-22 14:23:45 -040026 int sampleCnt,
Brian Salomon2a4f9832018-03-03 22:43:43 -050027 GrSurfaceOrigin origin,
Greg Danielf6f7b672018-02-15 13:06:26 -050028 GrMipMapped mipMapped,
Chris Dalton95d8ceb2019-07-30 11:17:59 -060029 GrMipMapsStatus mipMapsStatus,
Greg Daniel2c19e7f2019-06-18 13:29:21 -040030 const GrSwizzle& texSwizzle,
31 const GrSwizzle& outSwizzle,
Robert Phillips84a81202016-11-04 11:59:10 -040032 SkBackingFit fit,
Robert Phillipsc787e492017-02-28 11:26:32 -050033 SkBudgeted budgeted,
Brian Salomone8a766b2019-07-19 14:24:36 -040034 GrProtected isProtected,
Brian Salomonbeb7f522019-08-30 16:19:42 -040035 GrInternalSurfaceFlags surfaceFlags,
36 UseAllocator useAllocator)
Brian Salomonf2c2ba92019-07-17 09:59:59 -040037 : GrSurfaceProxy(format, desc, GrRenderable::kYes, origin, texSwizzle, fit, budgeted,
Brian Salomonbeb7f522019-08-30 16:19:42 -040038 isProtected, surfaceFlags, useAllocator)
Chris Dalton706a6ff2017-11-29 22:01:06 -070039 // for now textures w/ data are always wrapped
Brian Salomon27b4d8d2019-07-22 14:23:45 -040040 , GrRenderTargetProxy(caps, format, desc, sampleCnt, origin, texSwizzle, outSwizzle, fit,
Brian Salomonbeb7f522019-08-30 16:19:42 -040041 budgeted, isProtected, surfaceFlags, useAllocator)
Chris Dalton95d8ceb2019-07-30 11:17:59 -060042 , GrTextureProxy(format, desc, origin, mipMapped, mipMapsStatus, texSwizzle, fit, budgeted,
Brian Salomonbeb7f522019-08-30 16:19:42 -040043 isProtected, surfaceFlags, useAllocator) {
Chris Dalton3f7932e2019-08-19 00:39:13 -060044 this->initSurfaceFlags(caps);
45}
Chris Dalton706a6ff2017-11-29 22:01:06 -070046
47// Lazy-callback version
Chris Dalton3f7932e2019-08-19 00:39:13 -060048GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(const GrCaps& caps,
49 LazyInstantiateCallback&& callback,
Greg Daniel4065d452018-11-16 15:43:41 -050050 const GrBackendFormat& format,
Greg Daniel65fa8ca2018-01-10 17:06:31 -050051 const GrSurfaceDesc& desc,
Brian Salomon27b4d8d2019-07-22 14:23:45 -040052 int sampleCnt,
Brian Salomon2a4f9832018-03-03 22:43:43 -050053 GrSurfaceOrigin origin,
Greg Daniel65fa8ca2018-01-10 17:06:31 -050054 GrMipMapped mipMapped,
Chris Dalton95d8ceb2019-07-30 11:17:59 -060055 GrMipMapsStatus mipMapsStatus,
Greg Daniel2c19e7f2019-06-18 13:29:21 -040056 const GrSwizzle& texSwizzle,
57 const GrSwizzle& outSwizzle,
Greg Daniel65fa8ca2018-01-10 17:06:31 -050058 SkBackingFit fit,
59 SkBudgeted budgeted,
Brian Salomone8a766b2019-07-19 14:24:36 -040060 GrProtected isProtected,
Brian Salomonbeb7f522019-08-30 16:19:42 -040061 GrInternalSurfaceFlags surfaceFlags,
62 UseAllocator useAllocator)
63 : GrSurfaceProxy(std::move(callback), format, desc, GrRenderable::kYes, origin, texSwizzle,
64 fit, budgeted, isProtected, surfaceFlags, useAllocator)
Chris Dalton706a6ff2017-11-29 22:01:06 -070065 // 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.
Brian Salomonbeb7f522019-08-30 16:19:42 -040067 , GrRenderTargetProxy(LazyInstantiateCallback(), format, desc, sampleCnt, origin,
Brian Salomon27b4d8d2019-07-22 14:23:45 -040068 texSwizzle, outSwizzle, fit, budgeted, isProtected, surfaceFlags,
Brian Salomonbeb7f522019-08-30 16:19:42 -040069 useAllocator, WrapsVkSecondaryCB::kNo)
70 , GrTextureProxy(LazyInstantiateCallback(), format, desc, origin, mipMapped, mipMapsStatus,
71 texSwizzle, fit, budgeted, isProtected, surfaceFlags, useAllocator) {
Chris Dalton3f7932e2019-08-19 00:39:13 -060072 this->initSurfaceFlags(caps);
73}
Robert Phillips84a81202016-11-04 11:59:10 -040074
75// Wrapped version
Robert Phillipsc787e492017-02-28 11:26:32 -050076// This class is virtually derived from GrSurfaceProxy (via both GrTextureProxy and
Robert Phillips84a81202016-11-04 11:59:10 -040077// GrRenderTargetProxy) so its constructor must be explicitly called.
Robert Phillips066f0202017-07-25 10:16:35 -040078GrTextureRenderTargetProxy::GrTextureRenderTargetProxy(sk_sp<GrSurface> surf,
Greg Daniel2c19e7f2019-06-18 13:29:21 -040079 GrSurfaceOrigin origin,
80 const GrSwizzle& texSwizzle,
Brian Salomonbeb7f522019-08-30 16:19:42 -040081 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) {
Robert Phillips37430132016-11-09 06:50:43 -050086 SkASSERT(surf->asTexture());
87 SkASSERT(surf->asRenderTarget());
Chris Dalton3f7932e2019-08-19 00:39:13 -060088 SkASSERT(fSurfaceFlags == fTarget->surfacePriv().flags());
89 SkASSERT((this->numSamples() <= 1 ||
90 fTarget->getContext()->priv().caps()->msaaResolvesAutomatically()) !=
91 this->requiresManualMSAAResolve());
92}
93
94void 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 }
Robert Phillips84a81202016-11-04 11:59:10 -0400107}
108
Brian Salomonbb5711a2017-05-17 13:49:59 -0400109size_t GrTextureRenderTargetProxy::onUninstantiatedGpuMemorySize() const {
Chris Dalton6ce447a2019-06-23 18:07:38 -0600110 int colorSamplesPerPixel = this->numSamples();
Brian Salomonbdecacf2018-02-02 20:32:49 -0500111 if (colorSamplesPerPixel > 1) {
112 // Add one to account for the resolve buffer.
Greg Danielf6f7b672018-02-15 13:06:26 -0500113 ++colorSamplesPerPixel;
Brian Salomonbdecacf2018-02-02 20:32:49 -0500114 }
Brian Salomonbb5711a2017-05-17 13:49:59 -0400115
Robert Phillips84a81202016-11-04 11:59:10 -0400116 // TODO: do we have enough information to improve this worst case estimate?
Chris Dalton706a6ff2017-11-29 22:01:06 -0700117 return GrSurface::ComputeSize(this->config(), this->width(), this->height(),
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400118 colorSamplesPerPixel, this->proxyMipMapped(),
Greg Daniel3b2ebbb2018-02-09 10:49:23 -0500119 !this->priv().isExact());
Robert Phillips84a81202016-11-04 11:59:10 -0400120}
121
Robert Phillips10d17212019-04-24 14:09:10 -0400122bool GrTextureRenderTargetProxy::instantiate(GrResourceProvider* resourceProvider) {
Brian Salomonbeb7f522019-08-30 16:19:42 -0400123 if (this->isLazy()) {
Greg Daniel0a375db2018-02-01 12:21:39 -0500124 return false;
125 }
Brian Salomonbb5711a2017-05-17 13:49:59 -0400126
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400127 const GrUniqueKey& key = this->getUniqueKey();
128
Brian Salomonf2c2ba92019-07-17 09:59:59 -0400129 if (!this->instantiateImpl(resourceProvider, this->numSamples(), this->numStencilSamples(),
130 GrRenderable::kYes, this->mipMapped(),
131 key.isValid() ? &key : nullptr)) {
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400132 return false;
Brian Salomonbb5711a2017-05-17 13:49:59 -0400133 }
Robert Phillipsae7d3f32017-09-21 08:26:08 -0400134 if (key.isValid()) {
135 SkASSERT(key == this->getUniqueKey());
136 }
137
Robert Phillipsb5204762019-06-19 14:12:13 -0400138 SkASSERT(this->peekRenderTarget());
139 SkASSERT(this->peekTexture());
Brian Salomonbb5711a2017-05-17 13:49:59 -0400140
Robert Phillipseee4d6e2017-06-05 09:26:07 -0400141 return true;
Brian Salomonbb5711a2017-05-17 13:49:59 -0400142}
Robert Phillips5af44de2017-07-18 14:49:38 -0400143
144sk_sp<GrSurface> GrTextureRenderTargetProxy::createSurface(
145 GrResourceProvider* resourceProvider) const {
Brian Salomonf2c2ba92019-07-17 09:59:59 -0400146 sk_sp<GrSurface> surface =
147 this->createSurfaceImpl(resourceProvider, this->numSamples(), this->numStencilSamples(),
148 GrRenderable::kYes, this->mipMapped());
Robert Phillips5af44de2017-07-18 14:49:38 -0400149 if (!surface) {
150 return nullptr;
151 }
152 SkASSERT(surface->asRenderTarget());
153 SkASSERT(surface->asTexture());
154
155 return surface;
156}
157
Chris Dalton706a6ff2017-11-29 22:01:06 -0700158#ifdef SK_DEBUG
Greg Daniel849dce12018-04-24 14:32:53 -0400159void GrTextureRenderTargetProxy::onValidateSurface(const GrSurface* surface) {
Robert Phillipse8fabb22018-02-04 14:33:21 -0500160 // Anything checked here should also be checking the GrTextureProxy version
161 SkASSERT(surface->asTexture());
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400162 SkASSERT(GrMipMapped::kNo == this->proxyMipMapped() ||
Robert Phillips4150eea2018-02-07 17:08:21 -0500163 GrMipMapped::kYes == surface->asTexture()->texturePriv().mipMapped());
Robert Phillipse8fabb22018-02-04 14:33:21 -0500164
165 // Anything checked here should also be checking the GrRenderTargetProxy version
166 SkASSERT(surface->asRenderTarget());
Chris Dalton6ce447a2019-06-23 18:07:38 -0600167 SkASSERT(surface->asRenderTarget()->numSamples() == this->numSamples());
Greg Daniel849dce12018-04-24 14:32:53 -0400168
Brian Salomonc67c31c2018-12-06 10:00:03 -0500169 SkASSERT(surface->asTexture()->texturePriv().textureType() == this->textureType());
170
Greg Daniel849dce12018-04-24 14:32:53 -0400171 GrInternalSurfaceFlags proxyFlags = fSurfaceFlags;
172 GrInternalSurfaceFlags surfaceFlags = surface->surfacePriv().flags();
Brian Salomonc67c31c2018-12-06 10:00:03 -0500173
174 // Only non-RT textures can be read only.
175 SkASSERT(!(proxyFlags & GrInternalSurfaceFlags::kReadOnly));
176 SkASSERT(!(surfaceFlags & GrInternalSurfaceFlags::kReadOnly));
177
Chris Dalton3f7932e2019-08-19 00:39:13 -0600178 SkASSERT(((int)proxyFlags & kGrInternalTextureRenderTargetFlagsMask) ==
179 ((int)surfaceFlags & kGrInternalTextureRenderTargetFlagsMask));
Chris Dalton706a6ff2017-11-29 22:01:06 -0700180}
181#endif
182