1 /*
2 * Copyright 2021 Google LLC
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/graphite/TextureProxy.h"
9
10 #include "src/core/SkMipmap.h"
11 #include "src/gpu/graphite/Caps.h"
12 #include "src/gpu/graphite/ResourceProvider.h"
13 #include "src/gpu/graphite/Texture.h"
14
15 namespace skgpu::graphite {
16
TextureProxy(SkISize dimensions,const TextureInfo & info,skgpu::Budgeted budgeted)17 TextureProxy::TextureProxy(SkISize dimensions, const TextureInfo& info, skgpu::Budgeted budgeted)
18 : fDimensions(dimensions), fInfo(info), fBudgeted(budgeted), fVolatile(Volatile::kNo) {
19 SkASSERT(fInfo.isValid());
20 }
21
TextureProxy(sk_sp<Texture> texture)22 TextureProxy::TextureProxy(sk_sp<Texture> texture)
23 : fDimensions(texture->dimensions())
24 , fInfo(texture->textureInfo())
25 , fBudgeted(texture->budgeted())
26 , fVolatile(Volatile::kNo)
27 , fTexture(std::move(texture)) {
28 SkASSERT(fInfo.isValid());
29 }
30
TextureProxy(SkISize dimensions,const TextureInfo & textureInfo,skgpu::Budgeted budgeted,Volatile isVolatile,LazyInstantiateCallback && callback)31 TextureProxy::TextureProxy(SkISize dimensions,
32 const TextureInfo& textureInfo,
33 skgpu::Budgeted budgeted,
34 Volatile isVolatile,
35 LazyInstantiateCallback&& callback)
36 : fDimensions(dimensions)
37 , fInfo(textureInfo)
38 , fBudgeted(budgeted)
39 , fVolatile(isVolatile)
40 , fLazyInstantiateCallback(std::move(callback)) {
41 SkASSERT(fInfo.isValid());
42 SkASSERT(fLazyInstantiateCallback);
43 }
44
~TextureProxy()45 TextureProxy::~TextureProxy() {}
46
dimensions() const47 SkISize TextureProxy::dimensions() const {
48 SkASSERT(!this->isFullyLazy() || this->isInstantiated());
49 return this->isInstantiated() ? fTexture->dimensions() : fDimensions;
50 }
51
isLazy() const52 bool TextureProxy::isLazy() const {
53 return SkToBool(fLazyInstantiateCallback);
54 }
55
isFullyLazy() const56 bool TextureProxy::isFullyLazy() const {
57 bool result = fDimensions.width() < 0;
58 SkASSERT(result == (fDimensions.height() < 0));
59 SkASSERT(!result || this->isLazy());
60 return result;
61 }
62
isVolatile() const63 bool TextureProxy::isVolatile() const {
64 SkASSERT(fVolatile == Volatile::kNo || SkToBool(fLazyInstantiateCallback));
65
66 return fVolatile == Volatile::kYes;
67 }
68
69
instantiate(ResourceProvider * resourceProvider)70 bool TextureProxy::instantiate(ResourceProvider* resourceProvider) {
71 SkASSERT(!this->isLazy());
72
73 if (fTexture) {
74 return true;
75 }
76
77 fTexture = resourceProvider->findOrCreateScratchTexture(fDimensions, fInfo, fBudgeted);
78 if (!fTexture) {
79 return false;
80 }
81 SkDEBUGCODE(this->validateTexture(fTexture.get()));
82 return true;
83 }
84
lazyInstantiate(ResourceProvider * resourceProvider)85 bool TextureProxy::lazyInstantiate(ResourceProvider* resourceProvider) {
86 SkASSERT(this->isLazy());
87
88 if (fTexture) {
89 return true;
90 }
91
92 fTexture = fLazyInstantiateCallback(resourceProvider);
93 if (!fTexture) {
94 return false;
95 }
96 SkDEBUGCODE(this->validateTexture(fTexture.get()));
97 return true;
98 }
99
InstantiateIfNotLazy(ResourceProvider * resourceProvider,TextureProxy * textureProxy)100 bool TextureProxy::InstantiateIfNotLazy(ResourceProvider* resourceProvider,
101 TextureProxy* textureProxy) {
102 if (textureProxy->isLazy()) {
103 return true;
104 }
105
106 return textureProxy->instantiate(resourceProvider);
107 }
108
deinstantiate()109 void TextureProxy::deinstantiate() {
110 SkASSERT(fVolatile == Volatile::kYes && SkToBool(fLazyInstantiateCallback));
111
112 fTexture.reset();
113 }
114
refTexture() const115 sk_sp<Texture> TextureProxy::refTexture() const {
116 return fTexture;
117 }
118
texture() const119 const Texture* TextureProxy::texture() const {
120 return fTexture.get();
121 }
122
Make(const Caps * caps,SkISize dimensions,SkColorType colorType,Mipmapped mipmapped,Protected isProtected,Renderable renderable,skgpu::Budgeted budgeted)123 sk_sp<TextureProxy> TextureProxy::Make(const Caps* caps,
124 SkISize dimensions,
125 SkColorType colorType,
126 Mipmapped mipmapped,
127 Protected isProtected,
128 Renderable renderable,
129 skgpu::Budgeted budgeted) {
130 if (dimensions.width() < 1 || dimensions.height() < 1) {
131 return nullptr;
132 }
133
134 TextureInfo textureInfo = caps->getDefaultSampledTextureInfo(colorType,
135 mipmapped,
136 isProtected,
137 renderable);
138 if (!textureInfo.isValid()) {
139 return nullptr;
140 }
141
142 return sk_make_sp<TextureProxy>(dimensions, textureInfo, budgeted);
143 }
144
MakeLazy(SkISize dimensions,const TextureInfo & textureInfo,skgpu::Budgeted budgeted,Volatile isVolatile,LazyInstantiateCallback && callback)145 sk_sp<TextureProxy> TextureProxy::MakeLazy(SkISize dimensions,
146 const TextureInfo& textureInfo,
147 skgpu::Budgeted budgeted,
148 Volatile isVolatile,
149 LazyInstantiateCallback&& callback) {
150 SkASSERT(textureInfo.isValid());
151
152 return sk_sp<TextureProxy>(new TextureProxy(dimensions, textureInfo, budgeted,
153 isVolatile, std::move(callback)));
154 }
155
MakeFullyLazy(const TextureInfo & textureInfo,skgpu::Budgeted budgeted,Volatile isVolatile,LazyInstantiateCallback && callback)156 sk_sp<TextureProxy> TextureProxy::MakeFullyLazy(const TextureInfo& textureInfo,
157 skgpu::Budgeted budgeted,
158 Volatile isVolatile,
159 LazyInstantiateCallback&& callback) {
160 return MakeLazy(SkISize::Make(-1, -1), textureInfo, budgeted, isVolatile, std::move(callback));
161 }
162
163 #ifdef SK_DEBUG
validateTexture(const Texture * texture)164 void TextureProxy::validateTexture(const Texture* texture) {
165 SkASSERT(this->isFullyLazy() || fDimensions == texture->dimensions());
166 SkASSERT(fInfo == texture->textureInfo());
167 }
168 #endif
169
170 } // namespace skgpu::graphite
171