Skip to content

Commit

Permalink
Add SkiaOutputDeviceDawn and create a Dawn GrContext
Browse files Browse the repository at this point in the history
Create a Dawn device using D3D12 on Windows and Vulkan on Linux, and
use it to create a Skia Dawn GrContext.

On Windows, create a SkiaOutputDeviceDawn, which uses a native D3D12
swapchain for presentation. On Linux, use a SkiaOutputDeviceX11 for
now, until the Vulkan swapchain is ready.

Bug: 1021566
Change-Id: If3e1f435fe87132c9294f5613c85d675a7282b3a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1899200
Commit-Queue: Sean Gilhuly <sgilhuly@chromium.org>
Reviewed-by: Jonathan Backer <backer@chromium.org>
Reviewed-by: Bo <boliu@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Cr-Commit-Position: refs/heads/master@{#713851}
  • Loading branch information
Sean Gilhuly authored and Commit Bot committed Nov 8, 2019
1 parent 43812c2 commit e534232
Show file tree
Hide file tree
Showing 26 changed files with 438 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ bool SkiaOutputSurfaceDependencyWebView::IsUsingVulkan() {
return shared_context_state_ && shared_context_state_->GrContextIsVulkan();
}

bool SkiaOutputSurfaceDependencyWebView::IsUsingDawn() {
return false;
}

gpu::SharedImageManager*
SkiaOutputSurfaceDependencyWebView::GetSharedImageManager() {
return gpu_service_->shared_image_manager();
Expand Down Expand Up @@ -67,6 +71,11 @@ SkiaOutputSurfaceDependencyWebView::GetVulkanContextProvider() {
return shared_context_state_->vk_context_provider();
}

viz::DawnContextProvider*
SkiaOutputSurfaceDependencyWebView::GetDawnContextProvider() {
return nullptr;
}

const gpu::GpuPreferences&
SkiaOutputSurfaceDependencyWebView::GetGpuPreferences() {
return gpu_service_->gpu_preferences();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ class SkiaOutputSurfaceDependencyWebView

std::unique_ptr<gpu::SingleTaskSequence> CreateSequence() override;
bool IsUsingVulkan() override;
bool IsUsingDawn() override;
gpu::SharedImageManager* GetSharedImageManager() override;
gpu::SyncPointManager* GetSyncPointManager() override;
const gpu::GpuDriverBugWorkarounds& GetGpuDriverBugWorkarounds() override;
scoped_refptr<gpu::SharedContextState> GetSharedContextState() override;
gpu::raster::GrShaderCache* GetGrShaderCache() override;
viz::VulkanContextProvider* GetVulkanContextProvider() override;
viz::DawnContextProvider* GetDawnContextProvider() override;
const gpu::GpuPreferences& GetGpuPreferences() override;
const gpu::GpuFeatureInfo& GetGpuFeatureInfo() override;
gpu::MailboxManager* GetMailboxManager() override;
Expand Down
5 changes: 5 additions & 0 deletions components/viz/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,15 @@ if (skia_use_dawn) {

public_deps = [
"//skia",
"//third_party/dawn/src/dawn:dawn_headers",
]

deps = [
"//base",
"//third_party/dawn:libdawn_native",
"//third_party/dawn:libdawn_native_sources",
"//third_party/dawn/src/dawn:dawncpp",
"//third_party/dawn/src/dawn:libdawn_proc",
]
}
}
Expand Down
1 change: 1 addition & 0 deletions components/viz/common/gpu/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ include_rules = [
"+gpu/command_buffer",
"+gpu/GLES2/gl2extchromium.h",
"+gpu/vulkan",
"+third_party/dawn/src/include",
"+third_party/khronos/GLES2/gl2.h",
"+third_party/skia/include/gpu",
"+third_party/vulkan/include",
Expand Down
37 changes: 36 additions & 1 deletion components/viz/common/gpu/dawn_context_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,54 @@

#include "components/viz/common/gpu/dawn_context_provider.h"

#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "build/build_config.h"
#include "third_party/dawn/src/include/dawn/dawn_proc.h"

namespace viz {

namespace {

dawn_native::BackendType GetDefaultBackendType() {
#if defined(OS_WIN)
return dawn_native::BackendType::D3D12;
#elif defined(OS_LINUX)
return dawn_native::BackendType::Vulkan;
#else
NOTREACHED();
return dawn_native::BackendType::Null;
#endif
}

} // namespace

std::unique_ptr<DawnContextProvider> DawnContextProvider::Create() {
auto context_provider = base::WrapUnique(new DawnContextProvider());
if (!context_provider->IsValid())
return nullptr;
return context_provider;
}

DawnContextProvider::DawnContextProvider() = default;
DawnContextProvider::DawnContextProvider() {
device_ = CreateDevice(GetDefaultBackendType());
if (device_)
gr_context_ = GrContext::MakeDawn(device_);
}

DawnContextProvider::~DawnContextProvider() = default;

dawn::Device DawnContextProvider::CreateDevice(dawn_native::BackendType type) {
instance_.DiscoverDefaultAdapters();
DawnProcTable backend_procs = dawn_native::GetProcs();
dawnProcSetProcs(&backend_procs);

std::vector<dawn_native::Adapter> adapters = instance_.GetAdapters();
for (dawn_native::Adapter adapter : adapters) {
if (adapter.GetBackendType() == type)
return adapter.CreateDevice();
}
return nullptr;
}

} // namespace viz
7 changes: 7 additions & 0 deletions components/viz/common/gpu/dawn_context_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@

#include "base/macros.h"
#include "components/viz/common/viz_dawn_context_provider_export.h"
#include "third_party/dawn/src/include/dawn_native/DawnNative.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/dawn/GrDawnTypes.h"

class GrContext;

Expand All @@ -18,12 +20,17 @@ class VIZ_DAWN_CONTEXT_PROVIDER_EXPORT DawnContextProvider {
static std::unique_ptr<DawnContextProvider> Create();
~DawnContextProvider();

dawn::Device GetDevice() { return device_; }
GrContext* GetGrContext() { return gr_context_.get(); }
bool IsValid() { return !!gr_context_; }

private:
DawnContextProvider();

dawn::Device CreateDevice(dawn_native::BackendType type);

dawn_native::Instance instance_;
dawn::Device device_;
sk_sp<GrContext> gr_context_;

DISALLOW_COPY_AND_ASSIGN(DawnContextProvider);
Expand Down
16 changes: 16 additions & 0 deletions components/viz/service/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import("//build/config/ui.gni")
import("//components/viz/viz.gni")
import("//gpu/vulkan/features.gni")
import("//media/gpu/args.gni")
import("//skia/features.gni")
import("//testing/libfuzzer/fuzzer_test.gni")

config("viz_service_implementation") {
Expand Down Expand Up @@ -391,6 +392,21 @@ viz_source_set("gpu_service_dependencies") {
configs = [ "//build/config/linux:x11" ]
deps += [ "//ui/gfx/x" ]
}

if (skia_use_dawn) {
sources += [
"display_embedder/skia_output_device_dawn.cc",
"display_embedder/skia_output_device_dawn.h",
]

public_deps += [ "//third_party/dawn/src/dawn:dawn_headers" ]

deps += [
"//third_party/dawn:libdawn_native",
"//third_party/dawn:libdawn_native_sources",
"//third_party/dawn/src/dawn:dawncpp",
]
}
}

viz_source_set("unit_tests") {
Expand Down
1 change: 1 addition & 0 deletions components/viz/service/display_embedder/DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ include_rules = [
"+mojo/public/cpp/bindings",
"+mojo/public/cpp/system",
"+skia",
"+third_party/dawn/src/include",
"+third_party/khronos/GLES2/gl2.h",
"+third_party/khronos/GLES2/gl2ext.h",
"+third_party/skia",
Expand Down
121 changes: 121 additions & 0 deletions components/viz/service/display_embedder/skia_output_device_dawn.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// 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_dawn.h"

#include "base/logging.h"
#include "build/build_config.h"
#include "components/viz/common/gpu/dawn_context_provider.h"

#if defined(OS_WIN)
#include "third_party/dawn/src/include/dawn_native/D3D12Backend.h"
#elif defined(OS_LINUX)
#include "third_party/dawn/src/include/dawn_native/VulkanBackend.h"
#endif

namespace viz {

namespace {

// Some Vulkan drivers do not support kRGB_888x_SkColorType. Always use
// kRGBA_8888_SkColorType instead and initialize surface to opaque as necessary.
constexpr SkColorType kSurfaceColorType = kRGBA_8888_SkColorType;
constexpr dawn::TextureFormat kSwapChainFormat =
dawn::TextureFormat::RGBA8Unorm;

constexpr dawn::TextureUsage kUsage =
dawn::TextureUsage::OutputAttachment | dawn::TextureUsage::CopySrc;

} // namespace

SkiaOutputDeviceDawn::SkiaOutputDeviceDawn(
DawnContextProvider* context_provider,
gfx::AcceleratedWidget widget,
DidSwapBufferCompleteCallback did_swap_buffer_complete_callback)
: SkiaOutputDevice(/*need_swap_semaphore=*/false,
did_swap_buffer_complete_callback),
context_provider_(context_provider),
widget_(widget) {
capabilities_.supports_post_sub_buffer = false;
}

SkiaOutputDeviceDawn::~SkiaOutputDeviceDawn() = default;

bool SkiaOutputDeviceDawn::Reshape(const gfx::Size& size,
float device_scale_factor,
const gfx::ColorSpace& color_space,
bool has_alpha,
gfx::OverlayTransform transform) {
DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE);

DiscardBackbuffer();
size_ = size;
sk_color_space_ = color_space.ToSkColorSpace();

CreateSwapChainImplementation();
dawn::SwapChainDescriptor desc;
desc.implementation = reinterpret_cast<int64_t>(&swap_chain_implementation_);
swap_chain_ = context_provider_->GetDevice().CreateSwapChain(&desc);
if (!swap_chain_)
return false;
swap_chain_.Configure(kSwapChainFormat, kUsage, size_.width(),
size_.height());

EnsureBackbuffer();
return true;
}

void SkiaOutputDeviceDawn::SwapBuffers(
BufferPresentedCallback feedback,
std::vector<ui::LatencyInfo> latency_info) {
StartSwapBuffers(std::move(feedback));
swap_chain_.Present(texture_);
texture_ = swap_chain_.GetNextTexture();
FinishSwapBuffers(gfx::SwapResult::SWAP_ACK,
gfx::Size(size_.width(), size_.height()),
std::move(latency_info));
}

SkSurface* SkiaOutputDeviceDawn::BeginPaint() {
GrDawnImageInfo info;
info.fTexture = texture_;
info.fFormat = kSwapChainFormat;
info.fLevelCount = 1;
GrBackendTexture backend_texture(size_.width(), size_.height(), info);
DCHECK(backend_texture.isValid());
sk_surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget(
context_provider_->GetGrContext(), backend_texture,
!capabilities_.flipped_output_surface ? kTopLeft_GrSurfaceOrigin
: kBottomLeft_GrSurfaceOrigin,
/*sampleCount=*/0, kSurfaceColorType, sk_color_space_,
/*surfaceProps=*/nullptr);
return sk_surface_.get();
}

void SkiaOutputDeviceDawn::EndPaint(const GrBackendSemaphore& semaphore) {
GrFlushInfo flush_info;
sk_surface_->flush(SkSurface::BackendSurfaceAccess::kPresent, flush_info);
sk_surface_.reset();
}

void SkiaOutputDeviceDawn::EnsureBackbuffer() {
if (swap_chain_)
texture_ = swap_chain_.GetNextTexture();
}

void SkiaOutputDeviceDawn::DiscardBackbuffer() {
texture_ = nullptr;
}

void SkiaOutputDeviceDawn::CreateSwapChainImplementation() {
#if defined(OS_WIN)
swap_chain_implementation_ = dawn_native::d3d12::CreateNativeSwapChainImpl(
context_provider_->GetDevice().Get(), widget_);
#else
NOTREACHED();
ALLOW_UNUSED_LOCAL(widget_);
#endif
}

} // namespace viz
62 changes: 62 additions & 0 deletions components/viz/service/display_embedder/skia_output_device_dawn.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// 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_DAWN_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_DAWN_H_

#include "components/viz/service/display_embedder/skia_output_device.h"
#include "third_party/dawn/src/include/dawn/dawn_wsi.h"
#include "third_party/dawn/src/include/dawn/dawncpp.h"
#include "third_party/dawn/src/include/dawn_native/DawnNative.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "ui/gfx/native_widget_types.h"

namespace viz {

class DawnContextProvider;

class SkiaOutputDeviceDawn : public SkiaOutputDevice {
public:
SkiaOutputDeviceDawn(
DawnContextProvider* context_provider,
gfx::AcceleratedWidget widget,
DidSwapBufferCompleteCallback did_swap_buffer_complete_callback);
~SkiaOutputDeviceDawn() override;

// SkiaOutputDevice implementation:
bool Reshape(const gfx::Size& size,
float device_scale_factor,
const gfx::ColorSpace& color_space,
bool has_alpha,
gfx::OverlayTransform transform) override;
void SwapBuffers(BufferPresentedCallback feedback,
std::vector<ui::LatencyInfo> latency_info) override;
SkSurface* BeginPaint() override;
void EndPaint(const GrBackendSemaphore& semaphore) override;
void EnsureBackbuffer() override;
void DiscardBackbuffer() override;

private:
// Create a platform-specific swapchain implementation.
void CreateSwapChainImplementation();

DawnContextProvider* const context_provider_;
gfx::AcceleratedWidget widget_;
DawnSwapChainImplementation swap_chain_implementation_;
dawn::SwapChain swap_chain_;
dawn::Texture texture_;
sk_sp<SkSurface> sk_surface_;

gfx::Size size_;
sk_sp<SkColorSpace> sk_color_space_;
GrBackendTexture backend_texture_;

DISALLOW_COPY_AND_ASSIGN(SkiaOutputDeviceDawn);
};

} // namespace viz

#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_DAWN_H_
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class GrShaderCache;

namespace viz {

class DawnContextProvider;
class VulkanContextProvider;

// This class exists to allow SkiaOutputSurfaceImpl to ignore differences
Expand All @@ -59,6 +60,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceDependency {
// These are client thread methods. All other methods should be called on
// the GPU thread only.
virtual bool IsUsingVulkan() = 0;
virtual bool IsUsingDawn() = 0;
// Returns a new task execution sequence. Sequences should not outlive the
// task executor.
virtual std::unique_ptr<gpu::SingleTaskSequence> CreateSequence() = 0;
Expand All @@ -71,6 +73,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceDependency {
virtual gpu::raster::GrShaderCache* GetGrShaderCache() = 0;
// May return null.
virtual VulkanContextProvider* GetVulkanContextProvider() = 0;
// May return null.
virtual DawnContextProvider* GetDawnContextProvider() = 0;
virtual const gpu::GpuPreferences& GetGpuPreferences() = 0;
virtual const gpu::GpuFeatureInfo& GetGpuFeatureInfo() = 0;
virtual gpu::MailboxManager* GetMailboxManager() = 0;
Expand Down
Loading

0 comments on commit e534232

Please sign in to comment.