From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Andy Dill 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 3b00759e513dc7e19fd68398e853c8ce6ac73905..47f4e7cc2e8b3141dcaf9e7a498fec32c9342f40 100644 --- a/components/viz/host/host_display_client.cc +++ b/components/viz/host/host_display_client.cc @@ -45,9 +45,9 @@ void HostDisplayClient::OnDisplayReceivedCALayerParams( } #endif -#if defined(OS_WIN) void HostDisplayClient::CreateLayeredWindowUpdater( mojo::PendingReceiver receiver) { +#if defined(OS_WIN) if (!NeedsToUseLayerWindow(widget_)) { DLOG(ERROR) << "HWND shouldn't be using a layered window"; return; @@ -55,8 +55,12 @@ void HostDisplayClient::CreateLayeredWindowUpdater( layered_window_updater_ = std::make_unique(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 +} // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch // of lacros-chrome is complete. diff --git a/components/viz/host/host_display_client.h b/components/viz/host/host_display_client.h index 5e260e13762f61971c99f755e93d73aa794d9175..a57770718b71def04fa35c7655d9368a58f39f20 100644 --- a/components/viz/host/host_display_client.h +++ b/components/viz/host/host_display_client.h @@ -39,10 +39,9 @@ class VIZ_HOST_EXPORT HostDisplayClient : public mojom::DisplayClient { const gfx::CALayerParams& ca_layer_params) override; #endif -#if defined(OS_WIN) + protected: void CreateLayeredWindowUpdater( mojo::PendingReceiver receiver) override; -#endif // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch // of lacros-chrome is complete. diff --git a/components/viz/host/layered_window_updater_impl.cc b/components/viz/host/layered_window_updater_impl.cc index b04f654fe820f821b18e059cdd40085fc2384c4e..ee22012b01ef92bb3b32b5b1081609a7bdfb0d93 100644 --- a/components/viz/host/layered_window_updater_impl.cc +++ b/components/viz/host/layered_window_updater_impl.cc @@ -44,7 +44,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 1026b739d283f0fc252fa2af83a6d4cf51bc8553..fe562ab60ce98b8bb0c5080a6428deb319a4dd04 100644 --- a/components/viz/host/layered_window_updater_impl.h +++ b/components/viz/host/layered_window_updater_impl.h @@ -35,7 +35,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 0f6a5a2fa3d82ae76889ef55af14e18b86cacffc..e33cd6305f53aa9287c61bf2d38848f878a14d30 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn @@ -119,6 +119,8 @@ viz_component("service") { "display_embedder/output_surface_provider_impl.h", "display_embedder/server_shared_bitmap_manager.cc", "display_embedder/server_shared_bitmap_manager.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/viz_process_context_provider.cc", diff --git a/components/viz/service/display_embedder/output_surface_provider.h b/components/viz/service/display_embedder/output_surface_provider.h index 77d463e683d8b8d3a202681a6884eacaab79d70d..05d51cb2637d34c073cd0025e365803633459a86 100644 --- a/components/viz/service/display_embedder/output_surface_provider.h +++ b/components/viz/service/display_embedder/output_surface_provider.h @@ -39,7 +39,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 79c800e77a160cc0b10a29dd560d37e19c9d05fd..a9b1b267c97ed513890ba8466f66c3eafcbd5d5b 100644 --- a/components/viz/service/display_embedder/output_surface_provider_impl.cc +++ b/components/viz/service/display_embedder/output_surface_provider_impl.cc @@ -25,6 +25,7 @@ #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/display_embedder/viz_process_context_provider.h" #include "components/viz/service/gl/gpu_service_impl.h" @@ -38,6 +39,7 @@ #include "gpu/ipc/scheduler_sequence.h" #include "gpu/ipc/service/gpu_channel_manager_delegate.h" #include "gpu/ipc/service/image_transport_surface.h" +#include "services/viz/privileged/mojom/compositing/layered_window_updater.mojom.h" #include "ui/base/ui_base_switches.h" #include "ui/gl/gl_context.h" #include "ui/gl/init/gl_factory.h" @@ -130,7 +132,8 @@ std::unique_ptr 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(); @@ -142,7 +145,7 @@ std::unique_ptr OutputSurfaceProviderImpl::CreateOutputSurface( if (!gpu_compositing) { output_surface = std::make_unique( - CreateSoftwareOutputDeviceForPlatform(surface_handle, display_client)); + CreateSoftwareOutputDeviceForPlatform(surface_handle, display_client, offscreen)); } else if (renderer_settings.use_skia_renderer) { DCHECK(gpu_dependency); { @@ -241,10 +244,22 @@ std::unique_ptr OutputSurfaceProviderImpl::CreateOutputSurface( std::unique_ptr OutputSurfaceProviderImpl::CreateSoftwareOutputDeviceForPlatform( gpu::SurfaceHandle surface_handle, - mojom::DisplayClient* display_client) { + mojom::DisplayClient* display_client, + bool offscreen) { if (headless_) return std::make_unique(); +#if !defined(OS_MAC) + if (offscreen) { + DCHECK(display_client); + mojom::LayeredWindowUpdaterPtr layered_window_updater; + display_client->CreateLayeredWindowUpdater( + mojo::MakeRequest(&layered_window_updater)); + return std::make_unique( + std::move(layered_window_updater)); + } +#endif + #if defined(OS_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 a6bb42cdbc567f526cc70c5c4d9b967274dc0332..d116844635922c8a1086dfa13063b8ae8b43ce59 100644 --- a/components/viz/service/display_embedder/output_surface_provider_impl.h +++ b/components/viz/service/display_embedder/output_surface_provider_impl.h @@ -61,12 +61,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 CreateSoftwareOutputDeviceForPlatform( gpu::SurfaceHandle surface_handle, - mojom::DisplayClient* display_client); + mojom::DisplayClient* display_client, + bool offscreen); GpuServiceImpl* const gpu_service_impl_; gpu::CommandBufferTaskExecutor* const task_executor_; 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 49149081cc603f14eacee647cbb2fcf8ed5e66fd..9ff3f2ee203403fdaa31edb8a0bcc000c4d214d7 100644 --- a/components/viz/service/display_embedder/software_output_device_mac.cc +++ b/components/viz/service/display_embedder/software_output_device_mac.cc @@ -102,6 +102,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(); @@ -187,6 +189,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 f3867356e3d641416e00e6d115ae9ae2a0be90ab..b1d192d2b20ccb63fba07093101d745e5ffe86dd 100644 --- a/components/viz/service/display_embedder/software_output_device_mac.h +++ b/components/viz/service/display_embedder/software_output_device_mac.h @@ -56,6 +56,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..4efea02f80f8b6818291321a7c63f0f4815a5b98 --- /dev/null +++ b/components/viz/service/display_embedder/software_output_device_proxy.cc @@ -0,0 +1,157 @@ +// 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 "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 defined(OS_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( + mojom::LayeredWindowUpdaterPtr 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) { + 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_, ResourceFormat::RGBA_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(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..48fa86caaab3c15764f105eb7ad2aecf2b89bf36 --- /dev/null +++ b/components/viz/service/display_embedder/software_output_device_proxy.h @@ -0,0 +1,90 @@ +// 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_ + +#if defined(OS_WIN) +#include +#endif + +#include + +#include "base/memory/shared_memory_mapping.h" +#include "base/threading/thread_checker.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 "services/viz/privileged/mojom/compositing/display_private.mojom.h" +#include "services/viz/privileged/mojom/compositing/layered_window_updater.mojom.h" + +namespace viz { + +// Shared base class for SoftwareOutputDevice implementations. +class SoftwareOutputDeviceBase : public SoftwareOutputDevice { + public: + SoftwareOutputDeviceBase() = default; + ~SoftwareOutputDeviceBase() override; + + // 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_); + + DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceBase); +}; + +// 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( + mojom::LayeredWindowUpdaterPtr layered_window_updater); + ~SoftwareOutputDeviceProxy() override; + + // SoftwareOutputDevice implementation. + void OnSwapBuffers(SoftwareOutputDevice::SwapBuffersCallback swap_ack_callback) 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(); + + mojom::LayeredWindowUpdaterPtr layered_window_updater_; + + std::unique_ptr canvas_; + bool waiting_on_draw_ack_ = false; + SoftwareOutputDevice::SwapBuffersCallback swap_ack_callback_; + +#if !defined(WIN32) + base::WritableSharedMemoryMapping shm_mapping_; +#endif + + DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceProxy); +}; + +} // 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 2bb30e5318b6b48c2e6d4b1f64a6a36c68f963d1..9e805f27a9d7d1c0aa68cdf9f48895c055ca7791 100644 --- a/components/viz/service/display_embedder/software_output_device_win.cc +++ b/components/viz/service/display_embedder/software_output_device_win.cc @@ -188,7 +188,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 8112abf9ca0bf214721f5996bb59f7458d9347d2..8b3c2a4cce0c4789fadd555b360dea2c145ae1a4 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 @@ -46,7 +46,8 @@ RootCompositorFrameSinkImpl::Create( params->gpu_compositing, params->widget, params->renderer_settings); 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/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc index 11ac1649ed0f5be1d12e8a30b8d170f86b8e9bb8..05746d9a561c3933ae0c5578467f20b486453943 100644 --- a/content/browser/compositor/viz_process_transport_factory.cc +++ b/content/browser/compositor/viz_process_transport_factory.cc @@ -414,8 +414,14 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel( compositor_data.display_private.reset(); root_params->display_private = compositor_data.display_private.BindNewEndpointAndPassReceiver(); - compositor_data.display_client = - std::make_unique(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(compositor); + } root_params->display_client = compositor_data.display_client->GetBoundRemote(resize_task_runner_); diff --git a/services/viz/privileged/mojom/compositing/display_private.mojom b/services/viz/privileged/mojom/compositing/display_private.mojom index 0c9686f3c8070000bf5b180d9c06a8817d430c4a..4538b95f6e71708144eb7752438b1b31d60cb2ca 100644 --- a/services/viz/privileged/mojom/compositing/display_private.mojom +++ b/services/viz/privileged/mojom/compositing/display_private.mojom @@ -85,7 +85,6 @@ interface DisplayClient { // Creates a LayeredWindowUpdater implementation to draw into a layered // window. - [EnableIf=is_win] CreateLayeredWindowUpdater(pending_receiver receiver); // Notifies that a swap has occurred and provides information about the pixel diff --git a/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom b/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom index a0b87925e0c9d02f586cc4e9446cbfcf12b7aa1c..71659834eec5237016f95f93defa9dcb30f0af52 100644 --- a/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom +++ b/services/viz/privileged/mojom/compositing/frame_sink_manager.mojom @@ -30,6 +30,7 @@ struct RootCompositorFrameSinkParams { // Disables begin frame rate limiting for the display compositor. bool disable_frame_rate_limit = false; bool use_preferred_interval_for_video = 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 6b7fbb6cf13dc8ee6ade0878a9a2c1efc5d4d3f1..e2af75168cb914a7b3b4a6c9b6a285498c3f8e72 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 e1db8f745c077b2f57b39a48aeab434fe0e98541..ddafd1f2aa38ef30776fa89ffcf5d108be963ac9 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h @@ -77,6 +77,7 @@ class ExternalBeginFrameController; class DelegatedInkPointRenderer; } // namespace mojom class ContextProvider; +class HostDisplayClient; class HostFrameSinkManager; class LocalSurfaceId; class RasterContextProvider; @@ -133,6 +134,16 @@ class COMPOSITOR_EXPORT ContextFactory { virtual viz::HostFrameSinkManager* GetHostFrameSinkManager() = 0; }; +class COMPOSITOR_EXPORT CompositorDelegate { + public: + virtual bool IsOffscreen() const = 0; + virtual std::unique_ptr 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 @@ -167,6 +178,9 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient, // 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 @@ -435,6 +449,8 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient, std::unique_ptr pending_begin_frame_args_; + CompositorDelegate* delegate_ = nullptr; + // The root of the Layer tree drawn by this compositor. Layer* root_layer_ = nullptr; diff --git a/ui/gfx/ca_layer_params.h b/ui/gfx/ca_layer_params.h index 64af450ed36a982124c6fcce7056b4058140747a..dcee2ec9de0e759b868b0de2c7106b2cf084c41c 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" @@ -41,6 +42,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 de00e766ba17532e10dcf5d0fd31fa344920a9f7..7aaedf83ad22dcc1d2dd39a31cf7e08b7b6ba4d3 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 c1f21d7f4348df96f7be5c0adb1b9650304048e0..760c849aebba70e575e59883655d707f36c5424a 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::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 4cac766eae3161baedac4202f694129cd90c80de..0821495ad22944d8856bb750cac8912a2f8328c3 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 { 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; }