1 /*
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
8 #include "Test.h"
9
10 #include "GrContext.h"
11 #include "GrContextPriv.h"
12 #include "GrGpu.h"
13 #include "SkSurface.h"
14
15 using namespace sk_gpu_test;
16
testing_finished_proc(void * ctx)17 static void testing_finished_proc(void* ctx) {
18 int* count = (int*)ctx;
19 *count += 1;
20 }
21
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(FlushFinishedProcTest,reporter,ctxInfo)22 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(FlushFinishedProcTest, reporter, ctxInfo) {
23 GrContext* ctx = ctxInfo.grContext();
24
25 SkImageInfo info =
26 SkImageInfo::Make(8, 8, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
27 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info);
28 SkCanvas* canvas = surface->getCanvas();
29
30 // We flush the surface first just to get rid of any discards/clears that got recorded from
31 // making the surface.
32 surface->flush();
33 ctx->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
34
35 int count = 0;
36
37 // There is no work on the surface so flushing should immediately call the finished proc.
38 surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, kNone_GrFlushFlags, 0, nullptr,
39 testing_finished_proc, (void*)&count);
40 // Workaround flush for older branch
41 ctx->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
42
43 REPORTER_ASSERT(reporter, count == 1);
44
45 canvas->clear(SK_ColorRED);
46
47 surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, kNone_GrFlushFlags, 0, nullptr,
48 testing_finished_proc, (void*)&count);
49
50 bool isVulkan = ctx->backend() == GrBackendApi::kVulkan;
51 if (isVulkan) {
52 // On Vulkan the command buffer we just submitted may or may not have finished immediately
53 // so the finish proc may not have been called.
54 REPORTER_ASSERT(reporter, count == 1 || count == 2);
55 } else {
56 REPORTER_ASSERT(reporter, count == 2);
57 }
58 ctx->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
59 REPORTER_ASSERT(reporter, count == 2);
60
61 // Test flushing via the GrContext
62 canvas->clear(SK_ColorBLUE);
63 ctx->flush(kNone_GrFlushFlags, 0, nullptr, testing_finished_proc, (void*)&count);
64 if (isVulkan) {
65 // On Vulkan the command buffer we just submitted may or may not have finished immediately
66 // so the finish proc may not have been called.
67 REPORTER_ASSERT(reporter, count == 2 || count == 3);
68 } else {
69 REPORTER_ASSERT(reporter, count == 3);
70 }
71 ctx->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
72 REPORTER_ASSERT(reporter, count == 3);
73
74 // There is no work on the surface so flushing should immediately call the finished proc.
75 ctx->flush(kNone_GrFlushFlags, 0, nullptr, testing_finished_proc, (void*)&count);
76 // Workaround flush for older branch
77 ctx->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
78 REPORTER_ASSERT(reporter, count == 4);
79
80 count = 0;
81 int count2 = 0;
82 canvas->clear(SK_ColorGREEN);
83 surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, kNone_GrFlushFlags, 0, nullptr,
84 testing_finished_proc, (void*)&count);
85 // There is no work to be flushed here so this will return immediately, but make sure the
86 // finished call from this proc isn't called till the previous surface flush also is finished.
87 ctx->flush(kNone_GrFlushFlags, 0, nullptr, testing_finished_proc, (void*)&count2);
88 // Workaround flush for older branch
89 ctx->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
90
91 REPORTER_ASSERT(reporter, count == count2);
92
93 ctx->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
94
95 REPORTER_ASSERT(reporter, count == 1);
96 REPORTER_ASSERT(reporter, count == count2);
97 }
98
99