osr_render_widget_host_view.cc 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  1. // Copyright (c) 2016 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/browser/osr/osr_render_widget_host_view.h"
  5. #include <algorithm>
  6. #include <memory>
  7. #include <utility>
  8. #include <vector>
  9. #include "base/functional/callback_helpers.h"
  10. #include "base/location.h"
  11. #include "base/memory/ptr_util.h"
  12. #include "base/memory/raw_ptr.h"
  13. #include "base/task/single_thread_task_runner.h"
  14. #include "base/time/time.h"
  15. #include "components/viz/common/features.h"
  16. #include "components/viz/common/frame_sinks/begin_frame_args.h"
  17. #include "components/viz/common/frame_sinks/copy_output_request.h"
  18. #include "components/viz/common/frame_sinks/delay_based_time_source.h"
  19. #include "components/viz/common/quads/compositor_render_pass.h"
  20. #include "content/browser/renderer_host/cursor_manager.h" // nogncheck
  21. #include "content/browser/renderer_host/input/synthetic_gesture_target.h" // nogncheck
  22. #include "content/browser/renderer_host/render_widget_host_delegate.h" // nogncheck
  23. #include "content/browser/renderer_host/render_widget_host_owner_delegate.h" // nogncheck
  24. #include "content/public/browser/browser_task_traits.h"
  25. #include "content/public/browser/browser_thread.h"
  26. #include "content/public/browser/context_factory.h"
  27. #include "content/public/browser/gpu_data_manager.h"
  28. #include "content/public/browser/render_process_host.h"
  29. #include "gpu/command_buffer/client/gl_helper.h"
  30. #include "media/base/video_frame.h"
  31. #include "third_party/abseil-cpp/absl/types/optional.h"
  32. #include "third_party/blink/public/common/input/web_input_event.h"
  33. #include "third_party/skia/include/core/SkCanvas.h"
  34. #include "ui/compositor/compositor.h"
  35. #include "ui/compositor/layer.h"
  36. #include "ui/compositor/layer_type.h"
  37. #include "ui/display/screen.h"
  38. #include "ui/events/base_event_utils.h"
  39. #include "ui/events/event_constants.h"
  40. #include "ui/gfx/canvas.h"
  41. #include "ui/gfx/geometry/dip_util.h"
  42. #include "ui/gfx/geometry/size_conversions.h"
  43. #include "ui/gfx/image/image_skia.h"
  44. #include "ui/gfx/native_widget_types.h"
  45. #include "ui/gfx/skbitmap_operations.h"
  46. #include "ui/latency/latency_info.h"
  47. namespace electron {
  48. namespace {
  49. const float kDefaultScaleFactor = 1.0;
  50. ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
  51. ui::EventType type = ui::EventType::ET_UNKNOWN;
  52. switch (event.GetType()) {
  53. case blink::WebInputEvent::Type::kMouseDown:
  54. type = ui::EventType::ET_MOUSE_PRESSED;
  55. break;
  56. case blink::WebInputEvent::Type::kMouseUp:
  57. type = ui::EventType::ET_MOUSE_RELEASED;
  58. break;
  59. case blink::WebInputEvent::Type::kMouseMove:
  60. type = ui::EventType::ET_MOUSE_MOVED;
  61. break;
  62. case blink::WebInputEvent::Type::kMouseEnter:
  63. type = ui::EventType::ET_MOUSE_ENTERED;
  64. break;
  65. case blink::WebInputEvent::Type::kMouseLeave:
  66. type = ui::EventType::ET_MOUSE_EXITED;
  67. break;
  68. case blink::WebInputEvent::Type::kMouseWheel:
  69. type = ui::EventType::ET_MOUSEWHEEL;
  70. break;
  71. default:
  72. type = ui::EventType::ET_UNKNOWN;
  73. break;
  74. }
  75. int button_flags = 0;
  76. switch (event.button) {
  77. case blink::WebMouseEvent::Button::kBack:
  78. button_flags |= ui::EF_BACK_MOUSE_BUTTON;
  79. break;
  80. case blink::WebMouseEvent::Button::kForward:
  81. button_flags |= ui::EF_FORWARD_MOUSE_BUTTON;
  82. break;
  83. case blink::WebMouseEvent::Button::kLeft:
  84. button_flags |= ui::EF_LEFT_MOUSE_BUTTON;
  85. break;
  86. case blink::WebMouseEvent::Button::kMiddle:
  87. button_flags |= ui::EF_MIDDLE_MOUSE_BUTTON;
  88. break;
  89. case blink::WebMouseEvent::Button::kRight:
  90. button_flags |= ui::EF_RIGHT_MOUSE_BUTTON;
  91. break;
  92. default:
  93. button_flags = 0;
  94. break;
  95. }
  96. ui::MouseEvent ui_event(type,
  97. gfx::Point(std::floor(event.PositionInWidget().x()),
  98. std::floor(event.PositionInWidget().y())),
  99. gfx::Point(std::floor(event.PositionInWidget().x()),
  100. std::floor(event.PositionInWidget().y())),
  101. ui::EventTimeForNow(), button_flags, button_flags);
  102. ui_event.SetClickCount(event.click_count);
  103. return ui_event;
  104. }
  105. ui::MouseWheelEvent UiMouseWheelEventFromWebMouseEvent(
  106. blink::WebMouseWheelEvent event) {
  107. return ui::MouseWheelEvent(UiMouseEventFromWebMouseEvent(event),
  108. std::floor(event.delta_x),
  109. std::floor(event.delta_y));
  110. }
  111. } // namespace
  112. class ElectronDelegatedFrameHostClient
  113. : public content::DelegatedFrameHostClient {
  114. public:
  115. explicit ElectronDelegatedFrameHostClient(OffScreenRenderWidgetHostView* view)
  116. : view_(view) {}
  117. // disable copy
  118. ElectronDelegatedFrameHostClient(const ElectronDelegatedFrameHostClient&) =
  119. delete;
  120. ElectronDelegatedFrameHostClient& operator=(
  121. const ElectronDelegatedFrameHostClient&) = delete;
  122. ui::Layer* DelegatedFrameHostGetLayer() const override {
  123. return view_->GetRootLayer();
  124. }
  125. bool DelegatedFrameHostIsVisible() const override {
  126. return view_->IsShowing();
  127. }
  128. SkColor DelegatedFrameHostGetGutterColor() const override {
  129. if (view_->render_widget_host()->delegate() &&
  130. view_->render_widget_host()->delegate()->IsFullscreen()) {
  131. return SK_ColorWHITE;
  132. }
  133. return *view_->GetBackgroundColor();
  134. }
  135. void OnFrameTokenChanged(uint32_t frame_token,
  136. base::TimeTicks activation_time) override {
  137. view_->render_widget_host()->DidProcessFrame(frame_token, activation_time);
  138. }
  139. float GetDeviceScaleFactor() const override {
  140. return view_->GetDeviceScaleFactor();
  141. }
  142. std::vector<viz::SurfaceId> CollectSurfaceIdsForEviction() override {
  143. return view_->render_widget_host()->CollectSurfaceIdsForEviction();
  144. }
  145. bool ShouldShowStaleContentOnEviction() override { return false; }
  146. void InvalidateLocalSurfaceIdOnEviction() override {}
  147. private:
  148. const raw_ptr<OffScreenRenderWidgetHostView> view_;
  149. };
  150. OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
  151. bool transparent,
  152. bool painting,
  153. int frame_rate,
  154. const OnPaintCallback& callback,
  155. content::RenderWidgetHost* host,
  156. OffScreenRenderWidgetHostView* parent_host_view,
  157. gfx::Size initial_size)
  158. : content::RenderWidgetHostViewBase(host),
  159. render_widget_host_(content::RenderWidgetHostImpl::From(host)),
  160. parent_host_view_(parent_host_view),
  161. transparent_(transparent),
  162. callback_(callback),
  163. frame_rate_(frame_rate),
  164. size_(initial_size),
  165. painting_(painting),
  166. cursor_manager_(std::make_unique<content::CursorManager>(this)),
  167. mouse_wheel_phase_handler_(this),
  168. backing_(std::make_unique<SkBitmap>()) {
  169. DCHECK(render_widget_host_);
  170. DCHECK(!render_widget_host_->GetView());
  171. // Initialize a screen_infos_ struct as needed, to cache the scale factor.
  172. if (screen_infos_.screen_infos.empty()) {
  173. UpdateScreenInfo();
  174. }
  175. screen_infos_.mutable_current().device_scale_factor = kDefaultScaleFactor;
  176. delegated_frame_host_allocator_.GenerateId();
  177. delegated_frame_host_surface_id_ =
  178. delegated_frame_host_allocator_.GetCurrentLocalSurfaceId();
  179. compositor_allocator_.GenerateId();
  180. compositor_surface_id_ = compositor_allocator_.GetCurrentLocalSurfaceId();
  181. delegated_frame_host_client_ =
  182. std::make_unique<ElectronDelegatedFrameHostClient>(this);
  183. delegated_frame_host_ = std::make_unique<content::DelegatedFrameHost>(
  184. AllocateFrameSinkId(), delegated_frame_host_client_.get(),
  185. true /* should_register_frame_sink_id */);
  186. root_layer_ = std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
  187. bool opaque = SkColorGetA(background_color_) == SK_AlphaOPAQUE;
  188. GetRootLayer()->SetFillsBoundsOpaquely(opaque);
  189. GetRootLayer()->SetColor(background_color_);
  190. ui::ContextFactory* context_factory = content::GetContextFactory();
  191. compositor_ = std::make_unique<ui::Compositor>(
  192. context_factory->AllocateFrameSinkId(), context_factory,
  193. base::SingleThreadTaskRunner::GetCurrentDefault(),
  194. false /* enable_pixel_canvas */,
  195. false /* use_external_begin_frame_control */);
  196. compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
  197. compositor_->SetDelegate(this);
  198. compositor_->SetRootLayer(root_layer_.get());
  199. ResizeRootLayer(false);
  200. render_widget_host_->SetView(this);
  201. if (content::GpuDataManager::GetInstance()->HardwareAccelerationEnabled()) {
  202. video_consumer_ = std::make_unique<OffScreenVideoConsumer>(
  203. this, base::BindRepeating(&OffScreenRenderWidgetHostView::OnPaint,
  204. weak_ptr_factory_.GetWeakPtr()));
  205. video_consumer_->SetActive(IsPainting());
  206. video_consumer_->SetFrameRate(GetFrameRate());
  207. }
  208. }
  209. OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() {
  210. // Marking the DelegatedFrameHost as removed from the window hierarchy is
  211. // necessary to remove all connections to its old ui::Compositor.
  212. if (is_showing_)
  213. delegated_frame_host_->WasHidden(
  214. content::DelegatedFrameHost::HiddenCause::kOther);
  215. delegated_frame_host_->DetachFromCompositor();
  216. delegated_frame_host_.reset();
  217. compositor_.reset();
  218. root_layer_.reset();
  219. }
  220. void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
  221. DCHECK(parent_host_view_);
  222. if (parent_host_view_->child_host_view_) {
  223. parent_host_view_->child_host_view_->CancelWidget();
  224. }
  225. parent_host_view_->set_child_host_view(this);
  226. parent_host_view_->Hide();
  227. ResizeRootLayer(false);
  228. SetPainting(parent_host_view_->IsPainting());
  229. }
  230. void OffScreenRenderWidgetHostView::SetSize(const gfx::Size& size) {
  231. size_ = size;
  232. SynchronizeVisualProperties();
  233. }
  234. void OffScreenRenderWidgetHostView::SetBounds(const gfx::Rect& new_bounds) {
  235. SetSize(new_bounds.size());
  236. }
  237. gfx::NativeView OffScreenRenderWidgetHostView::GetNativeView() {
  238. return gfx::NativeView();
  239. }
  240. gfx::NativeViewAccessible
  241. OffScreenRenderWidgetHostView::GetNativeViewAccessible() {
  242. return gfx::NativeViewAccessible();
  243. }
  244. ui::TextInputClient* OffScreenRenderWidgetHostView::GetTextInputClient() {
  245. return nullptr;
  246. }
  247. void OffScreenRenderWidgetHostView::Focus() {}
  248. bool OffScreenRenderWidgetHostView::HasFocus() {
  249. return false;
  250. }
  251. bool OffScreenRenderWidgetHostView::IsSurfaceAvailableForCopy() {
  252. return GetDelegatedFrameHost()->CanCopyFromCompositingSurface();
  253. }
  254. void OffScreenRenderWidgetHostView::ShowWithVisibility(
  255. content::PageVisibilityState /*page_visibility*/) {
  256. if (is_showing_)
  257. return;
  258. is_showing_ = true;
  259. delegated_frame_host_->AttachToCompositor(compositor_.get());
  260. delegated_frame_host_->WasShown(GetLocalSurfaceId(),
  261. GetRootLayer()->bounds().size(), {});
  262. if (render_widget_host_)
  263. render_widget_host_->WasShown({});
  264. }
  265. void OffScreenRenderWidgetHostView::Hide() {
  266. if (!is_showing_)
  267. return;
  268. if (render_widget_host_)
  269. render_widget_host_->WasHidden();
  270. // TODO(deermichel): correct or kOther?
  271. GetDelegatedFrameHost()->WasHidden(
  272. content::DelegatedFrameHost::HiddenCause::kOccluded);
  273. GetDelegatedFrameHost()->DetachFromCompositor();
  274. is_showing_ = false;
  275. }
  276. bool OffScreenRenderWidgetHostView::IsShowing() {
  277. return is_showing_;
  278. }
  279. void OffScreenRenderWidgetHostView::EnsureSurfaceSynchronizedForWebTest() {
  280. ++latest_capture_sequence_number_;
  281. SynchronizeVisualProperties();
  282. }
  283. gfx::Rect OffScreenRenderWidgetHostView::GetViewBounds() {
  284. if (IsPopupWidget())
  285. return popup_position_;
  286. return gfx::Rect(size_);
  287. }
  288. void OffScreenRenderWidgetHostView::SetBackgroundColor(SkColor color) {
  289. // The renderer will feed its color back to us with the first CompositorFrame.
  290. // We short-cut here to show a sensible color before that happens.
  291. UpdateBackgroundColorFromRenderer(color);
  292. if (render_widget_host_ && render_widget_host_->owner_delegate()) {
  293. render_widget_host_->owner_delegate()->SetBackgroundOpaque(
  294. SkColorGetA(color) == SK_AlphaOPAQUE);
  295. }
  296. }
  297. absl::optional<SkColor> OffScreenRenderWidgetHostView::GetBackgroundColor() {
  298. return background_color_;
  299. }
  300. void OffScreenRenderWidgetHostView::UpdateBackgroundColor() {}
  301. gfx::Size OffScreenRenderWidgetHostView::GetVisibleViewportSize() {
  302. return size_;
  303. }
  304. void OffScreenRenderWidgetHostView::SetInsets(const gfx::Insets& insets) {}
  305. blink::mojom::PointerLockResult OffScreenRenderWidgetHostView::LockMouse(
  306. bool request_unadjusted_movement) {
  307. return blink::mojom::PointerLockResult::kUnsupportedOptions;
  308. }
  309. blink::mojom::PointerLockResult OffScreenRenderWidgetHostView::ChangeMouseLock(
  310. bool request_unadjusted_movement) {
  311. return blink::mojom::PointerLockResult::kUnsupportedOptions;
  312. }
  313. void OffScreenRenderWidgetHostView::UnlockMouse() {}
  314. void OffScreenRenderWidgetHostView::TakeFallbackContentFrom(
  315. content::RenderWidgetHostView* view) {
  316. DCHECK(!static_cast<content::RenderWidgetHostViewBase*>(view)
  317. ->IsRenderWidgetHostViewChildFrame());
  318. auto* view_osr = static_cast<OffScreenRenderWidgetHostView*>(view);
  319. SetBackgroundColor(view_osr->background_color_);
  320. if (GetDelegatedFrameHost() && view_osr->GetDelegatedFrameHost()) {
  321. GetDelegatedFrameHost()->TakeFallbackContentFrom(
  322. view_osr->GetDelegatedFrameHost());
  323. }
  324. }
  325. void OffScreenRenderWidgetHostView::ResetFallbackToFirstNavigationSurface() {
  326. GetDelegatedFrameHost()->ResetFallbackToFirstNavigationSurface();
  327. }
  328. void OffScreenRenderWidgetHostView::InitAsPopup(
  329. content::RenderWidgetHostView* parent_host_view,
  330. const gfx::Rect& bounds,
  331. const gfx::Rect& anchor_rect) {
  332. DCHECK_EQ(parent_host_view_, parent_host_view);
  333. DCHECK_EQ(widget_type_, content::WidgetType::kPopup);
  334. if (parent_host_view_->popup_host_view_) {
  335. parent_host_view_->popup_host_view_->CancelWidget();
  336. }
  337. parent_host_view_->set_popup_host_view(this);
  338. parent_callback_ =
  339. base::BindRepeating(&OffScreenRenderWidgetHostView::OnPopupPaint,
  340. parent_host_view_->weak_ptr_factory_.GetWeakPtr());
  341. popup_position_ = bounds;
  342. ResizeRootLayer(true);
  343. SetPainting(parent_host_view_->IsPainting());
  344. Show();
  345. }
  346. void OffScreenRenderWidgetHostView::UpdateCursor(const ui::Cursor&) {}
  347. content::CursorManager* OffScreenRenderWidgetHostView::GetCursorManager() {
  348. return cursor_manager_.get();
  349. }
  350. void OffScreenRenderWidgetHostView::SetIsLoading(bool loading) {}
  351. void OffScreenRenderWidgetHostView::TextInputStateChanged(
  352. const ui::mojom::TextInputState& params) {}
  353. void OffScreenRenderWidgetHostView::ImeCancelComposition() {}
  354. void OffScreenRenderWidgetHostView::RenderProcessGone() {
  355. Destroy();
  356. }
  357. void OffScreenRenderWidgetHostView::Destroy() {
  358. if (!is_destroyed_) {
  359. is_destroyed_ = true;
  360. if (parent_host_view_ != nullptr) {
  361. CancelWidget();
  362. } else {
  363. if (popup_host_view_)
  364. popup_host_view_->CancelWidget();
  365. if (child_host_view_)
  366. child_host_view_->CancelWidget();
  367. if (!guest_host_views_.empty()) {
  368. // Guest RWHVs will be destroyed when the associated RWHVGuest is
  369. // destroyed. This parent RWHV may be destroyed first, so disassociate
  370. // the guest RWHVs here without destroying them.
  371. for (auto* guest_host_view : guest_host_views_)
  372. guest_host_view->parent_host_view_ = nullptr;
  373. guest_host_views_.clear();
  374. }
  375. for (auto* proxy_view : proxy_views_)
  376. proxy_view->RemoveObserver();
  377. Hide();
  378. }
  379. }
  380. delete this;
  381. }
  382. void OffScreenRenderWidgetHostView::UpdateTooltipUnderCursor(
  383. const std::u16string&) {}
  384. uint32_t OffScreenRenderWidgetHostView::GetCaptureSequenceNumber() const {
  385. return latest_capture_sequence_number_;
  386. }
  387. void OffScreenRenderWidgetHostView::CopyFromSurface(
  388. const gfx::Rect& src_rect,
  389. const gfx::Size& output_size,
  390. base::OnceCallback<void(const SkBitmap&)> callback) {
  391. GetDelegatedFrameHost()->CopyFromCompositingSurface(src_rect, output_size,
  392. std::move(callback));
  393. }
  394. display::ScreenInfo OffScreenRenderWidgetHostView::GetScreenInfo() const {
  395. display::ScreenInfo screen_info;
  396. screen_info.depth = 24;
  397. screen_info.depth_per_component = 8;
  398. screen_info.orientation_angle = 0;
  399. screen_info.device_scale_factor = GetDeviceScaleFactor();
  400. screen_info.orientation_type =
  401. display::mojom::ScreenOrientation::kLandscapePrimary;
  402. screen_info.rect = gfx::Rect(size_);
  403. screen_info.available_rect = gfx::Rect(size_);
  404. return screen_info;
  405. }
  406. void OffScreenRenderWidgetHostView::TransformPointToRootSurface(
  407. gfx::PointF* point) {}
  408. gfx::Rect OffScreenRenderWidgetHostView::GetBoundsInRootWindow() {
  409. return gfx::Rect(size_);
  410. }
  411. absl::optional<content::DisplayFeature>
  412. OffScreenRenderWidgetHostView::GetDisplayFeature() {
  413. return absl::nullopt;
  414. }
  415. void OffScreenRenderWidgetHostView::SetDisplayFeatureForTesting(
  416. const content::DisplayFeature* display_feature) {}
  417. viz::SurfaceId OffScreenRenderWidgetHostView::GetCurrentSurfaceId() const {
  418. return GetDelegatedFrameHost()
  419. ? GetDelegatedFrameHost()->GetCurrentSurfaceId()
  420. : viz::SurfaceId();
  421. }
  422. std::unique_ptr<content::SyntheticGestureTarget>
  423. OffScreenRenderWidgetHostView::CreateSyntheticGestureTarget() {
  424. NOTIMPLEMENTED();
  425. return nullptr;
  426. }
  427. void OffScreenRenderWidgetHostView::ImeCompositionRangeChanged(
  428. const gfx::Range&,
  429. const absl::optional<std::vector<gfx::Rect>>& character_bounds,
  430. const absl::optional<std::vector<gfx::Rect>>& line_bounds) {}
  431. gfx::Size OffScreenRenderWidgetHostView::GetCompositorViewportPixelSize() {
  432. return gfx::ScaleToCeiledSize(GetRequestedRendererSize(),
  433. GetDeviceScaleFactor());
  434. }
  435. ui::Compositor* OffScreenRenderWidgetHostView::GetCompositor() {
  436. return compositor_.get();
  437. }
  438. content::RenderWidgetHostViewBase*
  439. OffScreenRenderWidgetHostView::CreateViewForWidget(
  440. content::RenderWidgetHost* render_widget_host,
  441. content::RenderWidgetHost* embedder_render_widget_host,
  442. content::WebContentsView* web_contents_view) {
  443. if (render_widget_host->GetView()) {
  444. return static_cast<content::RenderWidgetHostViewBase*>(
  445. render_widget_host->GetView());
  446. }
  447. OffScreenRenderWidgetHostView* embedder_host_view = nullptr;
  448. if (embedder_render_widget_host) {
  449. embedder_host_view = static_cast<OffScreenRenderWidgetHostView*>(
  450. embedder_render_widget_host->GetView());
  451. }
  452. return new OffScreenRenderWidgetHostView(
  453. transparent_, true, embedder_host_view->GetFrameRate(), callback_,
  454. render_widget_host, embedder_host_view, size());
  455. }
  456. const viz::FrameSinkId& OffScreenRenderWidgetHostView::GetFrameSinkId() const {
  457. return GetDelegatedFrameHost()->frame_sink_id();
  458. }
  459. void OffScreenRenderWidgetHostView::DidNavigate() {
  460. ResizeRootLayer(true);
  461. if (delegated_frame_host_)
  462. delegated_frame_host_->DidNavigate();
  463. }
  464. bool OffScreenRenderWidgetHostView::TransformPointToCoordSpaceForView(
  465. const gfx::PointF& point,
  466. RenderWidgetHostViewBase* target_view,
  467. gfx::PointF* transformed_point) {
  468. if (target_view == this) {
  469. *transformed_point = point;
  470. return true;
  471. }
  472. return false;
  473. }
  474. void OffScreenRenderWidgetHostView::CancelWidget() {
  475. if (render_widget_host_)
  476. render_widget_host_->LostCapture();
  477. Hide();
  478. if (parent_host_view_) {
  479. if (parent_host_view_->popup_host_view_ == this) {
  480. parent_host_view_->set_popup_host_view(nullptr);
  481. } else if (parent_host_view_->child_host_view_ == this) {
  482. parent_host_view_->set_child_host_view(nullptr);
  483. parent_host_view_->Show();
  484. } else {
  485. parent_host_view_->RemoveGuestHostView(this);
  486. }
  487. parent_host_view_ = nullptr;
  488. }
  489. if (render_widget_host_ && !is_destroyed_) {
  490. is_destroyed_ = true;
  491. // Results in a call to Destroy().
  492. render_widget_host_->ShutdownAndDestroyWidget(true);
  493. }
  494. }
  495. void OffScreenRenderWidgetHostView::AddGuestHostView(
  496. OffScreenRenderWidgetHostView* guest_host) {
  497. guest_host_views_.insert(guest_host);
  498. }
  499. void OffScreenRenderWidgetHostView::RemoveGuestHostView(
  500. OffScreenRenderWidgetHostView* guest_host) {
  501. guest_host_views_.erase(guest_host);
  502. }
  503. void OffScreenRenderWidgetHostView::AddViewProxy(OffscreenViewProxy* proxy) {
  504. proxy->SetObserver(this);
  505. proxy_views_.insert(proxy);
  506. }
  507. void OffScreenRenderWidgetHostView::RemoveViewProxy(OffscreenViewProxy* proxy) {
  508. proxy->RemoveObserver();
  509. proxy_views_.erase(proxy);
  510. }
  511. void OffScreenRenderWidgetHostView::ProxyViewDestroyed(
  512. OffscreenViewProxy* proxy) {
  513. proxy_views_.erase(proxy);
  514. Invalidate();
  515. }
  516. bool OffScreenRenderWidgetHostView::IsOffscreen() const {
  517. return true;
  518. }
  519. std::unique_ptr<viz::HostDisplayClient>
  520. OffScreenRenderWidgetHostView::CreateHostDisplayClient(
  521. ui::Compositor* compositor) {
  522. host_display_client_ = new OffScreenHostDisplayClient(
  523. gfx::kNullAcceleratedWidget,
  524. base::BindRepeating(&OffScreenRenderWidgetHostView::OnPaint,
  525. weak_ptr_factory_.GetWeakPtr()));
  526. host_display_client_->SetActive(IsPainting());
  527. return base::WrapUnique(host_display_client_.get());
  528. }
  529. bool OffScreenRenderWidgetHostView::InstallTransparency() {
  530. if (transparent_) {
  531. SetBackgroundColor(SkColor());
  532. compositor_->SetBackgroundColor(SK_ColorTRANSPARENT);
  533. return true;
  534. }
  535. return false;
  536. }
  537. #if BUILDFLAG(IS_MAC)
  538. void OffScreenRenderWidgetHostView::SetActive(bool active) {}
  539. void OffScreenRenderWidgetHostView::ShowDefinitionForSelection() {}
  540. void OffScreenRenderWidgetHostView::SpeakSelection() {}
  541. void OffScreenRenderWidgetHostView::SetWindowFrameInScreen(
  542. const gfx::Rect& rect) {}
  543. void OffScreenRenderWidgetHostView::ShowSharePicker(
  544. const std::string& title,
  545. const std::string& text,
  546. const std::string& url,
  547. const std::vector<std::string>& file_paths,
  548. blink::mojom::ShareService::ShareCallback callback) {}
  549. bool OffScreenRenderWidgetHostView::UpdateNSViewAndDisplay() {
  550. return false;
  551. }
  552. #endif
  553. void OffScreenRenderWidgetHostView::OnPaint(const gfx::Rect& damage_rect,
  554. const SkBitmap& bitmap) {
  555. backing_ = std::make_unique<SkBitmap>();
  556. backing_->allocN32Pixels(bitmap.width(), bitmap.height(), !transparent_);
  557. bitmap.readPixels(backing_->pixmap());
  558. if (IsPopupWidget() && parent_callback_) {
  559. parent_callback_.Run(this->popup_position_);
  560. } else {
  561. CompositeFrame(damage_rect);
  562. }
  563. }
  564. gfx::Size OffScreenRenderWidgetHostView::SizeInPixels() {
  565. float sf = GetDeviceScaleFactor();
  566. return gfx::ToFlooredSize(
  567. gfx::ConvertSizeToPixels(GetViewBounds().size(), sf));
  568. }
  569. void OffScreenRenderWidgetHostView::CompositeFrame(
  570. const gfx::Rect& damage_rect) {
  571. HoldResize();
  572. gfx::Size size_in_pixels = SizeInPixels();
  573. SkBitmap frame;
  574. // Optimize for the case when there is no popup
  575. if (proxy_views_.empty() && !popup_host_view_) {
  576. frame = GetBacking();
  577. } else {
  578. float sf = GetDeviceScaleFactor();
  579. frame.allocN32Pixels(size_in_pixels.width(), size_in_pixels.height(),
  580. false);
  581. if (!GetBacking().drawsNothing()) {
  582. SkCanvas canvas(frame);
  583. canvas.writePixels(GetBacking(), 0, 0);
  584. if (popup_host_view_ && !popup_host_view_->GetBacking().drawsNothing()) {
  585. gfx::Rect rect = popup_host_view_->popup_position_;
  586. gfx::Point origin_in_pixels =
  587. gfx::ToFlooredPoint(gfx::ConvertPointToPixels(rect.origin(), sf));
  588. canvas.writePixels(popup_host_view_->GetBacking(), origin_in_pixels.x(),
  589. origin_in_pixels.y());
  590. }
  591. for (auto* proxy_view : proxy_views_) {
  592. gfx::Rect rect = proxy_view->GetBounds();
  593. gfx::Point origin_in_pixels =
  594. gfx::ToFlooredPoint(gfx::ConvertPointToPixels(rect.origin(), sf));
  595. canvas.writePixels(*proxy_view->GetBitmap(), origin_in_pixels.x(),
  596. origin_in_pixels.y());
  597. }
  598. }
  599. }
  600. callback_.Run(gfx::IntersectRects(gfx::Rect(size_in_pixels), damage_rect),
  601. frame);
  602. ReleaseResize();
  603. }
  604. void OffScreenRenderWidgetHostView::OnPopupPaint(const gfx::Rect& damage_rect) {
  605. InvalidateBounds(gfx::ToEnclosingRect(
  606. gfx::ConvertRectToPixels(damage_rect, GetDeviceScaleFactor())));
  607. }
  608. void OffScreenRenderWidgetHostView::OnProxyViewPaint(
  609. const gfx::Rect& damage_rect) {
  610. InvalidateBounds(gfx::ToEnclosingRect(
  611. gfx::ConvertRectToPixels(damage_rect, GetDeviceScaleFactor())));
  612. }
  613. void OffScreenRenderWidgetHostView::HoldResize() {
  614. if (!hold_resize_)
  615. hold_resize_ = true;
  616. }
  617. void OffScreenRenderWidgetHostView::ReleaseResize() {
  618. if (!hold_resize_)
  619. return;
  620. hold_resize_ = false;
  621. if (pending_resize_) {
  622. pending_resize_ = false;
  623. content::GetUIThreadTaskRunner({})->PostTask(
  624. FROM_HERE,
  625. base::BindOnce(
  626. &OffScreenRenderWidgetHostView::SynchronizeVisualProperties,
  627. weak_ptr_factory_.GetWeakPtr()));
  628. }
  629. }
  630. void OffScreenRenderWidgetHostView::SynchronizeVisualProperties() {
  631. if (hold_resize_) {
  632. if (!pending_resize_)
  633. pending_resize_ = true;
  634. return;
  635. }
  636. ResizeRootLayer(true);
  637. }
  638. void OffScreenRenderWidgetHostView::SendMouseEvent(
  639. const blink::WebMouseEvent& event) {
  640. for (auto* proxy_view : proxy_views_) {
  641. gfx::Rect bounds = proxy_view->GetBounds();
  642. if (bounds.Contains(event.PositionInWidget().x(),
  643. event.PositionInWidget().y())) {
  644. blink::WebMouseEvent proxy_event(event);
  645. proxy_event.SetPositionInWidget(
  646. proxy_event.PositionInWidget().x() - bounds.x(),
  647. proxy_event.PositionInWidget().y() - bounds.y());
  648. ui::MouseEvent ui_event = UiMouseEventFromWebMouseEvent(proxy_event);
  649. proxy_view->OnEvent(&ui_event);
  650. return;
  651. }
  652. }
  653. if (!IsPopupWidget()) {
  654. if (popup_host_view_ &&
  655. popup_host_view_->popup_position_.Contains(
  656. event.PositionInWidget().x(), event.PositionInWidget().y())) {
  657. blink::WebMouseEvent popup_event(event);
  658. popup_event.SetPositionInWidget(
  659. popup_event.PositionInWidget().x() -
  660. popup_host_view_->popup_position_.x(),
  661. popup_event.PositionInWidget().y() -
  662. popup_host_view_->popup_position_.y());
  663. popup_host_view_->ProcessMouseEvent(popup_event, ui::LatencyInfo());
  664. return;
  665. }
  666. }
  667. if (!render_widget_host_)
  668. return;
  669. render_widget_host_->ForwardMouseEvent(event);
  670. }
  671. void OffScreenRenderWidgetHostView::SendMouseWheelEvent(
  672. const blink::WebMouseWheelEvent& event) {
  673. for (auto* proxy_view : proxy_views_) {
  674. gfx::Rect bounds = proxy_view->GetBounds();
  675. if (bounds.Contains(event.PositionInWidget().x(),
  676. event.PositionInWidget().y())) {
  677. blink::WebMouseWheelEvent proxy_event(event);
  678. proxy_event.SetPositionInWidget(
  679. proxy_event.PositionInWidget().x() - bounds.x(),
  680. proxy_event.PositionInWidget().y() - bounds.y());
  681. ui::MouseWheelEvent ui_event =
  682. UiMouseWheelEventFromWebMouseEvent(proxy_event);
  683. proxy_view->OnEvent(&ui_event);
  684. return;
  685. }
  686. }
  687. blink::WebMouseWheelEvent mouse_wheel_event(event);
  688. bool should_route_event =
  689. render_widget_host_->delegate() &&
  690. render_widget_host_->delegate()->GetInputEventRouter();
  691. mouse_wheel_phase_handler_.SendWheelEndForTouchpadScrollingIfNeeded(
  692. should_route_event);
  693. mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
  694. mouse_wheel_event, false);
  695. if (!IsPopupWidget()) {
  696. if (popup_host_view_) {
  697. if (popup_host_view_->popup_position_.Contains(
  698. mouse_wheel_event.PositionInWidget().x(),
  699. mouse_wheel_event.PositionInWidget().y())) {
  700. blink::WebMouseWheelEvent popup_mouse_wheel_event(mouse_wheel_event);
  701. popup_mouse_wheel_event.SetPositionInWidget(
  702. mouse_wheel_event.PositionInWidget().x() -
  703. popup_host_view_->popup_position_.x(),
  704. mouse_wheel_event.PositionInWidget().y() -
  705. popup_host_view_->popup_position_.y());
  706. popup_mouse_wheel_event.SetPositionInScreen(
  707. popup_mouse_wheel_event.PositionInWidget().x(),
  708. popup_mouse_wheel_event.PositionInWidget().y());
  709. popup_host_view_->SendMouseWheelEvent(popup_mouse_wheel_event);
  710. return;
  711. } else {
  712. // Scrolling outside of the popup widget so destroy it.
  713. // Execute asynchronously to avoid deleting the widget from inside some
  714. // other callback.
  715. content::GetUIThreadTaskRunner({})->PostTask(
  716. FROM_HERE,
  717. base::BindOnce(&OffScreenRenderWidgetHostView::CancelWidget,
  718. popup_host_view_->weak_ptr_factory_.GetWeakPtr()));
  719. }
  720. } else if (!guest_host_views_.empty()) {
  721. for (auto* guest_host_view : guest_host_views_) {
  722. if (!guest_host_view->render_widget_host_ ||
  723. !guest_host_view->render_widget_host_->GetView()) {
  724. continue;
  725. }
  726. const gfx::Rect& guest_bounds =
  727. guest_host_view->render_widget_host_->GetView()->GetViewBounds();
  728. if (guest_bounds.Contains(mouse_wheel_event.PositionInWidget().x(),
  729. mouse_wheel_event.PositionInWidget().y())) {
  730. blink::WebMouseWheelEvent guest_mouse_wheel_event(mouse_wheel_event);
  731. guest_mouse_wheel_event.SetPositionInWidget(
  732. mouse_wheel_event.PositionInWidget().x() - guest_bounds.x(),
  733. mouse_wheel_event.PositionInWidget().y() - guest_bounds.y());
  734. guest_mouse_wheel_event.SetPositionInScreen(
  735. guest_mouse_wheel_event.PositionInWidget().x(),
  736. guest_mouse_wheel_event.PositionInWidget().y());
  737. guest_host_view->SendMouseWheelEvent(guest_mouse_wheel_event);
  738. return;
  739. }
  740. }
  741. }
  742. }
  743. if (!render_widget_host_)
  744. return;
  745. render_widget_host_->ForwardWheelEvent(event);
  746. }
  747. void OffScreenRenderWidgetHostView::SetPainting(bool painting) {
  748. painting_ = painting;
  749. if (popup_host_view_) {
  750. popup_host_view_->SetPainting(painting);
  751. }
  752. for (auto* guest_host_view : guest_host_views_)
  753. guest_host_view->SetPainting(painting);
  754. if (video_consumer_) {
  755. video_consumer_->SetActive(IsPainting());
  756. } else if (host_display_client_) {
  757. host_display_client_->SetActive(IsPainting());
  758. }
  759. }
  760. bool OffScreenRenderWidgetHostView::IsPainting() const {
  761. return painting_;
  762. }
  763. void OffScreenRenderWidgetHostView::SetFrameRate(int frame_rate) {
  764. if (parent_host_view_) {
  765. if (parent_host_view_->GetFrameRate() == GetFrameRate())
  766. return;
  767. frame_rate_ = parent_host_view_->GetFrameRate();
  768. } else {
  769. if (frame_rate <= 0)
  770. frame_rate = 1;
  771. if (frame_rate > 240)
  772. frame_rate = 240;
  773. frame_rate_ = frame_rate;
  774. }
  775. SetupFrameRate(true);
  776. if (video_consumer_) {
  777. video_consumer_->SetFrameRate(GetFrameRate());
  778. }
  779. for (auto* guest_host_view : guest_host_views_)
  780. guest_host_view->SetFrameRate(frame_rate);
  781. }
  782. int OffScreenRenderWidgetHostView::GetFrameRate() const {
  783. return frame_rate_;
  784. }
  785. ui::Layer* OffScreenRenderWidgetHostView::GetRootLayer() const {
  786. return root_layer_.get();
  787. }
  788. const viz::LocalSurfaceId& OffScreenRenderWidgetHostView::GetLocalSurfaceId()
  789. const {
  790. return delegated_frame_host_surface_id_;
  791. }
  792. content::DelegatedFrameHost*
  793. OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const {
  794. return delegated_frame_host_.get();
  795. }
  796. void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
  797. if (!force && frame_rate_threshold_us_ != 0)
  798. return;
  799. frame_rate_threshold_us_ = 1000000 / frame_rate_;
  800. if (compositor_) {
  801. compositor_->SetDisplayVSyncParameters(
  802. base::TimeTicks::Now(), base::Microseconds(frame_rate_threshold_us_));
  803. }
  804. }
  805. void OffScreenRenderWidgetHostView::Invalidate() {
  806. InvalidateBounds(gfx::Rect(GetRequestedRendererSize()));
  807. }
  808. void OffScreenRenderWidgetHostView::InvalidateBounds(const gfx::Rect& bounds) {
  809. CompositeFrame(bounds);
  810. }
  811. void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
  812. SetupFrameRate(false);
  813. display::Display display =
  814. display::Screen::GetScreen()->GetDisplayNearestView(GetNativeView());
  815. const float scaleFactor = display.device_scale_factor();
  816. float sf = GetDeviceScaleFactor();
  817. const bool sf_did_change = scaleFactor != sf;
  818. // Initialize a screen_infos_ struct as needed, to cache the scale factor.
  819. if (screen_infos_.screen_infos.empty()) {
  820. UpdateScreenInfo();
  821. }
  822. screen_infos_.mutable_current().device_scale_factor = scaleFactor;
  823. gfx::Size size = GetViewBounds().size();
  824. if (!force && !sf_did_change && size == GetRootLayer()->bounds().size())
  825. return;
  826. GetRootLayer()->SetBounds(gfx::Rect(size));
  827. const gfx::Size& size_in_pixels =
  828. gfx::ToFlooredSize(gfx::ConvertSizeToPixels(size, sf));
  829. if (compositor_) {
  830. compositor_allocator_.GenerateId();
  831. compositor_surface_id_ = compositor_allocator_.GetCurrentLocalSurfaceId();
  832. compositor_->SetScaleAndSize(sf, size_in_pixels, compositor_surface_id_);
  833. }
  834. delegated_frame_host_allocator_.GenerateId();
  835. delegated_frame_host_surface_id_ =
  836. delegated_frame_host_allocator_.GetCurrentLocalSurfaceId();
  837. GetDelegatedFrameHost()->EmbedSurface(
  838. delegated_frame_host_surface_id_, size,
  839. cc::DeadlinePolicy::UseDefaultDeadline());
  840. // Note that |render_widget_host_| will retrieve resize parameters from the
  841. // DelegatedFrameHost, so it must have SynchronizeVisualProperties called
  842. // after.
  843. if (render_widget_host_) {
  844. render_widget_host_->SynchronizeVisualProperties();
  845. }
  846. }
  847. viz::FrameSinkId OffScreenRenderWidgetHostView::AllocateFrameSinkId() {
  848. return viz::FrameSinkId(
  849. base::checked_cast<uint32_t>(render_widget_host_->GetProcess()->GetID()),
  850. base::checked_cast<uint32_t>(render_widget_host_->GetRoutingID()));
  851. }
  852. void OffScreenRenderWidgetHostView::UpdateBackgroundColorFromRenderer(
  853. SkColor color) {
  854. if (color == background_color_)
  855. return;
  856. background_color_ = color;
  857. bool opaque = SkColorGetA(color) == SK_AlphaOPAQUE;
  858. GetRootLayer()->SetFillsBoundsOpaquely(opaque);
  859. GetRootLayer()->SetColor(color);
  860. }
  861. void OffScreenRenderWidgetHostView::NotifyHostAndDelegateOnWasShown(
  862. blink::mojom::RecordContentToVisibleTimeRequestPtr) {
  863. NOTREACHED();
  864. }
  865. void OffScreenRenderWidgetHostView::
  866. RequestSuccessfulPresentationTimeFromHostOrDelegate(
  867. blink::mojom::RecordContentToVisibleTimeRequestPtr) {
  868. NOTREACHED();
  869. }
  870. void OffScreenRenderWidgetHostView::
  871. CancelSuccessfulPresentationTimeRequestForHostAndDelegate() {
  872. NOTREACHED();
  873. }
  874. } // namespace electron