Commit be9c03d9 authored by Vasiliy Telezhnikov's avatar Vasiliy Telezhnikov Committed by Commit Bot

Buffer Queue support for Skia renderer

This implements SkiaOutputDeviceBufferQueue. It's similar to
GLOutputSurfaceBufferQueue & BufferQueue but adapted to work with
SkiaRenderer. It is used for 'surfaceless' GLOutputSurface like
Surface Control on Android ( GLSurfaceEGLSurfaceControl )

Bug: 980653
Change-Id: I696d95c246621eb52c6474c8637396d70cf9459a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1708418
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Reviewed-by: default avatarJonathan Backer <backer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#679968}
parent 33ff3650
...@@ -310,6 +310,8 @@ viz_source_set("gpu_service_dependencies") { ...@@ -310,6 +310,8 @@ viz_source_set("gpu_service_dependencies") {
"display_embedder/image_context.h", "display_embedder/image_context.h",
"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_buffer_queue.cc",
"display_embedder/skia_output_device_buffer_queue.h",
"display_embedder/skia_output_device_gl.cc", "display_embedder/skia_output_device_gl.cc",
"display_embedder/skia_output_device_gl.h", "display_embedder/skia_output_device_gl.h",
"display_embedder/skia_output_device_offscreen.cc", "display_embedder/skia_output_device_offscreen.cc",
...@@ -402,6 +404,7 @@ viz_source_set("unit_tests") { ...@@ -402,6 +404,7 @@ viz_source_set("unit_tests") {
"display/texture_deleter_unittest.cc", "display/texture_deleter_unittest.cc",
"display_embedder/buffer_queue_unittest.cc", "display_embedder/buffer_queue_unittest.cc",
"display_embedder/server_shared_bitmap_manager_unittest.cc", "display_embedder/server_shared_bitmap_manager_unittest.cc",
"display_embedder/skia_output_device_buffer_queue_unittest.cc",
"display_embedder/skia_output_surface_impl_unittest.cc", "display_embedder/skia_output_surface_impl_unittest.cc",
"display_embedder/software_output_surface_unittest.cc", "display_embedder/software_output_surface_unittest.cc",
"display_embedder/vsync_parameter_listener_unittest.cc", "display_embedder/vsync_parameter_listener_unittest.cc",
......
...@@ -75,6 +75,9 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface, ...@@ -75,6 +75,9 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurface : public OutputSurface,
// Swaps the current backbuffer to the screen. // Swaps the current backbuffer to the screen.
virtual void SkiaSwapBuffers(OutputSurfaceFrame frame) = 0; virtual void SkiaSwapBuffers(OutputSurfaceFrame frame) = 0;
// Schedule overlay planes to be displayed
virtual void ScheduleOverlays(OverlayCandidateList overlays) = 0;
// Begin painting a render pass. This method will create a // Begin painting a render pass. This method will create a
// SkDeferredDisplayListRecorder and return a SkCanvas of it. The SkiaRenderer // SkDeferredDisplayListRecorder and return a SkCanvas of it. The SkiaRenderer
// will use this SkCanvas to paint the render pass. // will use this SkCanvas to paint the render pass.
......
...@@ -687,6 +687,9 @@ void SkiaRenderer::FinishDrawingFrame() { ...@@ -687,6 +687,9 @@ void SkiaRenderer::FinishDrawingFrame() {
if (use_swap_with_bounds_) if (use_swap_with_bounds_)
swap_content_bounds_ = current_frame()->root_content_bounds; swap_content_bounds_ = current_frame()->root_content_bounds;
skia_output_surface_->ScheduleOverlays(
std::move(current_frame()->overlay_list));
} }
void SkiaRenderer::SwapBuffers(std::vector<ui::LatencyInfo> latency_info) { void SkiaRenderer::SwapBuffers(std::vector<ui::LatencyInfo> latency_info) {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <utility> #include <utility>
#include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSurface.h"
#include "ui/gfx/gpu_fence.h"
#include "ui/gfx/presentation_feedback.h" #include "ui/gfx/presentation_feedback.h"
namespace viz { namespace viz {
...@@ -80,4 +81,12 @@ void SkiaOutputDevice::FinishSwapBuffers( ...@@ -80,4 +81,12 @@ void SkiaOutputDevice::FinishSwapBuffers(
void SkiaOutputDevice::EnsureBackbuffer() {} void SkiaOutputDevice::EnsureBackbuffer() {}
void SkiaOutputDevice::DiscardBackbuffer() {} void SkiaOutputDevice::DiscardBackbuffer() {}
gl::GLImage* SkiaOutputDevice::GetOverlayImage() {
return nullptr;
}
std::unique_ptr<gfx::GpuFence> SkiaOutputDevice::SubmitOverlayGpuFence() {
return nullptr;
}
} // namespace viz } // namespace viz
...@@ -19,6 +19,7 @@ class SkSurface; ...@@ -19,6 +19,7 @@ class SkSurface;
namespace gfx { namespace gfx {
class ColorSpace; class ColorSpace;
class GpuFence;
class Rect; class Rect;
class Size; class Size;
struct PresentationFeedback; struct PresentationFeedback;
...@@ -75,6 +76,9 @@ class SkiaOutputDevice { ...@@ -75,6 +76,9 @@ class SkiaOutputDevice {
BufferPresentedCallback feedback, BufferPresentedCallback feedback,
std::vector<ui::LatencyInfo> latency_info); std::vector<ui::LatencyInfo> latency_info);
virtual gl::GLImage* GetOverlayImage();
virtual std::unique_ptr<gfx::GpuFence> SubmitOverlayGpuFence();
// Set the rectangle that will be drawn into on the surface. // Set the rectangle that will be drawn into on the surface.
virtual void SetDrawRectangle(const gfx::Rect& draw_rectangle); virtual void SetDrawRectangle(const gfx::Rect& draw_rectangle);
......
// 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_BUFFER_QUEUE_H_
#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_BUFFER_QUEUE_H_
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/viz/service/display_embedder/skia_output_device.h"
#include "components/viz/service/viz_service_export.h"
#include "gpu/command_buffer/service/shared_image_factory.h"
namespace gpu {
class SharedImageRepresentationSkia;
} // namespace gpu
namespace gl {
class GLFence;
class GLSurface;
} // namespace gl
namespace viz {
class SkiaOutputSurfaceDependency;
class VIZ_SERVICE_EXPORT SkiaOutputDeviceBufferQueue final
: public SkiaOutputDevice {
public:
SkiaOutputDeviceBufferQueue(
scoped_refptr<gl::GLSurface> gl_surface,
SkiaOutputSurfaceDependency* deps,
const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback);
SkiaOutputDeviceBufferQueue(
scoped_refptr<gl::GLSurface> gl_surface,
SkiaOutputSurfaceDependency* deps,
const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback,
uint32_t shared_image_usage);
~SkiaOutputDeviceBufferQueue() override;
void SwapBuffers(BufferPresentedCallback feedback,
std::vector<ui::LatencyInfo> latency_info) override;
void PostSubBuffer(const gfx::Rect& rect,
BufferPresentedCallback feedback,
std::vector<ui::LatencyInfo> latency_info) override;
void Reshape(const gfx::Size& size,
float device_scale_factor,
const gfx::ColorSpace& color_space,
bool has_alpha,
gfx::OverlayTransform transform) override;
SkSurface* BeginPaint() override;
void EndPaint(const GrBackendSemaphore& semaphore) override;
bool supports_alpha() { return true; }
gl::GLImage* GetOverlayImage() override;
// Creates and submits gpu fence
std::unique_ptr<gfx::GpuFence> SubmitOverlayGpuFence() override;
private:
friend class SkiaOutputDeviceBufferQueueTest;
class VIZ_SERVICE_EXPORT Image {
public:
Image(gpu::SharedImageFactory* factory,
gpu::SharedImageRepresentationFactory* representation_factory);
~Image();
bool Initialize(const gfx::Size& size,
const gfx::ColorSpace& color_space,
ResourceFormat format,
SkiaOutputSurfaceDependency* deps,
uint32_t shared_image_usage);
sk_sp<SkSurface> BeginWriteSkia();
void EndWriteSkia();
gl::GLImage* GetImage() const;
std::unique_ptr<gfx::GpuFence> CreateFence();
void ResetFence();
private:
gpu::Mailbox mailbox;
std::unique_ptr<gpu::SharedImageRepresentationSkia> skia_representation_;
std::unique_ptr<gpu::SharedImageRepresentationGLTexture> gl_representation_;
std::vector<GrBackendSemaphore> end_semaphores_;
sk_sp<SkSurface> sk_surface_;
std::unique_ptr<gl::GLFence> fence_;
gpu::SharedImageFactory* factory_;
gpu::SharedImageRepresentationFactory* representation_factory_;
};
Image* GetCurrentImage();
std::unique_ptr<Image> GetNextImage();
void PageFlipComplete();
void FreeAllSurfaces();
// Used as callback for SwapBuffersAsync and PostSubBufferAsync to finish
// operation
void DoFinishSwapBuffers(const gfx::Size& size,
std::vector<ui::LatencyInfo> latency_info,
gfx::SwapResult result,
std::unique_ptr<gfx::GpuFence>);
SkiaOutputSurfaceDependency* const dependency_;
scoped_refptr<gl::GLSurface> gl_surface_;
// Format of images
gfx::ColorSpace color_space_;
gfx::Size image_size_;
// This image is currently used by Skia as RenderTarget. This may be nullptr
// if no drawing in progress or if allocation failed at bind.
std::unique_ptr<Image> current_image_;
// The image currently on the screen, if any.
std::unique_ptr<Image> displayed_image_;
// These are free for use, and are not nullptr.
std::vector<std::unique_ptr<Image>> available_images_;
// These have been scheduled to display but are not displayed yet.
// Entries of this deque may be nullptr, if they represent frames that have
// been destroyed.
base::circular_deque<std::unique_ptr<Image>> in_flight_images_;
// Shared Image factories
gpu::SharedImageFactory shared_image_factory_;
std::unique_ptr<gpu::SharedImageRepresentationFactory>
shared_image_representation_factory_;
uint32_t shared_image_usage_;
base::WeakPtrFactory<SkiaOutputDeviceBufferQueue> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(SkiaOutputDeviceBufferQueue);
};
} // namespace viz
#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_BUFFER_QUEUE_H_
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <utility> #include <utility>
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "components/viz/service/display_embedder/skia_output_surface_dependency.h"
#include "gpu/command_buffer/common/swap_buffers_complete_params.h" #include "gpu/command_buffer/common/swap_buffers_complete_params.h"
#include "gpu/command_buffer/service/feature_info.h" #include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gl_utils.h" #include "gpu/command_buffer/service/gl_utils.h"
...@@ -24,15 +23,13 @@ ...@@ -24,15 +23,13 @@
namespace viz { namespace viz {
SkiaOutputDeviceGL::SkiaOutputDeviceGL( SkiaOutputDeviceGL::SkiaOutputDeviceGL(
SkiaOutputSurfaceDependency* deps, scoped_refptr<gl::GLSurface> gl_surface,
scoped_refptr<gpu::gles2::FeatureInfo> feature_info, scoped_refptr<gpu::gles2::FeatureInfo> feature_info,
const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback) const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback)
: SkiaOutputDevice(false /*need_swap_semaphore */, : SkiaOutputDevice(false /*need_swap_semaphore */,
did_swap_buffer_complete_callback), did_swap_buffer_complete_callback),
dependency_(deps), feature_info_(feature_info),
feature_info_(feature_info) { gl_surface_(gl_surface) {}
gl_surface_ = dependency_->CreateGLSurface(weak_ptr_factory_.GetWeakPtr());
}
void SkiaOutputDeviceGL::Initialize(GrContext* gr_context, void SkiaOutputDeviceGL::Initialize(GrContext* gr_context,
gl::GLContext* gl_context) { gl::GLContext* gl_context) {
...@@ -179,8 +176,7 @@ void SkiaOutputDeviceGL::EndPaint(const GrBackendSemaphore& semaphore) {} ...@@ -179,8 +176,7 @@ void SkiaOutputDeviceGL::EndPaint(const GrBackendSemaphore& semaphore) {}
void SkiaOutputDeviceGL::DidCreateAcceleratedSurfaceChildWindow( void SkiaOutputDeviceGL::DidCreateAcceleratedSurfaceChildWindow(
gpu::SurfaceHandle parent_window, gpu::SurfaceHandle parent_window,
gpu::SurfaceHandle child_window) { gpu::SurfaceHandle child_window) {
dependency_->DidCreateAcceleratedSurfaceChildWindow(parent_window, NOTREACHED();
child_window);
} }
#endif #endif
......
...@@ -34,13 +34,11 @@ class FeatureInfo; ...@@ -34,13 +34,11 @@ class FeatureInfo;
namespace viz { namespace viz {
class SkiaOutputSurfaceDependency;
class SkiaOutputDeviceGL final : public SkiaOutputDevice, class SkiaOutputDeviceGL final : public SkiaOutputDevice,
public gpu::ImageTransportSurfaceDelegate { public gpu::ImageTransportSurfaceDelegate {
public: public:
SkiaOutputDeviceGL( SkiaOutputDeviceGL(
SkiaOutputSurfaceDependency* deps, scoped_refptr<gl::GLSurface> gl_surface,
scoped_refptr<gpu::gles2::FeatureInfo> feature_info, scoped_refptr<gpu::gles2::FeatureInfo> feature_info,
const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback); const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback);
~SkiaOutputDeviceGL() override; ~SkiaOutputDeviceGL() override;
...@@ -82,7 +80,6 @@ class SkiaOutputDeviceGL final : public SkiaOutputDevice, ...@@ -82,7 +80,6 @@ class SkiaOutputDeviceGL final : public SkiaOutputDevice,
GpuVSyncCallback GetGpuVSyncCallback() override; GpuVSyncCallback GetGpuVSyncCallback() override;
private: private:
SkiaOutputSurfaceDependency* const dependency_;
scoped_refptr<gpu::gles2::FeatureInfo> feature_info_; scoped_refptr<gpu::gles2::FeatureInfo> feature_info_;
gpu::GpuPreferences gpu_preferences_; gpu::GpuPreferences gpu_preferences_;
......
...@@ -357,6 +357,16 @@ void SkiaOutputSurfaceImpl::SkiaSwapBuffers(OutputSurfaceFrame frame) { ...@@ -357,6 +357,16 @@ void SkiaOutputSurfaceImpl::SkiaSwapBuffers(OutputSurfaceFrame frame) {
ScheduleGpuTask(std::move(callback), std::vector<gpu::SyncToken>()); ScheduleGpuTask(std::move(callback), std::vector<gpu::SyncToken>());
} }
void SkiaOutputSurfaceImpl::ScheduleOverlays(OverlayCandidateList overlays) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
// impl_on_gpu_ is released on the GPU thread by a posted task from
// SkiaOutputSurfaceImpl::dtor. So it is safe to use base::Unretained.
auto callback =
base::BindOnce(&SkiaOutputSurfaceImplOnGpu::ScheduleOverlays,
base::Unretained(impl_on_gpu_.get()), std::move(overlays));
ScheduleGpuTask(std::move(callback), std::vector<gpu::SyncToken>());
}
SkCanvas* SkiaOutputSurfaceImpl::BeginPaintRenderPass( SkCanvas* SkiaOutputSurfaceImpl::BeginPaintRenderPass(
const RenderPassId& id, const RenderPassId& id,
const gfx::Size& surface_size, const gfx::Size& surface_size,
...@@ -558,6 +568,7 @@ void SkiaOutputSurfaceImpl::InitializeOnGpuThread(base::WaitableEvent* event, ...@@ -558,6 +568,7 @@ void SkiaOutputSurfaceImpl::InitializeOnGpuThread(base::WaitableEvent* event,
*result = false; *result = false;
} else { } else {
capabilities_ = impl_on_gpu_->capabilities(); capabilities_ = impl_on_gpu_->capabilities();
is_displayed_as_overlay_ = impl_on_gpu_->IsDisplayedAsOverlay();
*result = true; *result = true;
} }
} }
...@@ -681,7 +692,7 @@ uint32_t SkiaOutputSurfaceImpl::GetFramebufferCopyTextureFormat() { ...@@ -681,7 +692,7 @@ uint32_t SkiaOutputSurfaceImpl::GetFramebufferCopyTextureFormat() {
} }
bool SkiaOutputSurfaceImpl::IsDisplayedAsOverlayPlane() const { bool SkiaOutputSurfaceImpl::IsDisplayedAsOverlayPlane() const {
return false; return is_displayed_as_overlay_;
} }
unsigned SkiaOutputSurfaceImpl::GetOverlayTextureId() const { unsigned SkiaOutputSurfaceImpl::GetOverlayTextureId() const {
......
...@@ -90,6 +90,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface { ...@@ -90,6 +90,8 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
sk_sp<SkColorSpace> dst_color_space, sk_sp<SkColorSpace> dst_color_space,
bool has_alpha) override; bool has_alpha) override;
void SkiaSwapBuffers(OutputSurfaceFrame frame) override; void SkiaSwapBuffers(OutputSurfaceFrame frame) override;
void ScheduleOverlays(OverlayCandidateList overlays) override;
SkCanvas* BeginPaintRenderPass(const RenderPassId& id, SkCanvas* BeginPaintRenderPass(const RenderPassId& id,
const gfx::Size& surface_size, const gfx::Size& surface_size,
ResourceFormat format, ResourceFormat format,
...@@ -160,6 +162,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface { ...@@ -160,6 +162,7 @@ class VIZ_SERVICE_EXPORT SkiaOutputSurfaceImpl : public SkiaOutputSurface {
std::unique_ptr<SkiaOutputSurfaceDependency> dependency_; std::unique_ptr<SkiaOutputSurfaceDependency> dependency_;
const bool is_using_vulkan_; const bool is_using_vulkan_;
UpdateVSyncParametersCallback update_vsync_parameters_callback_; UpdateVSyncParametersCallback update_vsync_parameters_callback_;
bool is_displayed_as_overlay_ = false;
std::unique_ptr<base::WaitableEvent> initialize_waitable_event_; std::unique_ptr<base::WaitableEvent> initialize_waitable_event_;
SkSurfaceCharacterization characterization_; SkSurfaceCharacterization characterization_;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/atomic_sequence_num.h" #include "base/atomic_sequence_num.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback_helpers.h" #include "base/callback_helpers.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/optional.h" #include "base/optional.h"
...@@ -22,6 +23,7 @@ ...@@ -22,6 +23,7 @@
#include "components/viz/service/display_embedder/direct_context_provider.h" #include "components/viz/service/display_embedder/direct_context_provider.h"
#include "components/viz/service/display_embedder/image_context.h" #include "components/viz/service/display_embedder/image_context.h"
#include "components/viz/service/display_embedder/skia_output_device.h" #include "components/viz/service/display_embedder/skia_output_device.h"
#include "components/viz/service/display_embedder/skia_output_device_buffer_queue.h"
#include "components/viz/service/display_embedder/skia_output_device_gl.h" #include "components/viz/service/display_embedder/skia_output_device_gl.h"
#include "components/viz/service/display_embedder/skia_output_device_offscreen.h" #include "components/viz/service/display_embedder/skia_output_device_offscreen.h"
#include "components/viz/service/display_embedder/skia_output_surface_dependency.h" #include "components/viz/service/display_embedder/skia_output_surface_dependency.h"
...@@ -40,12 +42,12 @@ ...@@ -40,12 +42,12 @@
#include "gpu/config/gpu_preferences.h" #include "gpu/config/gpu_preferences.h"
#include "gpu/ipc/common/gpu_client_ids.h" #include "gpu/ipc/common/gpu_client_ids.h"
#include "gpu/ipc/common/gpu_surface_lookup.h" #include "gpu/ipc/common/gpu_surface_lookup.h"
#include "gpu/ipc/service/image_transport_surface.h"
#include "gpu/vulkan/buildflags.h" #include "gpu/vulkan/buildflags.h"
#include "skia/ext/image_operations.h" #include "skia/ext/image_operations.h"
#include "third_party/skia/include/core/SkPixelRef.h" #include "third_party/skia/include/core/SkPixelRef.h"
#include "third_party/skia/include/private/SkDeferredDisplayList.h" #include "third_party/skia/include/private/SkDeferredDisplayList.h"
#include "ui/gfx/color_space.h" #include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/skia_util.h" #include "ui/gfx/skia_util.h"
#include "ui/gl/gl_bindings.h" #include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h" #include "ui/gl/gl_context.h"
...@@ -592,9 +594,13 @@ SkiaOutputSurfaceImplOnGpu::~SkiaOutputSurfaceImplOnGpu() { ...@@ -592,9 +594,13 @@ SkiaOutputSurfaceImplOnGpu::~SkiaOutputSurfaceImplOnGpu() {
// This ensures any outstanding callbacks for promise images are performed. // This ensures any outstanding callbacks for promise images are performed.
gr_context()->flush(); gr_context()->flush();
} }
copier_ = nullptr;
texture_deleter_ = nullptr; if (copier_) {
context_provider_ = nullptr; copier_ = nullptr;
texture_deleter_ = nullptr;
context_provider_ = nullptr;
MakeCurrent(false /* need_fbo0 */);
}
sync_point_client_state_->Destroy(); sync_point_client_state_->Destroy();
} }
...@@ -645,15 +651,15 @@ void SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame( ...@@ -645,15 +651,15 @@ void SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame(
DCHECK(ddl); DCHECK(ddl);
DCHECK(!scoped_output_device_paint_); DCHECK(!scoped_output_device_paint_);
if (!MakeCurrent(true /* need_fbo0 */))
return;
// We do not reset scoped_output_device_paint_ after drawing the ddl until // We do not reset scoped_output_device_paint_ after drawing the ddl until
// SwapBuffers() is called, because we may need access to output_sk_surface() // SwapBuffers() is called, because we may need access to output_sk_surface()
// for CopyOutput(). // for CopyOutput().
scoped_output_device_paint_.emplace(output_device_.get()); scoped_output_device_paint_.emplace(output_device_.get());
DCHECK(output_sk_surface()); DCHECK(output_sk_surface());
if (!MakeCurrent(true /* need_fbo0 */))
return;
dependency_->ScheduleGrContextCleanup(); dependency_->ScheduleGrContextCleanup();
PullTextureUpdates(std::move(sync_tokens)); PullTextureUpdates(std::move(sync_tokens));
...@@ -727,6 +733,36 @@ void SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame( ...@@ -727,6 +733,36 @@ void SkiaOutputSurfaceImplOnGpu::FinishPaintCurrentFrame(
ReleaseFenceSyncAndPushTextureUpdates(sync_fence_release); ReleaseFenceSyncAndPushTextureUpdates(sync_fence_release);
} }
void SkiaOutputSurfaceImplOnGpu::ScheduleOverlays(
const OverlayCandidateList& overlays) {
if (overlays.empty())
return;
DCHECK(!is_using_vulkan());
if (!MakeCurrent(!dependency_->IsOffscreen() /* need_fbo0 */))
return;
for (const auto& overlay_candidate : overlays) {
gl::GLImage* image = nullptr;
std::unique_ptr<gfx::GpuFence> gpu_fence;
if (overlay_candidate.use_output_surface_for_resource) {
image = output_device_->GetOverlayImage();
gpu_fence = output_device_->SubmitOverlayGpuFence();
} else {
NOTIMPLEMENTED_LOG_ONCE();
}
if (image) {
gl_surface_->ScheduleOverlayPlane(
overlay_candidate.plane_z_order, overlay_candidate.transform, image,
ToNearestRect(overlay_candidate.display_rect),
overlay_candidate.uv_rect, !overlay_candidate.is_opaque,
std::move(gpu_fence));
}
}
}
void SkiaOutputSurfaceImplOnGpu::SwapBuffers(OutputSurfaceFrame frame) { void SkiaOutputSurfaceImplOnGpu::SwapBuffers(OutputSurfaceFrame frame) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
DCHECK(scoped_output_device_paint_); DCHECK(scoped_output_device_paint_);
...@@ -1256,20 +1292,6 @@ bool SkiaOutputSurfaceImplOnGpu::Initialize() { ...@@ -1256,20 +1292,6 @@ bool SkiaOutputSurfaceImplOnGpu::Initialize() {
} }
bool SkiaOutputSurfaceImplOnGpu::InitializeForGL() { bool SkiaOutputSurfaceImplOnGpu::InitializeForGL() {
std::unique_ptr<SkiaOutputDeviceGL> onscreen_device;
if (!dependency_->IsOffscreen()) {
onscreen_device = std::make_unique<SkiaOutputDeviceGL>(
dependency_, feature_info_, did_swap_buffer_complete_callback_);
gl_surface_ = onscreen_device->gl_surface();
} else {
gl_surface_ = dependency_->CreateGLSurface(nullptr);
}
if (!gl_surface_)
return false;
DCHECK_EQ(gl_surface_->IsOffscreen(), dependency_->IsOffscreen());
context_state_ = dependency_->GetSharedContextState(); context_state_ = dependency_->GetSharedContextState();
if (!context_state_) { if (!context_state_) {
DLOG(ERROR) << "Failed to create GrContext"; DLOG(ERROR) << "Failed to create GrContext";
...@@ -1281,23 +1303,47 @@ bool SkiaOutputSurfaceImplOnGpu::InitializeForGL() { ...@@ -1281,23 +1303,47 @@ bool SkiaOutputSurfaceImplOnGpu::InitializeForGL() {
api_ = current_gl->Api; api_ = current_gl->Api;
gl_version_info_ = context->GetVersionInfo(); gl_version_info_ = context->GetVersionInfo();
if (onscreen_device) { if (dependency_->IsOffscreen()) {
if (!MakeCurrent(true /* need_fbo0 */)) { gl_surface_ = dependency_->CreateGLSurface(nullptr);
gl_surface_ = nullptr; if (!gl_surface_)
context_state_ = nullptr;
DLOG(ERROR) << "Failed to make current during initialization.";
return false; return false;
}
onscreen_device->Initialize(gr_context(), context);
supports_alpha_ = onscreen_device->supports_alpha();
output_device_ = std::move(onscreen_device);
} else {
output_device_ = std::make_unique<SkiaOutputDeviceOffscreen>( output_device_ = std::make_unique<SkiaOutputDeviceOffscreen>(
gr_context(), true /* flipped */, gr_context(), true /* flipped */,
renderer_settings_.requires_alpha_channel, renderer_settings_.requires_alpha_channel,
did_swap_buffer_complete_callback_); did_swap_buffer_complete_callback_);
supports_alpha_ = renderer_settings_.requires_alpha_channel; supports_alpha_ = renderer_settings_.requires_alpha_channel;
} else {
gl_surface_ = dependency_->CreateGLSurface(weak_ptr_factory_.GetWeakPtr());
if (!gl_surface_)
return false;
if (MakeCurrent(true /* need_fbo0 */)) {
if (gl_surface_->IsSurfaceless()) {
std::unique_ptr<SkiaOutputDeviceBufferQueue> onscreen_device =
std::make_unique<SkiaOutputDeviceBufferQueue>(
gl_surface_, dependency_, did_swap_buffer_complete_callback_);
supports_alpha_ = onscreen_device->supports_alpha();
output_device_ = std::move(onscreen_device);
} else {
std::unique_ptr<SkiaOutputDeviceGL> onscreen_device =
std::make_unique<SkiaOutputDeviceGL>(
gl_surface_, feature_info_, did_swap_buffer_complete_callback_);
onscreen_device->Initialize(gr_context(), context);
supports_alpha_ = onscreen_device->supports_alpha();
output_device_ = std::move(onscreen_device);
}
} else {
gl_surface_ = nullptr;
context_state_ = nullptr;
LOG(FATAL) << "Failed to make current during initialization.";
return false;
}
} }
DCHECK_EQ(gl_surface_->IsOffscreen(), dependency_->IsOffscreen());
return true; return true;
} }
...@@ -1419,4 +1465,41 @@ void SkiaOutputSurfaceImplOnGpu::ReleaseFenceSyncAndPushTextureUpdates( ...@@ -1419,4 +1465,41 @@ void SkiaOutputSurfaceImplOnGpu::ReleaseFenceSyncAndPushTextureUpdates(
sync_point_client_state_->ReleaseFenceSync(sync_fence_release); sync_point_client_state_->ReleaseFenceSync(sync_fence_release);
} }
bool SkiaOutputSurfaceImplOnGpu::IsDisplayedAsOverlay() {
return gl_surface_ ? gl_surface_->IsSurfaceless() : false;
}
#if defined(OS_WIN)
void SkiaOutputSurfaceImplOnGpu::DidCreateAcceleratedSurfaceChildWindow(
gpu::SurfaceHandle parent_window,
gpu::SurfaceHandle child_window) {
dependency_->DidCreateAcceleratedSurfaceChildWindow(parent_window,
child_window);
}
#endif
const gpu::gles2::FeatureInfo* SkiaOutputSurfaceImplOnGpu::GetFeatureInfo()
const {
return feature_info_.get();
}
const gpu::GpuPreferences& SkiaOutputSurfaceImplOnGpu::GetGpuPreferences()
const {
return gpu_preferences_;
}
GpuVSyncCallback SkiaOutputSurfaceImplOnGpu::GetGpuVSyncCallback() {
return base::DoNothing::Repeatedly<base::TimeTicks, base::TimeDelta>();
}
void SkiaOutputSurfaceImplOnGpu::DidSwapBuffersComplete(
gpu::SwapBuffersCompleteParams params) {
NOTIMPLEMENTED_LOG_ONCE();
}
void SkiaOutputSurfaceImplOnGpu::BufferPresented(
const gfx::PresentationFeedback& feedback) {
NOTIMPLEMENTED_LOG_ONCE();
}
} // namespace viz } // namespace viz
...@@ -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 { class SkiaOutputSurfaceImplOnGpu : public gpu::ImageTransportSurfaceDelegate {
public: public:
using DidSwapBufferCompleteCallback = using DidSwapBufferCompleteCallback =
base::RepeatingCallback<void(gpu::SwapBuffersCompleteParams, base::RepeatingCallback<void(gpu::SwapBuffersCompleteParams,
...@@ -92,7 +92,7 @@ class SkiaOutputSurfaceImplOnGpu { ...@@ -92,7 +92,7 @@ class SkiaOutputSurfaceImplOnGpu {
const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback, const DidSwapBufferCompleteCallback& did_swap_buffer_complete_callback,
const BufferPresentedCallback& buffer_presented_callback, const BufferPresentedCallback& buffer_presented_callback,
const ContextLostCallback& context_lost_callback); const ContextLostCallback& context_lost_callback);
~SkiaOutputSurfaceImplOnGpu(); ~SkiaOutputSurfaceImplOnGpu() override;
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();
...@@ -119,6 +119,7 @@ class SkiaOutputSurfaceImplOnGpu { ...@@ -119,6 +119,7 @@ class SkiaOutputSurfaceImplOnGpu {
std::vector<gpu::SyncToken> sync_tokens, std::vector<gpu::SyncToken> sync_tokens,
uint64_t sync_fence_release, uint64_t sync_fence_release,
base::OnceClosure on_finished); base::OnceClosure on_finished);
void ScheduleOverlays(const OverlayCandidateList& overlays);
void SwapBuffers(OutputSurfaceFrame frame); void SwapBuffers(OutputSurfaceFrame frame);
void EnsureBackbuffer() { output_device_->EnsureBackbuffer(); } void EnsureBackbuffer() { output_device_->EnsureBackbuffer(); }
void DiscardBackbuffer() { output_device_->DiscardBackbuffer(); } void DiscardBackbuffer() { output_device_->DiscardBackbuffer(); }
...@@ -154,6 +155,20 @@ class SkiaOutputSurfaceImplOnGpu { ...@@ -154,6 +155,20 @@ class SkiaOutputSurfaceImplOnGpu {
void SetCapabilitiesForTesting( void SetCapabilitiesForTesting(
const OutputSurface::Capabilities& capabilities); const OutputSurface::Capabilities& capabilities);
bool IsDisplayedAsOverlay();
// gpu::ImageTransportSurfaceDelegate implementation:
#if defined(OS_WIN)
void DidCreateAcceleratedSurfaceChildWindow(
gpu::SurfaceHandle parent_window,
gpu::SurfaceHandle child_window) override;
#endif
const gpu::gles2::FeatureInfo* GetFeatureInfo() const override;
const gpu::GpuPreferences& GetGpuPreferences() const override;
void DidSwapBuffersComplete(gpu::SwapBuffersCompleteParams params) override;
void BufferPresented(const gfx::PresentationFeedback& feedback) override;
GpuVSyncCallback GetGpuVSyncCallback() override;
private: private:
class ScopedPromiseImageAccess; class ScopedPromiseImageAccess;
......
...@@ -83,6 +83,11 @@ void FakeSkiaOutputSurface::SwapBuffers(OutputSurfaceFrame frame) { ...@@ -83,6 +83,11 @@ void FakeSkiaOutputSurface::SwapBuffers(OutputSurfaceFrame frame) {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
void FakeSkiaOutputSurface::ScheduleOverlays(OverlayCandidateList overlays) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
NOTIMPLEMENTED();
}
uint32_t FakeSkiaOutputSurface::GetFramebufferCopyTextureFormat() { uint32_t FakeSkiaOutputSurface::GetFramebufferCopyTextureFormat() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return GL_RGB; return GL_RGB;
......
...@@ -49,6 +49,7 @@ class FakeSkiaOutputSurface : public SkiaOutputSurface { ...@@ -49,6 +49,7 @@ class FakeSkiaOutputSurface : public SkiaOutputSurface {
bool has_alpha, bool has_alpha,
bool use_stencil) override; bool use_stencil) override;
void SwapBuffers(OutputSurfaceFrame frame) override; void SwapBuffers(OutputSurfaceFrame frame) override;
void ScheduleOverlays(OverlayCandidateList overlays) override;
uint32_t GetFramebufferCopyTextureFormat() override; uint32_t GetFramebufferCopyTextureFormat() override;
bool IsDisplayedAsOverlayPlane() const override; bool IsDisplayedAsOverlayPlane() const override;
unsigned GetOverlayTextureId() const override; unsigned GetOverlayTextureId() const override;
......
...@@ -293,6 +293,13 @@ SharedImageBackingFactory* SharedImageFactory::GetFactoryByUsage( ...@@ -293,6 +293,13 @@ SharedImageBackingFactory* SharedImageFactory::GetFactoryByUsage(
bool using_interop_factory = share_between_threads || bool using_interop_factory = share_between_threads ||
share_between_gl_vulkan || using_dawn || share_between_gl_vulkan || using_dawn ||
share_between_gl_metal; share_between_gl_metal;
// TODO(vasilyt): Android required AHB for overlays
// What about other platforms?
#if defined(OS_ANDROID)
using_interop_factory |= usage & SHARED_IMAGE_USAGE_SCANOUT;
#endif
// wrapped_sk_image_factory_ is only used for OOPR and supports // wrapped_sk_image_factory_ is only used for OOPR and supports
// a limited number of flags (e.g. no SHARED_IMAGE_USAGE_SCANOUT). // a limited number of flags (e.g. no SHARED_IMAGE_USAGE_SCANOUT).
constexpr auto kWrappedSkImageUsage = SHARED_IMAGE_USAGE_RASTER | constexpr auto kWrappedSkImageUsage = SHARED_IMAGE_USAGE_RASTER |
......
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