|
@@ -0,0 +1,636 @@
|
|
|
+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 3547ee865c22..715bfa4b5db5 100644
|
|
|
+--- a/components/viz/host/host_display_client.cc
|
|
|
++++ b/components/viz/host/host_display_client.cc
|
|
|
+@@ -43,9 +43,13 @@ void HostDisplayClient::OnDisplayReceivedCALayerParams(
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
+-#if defined(OS_WIN)
|
|
|
++void HostDisplayClient::IsOffscreen(IsOffscreenCallback 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 +57,12 @@ 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 defined(OS_LINUX) && !defined(OS_CHROMEOS)
|
|
|
+ void HostDisplayClient::DidCompleteSwapWithNewSize(const gfx::Size& size) {
|
|
|
+diff --git a/components/viz/host/host_display_client.h b/components/viz/host/host_display_client.h
|
|
|
+index cedf833d2358..4437a7875076 100644
|
|
|
+--- a/components/viz/host/host_display_client.h
|
|
|
++++ b/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 IsOffscreen(IsOffscreenCallback 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 a/components/viz/host/layered_window_updater_impl.cc b/components/viz/host/layered_window_updater_impl.cc
|
|
|
+index b04f654fe820..ee22012b01ef 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 1026b739d283..fe562ab60ce9 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 7a1277ad28ed..d09e6480b18d 100644
|
|
|
+--- a/components/viz/service/BUILD.gn
|
|
|
++++ b/components/viz/service/BUILD.gn
|
|
|
+@@ -111,6 +111,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_impl.cc b/components/viz/service/display_embedder/output_surface_provider_impl.cc
|
|
|
+index 97feccc71b94..c267d1e72ec6 100644
|
|
|
+--- a/components/viz/service/display_embedder/output_surface_provider_impl.cc
|
|
|
++++ b/components/viz/service/display_embedder/output_surface_provider_impl.cc
|
|
|
+@@ -21,6 +21,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"
|
|
|
+@@ -34,6 +35,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"
|
|
|
+@@ -242,6 +244,22 @@ OutputSurfaceProviderImpl::CreateSoftwareOutputDeviceForPlatform(
|
|
|
+ if (headless_)
|
|
|
+ return std::make_unique<SoftwareOutputDevice>();
|
|
|
+
|
|
|
++#if !defined(OS_MACOSX)
|
|
|
++ {
|
|
|
++ mojo::ScopedAllowSyncCallForTesting allow_sync;
|
|
|
++ DCHECK(display_client);
|
|
|
++ bool offscreen = false;
|
|
|
++ if (display_client->IsOffscreen(&offscreen) && offscreen) {
|
|
|
++ mojom::LayeredWindowUpdaterPtr layered_window_updater;
|
|
|
++ display_client->CreateLayeredWindowUpdater(
|
|
|
++ mojo::MakeRequest(&layered_window_updater));
|
|
|
++
|
|
|
++ return std::make_unique<SoftwareOutputDeviceProxy>(
|
|
|
++ 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/software_output_device_mac.cc b/components/viz/service/display_embedder/software_output_device_mac.cc
|
|
|
+index b9357082293c..b4cb07e26d15 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();
|
|
|
+@@ -184,6 +186,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 f3867356e3d6..b1d192d2b20c 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 000000000000..4efea02f80f8
|
|
|
+--- /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<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 000000000000..48fa86caaab3
|
|
|
+--- /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 <windows.h>
|
|
|
++#endif
|
|
|
++
|
|
|
++#include <memory>
|
|
|
++
|
|
|
++#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<SkCanvas> 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 bb07c338fac5..e0ebb98d9a02 100644
|
|
|
+--- a/components/viz/service/display_embedder/software_output_device_win.cc
|
|
|
++++ b/components/viz/service/display_embedder/software_output_device_win.cc
|
|
|
+@@ -268,7 +268,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/mojo/public/cpp/bindings/sync_call_restrictions.h b/mojo/public/cpp/bindings/sync_call_restrictions.h
|
|
|
+index ac94eab98fd0..b89d52a0c869 100644
|
|
|
+--- a/mojo/public/cpp/bindings/sync_call_restrictions.h
|
|
|
++++ b/mojo/public/cpp/bindings/sync_call_restrictions.h
|
|
|
+@@ -29,6 +29,7 @@ class HostContextFactoryPrivate;
|
|
|
+
|
|
|
+ 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::HostContextFactoryPrivate;
|
|
|
++ // For query of whether to use SoftwareOutputDevice or not
|
|
|
++ friend class viz::GpuDisplayProvider;
|
|
|
+ // END ALLOWED USAGE.
|
|
|
+
|
|
|
+ #if ENABLE_SYNC_CALL_RESTRICTIONS
|
|
|
+diff --git a/services/viz/privileged/mojom/compositing/display_private.mojom b/services/viz/privileged/mojom/compositing/display_private.mojom
|
|
|
+index 609ded904478..2e6a7c8808d3 100644
|
|
|
+--- a/services/viz/privileged/mojom/compositing/display_private.mojom
|
|
|
++++ b/services/viz/privileged/mojom/compositing/display_private.mojom
|
|
|
+@@ -75,12 +75,14 @@ interface DisplayPrivate {
|
|
|
+ };
|
|
|
+
|
|
|
+ interface DisplayClient {
|
|
|
++ [Sync]
|
|
|
++ IsOffscreen() => (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 a/services/viz/privileged/mojom/compositing/layered_window_updater.mojom b/services/viz/privileged/mojom/compositing/layered_window_updater.mojom
|
|
|
+index 6b7fbb6cf13d..e2af75168cb9 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 443406844ecf..0b4ca067fe1e 100644
|
|
|
+--- a/ui/compositor/compositor.h
|
|
|
++++ b/ui/compositor/compositor.h
|
|
|
+@@ -66,6 +66,7 @@ class GpuMemoryBufferManager;
|
|
|
+
|
|
|
+ namespace viz {
|
|
|
+ class ContextProvider;
|
|
|
++class HostDisplayClient;
|
|
|
+ class HostFrameSinkManager;
|
|
|
+ class LocalSurfaceIdAllocation;
|
|
|
+ class RasterContextProvider;
|
|
|
+@@ -166,6 +167,15 @@ class COMPOSITOR_EXPORT ContextFactory {
|
|
|
+ virtual cc::TaskGraphRunner* GetTaskGraphRunner() = 0;
|
|
|
+ };
|
|
|
+
|
|
|
++class COMPOSITOR_EXPORT CompositorDelegate {
|
|
|
++ public:
|
|
|
++ 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
|
|
|
+@@ -205,6 +215,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
|
|
|
+@@ -422,6 +435,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 a/ui/compositor/host/host_context_factory_private.cc b/ui/compositor/host/host_context_factory_private.cc
|
|
|
+index 1db09f76243c..f07cd7a5098b 100644
|
|
|
+--- a/ui/compositor/host/host_context_factory_private.cc
|
|
|
++++ b/ui/compositor/host/host_context_factory_private.cc
|
|
|
+@@ -112,8 +112,13 @@ void HostContextFactoryPrivate::ConfigureCompositor(
|
|
|
+ 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(
|
|
|
++ compositor);
|
|
|
++ } else {
|
|
|
++ compositor_data.display_client =
|
|
|
++ std::make_unique<HostDisplayClient>(compositor);
|
|
|
++ }
|
|
|
+ root_params->display_client =
|
|
|
+ compositor_data.display_client->GetBoundRemote(resize_task_runner_);
|
|
|
+
|
|
|
+diff --git a/ui/gfx/ca_layer_params.h b/ui/gfx/ca_layer_params.h
|
|
|
+index 4014e64a75da..25e57784e1a1 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 a73b2e678ffe..6c36626d204c 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 843d5c24ec33..0ea594950fcd 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 4cac766eae31..0821495ad229 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;
|
|
|
+ }
|