1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2022 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/BackendTexture.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Context.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Image.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Recorder.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/Surface.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Caps.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ContextPriv.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RecorderPriv.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ResourceProvider.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Texture.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/TextureProxy.h"
24*c8dee2aaSAndroid Build Coastguard Worker
25*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
26*c8dee2aaSAndroid Build Coastguard Worker
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphiteTextureProxyTest,reporter,context,CtsEnforcement::kApiLevel_V)27*c8dee2aaSAndroid Build Coastguard Worker DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphiteTextureProxyTest, reporter, context,
28*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_V) {
29*c8dee2aaSAndroid Build Coastguard Worker const Caps* caps = context->priv().caps();
30*c8dee2aaSAndroid Build Coastguard Worker constexpr SkISize kValidSize = SkISize::Make(1, 1);
31*c8dee2aaSAndroid Build Coastguard Worker constexpr SkISize kInvalidSize = SkISize::MakeEmpty();
32*c8dee2aaSAndroid Build Coastguard Worker constexpr SkColorType kValidColorType = kRGBA_8888_SkColorType;
33*c8dee2aaSAndroid Build Coastguard Worker constexpr SkColorType kInvalidColorType = kUnknown_SkColorType;
34*c8dee2aaSAndroid Build Coastguard Worker
35*c8dee2aaSAndroid Build Coastguard Worker Protected isProtected = Protected(caps->protectedSupport());
36*c8dee2aaSAndroid Build Coastguard Worker
37*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Recorder> recorder = context->makeRecorder();
38*c8dee2aaSAndroid Build Coastguard Worker ResourceProvider* resourceProvider = recorder->priv().resourceProvider();
39*c8dee2aaSAndroid Build Coastguard Worker const TextureInfo textureInfo = caps->getDefaultSampledTextureInfo(
40*c8dee2aaSAndroid Build Coastguard Worker kValidColorType, Mipmapped::kNo, isProtected, Renderable::kNo);
41*c8dee2aaSAndroid Build Coastguard Worker BackendTexture backendTexture = recorder->createBackendTexture(kValidSize, textureInfo);
42*c8dee2aaSAndroid Build Coastguard Worker sk_sp<Texture> texture = resourceProvider->createWrappedTexture(backendTexture,
43*c8dee2aaSAndroid Build Coastguard Worker "TextureProxyTestWrappedTex");
44*c8dee2aaSAndroid Build Coastguard Worker
45*c8dee2aaSAndroid Build Coastguard Worker auto makeProxy = [&](SkISize dimensions, SkColorType colorType, Mipmapped mipmapped,
46*c8dee2aaSAndroid Build Coastguard Worker Protected isProtected, Renderable renderable, Budgeted budgeted) {
47*c8dee2aaSAndroid Build Coastguard Worker auto textureInfo = caps->getDefaultSampledTextureInfo(colorType, mipmapped,
48*c8dee2aaSAndroid Build Coastguard Worker isProtected, renderable);
49*c8dee2aaSAndroid Build Coastguard Worker return TextureProxy::Make(caps, recorder->priv().resourceProvider(),
50*c8dee2aaSAndroid Build Coastguard Worker dimensions, textureInfo, "TextureProxyTestTexture", budgeted);
51*c8dee2aaSAndroid Build Coastguard Worker };
52*c8dee2aaSAndroid Build Coastguard Worker
53*c8dee2aaSAndroid Build Coastguard Worker auto nullCallback = [](ResourceProvider*) -> sk_sp<Texture> { return nullptr; };
54*c8dee2aaSAndroid Build Coastguard Worker auto callback = [texture](ResourceProvider*) -> sk_sp<Texture> { return texture; };
55*c8dee2aaSAndroid Build Coastguard Worker
56*c8dee2aaSAndroid Build Coastguard Worker // Assign to assignableTexture before instantiating with this callback.
57*c8dee2aaSAndroid Build Coastguard Worker sk_sp<Texture> assignableTexture;
58*c8dee2aaSAndroid Build Coastguard Worker auto assignableCallback = [&assignableTexture](ResourceProvider*) -> sk_sp<Texture> {
59*c8dee2aaSAndroid Build Coastguard Worker return assignableTexture;
60*c8dee2aaSAndroid Build Coastguard Worker };
61*c8dee2aaSAndroid Build Coastguard Worker
62*c8dee2aaSAndroid Build Coastguard Worker // Invalid parameters.
63*c8dee2aaSAndroid Build Coastguard Worker sk_sp<TextureProxy> textureProxy;
64*c8dee2aaSAndroid Build Coastguard Worker textureProxy = makeProxy(kInvalidSize,
65*c8dee2aaSAndroid Build Coastguard Worker kValidColorType,
66*c8dee2aaSAndroid Build Coastguard Worker Mipmapped::kNo,
67*c8dee2aaSAndroid Build Coastguard Worker isProtected,
68*c8dee2aaSAndroid Build Coastguard Worker Renderable::kNo,
69*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted::kNo);
70*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy == nullptr);
71*c8dee2aaSAndroid Build Coastguard Worker textureProxy = makeProxy(kValidSize,
72*c8dee2aaSAndroid Build Coastguard Worker kInvalidColorType,
73*c8dee2aaSAndroid Build Coastguard Worker Mipmapped::kNo,
74*c8dee2aaSAndroid Build Coastguard Worker isProtected,
75*c8dee2aaSAndroid Build Coastguard Worker Renderable::kNo,
76*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted::kNo);
77*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy == nullptr);
78*c8dee2aaSAndroid Build Coastguard Worker
79*c8dee2aaSAndroid Build Coastguard Worker // Non-budgeted, non-lazy TextureProxy is instantiated on return
80*c8dee2aaSAndroid Build Coastguard Worker textureProxy = makeProxy(kValidSize,
81*c8dee2aaSAndroid Build Coastguard Worker kValidColorType,
82*c8dee2aaSAndroid Build Coastguard Worker Mipmapped::kNo,
83*c8dee2aaSAndroid Build Coastguard Worker isProtected,
84*c8dee2aaSAndroid Build Coastguard Worker Renderable::kNo,
85*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted::kNo);
86*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isLazy());
87*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isFullyLazy());
88*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isVolatile());
89*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->isInstantiated());
90*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->dimensions() == kValidSize);
91*c8dee2aaSAndroid Build Coastguard Worker
92*c8dee2aaSAndroid Build Coastguard Worker // Budgeted, non-lazy TextureProxy, successful instantiation later on
93*c8dee2aaSAndroid Build Coastguard Worker textureProxy = makeProxy(kValidSize,
94*c8dee2aaSAndroid Build Coastguard Worker kValidColorType,
95*c8dee2aaSAndroid Build Coastguard Worker Mipmapped::kNo,
96*c8dee2aaSAndroid Build Coastguard Worker isProtected,
97*c8dee2aaSAndroid Build Coastguard Worker Renderable::kNo,
98*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted::kYes);
99*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isLazy());
100*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isFullyLazy());
101*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isVolatile());
102*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
103*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->dimensions() == kValidSize);
104*c8dee2aaSAndroid Build Coastguard Worker
105*c8dee2aaSAndroid Build Coastguard Worker bool instantiateSuccess = textureProxy->instantiate(resourceProvider);
106*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, instantiateSuccess);
107*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->isInstantiated());
108*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->dimensions() == kValidSize);
109*c8dee2aaSAndroid Build Coastguard Worker const Texture* createdTexture = textureProxy->texture();
110*c8dee2aaSAndroid Build Coastguard Worker
111*c8dee2aaSAndroid Build Coastguard Worker instantiateSuccess = textureProxy->instantiate(resourceProvider);
112*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, instantiateSuccess);
113*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->texture() == createdTexture);
114*c8dee2aaSAndroid Build Coastguard Worker
115*c8dee2aaSAndroid Build Coastguard Worker // Lazy, non-volatile TextureProxy, unsuccessful instantiation.
116*c8dee2aaSAndroid Build Coastguard Worker textureProxy = TextureProxy::MakeLazy(
117*c8dee2aaSAndroid Build Coastguard Worker caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kNo, nullCallback);
118*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->isLazy());
119*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isFullyLazy());
120*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isVolatile());
121*c8dee2aaSAndroid Build Coastguard Worker
122*c8dee2aaSAndroid Build Coastguard Worker instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
123*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !instantiateSuccess);
124*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
125*c8dee2aaSAndroid Build Coastguard Worker
126*c8dee2aaSAndroid Build Coastguard Worker // Lazy, non-volatile TextureProxy, successful instantiation.
127*c8dee2aaSAndroid Build Coastguard Worker textureProxy = TextureProxy::MakeLazy(
128*c8dee2aaSAndroid Build Coastguard Worker caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kNo, callback);
129*c8dee2aaSAndroid Build Coastguard Worker
130*c8dee2aaSAndroid Build Coastguard Worker instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
131*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, instantiateSuccess);
132*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->texture() == texture.get());
133*c8dee2aaSAndroid Build Coastguard Worker
134*c8dee2aaSAndroid Build Coastguard Worker // Lazy, volatile TextureProxy, unsuccessful instantiation.
135*c8dee2aaSAndroid Build Coastguard Worker textureProxy = TextureProxy::MakeLazy(
136*c8dee2aaSAndroid Build Coastguard Worker caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kYes, nullCallback);
137*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->isLazy());
138*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isFullyLazy());
139*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->isVolatile());
140*c8dee2aaSAndroid Build Coastguard Worker
141*c8dee2aaSAndroid Build Coastguard Worker instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
142*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !instantiateSuccess);
143*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
144*c8dee2aaSAndroid Build Coastguard Worker
145*c8dee2aaSAndroid Build Coastguard Worker // Lazy, volatile TextureProxy, successful instantiation.
146*c8dee2aaSAndroid Build Coastguard Worker textureProxy = TextureProxy::MakeLazy(
147*c8dee2aaSAndroid Build Coastguard Worker caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kYes, callback);
148*c8dee2aaSAndroid Build Coastguard Worker
149*c8dee2aaSAndroid Build Coastguard Worker instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
150*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, instantiateSuccess);
151*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->texture() == texture.get());
152*c8dee2aaSAndroid Build Coastguard Worker
153*c8dee2aaSAndroid Build Coastguard Worker textureProxy->deinstantiate();
154*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
155*c8dee2aaSAndroid Build Coastguard Worker
156*c8dee2aaSAndroid Build Coastguard Worker // Fully-lazy TextureProxy.
157*c8dee2aaSAndroid Build Coastguard Worker textureProxy = TextureProxy::MakeFullyLazy(
158*c8dee2aaSAndroid Build Coastguard Worker textureInfo, skgpu::Budgeted::kNo, Volatile::kYes, assignableCallback);
159*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->isLazy());
160*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->isFullyLazy());
161*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->isVolatile());
162*c8dee2aaSAndroid Build Coastguard Worker
163*c8dee2aaSAndroid Build Coastguard Worker assignableTexture = texture;
164*c8dee2aaSAndroid Build Coastguard Worker instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
165*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, instantiateSuccess);
166*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->isInstantiated());
167*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->isFullyLazy());
168*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->dimensions() == kValidSize);
169*c8dee2aaSAndroid Build Coastguard Worker
170*c8dee2aaSAndroid Build Coastguard Worker textureProxy->deinstantiate();
171*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !textureProxy->isInstantiated());
172*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->isFullyLazy());
173*c8dee2aaSAndroid Build Coastguard Worker
174*c8dee2aaSAndroid Build Coastguard Worker constexpr SkISize kLargerSize = SkISize::Make(2, 2);
175*c8dee2aaSAndroid Build Coastguard Worker BackendTexture largerBackendTexture =
176*c8dee2aaSAndroid Build Coastguard Worker recorder->createBackendTexture(kLargerSize, textureInfo);
177*c8dee2aaSAndroid Build Coastguard Worker assignableTexture = resourceProvider->createWrappedTexture(largerBackendTexture,
178*c8dee2aaSAndroid Build Coastguard Worker "TextureProxyTestWrappedTex");
179*c8dee2aaSAndroid Build Coastguard Worker instantiateSuccess = textureProxy->lazyInstantiate(resourceProvider);
180*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, instantiateSuccess);
181*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, textureProxy->dimensions() == kLargerSize);
182*c8dee2aaSAndroid Build Coastguard Worker
183*c8dee2aaSAndroid Build Coastguard Worker // InstantiateIfNotLazy tests.
184*c8dee2aaSAndroid Build Coastguard Worker textureProxy = makeProxy(kValidSize,
185*c8dee2aaSAndroid Build Coastguard Worker kValidColorType,
186*c8dee2aaSAndroid Build Coastguard Worker Mipmapped::kNo,
187*c8dee2aaSAndroid Build Coastguard Worker isProtected,
188*c8dee2aaSAndroid Build Coastguard Worker Renderable::kNo,
189*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted::kYes);
190*c8dee2aaSAndroid Build Coastguard Worker instantiateSuccess = TextureProxy::InstantiateIfNotLazy(resourceProvider, textureProxy.get());
191*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, instantiateSuccess);
192*c8dee2aaSAndroid Build Coastguard Worker
193*c8dee2aaSAndroid Build Coastguard Worker textureProxy = TextureProxy::MakeLazy(
194*c8dee2aaSAndroid Build Coastguard Worker caps, kValidSize, textureInfo, skgpu::Budgeted::kNo, Volatile::kNo, nullCallback);
195*c8dee2aaSAndroid Build Coastguard Worker instantiateSuccess = TextureProxy::InstantiateIfNotLazy(resourceProvider, textureProxy.get());
196*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, instantiateSuccess);
197*c8dee2aaSAndroid Build Coastguard Worker // Clean up the backend textures.
198*c8dee2aaSAndroid Build Coastguard Worker recorder->deleteBackendTexture(backendTexture);
199*c8dee2aaSAndroid Build Coastguard Worker recorder->deleteBackendTexture(largerBackendTexture);
200*c8dee2aaSAndroid Build Coastguard Worker }
201*c8dee2aaSAndroid Build Coastguard Worker
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphiteTextureTooLargeTest,reporter,context,CtsEnforcement::kApiLevel_V)202*c8dee2aaSAndroid Build Coastguard Worker DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphiteTextureTooLargeTest, reporter, context,
203*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_V) {
204*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Recorder> recorder = context->makeRecorder();
205*c8dee2aaSAndroid Build Coastguard Worker const Caps* caps = context->priv().caps();
206*c8dee2aaSAndroid Build Coastguard Worker
207*c8dee2aaSAndroid Build Coastguard Worker // Try to create a texture that is too large for the backend.
208*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bitmap;
209*c8dee2aaSAndroid Build Coastguard Worker SkISize dimensions = SkISize::Make(caps->maxTextureSize() + 1, 1);
210*c8dee2aaSAndroid Build Coastguard Worker bitmap.allocPixels(SkImageInfo::Make(
211*c8dee2aaSAndroid Build Coastguard Worker dimensions, SkColorType::kRGBA_8888_SkColorType, SkAlphaType::kPremul_SkAlphaType));
212*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> rasterImage = SkImages::RasterFromBitmap(bitmap);
213*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> graphiteImage =
214*c8dee2aaSAndroid Build Coastguard Worker SkImages::TextureFromImage(recorder.get(), rasterImage.get(), /*requiredProps=*/{});
215*c8dee2aaSAndroid Build Coastguard Worker
216*c8dee2aaSAndroid Build Coastguard Worker // Image creation should have failed.
217*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !graphiteImage);
218*c8dee2aaSAndroid Build Coastguard Worker
219*c8dee2aaSAndroid Build Coastguard Worker // Snapping should still succeed, no texture upload should actually be attempted.
220*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, recorder->snap());
221*c8dee2aaSAndroid Build Coastguard Worker }
222*c8dee2aaSAndroid Build Coastguard Worker
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphiteLazyTextureInvalidDimensions,reporter,context,CtsEnforcement::kApiLevel_V)223*c8dee2aaSAndroid Build Coastguard Worker DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(GraphiteLazyTextureInvalidDimensions, reporter, context,
224*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_V) {
225*c8dee2aaSAndroid Build Coastguard Worker class FulfillContext {
226*c8dee2aaSAndroid Build Coastguard Worker public:
227*c8dee2aaSAndroid Build Coastguard Worker FulfillContext(BackendTexture backendTexture) : fBackendTexture(backendTexture) {}
228*c8dee2aaSAndroid Build Coastguard Worker
229*c8dee2aaSAndroid Build Coastguard Worker static std::tuple<BackendTexture, void*> Fulfill(void* ctx) {
230*c8dee2aaSAndroid Build Coastguard Worker FulfillContext* self = reinterpret_cast<FulfillContext*>(ctx);
231*c8dee2aaSAndroid Build Coastguard Worker return {self->fBackendTexture, nullptr};
232*c8dee2aaSAndroid Build Coastguard Worker }
233*c8dee2aaSAndroid Build Coastguard Worker
234*c8dee2aaSAndroid Build Coastguard Worker BackendTexture fBackendTexture;
235*c8dee2aaSAndroid Build Coastguard Worker };
236*c8dee2aaSAndroid Build Coastguard Worker
237*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Recorder> recorder = context->makeRecorder();
238*c8dee2aaSAndroid Build Coastguard Worker const Caps* caps = context->priv().caps();
239*c8dee2aaSAndroid Build Coastguard Worker
240*c8dee2aaSAndroid Build Coastguard Worker // Try to create textures with invalid dimensions.
241*c8dee2aaSAndroid Build Coastguard Worker SkISize largeDimensions = SkISize::Make(caps->maxTextureSize() + 1, 1);
242*c8dee2aaSAndroid Build Coastguard Worker SkISize negativeDimensions = SkISize::Make(-1, -1);
243*c8dee2aaSAndroid Build Coastguard Worker
244*c8dee2aaSAndroid Build Coastguard Worker for (const SkISize& dimensions : {largeDimensions, negativeDimensions}) {
245*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo imageInfo = SkImageInfo::Make(
246*c8dee2aaSAndroid Build Coastguard Worker dimensions, SkColorType::kRGBA_8888_SkColorType, SkAlphaType::kPremul_SkAlphaType);
247*c8dee2aaSAndroid Build Coastguard Worker TextureInfo textureInfo = caps->getDefaultSampledTextureInfo(
248*c8dee2aaSAndroid Build Coastguard Worker imageInfo.colorInfo().colorType(), Mipmapped::kNo, Protected::kNo, Renderable::kNo);
249*c8dee2aaSAndroid Build Coastguard Worker
250*c8dee2aaSAndroid Build Coastguard Worker // The created BackendTexture should be invalid, so an invalid texture would be used to
251*c8dee2aaSAndroid Build Coastguard Worker // fulfill the promise image created later, if we were to attempt to draw it.
252*c8dee2aaSAndroid Build Coastguard Worker BackendTexture backendTexture =
253*c8dee2aaSAndroid Build Coastguard Worker recorder->createBackendTexture(imageInfo.dimensions(), textureInfo);
254*c8dee2aaSAndroid Build Coastguard Worker FulfillContext fulfillContext(backendTexture);
255*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, !backendTexture.isValid());
256*c8dee2aaSAndroid Build Coastguard Worker
257*c8dee2aaSAndroid Build Coastguard Worker // Drawing should still succeed, as no image draw should actually be attempted with this
258*c8dee2aaSAndroid Build Coastguard Worker // texture.
259*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo surfaceImageInfo = SkImageInfo::Make(
260*c8dee2aaSAndroid Build Coastguard Worker 1, 1, SkColorType::kRGBA_8888_SkColorType, SkAlphaType::kPremul_SkAlphaType);
261*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(recorder.get(), surfaceImageInfo);
262*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkImage> promiseImage = SkImages::PromiseTextureFrom(recorder.get(),
263*c8dee2aaSAndroid Build Coastguard Worker imageInfo.dimensions(),
264*c8dee2aaSAndroid Build Coastguard Worker textureInfo,
265*c8dee2aaSAndroid Build Coastguard Worker imageInfo.colorInfo(),
266*c8dee2aaSAndroid Build Coastguard Worker Volatile::kNo,
267*c8dee2aaSAndroid Build Coastguard Worker FulfillContext::Fulfill,
268*c8dee2aaSAndroid Build Coastguard Worker nullptr,
269*c8dee2aaSAndroid Build Coastguard Worker nullptr,
270*c8dee2aaSAndroid Build Coastguard Worker &fulfillContext);
271*c8dee2aaSAndroid Build Coastguard Worker
272*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->drawImage(promiseImage, 0.0f, 0.0f);
273*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<Recording> recording = recorder->snap();
274*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, context->insertRecording({recording.get()}));
275*c8dee2aaSAndroid Build Coastguard Worker // Clean up backend texture
276*c8dee2aaSAndroid Build Coastguard Worker context->deleteBackendTexture(fulfillContext.fBackendTexture);
277*c8dee2aaSAndroid Build Coastguard Worker }
278*c8dee2aaSAndroid Build Coastguard Worker }
279*c8dee2aaSAndroid Build Coastguard Worker
280*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite
281