xref: /aosp_15_r20/external/skia/tests/SurfaceSemaphoreTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2017 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkAlphaType.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorType.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImage.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSemaphore.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkImageGanesh.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkSurfaceGanesh.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "tests/CtsEnforcement.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/ContextType.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/TestContext.h"
36*c8dee2aaSAndroid Build Coastguard Worker 
37*c8dee2aaSAndroid Build Coastguard Worker #include <cstring>
38*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
39*c8dee2aaSAndroid Build Coastguard Worker #include <initializer_list>
40*c8dee2aaSAndroid Build Coastguard Worker 
41*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
42*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLFunctions.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLInterface.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLTypes.h"
45*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLGpu.h"
46*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLUtil.h"
47*c8dee2aaSAndroid Build Coastguard Worker #endif
48*c8dee2aaSAndroid Build Coastguard Worker 
49*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_VULKAN
50*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkBackendSemaphore.h"
51*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/vk/GrVkBackendSurface.h"
52*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkCommandPool.h"
53*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkGpu.h"
54*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/vk/GrVkUtil.h"
55*c8dee2aaSAndroid Build Coastguard Worker 
56*c8dee2aaSAndroid Build Coastguard Worker #include <vulkan/vulkan_core.h>
57*c8dee2aaSAndroid Build Coastguard Worker 
58*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu { struct VulkanInterface; }
59*c8dee2aaSAndroid Build Coastguard Worker 
60*c8dee2aaSAndroid Build Coastguard Worker #ifdef VK_USE_PLATFORM_WIN32_KHR
61*c8dee2aaSAndroid Build Coastguard Worker // windows wants to define this as CreateSemaphoreA or CreateSemaphoreW
62*c8dee2aaSAndroid Build Coastguard Worker #undef CreateSemaphore
63*c8dee2aaSAndroid Build Coastguard Worker #endif
64*c8dee2aaSAndroid Build Coastguard Worker #endif
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
67*c8dee2aaSAndroid Build Coastguard Worker 
68*c8dee2aaSAndroid Build Coastguard Worker struct GrContextOptions;
69*c8dee2aaSAndroid Build Coastguard Worker 
70*c8dee2aaSAndroid Build Coastguard Worker static const int MAIN_W = 8, MAIN_H = 16;
71*c8dee2aaSAndroid Build Coastguard Worker static const int CHILD_W = 16, CHILD_H = 16;
72*c8dee2aaSAndroid Build Coastguard Worker 
check_pixels(skiatest::Reporter * reporter,const SkBitmap & bitmap)73*c8dee2aaSAndroid Build Coastguard Worker void check_pixels(skiatest::Reporter* reporter, const SkBitmap& bitmap) {
74*c8dee2aaSAndroid Build Coastguard Worker     const uint32_t* canvasPixels = static_cast<const uint32_t*>(bitmap.getPixels());
75*c8dee2aaSAndroid Build Coastguard Worker 
76*c8dee2aaSAndroid Build Coastguard Worker     bool failureFound = false;
77*c8dee2aaSAndroid Build Coastguard Worker     SkPMColor expectedPixel;
78*c8dee2aaSAndroid Build Coastguard Worker     for (int cy = 0; cy < CHILD_H && !failureFound; ++cy) {
79*c8dee2aaSAndroid Build Coastguard Worker         for (int cx = 0; cx < CHILD_W && !failureFound; ++cx) {
80*c8dee2aaSAndroid Build Coastguard Worker             SkPMColor canvasPixel = canvasPixels[cy * CHILD_W + cx];
81*c8dee2aaSAndroid Build Coastguard Worker             if (cy < CHILD_H / 2) {
82*c8dee2aaSAndroid Build Coastguard Worker                 if (cx < CHILD_W / 2) {
83*c8dee2aaSAndroid Build Coastguard Worker                     expectedPixel = 0xFF0000FF; // Red
84*c8dee2aaSAndroid Build Coastguard Worker                 } else {
85*c8dee2aaSAndroid Build Coastguard Worker                     expectedPixel = 0xFFFF0000; // Blue
86*c8dee2aaSAndroid Build Coastguard Worker                 }
87*c8dee2aaSAndroid Build Coastguard Worker             } else {
88*c8dee2aaSAndroid Build Coastguard Worker                 expectedPixel = 0xFF00FF00; // Green
89*c8dee2aaSAndroid Build Coastguard Worker             }
90*c8dee2aaSAndroid Build Coastguard Worker             if (expectedPixel != canvasPixel) {
91*c8dee2aaSAndroid Build Coastguard Worker                 failureFound = true;
92*c8dee2aaSAndroid Build Coastguard Worker                 ERRORF(reporter, "Wrong color at %d, %d. Got 0x%08x when we expected 0x%08x",
93*c8dee2aaSAndroid Build Coastguard Worker                        cx, cy, canvasPixel, expectedPixel);
94*c8dee2aaSAndroid Build Coastguard Worker             }
95*c8dee2aaSAndroid Build Coastguard Worker         }
96*c8dee2aaSAndroid Build Coastguard Worker     }
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker 
draw_child(skiatest::Reporter * reporter,const sk_gpu_test::ContextInfo & childInfo,const GrBackendTexture & backendTexture,const GrBackendSemaphore & semaphore)99*c8dee2aaSAndroid Build Coastguard Worker void draw_child(skiatest::Reporter* reporter,
100*c8dee2aaSAndroid Build Coastguard Worker                 const sk_gpu_test::ContextInfo& childInfo,
101*c8dee2aaSAndroid Build Coastguard Worker                 const GrBackendTexture& backendTexture,
102*c8dee2aaSAndroid Build Coastguard Worker                 const GrBackendSemaphore& semaphore) {
103*c8dee2aaSAndroid Build Coastguard Worker 
104*c8dee2aaSAndroid Build Coastguard Worker     childInfo.testContext()->makeCurrent();
105*c8dee2aaSAndroid Build Coastguard Worker 
106*c8dee2aaSAndroid Build Coastguard Worker     const SkImageInfo childII = SkImageInfo::Make(CHILD_W, CHILD_H, kRGBA_8888_SkColorType,
107*c8dee2aaSAndroid Build Coastguard Worker                                                   kPremul_SkAlphaType);
108*c8dee2aaSAndroid Build Coastguard Worker 
109*c8dee2aaSAndroid Build Coastguard Worker     auto childDContext = childInfo.directContext();
110*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkSurface> childSurface(SkSurfaces::RenderTarget(
111*c8dee2aaSAndroid Build Coastguard Worker             childDContext, skgpu::Budgeted::kNo, childII, 0, kTopLeft_GrSurfaceOrigin, nullptr));
112*c8dee2aaSAndroid Build Coastguard Worker 
113*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkImage> childImage = SkImages::BorrowTextureFrom(childDContext,
114*c8dee2aaSAndroid Build Coastguard Worker                                                             backendTexture,
115*c8dee2aaSAndroid Build Coastguard Worker                                                             kTopLeft_GrSurfaceOrigin,
116*c8dee2aaSAndroid Build Coastguard Worker                                                             kRGBA_8888_SkColorType,
117*c8dee2aaSAndroid Build Coastguard Worker                                                             kPremul_SkAlphaType,
118*c8dee2aaSAndroid Build Coastguard Worker                                                             nullptr,
119*c8dee2aaSAndroid Build Coastguard Worker                                                             nullptr,
120*c8dee2aaSAndroid Build Coastguard Worker                                                             nullptr);
121*c8dee2aaSAndroid Build Coastguard Worker 
122*c8dee2aaSAndroid Build Coastguard Worker     SkCanvas* childCanvas = childSurface->getCanvas();
123*c8dee2aaSAndroid Build Coastguard Worker     childCanvas->clear(SK_ColorRED);
124*c8dee2aaSAndroid Build Coastguard Worker 
125*c8dee2aaSAndroid Build Coastguard Worker     childSurface->wait(1, &semaphore);
126*c8dee2aaSAndroid Build Coastguard Worker 
127*c8dee2aaSAndroid Build Coastguard Worker     childCanvas->drawImage(childImage, CHILD_W/2, 0);
128*c8dee2aaSAndroid Build Coastguard Worker 
129*c8dee2aaSAndroid Build Coastguard Worker     SkPaint paint;
130*c8dee2aaSAndroid Build Coastguard Worker     paint.setColor(SK_ColorGREEN);
131*c8dee2aaSAndroid Build Coastguard Worker     SkIRect rect = SkIRect::MakeLTRB(0, CHILD_H/2, CHILD_W, CHILD_H);
132*c8dee2aaSAndroid Build Coastguard Worker     childCanvas->drawIRect(rect, paint);
133*c8dee2aaSAndroid Build Coastguard Worker 
134*c8dee2aaSAndroid Build Coastguard Worker     // read pixels
135*c8dee2aaSAndroid Build Coastguard Worker     SkBitmap bitmap;
136*c8dee2aaSAndroid Build Coastguard Worker     bitmap.allocPixels(childII);
137*c8dee2aaSAndroid Build Coastguard Worker     childSurface->readPixels(bitmap, 0, 0);
138*c8dee2aaSAndroid Build Coastguard Worker 
139*c8dee2aaSAndroid Build Coastguard Worker     check_pixels(reporter, bitmap);
140*c8dee2aaSAndroid Build Coastguard Worker }
141*c8dee2aaSAndroid Build Coastguard Worker 
142*c8dee2aaSAndroid Build Coastguard Worker enum class FlushType { kSurface, kImage, kContext };
143*c8dee2aaSAndroid Build Coastguard Worker 
surface_semaphore_test(skiatest::Reporter * reporter,const sk_gpu_test::ContextInfo & mainInfo,const sk_gpu_test::ContextInfo & childInfo1,const sk_gpu_test::ContextInfo & childInfo2,FlushType flushType)144*c8dee2aaSAndroid Build Coastguard Worker void surface_semaphore_test(skiatest::Reporter* reporter,
145*c8dee2aaSAndroid Build Coastguard Worker                             const sk_gpu_test::ContextInfo& mainInfo,
146*c8dee2aaSAndroid Build Coastguard Worker                             const sk_gpu_test::ContextInfo& childInfo1,
147*c8dee2aaSAndroid Build Coastguard Worker                             const sk_gpu_test::ContextInfo& childInfo2,
148*c8dee2aaSAndroid Build Coastguard Worker                             FlushType flushType) {
149*c8dee2aaSAndroid Build Coastguard Worker     auto mainCtx = mainInfo.directContext();
150*c8dee2aaSAndroid Build Coastguard Worker     if (!mainCtx->priv().caps()->backendSemaphoreSupport()) {
151*c8dee2aaSAndroid Build Coastguard Worker         return;
152*c8dee2aaSAndroid Build Coastguard Worker     }
153*c8dee2aaSAndroid Build Coastguard Worker 
154*c8dee2aaSAndroid Build Coastguard Worker     const SkImageInfo ii = SkImageInfo::Make(MAIN_W, MAIN_H, kRGBA_8888_SkColorType,
155*c8dee2aaSAndroid Build Coastguard Worker                                              kPremul_SkAlphaType);
156*c8dee2aaSAndroid Build Coastguard Worker 
157*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkSurface> mainSurface(SkSurfaces::RenderTarget(
158*c8dee2aaSAndroid Build Coastguard Worker             mainCtx, skgpu::Budgeted::kNo, ii, 0, kTopLeft_GrSurfaceOrigin, nullptr));
159*c8dee2aaSAndroid Build Coastguard Worker     SkCanvas* mainCanvas = mainSurface->getCanvas();
160*c8dee2aaSAndroid Build Coastguard Worker     auto blueSurface = mainSurface->makeSurface(ii);
161*c8dee2aaSAndroid Build Coastguard Worker     blueSurface->getCanvas()->clear(SK_ColorBLUE);
162*c8dee2aaSAndroid Build Coastguard Worker     auto blueImage = blueSurface->makeImageSnapshot();
163*c8dee2aaSAndroid Build Coastguard Worker     blueSurface.reset();
164*c8dee2aaSAndroid Build Coastguard Worker     mainCanvas->drawImage(blueImage, 0, 0);
165*c8dee2aaSAndroid Build Coastguard Worker 
166*c8dee2aaSAndroid Build Coastguard Worker     AutoTArray<GrBackendSemaphore> semaphores(2);
167*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_VULKAN
168*c8dee2aaSAndroid Build Coastguard Worker     if (GrBackendApi::kVulkan == mainInfo.backend()) {
169*c8dee2aaSAndroid Build Coastguard Worker         // Initialize the secondary semaphore instead of having Ganesh create one internally
170*c8dee2aaSAndroid Build Coastguard Worker         GrVkGpu* gpu = static_cast<GrVkGpu*>(mainCtx->priv().getGpu());
171*c8dee2aaSAndroid Build Coastguard Worker         VkDevice device = gpu->device();
172*c8dee2aaSAndroid Build Coastguard Worker 
173*c8dee2aaSAndroid Build Coastguard Worker         VkSemaphore vkSem;
174*c8dee2aaSAndroid Build Coastguard Worker 
175*c8dee2aaSAndroid Build Coastguard Worker         VkSemaphoreCreateInfo createInfo;
176*c8dee2aaSAndroid Build Coastguard Worker         createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
177*c8dee2aaSAndroid Build Coastguard Worker         createInfo.pNext = nullptr;
178*c8dee2aaSAndroid Build Coastguard Worker         createInfo.flags = 0;
179*c8dee2aaSAndroid Build Coastguard Worker         GR_VK_CALL_ERRCHECK(gpu, CreateSemaphore(device, &createInfo, nullptr, &vkSem));
180*c8dee2aaSAndroid Build Coastguard Worker 
181*c8dee2aaSAndroid Build Coastguard Worker         semaphores[1] = GrBackendSemaphores::MakeVk(vkSem);
182*c8dee2aaSAndroid Build Coastguard Worker     }
183*c8dee2aaSAndroid Build Coastguard Worker #endif
184*c8dee2aaSAndroid Build Coastguard Worker 
185*c8dee2aaSAndroid Build Coastguard Worker     GrFlushInfo info;
186*c8dee2aaSAndroid Build Coastguard Worker     info.fNumSemaphores = 2;
187*c8dee2aaSAndroid Build Coastguard Worker     info.fSignalSemaphores = semaphores.get();
188*c8dee2aaSAndroid Build Coastguard Worker     switch (flushType) {
189*c8dee2aaSAndroid Build Coastguard Worker         case FlushType::kSurface:
190*c8dee2aaSAndroid Build Coastguard Worker             mainCtx->flush(mainSurface.get(), SkSurfaces::BackendSurfaceAccess::kNoAccess, info);
191*c8dee2aaSAndroid Build Coastguard Worker             break;
192*c8dee2aaSAndroid Build Coastguard Worker         case FlushType::kImage:
193*c8dee2aaSAndroid Build Coastguard Worker             mainCtx->flush(blueImage, info);
194*c8dee2aaSAndroid Build Coastguard Worker             break;
195*c8dee2aaSAndroid Build Coastguard Worker         case FlushType::kContext:
196*c8dee2aaSAndroid Build Coastguard Worker             mainCtx->flush(info);
197*c8dee2aaSAndroid Build Coastguard Worker             break;
198*c8dee2aaSAndroid Build Coastguard Worker     }
199*c8dee2aaSAndroid Build Coastguard Worker     mainCtx->submit();
200*c8dee2aaSAndroid Build Coastguard Worker 
201*c8dee2aaSAndroid Build Coastguard Worker     GrBackendTexture backendTexture = SkSurfaces::GetBackendTexture(
202*c8dee2aaSAndroid Build Coastguard Worker             mainSurface.get(), SkSurface::BackendHandleAccess::kFlushRead);
203*c8dee2aaSAndroid Build Coastguard Worker 
204*c8dee2aaSAndroid Build Coastguard Worker     draw_child(reporter, childInfo1, backendTexture, semaphores[0]);
205*c8dee2aaSAndroid Build Coastguard Worker 
206*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_VULKAN
207*c8dee2aaSAndroid Build Coastguard Worker     if (GrBackendApi::kVulkan == mainInfo.backend()) {
208*c8dee2aaSAndroid Build Coastguard Worker         // In Vulkan we need to make sure we are sending the correct VkImageLayout in with the
209*c8dee2aaSAndroid Build Coastguard Worker         // backendImage. After the first child draw the layout gets changed to SHADER_READ, so
210*c8dee2aaSAndroid Build Coastguard Worker         // we just manually set that here.
211*c8dee2aaSAndroid Build Coastguard Worker         GrBackendTextures::SetVkImageLayout(&backendTexture,
212*c8dee2aaSAndroid Build Coastguard Worker                                             VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
213*c8dee2aaSAndroid Build Coastguard Worker     }
214*c8dee2aaSAndroid Build Coastguard Worker #endif
215*c8dee2aaSAndroid Build Coastguard Worker 
216*c8dee2aaSAndroid Build Coastguard Worker     draw_child(reporter, childInfo2, backendTexture, semaphores[1]);
217*c8dee2aaSAndroid Build Coastguard Worker }
218*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST(SurfaceSemaphores,reporter,options,CtsEnforcement::kApiLevel_T)219*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST(SurfaceSemaphores, reporter, options, CtsEnforcement::kApiLevel_T) {
220*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC)
221*c8dee2aaSAndroid Build Coastguard Worker     static constexpr auto kNativeGLType = skgpu::ContextType::kGL;
222*c8dee2aaSAndroid Build Coastguard Worker #else
223*c8dee2aaSAndroid Build Coastguard Worker     static constexpr auto kNativeGLType = skgpu::ContextType::kGLES;
224*c8dee2aaSAndroid Build Coastguard Worker #endif
225*c8dee2aaSAndroid Build Coastguard Worker 
226*c8dee2aaSAndroid Build Coastguard Worker     for (int typeInt = 0; typeInt < skgpu::kContextTypeCount; ++typeInt) {
227*c8dee2aaSAndroid Build Coastguard Worker         for (auto flushType : {FlushType::kSurface, FlushType::kImage, FlushType::kContext}) {
228*c8dee2aaSAndroid Build Coastguard Worker             skgpu::ContextType contextType = static_cast<skgpu::ContextType>(typeInt);
229*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_GL
230*c8dee2aaSAndroid Build Coastguard Worker             // Use "native" instead of explicitly trying OpenGL and OpenGL ES. Do not use GLES on
231*c8dee2aaSAndroid Build Coastguard Worker             // desktop since tests do not account for not fixing http://skbug.com/2809
232*c8dee2aaSAndroid Build Coastguard Worker             if (contextType == skgpu::ContextType::kGL ||
233*c8dee2aaSAndroid Build Coastguard Worker                 contextType == skgpu::ContextType::kGLES) {
234*c8dee2aaSAndroid Build Coastguard Worker                 if (contextType != kNativeGLType) {
235*c8dee2aaSAndroid Build Coastguard Worker                     continue;
236*c8dee2aaSAndroid Build Coastguard Worker                 }
237*c8dee2aaSAndroid Build Coastguard Worker             }
238*c8dee2aaSAndroid Build Coastguard Worker #else
239*c8dee2aaSAndroid Build Coastguard Worker             sk_ignore_unused_variable(kNativeGLType);  // Do something to avoid unused variable
240*c8dee2aaSAndroid Build Coastguard Worker #endif
241*c8dee2aaSAndroid Build Coastguard Worker             sk_gpu_test::GrContextFactory factory(options);
242*c8dee2aaSAndroid Build Coastguard Worker             sk_gpu_test::ContextInfo ctxInfo = factory.getContextInfo(contextType);
243*c8dee2aaSAndroid Build Coastguard Worker             if (!skgpu::IsRenderingContext(contextType)) {
244*c8dee2aaSAndroid Build Coastguard Worker                 continue;
245*c8dee2aaSAndroid Build Coastguard Worker             }
246*c8dee2aaSAndroid Build Coastguard Worker             skiatest::ReporterContext ctx(reporter, SkString(skgpu::ContextTypeName(contextType)));
247*c8dee2aaSAndroid Build Coastguard Worker             if (ctxInfo.directContext()) {
248*c8dee2aaSAndroid Build Coastguard Worker                 sk_gpu_test::ContextInfo child1 =
249*c8dee2aaSAndroid Build Coastguard Worker                         factory.getSharedContextInfo(ctxInfo.directContext(), 0);
250*c8dee2aaSAndroid Build Coastguard Worker                 sk_gpu_test::ContextInfo child2 =
251*c8dee2aaSAndroid Build Coastguard Worker                         factory.getSharedContextInfo(ctxInfo.directContext(), 1);
252*c8dee2aaSAndroid Build Coastguard Worker                 if (!child1.directContext() || !child2.directContext()) {
253*c8dee2aaSAndroid Build Coastguard Worker                     continue;
254*c8dee2aaSAndroid Build Coastguard Worker                 }
255*c8dee2aaSAndroid Build Coastguard Worker 
256*c8dee2aaSAndroid Build Coastguard Worker                 surface_semaphore_test(reporter, ctxInfo, child1, child2, flushType);
257*c8dee2aaSAndroid Build Coastguard Worker             }
258*c8dee2aaSAndroid Build Coastguard Worker         }
259*c8dee2aaSAndroid Build Coastguard Worker     }
260*c8dee2aaSAndroid Build Coastguard Worker }
261*c8dee2aaSAndroid Build Coastguard Worker 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(EmptySurfaceSemaphoreTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)262*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(EmptySurfaceSemaphoreTest,
263*c8dee2aaSAndroid Build Coastguard Worker                                        reporter,
264*c8dee2aaSAndroid Build Coastguard Worker                                        ctxInfo,
265*c8dee2aaSAndroid Build Coastguard Worker                                        CtsEnforcement::kApiLevel_T) {
266*c8dee2aaSAndroid Build Coastguard Worker     auto ctx = ctxInfo.directContext();
267*c8dee2aaSAndroid Build Coastguard Worker     if (!ctx->priv().caps()->backendSemaphoreSupport()) {
268*c8dee2aaSAndroid Build Coastguard Worker         // For example, the GL backend does not support these.
269*c8dee2aaSAndroid Build Coastguard Worker         return;
270*c8dee2aaSAndroid Build Coastguard Worker     }
271*c8dee2aaSAndroid Build Coastguard Worker 
272*c8dee2aaSAndroid Build Coastguard Worker     const SkImageInfo ii = SkImageInfo::Make(MAIN_W, MAIN_H, kRGBA_8888_SkColorType,
273*c8dee2aaSAndroid Build Coastguard Worker                                              kPremul_SkAlphaType);
274*c8dee2aaSAndroid Build Coastguard Worker 
275*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkSurface> mainSurface(SkSurfaces::RenderTarget(
276*c8dee2aaSAndroid Build Coastguard Worker             ctx, skgpu::Budgeted::kNo, ii, 0, kTopLeft_GrSurfaceOrigin, nullptr));
277*c8dee2aaSAndroid Build Coastguard Worker 
278*c8dee2aaSAndroid Build Coastguard Worker     // Flush surface once without semaphores to make sure there is no pending IO for it.
279*c8dee2aaSAndroid Build Coastguard Worker     ctx->flushAndSubmit(mainSurface.get(), GrSyncCpu::kNo);
280*c8dee2aaSAndroid Build Coastguard Worker 
281*c8dee2aaSAndroid Build Coastguard Worker     GrBackendSemaphore semaphore;
282*c8dee2aaSAndroid Build Coastguard Worker     GrFlushInfo flushInfo;
283*c8dee2aaSAndroid Build Coastguard Worker     flushInfo.fNumSemaphores = 1;
284*c8dee2aaSAndroid Build Coastguard Worker     flushInfo.fSignalSemaphores = &semaphore;
285*c8dee2aaSAndroid Build Coastguard Worker     GrSemaphoresSubmitted submitted =
286*c8dee2aaSAndroid Build Coastguard Worker             ctx->flush(mainSurface.get(), SkSurfaces::BackendSurfaceAccess::kNoAccess, flushInfo);
287*c8dee2aaSAndroid Build Coastguard Worker     REPORTER_ASSERT(reporter, GrSemaphoresSubmitted::kYes == submitted);
288*c8dee2aaSAndroid Build Coastguard Worker     ctx->submit();
289*c8dee2aaSAndroid Build Coastguard Worker 
290*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_VULKAN
291*c8dee2aaSAndroid Build Coastguard Worker     if (GrBackendApi::kVulkan == ctxInfo.backend()) {
292*c8dee2aaSAndroid Build Coastguard Worker         GrVkGpu* gpu = static_cast<GrVkGpu*>(ctx->priv().getGpu());
293*c8dee2aaSAndroid Build Coastguard Worker         const skgpu::VulkanInterface* interface = gpu->vkInterface();
294*c8dee2aaSAndroid Build Coastguard Worker         VkDevice device = gpu->device();
295*c8dee2aaSAndroid Build Coastguard Worker         VkQueue queue = gpu->queue();
296*c8dee2aaSAndroid Build Coastguard Worker         GrVkCommandPool* cmdPool = gpu->cmdPool();
297*c8dee2aaSAndroid Build Coastguard Worker         VkCommandBuffer cmdBuffer;
298*c8dee2aaSAndroid Build Coastguard Worker 
299*c8dee2aaSAndroid Build Coastguard Worker         // Create Command Buffer
300*c8dee2aaSAndroid Build Coastguard Worker         const VkCommandBufferAllocateInfo cmdInfo = {
301*c8dee2aaSAndroid Build Coastguard Worker             VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,   // sType
302*c8dee2aaSAndroid Build Coastguard Worker             nullptr,                                          // pNext
303*c8dee2aaSAndroid Build Coastguard Worker             cmdPool->vkCommandPool(),                         // commandPool
304*c8dee2aaSAndroid Build Coastguard Worker             VK_COMMAND_BUFFER_LEVEL_PRIMARY,                  // level
305*c8dee2aaSAndroid Build Coastguard Worker             1                                                 // bufferCount
306*c8dee2aaSAndroid Build Coastguard Worker         };
307*c8dee2aaSAndroid Build Coastguard Worker 
308*c8dee2aaSAndroid Build Coastguard Worker         VkResult err = GR_VK_CALL(interface, AllocateCommandBuffers(device, &cmdInfo, &cmdBuffer));
309*c8dee2aaSAndroid Build Coastguard Worker         if (err) {
310*c8dee2aaSAndroid Build Coastguard Worker             return;
311*c8dee2aaSAndroid Build Coastguard Worker         }
312*c8dee2aaSAndroid Build Coastguard Worker 
313*c8dee2aaSAndroid Build Coastguard Worker         VkCommandBufferBeginInfo cmdBufferBeginInfo;
314*c8dee2aaSAndroid Build Coastguard Worker         memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo));
315*c8dee2aaSAndroid Build Coastguard Worker         cmdBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
316*c8dee2aaSAndroid Build Coastguard Worker         cmdBufferBeginInfo.pNext = nullptr;
317*c8dee2aaSAndroid Build Coastguard Worker         cmdBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
318*c8dee2aaSAndroid Build Coastguard Worker         cmdBufferBeginInfo.pInheritanceInfo = nullptr;
319*c8dee2aaSAndroid Build Coastguard Worker 
320*c8dee2aaSAndroid Build Coastguard Worker         GR_VK_CALL_ERRCHECK(gpu, BeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo));
321*c8dee2aaSAndroid Build Coastguard Worker         GR_VK_CALL_ERRCHECK(gpu, EndCommandBuffer(cmdBuffer));
322*c8dee2aaSAndroid Build Coastguard Worker 
323*c8dee2aaSAndroid Build Coastguard Worker         VkFenceCreateInfo fenceInfo;
324*c8dee2aaSAndroid Build Coastguard Worker         VkFence fence;
325*c8dee2aaSAndroid Build Coastguard Worker 
326*c8dee2aaSAndroid Build Coastguard Worker         memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
327*c8dee2aaSAndroid Build Coastguard Worker         fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
328*c8dee2aaSAndroid Build Coastguard Worker         err = GR_VK_CALL(interface, CreateFence(device, &fenceInfo, nullptr, &fence));
329*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!err);
330*c8dee2aaSAndroid Build Coastguard Worker 
331*c8dee2aaSAndroid Build Coastguard Worker         VkPipelineStageFlags waitStages = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
332*c8dee2aaSAndroid Build Coastguard Worker         VkSubmitInfo submitInfo;
333*c8dee2aaSAndroid Build Coastguard Worker         memset(&submitInfo, 0, sizeof(VkSubmitInfo));
334*c8dee2aaSAndroid Build Coastguard Worker         submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
335*c8dee2aaSAndroid Build Coastguard Worker         submitInfo.pNext = nullptr;
336*c8dee2aaSAndroid Build Coastguard Worker         submitInfo.waitSemaphoreCount = 1;
337*c8dee2aaSAndroid Build Coastguard Worker         VkSemaphore vkSem = GrBackendSemaphores::GetVkSemaphore(semaphore);
338*c8dee2aaSAndroid Build Coastguard Worker         submitInfo.pWaitSemaphores = &vkSem;
339*c8dee2aaSAndroid Build Coastguard Worker         submitInfo.pWaitDstStageMask = &waitStages;
340*c8dee2aaSAndroid Build Coastguard Worker         submitInfo.commandBufferCount = 1;
341*c8dee2aaSAndroid Build Coastguard Worker         submitInfo.pCommandBuffers = &cmdBuffer;
342*c8dee2aaSAndroid Build Coastguard Worker         submitInfo.signalSemaphoreCount = 0;
343*c8dee2aaSAndroid Build Coastguard Worker         submitInfo.pSignalSemaphores = nullptr;
344*c8dee2aaSAndroid Build Coastguard Worker         GR_VK_CALL_ERRCHECK(gpu, QueueSubmit(queue, 1, &submitInfo, fence));
345*c8dee2aaSAndroid Build Coastguard Worker 
346*c8dee2aaSAndroid Build Coastguard Worker         err = GR_VK_CALL(interface, WaitForFences(device, 1, &fence, true, 3000000000));
347*c8dee2aaSAndroid Build Coastguard Worker 
348*c8dee2aaSAndroid Build Coastguard Worker         REPORTER_ASSERT(reporter, err != VK_TIMEOUT);
349*c8dee2aaSAndroid Build Coastguard Worker 
350*c8dee2aaSAndroid Build Coastguard Worker         GR_VK_CALL(interface, DestroyFence(device, fence, nullptr));
351*c8dee2aaSAndroid Build Coastguard Worker         GR_VK_CALL(interface, DestroySemaphore(device, vkSem, nullptr));
352*c8dee2aaSAndroid Build Coastguard Worker         // If the above test fails the wait semaphore will never be signaled which can cause the
353*c8dee2aaSAndroid Build Coastguard Worker         // device to hang when tearing down (even if just tearing down GL). So we Fail here to
354*c8dee2aaSAndroid Build Coastguard Worker         // kill things.
355*c8dee2aaSAndroid Build Coastguard Worker         if (err == VK_TIMEOUT) {
356*c8dee2aaSAndroid Build Coastguard Worker             SK_ABORT("Waiting on semaphore indefinitely");
357*c8dee2aaSAndroid Build Coastguard Worker         }
358*c8dee2aaSAndroid Build Coastguard Worker     }
359*c8dee2aaSAndroid Build Coastguard Worker #endif
360*c8dee2aaSAndroid Build Coastguard Worker }
361