Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
GraphiteVulkanWindowContext.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023 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
9
29#include "tools/GpuToolUtils.h"
30#include "tools/ToolUtils.h"
31
32#ifdef VK_USE_PLATFORM_WIN32_KHR
33// windows wants to define this as CreateSemaphoreA or CreateSemaphoreW
34#undef CreateSemaphore
35#endif
36
37#define GET_PROC(F) f ## F = \
38 (PFN_vk ## F) backendContext.fGetProc("vk" #F, fInstance, VK_NULL_HANDLE)
39#define GET_DEV_PROC(F) f ## F = \
40 (PFN_vk ## F) backendContext.fGetProc("vk" #F, VK_NULL_HANDLE, fDevice)
41
42namespace skwindow::internal {
43
44GraphiteVulkanWindowContext::GraphiteVulkanWindowContext(const DisplayParams& params,
45 CreateVkSurfaceFn createVkSurface,
46 CanPresentFn canPresent,
48 : WindowContext(params)
49 , fCreateVkSurfaceFn(std::move(createVkSurface))
50 , fCanPresentFn(std::move(canPresent))
51 , fSurface(VK_NULL_HANDLE)
52 , fSwapchain(VK_NULL_HANDLE)
53 , fImages(nullptr)
54 , fImageLayouts(nullptr)
55 , fSurfaces(nullptr)
56 , fBackbuffers(nullptr) {
57 fGetInstanceProcAddr = instProc;
58 this->initializeContext();
59}
60
61void GraphiteVulkanWindowContext::initializeContext() {
62 SkASSERT(!fGraphiteContext && !fGraphiteRecorder);
63 // any config code here (particularly for msaa)?
64
65 PFN_vkGetInstanceProcAddr getInstanceProc = fGetInstanceProcAddr;
66 skgpu::VulkanBackendContext backendContext;
67 skgpu::VulkanExtensions extensions;
69 if (!sk_gpu_test::CreateVkBackendContext(getInstanceProc, &backendContext, &extensions,
70 &features, &fDebugCallback, &fPresentQueueIndex,
71 fCanPresentFn,
72 fDisplayParams.fCreateProtectedNativeBackend)) {
73 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
74 return;
75 }
76
77 if (!extensions.hasExtension(VK_KHR_SURFACE_EXTENSION_NAME, 25) ||
78 !extensions.hasExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME, 68)) {
79 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
80 return;
81 }
82
83 fInstance = backendContext.fInstance;
84 fPhysicalDevice = backendContext.fPhysicalDevice;
85 fDevice = backendContext.fDevice;
86 fGraphicsQueueIndex = backendContext.fGraphicsQueueIndex;
87 fGraphicsQueue = backendContext.fQueue;
88
89 PFN_vkGetPhysicalDeviceProperties localGetPhysicalDeviceProperties =
90 reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(
91 backendContext.fGetProc("vkGetPhysicalDeviceProperties",
92 backendContext.fInstance,
94 if (!localGetPhysicalDeviceProperties) {
95 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
96 return;
97 }
98 VkPhysicalDeviceProperties physDeviceProperties;
99 localGetPhysicalDeviceProperties(backendContext.fPhysicalDevice, &physDeviceProperties);
100 uint32_t physDevVersion = physDeviceProperties.apiVersion;
101
102 fInterface.reset(new skgpu::VulkanInterface(backendContext.fGetProc, fInstance, fDevice,
103 backendContext.fMaxAPIVersion, physDevVersion,
104 &extensions));
105
106 GET_PROC(DestroyInstance);
107 if (fDebugCallback != VK_NULL_HANDLE) {
108 GET_PROC(DestroyDebugReportCallbackEXT);
109 }
110 GET_PROC(DestroySurfaceKHR);
111 GET_PROC(GetPhysicalDeviceSurfaceSupportKHR);
112 GET_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
113 GET_PROC(GetPhysicalDeviceSurfaceFormatsKHR);
114 GET_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
115 GET_DEV_PROC(DeviceWaitIdle);
116 GET_DEV_PROC(QueueWaitIdle);
117 GET_DEV_PROC(DestroyDevice);
118 GET_DEV_PROC(CreateSwapchainKHR);
119 GET_DEV_PROC(DestroySwapchainKHR);
120 GET_DEV_PROC(GetSwapchainImagesKHR);
121 GET_DEV_PROC(AcquireNextImageKHR);
122 GET_DEV_PROC(QueuePresentKHR);
123 GET_DEV_PROC(GetDeviceQueue);
124
125 skgpu::graphite::ContextOptions contextOptions;
126 skgpu::graphite::ContextOptionsPriv contextOptionsPriv;
127 // Needed to make synchronous readPixels work
128 contextOptionsPriv.fStoreContextRefInRecorder = true;
129 contextOptions.fOptionsPriv = &contextOptionsPriv;
130 fGraphiteContext = skgpu::graphite::ContextFactory::MakeVulkan(backendContext, contextOptions);
131 fGraphiteRecorder = fGraphiteContext->makeRecorder(ToolUtils::CreateTestingRecorderOptions());
132
133 fSurface = fCreateVkSurfaceFn(fInstance);
134 if (VK_NULL_HANDLE == fSurface) {
135 this->destroyContext();
136 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
137 return;
138 }
139
140 VkBool32 supported;
141 VkResult res = fGetPhysicalDeviceSurfaceSupportKHR(fPhysicalDevice, fPresentQueueIndex,
142 fSurface, &supported);
143 if (VK_SUCCESS != res) {
144 this->destroyContext();
145 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
146 return;
147 }
148
149 if (!this->createSwapchain(-1, -1, fDisplayParams)) {
150 this->destroyContext();
151 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
152 return;
153 }
154
155 // create presentQueue
156 fGetDeviceQueue(fDevice, fPresentQueueIndex, 0, &fPresentQueue);
157 sk_gpu_test::FreeVulkanFeaturesStructs(&features);
158}
159
160bool GraphiteVulkanWindowContext::createSwapchain(int width, int height,
161 const DisplayParams& params) {
162 // check for capabilities
164 VkResult res = fGetPhysicalDeviceSurfaceCapabilitiesKHR(fPhysicalDevice, fSurface, &caps);
165 if (VK_SUCCESS != res) {
166 return false;
167 }
168
169 uint32_t surfaceFormatCount;
170 res = fGetPhysicalDeviceSurfaceFormatsKHR(fPhysicalDevice, fSurface, &surfaceFormatCount,
171 nullptr);
172 if (VK_SUCCESS != res) {
173 return false;
174 }
175
176 SkAutoMalloc surfaceFormatAlloc(surfaceFormatCount * sizeof(VkSurfaceFormatKHR));
177 VkSurfaceFormatKHR* surfaceFormats = (VkSurfaceFormatKHR*)surfaceFormatAlloc.get();
178 res = fGetPhysicalDeviceSurfaceFormatsKHR(fPhysicalDevice, fSurface, &surfaceFormatCount,
179 surfaceFormats);
180 if (VK_SUCCESS != res) {
181 return false;
182 }
183
184 uint32_t presentModeCount;
185 res = fGetPhysicalDeviceSurfacePresentModesKHR(fPhysicalDevice, fSurface, &presentModeCount,
186 nullptr);
187 if (VK_SUCCESS != res) {
188 return false;
189 }
190
191 SkAutoMalloc presentModeAlloc(presentModeCount * sizeof(VkPresentModeKHR));
192 VkPresentModeKHR* presentModes = (VkPresentModeKHR*)presentModeAlloc.get();
193 res = fGetPhysicalDeviceSurfacePresentModesKHR(fPhysicalDevice, fSurface, &presentModeCount,
194 presentModes);
195 if (VK_SUCCESS != res) {
196 return false;
197 }
198
199 VkExtent2D extent = caps.currentExtent;
200 // use the hints
201 if (extent.width == (uint32_t)-1) {
202 extent.width = width;
203 extent.height = height;
204 }
205
206 // clamp width; to protect us from broken hints
207 if (extent.width < caps.minImageExtent.width) {
208 extent.width = caps.minImageExtent.width;
209 } else if (extent.width > caps.maxImageExtent.width) {
210 extent.width = caps.maxImageExtent.width;
211 }
212 // clamp height
213 if (extent.height < caps.minImageExtent.height) {
214 extent.height = caps.minImageExtent.height;
215 } else if (extent.height > caps.maxImageExtent.height) {
216 extent.height = caps.maxImageExtent.height;
217 }
218
219 fWidth = (int)extent.width;
220 fHeight = (int)extent.height;
221
222 uint32_t imageCount = caps.minImageCount + 2;
223 if (caps.maxImageCount > 0 && imageCount > caps.maxImageCount) {
224 // Application must settle for fewer images than desired:
225 imageCount = caps.maxImageCount;
226 }
227
231 SkASSERT((caps.supportedUsageFlags & usageFlags) == usageFlags);
234 }
236 usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
237 }
241 VkCompositeAlphaFlagBitsKHR composite_alpha =
245
246 // Pick our surface format.
247 VkFormat surfaceFormat = VK_FORMAT_UNDEFINED;
249 for (uint32_t i = 0; i < surfaceFormatCount; ++i) {
250 VkFormat localFormat = surfaceFormats[i].format;
251 if (skgpu::graphite::vkFormatIsSupported(localFormat)) {
252 surfaceFormat = localFormat;
253 colorSpace = surfaceFormats[i].colorSpace;
254 break;
255 }
256 }
257 fDisplayParams = params;
258 fSampleCount = std::max(1, params.fMSAASampleCount);
259 fStencilBits = 8;
260
261 if (VK_FORMAT_UNDEFINED == surfaceFormat) {
262 return false;
263 }
264
266 switch (surfaceFormat) {
267 case VK_FORMAT_R8G8B8A8_UNORM: // fall through
270 break;
271 case VK_FORMAT_B8G8R8A8_UNORM: // fall through
273 break;
274 default:
275 return false;
276 }
277
278 // If mailbox mode is available, use it, as it is the lowest-latency non-
279 // tearing mode. If not, fall back to FIFO which is always available.
281 bool hasImmediate = false;
282 for (uint32_t i = 0; i < presentModeCount; ++i) {
283 // use mailbox
284 if (VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) {
286 }
287 if (VK_PRESENT_MODE_IMMEDIATE_KHR == presentModes[i]) {
288 hasImmediate = true;
289 }
290 }
291 if (params.fDisableVsync && hasImmediate) {
293 }
294
295 VkSwapchainCreateInfoKHR swapchainCreateInfo;
296 memset(&swapchainCreateInfo, 0, sizeof(VkSwapchainCreateInfoKHR));
298 swapchainCreateInfo.flags = fDisplayParams.fCreateProtectedNativeBackend
300 : 0;
301 swapchainCreateInfo.surface = fSurface;
302 swapchainCreateInfo.minImageCount = imageCount;
303 swapchainCreateInfo.imageFormat = surfaceFormat;
304 swapchainCreateInfo.imageColorSpace = colorSpace;
305 swapchainCreateInfo.imageExtent = extent;
306 swapchainCreateInfo.imageArrayLayers = 1;
307 swapchainCreateInfo.imageUsage = usageFlags;
308
309 uint32_t queueFamilies[] = { fGraphicsQueueIndex, fPresentQueueIndex };
310 if (fGraphicsQueueIndex != fPresentQueueIndex) {
311 swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
312 swapchainCreateInfo.queueFamilyIndexCount = 2;
313 swapchainCreateInfo.pQueueFamilyIndices = queueFamilies;
314 } else {
315 swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
316 swapchainCreateInfo.queueFamilyIndexCount = 0;
317 swapchainCreateInfo.pQueueFamilyIndices = nullptr;
318 }
319
321 swapchainCreateInfo.compositeAlpha = composite_alpha;
322 swapchainCreateInfo.presentMode = mode;
323 swapchainCreateInfo.clipped = true;
324 swapchainCreateInfo.oldSwapchain = fSwapchain;
325
326 res = fCreateSwapchainKHR(fDevice, &swapchainCreateInfo, nullptr, &fSwapchain);
327 if (VK_SUCCESS != res) {
328 return false;
329 }
330
331 // destroy the old swapchain
332 if (swapchainCreateInfo.oldSwapchain != VK_NULL_HANDLE) {
333 fDeviceWaitIdle(fDevice);
334
335 this->destroyBuffers();
336
337 fDestroySwapchainKHR(fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
338 swapchainCreateInfo.oldSwapchain = VK_NULL_HANDLE;
339 }
340
341 if (!this->createBuffers(swapchainCreateInfo.imageFormat, usageFlags, colorType,
342 swapchainCreateInfo.imageSharingMode)) {
343 fDeviceWaitIdle(fDevice);
344
345 this->destroyBuffers();
346
347 fDestroySwapchainKHR(fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
348 swapchainCreateInfo.oldSwapchain = VK_NULL_HANDLE;
349 }
350
351 return true;
352}
353
354bool GraphiteVulkanWindowContext::createBuffers(VkFormat format,
355 VkImageUsageFlags usageFlags,
357 VkSharingMode sharingMode) {
358 fGetSwapchainImagesKHR(fDevice, fSwapchain, &fImageCount, nullptr);
359 SkASSERT(fImageCount);
360 fImages = new VkImage[fImageCount];
361 fGetSwapchainImagesKHR(fDevice, fSwapchain, &fImageCount, fImages);
362
363 // set up initial image layouts and create surfaces
364 fImageLayouts = new VkImageLayout[fImageCount];
365 fSurfaces = new sk_sp<SkSurface>[fImageCount];
366 for (uint32_t i = 0; i < fImageCount; ++i) {
367 fImageLayouts[i] = VK_IMAGE_LAYOUT_UNDEFINED;
368
371 info.fFormat = format;
372 info.fImageUsageFlags = usageFlags;
373 info.fSharingMode = sharingMode;
374 info.fFlags = fDisplayParams.fCreateProtectedNativeBackend ? VK_IMAGE_CREATE_PROTECTED_BIT
375 : 0;
376
377 skgpu::graphite::BackendTexture backendTex(this->dimensions(),
378 info,
380 fPresentQueueIndex,
381 fImages[i],
383
384 fSurfaces[i] = SkSurfaces::WrapBackendTexture(this->graphiteRecorder(),
385 backendTex,
386 colorType,
387 fDisplayParams.fColorSpace,
388 &fDisplayParams.fSurfaceProps);
389
390 if (!fSurfaces[i]) {
391 return false;
392 }
393 }
394
395 // set up the backbuffers
396 VkSemaphoreCreateInfo semaphoreInfo;
397 memset(&semaphoreInfo, 0, sizeof(VkSemaphoreCreateInfo));
399 semaphoreInfo.pNext = nullptr;
400 semaphoreInfo.flags = 0;
401
402 // we create one additional backbuffer structure here, because we want to
403 // give the command buffers they contain a chance to finish before we cycle back
404 fBackbuffers = new BackbufferInfo[fImageCount + 1];
405 for (uint32_t i = 0; i < fImageCount + 1; ++i) {
406 fBackbuffers[i].fImageIndex = -1;
409 fInterface,
410 result,
411 CreateSemaphore(
412 fDevice, &semaphoreInfo, nullptr, &fBackbuffers[i].fRenderSemaphore));
413 }
414 fCurrentBackbufferIndex = fImageCount;
415
416 return true;
417}
418
419void GraphiteVulkanWindowContext::destroyBuffers() {
420 if (fBackbuffers) {
421 for (uint32_t i = 0; i < fImageCount + 1; ++i) {
422 fBackbuffers[i].fImageIndex = -1;
423 VULKAN_CALL(fInterface,
424 DestroySemaphore(fDevice,
425 fBackbuffers[i].fRenderSemaphore,
426 nullptr));
427 }
428 }
429
430 delete[] fBackbuffers;
431 fBackbuffers = nullptr;
432
433 // Does this actually free the surfaces?
434 delete[] fSurfaces;
435 fSurfaces = nullptr;
436 delete[] fImageLayouts;
437 fImageLayouts = nullptr;
438 delete[] fImages;
439 fImages = nullptr;
440}
441
442GraphiteVulkanWindowContext::~GraphiteVulkanWindowContext() {
443 this->destroyContext();
444}
445
446void GraphiteVulkanWindowContext::destroyContext() {
447 if (this->isValid()) {
448 fQueueWaitIdle(fPresentQueue);
449 fDeviceWaitIdle(fDevice);
450
451 if (fWaitSemaphore != VK_NULL_HANDLE) {
452 VULKAN_CALL(fInterface, DestroySemaphore(fDevice, fWaitSemaphore, nullptr));
453 fWaitSemaphore = VK_NULL_HANDLE;
454 }
455
456 this->destroyBuffers();
457
458 if (fSwapchain != VK_NULL_HANDLE) {
459 fDestroySwapchainKHR(fDevice, fSwapchain, nullptr);
460 fSwapchain = VK_NULL_HANDLE;
461 }
462
463 if (fSurface != VK_NULL_HANDLE) {
464 fDestroySurfaceKHR(fInstance, fSurface, nullptr);
465 fSurface = VK_NULL_HANDLE;
466 }
467 }
468
469 if (fGraphiteContext) {
470 fGraphiteRecorder.reset();
471 fGraphiteContext.reset();
472 }
473 fInterface.reset();
474
475 if (fDevice != VK_NULL_HANDLE) {
476 fDestroyDevice(fDevice, nullptr);
477 fDevice = VK_NULL_HANDLE;
478 }
479
480#ifdef SK_ENABLE_VK_LAYERS
481 if (fDebugCallback != VK_NULL_HANDLE) {
482 fDestroyDebugReportCallbackEXT(fInstance, fDebugCallback, nullptr);
483 }
484#endif
485
486 fPhysicalDevice = VK_NULL_HANDLE;
487
488 if (fInstance != VK_NULL_HANDLE) {
489 fDestroyInstance(fInstance, nullptr);
490 fInstance = VK_NULL_HANDLE;
491 }
492}
493
494GraphiteVulkanWindowContext::BackbufferInfo* GraphiteVulkanWindowContext::getAvailableBackbuffer() {
495 SkASSERT(fBackbuffers);
496
497 ++fCurrentBackbufferIndex;
498 if (fCurrentBackbufferIndex > fImageCount) {
499 fCurrentBackbufferIndex = 0;
500 }
501
502 BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
503 return backbuffer;
504}
505
506sk_sp<SkSurface> GraphiteVulkanWindowContext::getBackbufferSurface() {
507 BackbufferInfo* backbuffer = this->getAvailableBackbuffer();
508 SkASSERT(backbuffer);
509
510 // semaphores should be in unsignaled state
511 VkSemaphoreCreateInfo semaphoreInfo;
512 memset(&semaphoreInfo, 0, sizeof(VkSemaphoreCreateInfo));
514 semaphoreInfo.pNext = nullptr;
515 semaphoreInfo.flags = 0;
518 fInterface, result, CreateSemaphore(fDevice, &semaphoreInfo, nullptr, &fWaitSemaphore));
519
520 // acquire the image
521 VkResult res = fAcquireNextImageKHR(fDevice, fSwapchain, UINT64_MAX,
522 fWaitSemaphore, VK_NULL_HANDLE,
523 &backbuffer->fImageIndex);
524 if (VK_ERROR_SURFACE_LOST_KHR == res) {
525 // TODO: Recreate fSurface using fCreateVkSurfaceFn, and then rebuild the swapchain
526 VULKAN_CALL(fInterface, DestroySemaphore(fDevice, fWaitSemaphore, nullptr));
527 return nullptr;
528 }
529 if (VK_ERROR_OUT_OF_DATE_KHR == res) {
530 // tear swapchain down and try again
531 if (!this->createSwapchain(-1, -1, fDisplayParams)) {
532 VULKAN_CALL(fInterface, DestroySemaphore(fDevice, fWaitSemaphore, nullptr));
533 return nullptr;
534 }
535 backbuffer = this->getAvailableBackbuffer();
536
537 // acquire the image
538 res = fAcquireNextImageKHR(fDevice, fSwapchain, UINT64_MAX,
539 fWaitSemaphore, VK_NULL_HANDLE,
540 &backbuffer->fImageIndex);
541
542 if (VK_SUCCESS != res) {
543 VULKAN_CALL(fInterface, DestroySemaphore(fDevice, fWaitSemaphore, nullptr));
544 return nullptr;
545 }
546 }
547
548 SkSurface* surface = fSurfaces[backbuffer->fImageIndex].get();
549
550 return sk_ref_sp(surface);
551}
552
553void GraphiteVulkanWindowContext::onSwapBuffers() {
554 if (!fGraphiteContext) {
555 return;
556 }
557 SkASSERT(fGraphiteRecorder);
558
559 BackbufferInfo* backbuffer = fBackbuffers + fCurrentBackbufferIndex;
560
561 std::unique_ptr<skgpu::graphite::Recording> recording = fGraphiteRecorder->snap();
562 if (recording) {
564 info.fRecording = recording.get();
565
566 // set up surface for layout transition
567 info.fTargetSurface = fSurfaces[backbuffer->fImageIndex].get();
569 VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, fPresentQueueIndex);
570 info.fTargetTextureState = &presentState;
571
572 SkASSERT(fWaitSemaphore != VK_NULL_HANDLE);
573 skgpu::graphite::BackendSemaphore beWaitSemaphore(fWaitSemaphore);
574 info.fNumWaitSemaphores = 1;
575 info.fWaitSemaphores = &beWaitSemaphore;
576 skgpu::graphite::BackendSemaphore beSignalSemaphore(backbuffer->fRenderSemaphore);
577 info.fNumSignalSemaphores = 1;
578 info.fSignalSemaphores = &beSignalSemaphore;
579
580 // Insert finishedProc to delete waitSemaphore when done
581 struct FinishContext {
583 VkDevice device;
584 VkSemaphore waitSemaphore;
585 };
586 auto* finishContext = new FinishContext{fInterface, fDevice, fWaitSemaphore};
588 skgpu::CallbackResult status) {
589 // regardless of the status we need to destroy the semaphore
590 const auto* context = reinterpret_cast<const FinishContext*>(c);
591 VULKAN_CALL(context->interface,
592 DestroySemaphore(context->device, context->waitSemaphore, nullptr));
593 };
594 info.fFinishedContext = finishContext;
595 info.fFinishedProc = finishCallback;
596
597 fGraphiteContext->insertRecording(info);
598 fGraphiteContext->submit(skgpu::graphite::SyncToCpu::kNo);
599 fWaitSemaphore = VK_NULL_HANDLE; // FinishCallback will destroy this
600 }
601
602 // Submit present operation to present queue
603 const VkPresentInfoKHR presentInfo =
604 {
606 nullptr, // pNext
607 1, // waitSemaphoreCount
608 &backbuffer->fRenderSemaphore, // pWaitSemaphores
609 1, // swapchainCount
610 &fSwapchain, // pSwapchains
611 &backbuffer->fImageIndex, // pImageIndices
612 nullptr // pResults
613 };
614
615 fQueuePresentKHR(fPresentQueue, &presentInfo);
616}
617
618} //namespace skwindow::internal
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
#define GET_DEV_PROC(F)
#define SkASSERT(cond)
Definition SkAssert.h:116
SkColorType
Definition SkColorType.h:19
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition SkColorType.h:26
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
#define VULKAN_CALL(IFACE, X)
#define VULKAN_CALL_RESULT_NOCHECK(IFACE, RESULT, X)
Type::kYUV Type::kRGBA() int(0.7 *637)
void * get()
const EmbeddedViewParams * params
VkDevice device
Definition main.cc:53
VkSurfaceKHR surface
Definition main.cc:49
GAsyncResult * result
uint32_t uint32_t * format
SK_API sk_sp< SkSurface > WrapBackendTexture(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, int sampleCnt, SkColorType colorType, sk_sp< SkColorSpace > colorSpace, const SkSurfaceProps *surfaceProps, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
SK_API MutableTextureState MakeVulkan(VkImageLayout layout, uint32_t queueFamilyIndex)
SK_API std::unique_ptr< Context > MakeVulkan(const VulkanBackendContext &, const ContextOptions &)
bool vkFormatIsSupported(VkFormat format)
void * GpuFinishedContext
void(*)(GpuFinishedContext finishedContext, CallbackResult) GpuFinishedProc
CallbackResult
Definition GpuTypes.h:45
int32_t height
int32_t width
uint32_t width
uint32_t height
VkStructureType sType
VkSemaphoreCreateFlags flags
VkSurfaceTransformFlagBitsKHR currentTransform
VkCompositeAlphaFlagsKHR supportedCompositeAlpha
VkSurfaceTransformFlagsKHR supportedTransforms
VkImageUsageFlags supportedUsageFlags
VkColorSpaceKHR colorSpace
VkPresentModeKHR presentMode
VkImageUsageFlags imageUsage
VkSharingMode imageSharingMode
VkSwapchainCreateFlagsKHR flags
VkSwapchainKHR oldSwapchain
VkColorSpaceKHR imageColorSpace
VkSurfaceTransformFlagBitsKHR preTransform
const uint32_t * pQueueFamilyIndices
VkCompositeAlphaFlagBitsKHR compositeAlpha
ContextOptionsPriv * fOptionsPriv
@ VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR
VkImageLayout
@ VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
@ VK_IMAGE_LAYOUT_UNDEFINED
VkSharingMode
@ VK_SHARING_MODE_CONCURRENT
@ VK_SHARING_MODE_EXCLUSIVE
VkFlags VkImageUsageFlags
@ VK_IMAGE_CREATE_PROTECTED_BIT
@ VK_IMAGE_TILING_OPTIMAL
#define VK_KHR_SURFACE_EXTENSION_NAME
void(VKAPI_PTR * PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties *pProperties)
@ VK_IMAGE_USAGE_TRANSFER_DST_BIT
@ VK_IMAGE_USAGE_SAMPLED_BIT
@ VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
@ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
@ VK_IMAGE_USAGE_TRANSFER_SRC_BIT
VkCompositeAlphaFlagBitsKHR
@ VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR
@ VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR
VkResult
@ VK_SUCCESS
@ VK_ERROR_OUT_OF_DATE_KHR
@ VK_ERROR_SURFACE_LOST_KHR
@ VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
VkPresentModeKHR
@ VK_PRESENT_MODE_IMMEDIATE_KHR
@ VK_PRESENT_MODE_MAILBOX_KHR
@ VK_PRESENT_MODE_FIFO_KHR
#define VK_NULL_HANDLE
Definition vulkan_core.h:46
VkFormat
@ VK_FORMAT_R8G8B8A8_SRGB
@ VK_FORMAT_B8G8R8A8_UNORM
@ VK_FORMAT_R8G8B8A8_UNORM
@ VK_FORMAT_UNDEFINED
VkColorSpaceKHR
@ VK_COLORSPACE_SRGB_NONLINEAR_KHR
uint32_t VkBool32
Definition vulkan_core.h:94
#define VK_KHR_SWAPCHAIN_EXTENSION_NAME
PFN_vkVoidFunction(VKAPI_PTR * PFN_vkGetInstanceProcAddr)(VkInstance instance, const char *pName)
@ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO
@ VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR
@ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR