feat_enable_offscreen_rendering_with_viz_compositor.patch 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
  2. From: Andy Dill <[email protected]>
  3. Date: Thu, 30 Jan 2020 09:36:07 -0800
  4. Subject: feat: enable off-screen rendering with viz compositor
  5. This patch adds hooks in the relevant places that allow for off-screen
  6. rendering with the viz compositor by way of a custom HostDisplayClient
  7. and LayeredWindowUpdater.
  8. diff --git a/components/viz/host/host_display_client.cc b/components/viz/host/host_display_client.cc
  9. index 3547ee865c220731a6b4be4c1b32ec899b3dd11f..715bfa4b5db5fc4beb83c26b1eedda82c87a245b 100644
  10. --- a/components/viz/host/host_display_client.cc
  11. +++ b/components/viz/host/host_display_client.cc
  12. @@ -43,9 +43,13 @@ void HostDisplayClient::OnDisplayReceivedCALayerParams(
  13. }
  14. #endif
  15. -#if defined(OS_WIN)
  16. +void HostDisplayClient::IsOffscreen(IsOffscreenCallback callback) {
  17. + std::move(callback).Run(false);
  18. +}
  19. +
  20. void HostDisplayClient::CreateLayeredWindowUpdater(
  21. mojo::PendingReceiver<mojom::LayeredWindowUpdater> receiver) {
  22. +#if defined(OS_WIN)
  23. if (!NeedsToUseLayerWindow(widget_)) {
  24. DLOG(ERROR) << "HWND shouldn't be using a layered window";
  25. return;
  26. @@ -53,8 +57,12 @@ void HostDisplayClient::CreateLayeredWindowUpdater(
  27. layered_window_updater_ =
  28. std::make_unique<LayeredWindowUpdaterImpl>(widget_, std::move(receiver));
  29. -}
  30. +#else
  31. + CHECK(false) << "Chromium is calling CreateLayeredWindowUpdater for non-OSR "
  32. + "windows on POSIX platforms, something is wrong with "
  33. + "Electron's OSR implementation.";
  34. #endif
  35. +}
  36. #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
  37. void HostDisplayClient::DidCompleteSwapWithNewSize(const gfx::Size& size) {
  38. diff --git a/components/viz/host/host_display_client.h b/components/viz/host/host_display_client.h
  39. index cedf833d23589dc3157168cfc7e6d3bb12939f7a..4437a7875076ef5a99ddcd767036ec37c2d48d44 100644
  40. --- a/components/viz/host/host_display_client.h
  41. +++ b/components/viz/host/host_display_client.h
  42. @@ -31,17 +31,17 @@ class VIZ_HOST_EXPORT HostDisplayClient : public mojom::DisplayClient {
  43. mojo::PendingRemote<mojom::DisplayClient> GetBoundRemote(
  44. scoped_refptr<base::SingleThreadTaskRunner> task_runner);
  45. - private:
  46. + protected:
  47. // mojom::DisplayClient implementation:
  48. + void IsOffscreen(IsOffscreenCallback callback) override;
  49. +
  50. #if defined(OS_MACOSX)
  51. void OnDisplayReceivedCALayerParams(
  52. const gfx::CALayerParams& ca_layer_params) override;
  53. #endif
  54. -#if defined(OS_WIN)
  55. void CreateLayeredWindowUpdater(
  56. mojo::PendingReceiver<mojom::LayeredWindowUpdater> receiver) override;
  57. -#endif
  58. #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
  59. void DidCompleteSwapWithNewSize(const gfx::Size& size) override;
  60. diff --git a/components/viz/host/layered_window_updater_impl.cc b/components/viz/host/layered_window_updater_impl.cc
  61. index b04f654fe820f821b18e059cdd40085fc2384c4e..ee22012b01ef92bb3b32b5b1081609a7bdfb0d93 100644
  62. --- a/components/viz/host/layered_window_updater_impl.cc
  63. +++ b/components/viz/host/layered_window_updater_impl.cc
  64. @@ -44,7 +44,9 @@ void LayeredWindowUpdaterImpl::OnAllocatedSharedMemory(
  65. // |region|'s handle will close when it goes out of scope.
  66. }
  67. -void LayeredWindowUpdaterImpl::Draw(DrawCallback draw_callback) {
  68. +void LayeredWindowUpdaterImpl::Draw(
  69. + const gfx::Rect& damage_rect,
  70. + DrawCallback draw_callback) {
  71. TRACE_EVENT0("viz", "LayeredWindowUpdaterImpl::Draw");
  72. if (!canvas_) {
  73. diff --git a/components/viz/host/layered_window_updater_impl.h b/components/viz/host/layered_window_updater_impl.h
  74. index 1026b739d283f0fc252fa2af83a6d4cf51bc8553..fe562ab60ce98b8bb0c5080a6428deb319a4dd04 100644
  75. --- a/components/viz/host/layered_window_updater_impl.h
  76. +++ b/components/viz/host/layered_window_updater_impl.h
  77. @@ -35,7 +35,7 @@ class VIZ_HOST_EXPORT LayeredWindowUpdaterImpl
  78. // mojom::LayeredWindowUpdater implementation.
  79. void OnAllocatedSharedMemory(const gfx::Size& pixel_size,
  80. base::UnsafeSharedMemoryRegion region) override;
  81. - void Draw(DrawCallback draw_callback) override;
  82. + void Draw(const gfx::Rect& damage_rect, DrawCallback draw_callback) override;
  83. private:
  84. const HWND hwnd_;
  85. diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
  86. index 8c4f933b32420d2cfc40d5bc5883fda61636b52a..6f2322736e570b1e994a4f0c39396261cb8a6f58 100644
  87. --- a/components/viz/service/BUILD.gn
  88. +++ b/components/viz/service/BUILD.gn
  89. @@ -111,6 +111,8 @@ viz_component("service") {
  90. "display_embedder/output_surface_provider_impl.h",
  91. "display_embedder/server_shared_bitmap_manager.cc",
  92. "display_embedder/server_shared_bitmap_manager.h",
  93. + "display_embedder/software_output_device_proxy.cc",
  94. + "display_embedder/software_output_device_proxy.h",
  95. "display_embedder/software_output_surface.cc",
  96. "display_embedder/software_output_surface.h",
  97. "display_embedder/viz_process_context_provider.cc",
  98. diff --git a/components/viz/service/display_embedder/output_surface_provider_impl.cc b/components/viz/service/display_embedder/output_surface_provider_impl.cc
  99. index b58099c6c1ad5727a806b81d674f4dac187da927..6d38e89500b6f3dd2b76fe3c7e67c568862aa4af 100644
  100. --- a/components/viz/service/display_embedder/output_surface_provider_impl.cc
  101. +++ b/components/viz/service/display_embedder/output_surface_provider_impl.cc
  102. @@ -21,6 +21,7 @@
  103. #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
  104. #include "components/viz/service/display_embedder/skia_output_surface_dependency_impl.h"
  105. #include "components/viz/service/display_embedder/skia_output_surface_impl.h"
  106. +#include "components/viz/service/display_embedder/software_output_device_proxy.h"
  107. #include "components/viz/service/display_embedder/software_output_surface.h"
  108. #include "components/viz/service/display_embedder/viz_process_context_provider.h"
  109. #include "components/viz/service/gl/gpu_service_impl.h"
  110. @@ -34,6 +35,7 @@
  111. #include "gpu/ipc/scheduler_sequence.h"
  112. #include "gpu/ipc/service/gpu_channel_manager_delegate.h"
  113. #include "gpu/ipc/service/image_transport_surface.h"
  114. +#include "services/viz/privileged/mojom/compositing/layered_window_updater.mojom.h"
  115. #include "ui/base/ui_base_switches.h"
  116. #include "ui/gl/gl_context.h"
  117. #include "ui/gl/init/gl_factory.h"
  118. @@ -218,6 +220,22 @@ OutputSurfaceProviderImpl::CreateSoftwareOutputDeviceForPlatform(
  119. if (headless_)
  120. return std::make_unique<SoftwareOutputDevice>();
  121. +#if !defined(OS_MACOSX)
  122. + {
  123. + mojo::ScopedAllowSyncCallForTesting allow_sync;
  124. + DCHECK(display_client);
  125. + bool offscreen = false;
  126. + if (display_client->IsOffscreen(&offscreen) && offscreen) {
  127. + mojom::LayeredWindowUpdaterPtr layered_window_updater;
  128. + display_client->CreateLayeredWindowUpdater(
  129. + mojo::MakeRequest(&layered_window_updater));
  130. +
  131. + return std::make_unique<SoftwareOutputDeviceProxy>(
  132. + std::move(layered_window_updater));
  133. + }
  134. + }
  135. +#endif
  136. +
  137. #if defined(OS_WIN)
  138. return CreateSoftwareOutputDeviceWin(surface_handle, &output_device_backing_,
  139. display_client);
  140. diff --git a/components/viz/service/display_embedder/software_output_device_mac.cc b/components/viz/service/display_embedder/software_output_device_mac.cc
  141. index 49149081cc603f14eacee647cbb2fcf8ed5e66fd..9ff3f2ee203403fdaa31edb8a0bcc000c4d214d7 100644
  142. --- a/components/viz/service/display_embedder/software_output_device_mac.cc
  143. +++ b/components/viz/service/display_embedder/software_output_device_mac.cc
  144. @@ -102,6 +102,8 @@ void SoftwareOutputDeviceMac::UpdateAndCopyBufferDamage(
  145. SkCanvas* SoftwareOutputDeviceMac::BeginPaint(
  146. const gfx::Rect& new_damage_rect) {
  147. + last_damage = new_damage_rect;
  148. +
  149. // Record the previous paint buffer.
  150. Buffer* previous_paint_buffer =
  151. buffer_queue_.empty() ? nullptr : buffer_queue_.back().get();
  152. @@ -187,6 +189,7 @@ void SoftwareOutputDeviceMac::EndPaint() {
  153. ca_layer_params.is_empty = false;
  154. ca_layer_params.scale_factor = scale_factor_;
  155. ca_layer_params.pixel_size = pixel_size_;
  156. + ca_layer_params.damage = last_damage;
  157. ca_layer_params.io_surface_mach_port.reset(
  158. IOSurfaceCreateMachPort(current_paint_buffer_->io_surface));
  159. client_->SoftwareDeviceUpdatedCALayerParams(ca_layer_params);
  160. diff --git a/components/viz/service/display_embedder/software_output_device_mac.h b/components/viz/service/display_embedder/software_output_device_mac.h
  161. index f3867356e3d641416e00e6d115ae9ae2a0be90ab..b1d192d2b20ccb63fba07093101d745e5ffe86dd 100644
  162. --- a/components/viz/service/display_embedder/software_output_device_mac.h
  163. +++ b/components/viz/service/display_embedder/software_output_device_mac.h
  164. @@ -56,6 +56,7 @@ class VIZ_SERVICE_EXPORT SoftwareOutputDeviceMac : public SoftwareOutputDevice {
  165. void UpdateAndCopyBufferDamage(Buffer* previous_paint_buffer,
  166. const SkRegion& new_damage_rect);
  167. + gfx::Rect last_damage;
  168. gfx::Size pixel_size_;
  169. float scale_factor_ = 1;
  170. diff --git a/components/viz/service/display_embedder/software_output_device_proxy.cc b/components/viz/service/display_embedder/software_output_device_proxy.cc
  171. new file mode 100644
  172. index 0000000000000000000000000000000000000000..4efea02f80f8b6818291321a7c63f0f4815a5b98
  173. --- /dev/null
  174. +++ b/components/viz/service/display_embedder/software_output_device_proxy.cc
  175. @@ -0,0 +1,157 @@
  176. +// Copyright 2014 The Chromium Authors. All rights reserved.
  177. +// Use of this source code is governed by a BSD-style license that can be
  178. +// found in the LICENSE file.
  179. +
  180. +#include "components/viz/service/display_embedder/software_output_device_proxy.h"
  181. +
  182. +#include "base/memory/unsafe_shared_memory_region.h"
  183. +#include "base/threading/thread_checker.h"
  184. +#include "base/trace_event/trace_event.h"
  185. +#include "components/viz/common/resources/resource_sizes.h"
  186. +#include "components/viz/service/display_embedder/output_device_backing.h"
  187. +#include "mojo/public/cpp/system/platform_handle.h"
  188. +#include "services/viz/privileged/mojom/compositing/layered_window_updater.mojom.h"
  189. +#include "skia/ext/platform_canvas.h"
  190. +#include "third_party/skia/include/core/SkCanvas.h"
  191. +#include "ui/gfx/skia_util.h"
  192. +
  193. +#if defined(OS_WIN)
  194. +#include "skia/ext/skia_utils_win.h"
  195. +#include "ui/gfx/gdi_util.h"
  196. +#include "ui/gfx/win/hwnd_util.h"
  197. +#else
  198. +#include "mojo/public/cpp/base/shared_memory_utils.h"
  199. +#endif
  200. +
  201. +namespace viz {
  202. +
  203. +SoftwareOutputDeviceBase::~SoftwareOutputDeviceBase() {
  204. + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  205. + DCHECK(!in_paint_);
  206. +}
  207. +
  208. +void SoftwareOutputDeviceBase::Resize(const gfx::Size& viewport_pixel_size,
  209. + float scale_factor) {
  210. + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  211. + DCHECK(!in_paint_);
  212. +
  213. + if (viewport_pixel_size_ == viewport_pixel_size)
  214. + return;
  215. +
  216. + viewport_pixel_size_ = viewport_pixel_size;
  217. + ResizeDelegated();
  218. +}
  219. +
  220. +SkCanvas* SoftwareOutputDeviceBase::BeginPaint(
  221. + const gfx::Rect& damage_rect) {
  222. + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  223. + DCHECK(!in_paint_);
  224. +
  225. + damage_rect_ = damage_rect;
  226. + in_paint_ = true;
  227. + return BeginPaintDelegated();
  228. +}
  229. +
  230. +void SoftwareOutputDeviceBase::EndPaint() {
  231. + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  232. + DCHECK(in_paint_);
  233. +
  234. + in_paint_ = false;
  235. +
  236. + gfx::Rect intersected_damage_rect = damage_rect_;
  237. + intersected_damage_rect.Intersect(gfx::Rect(viewport_pixel_size_));
  238. + if (intersected_damage_rect.IsEmpty())
  239. + return;
  240. +
  241. + EndPaintDelegated(intersected_damage_rect);
  242. +}
  243. +
  244. +SoftwareOutputDeviceProxy::~SoftwareOutputDeviceProxy() = default;
  245. +
  246. +SoftwareOutputDeviceProxy::SoftwareOutputDeviceProxy(
  247. + mojom::LayeredWindowUpdaterPtr layered_window_updater)
  248. + : layered_window_updater_(std::move(layered_window_updater)) {
  249. + DCHECK(layered_window_updater_.is_bound());
  250. +}
  251. +
  252. +void SoftwareOutputDeviceProxy::OnSwapBuffers(
  253. + SoftwareOutputDevice::SwapBuffersCallback swap_ack_callback) {
  254. + DCHECK(swap_ack_callback_.is_null());
  255. +
  256. + // We aren't waiting on DrawAck() and can immediately run the callback.
  257. + if (!waiting_on_draw_ack_) {
  258. + task_runner_->PostTask(FROM_HERE,
  259. + base::BindOnce(std::move(swap_ack_callback), viewport_pixel_size_));
  260. + return;
  261. + }
  262. +
  263. + swap_ack_callback_ = std::move(swap_ack_callback);
  264. +}
  265. +
  266. +void SoftwareOutputDeviceProxy::ResizeDelegated() {
  267. + canvas_.reset();
  268. +
  269. + size_t required_bytes;
  270. + if (!ResourceSizes::MaybeSizeInBytes(
  271. + viewport_pixel_size_, ResourceFormat::RGBA_8888, &required_bytes)) {
  272. + DLOG(ERROR) << "Invalid viewport size " << viewport_pixel_size_.ToString();
  273. + return;
  274. + }
  275. +
  276. + base::UnsafeSharedMemoryRegion region =
  277. + base::UnsafeSharedMemoryRegion::Create(required_bytes);
  278. + if (!region.IsValid()) {
  279. + DLOG(ERROR) << "Failed to allocate " << required_bytes << " bytes";
  280. + return;
  281. + }
  282. +
  283. + #if defined(WIN32)
  284. + canvas_ = skia::CreatePlatformCanvasWithSharedSection(
  285. + viewport_pixel_size_.width(), viewport_pixel_size_.height(), false,
  286. + region.GetPlatformHandle(), skia::CRASH_ON_FAILURE);
  287. + #else
  288. + shm_mapping_ = region.Map();
  289. + if (!shm_mapping_.IsValid()) {
  290. + DLOG(ERROR) << "Failed to map " << required_bytes << " bytes";
  291. + return;
  292. + }
  293. +
  294. + canvas_ = skia::CreatePlatformCanvasWithPixels(
  295. + viewport_pixel_size_.width(), viewport_pixel_size_.height(), false,
  296. + static_cast<uint8_t*>(shm_mapping_.memory()), skia::CRASH_ON_FAILURE);
  297. + #endif
  298. +
  299. + // Transfer region ownership to the browser process.
  300. + layered_window_updater_->OnAllocatedSharedMemory(viewport_pixel_size_,
  301. + std::move(region));
  302. +}
  303. +
  304. +SkCanvas* SoftwareOutputDeviceProxy::BeginPaintDelegated() {
  305. + return canvas_.get();
  306. +}
  307. +
  308. +void SoftwareOutputDeviceProxy::EndPaintDelegated(
  309. + const gfx::Rect& damage_rect) {
  310. + DCHECK(!waiting_on_draw_ack_);
  311. +
  312. + if (!canvas_)
  313. + return;
  314. +
  315. + layered_window_updater_->Draw(damage_rect, base::BindOnce(
  316. + &SoftwareOutputDeviceProxy::DrawAck, base::Unretained(this)));
  317. + waiting_on_draw_ack_ = true;
  318. +
  319. + TRACE_EVENT_ASYNC_BEGIN0("viz", "SoftwareOutputDeviceProxy::Draw", this);
  320. +}
  321. +
  322. +void SoftwareOutputDeviceProxy::DrawAck() {
  323. + DCHECK(waiting_on_draw_ack_);
  324. + DCHECK(!swap_ack_callback_.is_null());
  325. +
  326. + TRACE_EVENT_ASYNC_END0("viz", "SoftwareOutputDeviceProxy::Draw", this);
  327. +
  328. + waiting_on_draw_ack_ = false;
  329. + std::move(swap_ack_callback_).Run(viewport_pixel_size_);
  330. +}
  331. +
  332. +} // namespace viz
  333. diff --git a/components/viz/service/display_embedder/software_output_device_proxy.h b/components/viz/service/display_embedder/software_output_device_proxy.h
  334. new file mode 100644
  335. index 0000000000000000000000000000000000000000..48fa86caaab3c15764f105eb7ad2aecf2b89bf36
  336. --- /dev/null
  337. +++ b/components/viz/service/display_embedder/software_output_device_proxy.h
  338. @@ -0,0 +1,90 @@
  339. +// Copyright 2014 The Chromium Authors. All rights reserved.
  340. +// Use of this source code is governed by a BSD-style license that can be
  341. +// found in the LICENSE file.
  342. +
  343. +#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_DEVICE_PROXY_H_
  344. +#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_DEVICE_PROXY_H_
  345. +
  346. +#if defined(OS_WIN)
  347. +#include <windows.h>
  348. +#endif
  349. +
  350. +#include <memory>
  351. +
  352. +#include "base/memory/shared_memory_mapping.h"
  353. +#include "base/threading/thread_checker.h"
  354. +#include "components/viz/host/host_display_client.h"
  355. +#include "components/viz/service/display/software_output_device.h"
  356. +#include "components/viz/service/viz_service_export.h"
  357. +#include "services/viz/privileged/mojom/compositing/display_private.mojom.h"
  358. +#include "services/viz/privileged/mojom/compositing/layered_window_updater.mojom.h"
  359. +
  360. +namespace viz {
  361. +
  362. +// Shared base class for SoftwareOutputDevice implementations.
  363. +class SoftwareOutputDeviceBase : public SoftwareOutputDevice {
  364. + public:
  365. + SoftwareOutputDeviceBase() = default;
  366. + ~SoftwareOutputDeviceBase() override;
  367. +
  368. + // SoftwareOutputDevice implementation.
  369. + void Resize(const gfx::Size& viewport_pixel_size,
  370. + float scale_factor) override;
  371. + SkCanvas* BeginPaint(const gfx::Rect& damage_rect) override;
  372. + void EndPaint() override;
  373. +
  374. + // Called from Resize() if |viewport_pixel_size_| has changed.
  375. + virtual void ResizeDelegated() = 0;
  376. +
  377. + // Called from BeginPaint() and should return an SkCanvas.
  378. + virtual SkCanvas* BeginPaintDelegated() = 0;
  379. +
  380. + // Called from EndPaint() if there is damage.
  381. + virtual void EndPaintDelegated(const gfx::Rect& damage_rect) = 0;
  382. +
  383. + private:
  384. + bool in_paint_ = false;
  385. +
  386. + THREAD_CHECKER(thread_checker_);
  387. +
  388. + DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceBase);
  389. +};
  390. +
  391. +// SoftwareOutputDevice implementation that draws indirectly. An implementation
  392. +// of mojom::LayeredWindowUpdater in the browser process handles the actual
  393. +// drawing. Pixel backing is in SharedMemory so no copying between processes
  394. +// is required.
  395. +class SoftwareOutputDeviceProxy : public SoftwareOutputDeviceBase {
  396. + public:
  397. + explicit SoftwareOutputDeviceProxy(
  398. + mojom::LayeredWindowUpdaterPtr layered_window_updater);
  399. + ~SoftwareOutputDeviceProxy() override;
  400. +
  401. + // SoftwareOutputDevice implementation.
  402. + void OnSwapBuffers(SoftwareOutputDevice::SwapBuffersCallback swap_ack_callback) override;
  403. +
  404. + // SoftwareOutputDeviceBase implementation.
  405. + void ResizeDelegated() override;
  406. + SkCanvas* BeginPaintDelegated() override;
  407. + void EndPaintDelegated(const gfx::Rect& rect) override;
  408. +
  409. + private:
  410. + // Runs |swap_ack_callback_| after draw has happened.
  411. + void DrawAck();
  412. +
  413. + mojom::LayeredWindowUpdaterPtr layered_window_updater_;
  414. +
  415. + std::unique_ptr<SkCanvas> canvas_;
  416. + bool waiting_on_draw_ack_ = false;
  417. + SoftwareOutputDevice::SwapBuffersCallback swap_ack_callback_;
  418. +
  419. +#if !defined(WIN32)
  420. + base::WritableSharedMemoryMapping shm_mapping_;
  421. +#endif
  422. +
  423. + DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDeviceProxy);
  424. +};
  425. +
  426. +} // namespace viz
  427. +
  428. +#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SOFTWARE_OUTPUT_DEVICE_PROXY_H_
  429. diff --git a/components/viz/service/display_embedder/software_output_device_win.cc b/components/viz/service/display_embedder/software_output_device_win.cc
  430. index 2bb30e5318b6b48c2e6d4b1f64a6a36c68f963d1..9e805f27a9d7d1c0aa68cdf9f48895c055ca7791 100644
  431. --- a/components/viz/service/display_embedder/software_output_device_win.cc
  432. +++ b/components/viz/service/display_embedder/software_output_device_win.cc
  433. @@ -188,7 +188,7 @@ void SoftwareOutputDeviceWinProxy::EndPaintDelegated(
  434. if (!canvas_)
  435. return;
  436. - layered_window_updater_->Draw(base::BindOnce(
  437. + layered_window_updater_->Draw(damage_rect, base::BindOnce(
  438. &SoftwareOutputDeviceWinProxy::DrawAck, base::Unretained(this)));
  439. waiting_on_draw_ack_ = true;
  440. diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc
  441. index 641a63e8c18e3e81acacb67a59b285dac44abbb1..72b74ec00402ff7b5b4853c08365eb2f69d62713 100644
  442. --- a/content/browser/compositor/viz_process_transport_factory.cc
  443. +++ b/content/browser/compositor/viz_process_transport_factory.cc
  444. @@ -403,8 +403,13 @@ void VizProcessTransportFactory::OnEstablishedGpuChannel(
  445. compositor_data.display_private.reset();
  446. root_params->display_private =
  447. compositor_data.display_private.BindNewEndpointAndPassReceiver();
  448. - compositor_data.display_client =
  449. - std::make_unique<HostDisplayClient>(compositor);
  450. + if (compositor->delegate()) {
  451. + compositor_data.display_client = compositor->delegate()->CreateHostDisplayClient(
  452. + compositor);
  453. + } else {
  454. + compositor_data.display_client =
  455. + std::make_unique<HostDisplayClient>(compositor);
  456. + }
  457. root_params->display_client =
  458. compositor_data.display_client->GetBoundRemote(resize_task_runner_);
  459. diff --git a/mojo/public/cpp/bindings/sync_call_restrictions.h b/mojo/public/cpp/bindings/sync_call_restrictions.h
  460. index 599d24e260ae85a2f71054cc64f296875b97170d..70269ce3332edd07f1760476f3592d08c3dc3130 100644
  461. --- a/mojo/public/cpp/bindings/sync_call_restrictions.h
  462. +++ b/mojo/public/cpp/bindings/sync_call_restrictions.h
  463. @@ -33,6 +33,7 @@ class Compositor;
  464. namespace viz {
  465. class HostFrameSinkManager;
  466. +class GpuDisplayProvider;
  467. }
  468. namespace mojo {
  469. @@ -83,6 +84,8 @@ class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) SyncCallRestrictions {
  470. // For destroying the GL context/surface that draw to a platform window before
  471. // the platform window is destroyed.
  472. friend class viz::HostFrameSinkManager;
  473. + // For query of whether to use SoftwareOutputDevice or not
  474. + friend class viz::GpuDisplayProvider;
  475. // For preventing frame swaps of wrong size during resize on Windows.
  476. // (https://crbug.com/811945)
  477. friend class ui::Compositor;
  478. diff --git a/services/viz/privileged/mojom/compositing/display_private.mojom b/services/viz/privileged/mojom/compositing/display_private.mojom
  479. index d88fab3b7d0a968b2a5503e04a0812dc1edeaf28..4f66ac576ca495630cba4f82f0e5e0ebda434ddd 100644
  480. --- a/services/viz/privileged/mojom/compositing/display_private.mojom
  481. +++ b/services/viz/privileged/mojom/compositing/display_private.mojom
  482. @@ -74,12 +74,14 @@ interface DisplayPrivate {
  483. };
  484. interface DisplayClient {
  485. + [Sync]
  486. + IsOffscreen() => (bool success);
  487. +
  488. [EnableIf=is_mac]
  489. OnDisplayReceivedCALayerParams(gfx.mojom.CALayerParams ca_layer_params);
  490. // Creates a LayeredWindowUpdater implementation to draw into a layered
  491. // window.
  492. - [EnableIf=is_win]
  493. CreateLayeredWindowUpdater(pending_receiver<LayeredWindowUpdater> receiver);
  494. // Notifies that a swap has occurred and provides information about the pixel
  495. diff --git a/services/viz/privileged/mojom/compositing/layered_window_updater.mojom b/services/viz/privileged/mojom/compositing/layered_window_updater.mojom
  496. index 6b7fbb6cf13dc8ee6ade0878a9a2c1efc5d4d3f1..e2af75168cb914a7b3b4a6c9b6a285498c3f8e72 100644
  497. --- a/services/viz/privileged/mojom/compositing/layered_window_updater.mojom
  498. +++ b/services/viz/privileged/mojom/compositing/layered_window_updater.mojom
  499. @@ -26,5 +26,5 @@ interface LayeredWindowUpdater {
  500. // Draws to the HWND by copying pixels from shared memory. Callback must be
  501. // called after draw operation is complete to signal shared memory can be
  502. // modified.
  503. - Draw() => ();
  504. + Draw(gfx.mojom.Rect damage_rect) => ();
  505. };
  506. diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
  507. index 0f99c9d78626ccc211236832e5df2008ce0df5f2..f1dfa72d21e93f5223cde8e2b34d5ed2a6c04209 100644
  508. --- a/ui/compositor/compositor.h
  509. +++ b/ui/compositor/compositor.h
  510. @@ -74,6 +74,7 @@ class DisplayPrivate;
  511. class ExternalBeginFrameController;
  512. } // namespace mojom
  513. class ContextProvider;
  514. +class HostDisplayClient;
  515. class HostFrameSinkManager;
  516. class LocalSurfaceIdAllocation;
  517. class RasterContextProvider;
  518. @@ -127,6 +128,15 @@ class COMPOSITOR_EXPORT ContextFactory {
  519. virtual viz::HostFrameSinkManager* GetHostFrameSinkManager() = 0;
  520. };
  521. +class COMPOSITOR_EXPORT CompositorDelegate {
  522. + public:
  523. + virtual std::unique_ptr<viz::HostDisplayClient> CreateHostDisplayClient(
  524. + ui::Compositor* compositor) = 0;
  525. +
  526. + protected:
  527. + virtual ~CompositorDelegate() {}
  528. +};
  529. +
  530. // Compositor object to take care of GPU painting.
  531. // A Browser compositor object is responsible for generating the final
  532. // displayable form of pixels comprising a single widget's contents. It draws an
  533. @@ -161,6 +171,9 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
  534. // Schedules a redraw of the layer tree associated with this compositor.
  535. void ScheduleDraw();
  536. + CompositorDelegate* delegate() const { return delegate_; }
  537. + void SetDelegate(CompositorDelegate* delegate) { delegate_ = delegate; }
  538. +
  539. // Sets the root of the layer tree drawn by this Compositor. The root layer
  540. // must have no parent. The compositor's root layer is reset if the root layer
  541. // is destroyed. NULL can be passed to reset the root layer, in which case the
  542. @@ -424,6 +437,8 @@ class COMPOSITOR_EXPORT Compositor : public cc::LayerTreeHostClient,
  543. std::unique_ptr<PendingBeginFrameArgs> pending_begin_frame_args_;
  544. + CompositorDelegate* delegate_ = nullptr;
  545. +
  546. // The root of the Layer tree drawn by this compositor.
  547. Layer* root_layer_ = nullptr;
  548. diff --git a/ui/gfx/ca_layer_params.h b/ui/gfx/ca_layer_params.h
  549. index 4014e64a75da88cf66c02e8adb71171c2666cab7..25e57784e1a1ffc546b003daa4cd0059c468432f 100644
  550. --- a/ui/gfx/ca_layer_params.h
  551. +++ b/ui/gfx/ca_layer_params.h
  552. @@ -6,6 +6,7 @@
  553. #define UI_GFX_CA_LAYER_PARAMS_H_
  554. #include "build/build_config.h"
  555. +#include "ui/gfx/geometry/rect.h"
  556. #include "ui/gfx/geometry/size.h"
  557. #include "ui/gfx/gfx_export.h"
  558. @@ -41,6 +42,8 @@ struct GFX_EXPORT CALayerParams {
  559. gfx::ScopedRefCountedIOSurfaceMachPort io_surface_mach_port;
  560. #endif
  561. + gfx::Rect damage;
  562. +
  563. // The geometry of the frame.
  564. gfx::Size pixel_size;
  565. float scale_factor = 1.f;
  566. diff --git a/ui/gfx/mojom/ca_layer_params.mojom b/ui/gfx/mojom/ca_layer_params.mojom
  567. index de00e766ba17532e10dcf5d0fd31fa344920a9f7..7aaedf83ad22dcc1d2dd39a31cf7e08b7b6ba4d3 100644
  568. --- a/ui/gfx/mojom/ca_layer_params.mojom
  569. +++ b/ui/gfx/mojom/ca_layer_params.mojom
  570. @@ -18,5 +18,6 @@ struct CALayerParams {
  571. bool is_empty;
  572. CALayerContent content;
  573. gfx.mojom.Size pixel_size;
  574. + gfx.mojom.Rect damage;
  575. float scale_factor;
  576. };
  577. diff --git a/ui/gfx/mojom/ca_layer_params_mojom_traits.cc b/ui/gfx/mojom/ca_layer_params_mojom_traits.cc
  578. index d6ec9ef087f00d4c8d7c495b7e57a1d9c3c8b3bb..1b1aafcf75e422b4c94bdc8da895488245cdf360 100644
  579. --- a/ui/gfx/mojom/ca_layer_params_mojom_traits.cc
  580. +++ b/ui/gfx/mojom/ca_layer_params_mojom_traits.cc
  581. @@ -52,6 +52,9 @@ bool StructTraits<gfx::mojom::CALayerParamsDataView, gfx::CALayerParams>::Read(
  582. if (!data.ReadPixelSize(&out->pixel_size))
  583. return false;
  584. + if (!data.ReadDamage(&out->damage))
  585. + return false;
  586. +
  587. out->scale_factor = data.scale_factor();
  588. return true;
  589. }
  590. diff --git a/ui/gfx/mojom/ca_layer_params_mojom_traits.h b/ui/gfx/mojom/ca_layer_params_mojom_traits.h
  591. index 4cac766eae3161baedac4202f694129cd90c80de..0821495ad22944d8856bb750cac8912a2f8328c3 100644
  592. --- a/ui/gfx/mojom/ca_layer_params_mojom_traits.h
  593. +++ b/ui/gfx/mojom/ca_layer_params_mojom_traits.h
  594. @@ -20,6 +20,10 @@ struct StructTraits<gfx::mojom::CALayerParamsDataView, gfx::CALayerParams> {
  595. return ca_layer_params.pixel_size;
  596. }
  597. + static gfx::Rect damage(const gfx::CALayerParams& ca_layer_params) {
  598. + return ca_layer_params.damage;
  599. + }
  600. +
  601. static float scale_factor(const gfx::CALayerParams& ca_layer_params) {
  602. return ca_layer_params.scale_factor;
  603. }