| diff --git components/viz/host/host_display_client.cc components/viz/host/host_display_client.cc |
| index 3547ee865c22..2215296ffadc 100644 |
| --- components/viz/host/host_display_client.cc |
| +++ components/viz/host/host_display_client.cc |
| @@ -43,9 +43,14 @@ void HostDisplayClient::OnDisplayReceivedCALayerParams( |
| } |
| #endif |
| |
| -#if defined(OS_WIN) |
| +void HostDisplayClient::UseProxyOutputDevice( |
| + UseProxyOutputDeviceCallback callback) { |
| + std::move(callback).Run(false); |
| +} |
| + |
| void HostDisplayClient::CreateLayeredWindowUpdater( |
| mojo::PendingReceiver<mojom::LayeredWindowUpdater> receiver) { |
| +#if defined(OS_WIN) |
| if (!NeedsToUseLayerWindow(widget_)) { |
| DLOG(ERROR) << "HWND shouldn't be using a layered window"; |
| return; |
| @@ -53,8 +58,8 @@ void HostDisplayClient::CreateLayeredWindowUpdater( |
| |
| layered_window_updater_ = |
| std::make_unique<LayeredWindowUpdaterImpl>(widget_, std::move(receiver)); |
| -} |
| #endif |
| +} |
| |
| #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| void HostDisplayClient::DidCompleteSwapWithNewSize(const gfx::Size& size) { |
| diff --git components/viz/host/host_display_client.h components/viz/host/host_display_client.h |
| index cedf833d2358..04456e045304 100644 |
| --- components/viz/host/host_display_client.h |
| +++ components/viz/host/host_display_client.h |
| @@ -31,17 +31,17 @@ class VIZ_HOST_EXPORT HostDisplayClient : public mojom::DisplayClient { |
| mojo::PendingRemote<mojom::DisplayClient> GetBoundRemote( |
| scoped_refptr<base::SingleThreadTaskRunner> 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( |
| mojo::PendingReceiver<mojom::LayeredWindowUpdater> receiver) override; |
| -#endif |
| |
| #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 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 b04f654fe820..131977a36591 100644 |
| --- components/viz/host/layered_window_updater_impl.cc |
| +++ components/viz/host/layered_window_updater_impl.cc |
| @@ -44,7 +44,7 @@ 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 components/viz/host/layered_window_updater_impl.h components/viz/host/layered_window_updater_impl.h |
| index 1026b739d283..fe562ab60ce9 100644 |
| --- components/viz/host/layered_window_updater_impl.h |
| +++ 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 components/viz/service/BUILD.gn components/viz/service/BUILD.gn |
| index eb1a0ae5ca25..846c738053b7 100644 |
| --- components/viz/service/BUILD.gn |
| +++ components/viz/service/BUILD.gn |
| @@ -13,7 +13,10 @@ config("viz_service_implementation") { |
| } |
| |
| viz_component("service") { |
| + never_build_jumbo = true |
| 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 b4d4b1c1c597..9ce685048ab1 100644 |
| --- components/viz/service/display_embedder/output_surface_provider_impl.cc |
| +++ components/viz/service/display_embedder/output_surface_provider_impl.cc |
| @@ -13,6 +13,7 @@ |
| #include "base/threading/thread_task_runner_handle.h" |
| #include "build/chromecast_buildflags.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" |
| @@ -224,6 +225,20 @@ OutputSurfaceProviderImpl::CreateSoftwareOutputDeviceForPlatform( |
| if (headless_) |
| return std::make_unique<SoftwareOutputDevice>(); |
| |
| + { |
| + 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<SoftwareOutputDeviceProxy>( |
| + 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 2bb30e5318b6..535535dd6c10 100644 |
| --- components/viz/service/display_embedder/software_output_device_win.cc |
| +++ components/viz/service/display_embedder/software_output_device_win.cc |
| @@ -188,8 +188,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 content/browser/compositor/viz_process_transport_factory.cc content/browser/compositor/viz_process_transport_factory.cc |
| index 8e10af98f2b0..d39fc7ec7b4c 100644 |
| --- content/browser/compositor/viz_process_transport_factory.cc |
| +++ content/browser/compositor/viz_process_transport_factory.cc |
| @@ -404,8 +404,13 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel( |
| compositor_data.display_private.reset(); |
| root_params->display_private = |
| compositor_data.display_private.BindNewEndpointAndPassReceiver(); |
| - compositor_data.display_client = |
| - std::make_unique<HostDisplayClient>(compositor); |
| + if (compositor->delegate()) { |
| + compositor_data.display_client = |
| + compositor->delegate()->CreateHostDisplayClient(); |
| + } else { |
| + compositor_data.display_client = |
| + std::make_unique<HostDisplayClient>(compositor); |
| + } |
| root_params->display_client = |
| compositor_data.display_client->GetBoundRemote(resize_task_runner_); |
| |
| diff --git mojo/public/cpp/bindings/sync_call_restrictions.h mojo/public/cpp/bindings/sync_call_restrictions.h |
| index 60e114920575..01f2ce164a3b 100644 |
| --- mojo/public/cpp/bindings/sync_call_restrictions.h |
| +++ mojo/public/cpp/bindings/sync_call_restrictions.h |
| @@ -29,6 +29,7 @@ class Compositor; |
| |
| namespace viz { |
| class HostFrameSinkManager; |
| +class GpuDisplayProvider; |
| } |
| |
| namespace mojo { |
| @@ -82,6 +83,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::Compositor; |
| + // 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/mojom/compositing/display_private.mojom services/viz/privileged/mojom/compositing/display_private.mojom |
| index d36f62e6ee41..e8ec62cda569 100644 |
| --- services/viz/privileged/mojom/compositing/display_private.mojom |
| +++ services/viz/privileged/mojom/compositing/display_private.mojom |
| @@ -74,12 +74,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(pending_receiver<LayeredWindowUpdater> receiver); |
| |
| // Notifies that a swap has occurred and provides information about the pixel |
| diff --git services/viz/privileged/mojom/compositing/layered_window_updater.mojom services/viz/privileged/mojom/compositing/layered_window_updater.mojom |
| index 6b7fbb6cf13d..e2af75168cb9 100644 |
| --- services/viz/privileged/mojom/compositing/layered_window_updater.mojom |
| +++ 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 ui/compositor/compositor.h ui/compositor/compositor.h |
| index 3e2d2304faf7..f0029d34f591 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 "mojo/public/cpp/bindings/pending_remote.h" |
| #include "services/viz/privileged/mojom/compositing/vsync_parameter_observer.mojom-forward.h" |
| #include "third_party/skia/include/core/SkColor.h" |
| @@ -122,6 +124,14 @@ class COMPOSITOR_EXPORT ContextFactory { |
| virtual viz::HostFrameSinkManager* GetHostFrameSinkManager() = 0; |
| }; |
| |
| +class COMPOSITOR_EXPORT CompositorDelegate { |
| + public: |
| + virtual std::unique_ptr<viz::HostDisplayClient> 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 |
| @@ -155,6 +165,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 |
| @@ -390,6 +403,8 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient, |
| |
| std::unique_ptr<PendingBeginFrameArgs> pending_begin_frame_args_; |
| |
| + CompositorDelegate* delegate_ = nullptr; |
| + |
| // The root of the Layer tree drawn by this compositor. |
| Layer* root_layer_ = nullptr; |
| |