blob: 04a5fa7b734d7431faa676b43e096e233b16cf47 [file] [log] [blame]
Greg Daniela3aa75a2019-04-12 14:24:55 -04001/*
2 * Copyright 2019 Google Inc.
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "tests/Test.h"
Greg Daniela3aa75a2019-04-12 14:24:55 -04009
Brian Salomonb0d8b762019-05-06 16:58:22 -040010#include <chrono>
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkSurface.h"
12#include "include/gpu/GrContext.h"
13#include "src/gpu/GrContextPriv.h"
14#include "src/gpu/GrGpu.h"
Greg Daniela3aa75a2019-04-12 14:24:55 -040015
16using namespace sk_gpu_test;
17
18static void testing_finished_proc(void* ctx) {
19 int* count = (int*)ctx;
20 *count += 1;
21}
22
Brian Salomonb0d8b762019-05-06 16:58:22 -040023static void busy_wait_for_callback(int* count, int expectedValue, GrContext* ctx,
24 skiatest::Reporter* reporter) {
25 // Busy waiting should detect that the work is done.
26 auto begin = std::chrono::steady_clock::now();
27 auto end = begin;
28 do {
29 ctx->checkAsyncWorkCompletion();
30 end = std::chrono::steady_clock::now();
31 } while (*count != expectedValue && (end - begin) < std::chrono::seconds(1));
32 if (*count != expectedValue) {
33 ERRORF(reporter, "Expected count failed to reach %d within 1 second of busy waiting.",
34 expectedValue);
35 }
36}
37
Greg Daniela3aa75a2019-04-12 14:24:55 -040038DEF_GPUTEST_FOR_RENDERING_CONTEXTS(FlushFinishedProcTest, reporter, ctxInfo) {
39 GrContext* ctx = ctxInfo.grContext();
40
41 SkImageInfo info =
42 SkImageInfo::Make(8, 8, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
43 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info);
44 SkCanvas* canvas = surface->getCanvas();
45
Brian Salomonf9a1fdf2019-05-09 10:30:12 -040046 canvas->clear(SK_ColorGREEN);
47 auto image = surface->makeImageSnapshot();
48
Greg Daniele6bfb7d2019-04-17 15:26:11 -040049 GrFlushInfo flushInfoSyncCpu;
50 flushInfoSyncCpu.fFlags = kSyncCpu_GrFlushFlag;
51 ctx->flush(flushInfoSyncCpu);
Greg Daniela3aa75a2019-04-12 14:24:55 -040052
53 int count = 0;
54
Greg Daniele6bfb7d2019-04-17 15:26:11 -040055 GrFlushInfo flushInfoFinishedProc;
56 flushInfoFinishedProc.fFinishedProc = testing_finished_proc;
57 flushInfoFinishedProc.fFinishedContext = (void*)&count;
Brian Salomonb0d8b762019-05-06 16:58:22 -040058 // There is no work on the surface so flushing may immediately call the finished proc.
Greg Daniele6bfb7d2019-04-17 15:26:11 -040059 surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfoFinishedProc);
Brian Salomonb0d8b762019-05-06 16:58:22 -040060 REPORTER_ASSERT(reporter, count == 0 || count == 1);
61 // Busy waiting should detect that the work is done.
62 busy_wait_for_callback(&count, 1, ctx, reporter);
Greg Daniela3aa75a2019-04-12 14:24:55 -040063
64 canvas->clear(SK_ColorRED);
65
Greg Daniele6bfb7d2019-04-17 15:26:11 -040066 surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfoFinishedProc);
Greg Daniela3aa75a2019-04-12 14:24:55 -040067
Brian Salomonb0d8b762019-05-06 16:58:22 -040068 bool expectAsyncCallback =
69 ctx->backend() == GrBackendApi::kVulkan ||
70 ((ctx->backend() == GrBackendApi::kOpenGL) && ctx->priv().caps()->fenceSyncSupport());
71 if (expectAsyncCallback) {
Greg Daniela3aa75a2019-04-12 14:24:55 -040072 // On Vulkan the command buffer we just submitted may or may not have finished immediately
73 // so the finish proc may not have been called.
74 REPORTER_ASSERT(reporter, count == 1 || count == 2);
75 } else {
76 REPORTER_ASSERT(reporter, count == 2);
77 }
Greg Daniele6bfb7d2019-04-17 15:26:11 -040078 ctx->flush(flushInfoSyncCpu);
Greg Daniela3aa75a2019-04-12 14:24:55 -040079 REPORTER_ASSERT(reporter, count == 2);
80
Brian Salomonf9a1fdf2019-05-09 10:30:12 -040081 // Test flushing via the SkImage
82 canvas->drawImage(image, 0, 0);
83 image->flush(ctx, flushInfoFinishedProc);
Brian Salomonb0d8b762019-05-06 16:58:22 -040084 if (expectAsyncCallback) {
Greg Daniela3aa75a2019-04-12 14:24:55 -040085 // On Vulkan the command buffer we just submitted may or may not have finished immediately
86 // so the finish proc may not have been called.
87 REPORTER_ASSERT(reporter, count == 2 || count == 3);
88 } else {
89 REPORTER_ASSERT(reporter, count == 3);
90 }
Greg Daniele6bfb7d2019-04-17 15:26:11 -040091 ctx->flush(flushInfoSyncCpu);
Greg Daniela3aa75a2019-04-12 14:24:55 -040092 REPORTER_ASSERT(reporter, count == 3);
93
Brian Salomonf9a1fdf2019-05-09 10:30:12 -040094 // Test flushing via the GrContext
95 canvas->clear(SK_ColorBLUE);
96 ctx->flush(flushInfoFinishedProc);
97 if (expectAsyncCallback) {
98 // On Vulkan the command buffer we just submitted may or may not have finished immediately
99 // so the finish proc may not have been called.
100 REPORTER_ASSERT(reporter, count == 3 || count == 4);
101 } else {
102 REPORTER_ASSERT(reporter, count == 4);
103 }
104 ctx->flush(flushInfoSyncCpu);
105 REPORTER_ASSERT(reporter, count == 4);
106
Brian Salomonb0d8b762019-05-06 16:58:22 -0400107 // There is no work on the surface so flushing may immediately call the finished proc.
Greg Daniele6bfb7d2019-04-17 15:26:11 -0400108 ctx->flush(flushInfoFinishedProc);
Brian Salomonf9a1fdf2019-05-09 10:30:12 -0400109 REPORTER_ASSERT(reporter, count == 4 || count == 5);
110 busy_wait_for_callback(&count, 5, ctx, reporter);
Greg Daniela3aa75a2019-04-12 14:24:55 -0400111
112 count = 0;
113 int count2 = 0;
114 canvas->clear(SK_ColorGREEN);
Greg Daniele6bfb7d2019-04-17 15:26:11 -0400115 surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, flushInfoFinishedProc);
Greg Daniela3aa75a2019-04-12 14:24:55 -0400116 // There is no work to be flushed here so this will return immediately, but make sure the
117 // finished call from this proc isn't called till the previous surface flush also is finished.
Greg Daniele6bfb7d2019-04-17 15:26:11 -0400118 flushInfoFinishedProc.fFinishedContext = (void*)&count2;
119 ctx->flush(flushInfoFinishedProc);
Brian Salomonb0d8b762019-05-06 16:58:22 -0400120 REPORTER_ASSERT(reporter, count <= 1 && count2 <= count);
Greg Daniela3aa75a2019-04-12 14:24:55 -0400121
Greg Daniele6bfb7d2019-04-17 15:26:11 -0400122 ctx->flush(flushInfoSyncCpu);
Greg Daniela3aa75a2019-04-12 14:24:55 -0400123
124 REPORTER_ASSERT(reporter, count == 1);
125 REPORTER_ASSERT(reporter, count == count2);
126}
127