Skip to content

Commit

Permalink
Refactor SurfaceWrapper out of SkiaOutputSurfaceImplOnGPU
Browse files Browse the repository at this point in the history
Bug: 943583
Change-Id: Ieeee2b7addeb50da68b30a207d141539fb0c1b59
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1532521
Reviewed-by: Jonathan Backer <[email protected]>
Commit-Queue: Peng Huang <[email protected]>
Auto-Submit: Peng Huang <[email protected]>
Cr-Commit-Position: refs/heads/master@{#642644}
  • Loading branch information
phuang authored and Commit Bot committed Mar 20, 2019
1 parent b31be95 commit 9cbb3c8
Show file tree
Hide file tree
Showing 8 changed files with 306 additions and 208 deletions.
8 changes: 8 additions & 0 deletions components/viz/service/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ viz_component("service") {
# then this build target will no longer be needed.
viz_source_set("gpu_service_dependencies") {
sources = [
"display_embedder/skia_output_device.h",
"display_embedder/skia_output_surface_impl.cc",
"display_embedder/skia_output_surface_impl.h",
"display_embedder/skia_output_surface_impl_non_ddl.cc",
Expand Down Expand Up @@ -347,6 +348,13 @@ viz_source_set("gpu_service_dependencies") {
}

if (enable_vulkan) {
sources += [
"display_embedder/skia_output_device_offscreen.cc",
"display_embedder/skia_output_device_offscreen.h",
"display_embedder/skia_output_device_vulkan.cc",
"display_embedder/skia_output_device_vulkan.h",
]

public_deps += [ "//gpu/vulkan" ]
}
}
Expand Down
37 changes: 37 additions & 0 deletions components/viz/service/display_embedder/skia_output_device.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_H_

#include "base/macros.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/swap_result.h"

class SkSurface;

namespace viz {

class SkiaOutputDevice {
public:
SkiaOutputDevice() = default;
virtual ~SkiaOutputDevice() = default;

// SkSurface that can be drawn to.
virtual sk_sp<SkSurface> DrawSurface() = 0;

// Changes the size of draw surface and invalidates it's contents.
virtual void Reshape(const gfx::Size& size) = 0;

// Presents DrawSurface.
virtual gfx::SwapResult SwapBuffers() = 0;

private:
DISALLOW_COPY_AND_ASSIGN(SkiaOutputDevice);
};

} // namespace viz

#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/viz/service/display_embedder/skia_output_device_offscreen.h"

#include "third_party/skia/include/core/SkSurface.h"

namespace viz {

SkiaOutputDeviceOffscreen::SkiaOutputDeviceOffscreen(GrContext* gr_context)
: gr_context_(gr_context) {}

SkiaOutputDeviceOffscreen::~SkiaOutputDeviceOffscreen() = default;

sk_sp<SkSurface> SkiaOutputDeviceOffscreen::DrawSurface() {
return draw_surface_;
}

void SkiaOutputDeviceOffscreen::Reshape(const gfx::Size& size) {
auto image_info = SkImageInfo::Make(
size.width(), size.height(), kRGBA_8888_SkColorType, kOpaque_SkAlphaType);
draw_surface_ =
SkSurface::MakeRenderTarget(gr_context_, SkBudgeted::kNo, image_info);
}

gfx::SwapResult SkiaOutputDeviceOffscreen::SwapBuffers() {
// Reshape should have been called first.
DCHECK(draw_surface_);
return gfx::SwapResult::SWAP_ACK;
}

} // namespace viz
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_OFFSCREEN_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_OFFSCREEN_H_

#include "base/macros.h"
#include "components/viz/service/display_embedder/skia_output_device.h"

class GrContext;

namespace viz {

class SkiaOutputDeviceOffscreen : public SkiaOutputDevice {
public:
explicit SkiaOutputDeviceOffscreen(GrContext* gr_context);
~SkiaOutputDeviceOffscreen() override;

sk_sp<SkSurface> DrawSurface() override;
void Reshape(const gfx::Size& size) override;
gfx::SwapResult SwapBuffers() override;

private:
GrContext* const gr_context_;
sk_sp<SkSurface> draw_surface_;

DISALLOW_COPY_AND_ASSIGN(SkiaOutputDeviceOffscreen);
};

} // namespace viz

#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_OFFSCREEN_H_
125 changes: 125 additions & 0 deletions components/viz/service/display_embedder/skia_output_device_vulkan.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/viz/service/display_embedder/skia_output_device_vulkan.h"

#include "build/build_config.h"
#include "components/viz/common/gpu/vulkan_context_provider.h"
#include "gpu/ipc/common/gpu_surface_lookup.h"
#include "gpu/vulkan/vulkan_implementation.h"
#include "gpu/vulkan/vulkan_surface.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/vk/GrVkTypes.h"

namespace viz {

SkiaOutputDeviceVulkan::SkiaOutputDeviceVulkan(
VulkanContextProvider* context_provider,
gpu::SurfaceHandle surface_handle)
: context_provider_(context_provider), surface_handle_(surface_handle) {}

SkiaOutputDeviceVulkan::~SkiaOutputDeviceVulkan() {
if (vulkan_surface_)
vulkan_surface_->Destroy();
}

sk_sp<SkSurface> SkiaOutputDeviceVulkan::DrawSurface() {
return draw_surface_;
}

void SkiaOutputDeviceVulkan::Reshape(const gfx::Size& size) {
if (!vulkan_surface_)
CreateVulkanSurface();

auto old_size = vulkan_surface_->size();
vulkan_surface_->SetSize(size);
if (vulkan_surface_->size() != old_size) {
// Size has been changed, we need to clear all surfaces which will be
// recreated later.
sk_surfaces_.clear();
sk_surfaces_.resize(vulkan_surface_->GetSwapChain()->num_images());
}

UpdateDrawSurface();
}

gfx::SwapResult SkiaOutputDeviceVulkan::SwapBuffers() {
// Reshape should have been called first.
DCHECK(vulkan_surface_);
DCHECK(draw_surface_);

auto backend = draw_surface_->getBackendRenderTarget(
SkSurface::kFlushRead_BackendHandleAccess);
GrVkImageInfo vk_image_info;
if (!backend.getVkImageInfo(&vk_image_info))
NOTREACHED() << "Failed to get the image info.";
vulkan_surface_->GetSwapChain()->SetCurrentImageLayout(
vk_image_info.fImageLayout);
auto result = vulkan_surface_->SwapBuffers();

UpdateDrawSurface();

return result;
}

void SkiaOutputDeviceVulkan::CreateVulkanSurface() {
LOG(ERROR) << "CreateVulkanSurface";
gfx::AcceleratedWidget accelerated_widget = gfx::kNullAcceleratedWidget;
#if defined(OS_ANDROID)
accelerated_widget =
gpu::GpuSurfaceLookup::GetInstance()->AcquireNativeWidget(
surface_handle_);
#else
accelerated_widget = surface_handle_;
#endif
auto vulkan_surface =
context_provider_->GetVulkanImplementation()->CreateViewSurface(
accelerated_widget);
if (!vulkan_surface)
LOG(FATAL) << "Failed to create vulkan surface.";
if (!vulkan_surface->Initialize(context_provider_->GetDeviceQueue(),
gpu::VulkanSurface::FORMAT_RGBA_32)) {
LOG(FATAL) << "Failed to initialize vulkan surface.";
}
vulkan_surface_ = std::move(vulkan_surface);
}

void SkiaOutputDeviceVulkan::UpdateDrawSurface() {
DCHECK(vulkan_surface_);
auto* swap_chain = vulkan_surface_->GetSwapChain();
auto index = swap_chain->current_image();
auto& sk_surface = sk_surfaces_[index];
if (!sk_surface) {
SkSurfaceProps surface_props =
SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
VkImage vk_image = swap_chain->GetCurrentImage();
VkImageLayout vk_image_layout = swap_chain->GetCurrentImageLayout();
const auto surface_format = vulkan_surface_->surface_format().format;
DCHECK(surface_format == VK_FORMAT_B8G8R8A8_UNORM ||
surface_format == VK_FORMAT_R8G8B8A8_UNORM);
GrVkImageInfo vk_image_info(vk_image, GrVkAlloc(), VK_IMAGE_TILING_OPTIMAL,
vk_image_layout, surface_format,
1 /* level_count */);
GrBackendRenderTarget render_target(vulkan_surface_->size().width(),
vulkan_surface_->size().height(),
0 /* sample_cnt */, vk_image_info);
auto sk_color_type = surface_format == VK_FORMAT_B8G8R8A8_UNORM
? kBGRA_8888_SkColorType
: kRGBA_8888_SkColorType;
sk_surface = SkSurface::MakeFromBackendRenderTarget(
context_provider_->GetGrContext(), render_target,
kTopLeft_GrSurfaceOrigin, sk_color_type, nullptr /* color_space */,
&surface_props);
DCHECK(sk_surface);
} else {
auto backend = sk_surface->getBackendRenderTarget(
SkSurface::kFlushRead_BackendHandleAccess);
backend.setVkImageLayout(swap_chain->GetCurrentImageLayout());
}

draw_surface_ = sk_surface;
}

} // namespace viz
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_VULKAN_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_VULKAN_H_

#include <memory>
#include <vector>

#include "base/macros.h"
#include "components/viz/service/display_embedder/skia_output_device.h"
#include "gpu/ipc/common/surface_handle.h"

namespace gpu {
class VulkanSurface;
}

namespace viz {

class VulkanContextProvider;

class SkiaOutputDeviceVulkan : public SkiaOutputDevice {
public:
SkiaOutputDeviceVulkan(VulkanContextProvider* context_provider,
gpu::SurfaceHandle surface_handle);
~SkiaOutputDeviceVulkan() override;

sk_sp<SkSurface> DrawSurface() override;
void Reshape(const gfx::Size& size) override;
gfx::SwapResult SwapBuffers() override;

private:
void CreateVulkanSurface();
void UpdateDrawSurface();

VulkanContextProvider* const context_provider_;

const gpu::SurfaceHandle surface_handle_;
std::unique_ptr<gpu::VulkanSurface> vulkan_surface_;

// SkSurfaces for swap chain images.
std::vector<sk_sp<SkSurface>> sk_surfaces_;

// SkSurface to be drawn to. Updated after Reshape and SwapBuffers.
sk_sp<SkSurface> draw_surface_;

DISALLOW_COPY_AND_ASSIGN(SkiaOutputDeviceVulkan);
};

} // namespace viz

#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_VULKAN_H_
Loading

0 comments on commit 9cbb3c8

Please sign in to comment.