Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 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 | |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 8 | #include "tests/Test.h" |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 9 | |
Brian Salomon | b0d8b76 | 2019-05-06 16:58:22 -0400 | [diff] [blame] | 10 | #include <chrono> |
Robert Phillips | e19babf | 2020-04-06 13:57:30 -0400 | [diff] [blame] | 11 | #include "include/core/SkCanvas.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 12 | #include "include/core/SkSurface.h" |
Robert Phillips | 6d344c3 | 2020-07-06 10:56:46 -0400 | [diff] [blame] | 13 | #include "include/gpu/GrDirectContext.h" |
Adlai Holler | a069304 | 2020-10-14 11:23:11 -0400 | [diff] [blame] | 14 | #include "src/gpu/GrDirectContextPriv.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 15 | #include "src/gpu/GrGpu.h" |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 16 | |
| 17 | using namespace sk_gpu_test; |
| 18 | |
| 19 | static void testing_finished_proc(void* ctx) { |
| 20 | int* count = (int*)ctx; |
| 21 | *count += 1; |
| 22 | } |
| 23 | |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 24 | static void busy_wait_for_callback(int* count, int expectedValue, GrDirectContext* dContext, |
Brian Salomon | b0d8b76 | 2019-05-06 16:58:22 -0400 | [diff] [blame] | 25 | skiatest::Reporter* reporter) { |
| 26 | // Busy waiting should detect that the work is done. |
| 27 | auto begin = std::chrono::steady_clock::now(); |
| 28 | auto end = begin; |
| 29 | do { |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 30 | dContext->checkAsyncWorkCompletion(); |
Brian Salomon | b0d8b76 | 2019-05-06 16:58:22 -0400 | [diff] [blame] | 31 | end = std::chrono::steady_clock::now(); |
| 32 | } while (*count != expectedValue && (end - begin) < std::chrono::seconds(1)); |
| 33 | if (*count != expectedValue) { |
| 34 | ERRORF(reporter, "Expected count failed to reach %d within 1 second of busy waiting.", |
| 35 | expectedValue); |
| 36 | } |
| 37 | } |
| 38 | |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 39 | DEF_GPUTEST_FOR_RENDERING_CONTEXTS(FlushFinishedProcTest, reporter, ctxInfo) { |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 40 | auto dContext = ctxInfo.directContext(); |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 41 | |
| 42 | SkImageInfo info = |
| 43 | SkImageInfo::Make(8, 8, kRGBA_8888_SkColorType, kPremul_SkAlphaType); |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 44 | sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(dContext, SkBudgeted::kNo, info); |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 45 | SkCanvas* canvas = surface->getCanvas(); |
| 46 | |
Brian Salomon | f9a1fdf | 2019-05-09 10:30:12 -0400 | [diff] [blame] | 47 | canvas->clear(SK_ColorGREEN); |
| 48 | auto image = surface->makeImageSnapshot(); |
| 49 | |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 50 | dContext->flush(); |
| 51 | dContext->submit(true); |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 52 | |
| 53 | int count = 0; |
| 54 | |
Greg Daniel | e6bfb7d | 2019-04-17 15:26:11 -0400 | [diff] [blame] | 55 | GrFlushInfo flushInfoFinishedProc; |
| 56 | flushInfoFinishedProc.fFinishedProc = testing_finished_proc; |
| 57 | flushInfoFinishedProc.fFinishedContext = (void*)&count; |
Brian Salomon | b0d8b76 | 2019-05-06 16:58:22 -0400 | [diff] [blame] | 58 | // There is no work on the surface so flushing may immediately call the finished proc. |
Greg Daniel | ce9f016 | 2020-06-30 13:42:46 -0400 | [diff] [blame] | 59 | surface->flush(flushInfoFinishedProc); |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 60 | dContext->submit(); |
Brian Salomon | b0d8b76 | 2019-05-06 16:58:22 -0400 | [diff] [blame] | 61 | REPORTER_ASSERT(reporter, count == 0 || count == 1); |
| 62 | // Busy waiting should detect that the work is done. |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 63 | busy_wait_for_callback(&count, 1, dContext, reporter); |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 64 | |
| 65 | canvas->clear(SK_ColorRED); |
| 66 | |
Greg Daniel | ce9f016 | 2020-06-30 13:42:46 -0400 | [diff] [blame] | 67 | surface->flush(flushInfoFinishedProc); |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 68 | dContext->submit(); |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 69 | |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 70 | bool fenceSupport = dContext->priv().caps()->fenceSyncSupport(); |
Brian Salomon | b0d8b76 | 2019-05-06 16:58:22 -0400 | [diff] [blame] | 71 | bool expectAsyncCallback = |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 72 | dContext->backend() == GrBackendApi::kVulkan || |
| 73 | ((dContext->backend() == GrBackendApi::kOpenGL) && fenceSupport) || |
| 74 | ((dContext->backend() == GrBackendApi::kMetal) && fenceSupport) || |
| 75 | dContext->backend() == GrBackendApi::kDawn || |
| 76 | dContext->backend() == GrBackendApi::kDirect3D; |
Brian Salomon | b0d8b76 | 2019-05-06 16:58:22 -0400 | [diff] [blame] | 77 | if (expectAsyncCallback) { |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 78 | // On Vulkan the command buffer we just submitted may or may not have finished immediately |
| 79 | // so the finish proc may not have been called. |
| 80 | REPORTER_ASSERT(reporter, count == 1 || count == 2); |
| 81 | } else { |
| 82 | REPORTER_ASSERT(reporter, count == 2); |
| 83 | } |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 84 | dContext->flush(); |
| 85 | dContext->submit(true); |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 86 | REPORTER_ASSERT(reporter, count == 2); |
| 87 | |
Brian Salomon | f9a1fdf | 2019-05-09 10:30:12 -0400 | [diff] [blame] | 88 | // Test flushing via the SkImage |
| 89 | canvas->drawImage(image, 0, 0); |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 90 | image->flush(dContext, flushInfoFinishedProc); |
| 91 | dContext->submit(); |
Brian Salomon | b0d8b76 | 2019-05-06 16:58:22 -0400 | [diff] [blame] | 92 | if (expectAsyncCallback) { |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 93 | // On Vulkan the command buffer we just submitted may or may not have finished immediately |
| 94 | // so the finish proc may not have been called. |
| 95 | REPORTER_ASSERT(reporter, count == 2 || count == 3); |
| 96 | } else { |
| 97 | REPORTER_ASSERT(reporter, count == 3); |
| 98 | } |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 99 | dContext->flush(); |
| 100 | dContext->submit(true); |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 101 | REPORTER_ASSERT(reporter, count == 3); |
| 102 | |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 103 | // Test flushing via the GrDirectContext |
Brian Salomon | f9a1fdf | 2019-05-09 10:30:12 -0400 | [diff] [blame] | 104 | canvas->clear(SK_ColorBLUE); |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 105 | dContext->flush(flushInfoFinishedProc); |
| 106 | dContext->submit(); |
Brian Salomon | f9a1fdf | 2019-05-09 10:30:12 -0400 | [diff] [blame] | 107 | if (expectAsyncCallback) { |
| 108 | // On Vulkan the command buffer we just submitted may or may not have finished immediately |
| 109 | // so the finish proc may not have been called. |
| 110 | REPORTER_ASSERT(reporter, count == 3 || count == 4); |
| 111 | } else { |
| 112 | REPORTER_ASSERT(reporter, count == 4); |
| 113 | } |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 114 | dContext->flush(); |
| 115 | dContext->submit(true); |
Brian Salomon | f9a1fdf | 2019-05-09 10:30:12 -0400 | [diff] [blame] | 116 | REPORTER_ASSERT(reporter, count == 4); |
| 117 | |
Brian Salomon | b0d8b76 | 2019-05-06 16:58:22 -0400 | [diff] [blame] | 118 | // There is no work on the surface so flushing may immediately call the finished proc. |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 119 | dContext->flush(flushInfoFinishedProc); |
| 120 | dContext->submit(); |
Brian Salomon | f9a1fdf | 2019-05-09 10:30:12 -0400 | [diff] [blame] | 121 | REPORTER_ASSERT(reporter, count == 4 || count == 5); |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 122 | busy_wait_for_callback(&count, 5, dContext, reporter); |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 123 | |
| 124 | count = 0; |
| 125 | int count2 = 0; |
| 126 | canvas->clear(SK_ColorGREEN); |
Greg Daniel | ce9f016 | 2020-06-30 13:42:46 -0400 | [diff] [blame] | 127 | surface->flush(flushInfoFinishedProc); |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 128 | dContext->submit(); |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 129 | // There is no work to be flushed here so this will return immediately, but make sure the |
| 130 | // finished call from this proc isn't called till the previous surface flush also is finished. |
Greg Daniel | e6bfb7d | 2019-04-17 15:26:11 -0400 | [diff] [blame] | 131 | flushInfoFinishedProc.fFinishedContext = (void*)&count2; |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 132 | dContext->flush(flushInfoFinishedProc); |
| 133 | dContext->submit(); |
Brian Salomon | b0d8b76 | 2019-05-06 16:58:22 -0400 | [diff] [blame] | 134 | REPORTER_ASSERT(reporter, count <= 1 && count2 <= count); |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 135 | |
Robert Phillips | c8ae494 | 2020-07-20 10:56:01 -0400 | [diff] [blame] | 136 | dContext->flush(); |
| 137 | dContext->submit(true); |
Greg Daniel | a3aa75a | 2019-04-12 14:24:55 -0400 | [diff] [blame] | 138 | |
| 139 | REPORTER_ASSERT(reporter, count == 1); |
| 140 | REPORTER_ASSERT(reporter, count == count2); |
| 141 | } |
| 142 | |