Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Enumerations | Functions | Variables
SurfaceSemaphoreTest.cpp File Reference
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/GrBackendSemaphore.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrTypes.h"
#include "include/gpu/ganesh/SkImageGanesh.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/private/base/SkTemplates.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include "tools/gpu/ContextType.h"
#include "tools/gpu/TestContext.h"
#include <cstring>
#include <cstdint>
#include <initializer_list>

Go to the source code of this file.

Enumerations

enum class  FlushType { kSurface , kImage , kContext }
 

Functions

void check_pixels (skiatest::Reporter *reporter, const SkBitmap &bitmap)
 
void draw_child (skiatest::Reporter *reporter, const sk_gpu_test::ContextInfo &childInfo, const GrBackendTexture &backendTexture, const GrBackendSemaphore &semaphore)
 
void 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)
 
 DEF_GANESH_TEST (SurfaceSemaphores, reporter, options, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (EmptySurfaceSemaphoreTest, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 

Variables

static const int MAIN_W = 8
 
static const int MAIN_H = 16
 
static const int CHILD_W = 16
 
static const int CHILD_H = 16
 

Enumeration Type Documentation

◆ FlushType

enum class FlushType
strong
Enumerator
kSurface 
kImage 
kContext 

Definition at line 142 of file SurfaceSemaphoreTest.cpp.

Function Documentation

◆ check_pixels()

void check_pixels ( skiatest::Reporter reporter,
const SkBitmap bitmap 
)

Definition at line 73 of file SurfaceSemaphoreTest.cpp.

73 {
74 const uint32_t* canvasPixels = static_cast<const uint32_t*>(bitmap.getPixels());
75
76 bool failureFound = false;
77 SkPMColor expectedPixel;
78 for (int cy = 0; cy < CHILD_H && !failureFound; ++cy) {
79 for (int cx = 0; cx < CHILD_W && !failureFound; ++cx) {
80 SkPMColor canvasPixel = canvasPixels[cy * CHILD_W + cx];
81 if (cy < CHILD_H / 2) {
82 if (cx < CHILD_W / 2) {
83 expectedPixel = 0xFF0000FF; // Red
84 } else {
85 expectedPixel = 0xFFFF0000; // Blue
86 }
87 } else {
88 expectedPixel = 0xFF00FF00; // Green
89 }
90 if (expectedPixel != canvasPixel) {
91 failureFound = true;
92 ERRORF(reporter, "Wrong color at %d, %d. Got 0x%08x when we expected 0x%08x",
93 cx, cy, canvasPixel, expectedPixel);
94 }
95 }
96 }
97}
reporter
uint32_t SkPMColor
Definition SkColor.h:205
static const int CHILD_W
static const int CHILD_H
#define ERRORF(r,...)
Definition Test.h:293

◆ DEF_GANESH_TEST()

DEF_GANESH_TEST ( SurfaceSemaphores  ,
reporter  ,
options  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 219 of file SurfaceSemaphoreTest.cpp.

219 {
220#if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_WIN) || defined(SK_BUILD_FOR_MAC)
221 static constexpr auto kNativeGLType = skgpu::ContextType::kGL;
222#else
223 static constexpr auto kNativeGLType = skgpu::ContextType::kGLES;
224#endif
225
226 for (int typeInt = 0; typeInt < skgpu::kContextTypeCount; ++typeInt) {
228 skgpu::ContextType contextType = static_cast<skgpu::ContextType>(typeInt);
229#ifdef SK_GL
230 // Use "native" instead of explicitly trying OpenGL and OpenGL ES. Do not use GLES on
231 // desktop since tests do not account for not fixing http://skbug.com/2809
232 if (contextType == skgpu::ContextType::kGL ||
233 contextType == skgpu::ContextType::kGLES) {
234 if (contextType != kNativeGLType) {
235 continue;
236 }
237 }
238#else
239 sk_ignore_unused_variable(kNativeGLType); // Do something to avoid unused variable
240#endif
242 sk_gpu_test::ContextInfo ctxInfo = factory.getContextInfo(contextType);
243 if (!skgpu::IsRenderingContext(contextType)) {
244 continue;
245 }
247 if (ctxInfo.directContext()) {
249 factory.getSharedContextInfo(ctxInfo.directContext(), 0);
251 factory.getSharedContextInfo(ctxInfo.directContext(), 1);
252 if (!child1.directContext() || !child2.directContext()) {
253 continue;
254 }
255
256 surface_semaphore_test(reporter, ctxInfo, child1, child2, flushType);
257 }
258 }
259 }
260}
const char * options
void sk_ignore_unused_variable(const T &)
Definition SkTemplates.h:37
void 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)
GrDirectContext * directContext() const
static const int kContextTypeCount
Definition ContextType.h:42
const char * ContextTypeName(skgpu::ContextType type)
bool IsRenderingContext(skgpu::ContextType type)

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS()

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( EmptySurfaceSemaphoreTest  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 262 of file SurfaceSemaphoreTest.cpp.

265 {
266 auto ctx = ctxInfo.directContext();
267 if (!ctx->priv().caps()->backendSemaphoreSupport()) {
268 // For example, the GL backend does not support these.
269 return;
270 }
271
274
276 ctx, skgpu::Budgeted::kNo, ii, 0, kTopLeft_GrSurfaceOrigin, nullptr));
277
278 // Flush surface once without semaphores to make sure there is no pending IO for it.
279 ctx->flushAndSubmit(mainSurface.get(), GrSyncCpu::kNo);
280
281 GrBackendSemaphore semaphore;
282 GrFlushInfo flushInfo;
283 flushInfo.fNumSemaphores = 1;
284 flushInfo.fSignalSemaphores = &semaphore;
285 GrSemaphoresSubmitted submitted =
286 ctx->flush(mainSurface.get(), SkSurfaces::BackendSurfaceAccess::kNoAccess, flushInfo);
288 ctx->submit();
289
290#ifdef SK_VULKAN
291 if (GrBackendApi::kVulkan == ctxInfo.backend()) {
292 GrVkGpu* gpu = static_cast<GrVkGpu*>(ctx->priv().getGpu());
293 const skgpu::VulkanInterface* interface = gpu->vkInterface();
294 VkDevice device = gpu->device();
295 VkQueue queue = gpu->queue();
296 GrVkCommandPool* cmdPool = gpu->cmdPool();
297 VkCommandBuffer cmdBuffer;
298
299 // Create Command Buffer
300 const VkCommandBufferAllocateInfo cmdInfo = {
302 nullptr, // pNext
303 cmdPool->vkCommandPool(), // commandPool
305 1 // bufferCount
306 };
307
308 VkResult err = GR_VK_CALL(interface, AllocateCommandBuffers(device, &cmdInfo, &cmdBuffer));
309 if (err) {
310 return;
311 }
312
313 VkCommandBufferBeginInfo cmdBufferBeginInfo;
314 memset(&cmdBufferBeginInfo, 0, sizeof(VkCommandBufferBeginInfo));
316 cmdBufferBeginInfo.pNext = nullptr;
318 cmdBufferBeginInfo.pInheritanceInfo = nullptr;
319
320 GR_VK_CALL_ERRCHECK(gpu, BeginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo));
321 GR_VK_CALL_ERRCHECK(gpu, EndCommandBuffer(cmdBuffer));
322
323 VkFenceCreateInfo fenceInfo;
324 VkFence fence;
325
326 memset(&fenceInfo, 0, sizeof(VkFenceCreateInfo));
328 err = GR_VK_CALL(interface, CreateFence(device, &fenceInfo, nullptr, &fence));
329 SkASSERT(!err);
330
332 VkSubmitInfo submitInfo;
333 memset(&submitInfo, 0, sizeof(VkSubmitInfo));
335 submitInfo.pNext = nullptr;
336 submitInfo.waitSemaphoreCount = 1;
337 VkSemaphore vkSem = GrBackendSemaphores::GetVkSemaphore(semaphore);
338 submitInfo.pWaitSemaphores = &vkSem;
339 submitInfo.pWaitDstStageMask = &waitStages;
340 submitInfo.commandBufferCount = 1;
341 submitInfo.pCommandBuffers = &cmdBuffer;
342 submitInfo.signalSemaphoreCount = 0;
343 submitInfo.pSignalSemaphores = nullptr;
344 GR_VK_CALL_ERRCHECK(gpu, QueueSubmit(queue, 1, &submitInfo, fence));
345
346 err = GR_VK_CALL(interface, WaitForFences(device, 1, &fence, true, 3000000000));
347
349
350 GR_VK_CALL(interface, DestroyFence(device, fence, nullptr));
351 GR_VK_CALL(interface, DestroySemaphore(device, vkSem, nullptr));
352 // If the above test fails the wait semaphore will never be signaled which can cause the
353 // device to hang when tearing down (even if just tearing down GL). So we Fail here to
354 // kill things.
355 if (err == VK_TIMEOUT) {
356 SK_ABORT("Waiting on semaphore indefinitely");
357 }
358 }
359#endif
360}
@ kTopLeft_GrSurfaceOrigin
Definition GrTypes.h:148
GrSemaphoresSubmitted
Definition GrTypes.h:229
#define GR_VK_CALL(IFACE, X)
Definition GrVkUtil.h:24
#define GR_VK_CALL_ERRCHECK(GPU, X)
Definition GrVkUtil.h:50
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
#define SK_ABORT(message,...)
Definition SkAssert.h:70
#define SkASSERT(cond)
Definition SkAssert.h:116
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
static const int MAIN_H
static const int MAIN_W
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
VkCommandPool vkCommandPool() const
VkDevice device() const
Definition GrVkGpu.h:71
GrVkCommandPool * cmdPool() const
Definition GrVkGpu.h:74
VkQueue queue() const
Definition GrVkGpu.h:72
VkDevice device
Definition main.cc:53
VkQueue queue
Definition main.cc:55
SK_API VkSemaphore GetVkSemaphore(const GrBackendSemaphore &)
@ kNoAccess
back-end surface will not be used by client
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
GrBackendSemaphore * fSignalSemaphores
Definition GrTypes.h:218
size_t fNumSemaphores
Definition GrTypes.h:217
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
const VkCommandBufferInheritanceInfo * pInheritanceInfo
VkCommandBufferUsageFlags flags
VkStructureType sType
uint32_t waitSemaphoreCount
const VkPipelineStageFlags * pWaitDstStageMask
uint32_t commandBufferCount
const VkSemaphore * pWaitSemaphores
uint32_t signalSemaphoreCount
const VkCommandBuffer * pCommandBuffers
const void * pNext
const VkSemaphore * pSignalSemaphores
VkStructureType sType
VkFlags VkPipelineStageFlags
@ VK_COMMAND_BUFFER_LEVEL_PRIMARY
@ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
VkResult
@ VK_TIMEOUT
@ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
@ VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO
@ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO
@ VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
@ VK_STRUCTURE_TYPE_SUBMIT_INFO

◆ draw_child()

void draw_child ( skiatest::Reporter reporter,
const sk_gpu_test::ContextInfo childInfo,
const GrBackendTexture backendTexture,
const GrBackendSemaphore semaphore 
)

Definition at line 99 of file SurfaceSemaphoreTest.cpp.

102 {
103
104 childInfo.testContext()->makeCurrent();
105
108
109 auto childDContext = childInfo.directContext();
111 childDContext, skgpu::Budgeted::kNo, childII, 0, kTopLeft_GrSurfaceOrigin, nullptr));
112
113 sk_sp<SkImage> childImage = SkImages::BorrowTextureFrom(childDContext,
114 backendTexture,
118 nullptr,
119 nullptr,
120 nullptr);
121
122 SkCanvas* childCanvas = childSurface->getCanvas();
123 childCanvas->clear(SK_ColorRED);
124
125 childSurface->wait(1, &semaphore);
126
127 childCanvas->drawImage(childImage, CHILD_W/2, 0);
128
130 paint.setColor(SK_ColorGREEN);
132 childCanvas->drawIRect(rect, paint);
133
134 // read pixels
136 bitmap.allocPixels(childII);
137 childSurface->readPixels(bitmap, 0, 0);
138
140}
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition SkColor.h:131
void check_pixels(skiatest::Reporter *reporter, const SkBitmap &bitmap)
void drawIRect(const SkIRect &rect, const SkPaint &paint)
Definition SkCanvas.h:1358
void clear(SkColor color)
Definition SkCanvas.h:1199
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1528
TestContext * testContext() const
const Paint & paint
SK_API sk_sp< SkImage > BorrowTextureFrom(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, SkColorType colorType, SkAlphaType alphaType, sk_sp< SkColorSpace > colorSpace, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350
static constexpr SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
Definition SkRect.h:91

◆ surface_semaphore_test()

void 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 
)

Definition at line 144 of file SurfaceSemaphoreTest.cpp.

148 {
149 auto mainCtx = mainInfo.directContext();
150 if (!mainCtx->priv().caps()->backendSemaphoreSupport()) {
151 return;
152 }
153
156
158 mainCtx, skgpu::Budgeted::kNo, ii, 0, kTopLeft_GrSurfaceOrigin, nullptr));
159 SkCanvas* mainCanvas = mainSurface->getCanvas();
160 auto blueSurface = mainSurface->makeSurface(ii);
161 blueSurface->getCanvas()->clear(SK_ColorBLUE);
162 auto blueImage = blueSurface->makeImageSnapshot();
163 blueSurface.reset();
164 mainCanvas->drawImage(blueImage, 0, 0);
165
166 AutoTArray<GrBackendSemaphore> semaphores(2);
167#ifdef SK_VULKAN
168 if (GrBackendApi::kVulkan == mainInfo.backend()) {
169 // Initialize the secondary semaphore instead of having Ganesh create one internally
170 GrVkGpu* gpu = static_cast<GrVkGpu*>(mainCtx->priv().getGpu());
171 VkDevice device = gpu->device();
172
173 VkSemaphore vkSem;
174
175 VkSemaphoreCreateInfo createInfo;
177 createInfo.pNext = nullptr;
178 createInfo.flags = 0;
179 GR_VK_CALL_ERRCHECK(gpu, CreateSemaphore(device, &createInfo, nullptr, &vkSem));
180
181 semaphores[1] = GrBackendSemaphores::MakeVk(vkSem);
182 }
183#endif
184
187 info.fSignalSemaphores = semaphores.get();
188 switch (flushType) {
190 mainCtx->flush(mainSurface.get(), SkSurfaces::BackendSurfaceAccess::kNoAccess, info);
191 break;
193 mainCtx->flush(blueImage, info);
194 break;
196 mainCtx->flush(info);
197 break;
198 }
199 mainCtx->submit();
200
203
204 draw_child(reporter, childInfo1, backendTexture, semaphores[0]);
205
206#ifdef SK_VULKAN
207 if (GrBackendApi::kVulkan == mainInfo.backend()) {
208 // In Vulkan we need to make sure we are sending the correct VkImageLayout in with the
209 // backendImage. After the first child draw the layout gets changed to SHADER_READ, so
210 // we just manually set that here.
213 }
214#endif
215
216 draw_child(reporter, childInfo2, backendTexture, semaphores[1]);
217}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
constexpr SkColor SK_ColorBLUE
Definition SkColor.h:135
void draw_child(skiatest::Reporter *reporter, const sk_gpu_test::ContextInfo &childInfo, const GrBackendTexture &backendTexture, const GrBackendSemaphore &semaphore)
sk_sp< SkSurface > makeSurface(const SkImageInfo &info, const SkSurfaceProps *props=nullptr)
SkCanvas * getCanvas()
Definition SkSurface.cpp:82
@ kFlushRead
back-end object is readable
GrBackendApi backend() const
SK_API GrBackendSemaphore MakeVk(VkSemaphore semaphore)
SK_API void SetVkImageLayout(GrBackendTexture *, VkImageLayout)
SK_API GrBackendTexture GetBackendTexture(SkSurface *, BackendHandleAccess)
VkStructureType sType
VkSemaphoreCreateFlags flags
@ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
@ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO

Variable Documentation

◆ CHILD_H

const int CHILD_H = 16
static

Definition at line 71 of file SurfaceSemaphoreTest.cpp.

◆ CHILD_W

const int CHILD_W = 16
static

Definition at line 71 of file SurfaceSemaphoreTest.cpp.

◆ MAIN_H

const int MAIN_H = 16
static

Definition at line 70 of file SurfaceSemaphoreTest.cpp.

◆ MAIN_W

const int MAIN_W = 8
static

Definition at line 70 of file SurfaceSemaphoreTest.cpp.