Browse Source

fix: revive offscreen rendering support (#22160) (#22425)

(cherry picked from commit 36f982aee2368c0c73b9f1b448c6c1f54099555b)

Co-authored-by: Andy Dill <[email protected]>
John Kleinschmidt 5 years ago
parent
commit
faee8a092d

+ 1 - 0
BUILD.gn

@@ -791,6 +791,7 @@ if (is_mac) {
 
     include_dirs = [ "." ]
     sources = filenames.framework_sources
+    libs = []
 
     if (enable_osr) {
       libs += [ "IOSurface.framework" ]

+ 1 - 2
build/args/all.gn

@@ -21,7 +21,6 @@ dawn_enable_vulkan_validation_layers = false
 
 is_cfi = false
 
-# TODO: disabled due to crashes. re-enable.
-enable_osr = false
+enable_osr = true
 
 enable_electron_extensions = true

+ 1 - 0
patches/chromium/.patches

@@ -86,5 +86,6 @@ use_electron_resources_in_pdf_util.patch
 hack_plugin_response_interceptor_to_point_to_electron.patch
 delay_lock_the_protocol_scheme_registry.patch
 fix_route_mouse_event_navigations_through_the_web_contents_delegate.patch
+feat_enable_offscreen_rendering_with_viz_compositor.patch
 feat_add_support_for_overriding_the_base_spellchecker_download_url.patch
 gpu_notify_when_dxdiag_request_fails.patch

+ 636 - 0
patches/chromium/feat_enable_offscreen_rendering_with_viz_compositor.patch

@@ -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;
+   }

+ 9 - 5
shell/browser/osr/osr_host_display_client.cc

@@ -6,7 +6,6 @@
 
 #include <utility>
 
-#include "base/memory/shared_memory.h"
 #include "components/viz/common/resources/resource_format.h"
 #include "components/viz/common/resources/resource_sizes.h"
 #include "mojo/public/cpp/system/platform_handle.h"
@@ -23,9 +22,9 @@
 namespace electron {
 
 LayeredWindowUpdater::LayeredWindowUpdater(
-    viz::mojom::LayeredWindowUpdaterRequest request,
+    mojo::PendingReceiver<viz::mojom::LayeredWindowUpdater> receiver,
     OnPaintCallback callback)
-    : callback_(callback), binding_(this, std::move(request)) {}
+    : callback_(callback), receiver_(this, std::move(receiver)) {}
 
 LayeredWindowUpdater::~LayeredWindowUpdater() = default;
 
@@ -96,10 +95,15 @@ void OffScreenHostDisplayClient::IsOffscreen(IsOffscreenCallback callback) {
 }
 
 void OffScreenHostDisplayClient::CreateLayeredWindowUpdater(
-    viz::mojom::LayeredWindowUpdaterRequest request) {
+    mojo::PendingReceiver<viz::mojom::LayeredWindowUpdater> receiver) {
   layered_window_updater_ =
-      std::make_unique<LayeredWindowUpdater>(std::move(request), callback_);
+      std::make_unique<LayeredWindowUpdater>(std::move(receiver), callback_);
   layered_window_updater_->SetActive(active_);
 }
 
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+void OffScreenHostDisplayClient::DidCompleteSwapWithNewSize(
+    const gfx::Size& size) {}
+#endif
+
 }  // namespace electron

+ 10 - 4
shell/browser/osr/osr_host_display_client.h

@@ -21,8 +21,9 @@ typedef base::Callback<void(const gfx::Rect&, const SkBitmap&)> OnPaintCallback;
 
 class LayeredWindowUpdater : public viz::mojom::LayeredWindowUpdater {
  public:
-  explicit LayeredWindowUpdater(viz::mojom::LayeredWindowUpdaterRequest request,
-                                OnPaintCallback callback);
+  explicit LayeredWindowUpdater(
+      mojo::PendingReceiver<viz::mojom::LayeredWindowUpdater> receiver,
+      OnPaintCallback callback);
   ~LayeredWindowUpdater() override;
 
   void SetActive(bool active);
@@ -34,7 +35,7 @@ class LayeredWindowUpdater : public viz::mojom::LayeredWindowUpdater {
 
  private:
   OnPaintCallback callback_;
-  mojo::Binding<viz::mojom::LayeredWindowUpdater> binding_;
+  mojo::Receiver<viz::mojom::LayeredWindowUpdater> receiver_;
   std::unique_ptr<SkCanvas> canvas_;
   bool active_ = false;
 
@@ -62,7 +63,12 @@ class OffScreenHostDisplayClient : public viz::HostDisplayClient {
 #endif
 
   void CreateLayeredWindowUpdater(
-      viz::mojom::LayeredWindowUpdaterRequest request) override;
+      mojo::PendingReceiver<viz::mojom::LayeredWindowUpdater> receiver)
+      override;
+
+#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
+  void DidCompleteSwapWithNewSize(const gfx::Size& size) override;
+#endif
 
   std::unique_ptr<LayeredWindowUpdater> layered_window_updater_;
   OnPaintCallback callback_;

+ 48 - 163
shell/browser/osr/osr_render_widget_host_view.cc

@@ -17,6 +17,7 @@
 #include "base/task/post_task.h"
 #include "base/time/time.h"
 #include "components/viz/common/features.h"
+#include "components/viz/common/frame_sinks/begin_frame_args.h"
 #include "components/viz/common/frame_sinks/copy_output_request.h"
 #include "components/viz/common/frame_sinks/delay_based_time_source.h"
 #include "components/viz/common/gl_helper.h"
@@ -102,10 +103,10 @@ ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
   }
 
   ui::MouseEvent ui_event(type,
-                          gfx::Point(std::floor(event.PositionInWidget().x),
-                                     std::floor(event.PositionInWidget().y)),
-                          gfx::Point(std::floor(event.PositionInWidget().x),
-                                     std::floor(event.PositionInWidget().y)),
+                          gfx::Point(std::floor(event.PositionInWidget().x()),
+                                     std::floor(event.PositionInWidget().y())),
+                          gfx::Point(std::floor(event.PositionInWidget().x()),
+                                     std::floor(event.PositionInWidget().y())),
                           ui::EventTimeForNow(), button_flags, button_flags);
   ui_event.SetClickCount(event.click_count);
 
@@ -121,38 +122,6 @@ ui::MouseWheelEvent UiMouseWheelEventFromWebMouseEvent(
 
 }  // namespace
 
-class ElectronBeginFrameTimer : public viz::DelayBasedTimeSourceClient {
- public:
-  ElectronBeginFrameTimer(int frame_rate_threshold_us,
-                          const base::Closure& callback)
-      : callback_(callback) {
-    time_source_ = std::make_unique<viz::DelayBasedTimeSource>(
-        base::CreateSingleThreadTaskRunner({content::BrowserThread::UI}).get());
-    time_source_->SetTimebaseAndInterval(
-        base::TimeTicks(),
-        base::TimeDelta::FromMicroseconds(frame_rate_threshold_us));
-    time_source_->SetClient(this);
-  }
-
-  void SetActive(bool active) { time_source_->SetActive(active); }
-
-  bool IsActive() const { return time_source_->Active(); }
-
-  void SetFrameRateThresholdUs(int frame_rate_threshold_us) {
-    time_source_->SetTimebaseAndInterval(
-        base::TimeTicks::Now(),
-        base::TimeDelta::FromMicroseconds(frame_rate_threshold_us));
-  }
-
- private:
-  void OnTimerTick() override { callback_.Run(); }
-
-  const base::Closure callback_;
-  std::unique_ptr<viz::DelayBasedTimeSource> time_source_;
-
-  DISALLOW_COPY_AND_ASSIGN(ElectronBeginFrameTimer);
-};
-
 class ElectronDelegatedFrameHostClient
     : public content::DelegatedFrameHostClient {
  public:
@@ -189,7 +158,6 @@ class ElectronDelegatedFrameHostClient
 
   bool ShouldShowStaleContentOnEviction() override { return false; }
 
-  void OnBeginFrame(base::TimeTicks frame_time) override {}
   void InvalidateLocalSurfaceIdOnEviction() override {}
 
  private:
@@ -220,7 +188,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
       backing_(new SkBitmap),
       weak_ptr_factory_(this) {
   DCHECK(render_widget_host_);
-  bool is_guest_view_hack = parent_host_view_ != nullptr;
+  DCHECK(!render_widget_host_->GetView());
 
   current_device_scale_factor_ = kDefaultScaleFactor;
 
@@ -234,8 +202,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
   delegated_frame_host_client_ =
       std::make_unique<ElectronDelegatedFrameHostClient>(this);
   delegated_frame_host_ = std::make_unique<content::DelegatedFrameHost>(
-      AllocateFrameSinkId(is_guest_view_hack),
-      delegated_frame_host_client_.get(),
+      AllocateFrameSinkId(), delegated_frame_host_client_.get(),
       true /* should_register_frame_sink_id */);
 
   root_layer_ = std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
@@ -244,21 +211,17 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
   GetRootLayer()->SetFillsBoundsOpaquely(opaque);
   GetRootLayer()->SetColor(background_color_);
 
-  content::ImageTransportFactory* factory =
-      content::ImageTransportFactory::GetInstance();
-
   ui::ContextFactoryPrivate* context_factory_private =
-      factory->GetContextFactoryPrivate();
+      content::GetContextFactoryPrivate();
   compositor_ = std::make_unique<ui::Compositor>(
       context_factory_private->AllocateFrameSinkId(),
       content::GetContextFactory(), context_factory_private,
       base::ThreadTaskRunnerHandle::Get(), false /* enable_pixel_canvas */,
       false /* use_external_begin_frame_control */);
   compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
+  compositor_->SetDelegate(this);
   compositor_->SetRootLayer(root_layer_.get());
 
-  GetCompositor()->SetDelegate(this);
-
   ResizeRootLayer(false);
   render_widget_host_->SetView(this);
   InstallTransparency();
@@ -292,36 +255,6 @@ OffScreenRenderWidgetHostView::CreateBrowserAccessibilityManager(
   return nullptr;
 }
 
-void OffScreenRenderWidgetHostView::OnBeginFrameTimerTick() {
-  const base::TimeTicks frame_time = base::TimeTicks::Now();
-  const base::TimeDelta vsync_period =
-      base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_);
-  SendBeginFrame(frame_time, vsync_period);
-}
-
-void OffScreenRenderWidgetHostView::SendBeginFrame(
-    base::TimeTicks frame_time,
-    base::TimeDelta vsync_period) {
-  base::TimeTicks display_time = frame_time + vsync_period;
-
-  base::TimeDelta estimated_browser_composite_time =
-      base::TimeDelta::FromMicroseconds(
-          (1.0f * base::Time::kMicrosecondsPerSecond) / (3.0f * 60));
-
-  base::TimeTicks deadline = display_time - estimated_browser_composite_time;
-
-  const viz::BeginFrameArgs& begin_frame_args = viz::BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, begin_frame_source_.source_id(),
-      begin_frame_number_, frame_time, deadline, vsync_period,
-      viz::BeginFrameArgs::NORMAL);
-  DCHECK(begin_frame_args.IsValid());
-  begin_frame_number_++;
-
-  compositor_->context_factory_private()->IssueExternalBeginFrame(
-      compositor_.get(), begin_frame_args, /* force */ true,
-      base::NullCallback());
-}
-
 void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
   DCHECK(parent_host_view_);
 
@@ -450,8 +383,6 @@ void OffScreenRenderWidgetHostView::TakeFallbackContentFrom(
     content::RenderWidgetHostView* view) {
   DCHECK(!static_cast<content::RenderWidgetHostViewBase*>(view)
               ->IsRenderWidgetHostViewChildFrame());
-  DCHECK(!static_cast<content::RenderWidgetHostViewBase*>(view)
-              ->IsRenderWidgetHostViewGuest());
   OffScreenRenderWidgetHostView* view_osr =
       static_cast<OffScreenRenderWidgetHostView*>(view);
   SetBackgroundColor(view_osr->background_color_);
@@ -462,23 +393,6 @@ void OffScreenRenderWidgetHostView::TakeFallbackContentFrom(
   host()->GetContentRenderingTimeoutFrom(view_osr->host());
 }
 
-void OffScreenRenderWidgetHostView::DidCreateNewRendererCompositorFrameSink(
-    viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) {
-  renderer_compositor_frame_sink_ = renderer_compositor_frame_sink;
-
-  if (GetDelegatedFrameHost()) {
-    GetDelegatedFrameHost()->DidCreateNewRendererCompositorFrameSink(
-        renderer_compositor_frame_sink_);
-  }
-}
-
-void OffScreenRenderWidgetHostView::SubmitCompositorFrame(
-    const viz::LocalSurfaceId& local_surface_id,
-    viz::CompositorFrame frame,
-    base::Optional<viz::HitTestRegionList> hit_test_region_list) {
-  NOTREACHED();
-}
-
 void OffScreenRenderWidgetHostView::ResetFallbackToFirstNavigationSurface() {
   GetDelegatedFrameHost()->ResetFallbackToFirstNavigationSurface();
 }
@@ -582,13 +496,6 @@ void OffScreenRenderWidgetHostView::GetScreenInfo(
   screen_info->available_rect = gfx::Rect(size_);
 }
 
-void OffScreenRenderWidgetHostView::InitAsGuest(
-    content::RenderWidgetHostView* parent_host_view,
-    content::RenderWidgetHostViewGuest* guest_view) {
-  parent_host_view_->AddGuestHostView(this);
-  SetPainting(parent_host_view_->IsPainting());
-}
-
 void OffScreenRenderWidgetHostView::TransformPointToRootSurface(
     gfx::PointF* point) {}
 
@@ -730,14 +637,6 @@ bool OffScreenRenderWidgetHostView::InstallTransparency() {
   return false;
 }
 
-void OffScreenRenderWidgetHostView::SetNeedsBeginFrames(
-    bool needs_begin_frames) {
-  SetupFrameRate(true);
-  begin_frame_timer_->SetActive(needs_begin_frames);
-}
-
-void OffScreenRenderWidgetHostView::SetWantsAnimateOnlyBeginFrames() {}
-
 #if defined(OS_MACOSX)
 void OffScreenRenderWidgetHostView::SetActive(bool active) {}
 
@@ -862,12 +761,12 @@ void OffScreenRenderWidgetHostView::SendMouseEvent(
     const blink::WebMouseEvent& event) {
   for (auto* proxy_view : proxy_views_) {
     gfx::Rect bounds = proxy_view->GetBounds();
-    if (bounds.Contains(event.PositionInWidget().x,
-                        event.PositionInWidget().y)) {
+    if (bounds.Contains(event.PositionInWidget().x(),
+                        event.PositionInWidget().y())) {
       blink::WebMouseEvent proxy_event(event);
       proxy_event.SetPositionInWidget(
-          proxy_event.PositionInWidget().x - bounds.x(),
-          proxy_event.PositionInWidget().y - bounds.y());
+          proxy_event.PositionInWidget().x() - bounds.x(),
+          proxy_event.PositionInWidget().y() - bounds.y());
 
       ui::MouseEvent ui_event = UiMouseEventFromWebMouseEvent(proxy_event);
       proxy_view->OnEvent(&ui_event);
@@ -878,12 +777,12 @@ void OffScreenRenderWidgetHostView::SendMouseEvent(
   if (!IsPopupWidget()) {
     if (popup_host_view_ &&
         popup_host_view_->popup_position_.Contains(
-            event.PositionInWidget().x, event.PositionInWidget().y)) {
+            event.PositionInWidget().x(), event.PositionInWidget().y())) {
       blink::WebMouseEvent popup_event(event);
       popup_event.SetPositionInWidget(
-          popup_event.PositionInWidget().x -
+          popup_event.PositionInWidget().x() -
               popup_host_view_->popup_position_.x(),
-          popup_event.PositionInWidget().y -
+          popup_event.PositionInWidget().y() -
               popup_host_view_->popup_position_.y());
 
       popup_host_view_->ProcessMouseEvent(popup_event, ui::LatencyInfo());
@@ -900,12 +799,12 @@ void OffScreenRenderWidgetHostView::SendMouseWheelEvent(
     const blink::WebMouseWheelEvent& event) {
   for (auto* proxy_view : proxy_views_) {
     gfx::Rect bounds = proxy_view->GetBounds();
-    if (bounds.Contains(event.PositionInWidget().x,
-                        event.PositionInWidget().y)) {
+    if (bounds.Contains(event.PositionInWidget().x(),
+                        event.PositionInWidget().y())) {
       blink::WebMouseWheelEvent proxy_event(event);
       proxy_event.SetPositionInWidget(
-          proxy_event.PositionInWidget().x - bounds.x(),
-          proxy_event.PositionInWidget().y - bounds.y());
+          proxy_event.PositionInWidget().x() - bounds.x(),
+          proxy_event.PositionInWidget().y() - bounds.y());
 
       ui::MouseWheelEvent ui_event =
           UiMouseWheelEventFromWebMouseEvent(proxy_event);
@@ -927,17 +826,17 @@ void OffScreenRenderWidgetHostView::SendMouseWheelEvent(
   if (!IsPopupWidget()) {
     if (popup_host_view_) {
       if (popup_host_view_->popup_position_.Contains(
-              mouse_wheel_event.PositionInWidget().x,
-              mouse_wheel_event.PositionInWidget().y)) {
+              mouse_wheel_event.PositionInWidget().x(),
+              mouse_wheel_event.PositionInWidget().y())) {
         blink::WebMouseWheelEvent popup_mouse_wheel_event(mouse_wheel_event);
         popup_mouse_wheel_event.SetPositionInWidget(
-            mouse_wheel_event.PositionInWidget().x -
+            mouse_wheel_event.PositionInWidget().x() -
                 popup_host_view_->popup_position_.x(),
-            mouse_wheel_event.PositionInWidget().y -
+            mouse_wheel_event.PositionInWidget().y() -
                 popup_host_view_->popup_position_.y());
         popup_mouse_wheel_event.SetPositionInScreen(
-            popup_mouse_wheel_event.PositionInWidget().x,
-            popup_mouse_wheel_event.PositionInWidget().y);
+            popup_mouse_wheel_event.PositionInWidget().x(),
+            popup_mouse_wheel_event.PositionInWidget().y());
 
         popup_host_view_->SendMouseWheelEvent(popup_mouse_wheel_event);
         return;
@@ -958,15 +857,15 @@ void OffScreenRenderWidgetHostView::SendMouseWheelEvent(
         }
         const gfx::Rect& guest_bounds =
             guest_host_view->render_widget_host_->GetView()->GetViewBounds();
-        if (guest_bounds.Contains(mouse_wheel_event.PositionInWidget().x,
-                                  mouse_wheel_event.PositionInWidget().y)) {
+        if (guest_bounds.Contains(mouse_wheel_event.PositionInWidget().x(),
+                                  mouse_wheel_event.PositionInWidget().y())) {
           blink::WebMouseWheelEvent guest_mouse_wheel_event(mouse_wheel_event);
           guest_mouse_wheel_event.SetPositionInWidget(
-              mouse_wheel_event.PositionInWidget().x - guest_bounds.x(),
-              mouse_wheel_event.PositionInWidget().y - guest_bounds.y());
+              mouse_wheel_event.PositionInWidget().x() - guest_bounds.x(),
+              mouse_wheel_event.PositionInWidget().y() - guest_bounds.y());
           guest_mouse_wheel_event.SetPositionInScreen(
-              guest_mouse_wheel_event.PositionInWidget().x,
-              guest_mouse_wheel_event.PositionInWidget().y);
+              guest_mouse_wheel_event.PositionInWidget().x(),
+              guest_mouse_wheel_event.PositionInWidget().y());
 
           guest_host_view->SendMouseWheelEvent(guest_mouse_wheel_event);
           return;
@@ -1053,14 +952,10 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
 
   frame_rate_threshold_us_ = 1000000 / frame_rate_;
 
-  if (begin_frame_timer_.get()) {
-    begin_frame_timer_->SetFrameRateThresholdUs(frame_rate_threshold_us_);
-  } else {
-    begin_frame_timer_ = std::make_unique<ElectronBeginFrameTimer>(
-        frame_rate_threshold_us_,
-        base::BindRepeating(
-            &OffScreenRenderWidgetHostView::OnBeginFrameTimerTick,
-            weak_ptr_factory_.GetWeakPtr()));
+  if (compositor_) {
+    compositor_->SetDisplayVSyncParameters(
+        base::TimeTicks::Now(),
+        base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_));
   }
 }
 
@@ -1098,18 +993,18 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
   const gfx::Size& size_in_pixels =
       gfx::ConvertSizeToPixel(current_device_scale_factor_, size);
 
-  compositor_allocator_.GenerateId();
-  compositor_allocation_ =
-      compositor_allocator_.GetCurrentLocalSurfaceIdAllocation();
-
-  GetCompositor()->SetScaleAndSize(current_device_scale_factor_, size_in_pixels,
-                                   compositor_allocation_);
+  if (compositor_) {
+    compositor_allocator_.GenerateId();
+    compositor_allocation_ =
+        compositor_allocator_.GetCurrentLocalSurfaceIdAllocation();
+    compositor_->SetScaleAndSize(current_device_scale_factor_, size_in_pixels,
+                                 compositor_allocation_);
+  }
 
   delegated_frame_host_allocator_.GenerateId();
   delegated_frame_host_allocation_ =
       delegated_frame_host_allocator_.GetCurrentLocalSurfaceIdAllocation();
 
-  bool resized = true;
   GetDelegatedFrameHost()->EmbedSurface(
       delegated_frame_host_allocation_.local_surface_id(), size,
       cc::DeadlinePolicy::UseDefaultDeadline());
@@ -1117,25 +1012,15 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
   // Note that |render_widget_host_| will retrieve resize parameters from the
   // DelegatedFrameHost, so it must have SynchronizeVisualProperties called
   // after.
-  if (resized && render_widget_host_) {
+  if (render_widget_host_) {
     render_widget_host_->SynchronizeVisualProperties();
   }
 }
 
-viz::FrameSinkId OffScreenRenderWidgetHostView::AllocateFrameSinkId(
-    bool is_guest_view_hack) {
-  // GuestViews have two RenderWidgetHostViews and so we need to make sure
-  // we don't have FrameSinkId collisions.
-  // The FrameSinkId generated here must be unique with FrameSinkId allocated
-  // in ContextFactoryPrivate.
-  content::ImageTransportFactory* factory =
-      content::ImageTransportFactory::GetInstance();
-  return is_guest_view_hack
-             ? factory->GetContextFactoryPrivate()->AllocateFrameSinkId()
-             : viz::FrameSinkId(base::checked_cast<uint32_t>(
-                                    render_widget_host_->GetProcess()->GetID()),
-                                base::checked_cast<uint32_t>(
-                                    render_widget_host_->GetRoutingID()));
+viz::FrameSinkId OffScreenRenderWidgetHostView::AllocateFrameSinkId() {
+  return viz::FrameSinkId(
+      base::checked_cast<uint32_t>(render_widget_host_->GetProcess()->GetID()),
+      base::checked_cast<uint32_t>(render_widget_host_->GetRoutingID()));
 }
 
 void OffScreenRenderWidgetHostView::UpdateBackgroundColorFromRenderer(

+ 1 - 26
shell/browser/osr/osr_render_widget_host_view.h

@@ -17,11 +17,8 @@
 #include "base/process/kill.h"
 #include "base/threading/thread.h"
 #include "base/time/time.h"
-#include "components/viz/common/frame_sinks/begin_frame_args.h"
-#include "components/viz/common/frame_sinks/begin_frame_source.h"
 #include "components/viz/common/quads/compositor_frame.h"
 #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
-#include "content/browser/frame_host/render_widget_host_view_guest.h"  // nogncheck
 #include "content/browser/renderer_host/delegated_frame_host.h"  // nogncheck
 #include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h"  // nogncheck
 #include "content/browser/renderer_host/render_widget_host_impl.h"  // nogncheck
@@ -99,8 +96,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
   bool LockMouse(bool request_unadjusted_movement) override;
   void UnlockMouse(void) override;
   void TakeFallbackContentFrom(content::RenderWidgetHostView* view) override;
-  void SetNeedsBeginFrames(bool needs_begin_frames) override;
-  void SetWantsAnimateOnlyBeginFrames() override;
 #if defined(OS_MACOSX)
   void SetActive(bool active) override;
   void ShowDefinitionForSelection() override;
@@ -109,13 +104,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
 #endif  // defined(OS_MACOSX)
 
   // content::RenderWidgetHostViewBase:
-  void DidCreateNewRendererCompositorFrameSink(
-      viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink)
-      override;
-  void SubmitCompositorFrame(
-      const viz::LocalSurfaceId& local_surface_id,
-      viz::CompositorFrame frame,
-      base::Optional<viz::HitTestRegionList> hit_test_region_list) override;
 
   void ResetFallbackToFirstNavigationSurface() override;
   void InitAsPopup(content::RenderWidgetHostView* rwhv,
@@ -134,8 +122,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
       const gfx::Size& output_size,
       base::OnceCallback<void(const SkBitmap&)> callback) override;
   void GetScreenInfo(content::ScreenInfo* results) override;
-  void InitAsGuest(content::RenderWidgetHostView*,
-                   content::RenderWidgetHostViewGuest*) override;
   void TransformPointToRootSurface(gfx::PointF* point) override;
   gfx::Rect GetBoundsInRootWindow(void) override;
   viz::SurfaceId GetCurrentSurfaceId() const override;
@@ -167,9 +153,6 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
 
   bool InstallTransparency();
 
-  void OnBeginFrameTimerTick();
-  void SendBeginFrame(base::TimeTicks frame_time, base::TimeDelta vsync_period);
-
   void CancelWidget();
   void AddGuestHostView(OffScreenRenderWidgetHostView* guest_host);
   void RemoveGuestHostView(OffScreenRenderWidgetHostView* guest_host);
@@ -230,7 +213,7 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
   void SetupFrameRate(bool force);
   void ResizeRootLayer(bool force);
 
-  viz::FrameSinkId AllocateFrameSinkId(bool is_guest_view_hack);
+  viz::FrameSinkId AllocateFrameSinkId();
 
   // Applies background color without notifying the RenderWidget about
   // opaqueness changes.
@@ -279,22 +262,14 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,
 
   std::unique_ptr<content::CursorManager> cursor_manager_;
 
-  std::unique_ptr<ElectronBeginFrameTimer> begin_frame_timer_;
   OffScreenHostDisplayClient* host_display_client_;
   std::unique_ptr<OffScreenVideoConsumer> video_consumer_;
 
-  // Provides |source_id| for BeginFrameArgs that we create.
-  viz::StubBeginFrameSource begin_frame_source_;
-  uint64_t begin_frame_number_ = viz::BeginFrameArgs::kStartingFrameNumber;
-
   std::unique_ptr<ElectronDelegatedFrameHostClient>
       delegated_frame_host_client_;
 
   content::MouseWheelPhaseHandler mouse_wheel_phase_handler_;
 
-  viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink_ =
-      nullptr;
-
   // Latest capture sequence number which is incremented when the caller
   // requests surfaces be synchronized via
   // EnsureSurfaceSynchronizedForWebTest().

+ 12 - 5
shell/browser/osr/osr_video_consumer.cc

@@ -54,7 +54,8 @@ void OffScreenVideoConsumer::OnFrameCaptured(
     base::ReadOnlySharedMemoryRegion data,
     ::media::mojom::VideoFrameInfoPtr info,
     const gfx::Rect& content_rect,
-    viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) {
+    mojo::PendingRemote<viz::mojom::FrameSinkVideoConsumerFrameCallbacks>
+        callbacks) {
   if (!CheckContentRect(content_rect)) {
     gfx::Size view_size = view_->SizeInPixels();
     video_capturer_->SetResolutionConstraints(view_size, view_size, true);
@@ -62,18 +63,23 @@ void OffScreenVideoConsumer::OnFrameCaptured(
     return;
   }
 
+  mojo::Remote<viz::mojom::FrameSinkVideoConsumerFrameCallbacks>
+      callbacks_remote(std::move(callbacks));
+
   if (!data.IsValid()) {
-    callbacks->Done();
+    callbacks_remote->Done();
     return;
   }
   base::ReadOnlySharedMemoryMapping mapping = data.Map();
   if (!mapping.IsValid()) {
     DLOG(ERROR) << "Shared memory mapping failed.";
+    callbacks_remote->Done();
     return;
   }
   if (mapping.size() <
       media::VideoFrame::AllocationSize(info->pixel_format, info->coded_size)) {
     DLOG(ERROR) << "Shared memory size was less than expected.";
+    callbacks_remote->Done();
     return;
   }
 
@@ -89,7 +95,8 @@ void OffScreenVideoConsumer::OnFrameCaptured(
     base::ReadOnlySharedMemoryMapping mapping;
     // Prevents FrameSinkVideoCapturer from recycling the shared memory that
     // backs |frame_|.
-    viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr releaser;
+    mojo::PendingRemote<viz::mojom::FrameSinkVideoConsumerFrameCallbacks>
+        releaser;
   };
 
   SkBitmap bitmap;
@@ -102,7 +109,7 @@ void OffScreenVideoConsumer::OnFrameCaptured(
       [](void* addr, void* context) {
         delete static_cast<FramePinner*>(context);
       },
-      new FramePinner{std::move(mapping), std::move(callbacks)});
+      new FramePinner{std::move(mapping), callbacks_remote.Unbind()});
   bitmap.setImmutable();
 
   media::VideoFrameMetadata metadata;
@@ -110,7 +117,7 @@ void OffScreenVideoConsumer::OnFrameCaptured(
   gfx::Rect damage_rect;
 
   auto UPDATE_RECT = media::VideoFrameMetadata::CAPTURE_UPDATE_RECT;
-  if (!metadata.GetRect(UPDATE_RECT, &damage_rect)) {
+  if (!metadata.GetRect(UPDATE_RECT, &damage_rect) || damage_rect.IsEmpty()) {
     damage_rect = content_rect;
   }
 

+ 3 - 1
shell/browser/osr/osr_video_consumer.h

@@ -10,6 +10,7 @@
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "components/viz/host/client_frame_sink_video_capturer.h"
+#include "media/capture/mojom/video_capture_types.mojom.h"
 
 namespace electron {
 
@@ -34,7 +35,8 @@ class OffScreenVideoConsumer : public viz::mojom::FrameSinkVideoConsumer {
       base::ReadOnlySharedMemoryRegion data,
       ::media::mojom::VideoFrameInfoPtr info,
       const gfx::Rect& content_rect,
-      viz::mojom::FrameSinkVideoConsumerFrameCallbacksPtr callbacks) override;
+      mojo::PendingRemote<viz::mojom::FrameSinkVideoConsumerFrameCallbacks>
+          callbacks) override;
   void OnStopped() override;
 
   bool CheckContentRect(const gfx::Rect& content_rect);