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 17 static void testing_finished_proc(void* ctx) { 18 int* count = (int*)ctx; 19 *count += 1; 20 } 21 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