Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
TextureProxyTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 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 "tests/Test.h"
9
24
25namespace skgpu::graphite {
26
27DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphiteTextureProxyTest, reporter, context,
29 const Caps* caps = context->priv().caps();
30 constexpr SkISize kValidSize = SkISize::Make(1, 1);
31 constexpr SkISize kInvalidSize = SkISize::MakeEmpty();
32 constexpr SkColorType kValidColorType = kRGBA_8888_SkColorType;
33 constexpr SkColorType kInvalidColorType = kUnknown_SkColorType;
34
35 Protected isProtected = Protected(caps->protectedSupport());
36
37 std::unique_ptr<Recorder> recorder = context->makeRecorder();
38 ResourceProvider* resourceProvider = recorder->priv().resourceProvider();
39 const TextureInfo textureInfo = caps->getDefaultSampledTextureInfo(
40 kValidColorType, Mipmapped::kNo, isProtected, Renderable::kNo);
41 BackendTexture backendTexture = recorder->createBackendTexture(kValidSize, textureInfo);
42 sk_sp<Texture> texture = resourceProvider->createWrappedTexture(backendTexture);
43
44 auto makeProxy = [&](SkISize dimensions, SkColorType colorType, Mipmapped mipmapped,
45 Protected isProtected, Renderable renderable, Budgeted budgeted) {
46 auto textureInfo = caps->getDefaultSampledTextureInfo(colorType, mipmapped,
47 isProtected, renderable);
48 return TextureProxy::Make(caps, recorder->priv().resourceProvider(),
49 dimensions, textureInfo, budgeted);
50 };
51
52 auto nullCallback = [](ResourceProvider*) -> sk_sp<Texture> { return nullptr; };
53 auto callback = [texture](ResourceProvider*) -> sk_sp<Texture> { return texture; };
54
55 // Assign to assignableTexture before instantiating with this callback.
56 sk_sp<Texture> assignableTexture;
57 auto assignableCallback = [&assignableTexture](ResourceProvider*) -> sk_sp<Texture> {
58 return assignableTexture;
59 };
60
61 // Invalid parameters.
62 sk_sp<TextureProxy> textureProxy;
63 textureProxy = makeProxy(kInvalidSize,
64 kValidColorType,
65 Mipmapped::kNo,
66 isProtected,
67 Renderable::kNo,
69 REPORTER_ASSERT(reporter, textureProxy == nullptr);
70 textureProxy = makeProxy(kValidSize,
71 kInvalidColorType,
72 Mipmapped::kNo,
73 isProtected,
74 Renderable::kNo,
76 REPORTER_ASSERT(reporter, textureProxy == nullptr);
77
78 // Non-budgeted, non-lazy TextureProxy is instantiated on return
79 textureProxy = makeProxy(kValidSize,
80 kValidColorType,
81 Mipmapped::kNo,
82 isProtected,
83 Renderable::kNo,
85 REPORTER_ASSERT(reporter, !textureProxy->isLazy());
86 REPORTER_ASSERT(reporter, !textureProxy->isFullyLazy());
87 REPORTER_ASSERT(reporter, !textureProxy->isVolatile());
88 REPORTER_ASSERT(reporter, textureProxy->isInstantiated());
89 REPORTER_ASSERT(reporter, textureProxy->dimensions() == kValidSize);
90
91 // Budgeted, non-lazy TextureProxy, successful instantiation later on
92 textureProxy = makeProxy(kValidSize,
93 kValidColorType,
94 Mipmapped::kNo,
95 isProtected,
96 Renderable::kNo,
98 REPORTER_ASSERT(reporter, !textureProxy->isLazy());
99 REPORTER_ASSERT(reporter, !textureProxy->isFullyLazy());
100 REPORTER_ASSERT(reporter, !textureProxy->isVolatile());
101 REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
102 REPORTER_ASSERT(reporter, textureProxy->dimensions() == kValidSize);
103
104 bool instantiateSuccess = textureProxy->instantiate(resourceProvider);
105 REPORTER_ASSERT(reporter, instantiateSuccess);
106 REPORTER_ASSERT(reporter, textureProxy->isInstantiated());
107 REPORTER_ASSERT(reporter, textureProxy->dimensions() == kValidSize);
108 const Texture* createdTexture = textureProxy->texture();
109
110 instantiateSuccess = textureProxy->instantiate(resourceProvider);
111 REPORTER_ASSERT(reporter, instantiateSuccess);
112 REPORTER_ASSERT(reporter, textureProxy->texture() == createdTexture);
113
114 // Lazy, non-volatile TextureProxy, unsuccessful instantiation.
115 textureProxy = TextureProxy::MakeLazy(
116 caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kNo, nullCallback);
117 REPORTER_ASSERT(reporter, textureProxy->isLazy());
118 REPORTER_ASSERT(reporter, !textureProxy->isFullyLazy());
119 REPORTER_ASSERT(reporter, !textureProxy->isVolatile());
120
121 instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
122 REPORTER_ASSERT(reporter, !instantiateSuccess);
123 REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
124
125 // Lazy, non-volatile TextureProxy, successful instantiation.
126 textureProxy = TextureProxy::MakeLazy(
127 caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kNo, callback);
128
129 instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
130 REPORTER_ASSERT(reporter, instantiateSuccess);
131 REPORTER_ASSERT(reporter, textureProxy->texture() == texture.get());
132
133 // Lazy, volatile TextureProxy, unsuccessful instantiation.
134 textureProxy = TextureProxy::MakeLazy(
135 caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kYes, nullCallback);
136 REPORTER_ASSERT(reporter, textureProxy->isLazy());
137 REPORTER_ASSERT(reporter, !textureProxy->isFullyLazy());
138 REPORTER_ASSERT(reporter, textureProxy->isVolatile());
139
140 instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
141 REPORTER_ASSERT(reporter, !instantiateSuccess);
142 REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
143
144 // Lazy, volatile TextureProxy, successful instantiation.
145 textureProxy = TextureProxy::MakeLazy(
146 caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kYes, callback);
147
148 instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
149 REPORTER_ASSERT(reporter, instantiateSuccess);
150 REPORTER_ASSERT(reporter, textureProxy->texture() == texture.get());
151
152 textureProxy->deinstantiate();
153 REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
154
155 // Fully-lazy TextureProxy.
156 textureProxy = TextureProxy::MakeFullyLazy(
157 textureInfo, skgpu::Budgeted::kNo, Volatile::kYes, assignableCallback);
158 REPORTER_ASSERT(reporter, textureProxy->isLazy());
159 REPORTER_ASSERT(reporter, textureProxy->isFullyLazy());
160 REPORTER_ASSERT(reporter, textureProxy->isVolatile());
161
162 assignableTexture = texture;
163 instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
164 REPORTER_ASSERT(reporter, instantiateSuccess);
165 REPORTER_ASSERT(reporter, textureProxy->isInstantiated());
166 REPORTER_ASSERT(reporter, textureProxy->isFullyLazy());
167 REPORTER_ASSERT(reporter, textureProxy->dimensions() == kValidSize);
168
169 textureProxy->deinstantiate();
170 REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
171 REPORTER_ASSERT(reporter, textureProxy->isFullyLazy());
172
173 constexpr SkISize kLargerSize = SkISize::Make(2, 2);
174 BackendTexture largerBackendTexture =
175 recorder->createBackendTexture(kLargerSize, textureInfo);
176 assignableTexture = resourceProvider->createWrappedTexture(largerBackendTexture);
177 instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
178 REPORTER_ASSERT(reporter, instantiateSuccess);
179 REPORTER_ASSERT(reporter, textureProxy->dimensions() == kLargerSize);
180
181 // InstantiateIfNotLazy tests.
182 textureProxy = makeProxy(kValidSize,
183 kValidColorType,
184 Mipmapped::kNo,
185 isProtected,
186 Renderable::kNo,
188 instantiateSuccess = TextureProxy::InstantiateIfNotLazy(resourceProvider, textureProxy.get());
189 REPORTER_ASSERT(reporter, instantiateSuccess);
190
191 textureProxy = TextureProxy::MakeLazy(
192 caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kNo, nullCallback);
193 instantiateSuccess = TextureProxy::InstantiateIfNotLazy(resourceProvider, textureProxy.get());
194 REPORTER_ASSERT(reporter, instantiateSuccess);
195 // Clean up the backend textures.
196 recorder->deleteBackendTexture(backendTexture);
197 recorder->deleteBackendTexture(largerBackendTexture);
198}
199
200DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphiteTextureTooLargeTest, reporter, context,
202 std::unique_ptr<Recorder> recorder = context->makeRecorder();
203 const Caps* caps = context->priv().caps();
204
205 // Try to create a texture that is too large for the backend.
207 SkISize dimensions = SkISize::Make(caps->maxTextureSize() + 1, 1);
208 bitmap.allocPixels(SkImageInfo::Make(
211 sk_sp<SkImage> graphiteImage =
212 SkImages::TextureFromImage(recorder.get(), rasterImage.get(), /*requiredProps=*/{});
213
214 // Image creation should have failed.
215 REPORTER_ASSERT(reporter, !graphiteImage);
216
217 // Snapping should still succeed, no texture upload should actually be attempted.
218 REPORTER_ASSERT(reporter, recorder->snap());
219}
220
221DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphiteLazyTextureInvalidDimensions, reporter, context,
223 class FulfillContext {
224 public:
225 FulfillContext(BackendTexture backendTexture) : fBackendTexture(backendTexture) {}
226
227 static std::tuple<BackendTexture, void*> Fulfill(void* ctx) {
228 FulfillContext* self = reinterpret_cast<FulfillContext*>(ctx);
229 return {self->fBackendTexture, nullptr};
230 }
231
232 BackendTexture fBackendTexture;
233 };
234
235 std::unique_ptr<Recorder> recorder = context->makeRecorder();
236 const Caps* caps = context->priv().caps();
237
238 // Try to create textures with invalid dimensions.
239 SkISize largeDimensions = SkISize::Make(caps->maxTextureSize() + 1, 1);
240 SkISize negativeDimensions = SkISize::Make(-1, -1);
241
242 for (const SkISize& dimensions : {largeDimensions, negativeDimensions}) {
243 SkImageInfo imageInfo = SkImageInfo::Make(
245 TextureInfo textureInfo = caps->getDefaultSampledTextureInfo(
246 imageInfo.colorInfo().colorType(), Mipmapped::kNo, Protected::kNo, Renderable::kNo);
247
248 // The created BackendTexture should be invalid, so an invalid texture would be used to
249 // fulfill the promise image created later, if we were to attempt to draw it.
250 BackendTexture backendTexture =
251 recorder->createBackendTexture(imageInfo.dimensions(), textureInfo);
252 FulfillContext fulfillContext(backendTexture);
253 REPORTER_ASSERT(reporter, !backendTexture.isValid());
254
255 // Drawing should still succeed, as no image draw should actually be attempted with this
256 // texture.
257 SkImageInfo surfaceImageInfo = SkImageInfo::Make(
259 sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(recorder.get(), surfaceImageInfo);
260 sk_sp<SkImage> promiseImage = SkImages::PromiseTextureFrom(recorder.get(),
261 imageInfo.dimensions(),
262 textureInfo,
263 imageInfo.colorInfo(),
265 FulfillContext::Fulfill,
266 nullptr,
267 nullptr,
268 &fulfillContext);
269
270 surface->getCanvas()->drawImage(promiseImage, 0.0f, 0.0f);
271 std::unique_ptr<Recording> recording = recorder->snap();
272 REPORTER_ASSERT(reporter, context->insertRecording({recording.get()}));
273 // Clean up backend texture
274 context->deleteBackendTexture(fulfillContext.fBackendTexture);
275 }
276}
277
278} // namespace skgpu::graphite
reporter
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
SkColorType
Definition SkColorType.h:19
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
@ kUnknown_SkColorType
uninitialized
Definition SkColorType.h:20
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
#define DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(name, reporter, graphite_ctx, ctsEnforcement)
Definition Test.h:373
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
SkColorType colorType() const
T * get() const
Definition SkRefCnt.h:303
bool protectedSupport() const
Definition Caps.h:219
virtual TextureInfo getDefaultSampledTextureInfo(SkColorType, Mipmapped mipmapped, Protected, Renderable) const =0
int maxTextureSize() const
Definition Caps.h:134
virtual sk_sp< Texture > createWrappedTexture(const BackendTexture &)=0
static bool InstantiateIfNotLazy(ResourceProvider *, TextureProxy *)
static sk_sp< TextureProxy > Make(const Caps *, ResourceProvider *, SkISize dimensions, const TextureInfo &, skgpu::Budgeted)
static sk_sp< TextureProxy > MakeFullyLazy(const TextureInfo &, skgpu::Budgeted, Volatile, LazyInstantiateCallback &&)
static sk_sp< TextureProxy > MakeLazy(const Caps *, SkISize dimensions, const TextureInfo &, skgpu::Budgeted, Volatile, LazyInstantiateCallback &&)
VkSurfaceKHR surface
Definition main.cc:49
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
FlTexture * texture
SK_API sk_sp< SkImage > TextureFromImage(GrDirectContext *, const SkImage *, skgpu::Mipmapped=skgpu::Mipmapped::kNo, skgpu::Budgeted=skgpu::Budgeted::kYes)
SK_API sk_sp< SkImage > RasterFromBitmap(const SkBitmap &bitmap)
SK_API sk_sp< SkImage > PromiseTextureFrom(skgpu::graphite::Recorder *, SkISize dimensions, const skgpu::graphite::TextureInfo &, const SkColorInfo &, skgpu::Origin origin, skgpu::graphite::Volatile, GraphitePromiseTextureFulfillProc, GraphitePromiseImageReleaseProc, GraphitePromiseTextureReleaseProc, GraphitePromiseImageContext)
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
Budgeted
Definition GpuTypes.h:35
Renderable
Definition GpuTypes.h:69
Mipmapped
Definition GpuTypes.h:53
Protected
Definition GpuTypes.h:61
static constexpr SkISize MakeEmpty()
Definition SkSize.h:22
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
const SkColorInfo & colorInfo() const
SkISize dimensions() const
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)