Flutter Engine
The Flutter Engine
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 "TextureProxyTestWrappedTex");
44
45 auto makeProxy = [&](SkISize dimensions, SkColorType colorType, Mipmapped mipmapped,
46 Protected isProtected, Renderable renderable, Budgeted budgeted) {
47 auto textureInfo = caps->getDefaultSampledTextureInfo(colorType, mipmapped,
48 isProtected, renderable);
49 return TextureProxy::Make(caps, recorder->priv().resourceProvider(),
50 dimensions, textureInfo, "TextureProxyTestTexture", budgeted);
51 };
52
53 auto nullCallback = [](ResourceProvider*) -> sk_sp<Texture> { return nullptr; };
54 auto callback = [texture](ResourceProvider*) -> sk_sp<Texture> { return texture; };
55
56 // Assign to assignableTexture before instantiating with this callback.
57 sk_sp<Texture> assignableTexture;
58 auto assignableCallback = [&assignableTexture](ResourceProvider*) -> sk_sp<Texture> {
59 return assignableTexture;
60 };
61
62 // Invalid parameters.
63 sk_sp<TextureProxy> textureProxy;
64 textureProxy = makeProxy(kInvalidSize,
65 kValidColorType,
67 isProtected,
70 REPORTER_ASSERT(reporter, textureProxy == nullptr);
71 textureProxy = makeProxy(kValidSize,
72 kInvalidColorType,
74 isProtected,
77 REPORTER_ASSERT(reporter, textureProxy == nullptr);
78
79 // Non-budgeted, non-lazy TextureProxy is instantiated on return
80 textureProxy = makeProxy(kValidSize,
81 kValidColorType,
83 isProtected,
86 REPORTER_ASSERT(reporter, !textureProxy->isLazy());
87 REPORTER_ASSERT(reporter, !textureProxy->isFullyLazy());
88 REPORTER_ASSERT(reporter, !textureProxy->isVolatile());
89 REPORTER_ASSERT(reporter, textureProxy->isInstantiated());
90 REPORTER_ASSERT(reporter, textureProxy->dimensions() == kValidSize);
91
92 // Budgeted, non-lazy TextureProxy, successful instantiation later on
93 textureProxy = makeProxy(kValidSize,
94 kValidColorType,
96 isProtected,
99 REPORTER_ASSERT(reporter, !textureProxy->isLazy());
100 REPORTER_ASSERT(reporter, !textureProxy->isFullyLazy());
101 REPORTER_ASSERT(reporter, !textureProxy->isVolatile());
102 REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
103 REPORTER_ASSERT(reporter, textureProxy->dimensions() == kValidSize);
104
105 bool instantiateSuccess = textureProxy->instantiate(resourceProvider);
106 REPORTER_ASSERT(reporter, instantiateSuccess);
107 REPORTER_ASSERT(reporter, textureProxy->isInstantiated());
108 REPORTER_ASSERT(reporter, textureProxy->dimensions() == kValidSize);
109 const Texture* createdTexture = textureProxy->texture();
110
111 instantiateSuccess = textureProxy->instantiate(resourceProvider);
112 REPORTER_ASSERT(reporter, instantiateSuccess);
113 REPORTER_ASSERT(reporter, textureProxy->texture() == createdTexture);
114
115 // Lazy, non-volatile TextureProxy, unsuccessful instantiation.
116 textureProxy = TextureProxy::MakeLazy(
117 caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kNo, nullCallback);
118 REPORTER_ASSERT(reporter, textureProxy->isLazy());
119 REPORTER_ASSERT(reporter, !textureProxy->isFullyLazy());
120 REPORTER_ASSERT(reporter, !textureProxy->isVolatile());
121
122 instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
123 REPORTER_ASSERT(reporter, !instantiateSuccess);
124 REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
125
126 // Lazy, non-volatile TextureProxy, successful instantiation.
127 textureProxy = TextureProxy::MakeLazy(
128 caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kNo, callback);
129
130 instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
131 REPORTER_ASSERT(reporter, instantiateSuccess);
132 REPORTER_ASSERT(reporter, textureProxy->texture() == texture.get());
133
134 // Lazy, volatile TextureProxy, unsuccessful instantiation.
135 textureProxy = TextureProxy::MakeLazy(
136 caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kYes, nullCallback);
137 REPORTER_ASSERT(reporter, textureProxy->isLazy());
138 REPORTER_ASSERT(reporter, !textureProxy->isFullyLazy());
139 REPORTER_ASSERT(reporter, textureProxy->isVolatile());
140
141 instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
142 REPORTER_ASSERT(reporter, !instantiateSuccess);
143 REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
144
145 // Lazy, volatile TextureProxy, successful instantiation.
146 textureProxy = TextureProxy::MakeLazy(
147 caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kYes, callback);
148
149 instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
150 REPORTER_ASSERT(reporter, instantiateSuccess);
151 REPORTER_ASSERT(reporter, textureProxy->texture() == texture.get());
152
153 textureProxy->deinstantiate();
154 REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
155
156 // Fully-lazy TextureProxy.
157 textureProxy = TextureProxy::MakeFullyLazy(
158 textureInfo, skgpu::Budgeted::kNo, Volatile::kYes, assignableCallback);
159 REPORTER_ASSERT(reporter, textureProxy->isLazy());
160 REPORTER_ASSERT(reporter, textureProxy->isFullyLazy());
161 REPORTER_ASSERT(reporter, textureProxy->isVolatile());
162
163 assignableTexture = texture;
164 instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
165 REPORTER_ASSERT(reporter, instantiateSuccess);
166 REPORTER_ASSERT(reporter, textureProxy->isInstantiated());
167 REPORTER_ASSERT(reporter, textureProxy->isFullyLazy());
168 REPORTER_ASSERT(reporter, textureProxy->dimensions() == kValidSize);
169
170 textureProxy->deinstantiate();
171 REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
172 REPORTER_ASSERT(reporter, textureProxy->isFullyLazy());
173
174 constexpr SkISize kLargerSize = SkISize::Make(2, 2);
175 BackendTexture largerBackendTexture =
176 recorder->createBackendTexture(kLargerSize, textureInfo);
177 assignableTexture = resourceProvider->createWrappedTexture(largerBackendTexture,
178 "TextureProxyTestWrappedTex");
179 instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
180 REPORTER_ASSERT(reporter, instantiateSuccess);
181 REPORTER_ASSERT(reporter, textureProxy->dimensions() == kLargerSize);
182
183 // InstantiateIfNotLazy tests.
184 textureProxy = makeProxy(kValidSize,
185 kValidColorType,
187 isProtected,
190 instantiateSuccess = TextureProxy::InstantiateIfNotLazy(resourceProvider, textureProxy.get());
191 REPORTER_ASSERT(reporter, instantiateSuccess);
192
193 textureProxy = TextureProxy::MakeLazy(
194 caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kNo, nullCallback);
195 instantiateSuccess = TextureProxy::InstantiateIfNotLazy(resourceProvider, textureProxy.get());
196 REPORTER_ASSERT(reporter, instantiateSuccess);
197 // Clean up the backend textures.
198 recorder->deleteBackendTexture(backendTexture);
199 recorder->deleteBackendTexture(largerBackendTexture);
200}
201
202DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphiteTextureTooLargeTest, reporter, context,
204 std::unique_ptr<Recorder> recorder = context->makeRecorder();
205 const Caps* caps = context->priv().caps();
206
207 // Try to create a texture that is too large for the backend.
209 SkISize dimensions = SkISize::Make(caps->maxTextureSize() + 1, 1);
210 bitmap.allocPixels(SkImageInfo::Make(
213 sk_sp<SkImage> graphiteImage =
214 SkImages::TextureFromImage(recorder.get(), rasterImage.get(), /*requiredProps=*/{});
215
216 // Image creation should have failed.
217 REPORTER_ASSERT(reporter, !graphiteImage);
218
219 // Snapping should still succeed, no texture upload should actually be attempted.
220 REPORTER_ASSERT(reporter, recorder->snap());
221}
222
223DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphiteLazyTextureInvalidDimensions, reporter, context,
225 class FulfillContext {
226 public:
227 FulfillContext(BackendTexture backendTexture) : fBackendTexture(backendTexture) {}
228
229 static std::tuple<BackendTexture, void*> Fulfill(void* ctx) {
230 FulfillContext* self = reinterpret_cast<FulfillContext*>(ctx);
231 return {self->fBackendTexture, nullptr};
232 }
233
234 BackendTexture fBackendTexture;
235 };
236
237 std::unique_ptr<Recorder> recorder = context->makeRecorder();
238 const Caps* caps = context->priv().caps();
239
240 // Try to create textures with invalid dimensions.
241 SkISize largeDimensions = SkISize::Make(caps->maxTextureSize() + 1, 1);
242 SkISize negativeDimensions = SkISize::Make(-1, -1);
243
244 for (const SkISize& dimensions : {largeDimensions, negativeDimensions}) {
245 SkImageInfo imageInfo = SkImageInfo::Make(
247 TextureInfo textureInfo = caps->getDefaultSampledTextureInfo(
249
250 // The created BackendTexture should be invalid, so an invalid texture would be used to
251 // fulfill the promise image created later, if we were to attempt to draw it.
252 BackendTexture backendTexture =
253 recorder->createBackendTexture(imageInfo.dimensions(), textureInfo);
254 FulfillContext fulfillContext(backendTexture);
255 REPORTER_ASSERT(reporter, !backendTexture.isValid());
256
257 // Drawing should still succeed, as no image draw should actually be attempted with this
258 // texture.
259 SkImageInfo surfaceImageInfo = SkImageInfo::Make(
261 sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(recorder.get(), surfaceImageInfo);
262 sk_sp<SkImage> promiseImage = SkImages::PromiseTextureFrom(recorder.get(),
263 imageInfo.dimensions(),
264 textureInfo,
265 imageInfo.colorInfo(),
267 FulfillContext::Fulfill,
268 nullptr,
269 nullptr,
270 &fulfillContext);
271
272 surface->getCanvas()->drawImage(promiseImage, 0.0f, 0.0f);
273 std::unique_ptr<Recording> recording = recorder->snap();
274 REPORTER_ASSERT(reporter, context->insertRecording({recording.get()}));
275 // Clean up backend texture
276 context->deleteBackendTexture(fulfillContext.fBackendTexture);
277 }
278}
279
280} // namespace skgpu::graphite
reporter
Definition: FontMgrTest.cpp:39
@ 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 REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
SkColorType colorType() const
Definition: SkImageInfo.h:140
T * get() const
Definition: SkRefCnt.h:303
bool protectedSupport() const
Definition: Caps.h:226
virtual TextureInfo getDefaultSampledTextureInfo(SkColorType, Mipmapped mipmapped, Protected, Renderable) const =0
int maxTextureSize() const
Definition: Caps.h:141
sk_sp< Texture > createWrappedTexture(const BackendTexture &, std::string_view label)
static bool InstantiateIfNotLazy(ResourceProvider *, TextureProxy *)
static sk_sp< TextureProxy > Make(const Caps *, ResourceProvider *, SkISize dimensions, const TextureInfo &, std::string_view label, 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 > PromiseTextureFrom(skgpu::graphite::Recorder *, SkISize dimensions, const skgpu::graphite::TextureInfo &, const SkColorInfo &, skgpu::Origin origin, skgpu::graphite::Volatile, GraphitePromiseTextureFulfillProc, GraphitePromiseImageReleaseProc, GraphitePromiseTextureReleaseProc, GraphitePromiseImageContext, std::string_view label={})
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< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
Definition: bitmap.py:1
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(DeviceTestVertexTransparency, reporter, context, CtsEnforcement::kNextRelease)
Definition: DeviceTest.cpp:21
Budgeted
Definition: GpuTypes.h:35
Renderable
Definition: GpuTypes.h:69
Mipmapped
Definition: GpuTypes.h:53
Protected
Definition: GpuTypes.h:61
Definition: SkSize.h:16
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
Definition: SkImageInfo.h:404
SkISize dimensions() const
Definition: SkImageInfo.h:421
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)