Flutter Engine
The Flutter Engine
Classes | Enumerations | Functions
PromiseImageTest.cpp File Reference
#include "include/core/SkAlphaType.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkShader.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrTypes.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/private/base/SkTArray.h"
#include "include/private/chromium/GrDeferredDisplayListRecorder.h"
#include "include/private/chromium/GrPromiseImageTexture.h"
#include "include/private/chromium/SkImageChromium.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrResourceProvider.h"
#include "src/gpu/ganesh/GrTexture.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include "tools/gpu/ContextType.h"
#include "tools/gpu/FenceSync.h"
#include "tools/gpu/ManagedBackendTexture.h"
#include <cstddef>
#include <functional>
#include <utility>

Go to the source code of this file.

Classes

struct  PromiseTextureChecker
 

Enumerations

enum class  ReleaseBalanceExpectation {
  kBalanced , kAllUnbalanced , kUnknown , kUnbalancedByOne ,
  kBalancedOrOffByOne
}
 

Functions

static void check_fulfill_and_release_cnts (skiatest::Reporter *reporter, const PromiseTextureChecker &promiseChecker, int expectedFulfillCnt, ReleaseBalanceExpectation releaseBalanceExpecation)
 
static void check_unfulfilled (const PromiseTextureChecker &promiseChecker, skiatest::Reporter *reporter)
 
static void check_only_fulfilled (skiatest::Reporter *reporter, const PromiseTextureChecker &promiseChecker, int expectedFulfillCnt=1)
 
static void check_all_flushed_but_not_synced (skiatest::Reporter *reporter, const PromiseTextureChecker &promiseChecker, GrBackendApi api, int expectedFulfillCnt=1)
 
static void check_all_done (skiatest::Reporter *reporter, const PromiseTextureChecker &promiseChecker, int expectedFulfillCnt=1)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (PromiseImageTest, reporter, ctxInfo, CtsEnforcement::kNever)
 
 DEF_GANESH_TEST (PromiseImageTextureShutdown, reporter, ctxInfo, CtsEnforcement::kNever)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (PromiseImageTextureFullCache, reporter, ctxInfo, CtsEnforcement::kNever)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (PromiseImageNullFulfill, reporter, ctxInfo, CtsEnforcement::kNever)
 

Enumeration Type Documentation

◆ ReleaseBalanceExpectation

enum class ReleaseBalanceExpectation
strong
Enumerator
kBalanced 
kAllUnbalanced 
kUnknown 
kUnbalancedByOne 
kBalancedOrOffByOne 

Definition at line 74 of file PromiseImageTest.cpp.

Function Documentation

◆ check_all_done()

static void check_all_done ( skiatest::Reporter reporter,
const PromiseTextureChecker promiseChecker,
int  expectedFulfillCnt = 1 
)
static

Definition at line 141 of file PromiseImageTest.cpp.

143 {
144 check_fulfill_and_release_cnts(reporter, promiseChecker, expectedFulfillCnt,
146}
reporter
Definition: FontMgrTest.cpp:39
static void check_fulfill_and_release_cnts(skiatest::Reporter *reporter, const PromiseTextureChecker &promiseChecker, int expectedFulfillCnt, ReleaseBalanceExpectation releaseBalanceExpecation)

◆ check_all_flushed_but_not_synced()

static void check_all_flushed_but_not_synced ( skiatest::Reporter reporter,
const PromiseTextureChecker promiseChecker,
GrBackendApi  api,
int  expectedFulfillCnt = 1 
)
static

Definition at line 126 of file PromiseImageTest.cpp.

129 {
131 // On Vulkan and D3D Done isn't guaranteed to be called until a sync has occurred.
132 if (api == GrBackendApi::kVulkan || api == GrBackendApi::kDirect3D) {
133 releaseBalanceExpectation = expectedFulfillCnt == 1
136 }
137 check_fulfill_and_release_cnts(reporter, promiseChecker, expectedFulfillCnt,
138 releaseBalanceExpectation);
139}
ReleaseBalanceExpectation

◆ check_fulfill_and_release_cnts()

static void check_fulfill_and_release_cnts ( skiatest::Reporter reporter,
const PromiseTextureChecker promiseChecker,
int  expectedFulfillCnt,
ReleaseBalanceExpectation  releaseBalanceExpecation 
)
static

Definition at line 82 of file PromiseImageTest.cpp.

85 {
86 REPORTER_ASSERT(reporter, promiseChecker.fFulfillCount == expectedFulfillCnt);
87 if (!expectedFulfillCnt) {
88 // Release and Done should only ever be called after Fulfill.
89 REPORTER_ASSERT(reporter, !promiseChecker.fReleaseCount);
90 return;
91 }
92 int releaseDiff = promiseChecker.fFulfillCount - promiseChecker.fReleaseCount;
93 switch (releaseBalanceExpecation) {
95 REPORTER_ASSERT(reporter, !releaseDiff);
96 break;
98 REPORTER_ASSERT(reporter, releaseDiff == promiseChecker.fFulfillCount);
99 break;
102 releaseDiff >= 0 && releaseDiff <= promiseChecker.fFulfillCount);
103 break;
105 REPORTER_ASSERT(reporter, releaseDiff == 1);
106 break;
108 REPORTER_ASSERT(reporter, releaseDiff == 0 || releaseDiff == 1);
109 break;
110 }
111}
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286

◆ check_only_fulfilled()

static void check_only_fulfilled ( skiatest::Reporter reporter,
const PromiseTextureChecker promiseChecker,
int  expectedFulfillCnt = 1 
)
static

Definition at line 119 of file PromiseImageTest.cpp.

121 {
122 check_fulfill_and_release_cnts(reporter, promiseChecker, expectedFulfillCnt,
124}

◆ check_unfulfilled()

static void check_unfulfilled ( const PromiseTextureChecker promiseChecker,
skiatest::Reporter reporter 
)
static

Definition at line 113 of file PromiseImageTest.cpp.

◆ DEF_GANESH_TEST()

DEF_GANESH_TEST ( PromiseImageTextureShutdown  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kNever   
)

Definition at line 228 of file PromiseImageTest.cpp.

228 {
229 const int kWidth = 10;
230 const int kHeight = 10;
231
232 // Different ways of killing contexts.
234 DeathFn destroy = [](sk_gpu_test::GrContextFactory* factory, GrDirectContext*) {
235 factory->destroyContexts();
236 };
237 DeathFn abandon = [](sk_gpu_test::GrContextFactory* factory, GrDirectContext* dContext) {
238 dContext->abandonContext();
239 };
240 DeathFn releaseResourcesAndAbandon = [](sk_gpu_test::GrContextFactory* factory,
241 GrDirectContext* dContext) {
242 dContext->releaseResourcesAndAbandonContext();
243 };
244
245 for (int type = 0; type < skgpu::kContextTypeCount; ++type) {
246 auto contextType = static_cast<skgpu::ContextType>(type);
247 // These tests are difficult to get working with Vulkan. See http://skbug.com/8705
248 // and http://skbug.com/8275
249 // And Direct3D, for similar reasons.
253 continue;
254 }
255 DeathFn contextKillers[] = {destroy, abandon, releaseResourcesAndAbandon};
256 for (const DeathFn& contextDeath : contextKillers) {
258 auto ctx = factory.get(contextType);
259 if (!ctx) {
260 continue;
261 }
262
263 auto mbet = sk_gpu_test::ManagedBackendTexture::MakeWithoutData(ctx,
264 kWidth,
265 kHeight,
269 if (!mbet) {
270 ERRORF(reporter, "Could not create texture alpha texture.");
271 continue;
272 }
273
277 SkCanvas* canvas = surface->getCanvas();
278
279 PromiseTextureChecker promiseChecker(mbet->texture(), reporter, false);
281 mbet->texture().getBackendFormat(),
282 {kWidth, kHeight},
287 /*color space*/ nullptr,
288 PromiseTextureChecker::Fulfill,
289 PromiseTextureChecker::Release,
290 &promiseChecker));
292
293 canvas->drawImage(image, 0, 0);
294 image.reset();
295 // If the surface still holds a ref to the context then the factory will not be able
296 // to destroy the context (and instead will release-all-and-abandon).
297 surface.reset();
298
299 ctx->flushAndSubmit();
300 contextDeath(&factory, ctx);
301
302 check_all_done(reporter, promiseChecker);
303 }
304 }
305}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
@ kTopLeft_GrSurfaceOrigin
Definition: GrTypes.h:148
GrBackendApi
Definition: GrTypes.h:95
static void check_all_done(skiatest::Reporter *reporter, const PromiseTextureChecker &promiseChecker, int expectedFulfillCnt=1)
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition: SkColorType.h:21
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
#define ERRORF(r,...)
Definition: Test.h:293
GLenum type
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
GrDirectContext * get(ContextType type, ContextOverrides overrides=ContextOverrides::kNone)
void reset(T *ptr=nullptr)
Definition: SkRefCnt.h:310
VkSurfaceKHR surface
Definition: main.cc:49
Dart_NativeFunction function
Definition: fuchsia.cc:51
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_sp< const SkImage > image
Definition: SkRecords.h:269
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)
GrBackendApi ContextTypeBackend(skgpu::ContextType type)
Definition: ContextType.cpp:92
static const int kContextTypeCount
Definition: ContextType.h:42
ContextType
Definition: ContextType.h:19
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
constexpr size_t kHeight
constexpr size_t kWidth
int_closure destroy

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [1/3]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( PromiseImageNullFulfill  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kNever   
)

Definition at line 396 of file PromiseImageTest.cpp.

399 {
400 const int kWidth = 10;
401 const int kHeight = 10;
402
403 auto dContext = ctxInfo.directContext();
404
405 GrBackendFormat backendFormat =
406 dContext->defaultBackendFormat(kRGBA_8888_SkColorType, GrRenderable::kYes);
407 if (!backendFormat.isValid()) {
408 ERRORF(reporter, "No valid default kRGBA_8888 texture format.");
409 return;
410 }
411
412 struct Counts {
413 int fFulfillCount = 0;
414 int fReleaseCount = 0;
415 } counts;
416 auto fulfill = [](SkImages::PromiseImageTextureContext ctx) {
417 ++static_cast<Counts*>(ctx)->fFulfillCount;
419 };
420 auto release = [](SkImages::PromiseImageTextureContext ctx) {
421 ++static_cast<Counts*>(ctx)->fReleaseCount;
422 };
424 sk_sp<SkImage> refImg(SkImages::PromiseTextureFrom(dContext->threadSafeProxy(),
425 backendFormat,
426 {kWidth, kHeight},
428 texOrigin,
431 nullptr,
432 fulfill,
433 release,
434 &counts));
435
438 SkCanvas* canvas = surface->getCanvas();
439 // Draw the image a few different ways.
440 canvas->drawImage(refImg, 0, 0);
443 canvas->drawImage(refImg, 0, 0, SkSamplingOptions(), &paint);
444 auto shader = refImg->makeShader(SkSamplingOptions());
445 REPORTER_ASSERT(reporter, shader);
446 paint.setShader(std::move(shader));
447 canvas->drawRect(SkRect::MakeWH(1,1), paint);
448 paint.setShader(nullptr);
449 refImg.reset();
450 dContext->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
451 // We should only call each callback once and we should have made all the calls by this point.
452 REPORTER_ASSERT(reporter, counts.fFulfillCount == 1);
453 REPORTER_ASSERT(reporter, counts.fReleaseCount == 1);
454}
GrSurfaceOrigin
Definition: GrTypes.h:147
bool isValid() const
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
static sk_sp< SkColorFilter > LinearToSRGBGamma()
const Paint & paint
Definition: color_source.cc:38
void * PromiseImageTextureContext
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core counts
Definition: switches.h:239
SkSamplingOptions(SkFilterMode::kLinear))
static SkImageInfo MakeN32Premul(int width, int height)
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [2/3]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( PromiseImageTest  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kNever   
)

Definition at line 148 of file PromiseImageTest.cpp.

151 {
152 using namespace skgpu;
153 const int kWidth = 10;
154 const int kHeight = 10;
155
156 auto ctx = ctxInfo.directContext();
157
158 Protected isProtected = Protected(ctx->priv().caps()->supportsProtectedContent());
159
160 GrBackendTexture backendTex = ctx->createBackendTexture(kWidth,
161 kHeight,
166 isProtected);
167 REPORTER_ASSERT(reporter, backendTex.isValid());
168
169 GrBackendFormat backendFormat = backendTex.getBackendFormat();
170 REPORTER_ASSERT(reporter, backendFormat.isValid());
171
172 PromiseTextureChecker promiseChecker(backendTex, reporter, false);
174 sk_sp<SkImage> refImg(SkImages::PromiseTextureFrom(ctx->threadSafeProxy(),
175 backendFormat,
176 {kWidth, kHeight},
178 texOrigin,
181 nullptr,
182 PromiseTextureChecker::Fulfill,
183 PromiseTextureChecker::Release,
184 &promiseChecker));
185
188 SkCanvas* canvas = surface->getCanvas();
189
190 canvas->drawImage(refImg, 0, 0);
191 check_unfulfilled(promiseChecker, reporter);
192
193 ctx->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
194 // We still own the image so we should not have called Release or Done.
195 check_only_fulfilled(reporter, promiseChecker);
196
197 ctx->submit(GrSyncCpu::kYes);
198 check_only_fulfilled(reporter, promiseChecker);
199
200 canvas->drawImage(refImg, 0, 0);
201 canvas->drawImage(refImg, 0, 0);
202
203 ctx->flushAndSubmit(surface.get(), GrSyncCpu::kYes);
204
205 // Image should still be fulfilled from the first time we drew/flushed it.
206 check_only_fulfilled(reporter, promiseChecker);
207
208 canvas->drawImage(refImg, 0, 0);
209 ctx->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
210 check_only_fulfilled(reporter, promiseChecker);
211
212 canvas->drawImage(refImg, 0, 0);
213 refImg.reset();
214 // We no longer own the image but the last draw is still unflushed.
215 check_only_fulfilled(reporter, promiseChecker);
216
217 ctx->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
218 // Flushing should have called Release. Depending on the backend and timing it may have called
219 // done.
220 check_all_flushed_but_not_synced(reporter, promiseChecker, ctx->backend());
221 ctx->submit(GrSyncCpu::kYes);
222 // Now Done should definitely have been called.
223 check_all_done(reporter, promiseChecker);
224
225 ctx->deleteBackendTexture(backendTex);
226}
skgpu::Protected Protected
static void check_unfulfilled(const PromiseTextureChecker &promiseChecker, skiatest::Reporter *reporter)
static void check_only_fulfilled(skiatest::Reporter *reporter, const PromiseTextureChecker &promiseChecker, int expectedFulfillCnt=1)
static void check_all_flushed_but_not_synced(skiatest::Reporter *reporter, const PromiseTextureChecker &promiseChecker, GrBackendApi api, int expectedFulfillCnt=1)
GrBackendFormat getBackendFormat() const
bool isValid() const
constexpr SkColor4f kTransparent
Definition: SkColor.h:434
Definition: GpuTools.h:21
Protected
Definition: GpuTypes.h:61

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [3/3]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( PromiseImageTextureFullCache  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kNever   
)

Definition at line 307 of file PromiseImageTest.cpp.

310 {
311 using namespace skgpu;
312
313 const int kWidth = 10;
314 const int kHeight = 10;
315
316 auto dContext = ctxInfo.directContext();
317
318 Protected isProtected = Protected(dContext->priv().caps()->supportsProtectedContent());
319
320 GrBackendTexture backendTex = dContext->createBackendTexture(kWidth,
321 kHeight,
326 isProtected);
327 REPORTER_ASSERT(reporter, backendTex.isValid());
328
332 SkCanvas* canvas = surface->getCanvas();
333
334 PromiseTextureChecker promiseChecker(backendTex, reporter, false);
335 sk_sp<SkImage> image(SkImages::PromiseTextureFrom(dContext->threadSafeProxy(),
336 backendTex.getBackendFormat(),
337 {kWidth, kHeight},
342 nullptr,
343 PromiseTextureChecker::Fulfill,
344 PromiseTextureChecker::Release,
345 &promiseChecker));
347
348 // Make the cache full. This tests that we don't preemptively purge cached textures for
349 // fulfillment due to cache pressure.
350 static constexpr int kMaxBytes = 1;
351 dContext->setResourceCacheLimit(kMaxBytes);
352 TArray<sk_sp<GrTexture>> textures;
353 for (int i = 0; i < 5; ++i) {
354 auto format = dContext->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
356 textures.emplace_back(dContext->priv().resourceProvider()->createTexture(
357 {100, 100},
358 format,
361 1,
364 isProtected,
365 /*label=*/"PromiseImageTextureFullCacheTest"));
366 REPORTER_ASSERT(reporter, textures[i]);
367 }
368
369 size_t bytesUsed;
370
371 dContext->getResourceCacheUsage(nullptr, &bytesUsed);
372 REPORTER_ASSERT(reporter, bytesUsed > kMaxBytes);
373
374 // Relying on the asserts in the promiseImageChecker to ensure that fulfills and releases are
375 // properly ordered.
376 canvas->drawImage(image, 0, 0);
377 dContext->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
378 canvas->drawImage(image, 1, 0);
379 dContext->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
380 canvas->drawImage(image, 2, 0);
381 dContext->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
382 canvas->drawImage(image, 3, 0);
383 dContext->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
384 canvas->drawImage(image, 4, 0);
385 dContext->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
386 canvas->drawImage(image, 5, 0);
387 dContext->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
388 // Must call these to ensure that all callbacks are performed before the checker is destroyed.
389 image.reset();
390 dContext->flushAndSubmit(GrSyncCpu::kYes);
391
392 dContext->deleteBackendTexture(backendTex);
393}
T & emplace_back(Args &&... args)
Definition: SkTArray.h:248
uint32_t uint32_t * format