diff --git components/viz/host/host_display_client.cc components/viz/host/host_display_client.cc index f5e18df4e06e..58a8e8ef125b 100644 --- components/viz/host/host_display_client.cc +++ components/viz/host/host_display_client.cc @@ -46,9 +46,14 @@ void HostDisplayClient::OnDisplayReceivedCALayerParams( } #endif -#if defined(OS_WIN) +void HostDisplayClient::UseProxyOutputDevice( + UseProxyOutputDeviceCallback callback) { + std::move(callback).Run(false); +} + void HostDisplayClient::CreateLayeredWindowUpdater( mojom::LayeredWindowUpdaterRequest request) { +#if OS_WIN if (!NeedsToUseLayerWindow(widget_)) { DLOG(ERROR) << "HWND shouldn't be using a layered window"; return; @@ -56,8 +61,8 @@ void HostDisplayClient::CreateLayeredWindowUpdater( layered_window_updater_ = std::make_unique(widget_, std::move(request)); -} #endif +} #if defined(USE_X11) void HostDisplayClient::DidCompleteSwapWithNewSize(const gfx::Size& size) { diff --git components/viz/host/host_display_client.h components/viz/host/host_display_client.h index 5e5c5da4a3cf..30eca49765bd 100644 --- components/viz/host/host_display_client.h +++ components/viz/host/host_display_client.h @@ -30,17 +30,17 @@ class VIZ_HOST_EXPORT HostDisplayClient : public mojom::DisplayClient { mojom::DisplayClientPtr GetBoundPtr( scoped_refptr task_runner); - private: + protected: // mojom::DisplayClient implementation: + void UseProxyOutputDevice(UseProxyOutputDeviceCallback callback) override; + #if defined(OS_MACOSX) void OnDisplayReceivedCALayerParams( const gfx::CALayerParams& ca_layer_params) override; #endif -#if defined(OS_WIN) void CreateLayeredWindowUpdater( mojom::LayeredWindowUpdaterRequest request) override; -#endif #if defined(USE_X11) void DidCompleteSwapWithNewSize(const gfx::Size& size) override; diff --git components/viz/host/layered_window_updater_impl.cc components/viz/host/layered_window_updater_impl.cc index d3a49ed8be8d..38a927b8f734 100644 --- components/viz/host/layered_window_updater_impl.cc +++ components/viz/host/layered_window_updater_impl.cc @@ -47,7 +47,7 @@ void LayeredWindowUpdaterImpl::OnAllocatedSharedMemory( shm_handle.Close(); } -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 components/viz/host/layered_window_updater_impl.h components/viz/host/layered_window_updater_impl.h index 93c52d2b928c..4dc645e770a2 100644 --- components/viz/host/layered_window_updater_impl.h +++ components/viz/host/layered_window_updater_impl.h @@ -33,7 +33,7 @@ class VIZ_HOST_EXPORT LayeredWindowUpdaterImpl void OnAllocatedSharedMemory( const gfx::Size& pixel_size, mojo::ScopedSharedBufferHandle scoped_buffer_handle) override; - void Draw(DrawCallback draw_callback) override; + void Draw(const gfx::Rect& damage_rect, DrawCallback draw_callback) override; private: const HWND hwnd_; diff --git components/viz/service/BUILD.gn components/viz/service/BUILD.gn index f17983a5cc70..4a8f2fd8d415 100644 --- components/viz/service/BUILD.gn +++ components/viz/service/BUILD.gn @@ -13,6 +13,8 @@ config("viz_service_implementation") { viz_component("service") { sources = [ + "//cef/libcef/browser/osr/software_output_device_proxy.cc", + "//cef/libcef/browser/osr/software_output_device_proxy.h", "display/bsp_tree.cc", "display/bsp_tree.h", "display/bsp_walk_action.cc", diff --git components/viz/service/display_embedder/output_surface_provider_impl.cc components/viz/service/display_embedder/output_surface_provider_impl.cc index 8fe397588eb4..1218985f7310 100644 --- components/viz/service/display_embedder/output_surface_provider_impl.cc +++ components/viz/service/display_embedder/output_surface_provider_impl.cc @@ -11,6 +11,7 @@ #include "base/compiler_specific.h" #include "base/threading/thread_task_runner_handle.h" #include "cc/base/switches.h" +#include "cef/libcef/browser/osr/software_output_device_proxy.h" #include "components/viz/common/display/renderer_settings.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/service/display_embedder/gl_output_surface.h" @@ -243,6 +244,20 @@ OutputSurfaceProviderImpl::CreateSoftwareOutputDeviceForPlatform( if (headless_) return std::make_unique(); + { + mojo::ScopedAllowSyncCallForTesting allow_sync; + DCHECK(display_client); + bool use_proxy_output_device = false; + if (display_client->UseProxyOutputDevice(&use_proxy_output_device) && + use_proxy_output_device) { + mojom::LayeredWindowUpdaterPtr layered_window_updater; + display_client->CreateLayeredWindowUpdater( + mojo::MakeRequest(&layered_window_updater)); + return std::make_unique( + std::move(layered_window_updater)); + } + } + #if defined(OS_WIN) return CreateSoftwareOutputDeviceWin(surface_handle, &output_device_backing_, display_client); diff --git components/viz/service/display_embedder/software_output_device_win.cc components/viz/service/display_embedder/software_output_device_win.cc index 4e3f0255d5fe..0de947b54b7c 100644 --- components/viz/service/display_embedder/software_output_device_win.cc +++ components/viz/service/display_embedder/software_output_device_win.cc @@ -268,8 +268,9 @@ void SoftwareOutputDeviceWinProxy::EndPaintDelegated( if (!canvas_) return; - layered_window_updater_->Draw(base::BindOnce( - &SoftwareOutputDeviceWinProxy::DrawAck, base::Unretained(this))); + layered_window_updater_->Draw( + damage_rect, base::BindOnce(&SoftwareOutputDeviceWinProxy::DrawAck, + base::Unretained(this))); waiting_on_draw_ack_ = true; TRACE_EVENT_ASYNC_BEGIN0("viz", "SoftwareOutputDeviceWinProxy::Draw", this); diff --git mojo/public/cpp/bindings/sync_call_restrictions.h mojo/public/cpp/bindings/sync_call_restrictions.h index 906be544c90f..a110f254d7ec 100644 --- mojo/public/cpp/bindings/sync_call_restrictions.h +++ mojo/public/cpp/bindings/sync_call_restrictions.h @@ -34,6 +34,7 @@ class HostContextFactoryPrivate; namespace viz { class HostFrameSinkManager; +class GpuDisplayProvider; } namespace mojo { @@ -91,6 +92,8 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) SyncCallRestrictions { // For preventing frame swaps of wrong size during resize on Windows. // (https://crbug.com/811945) friend class ui::HostContextFactoryPrivate; + // For query of whether to use SoftwareOutputDevice or not + friend class viz::GpuDisplayProvider; // END ALLOWED USAGE. #if ENABLE_SYNC_CALL_RESTRICTIONS diff --git services/viz/privileged/interfaces/compositing/display_private.mojom services/viz/privileged/interfaces/compositing/display_private.mojom index deb327b77054..d9926ec35165 100644 --- services/viz/privileged/interfaces/compositing/display_private.mojom +++ services/viz/privileged/interfaces/compositing/display_private.mojom @@ -77,12 +77,14 @@ interface DisplayPrivate { }; interface DisplayClient { + [Sync] + UseProxyOutputDevice() => (bool success); + [EnableIf=is_mac] OnDisplayReceivedCALayerParams(gfx.mojom.CALayerParams ca_layer_params); // Creates a LayeredWindowUpdater implementation to draw into a layered // window. - [EnableIf=is_win] CreateLayeredWindowUpdater(LayeredWindowUpdater& layered_window_updater); // Notifies that a swap has occurred and provides information about the pixel diff --git services/viz/privileged/interfaces/compositing/layered_window_updater.mojom services/viz/privileged/interfaces/compositing/layered_window_updater.mojom index 360cab3eee4c..6834242f23d2 100644 --- services/viz/privileged/interfaces/compositing/layered_window_updater.mojom +++ services/viz/privileged/interfaces/compositing/layered_window_updater.mojom @@ -22,5 +22,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 ui/compositor/compositor.h ui/compositor/compositor.h index 494241c374b7..1cbfb9cdb683 100644 --- ui/compositor/compositor.h +++ ui/compositor/compositor.h @@ -23,7 +23,9 @@ #include "cc/trees/layer_tree_host_single_thread_client.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" #include "components/viz/common/surfaces/frame_sink_id.h" +#include "components/viz/host/host_display_client.h" #include "components/viz/host/host_frame_sink_client.h" +#include "components/viz/service/display/software_output_device.h" #include "services/viz/privileged/interfaces/compositing/vsync_parameter_observer.mojom-forward.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkMatrix44.h" @@ -199,6 +201,14 @@ class COMPOSITOR_EXPORT ContextFactory { virtual bool SyncTokensRequiredForDisplayCompositor() = 0; }; +class COMPOSITOR_EXPORT CompositorDelegate { + public: + virtual std::unique_ptr CreateHostDisplayClient() = 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 @@ -238,6 +248,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 @@ -454,6 +467,8 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient, ui::ContextFactory* context_factory_; ui::ContextFactoryPrivate* context_factory_private_; + CompositorDelegate* delegate_ = nullptr; + // The root of the Layer tree drawn by this compositor. Layer* root_layer_ = nullptr; diff --git ui/compositor/host/host_context_factory_private.cc ui/compositor/host/host_context_factory_private.cc index 0ff1e05244e0..5b8721034296 100644 --- ui/compositor/host/host_context_factory_private.cc +++ ui/compositor/host/host_context_factory_private.cc @@ -99,8 +99,13 @@ void HostContextFactoryPrivate::ConfigureCompositor( mojo::MakeRequest(&root_params->compositor_frame_sink_client); root_params->display_private = mojo::MakeRequest(&compositor_data.display_private); - compositor_data.display_client = - std::make_unique(compositor); + if (compositor->delegate()) { + compositor_data.display_client = + compositor->delegate()->CreateHostDisplayClient(); + } else { + compositor_data.display_client = + std::make_unique(compositor); + } root_params->display_client = compositor_data.display_client->GetBoundPtr(resize_task_runner_) .PassInterface();