Commit cb8aabf8 authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

ExternalVKBacking: support creating shared images with data

Bug: 932614
Change-Id: I8a0618eaddc4d192c605763e5cac37f7e73d3024
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1536115
Commit-Queue: Peng Huang <penghuang@chromium.org>
Reviewed-by: default avatarAntoine Labour <piman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#644658}
parent 98a9cb17
......@@ -113,8 +113,97 @@ std::unique_ptr<SharedImageBacking> ExternalVkImageFactory::CreateSharedImage(
const gfx::ColorSpace& color_space,
uint32_t usage,
base::span<const uint8_t> pixel_data) {
NOTIMPLEMENTED();
return nullptr;
switch (format) {
case viz::ETC1:
case viz::RED_8:
case viz::LUMINANCE_F16:
case viz::R16_EXT:
case viz::BGR_565:
case viz::RG_88:
case viz::BGRX_8888:
case viz::RGBX_1010102:
case viz::BGRX_1010102:
case viz::YVU_420:
case viz::YUV_420_BIPLANAR:
case viz::UYVY_422:
// TODO(https://crbug.com/945513): support all formats.
LOG(ERROR) << "format " << format << " is not supported.";
return nullptr;
default:
break;
}
auto sk_color_type = viz::ResourceFormatToClosestSkColorType(
true /* gpu_compositing */, format);
auto ii = SkImageInfo::Make(size.width(), size.height(), sk_color_type,
kOpaque_SkAlphaType);
// rows in pixel data are aligned with 4.
size_t row_bytes = (ii.minRowBytes() + 3) & ~3;
if (pixel_data.size() != ii.computeByteSize(row_bytes)) {
LOG(ERROR) << "Initial data does not have expected size.";
return nullptr;
}
auto backing = CreateSharedImage(mailbox, format, size, color_space, usage);
if (!backing)
return nullptr;
ExternalVkImageBacking* vk_backing =
static_cast<ExternalVkImageBacking*>(backing.get());
std::vector<base::ScopedFD> fds;
if (!vk_backing->BeginAccess(false /* readonly */, &fds)) {
LOG(ERROR) << "Failed to request write access of backing.";
return nullptr;
}
DCHECK(fds.empty());
// Create backend render target from the VkImage.
GrVkAlloc alloc(vk_backing->memory(), 0 /* offset */,
vk_backing->memory_size(), 0 /* flags */);
GrVkImageInfo vk_image_info(vk_backing->image(), alloc,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
vk_backing->vk_format(), 1 /* levelCount */);
GrBackendRenderTarget render_target(size.width(), size.height(),
1 /* sampleCnt */, vk_image_info);
SkSurfaceProps surface_props(0, SkSurfaceProps::kLegacyFontHost_InitType);
auto surface = SkSurface::MakeFromBackendRenderTarget(
context_state_->gr_context(), render_target, kTopLeft_GrSurfaceOrigin,
sk_color_type, nullptr, &surface_props);
SkPixmap pixmap(ii, pixel_data.data(), row_bytes);
surface->writePixels(pixmap, 0, 0);
VkSemaphore semaphore = vk_backing->CreateExternalVkSemaphore();
base::ScopedFD fd;
auto* vk_implementation =
context_state_->vk_context_provider()->GetVulkanImplementation();
VkDevice device = context_state_->vk_context_provider()
->GetDeviceQueue()
->GetVulkanDevice();
if (!vk_implementation->GetSemaphoreFdKHR(device, semaphore, &fd)) {
LOG(ERROR) << "GetSemaphoreFdKHR failed..";
vkDestroySemaphore(device, semaphore, nullptr /* pAllocator */);
return nullptr;
}
GrBackendSemaphore gr_semaphore;
gr_semaphore.initVulkan(semaphore);
if (surface->flushAndSignalSemaphores(1, &gr_semaphore) !=
GrSemaphoresSubmitted::kYes) {
LOG(ERROR) << "Failed to flush the surface.";
vkDestroySemaphore(device, semaphore, nullptr /* pAllocator */);
return nullptr;
}
vk_backing->EndAccess(false /* readonly */, std::move(fd));
VkQueue queue =
context_state_->vk_context_provider()->GetDeviceQueue()->GetVulkanQueue();
// TODO(https://crbug.com/932260): avoid blocking CPU thread.
vkQueueWaitIdle(queue);
vkDestroySemaphore(device, semaphore, nullptr /* pAllocator */);
return backing;
}
std::unique_ptr<SharedImageBacking> ExternalVkImageFactory::CreateSharedImage(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment