Commit 78b558a1 authored by Jonathan Backer's avatar Jonathan Backer Committed by Commit Bot

Add SkiaOutputDeviceGL

This CL moves some platform specific logic out of
SkiaOutputSurfaceImplOnGpu and into SkiaOutputDeviceGL. I also added the
hooks to support partial swaps and tested on an i7 gLinux laptop.

Bug: 920344
Change-Id: I77b86442fef2340094de9fa93057f1fa2af2f50b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1539792
Commit-Queue: Jonathan Backer <backer@chromium.org>
Reviewed-by: default avatarPeng Huang <penghuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#645059}
parent 8f59833a
...@@ -311,6 +311,8 @@ viz_source_set("gpu_service_dependencies") { ...@@ -311,6 +311,8 @@ viz_source_set("gpu_service_dependencies") {
sources = [ sources = [
"display_embedder/skia_output_device.cc", "display_embedder/skia_output_device.cc",
"display_embedder/skia_output_device.h", "display_embedder/skia_output_device.h",
"display_embedder/skia_output_device_gl.cc",
"display_embedder/skia_output_device_gl.h",
"display_embedder/skia_output_device_offscreen.cc", "display_embedder/skia_output_device_offscreen.cc",
"display_embedder/skia_output_device_offscreen.h", "display_embedder/skia_output_device_offscreen.h",
"display_embedder/skia_output_surface_impl.cc", "display_embedder/skia_output_surface_impl.cc",
......
...@@ -4,9 +4,16 @@ ...@@ -4,9 +4,16 @@
#include "components/viz/service/display_embedder/skia_output_device.h" #include "components/viz/service/display_embedder/skia_output_device.h"
#include <utility>
#include "third_party/skia/include/core/SkSurface.h"
#include "ui/gfx/presentation_feedback.h"
namespace viz { namespace viz {
SkiaOutputDevice::SkiaOutputDevice() = default; SkiaOutputDevice::SkiaOutputDevice(
DidSwapBufferCompleteCallback did_swap_buffer_complete_callback)
: did_swap_buffer_complete_callback_(did_swap_buffer_complete_callback) {}
SkiaOutputDevice::~SkiaOutputDevice() = default; SkiaOutputDevice::~SkiaOutputDevice() = default;
...@@ -14,9 +21,45 @@ bool SkiaOutputDevice::SupportPostSubBuffer() { ...@@ -14,9 +21,45 @@ bool SkiaOutputDevice::SupportPostSubBuffer() {
return false; return false;
} }
gfx::SwapResult SkiaOutputDevice::PostSubBuffer(const gfx::Rect& rect) { gfx::SwapResponse SkiaOutputDevice::PostSubBuffer(
const gfx::Rect& rect,
BufferPresentedCallback feedback) {
NOTREACHED(); NOTREACHED();
return gfx::SwapResult::SWAP_FAILED; StartSwapBuffers(std::move(feedback));
return FinishSwapBuffers(gfx::SwapResult::SWAP_FAILED);
}
void SkiaOutputDevice::StartSwapBuffers(
base::Optional<BufferPresentedCallback> feedback) {
DCHECK(!feedback_);
DCHECK(!params_);
feedback_ = std::move(feedback);
params_.emplace();
params_->swap_response.swap_id = ++swap_id_;
params_->swap_response.swap_start = base::TimeTicks::Now();
}
gfx::SwapResponse SkiaOutputDevice::FinishSwapBuffers(gfx::SwapResult result) {
DCHECK(params_);
params_->swap_response.result = result;
params_->swap_response.swap_end = base::TimeTicks::Now();
if (feedback_) {
std::move(*feedback_)
.Run(gfx::PresentationFeedback(
params_->swap_response.swap_start, base::TimeDelta() /* interval */,
params_->swap_response.result == gfx::SwapResult::SWAP_ACK
? 0
: gfx::PresentationFeedback::Flags::kFailure));
}
did_swap_buffer_complete_callback_.Run(
*params_, gfx::Size(draw_surface_->width(), draw_surface_->height()));
feedback_.reset();
auto response = params_->swap_response;
params_.reset();
return response;
} }
} // namespace viz } // namespace viz
...@@ -5,35 +5,66 @@ ...@@ -5,35 +5,66 @@
#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_H_ #ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_H_ #define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_H_
#include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/optional.h"
#include "gpu/command_buffer/common/swap_buffers_complete_params.h"
#include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkRefCnt.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/swap_result.h" #include "ui/gfx/swap_result.h"
class SkSurface; class SkSurface;
namespace gfx {
class ColorSpace;
class Rect;
class Size;
struct PresentationFeedback;
} // namespace gfx
namespace viz { namespace viz {
class SkiaOutputDevice { class SkiaOutputDevice {
public: public:
SkiaOutputDevice(); using BufferPresentedCallback =
base::OnceCallback<void(const gfx::PresentationFeedback& feedback)>;
using DidSwapBufferCompleteCallback =
base::RepeatingCallback<void(gpu::SwapBuffersCompleteParams,
const gfx::Size& pixel_size)>;
explicit SkiaOutputDevice(
DidSwapBufferCompleteCallback did_swap_buffer_complete_callback);
virtual ~SkiaOutputDevice(); virtual ~SkiaOutputDevice();
// SkSurface that can be drawn to. // SkSurface that can be drawn to.
virtual sk_sp<SkSurface> DrawSurface() = 0; sk_sp<SkSurface> DrawSurface() { return draw_surface_; }
// Changes the size of draw surface and invalidates it's contents. // Changes the size of draw surface and invalidates it's contents.
virtual void Reshape(const gfx::Size& size) = 0; virtual void Reshape(const gfx::Size& size,
float device_scale_factor,
const gfx::ColorSpace& color_space,
bool has_alpha) = 0;
// Presents DrawSurface. // Presents DrawSurface.
virtual gfx::SwapResult SwapBuffers() = 0; virtual gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) = 0;
virtual bool SupportPostSubBuffer(); virtual bool SupportPostSubBuffer();
virtual gfx::SwapResult PostSubBuffer(const gfx::Rect& rect); virtual gfx::SwapResponse PostSubBuffer(const gfx::Rect& rect,
BufferPresentedCallback feedback);
protected:
void StartSwapBuffers(base::Optional<BufferPresentedCallback> feedback);
gfx::SwapResponse FinishSwapBuffers(gfx::SwapResult result);
sk_sp<SkSurface> draw_surface_;
private: private:
uint64_t swap_id_ = 0;
DidSwapBufferCompleteCallback did_swap_buffer_complete_callback_;
// Only valid between StartSwapBuffers and FinishSwapBuffers.
base::Optional<BufferPresentedCallback> feedback_;
base::Optional<gpu::SwapBuffersCompleteParams> params_;
DISALLOW_COPY_AND_ASSIGN(SkiaOutputDevice); DISALLOW_COPY_AND_ASSIGN(SkiaOutputDevice);
}; };
......
// 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_gl.h"
#include <utility>
#include "gpu/command_buffer/common/swap_buffers_complete_params.h"
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/ipc/service/image_transport_surface.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkSurfaceProps.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/gl_version_info.h"
namespace viz {
SkiaOutputDeviceGL::SkiaOutputDeviceGL(
gpu::SurfaceHandle surface_handle,
scoped_refptr<gpu::gles2::FeatureInfo> feature_info,
const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback)
: SkiaOutputDevice(did_swap_buffer_complete_callback),
surface_handle_(surface_handle),
feature_info_(feature_info) {
DCHECK(surface_handle_);
gl_surface_ = gpu::ImageTransportSurface::CreateNativeSurface(
nullptr, surface_handle_, gl::GLSurfaceFormat());
}
void SkiaOutputDeviceGL::Initialize(GrContext* gr_context,
gl::GLContext* gl_context) {
DCHECK(gr_context);
DCHECK(gl_context);
gr_context_ = gr_context;
gl::CurrentGL* current_gl = gl_context->GetCurrentGL();
DCHECK(current_gl);
// Get alpha and stencil bits from the default frame buffer.
glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
gr_context_->resetContext(kRenderTarget_GrGLBackendState);
const auto* version = current_gl->Version;
GLint stencil_bits = 0;
GLint alpha_bits = 0;
if (version->is_desktop_core_profile) {
glGetFramebufferAttachmentParameterivEXT(
GL_FRAMEBUFFER, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
&stencil_bits);
glGetFramebufferAttachmentParameterivEXT(
GL_FRAMEBUFFER, GL_BACK_LEFT, GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
&alpha_bits);
} else {
glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
glGetIntegerv(GL_ALPHA_BITS, &alpha_bits);
}
CHECK_GL_ERROR();
supports_stencil_ = stencil_bits > 0;
supports_alpha_ = alpha_bits > 0;
supports_post_sub_buffer_ = gl_surface_->SupportsPostSubBuffer();
if (feature_info_->workarounds()
.disable_post_sub_buffers_for_onscreen_surfaces)
supports_post_sub_buffer_ = false;
}
SkiaOutputDeviceGL::~SkiaOutputDeviceGL() {}
scoped_refptr<gl::GLSurface> SkiaOutputDeviceGL::gl_surface() {
return gl_surface_;
}
void SkiaOutputDeviceGL::Reshape(const gfx::Size& size,
float device_scale_factor,
const gfx::ColorSpace& color_space,
bool has_alpha) {
// Conversion to GLSurface's color space follows the same logic as in
// gl::GetGLColorSpace().
gl::GLSurface::ColorSpace surface_color_space =
color_space.IsHDR() ? gl::GLSurface::ColorSpace::SCRGB_LINEAR
: gl::GLSurface::ColorSpace::UNSPECIFIED;
if (!gl_surface_->Resize(size, device_scale_factor, surface_color_space,
has_alpha)) {
LOG(FATAL) << "Failed to resize.";
// TODO(penghuang): Handle the failure.
}
SkSurfaceProps surface_props =
SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
GrGLFramebufferInfo framebuffer_info;
framebuffer_info.fFBOID = gl_surface_->GetBackingFramebufferObject();
framebuffer_info.fFormat = supports_alpha_ ? GL_RGBA8 : GL_RGB8_OES;
GrBackendRenderTarget render_target(size.width(), size.height(), 0, 8,
framebuffer_info);
auto origin = gl_surface_->FlipsVertically() ? kTopLeft_GrSurfaceOrigin
: kBottomLeft_GrSurfaceOrigin;
auto color_type =
supports_alpha_ ? kRGBA_8888_SkColorType : kRGB_888x_SkColorType;
draw_surface_ = SkSurface::MakeFromBackendRenderTarget(
gr_context_, render_target, origin, color_type,
color_space.ToSkColorSpace(), &surface_props);
DCHECK(draw_surface_);
}
gfx::SwapResponse SkiaOutputDeviceGL::SwapBuffers(
BufferPresentedCallback feedback) {
// TODO(backer): Support SwapBuffersAsync
StartSwapBuffers({});
return FinishSwapBuffers(gl_surface_->SwapBuffers(std::move(feedback)));
}
bool SkiaOutputDeviceGL::SupportPostSubBuffer() {
return supports_post_sub_buffer_;
}
gfx::SwapResponse SkiaOutputDeviceGL::PostSubBuffer(
const gfx::Rect& rect,
BufferPresentedCallback feedback) {
// TODO(backer): Support PostSubBufferAsync
StartSwapBuffers({});
return FinishSwapBuffers(gl_surface_->PostSubBuffer(
rect.x(), rect.y(), rect.width(), rect.height(), std::move(feedback)));
}
} // namespace viz
// 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_GL_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_GL_H_
#include <memory>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "components/viz/service/display_embedder/skia_output_device.h"
#include "gpu/config/gpu_preferences.h"
#include "gpu/ipc/common/surface_handle.h"
class GrContext;
namespace gl {
class GLContext;
class GLSurface;
} // namespace gl
namespace gpu {
namespace gles2 {
class FeatureInfo;
} // namespace gles2
} // namespace gpu
namespace viz {
class SkiaOutputDeviceGL final : public SkiaOutputDevice {
public:
SkiaOutputDeviceGL(
gpu::SurfaceHandle surface_handle,
scoped_refptr<gpu::gles2::FeatureInfo> feature_info,
const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback);
~SkiaOutputDeviceGL() override;
scoped_refptr<gl::GLSurface> gl_surface();
void Initialize(GrContext* gr_context, gl::GLContext* gl_context);
bool supports_alpha() {
DCHECK(gr_context_);
return supports_alpha_;
}
bool supports_stencil() {
DCHECK(gr_context_);
return supports_stencil_;
}
// SkiaOutputDevice implementation:
void Reshape(const gfx::Size& size,
float device_scale_factor,
const gfx::ColorSpace& color_space,
bool has_alpha) override;
gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) override;
bool SupportPostSubBuffer() override;
gfx::SwapResponse PostSubBuffer(const gfx::Rect& rect,
BufferPresentedCallback feedback) override;
private:
const gpu::SurfaceHandle surface_handle_;
scoped_refptr<gpu::gles2::FeatureInfo> feature_info_;
gpu::GpuPreferences gpu_preferences_;
GrContext* gr_context_ = nullptr;
scoped_refptr<gl::GLSurface> gl_surface_;
sk_sp<SkSurface> sk_surface_;
bool supports_alpha_ = false;
bool supports_stencil_ = false;
bool supports_post_sub_buffer_ = false;
DISALLOW_COPY_AND_ASSIGN(SkiaOutputDeviceGL);
};
} // namespace viz
#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_GL_H_
...@@ -4,22 +4,28 @@ ...@@ -4,22 +4,28 @@
#include "components/viz/service/display_embedder/skia_output_device_offscreen.h" #include "components/viz/service/display_embedder/skia_output_device_offscreen.h"
#include <utility>
#include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSurface.h"
namespace viz { namespace viz {
SkiaOutputDeviceOffscreen::SkiaOutputDeviceOffscreen(GrContext* gr_context, SkiaOutputDeviceOffscreen::SkiaOutputDeviceOffscreen(
bool flipped, GrContext* gr_context,
bool has_alpha) bool flipped,
: gr_context_(gr_context), flipped_(flipped), has_alpha_(has_alpha) {} bool has_alpha,
DidSwapBufferCompleteCallback did_swap_buffer_complete_callback)
: SkiaOutputDevice(did_swap_buffer_complete_callback),
gr_context_(gr_context),
flipped_(flipped),
has_alpha_(has_alpha) {}
SkiaOutputDeviceOffscreen::~SkiaOutputDeviceOffscreen() = default; SkiaOutputDeviceOffscreen::~SkiaOutputDeviceOffscreen() = default;
sk_sp<SkSurface> SkiaOutputDeviceOffscreen::DrawSurface() { void SkiaOutputDeviceOffscreen::Reshape(const gfx::Size& size,
return draw_surface_; float device_scale_factor,
} const gfx::ColorSpace& color_space,
bool has_alpha) {
void SkiaOutputDeviceOffscreen::Reshape(const gfx::Size& size) {
auto image_info = SkImageInfo::Make( auto image_info = SkImageInfo::Make(
size.width(), size.height(), size.width(), size.height(),
has_alpha_ ? kRGBA_8888_SkColorType : kRGB_888x_SkColorType, has_alpha_ ? kRGBA_8888_SkColorType : kRGB_888x_SkColorType,
...@@ -30,10 +36,13 @@ void SkiaOutputDeviceOffscreen::Reshape(const gfx::Size& size) { ...@@ -30,10 +36,13 @@ void SkiaOutputDeviceOffscreen::Reshape(const gfx::Size& size) {
nullptr /* surfaceProps */); nullptr /* surfaceProps */);
} }
gfx::SwapResult SkiaOutputDeviceOffscreen::SwapBuffers() { gfx::SwapResponse SkiaOutputDeviceOffscreen::SwapBuffers(
BufferPresentedCallback feedback) {
// Reshape should have been called first. // Reshape should have been called first.
DCHECK(draw_surface_); DCHECK(draw_surface_);
return gfx::SwapResult::SWAP_ACK;
StartSwapBuffers(std::move(feedback));
return FinishSwapBuffers(gfx::SwapResult::SWAP_ACK);
} }
} // namespace viz } // namespace viz
...@@ -14,18 +14,22 @@ namespace viz { ...@@ -14,18 +14,22 @@ namespace viz {
class SkiaOutputDeviceOffscreen : public SkiaOutputDevice { class SkiaOutputDeviceOffscreen : public SkiaOutputDevice {
public: public:
SkiaOutputDeviceOffscreen(GrContext* gr_context, SkiaOutputDeviceOffscreen(
bool flipped, GrContext* gr_context,
bool has_alpha); bool flipped,
bool has_alpha,
DidSwapBufferCompleteCallback did_swap_buffer_complete_callback);
~SkiaOutputDeviceOffscreen() override; ~SkiaOutputDeviceOffscreen() override;
sk_sp<SkSurface> DrawSurface() override; // SkiaOutputDevice implementation:
void Reshape(const gfx::Size& size) override; void Reshape(const gfx::Size& size,
gfx::SwapResult SwapBuffers() override; float device_scale_factor,
const gfx::ColorSpace& color_space,
bool has_alpha) override;
gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) override;
protected: protected:
GrContext* const gr_context_; GrContext* const gr_context_;
sk_sp<SkSurface> draw_surface_;
const bool flipped_; const bool flipped_;
const bool has_alpha_; const bool has_alpha_;
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "components/viz/service/display_embedder/skia_output_device_vulkan.h" #include "components/viz/service/display_embedder/skia_output_device_vulkan.h"
#include <utility>
#include "build/build_config.h" #include "build/build_config.h"
#include "components/viz/common/gpu/vulkan_context_provider.h" #include "components/viz/common/gpu/vulkan_context_provider.h"
#include "gpu/ipc/common/gpu_surface_lookup.h" #include "gpu/ipc/common/gpu_surface_lookup.h"
...@@ -17,19 +19,21 @@ namespace viz { ...@@ -17,19 +19,21 @@ namespace viz {
SkiaOutputDeviceVulkan::SkiaOutputDeviceVulkan( SkiaOutputDeviceVulkan::SkiaOutputDeviceVulkan(
VulkanContextProvider* context_provider, VulkanContextProvider* context_provider,
gpu::SurfaceHandle surface_handle) gpu::SurfaceHandle surface_handle,
: context_provider_(context_provider), surface_handle_(surface_handle) {} DidSwapBufferCompleteCallback did_swap_buffer_complete_callback)
: SkiaOutputDevice(did_swap_buffer_complete_callback),
context_provider_(context_provider),
surface_handle_(surface_handle) {}
SkiaOutputDeviceVulkan::~SkiaOutputDeviceVulkan() { SkiaOutputDeviceVulkan::~SkiaOutputDeviceVulkan() {
if (vulkan_surface_) if (vulkan_surface_)
vulkan_surface_->Destroy(); vulkan_surface_->Destroy();
} }
sk_sp<SkSurface> SkiaOutputDeviceVulkan::DrawSurface() { void SkiaOutputDeviceVulkan::Reshape(const gfx::Size& size,
return draw_surface_; float device_scale_factor,
} const gfx::ColorSpace& color_space,
bool has_alpha) {
void SkiaOutputDeviceVulkan::Reshape(const gfx::Size& size) {
if (!vulkan_surface_) if (!vulkan_surface_)
CreateVulkanSurface(); CreateVulkanSurface();
...@@ -45,11 +49,13 @@ void SkiaOutputDeviceVulkan::Reshape(const gfx::Size& size) { ...@@ -45,11 +49,13 @@ void SkiaOutputDeviceVulkan::Reshape(const gfx::Size& size) {
UpdateDrawSurface(); UpdateDrawSurface();
} }
gfx::SwapResult SkiaOutputDeviceVulkan::SwapBuffers() { gfx::SwapResponse SkiaOutputDeviceVulkan::SwapBuffers(
BufferPresentedCallback feedback) {
// Reshape should have been called first. // Reshape should have been called first.
DCHECK(vulkan_surface_); DCHECK(vulkan_surface_);
DCHECK(draw_surface_); DCHECK(draw_surface_);
StartSwapBuffers(std::move(feedback));
auto backend = draw_surface_->getBackendRenderTarget( auto backend = draw_surface_->getBackendRenderTarget(
SkSurface::kFlushRead_BackendHandleAccess); SkSurface::kFlushRead_BackendHandleAccess);
GrVkImageInfo vk_image_info; GrVkImageInfo vk_image_info;
...@@ -57,11 +63,11 @@ gfx::SwapResult SkiaOutputDeviceVulkan::SwapBuffers() { ...@@ -57,11 +63,11 @@ gfx::SwapResult SkiaOutputDeviceVulkan::SwapBuffers() {
NOTREACHED() << "Failed to get the image info."; NOTREACHED() << "Failed to get the image info.";
vulkan_surface_->GetSwapChain()->SetCurrentImageLayout( vulkan_surface_->GetSwapChain()->SetCurrentImageLayout(
vk_image_info.fImageLayout); vk_image_info.fImageLayout);
auto result = vulkan_surface_->SwapBuffers(); auto response = FinishSwapBuffers(vulkan_surface_->SwapBuffers());
UpdateDrawSurface(); UpdateDrawSurface();
return result; return response;
} }
void SkiaOutputDeviceVulkan::CreateVulkanSurface() { void SkiaOutputDeviceVulkan::CreateVulkanSurface() {
......
...@@ -20,15 +20,20 @@ namespace viz { ...@@ -20,15 +20,20 @@ namespace viz {
class VulkanContextProvider; class VulkanContextProvider;
class SkiaOutputDeviceVulkan : public SkiaOutputDevice { class SkiaOutputDeviceVulkan final : public SkiaOutputDevice {
public: public:
SkiaOutputDeviceVulkan(VulkanContextProvider* context_provider, SkiaOutputDeviceVulkan(
gpu::SurfaceHandle surface_handle); VulkanContextProvider* context_provider,
gpu::SurfaceHandle surface_handle,
DidSwapBufferCompleteCallback did_swap_buffer_complete_callback);
~SkiaOutputDeviceVulkan() override; ~SkiaOutputDeviceVulkan() override;
sk_sp<SkSurface> DrawSurface() override; // SkiaOutputDevice implementation:
void Reshape(const gfx::Size& size) override; void Reshape(const gfx::Size& size,
gfx::SwapResult SwapBuffers() override; float device_scale_factor,
const gfx::ColorSpace& color_space,
bool has_alpha) override;
gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) override;
private: private:
void CreateVulkanSurface(); void CreateVulkanSurface();
...@@ -42,9 +47,6 @@ class SkiaOutputDeviceVulkan : public SkiaOutputDevice { ...@@ -42,9 +47,6 @@ class SkiaOutputDeviceVulkan : public SkiaOutputDevice {
// SkSurfaces for swap chain images. // SkSurfaces for swap chain images.
std::vector<sk_sp<SkSurface>> sk_surfaces_; 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); DISALLOW_COPY_AND_ASSIGN(SkiaOutputDeviceVulkan);
}; };
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "components/viz/service/display_embedder/skia_output_device_x11.h" #include "components/viz/service/display_embedder/skia_output_device_x11.h"
#include <utility>
#include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h" #include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/vk/GrVkTypes.h" #include "third_party/skia/include/gpu/vk/GrVkTypes.h"
...@@ -13,11 +15,14 @@ ...@@ -13,11 +15,14 @@
namespace viz { namespace viz {
SkiaOutputDeviceX11::SkiaOutputDeviceX11(GrContext* gr_context, SkiaOutputDeviceX11::SkiaOutputDeviceX11(
gfx::AcceleratedWidget widget) GrContext* gr_context,
gfx::AcceleratedWidget widget,
DidSwapBufferCompleteCallback did_swap_buffer_complete_callback)
: SkiaOutputDeviceOffscreen(gr_context, : SkiaOutputDeviceOffscreen(gr_context,
false /* flipped */, false /* flipped */,
true /* has_alpha */), true /* has_alpha */,
did_swap_buffer_complete_callback),
display_(gfx::GetXDisplay()), display_(gfx::GetXDisplay()),
widget_(widget), widget_(widget),
gc_(XCreateGC(display_, widget_, 0, nullptr)) { gc_(XCreateGC(display_, widget_, 0, nullptr)) {
...@@ -32,23 +37,33 @@ SkiaOutputDeviceX11::~SkiaOutputDeviceX11() { ...@@ -32,23 +37,33 @@ SkiaOutputDeviceX11::~SkiaOutputDeviceX11() {
XFreeGC(display_, gc_); XFreeGC(display_, gc_);
} }
void SkiaOutputDeviceX11::Reshape(const gfx::Size& size) { void SkiaOutputDeviceX11::Reshape(const gfx::Size& size,
SkiaOutputDeviceOffscreen::Reshape(size); float device_scale_factor,
const gfx::ColorSpace& color_space,
bool has_alpha) {
SkiaOutputDeviceOffscreen::Reshape(size, device_scale_factor, color_space,
has_alpha);
auto ii = auto ii =
SkImageInfo::MakeN32(size.width(), size.height(), kOpaque_SkAlphaType); SkImageInfo::MakeN32(size.width(), size.height(), kOpaque_SkAlphaType);
pixels_.reserve(ii.computeMinByteSize()); pixels_.reserve(ii.computeMinByteSize());
} }
gfx::SwapResult SkiaOutputDeviceX11::SwapBuffers() { gfx::SwapResponse SkiaOutputDeviceX11::SwapBuffers(
BufferPresentedCallback feedback) {
return PostSubBuffer( return PostSubBuffer(
gfx::Rect(0, 0, draw_surface_->width(), draw_surface_->height())); gfx::Rect(0, 0, draw_surface_->width(), draw_surface_->height()),
std::move(feedback));
} }
bool SkiaOutputDeviceX11::SupportPostSubBuffer() { bool SkiaOutputDeviceX11::SupportPostSubBuffer() {
return true; return true;
} }
gfx::SwapResult SkiaOutputDeviceX11::PostSubBuffer(const gfx::Rect& rect) { gfx::SwapResponse SkiaOutputDeviceX11::PostSubBuffer(
const gfx::Rect& rect,
BufferPresentedCallback feedback) {
StartSwapBuffers(std::move(feedback));
auto ii = auto ii =
SkImageInfo::MakeN32(rect.width(), rect.height(), kOpaque_SkAlphaType); SkImageInfo::MakeN32(rect.width(), rect.height(), kOpaque_SkAlphaType);
DCHECK_GE(pixels_.capacity(), ii.computeMinByteSize()); DCHECK_GE(pixels_.capacity(), ii.computeMinByteSize());
...@@ -114,7 +129,7 @@ gfx::SwapResult SkiaOutputDeviceX11::PostSubBuffer(const gfx::Rect& rect) { ...@@ -114,7 +129,7 @@ gfx::SwapResult SkiaOutputDeviceX11::PostSubBuffer(const gfx::Rect& rect) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
XFlush(display_); XFlush(display_);
return gfx::SwapResult::SWAP_ACK; return FinishSwapBuffers(gfx::SwapResult::SWAP_ACK);
} }
} // namespace viz } // namespace viz
...@@ -17,13 +17,20 @@ namespace viz { ...@@ -17,13 +17,20 @@ namespace viz {
class SkiaOutputDeviceX11 final : public SkiaOutputDeviceOffscreen { class SkiaOutputDeviceX11 final : public SkiaOutputDeviceOffscreen {
public: public:
SkiaOutputDeviceX11(GrContext* gr_context, gfx::AcceleratedWidget widget); SkiaOutputDeviceX11(
GrContext* gr_context,
gfx::AcceleratedWidget widget,
DidSwapBufferCompleteCallback did_swap_buffer_complete_callback);
~SkiaOutputDeviceX11() override; ~SkiaOutputDeviceX11() override;
void Reshape(const gfx::Size& size) override; void Reshape(const gfx::Size& size,
gfx::SwapResult SwapBuffers() override; float device_scale_factor,
const gfx::ColorSpace& color_space,
bool has_alpha) override;
gfx::SwapResponse SwapBuffers(BufferPresentedCallback feedback) override;
bool SupportPostSubBuffer() override; bool SupportPostSubBuffer() override;
gfx::SwapResult PostSubBuffer(const gfx::Rect& rect) override; gfx::SwapResponse PostSubBuffer(const gfx::Rect& rect,
BufferPresentedCallback feedback) override;
private: private:
XDisplay* const display_; XDisplay* const display_;
......
...@@ -69,7 +69,7 @@ struct RenderPassGeometry; ...@@ -69,7 +69,7 @@ struct RenderPassGeometry;
// The SkiaOutputSurface implementation running on the GPU thread. This class // The SkiaOutputSurface implementation running on the GPU thread. This class
// should be created, used and destroyed on the GPU thread. // should be created, used and destroyed on the GPU thread.
class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate { class SkiaOutputSurfaceImplOnGpu {
public: public:
using DidSwapBufferCompleteCallback = using DidSwapBufferCompleteCallback =
base::RepeatingCallback<void(gpu::SwapBuffersCompleteParams, base::RepeatingCallback<void(gpu::SwapBuffersCompleteParams,
...@@ -98,7 +98,7 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate { ...@@ -98,7 +98,7 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate {
const BufferPresentedCallback& buffer_presented_callback, const BufferPresentedCallback& buffer_presented_callback,
const ContextLostCallback& context_lost_callback); const ContextLostCallback& context_lost_callback);
~SkiaOutputSurfaceImplOnGpu() override; ~SkiaOutputSurfaceImplOnGpu();
gpu::CommandBufferId command_buffer_id() const { gpu::CommandBufferId command_buffer_id() const {
return sync_point_client_state_->command_buffer_id(); return sync_point_client_state_->command_buffer_id();
...@@ -160,33 +160,11 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate { ...@@ -160,33 +160,11 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate {
const OutputSurface::Capabilities& capabilities); const OutputSurface::Capabilities& capabilities);
private: private:
// gpu::ImageTransportSurfaceDelegate implementation:
#if defined(OS_WIN)
void DidCreateAcceleratedSurfaceChildWindow(
gpu::SurfaceHandle parent_window,
gpu::SurfaceHandle child_window) override;
#endif
void DidSwapBuffersComplete(gpu::SwapBuffersCompleteParams params) override;
const gpu::gles2::FeatureInfo* GetFeatureInfo() const override;
const gpu::GpuPreferences& GetGpuPreferences() const override;
void BufferPresented(const gfx::PresentationFeedback& feedback) override;
void AddFilter(IPC::MessageFilter* message_filter) override;
int32_t GetRouteID() const override;
void InitializeForGL();
void InitializeForGLWithGpuService(GpuServiceImpl* gpu_service); void InitializeForGLWithGpuService(GpuServiceImpl* gpu_service);
void InitializeForGLWithTaskExecutor(
gpu::CommandBufferTaskExecutor* task_executor,
scoped_refptr<gl::GLSurface> gl_surface);
void InitializeForVulkan(GpuServiceImpl* gpu_service); void InitializeForVulkan(GpuServiceImpl* gpu_service);
void BindOrCopyTextureIfNecessary(gpu::TextureBase* texture_base); void BindOrCopyTextureIfNecessary(gpu::TextureBase* texture_base);
// Generage the next swap ID and push it to our pending swap ID queues.
void OnSwapBuffers();
void CreateSkSurfaceForGL();
// Make context current for GL, and return false if the context is lost. // Make context current for GL, and return false if the context is lost.
// It will do nothing when Vulkan is used. // It will do nothing when Vulkan is used.
bool MakeCurrent(bool need_fbo0); bool MakeCurrent(bool need_fbo0);
...@@ -253,12 +231,6 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate { ...@@ -253,12 +231,6 @@ class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate {
}; };
base::flat_map<RenderPassId, OffscreenSurface> offscreen_surfaces_; base::flat_map<RenderPassId, OffscreenSurface> offscreen_surfaces_;
// Params are pushed each time we begin a swap, and popped each time we
// present or complete a swap.
base::circular_deque<std::pair<uint64_t, gfx::Size>>
pending_swap_completed_params_;
uint64_t swap_id_ = 0;
ui::LatencyTracker latency_tracker_; ui::LatencyTracker latency_tracker_;
scoped_refptr<base::SingleThreadTaskRunner> context_current_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> context_current_task_runner_;
......
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