123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722 |
- 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 0c63e0d59b6b005059d59415bb3dde57a8c1314d..863f1974eb76dc0860362445e48b3064837e5b44 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();
- diff --git a/components/viz/host/host_display_client.h b/components/viz/host/host_display_client.h
- index 5eeaadec9773f4890d9f8cccba1d50f645045b74..d7eb61a67c507ff8bd9e60878a9f5bbfc0d667c2 100644
- --- a/components/viz/host/host_display_client.h
- +++ b/components/viz/host/host_display_client.h
- @@ -47,11 +47,13 @@ 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
-
- + protected:
- + void CreateLayeredWindowUpdater(
- + mojo::PendingReceiver<mojom::LayeredWindowUpdater> receiver) override;
- +
- // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
- // of lacros-chrome is complete.
- #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
- 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 72d9d594a93700a35eadb3c2bc017fa7996bf10d..729753a72edd761ec831f79828742a26f9dd2417 100644
- --- a/components/viz/service/BUILD.gn
- +++ b/components/viz/service/BUILD.gn
- @@ -141,6 +141,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 28f44e5df4a3591c8563564a9aba7cec1b023a29..befc5a556a7fd6719d8a1c2eb8e9278465469b37 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;
- };
-
- } // namespace viz
- 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 0bc450ca4faf2a4a38a93f4c6a60b95a583eec8b..5eaa99698b588edbfe8588aa80ba68457ccf8983 100644
- --- a/components/viz/service/display_embedder/output_surface_provider_impl.cc
- +++ b/components/viz/service/display_embedder/output_surface_provider_impl.cc
- @@ -23,12 +23,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)
- @@ -92,7 +94,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>();
- @@ -100,7 +103,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);
-
- @@ -140,10 +143,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 e82717d5167e13e2926bcaf6c0ad66c1502e66f6..783c4d6ed399120e026bbf18baab40929daf8fc1 100644
- --- a/components/viz/service/display_embedder/output_surface_provider_impl.h
- +++ b/components/viz/service/display_embedder/output_surface_provider_impl.h
- @@ -50,12 +50,14 @@ 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;
-
- 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 4ceb1a9d9f336f65e15831856d30b45af594dd0f..646ac22f074c3d1827e59170a93807bc10d83d0b 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();
- @@ -191,6 +193,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));
- 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 c70b0af70a68386c5d36833e621dd1b5cdc1522a..17e5c96cbb4ef2f575fd5ba7bd8b0c7bd58da5e7 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
- @@ -97,7 +97,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 59dd80087ada03e57c4b993dc887f75726789188..f42321d0cc1370d2828550c9899112dad5c0a505 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 cc1ceb263a60b9bd743bd4166def23cd1c01b49f..d2c24bf0b674c5028e48c6b51f23d4a8fdf4d95b 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;
- };
-
- } // namespace viz
- diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc
- index c34c0854efeec1ddddcd47fea40c9516f9c8dfaf..c27169973e2ac9b2faf802b9f35ed5c6d2b22543 100644
- --- a/content/browser/compositor/viz_process_transport_factory.cc
- +++ b/content/browser/compositor/viz_process_transport_factory.cc
- @@ -393,8 +393,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 29936bca703b86fee89e2b7f35c64a47cd60770b..7fb5a0082bae7d8e06ca8588129d34e866f043bf 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 e6447c185ebcfe387991f27d3fb25dc3c2f32e5b..d291f0db6e9b6a60ee9ca38febaf1ad0397ee113 100644
- --- a/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom
- +++ b/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom
- @@ -32,6 +32,7 @@ struct RootCompositorFrameSinkParams {
- bool disable_frame_rate_limit = false;
- // Whether to use variable refresh rates when generating begin frames.
- bool enable_variable_refresh_rate = 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 c9f14ed6547ba1f5cdaade063452036ac402885a..ddb28fd6f7549759df7e3b7d6b309cd982e199af 100644
- --- a/ui/compositor/compositor.h
- +++ b/ui/compositor/compositor.h
- @@ -89,6 +89,7 @@ class DisplayPrivate;
- class ExternalBeginFrameController;
- } // namespace mojom
- class ContextProvider;
- +class HostDisplayClient;
- class HostFrameSinkManager;
- class LocalSurfaceId;
- class RasterContextProvider;
- @@ -145,6 +146,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
- @@ -188,6 +199,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
- @@ -525,6 +539,8 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
-
- std::unique_ptr<PendingBeginFrameArgs> pending_begin_frame_args_;
-
- + 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 1944ef571b1f12fbee8dff553ad4de913c794efb..529296cbf858d2aaeb7b5fbe1ae8f36e4ec1d485 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;
- }
|