123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728 |
- From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
- From: Andy Dill <[email protected]>
- Date: Thu, 30 Jan 2020 09:36:07 -0800
- Subject: feat: enable off-screen rendering with viz compositor
- This patch adds hooks in the relevant places that allow for off-screen
- rendering with the viz compositor by way of a custom HostDisplayClient
- and LayeredWindowUpdater.
- diff --git a/components/viz/host/host_display_client.cc b/components/viz/host/host_display_client.cc
- index 0ad0fcd3d3ab1f13c3fc133db39135679bf84735..94cb46494157f7683931c54e135572245da79ae0 100644
- --- a/components/viz/host/host_display_client.cc
- +++ b/components/viz/host/host_display_client.cc
- @@ -48,9 +48,9 @@ void HostDisplayClient::OnDisplayReceivedCALayerParams(
- }
- #endif
-
- -#if BUILDFLAG(IS_WIN)
- void HostDisplayClient::CreateLayeredWindowUpdater(
- mojo::PendingReceiver<mojom::LayeredWindowUpdater> receiver) {
- +#if BUILDFLAG(IS_WIN)
- if (!NeedsToUseLayerWindow(widget_)) {
- DLOG(ERROR) << "HWND shouldn't be using a layered window";
- return;
- @@ -58,7 +58,15 @@ void HostDisplayClient::CreateLayeredWindowUpdater(
-
- layered_window_updater_ =
- std::make_unique<LayeredWindowUpdaterImpl>(widget_, std::move(receiver));
- +
- +#else
- + CHECK(false) << "Chromium is calling CreateLayeredWindowUpdater for non-OSR "
- + "windows on POSIX platforms, something is wrong with "
- + "Electron's OSR implementation.";
- +#endif
- }
- +
- +#if BUILDFLAG(IS_WIN)
- void HostDisplayClient::AddChildWindowToBrowser(
- gpu::SurfaceHandle child_window) {
- NOTREACHED_IN_MIGRATION();
- diff --git a/components/viz/host/host_display_client.h b/components/viz/host/host_display_client.h
- index cb16487f9fc0811ef577d455098f09e3000db86a..d67c0f8bce3c6a8f7643409e07e21e789b4bd391 100644
- --- a/components/viz/host/host_display_client.h
- +++ b/components/viz/host/host_display_client.h
- @@ -39,6 +39,9 @@ class VIZ_HOST_EXPORT HostDisplayClient : public mojom::DisplayClient {
- gfx::AcceleratedWidget widget() const { return widget_; }
- #endif
-
- + void CreateLayeredWindowUpdater(
- + mojo::PendingReceiver<mojom::LayeredWindowUpdater> receiver) override;
- +
- private:
- // mojom::DisplayClient implementation:
- #if BUILDFLAG(IS_APPLE)
- @@ -47,8 +50,6 @@ class VIZ_HOST_EXPORT HostDisplayClient : public mojom::DisplayClient {
- #endif
-
- #if BUILDFLAG(IS_WIN)
- - void CreateLayeredWindowUpdater(
- - mojo::PendingReceiver<mojom::LayeredWindowUpdater> receiver) override;
- void AddChildWindowToBrowser(gpu::SurfaceHandle child_window) override;
- #endif
-
- diff --git a/components/viz/host/layered_window_updater_impl.cc b/components/viz/host/layered_window_updater_impl.cc
- index 8f726bde2cb5da6acfe630006af0fc3a09811d6c..45d8cae3ba0fca9a1514f83032a10c8820b3126d 100644
- --- a/components/viz/host/layered_window_updater_impl.cc
- +++ b/components/viz/host/layered_window_updater_impl.cc
- @@ -46,7 +46,9 @@ void LayeredWindowUpdaterImpl::OnAllocatedSharedMemory(
- // |region|'s handle will close when it goes out of scope.
- }
-
- -void LayeredWindowUpdaterImpl::Draw(DrawCallback draw_callback) {
- +void LayeredWindowUpdaterImpl::Draw(
- + const gfx::Rect& damage_rect,
- + DrawCallback draw_callback) {
- TRACE_EVENT0("viz", "LayeredWindowUpdaterImpl::Draw");
-
- if (!canvas_) {
- diff --git a/components/viz/host/layered_window_updater_impl.h b/components/viz/host/layered_window_updater_impl.h
- index 8af69cac78b7488d28f1f05ccb174793fe5148cd..9f74e511c263d147b5fbe81fe100d217eb0b64c9 100644
- --- a/components/viz/host/layered_window_updater_impl.h
- +++ b/components/viz/host/layered_window_updater_impl.h
- @@ -38,7 +38,7 @@ class VIZ_HOST_EXPORT LayeredWindowUpdaterImpl
- // mojom::LayeredWindowUpdater implementation.
- void OnAllocatedSharedMemory(const gfx::Size& pixel_size,
- base::UnsafeSharedMemoryRegion region) override;
- - void Draw(DrawCallback draw_callback) override;
- + void Draw(const gfx::Rect& damage_rect, DrawCallback draw_callback) override;
-
- private:
- const HWND hwnd_;
- diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
- index 3c5ab7a6e6608b3f5e35f8b46a59880100b2a627..2cefb70548ddfbd1f98d4028177e661fec4cea9b 100644
- --- a/components/viz/service/BUILD.gn
- +++ b/components/viz/service/BUILD.gn
- @@ -169,6 +169,8 @@ viz_component("service") {
- "display_embedder/skia_output_surface_impl_on_gpu_debug_capture.h",
- "display_embedder/skia_render_copy_results.cc",
- "display_embedder/skia_render_copy_results.h",
- + "display_embedder/software_output_device_proxy.cc",
- + "display_embedder/software_output_device_proxy.h",
- "display_embedder/software_output_surface.cc",
- "display_embedder/software_output_surface.h",
- "display_embedder/vsync_parameter_listener.cc",
- diff --git a/components/viz/service/display_embedder/output_surface_provider.h b/components/viz/service/display_embedder/output_surface_provider.h
- index a4e6ad16fd2def9bbed7cd11ea13ba365a9f7322..20a426e6f7dff17c22dd05d75d601a560cd34283 100644
- --- a/components/viz/service/display_embedder/output_surface_provider.h
- +++ b/components/viz/service/display_embedder/output_surface_provider.h
- @@ -38,7 +38,8 @@ class OutputSurfaceProvider {
- mojom::DisplayClient* display_client,
- DisplayCompositorMemoryAndTaskController* gpu_dependency,
- const RendererSettings& renderer_settings,
- - const DebugRendererSettings* debug_settings) = 0;
- + const DebugRendererSettings* debug_settings,
- + bool offscreen) = 0;
-
- virtual gpu::SharedImageManager* GetSharedImageManager() = 0;
- virtual gpu::SyncPointManager* GetSyncPointManager() = 0;
- diff --git a/components/viz/service/display_embedder/output_surface_provider_impl.cc b/components/viz/service/display_embedder/output_surface_provider_impl.cc
- index 54a83ba9fe1e96f339117220da002987df98cd26..c89264115ea44bd7cabde7ff1123a5f05c8b0a1d 100644
- --- a/components/viz/service/display_embedder/output_surface_provider_impl.cc
- +++ b/components/viz/service/display_embedder/output_surface_provider_impl.cc
- @@ -25,12 +25,14 @@
- #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
- #include "components/viz/service/display_embedder/skia_output_surface_dependency_impl.h"
- #include "components/viz/service/display_embedder/skia_output_surface_impl.h"
- +#include "components/viz/service/display_embedder/software_output_device_proxy.h"
- #include "components/viz/service/display_embedder/software_output_surface.h"
- #include "components/viz/service/gl/gpu_service_impl.h"
- #include "gpu/command_buffer/client/shared_memory_limits.h"
- #include "gpu/command_buffer/service/scheduler_sequence.h"
- #include "gpu/config/gpu_finch_features.h"
- #include "gpu/ipc/common/surface_handle.h"
- +#include "services/viz/privileged/mojom/compositing/layered_window_updater.mojom.h"
- #include "ui/base/ui_base_switches.h"
-
- #if BUILDFLAG(IS_WIN)
- @@ -94,7 +96,8 @@ std::unique_ptr<OutputSurface> OutputSurfaceProviderImpl::CreateOutputSurface(
- mojom::DisplayClient* display_client,
- DisplayCompositorMemoryAndTaskController* gpu_dependency,
- const RendererSettings& renderer_settings,
- - const DebugRendererSettings* debug_settings) {
- + const DebugRendererSettings* debug_settings,
- + bool offscreen) {
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- if (surface_handle == gpu::kNullSurfaceHandle)
- return std::make_unique<OutputSurfaceUnified>();
- @@ -102,7 +105,7 @@ std::unique_ptr<OutputSurface> OutputSurfaceProviderImpl::CreateOutputSurface(
-
- if (!gpu_compositing) {
- return std::make_unique<SoftwareOutputSurface>(
- - CreateSoftwareOutputDeviceForPlatform(surface_handle, display_client));
- + CreateSoftwareOutputDeviceForPlatform(surface_handle, display_client, offscreen));
- } else {
- DCHECK(gpu_dependency);
-
- @@ -142,10 +145,22 @@ std::unique_ptr<OutputSurface> OutputSurfaceProviderImpl::CreateOutputSurface(
- std::unique_ptr<SoftwareOutputDevice>
- OutputSurfaceProviderImpl::CreateSoftwareOutputDeviceForPlatform(
- gpu::SurfaceHandle surface_handle,
- - mojom::DisplayClient* display_client) {
- + mojom::DisplayClient* display_client,
- + bool offscreen) {
- if (headless_)
- return std::make_unique<SoftwareOutputDevice>();
-
- +#if !BUILDFLAG(IS_APPLE)
- + if (offscreen) {
- + DCHECK(display_client);
- + mojo::PendingRemote<mojom::LayeredWindowUpdater> layered_window_updater;
- + display_client->CreateLayeredWindowUpdater(
- + layered_window_updater.InitWithNewPipeAndPassReceiver());
- + return std::make_unique<SoftwareOutputDeviceProxy>(
- + std::move(layered_window_updater));
- + }
- +#endif
- +
- #if BUILDFLAG(IS_WIN)
- return CreateSoftwareOutputDeviceWin(surface_handle, &output_device_backing_,
- display_client);
- diff --git a/components/viz/service/display_embedder/output_surface_provider_impl.h b/components/viz/service/display_embedder/output_surface_provider_impl.h
- index d149ef23deaf591e472fcd00a7ea32b2e4052b98..6e93321d2856d40a00fa04fe03a2bb72ba650e83 100644
- --- a/components/viz/service/display_embedder/output_surface_provider_impl.h
- +++ b/components/viz/service/display_embedder/output_surface_provider_impl.h
- @@ -50,7 +50,8 @@ class VIZ_SERVICE_EXPORT OutputSurfaceProviderImpl
- mojom::DisplayClient* display_client,
- DisplayCompositorMemoryAndTaskController* gpu_dependency,
- const RendererSettings& renderer_settings,
- - const DebugRendererSettings* debug_settings) override;
- + const DebugRendererSettings* debug_settings,
- + bool offscreen) override;
-
- gpu::SharedImageManager* GetSharedImageManager() override;
- gpu::SyncPointManager* GetSyncPointManager() override;
- @@ -58,7 +59,8 @@ class VIZ_SERVICE_EXPORT OutputSurfaceProviderImpl
- private:
- std::unique_ptr<SoftwareOutputDevice> CreateSoftwareOutputDeviceForPlatform(
- gpu::SurfaceHandle surface_handle,
- - mojom::DisplayClient* display_client);
- + mojom::DisplayClient* display_client,
- + bool offscreen);
-
- const raw_ptr<GpuServiceImpl> gpu_service_impl_;
-
- diff --git a/components/viz/service/display_embedder/software_output_device_mac.cc b/components/viz/service/display_embedder/software_output_device_mac.cc
- index 5dccc2360cd1f3d83ffc59697aeb559a19b0547a..5fe62069b15e6370e63645b257d931be2a714bc3 100644
- --- a/components/viz/service/display_embedder/software_output_device_mac.cc
- +++ b/components/viz/service/display_embedder/software_output_device_mac.cc
- @@ -106,6 +106,8 @@ void SoftwareOutputDeviceMac::UpdateAndCopyBufferDamage(
-
- SkCanvas* SoftwareOutputDeviceMac::BeginPaint(
- const gfx::Rect& new_damage_rect) {
- + last_damage = new_damage_rect;
- +
- // Record the previous paint buffer.
- Buffer* previous_paint_buffer =
- buffer_queue_.empty() ? nullptr : buffer_queue_.back().get();
- @@ -194,6 +196,7 @@ void SoftwareOutputDeviceMac::EndPaint() {
- ca_layer_params.is_empty = false;
- ca_layer_params.scale_factor = scale_factor_;
- ca_layer_params.pixel_size = pixel_size_;
- + ca_layer_params.damage = last_damage;
- ca_layer_params.io_surface_mach_port.reset(
- IOSurfaceCreateMachPort(current_paint_buffer_->io_surface.get()));
- client_->SoftwareDeviceUpdatedCALayerParams(ca_layer_params);
- diff --git a/components/viz/service/display_embedder/software_output_device_mac.h b/components/viz/service/display_embedder/software_output_device_mac.h
- index 67d5ff67d74c107a867b39b306c6528425b87e05..5fd12a25c9e319e8e675955926271c9d1cd3a7ca 100644
- --- a/components/viz/service/display_embedder/software_output_device_mac.h
- +++ b/components/viz/service/display_embedder/software_output_device_mac.h
- @@ -62,6 +62,7 @@ class VIZ_SERVICE_EXPORT SoftwareOutputDeviceMac : public SoftwareOutputDevice {
- void UpdateAndCopyBufferDamage(Buffer* previous_paint_buffer,
- const SkRegion& new_damage_rect);
-
- + gfx::Rect last_damage;
- gfx::Size pixel_size_;
- float scale_factor_ = 1;
-
- diff --git a/components/viz/service/display_embedder/software_output_device_proxy.cc b/components/viz/service/display_embedder/software_output_device_proxy.cc
- new file mode 100644
- index 0000000000000000000000000000000000000000..25c427e337a1bc049cd6977a13c4113085dc9401
- --- /dev/null
- +++ b/components/viz/service/display_embedder/software_output_device_proxy.cc
- @@ -0,0 +1,161 @@
- +// Copyright 2014 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/software_output_device_proxy.h"
- +
- +#include "base/memory/unsafe_shared_memory_region.h"
- +#include "base/threading/thread_checker.h"
- +#include "base/trace_event/trace_event.h"
- +#include "build/build_config.h"
- +#include "components/viz/common/resources/resource_sizes.h"
- +#include "components/viz/service/display_embedder/output_device_backing.h"
- +#include "mojo/public/cpp/system/platform_handle.h"
- +#include "services/viz/privileged/mojom/compositing/layered_window_updater.mojom.h"
- +#include "skia/ext/platform_canvas.h"
- +#include "third_party/skia/include/core/SkCanvas.h"
- +#include "ui/gfx/skia_util.h"
- +
- +#if BUILDFLAG(IS_WIN)
- +#include "skia/ext/skia_utils_win.h"
- +#include "ui/gfx/gdi_util.h"
- +#include "ui/gfx/win/hwnd_util.h"
- +#else
- +#include "mojo/public/cpp/base/shared_memory_utils.h"
- +#endif
- +
- +namespace viz {
- +
- +SoftwareOutputDeviceBase::~SoftwareOutputDeviceBase() {
- + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- + DCHECK(!in_paint_);
- +}
- +
- +void SoftwareOutputDeviceBase::Resize(const gfx::Size& viewport_pixel_size,
- + float scale_factor) {
- + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- + DCHECK(!in_paint_);
- +
- + if (viewport_pixel_size_ == viewport_pixel_size)
- + return;
- +
- + viewport_pixel_size_ = viewport_pixel_size;
- + ResizeDelegated();
- +}
- +
- +SkCanvas* SoftwareOutputDeviceBase::BeginPaint(const gfx::Rect& damage_rect) {
- + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- + DCHECK(!in_paint_);
- +
- + damage_rect_ = damage_rect;
- + in_paint_ = true;
- + return BeginPaintDelegated();
- +}
- +
- +void SoftwareOutputDeviceBase::EndPaint() {
- + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- + DCHECK(in_paint_);
- +
- + in_paint_ = false;
- +
- + gfx::Rect intersected_damage_rect = damage_rect_;
- + intersected_damage_rect.Intersect(gfx::Rect(viewport_pixel_size_));
- + if (intersected_damage_rect.IsEmpty())
- + return;
- +
- + EndPaintDelegated(intersected_damage_rect);
- +}
- +
- +SoftwareOutputDeviceProxy::~SoftwareOutputDeviceProxy() = default;
- +
- +SoftwareOutputDeviceProxy::SoftwareOutputDeviceProxy(
- + mojo::PendingRemote<mojom::LayeredWindowUpdater> layered_window_updater)
- + : layered_window_updater_(std::move(layered_window_updater)) {
- + DCHECK(layered_window_updater_.is_bound());
- +}
- +
- +void SoftwareOutputDeviceProxy::OnSwapBuffers(
- + SoftwareOutputDevice::SwapBuffersCallback swap_ack_callback,
- + gfx::FrameData data) {
- + DCHECK(swap_ack_callback_.is_null());
- +
- + // We aren't waiting on DrawAck() and can immediately run the callback.
- + if (!waiting_on_draw_ack_) {
- + task_runner_->PostTask(
- + FROM_HERE,
- + base::BindOnce(std::move(swap_ack_callback), viewport_pixel_size_));
- + return;
- + }
- +
- + swap_ack_callback_ = std::move(swap_ack_callback);
- +}
- +
- +void SoftwareOutputDeviceProxy::ResizeDelegated() {
- + canvas_.reset();
- +
- + size_t required_bytes;
- + if (!ResourceSizes::MaybeSizeInBytes(viewport_pixel_size_,
- + SinglePlaneFormat::kRGBA_8888,
- + &required_bytes)) {
- + DLOG(ERROR) << "Invalid viewport size " << viewport_pixel_size_.ToString();
- + return;
- + }
- +
- + base::UnsafeSharedMemoryRegion region =
- + base::UnsafeSharedMemoryRegion::Create(required_bytes);
- + if (!region.IsValid()) {
- + DLOG(ERROR) << "Failed to allocate " << required_bytes << " bytes";
- + return;
- + }
- +
- +#if defined(WIN32)
- + canvas_ = skia::CreatePlatformCanvasWithSharedSection(
- + viewport_pixel_size_.width(), viewport_pixel_size_.height(), false,
- + region.GetPlatformHandle(), skia::CRASH_ON_FAILURE);
- +#else
- + shm_mapping_ = region.Map();
- + if (!shm_mapping_.IsValid()) {
- + DLOG(ERROR) << "Failed to map " << required_bytes << " bytes";
- + return;
- + }
- +
- + canvas_ = skia::CreatePlatformCanvasWithPixels(
- + viewport_pixel_size_.width(), viewport_pixel_size_.height(), false,
- + static_cast<uint8_t*>(shm_mapping_.memory()), skia::CRASH_ON_FAILURE);
- +#endif
- +
- + // Transfer region ownership to the browser process.
- + layered_window_updater_->OnAllocatedSharedMemory(viewport_pixel_size_,
- + std::move(region));
- +}
- +
- +SkCanvas* SoftwareOutputDeviceProxy::BeginPaintDelegated() {
- + return canvas_.get();
- +}
- +
- +void SoftwareOutputDeviceProxy::EndPaintDelegated(
- + const gfx::Rect& damage_rect) {
- + DCHECK(!waiting_on_draw_ack_);
- +
- + if (!canvas_)
- + return;
- +
- + layered_window_updater_->Draw(
- + damage_rect, base::BindOnce(&SoftwareOutputDeviceProxy::DrawAck,
- + base::Unretained(this)));
- + waiting_on_draw_ack_ = true;
- +
- + TRACE_EVENT_ASYNC_BEGIN0("viz", "SoftwareOutputDeviceProxy::Draw", this);
- +}
- +
- +void SoftwareOutputDeviceProxy::DrawAck() {
- + DCHECK(waiting_on_draw_ack_);
- + DCHECK(!swap_ack_callback_.is_null());
- +
- + TRACE_EVENT_ASYNC_END0("viz", "SoftwareOutputDeviceProxy::Draw", this);
- +
- + waiting_on_draw_ack_ = false;
- + std::move(swap_ack_callback_).Run(viewport_pixel_size_);
- +}
- +
- +} // namespace viz
- diff --git a/components/viz/service/display_embedder/software_output_device_proxy.h b/components/viz/service/display_embedder/software_output_device_proxy.h
- new file mode 100644
- index 0000000000000000000000000000000000000000..e1a22ee881c0fd679ac2d2d4d11a3c937cc4e9d1
- --- /dev/null
- +++ b/components/viz/service/display_embedder/software_output_device_proxy.h
- @@ -0,0 +1,98 @@
- +// Copyright 2014 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_SOFTWARE_OUTPUT_DEVICE_PROXY_H_
- +#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_DEVICE_PROXY_H_
- +
- +#include <memory>
- +
- +#include "base/memory/shared_memory_mapping.h"
- +#include "base/threading/thread_checker.h"
- +#include "build/build_config.h"
- +#include "components/viz/host/host_display_client.h"
- +#include "components/viz/service/display/software_output_device.h"
- +#include "components/viz/service/viz_service_export.h"
- +#include "mojo/public/cpp/bindings/pending_remote.h"
- +#include "mojo/public/cpp/bindings/remote.h"
- +#include "services/viz/privileged/mojom/compositing/display_private.mojom.h"
- +#include "services/viz/privileged/mojom/compositing/layered_window_updater.mojom.h"
- +
- +#if BUILDFLAG(IS_WIN)
- +#include <windows.h>
- +#endif
- +
- +namespace viz {
- +
- +// Shared base class for SoftwareOutputDevice implementations.
- +class SoftwareOutputDeviceBase : public SoftwareOutputDevice {
- + public:
- + SoftwareOutputDeviceBase() = default;
- + ~SoftwareOutputDeviceBase() override;
- +
- + SoftwareOutputDeviceBase(const SoftwareOutputDeviceBase&) = delete;
- + SoftwareOutputDeviceBase& operator=(const SoftwareOutputDeviceBase&) = delete;
- +
- + // SoftwareOutputDevice implementation.
- + void Resize(const gfx::Size& viewport_pixel_size,
- + float scale_factor) override;
- + SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override;
- + void EndPaint() override;
- +
- + // Called from Resize() if |viewport_pixel_size_| has changed.
- + virtual void ResizeDelegated() = 0;
- +
- + // Called from BeginPaint() and should return an SkCanvas.
- + virtual SkCanvas* BeginPaintDelegated() = 0;
- +
- + // Called from EndPaint() if there is damage.
- + virtual void EndPaintDelegated(const gfx::Rect& damage_rect) = 0;
- +
- + private:
- + bool in_paint_ = false;
- +
- + THREAD_CHECKER(thread_checker_);
- +};
- +
- +// SoftwareOutputDevice implementation that draws indirectly. An implementation
- +// of mojom::LayeredWindowUpdater in the browser process handles the actual
- +// drawing. Pixel backing is in SharedMemory so no copying between processes
- +// is required.
- +class SoftwareOutputDeviceProxy : public SoftwareOutputDeviceBase {
- + public:
- + explicit SoftwareOutputDeviceProxy(
- + mojo::PendingRemote<mojom::LayeredWindowUpdater> layered_window_updater);
- + ~SoftwareOutputDeviceProxy() override;
- +
- + SoftwareOutputDeviceProxy(const SoftwareOutputDeviceProxy&) = delete;
- + SoftwareOutputDeviceProxy& operator=(const SoftwareOutputDeviceProxy&) =
- + delete;
- +
- + // SoftwareOutputDevice implementation.
- + void OnSwapBuffers(
- + SoftwareOutputDevice::SwapBuffersCallback swap_ack_callback,
- + gfx::FrameData data) override;
- +
- + // SoftwareOutputDeviceBase implementation.
- + void ResizeDelegated() override;
- + SkCanvas* BeginPaintDelegated() override;
- + void EndPaintDelegated(const gfx::Rect& rect) override;
- +
- + private:
- + // Runs |swap_ack_callback_| after draw has happened.
- + void DrawAck();
- +
- + mojo::Remote<mojom::LayeredWindowUpdater> layered_window_updater_;
- +
- + std::unique_ptr<SkCanvas> canvas_;
- + bool waiting_on_draw_ack_ = false;
- + SoftwareOutputDevice::SwapBuffersCallback swap_ack_callback_;
- +
- +#if !defined(WIN32)
- + base::WritableSharedMemoryMapping shm_mapping_;
- +#endif
- +};
- +
- +} // namespace viz
- +
- +#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_DEVICE_PROXY_H_
- diff --git a/components/viz/service/display_embedder/software_output_device_win.cc b/components/viz/service/display_embedder/software_output_device_win.cc
- index 796ae2688436eb07f19909641d1620dd02f10cdb..c9e0eee0b329caf46669b419b1cd10cf2a707ac8 100644
- --- a/components/viz/service/display_embedder/software_output_device_win.cc
- +++ b/components/viz/service/display_embedder/software_output_device_win.cc
- @@ -193,7 +193,7 @@ void SoftwareOutputDeviceWinProxy::EndPaintDelegated(
- if (!canvas_)
- return;
-
- - layered_window_updater_->Draw(base::BindOnce(
- + layered_window_updater_->Draw(damage_rect, base::BindOnce(
- &SoftwareOutputDeviceWinProxy::DrawAck, base::Unretained(this)));
- waiting_on_draw_ack_ = true;
-
- diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
- index 2cf77183de23c2715d5fcf93e03185da87e56e90..abc08f01c19afd62d97effe1c104f95ddaa3a1e6 100644
- --- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
- +++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
- @@ -100,7 +100,8 @@ RootCompositorFrameSinkImpl::Create(
- params->gpu_compositing, params->widget);
- auto output_surface = output_surface_provider->CreateOutputSurface(
- params->widget, params->gpu_compositing, display_client.get(),
- - display_controller.get(), params->renderer_settings, debug_settings);
- + display_controller.get(), params->renderer_settings, debug_settings,
- + params->offscreen);
-
- // Creating output surface failed. The host can send a new request, possibly
- // with a different compositing mode.
- diff --git a/components/viz/test/test_output_surface_provider.cc b/components/viz/test/test_output_surface_provider.cc
- index 7648cb06aa78891804bb0783f884b09e07597fbc..f1a73f157ca43620019b864aef35d0ad36c12353 100644
- --- a/components/viz/test/test_output_surface_provider.cc
- +++ b/components/viz/test/test_output_surface_provider.cc
- @@ -30,7 +30,8 @@ std::unique_ptr<OutputSurface> TestOutputSurfaceProvider::CreateOutputSurface(
- mojom::DisplayClient* display_client,
- DisplayCompositorMemoryAndTaskController* display_controller,
- const RendererSettings& renderer_settings,
- - const DebugRendererSettings* debug_settings) {
- + const DebugRendererSettings* debug_settings,
- + bool offscreen) {
- if (gpu_compositing) {
- return FakeSkiaOutputSurface::Create3d();
- } else {
- diff --git a/components/viz/test/test_output_surface_provider.h b/components/viz/test/test_output_surface_provider.h
- index febb2718cb34ea4d9f411f068d8c01a89c7db888..be8bd51cb61c20ef3df8552972a0ac2f11930150 100644
- --- a/components/viz/test/test_output_surface_provider.h
- +++ b/components/viz/test/test_output_surface_provider.h
- @@ -32,7 +32,8 @@ class TestOutputSurfaceProvider : public OutputSurfaceProvider {
- mojom::DisplayClient* display_client,
- DisplayCompositorMemoryAndTaskController* display_controller,
- const RendererSettings& renderer_settings,
- - const DebugRendererSettings* debug_settings) override;
- + const DebugRendererSettings* debug_settings,
- + bool offscreen) override;
- gpu::SharedImageManager* GetSharedImageManager() override;
- gpu::SyncPointManager* GetSyncPointManager() override;
- };
- diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc
- index b9ad5c8cbeb5b3684af6d84f70aa8aace69dc01a..55ea89b5c08daf3dd5cdf332be96ff43b8590233 100644
- --- a/content/browser/compositor/viz_process_transport_factory.cc
- +++ b/content/browser/compositor/viz_process_transport_factory.cc
- @@ -390,8 +390,14 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel(
- mojo::AssociatedRemote<viz::mojom::DisplayPrivate> display_private;
- root_params->display_private =
- display_private.BindNewEndpointAndPassReceiver();
- - compositor_data.display_client =
- - std::make_unique<HostDisplayClient>(compositor);
- + if (compositor->delegate()) {
- + compositor_data.display_client = compositor->delegate()->CreateHostDisplayClient(
- + compositor);
- + root_params->offscreen = compositor->delegate()->IsOffscreen();
- + } else {
- + compositor_data.display_client =
- + std::make_unique<HostDisplayClient>(compositor);
- + }
- root_params->display_client =
- compositor_data.display_client->GetBoundRemote(resize_task_runner_);
- mojo::AssociatedRemote<viz::mojom::ExternalBeginFrameController>
- diff --git a/services/viz/privileged/mojom/compositing/display_private.mojom b/services/viz/privileged/mojom/compositing/display_private.mojom
- index d7deccb6e6ec63592cd840a05403f402238e645e..4c4356b8def15ed3156db38d0a593b83a0544ed4 100644
- --- a/services/viz/privileged/mojom/compositing/display_private.mojom
- +++ b/services/viz/privileged/mojom/compositing/display_private.mojom
- @@ -114,7 +114,6 @@ interface DisplayClient {
-
- // Creates a LayeredWindowUpdater implementation to draw into a layered
- // window.
- - [EnableIf=is_win]
- CreateLayeredWindowUpdater(pending_receiver<LayeredWindowUpdater> receiver);
-
- // Sends the created child window to the browser process so that it can be
- diff --git a/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom b/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom
- index 7eff777e19817bc321d770cab31db17bd9bdf6b6..c7fad80559177054f048885c7b70484b8e8bc5de 100644
- --- a/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom
- +++ b/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom
- @@ -34,6 +34,7 @@ struct RootCompositorFrameSinkParams {
- bool send_swap_size_notifications = false;
- // Disables begin frame rate limiting for the display compositor.
- bool disable_frame_rate_limit = false;
- + bool offscreen = false;
-
- [EnableIf=is_android]
- float refresh_rate;
- diff --git a/services/viz/privileged/mojom/compositing/layered_window_updater.mojom b/services/viz/privileged/mojom/compositing/layered_window_updater.mojom
- index 2f462f0deb5fc8a637457243fb5d5849fc214d14..695869b83cefaa24af93a2e11b39de05456071f3 100644
- --- a/services/viz/privileged/mojom/compositing/layered_window_updater.mojom
- +++ b/services/viz/privileged/mojom/compositing/layered_window_updater.mojom
- @@ -26,5 +26,5 @@ interface LayeredWindowUpdater {
- // Draws to the HWND by copying pixels from shared memory. Callback must be
- // called after draw operation is complete to signal shared memory can be
- // modified.
- - Draw() => ();
- + Draw(gfx.mojom.Rect damage_rect) => ();
- };
- diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
- index adb90506e6df9b934b824169cd7d9ea3f00328ce..7d529e1af98d8392a98a7dbf9f3faff90f02c8bd 100644
- --- a/ui/compositor/compositor.h
- +++ b/ui/compositor/compositor.h
- @@ -90,6 +90,7 @@ namespace mojom {
- class DisplayPrivate;
- class ExternalBeginFrameController;
- } // namespace mojom
- +class HostDisplayClient;
- class HostFrameSinkManager;
- class LocalSurfaceId;
- class RasterContextProvider;
- @@ -141,6 +142,16 @@ class COMPOSITOR_EXPORT ContextFactory {
- virtual viz::HostFrameSinkManager* GetHostFrameSinkManager() = 0;
- };
-
- +class COMPOSITOR_EXPORT CompositorDelegate {
- + public:
- + virtual bool IsOffscreen() const = 0;
- + virtual std::unique_ptr<viz::HostDisplayClient> CreateHostDisplayClient(
- + ui::Compositor* compositor) = 0;
- +
- + protected:
- + virtual ~CompositorDelegate() {}
- +};
- +
- // Compositor object to take care of GPU painting.
- // A Browser compositor object is responsible for generating the final
- // displayable form of pixels comprising a single widget's contents. It draws an
- @@ -184,6 +195,9 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
- // Schedules a redraw of the layer tree associated with this compositor.
- void ScheduleDraw();
-
- + CompositorDelegate* delegate() const { return delegate_; }
- + void SetDelegate(CompositorDelegate* delegate) { delegate_ = delegate; }
- +
- // Sets the root of the layer tree drawn by this Compositor. The root layer
- // must have no parent. The compositor's root layer is reset if the root layer
- // is destroyed. NULL can be passed to reset the root layer, in which case the
- @@ -548,6 +562,8 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
- simple_begin_frame_observers_;
- std::unique_ptr<ui::HostBeginFrameObserver> host_begin_frame_observer_;
-
- + raw_ptr<CompositorDelegate> delegate_ = nullptr;
- +
- // The root of the Layer tree drawn by this compositor.
- raw_ptr<Layer> root_layer_ = nullptr;
-
- diff --git a/ui/gfx/ca_layer_params.h b/ui/gfx/ca_layer_params.h
- index 86d5be8b3778ced67e65d3f1e22b6aef467c7042..a2044ee0440339247cc91e06a7a0c323cbf332fc 100644
- --- a/ui/gfx/ca_layer_params.h
- +++ b/ui/gfx/ca_layer_params.h
- @@ -6,6 +6,7 @@
- #define UI_GFX_CA_LAYER_PARAMS_H_
-
- #include "build/build_config.h"
- +#include "ui/gfx/geometry/rect.h"
- #include "ui/gfx/geometry/size.h"
- #include "ui/gfx/gfx_export.h"
-
- @@ -51,6 +52,8 @@ struct GFX_EXPORT CALayerParams {
- gfx::ScopedRefCountedIOSurfaceMachPort io_surface_mach_port;
- #endif
-
- + gfx::Rect damage;
- +
- // The geometry of the frame.
- gfx::Size pixel_size;
- float scale_factor = 1.f;
- diff --git a/ui/gfx/mojom/ca_layer_params.mojom b/ui/gfx/mojom/ca_layer_params.mojom
- index c380e4882d699232869c88bc65dc4d396bb95780..7d3c81b200cc9b390084a35ab5d0fc1904137144 100644
- --- a/ui/gfx/mojom/ca_layer_params.mojom
- +++ b/ui/gfx/mojom/ca_layer_params.mojom
- @@ -18,5 +18,6 @@ struct CALayerParams {
- bool is_empty;
- CALayerContent content;
- gfx.mojom.Size pixel_size;
- + gfx.mojom.Rect damage;
- float scale_factor;
- };
- diff --git a/ui/gfx/mojom/ca_layer_params_mojom_traits.cc b/ui/gfx/mojom/ca_layer_params_mojom_traits.cc
- index e1c6ed1b3a456b164945ee7eef34f9d4f0b80e07..87bff4350cdfcca97de6f66946b9cb6155e36634 100644
- --- a/ui/gfx/mojom/ca_layer_params_mojom_traits.cc
- +++ b/ui/gfx/mojom/ca_layer_params_mojom_traits.cc
- @@ -52,6 +52,9 @@ bool StructTraits<gfx::mojom::CALayerParamsDataView, gfx::CALayerParams>::Read(
- if (!data.ReadPixelSize(&out->pixel_size))
- return false;
-
- + if (!data.ReadDamage(&out->damage))
- + return false;
- +
- out->scale_factor = data.scale_factor();
- return true;
- }
- diff --git a/ui/gfx/mojom/ca_layer_params_mojom_traits.h b/ui/gfx/mojom/ca_layer_params_mojom_traits.h
- index b6d3f2fea1d663ee1eba82a8008afc830897534c..e06f7d3184d66d9585af39c896036c1792693ac5 100644
- --- a/ui/gfx/mojom/ca_layer_params_mojom_traits.h
- +++ b/ui/gfx/mojom/ca_layer_params_mojom_traits.h
- @@ -20,6 +20,10 @@ struct StructTraits<gfx::mojom::CALayerParamsDataView, gfx::CALayerParams> {
- return ca_layer_params.pixel_size;
- }
-
- + static gfx::Rect damage(const gfx::CALayerParams& ca_layer_params) {
- + return ca_layer_params.damage;
- + }
- +
- static float scale_factor(const gfx::CALayerParams& ca_layer_params) {
- return ca_layer_params.scale_factor;
- }
|