* chore: bump chromium in DEPS to 142.0.7432.2 * chore: bump chromium in DEPS to 142.0.7434.1 * chore: bump chromium in DEPS to 142.0.7436.1 * chore: bump chromium in DEPS to 142.0.7438.1 * chore: bump chromium in DEPS to 142.0.7440.1 * chore: bump chromium in DEPS to 142.0.7442.1 * chore: bump chromium in DEPS to 142.0.7444.1 * chore: bump chromium in DEPS to 142.0.7444.6 * chore: bump chromium in DEPS to 142.0.7444.3 * 6973697: Use type tags for data stored in V8 internal fields https://chromium-review.googlesource.com/c/chromium/src/+/6973697 * chore: update patches * chore: update filenames.libcxx.gni * fix: parse macOS SDK version across line break https://chromium-review.googlesource.com/c/chromium/src/+/6980166 (cherry picked from commit 2bcbb33de04fa13e7c923b2420f89c3846f5988b) * fix: replace v8::Object::SetPrototype() usage https://chromium-review.googlesource.com/c/v8/v8/+/6983465 https://github.com/nodejs/node/pull/55453 (cherry picked from commit c31b9ed5ac84bbd111c72273d9334af6c50ed374) * fix: replace additional usages of SetPrototype https://chromium-review.googlesource.com/c/v8/v8/+/6983465 (cherry picked from commit bf151e9d28520c7dd74cba62240acbcaaab5433d) * fixup! fix: replace additional usages of SetPrototype https://chromium-review.googlesource.com/c/v8/v8/+/6983465 (cherry picked from commit f4434755b82b098e4d83d42bab26f183b6824f99) * build: use macos 15 minimum https://chromium-review.googlesource.com/c/chromium/src/+/6980166 (cherry picked from commit 4d2b5d7b2cf9a1786cdb1a77bf73e4ad0d3e45d1) * fixup! build: use macos 15 minimum https://chromium-review.googlesource.com/c/chromium/src/+/6980166 (cherry picked from commit 94bb41a66330dcaf6b92c80cfefd72759405793d) * ci: ignore missing dir for strip_universal_deep (cherry picked from commit 634963f171bc5f6050151f76973e7ffbab0e00cf) * chore: update patches * chore: update patches * chore: bump chromium in DEPS to 142.0.7444.23 * fix: disable C++ modules in electron_lib builds https://chromium-review.googlesource.com/c/chromium/src/+/6950738 (cherry picked from commit 6207c79aecae04675b1e258ec14025c3ddfdf270) * Revert "build: use macos 15 minimum" This reverts commit 2fc12d6acc1b24f3cbd0adb03122bf6b21eb14b9. Initially this change was made to test if it fixes libcxx compilation issues. As that's now resolved by disabling libcxx modules, this can be reverted. (cherry picked from commit ad52007d5baffc3da65c0a994943f25da0c3f1c2) * fix: js2c compilation failure https://chromium-review.googlesource.com/c/chromium/src/+/6950738 See patch description explaining MacOS 26 SDK headers incompatibility. (cherry picked from commit 39e2470875cdbf20b86c30ee2c5caa8845465434) * fix: disable C++ modules in libnode builds (cherry picked from commit fd0a7b61a151c92729da41eba63fb7ee5b0beebc) * fixup! fix: replace v8::Object::SetPrototype() usage https://chromium-review.googlesource.com/c/v8/v8/+/6983465 https://github.com/nodejs/node/pull/55453 (cherry picked from commit 2f52159b71ee4aa779dfd3e3050f3b09c2664c36) * build: switch to macos-15 runner build/mac/find_sdk.py now requires macOS 15 SDK as a minimum version. The macos 15 runners default to an Xcode using the 15 SDK and removes older versions. (cherry picked from commit e368703f24577e73d904c684a0b4ae53bacfaef2) * chore: update patches * fix: partially revert is_headless_mode removal https://chromium-review.googlesource.com/c/chromium/src/+/6955633 This patch should likely be reworked. For now, this partially reverts the removal of a required class property to restore behavior. (cherry picked from commit aff3bf9a244608863bc96b3e2aef911158b29574) * 6938086: Rename native_widget_types.h -> native_ui_types.h | https://chromium-review.googlesource.com/c/chromium/src/+/6938086 (cherry picked from commit c95ac7bf2b1eda493167b8e36c59d70d86d51429) * 6973697: Use type tags for data stored in V8 internal fields https://chromium-review.googlesource.com/c/chromium/src/+/6973697 * fixup! fix: check new forced colors enum value https://chromium-review.googlesource.com/c/chromium/src/+/6944403 (cherry picked from commit 0829c74b2fbcdf03ca462b4b0b76efd727d3d891) * fix: check new forced colors enum value https://chromium-review.googlesource.com/c/chromium/src/+/6944403 (cherry picked from commit d5858798074719d19d041fa291c3fd1af8d17f5d) * feat: add new memory-eviction exit reason https://chromium-review.googlesource.com/c/chromium/src/+/6991933 (cherry picked from commit 6e63197a2292aece65cd52b7b849d3ff3d10bb90) * fix: views::NonClientFrameView -> views::FrameView https://chromium-review.googlesource.com/c/chromium/src/+/7005027 https://chromium-review.googlesource.com/c/chromium/src/+/6966937 (cherry picked from commit 1e86b6ddfb2d19b5bfe30e7539f0a377ffa907ab) * fix: migrate NetworkConditions -> MatchedNetworkConditions https://chromium-review.googlesource.com/c/chromium/src/+/6827307 (cherry picked from commit 97100ac1682053d3447e63ed5f03dc2d9938e6ca) * fix: provide DeviceEmulationCacheBehavior param https://chromium-review.googlesource.com/c/chromium/src/+/6965238 (cherry picked from commit f9a08c53846ab269c57c14eae6b1c03b163fb30c) * fix: add missing image_skia include https://chromium-review.googlesource.com/c/chromium/src/+/6986762 (cherry picked from commit dd5eaf03fd7fbfd49afbe3259c5bf036be566bd9) * fixup! fix: add missing image_skia include https://chromium-review.googlesource.com/c/chromium/src/+/6986762 (cherry picked from commit 249c4d4de1df4d1588d6fa6fcf5f33b43a6c0f62) * 6948286: [wasm-imported-strings] Drop feature flag https://chromium-review.googlesource.com/c/v8/v8/+/6948286 * fix: disable protocol handler DCHECK https://chromium-review.googlesource.com/c/chromium/src/+/6727594 Ignore the extension custom protocol handler registry DCHECK until we invest in supporting it. Replacing this DCHECK seems harmless and will unblock the roll. (cherry picked from commit 019d3f0b09aeff8aed7991d9669a4ba7f265808b) * 6986762: Remove some includes of //ui/gfx/image/image_skia.h https: //chromium-review.googlesource.com/c/chromium/src/+/6986762 * fixup! fix: migrate NetworkConditions -> MatchedNetworkConditions https://chromium-review.googlesource.com/c/chromium/src/+/6827307 (cherry picked from commit a8f67f1ac3f8b07354d9457be9addf242ff70000) * fixup: 6986762: Remove some includes of //ui/gfx/image/image_skia.h s * fix: replace deprecated usage of SetPrototype https://chromium-review.googlesource.com/c/v8/v8/+/6983465 (cherry picked from commit 5435d87b40c15316bc8828fbc197be647b39b7bb) * chore: restore electron embedder data tag patch Co-Authored-By: Sam Maddock <sam@samuelmaddock.com> * chore: update patches --------- Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com> Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org> Co-authored-by: Samuel Maddock <smaddock@slack-corp.com> Co-authored-by: Alice Zhao <alicelovescake@anthropic.com> Co-authored-by: Sam Maddock <sam@samuelmaddock.com>
1039 lines
33 KiB
C++
1039 lines
33 KiB
C++
// Copyright (c) 2016 GitHub, Inc.
|
|
// Use of this source code is governed by the MIT license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "shell/browser/osr/osr_render_widget_host_view.h"
|
|
|
|
#include <algorithm>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <utility>
|
|
|
|
#include "base/functional/callback_helpers.h"
|
|
#include "base/location.h"
|
|
#include "base/memory/ptr_util.h"
|
|
#include "base/memory/raw_ptr.h"
|
|
#include "base/notimplemented.h"
|
|
#include "base/numerics/safe_conversions.h"
|
|
#include "base/task/single_thread_task_runner.h"
|
|
#include "base/time/time.h"
|
|
#include "components/input/cursor_manager.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/quads/compositor_render_pass.h"
|
|
#include "content/browser/renderer_host/render_widget_host_delegate.h" // nogncheck
|
|
#include "content/browser/renderer_host/render_widget_host_owner_delegate.h" // nogncheck
|
|
#include "content/common/input/synthetic_gesture.h" // nogncheck
|
|
#include "content/common/input/synthetic_gesture_target.h"
|
|
#include "content/public/browser/browser_task_traits.h"
|
|
#include "content/public/browser/browser_thread.h"
|
|
#include "content/public/browser/context_factory.h"
|
|
#include "content/public/browser/gpu_data_manager.h"
|
|
#include "content/public/browser/render_process_host.h"
|
|
#include "gpu/command_buffer/client/gl_helper.h"
|
|
#include "shell/browser/osr/osr_host_display_client.h"
|
|
#include "third_party/blink/public/common/input/web_input_event.h"
|
|
#include "third_party/skia/include/core/SkCanvas.h"
|
|
#include "ui/compositor/compositor.h"
|
|
#include "ui/compositor/layer.h"
|
|
#include "ui/compositor/layer_type.h"
|
|
#include "ui/display/screen.h"
|
|
#include "ui/events/base_event_utils.h"
|
|
#include "ui/events/event_constants.h"
|
|
#include "ui/gfx/geometry/dip_util.h"
|
|
#include "ui/gfx/geometry/size_conversions.h"
|
|
#include "ui/gfx/image/image_skia.h"
|
|
#include "ui/gfx/native_ui_types.h"
|
|
#include "ui/gfx/skbitmap_operations.h"
|
|
#include "ui/latency/latency_info.h"
|
|
|
|
namespace electron {
|
|
|
|
namespace {
|
|
|
|
const float kDefaultScaleFactor = 1.0;
|
|
|
|
ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
|
int button_flags = 0;
|
|
switch (event.button) {
|
|
case blink::WebMouseEvent::Button::kBack:
|
|
button_flags |= ui::EF_BACK_MOUSE_BUTTON;
|
|
break;
|
|
case blink::WebMouseEvent::Button::kForward:
|
|
button_flags |= ui::EF_FORWARD_MOUSE_BUTTON;
|
|
break;
|
|
case blink::WebMouseEvent::Button::kLeft:
|
|
button_flags |= ui::EF_LEFT_MOUSE_BUTTON;
|
|
break;
|
|
case blink::WebMouseEvent::Button::kMiddle:
|
|
button_flags |= ui::EF_MIDDLE_MOUSE_BUTTON;
|
|
break;
|
|
case blink::WebMouseEvent::Button::kRight:
|
|
button_flags |= ui::EF_RIGHT_MOUSE_BUTTON;
|
|
break;
|
|
default:
|
|
button_flags = 0;
|
|
break;
|
|
}
|
|
|
|
ui::MouseEvent ui_event{event.GetTypeAsUiEventType(),
|
|
event.PositionInWidget(),
|
|
event.PositionInWidget(),
|
|
ui::EventTimeForNow(),
|
|
button_flags,
|
|
button_flags};
|
|
ui_event.SetClickCount(event.click_count);
|
|
|
|
return ui_event;
|
|
}
|
|
|
|
ui::MouseWheelEvent UiMouseWheelEventFromWebMouseEvent(
|
|
blink::WebMouseWheelEvent event) {
|
|
return {UiMouseEventFromWebMouseEvent(event),
|
|
base::ClampFloor<int>(event.delta_x),
|
|
base::ClampFloor<int>(event.delta_y)};
|
|
}
|
|
|
|
} // namespace
|
|
|
|
class ElectronDelegatedFrameHostClient
|
|
: public content::DelegatedFrameHostClient {
|
|
public:
|
|
explicit ElectronDelegatedFrameHostClient(OffScreenRenderWidgetHostView* view)
|
|
: view_(view) {}
|
|
|
|
// disable copy
|
|
ElectronDelegatedFrameHostClient(const ElectronDelegatedFrameHostClient&) =
|
|
delete;
|
|
ElectronDelegatedFrameHostClient& operator=(
|
|
const ElectronDelegatedFrameHostClient&) = delete;
|
|
|
|
// content::DelegatedFrameHostClient
|
|
[[nodiscard]] ui::Layer* DelegatedFrameHostGetLayer() const override {
|
|
return view_->root_layer();
|
|
}
|
|
|
|
[[nodiscard]] bool DelegatedFrameHostIsVisible() const override {
|
|
return view_->IsShowing();
|
|
}
|
|
|
|
[[nodiscard]] SkColor DelegatedFrameHostGetGutterColor() const override {
|
|
if (view_->render_widget_host()->delegate() &&
|
|
view_->render_widget_host()->delegate()->IsFullscreen()) {
|
|
return SK_ColorWHITE;
|
|
}
|
|
return *view_->GetBackgroundColor();
|
|
}
|
|
|
|
void OnFrameTokenChanged(uint32_t frame_token,
|
|
base::TimeTicks activation_time) override {
|
|
view_->render_widget_host()->DidProcessFrame(frame_token, activation_time);
|
|
}
|
|
|
|
[[nodiscard]] float GetDeviceScaleFactor() const override {
|
|
return view_->GetDeviceScaleFactor();
|
|
}
|
|
|
|
viz::FrameEvictorClient::EvictIds CollectSurfaceIdsForEviction() override {
|
|
viz::FrameEvictorClient::EvictIds ids;
|
|
ids.embedded_ids =
|
|
view_->render_widget_host()->CollectSurfaceIdsForEviction();
|
|
return ids;
|
|
}
|
|
|
|
bool ShouldShowStaleContentOnEviction() override { return false; }
|
|
|
|
void InvalidateLocalSurfaceIdOnEviction() override {}
|
|
|
|
private:
|
|
const raw_ptr<OffScreenRenderWidgetHostView> view_;
|
|
};
|
|
|
|
OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
|
bool transparent,
|
|
bool offscreen_use_shared_texture,
|
|
bool painting,
|
|
int frame_rate,
|
|
const OnPaintCallback& callback,
|
|
content::RenderWidgetHost* host,
|
|
OffScreenRenderWidgetHostView* parent_host_view,
|
|
gfx::Size initial_size)
|
|
: content::RenderWidgetHostViewBase(host),
|
|
render_widget_host_(content::RenderWidgetHostImpl::From(host)),
|
|
parent_host_view_(parent_host_view),
|
|
transparent_(transparent),
|
|
offscreen_use_shared_texture_(offscreen_use_shared_texture),
|
|
callback_(callback),
|
|
frame_rate_(frame_rate),
|
|
size_(initial_size),
|
|
painting_(painting),
|
|
delegated_frame_host_client_{
|
|
std::make_unique<ElectronDelegatedFrameHostClient>(this)},
|
|
delegated_frame_host_{std::make_unique<content::DelegatedFrameHost>(
|
|
AllocateFrameSinkId(),
|
|
delegated_frame_host_client_.get(),
|
|
true /* should_register_frame_sink_id */)},
|
|
cursor_manager_(std::make_unique<input::CursorManager>(this)),
|
|
mouse_wheel_phase_handler_(this),
|
|
backing_(std::make_unique<SkBitmap>()) {
|
|
DCHECK(render_widget_host_);
|
|
DCHECK(!render_widget_host_->GetView());
|
|
|
|
// Initialize a screen_infos_ struct as needed, to cache the scale factor.
|
|
if (screen_infos_.screen_infos.empty()) {
|
|
UpdateScreenInfo();
|
|
}
|
|
screen_infos_.mutable_current().device_scale_factor = kDefaultScaleFactor;
|
|
|
|
delegated_frame_host_allocator_.GenerateId();
|
|
delegated_frame_host_surface_id_ =
|
|
delegated_frame_host_allocator_.GetCurrentLocalSurfaceId();
|
|
compositor_allocator_.GenerateId();
|
|
compositor_surface_id_ = compositor_allocator_.GetCurrentLocalSurfaceId();
|
|
|
|
root_layer_ = std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR);
|
|
|
|
root_layer()->SetColor(background_color_);
|
|
|
|
ui::ContextFactory* context_factory = content::GetContextFactory();
|
|
compositor_ = std::make_unique<ui::Compositor>(
|
|
context_factory->AllocateFrameSinkId(), context_factory,
|
|
base::SingleThreadTaskRunner::GetCurrentDefault(),
|
|
false /* enable_pixel_canvas */,
|
|
false /* use_external_begin_frame_control */);
|
|
compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget);
|
|
compositor_->SetDelegate(this);
|
|
compositor_->SetRootLayer(root_layer_.get());
|
|
|
|
ResizeRootLayer(false);
|
|
|
|
render_widget_host_->SetView(this);
|
|
|
|
if (content::GpuDataManager::GetInstance()->HardwareAccelerationEnabled()) {
|
|
video_consumer_ = std::make_unique<OffScreenVideoConsumer>(
|
|
this, base::BindRepeating(&OffScreenRenderWidgetHostView::OnPaint,
|
|
weak_ptr_factory_.GetWeakPtr()));
|
|
video_consumer_->SetActive(is_painting());
|
|
video_consumer_->SetFrameRate(this->frame_rate());
|
|
}
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::OnLocalSurfaceIdChanged(
|
|
const cc::RenderFrameMetadata& metadata) {
|
|
if (metadata.local_surface_id) {
|
|
bool changed = delegated_frame_host_allocator_.UpdateFromChild(
|
|
*metadata.local_surface_id);
|
|
|
|
if (changed) {
|
|
ResizeRootLayer(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() {
|
|
ReleaseCompositor();
|
|
root_layer_.reset();
|
|
|
|
DCHECK(!parent_host_view_);
|
|
DCHECK(!popup_host_view_);
|
|
DCHECK(!child_host_view_);
|
|
DCHECK(guest_host_views_.empty());
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::ReleaseCompositor() {
|
|
if (!compositor_) {
|
|
return; // already released
|
|
}
|
|
|
|
// Marking the DelegatedFrameHost as removed from the window hierarchy is
|
|
// necessary to remove all connections to its old ui::Compositor.
|
|
if (is_showing_) {
|
|
delegated_frame_host()->WasHidden(
|
|
content::DelegatedFrameHost::HiddenCause::kOther);
|
|
}
|
|
|
|
delegated_frame_host()->DetachFromCompositor();
|
|
delegated_frame_host_.reset();
|
|
|
|
host_display_client_ = nullptr;
|
|
compositor_.reset();
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) {
|
|
DCHECK(parent_host_view_);
|
|
|
|
if (parent_host_view_->child_host_view_) {
|
|
parent_host_view_->child_host_view_->CancelWidget();
|
|
}
|
|
|
|
parent_host_view_->set_child_host_view(this);
|
|
parent_host_view_->Hide();
|
|
|
|
ResizeRootLayer(false);
|
|
SetPainting(parent_host_view_->is_painting());
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::SetSize(const gfx::Size& size) {
|
|
size_ = size;
|
|
SynchronizeVisualProperties();
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::SetBounds(const gfx::Rect& new_bounds) {
|
|
SetSize(new_bounds.size());
|
|
}
|
|
|
|
gfx::NativeView OffScreenRenderWidgetHostView::GetNativeView() {
|
|
return {};
|
|
}
|
|
|
|
gfx::NativeViewAccessible
|
|
OffScreenRenderWidgetHostView::GetNativeViewAccessible() {
|
|
return {};
|
|
}
|
|
|
|
ui::TextInputClient* OffScreenRenderWidgetHostView::GetTextInputClient() {
|
|
return nullptr;
|
|
}
|
|
|
|
bool OffScreenRenderWidgetHostView::HasFocus() {
|
|
return false;
|
|
}
|
|
|
|
bool OffScreenRenderWidgetHostView::IsSurfaceAvailableForCopy() {
|
|
return delegated_frame_host()->CanCopyFromCompositingSurface();
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::ShowWithVisibility(
|
|
content::PageVisibilityState /*page_visibility*/) {
|
|
if (is_showing_)
|
|
return;
|
|
|
|
is_showing_ = true;
|
|
|
|
delegated_frame_host_->AttachToCompositor(compositor_.get());
|
|
delegated_frame_host_->WasShown(GetLocalSurfaceId(),
|
|
root_layer()->bounds().size(), {});
|
|
|
|
if (render_widget_host_) {
|
|
render_widget_host_->WasShown(
|
|
/*record_tab_switch_time_request=*/{});
|
|
|
|
// Call OnRenderFrameMetadataChangedAfterActivation for every frame.
|
|
auto* provider = content::RenderWidgetHostImpl::From(render_widget_host_)
|
|
->render_frame_metadata_provider();
|
|
provider->AddObserver(this);
|
|
}
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::Hide() {
|
|
if (!is_showing_)
|
|
return;
|
|
|
|
if (render_widget_host_) {
|
|
render_widget_host_->WasHidden();
|
|
|
|
auto* provider = content::RenderWidgetHostImpl::From(render_widget_host_)
|
|
->render_frame_metadata_provider();
|
|
provider->RemoveObserver(this);
|
|
}
|
|
|
|
if (delegated_frame_host()) {
|
|
delegated_frame_host()->WasHidden(
|
|
content::DelegatedFrameHost::HiddenCause::kOther);
|
|
delegated_frame_host()->DetachFromCompositor();
|
|
}
|
|
|
|
is_showing_ = false;
|
|
}
|
|
|
|
bool OffScreenRenderWidgetHostView::IsShowing() {
|
|
return is_showing_;
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::EnsureSurfaceSynchronizedForWebTest() {
|
|
++latest_capture_sequence_number_;
|
|
SynchronizeVisualProperties();
|
|
}
|
|
|
|
gfx::Rect OffScreenRenderWidgetHostView::GetViewBounds() {
|
|
if (IsPopupWidget())
|
|
return popup_position_;
|
|
|
|
return gfx::Rect(size_);
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::SetBackgroundColor(SkColor color) {
|
|
// The renderer will feed its color back to us with the first CompositorFrame.
|
|
// We short-cut here to show a sensible color before that happens.
|
|
UpdateBackgroundColorFromRenderer(color);
|
|
|
|
if (render_widget_host_ && render_widget_host_->owner_delegate()) {
|
|
render_widget_host_->owner_delegate()->SetBackgroundOpaque(
|
|
SkColorGetA(color) == SK_AlphaOPAQUE);
|
|
}
|
|
}
|
|
|
|
std::optional<SkColor> OffScreenRenderWidgetHostView::GetBackgroundColor() {
|
|
return background_color_;
|
|
}
|
|
|
|
gfx::Size OffScreenRenderWidgetHostView::GetVisibleViewportSize() {
|
|
return size_;
|
|
}
|
|
|
|
blink::mojom::PointerLockResult OffScreenRenderWidgetHostView::LockPointer(
|
|
bool request_unadjusted_movement) {
|
|
return blink::mojom::PointerLockResult::kUnsupportedOptions;
|
|
}
|
|
|
|
blink::mojom::PointerLockResult
|
|
OffScreenRenderWidgetHostView::ChangePointerLock(
|
|
bool request_unadjusted_movement) {
|
|
return blink::mojom::PointerLockResult::kUnsupportedOptions;
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::TakeFallbackContentFrom(
|
|
content::RenderWidgetHostView* view) {
|
|
DCHECK(!static_cast<content::RenderWidgetHostViewBase*>(view)
|
|
->IsRenderWidgetHostViewChildFrame());
|
|
auto* view_osr = static_cast<OffScreenRenderWidgetHostView*>(view);
|
|
SetBackgroundColor(view_osr->background_color_);
|
|
if (delegated_frame_host() && view_osr->delegated_frame_host()) {
|
|
delegated_frame_host()->TakeFallbackContentFrom(
|
|
view_osr->delegated_frame_host());
|
|
}
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::
|
|
InvalidateLocalSurfaceIdAndAllocationGroup() {
|
|
compositor_allocator_.Invalidate(/*also_invalidate_allocation_group=*/true);
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::UpdateFrameSinkIdRegistration() {
|
|
RenderWidgetHostViewBase::UpdateFrameSinkIdRegistration();
|
|
delegated_frame_host()->SetIsFrameSinkIdOwner(is_frame_sink_id_owner());
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::ResetFallbackToFirstNavigationSurface() {
|
|
delegated_frame_host()->ResetFallbackToFirstNavigationSurface();
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::InitAsPopup(
|
|
content::RenderWidgetHostView* parent_host_view,
|
|
const gfx::Rect& bounds,
|
|
const gfx::Rect& anchor_rect) {
|
|
DCHECK_EQ(parent_host_view_, parent_host_view);
|
|
DCHECK_EQ(widget_type_, content::WidgetType::kPopup);
|
|
|
|
if (parent_host_view_->popup_host_view_) {
|
|
parent_host_view_->popup_host_view_->CancelWidget();
|
|
}
|
|
|
|
parent_host_view_->set_popup_host_view(this);
|
|
parent_callback_ =
|
|
base::BindRepeating(&OffScreenRenderWidgetHostView::OnPopupPaint,
|
|
parent_host_view_->weak_ptr_factory_.GetWeakPtr());
|
|
|
|
popup_position_ = bounds;
|
|
|
|
ResizeRootLayer(true);
|
|
SetPainting(parent_host_view_->is_painting());
|
|
Show();
|
|
}
|
|
|
|
input::CursorManager* OffScreenRenderWidgetHostView::GetCursorManager() {
|
|
return cursor_manager_.get();
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::RenderProcessGone() {
|
|
Destroy();
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::Destroy() {
|
|
if (!is_destroyed_) {
|
|
is_destroyed_ = true;
|
|
|
|
if (parent_host_view_ != nullptr) {
|
|
CancelWidget();
|
|
} else {
|
|
if (popup_host_view_)
|
|
popup_host_view_->CancelWidget();
|
|
if (child_host_view_)
|
|
child_host_view_->CancelWidget();
|
|
if (!guest_host_views_.empty()) {
|
|
// Guest RWHVs will be destroyed when the associated RWHVGuest is
|
|
// destroyed. This parent RWHV may be destroyed first, so disassociate
|
|
// the guest RWHVs here without destroying them.
|
|
for (auto* guest_host_view : guest_host_views_)
|
|
guest_host_view->parent_host_view_ = nullptr;
|
|
guest_host_views_.clear();
|
|
}
|
|
for (auto* proxy_view : proxy_views_)
|
|
proxy_view->RemoveObserver();
|
|
Hide();
|
|
}
|
|
}
|
|
|
|
delete this;
|
|
}
|
|
|
|
uint32_t OffScreenRenderWidgetHostView::GetCaptureSequenceNumber() const {
|
|
return latest_capture_sequence_number_;
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::CopyFromSurface(
|
|
const gfx::Rect& src_rect,
|
|
const gfx::Size& output_size,
|
|
base::OnceCallback<void(const SkBitmap&)> callback) {
|
|
delegated_frame_host()->CopyFromCompositingSurface(src_rect, output_size,
|
|
std::move(callback));
|
|
}
|
|
|
|
display::ScreenInfo OffScreenRenderWidgetHostView::GetScreenInfo() const {
|
|
display::ScreenInfo screen_info;
|
|
screen_info.depth = 24;
|
|
screen_info.depth_per_component = 8;
|
|
screen_info.orientation_angle = 0;
|
|
screen_info.device_scale_factor = GetDeviceScaleFactor();
|
|
screen_info.orientation_type =
|
|
display::mojom::ScreenOrientation::kLandscapePrimary;
|
|
screen_info.rect = gfx::Rect(size_);
|
|
screen_info.available_rect = gfx::Rect(size_);
|
|
return screen_info;
|
|
}
|
|
|
|
gfx::Rect OffScreenRenderWidgetHostView::GetBoundsInRootWindow() {
|
|
return gfx::Rect(size_);
|
|
}
|
|
|
|
std::optional<content::DisplayFeature>
|
|
OffScreenRenderWidgetHostView::GetDisplayFeature() {
|
|
return std::nullopt;
|
|
}
|
|
|
|
viz::SurfaceId OffScreenRenderWidgetHostView::GetCurrentSurfaceId() const {
|
|
return delegated_frame_host() ? delegated_frame_host()->GetCurrentSurfaceId()
|
|
: viz::SurfaceId();
|
|
}
|
|
|
|
std::unique_ptr<content::SyntheticGestureTarget>
|
|
OffScreenRenderWidgetHostView::CreateSyntheticGestureTarget() {
|
|
NOTIMPLEMENTED();
|
|
return nullptr;
|
|
}
|
|
|
|
gfx::Size OffScreenRenderWidgetHostView::GetCompositorViewportPixelSize() {
|
|
return gfx::ScaleToCeiledSize(GetRequestedRendererSize(),
|
|
GetDeviceScaleFactor());
|
|
}
|
|
|
|
ui::Compositor* OffScreenRenderWidgetHostView::GetCompositor() {
|
|
return compositor_.get();
|
|
}
|
|
|
|
content::RenderWidgetHostViewBase*
|
|
OffScreenRenderWidgetHostView::CreateViewForWidget(
|
|
content::RenderWidgetHost* render_widget_host,
|
|
content::RenderWidgetHost* embedder_render_widget_host,
|
|
content::WebContentsView* web_contents_view) {
|
|
if (auto* rwhv = render_widget_host->GetView())
|
|
return static_cast<content::RenderWidgetHostViewBase*>(rwhv);
|
|
|
|
OffScreenRenderWidgetHostView* embedder_host_view = nullptr;
|
|
if (embedder_render_widget_host) {
|
|
embedder_host_view = static_cast<OffScreenRenderWidgetHostView*>(
|
|
embedder_render_widget_host->GetView());
|
|
}
|
|
|
|
return new OffScreenRenderWidgetHostView(
|
|
transparent_, offscreen_use_shared_texture_, true,
|
|
embedder_host_view->frame_rate(), callback_, render_widget_host,
|
|
embedder_host_view, size());
|
|
}
|
|
|
|
const viz::FrameSinkId& OffScreenRenderWidgetHostView::GetFrameSinkId() const {
|
|
return delegated_frame_host()->frame_sink_id();
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::DidNavigate() {
|
|
ResizeRootLayer(true);
|
|
if (delegated_frame_host())
|
|
delegated_frame_host()->DidNavigate();
|
|
}
|
|
|
|
bool OffScreenRenderWidgetHostView::TransformPointToCoordSpaceForView(
|
|
const gfx::PointF& point,
|
|
RenderWidgetHostViewInput* target_view,
|
|
gfx::PointF* transformed_point) {
|
|
if (target_view == this) {
|
|
*transformed_point = point;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::CancelWidget() {
|
|
if (render_widget_host_)
|
|
render_widget_host_->LostCapture();
|
|
Hide();
|
|
|
|
if (parent_host_view_) {
|
|
if (parent_host_view_->popup_host_view_ == this) {
|
|
parent_host_view_->set_popup_host_view(nullptr);
|
|
} else if (parent_host_view_->child_host_view_ == this) {
|
|
parent_host_view_->set_child_host_view(nullptr);
|
|
parent_host_view_->Show();
|
|
} else {
|
|
parent_host_view_->RemoveGuestHostView(this);
|
|
}
|
|
parent_host_view_ = nullptr;
|
|
}
|
|
|
|
if (render_widget_host_ && !is_destroyed_) {
|
|
is_destroyed_ = true;
|
|
// Results in a call to Destroy().
|
|
render_widget_host_->ShutdownAndDestroyWidget(true);
|
|
}
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::AddGuestHostView(
|
|
OffScreenRenderWidgetHostView* guest_host) {
|
|
guest_host_views_.insert(guest_host);
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::RemoveGuestHostView(
|
|
OffScreenRenderWidgetHostView* guest_host) {
|
|
guest_host_views_.erase(guest_host);
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::AddViewProxy(OffscreenViewProxy* proxy) {
|
|
proxy->SetObserver(this);
|
|
proxy_views_.insert(proxy);
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::RemoveViewProxy(OffscreenViewProxy* proxy) {
|
|
proxy->RemoveObserver();
|
|
proxy_views_.erase(proxy);
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::ProxyViewDestroyed(
|
|
OffscreenViewProxy* proxy) {
|
|
proxy_views_.erase(proxy);
|
|
Invalidate();
|
|
}
|
|
|
|
bool OffScreenRenderWidgetHostView::IsOffscreen() const {
|
|
return true;
|
|
}
|
|
|
|
std::unique_ptr<viz::HostDisplayClient>
|
|
OffScreenRenderWidgetHostView::CreateHostDisplayClient(
|
|
ui::Compositor* compositor) {
|
|
host_display_client_ = new OffScreenHostDisplayClient(
|
|
gfx::kNullAcceleratedWidget,
|
|
base::BindRepeating(&OffScreenRenderWidgetHostView::OnPaint,
|
|
weak_ptr_factory_.GetWeakPtr()));
|
|
host_display_client_->SetActive(is_painting());
|
|
return base::WrapUnique(host_display_client_.get());
|
|
}
|
|
|
|
bool OffScreenRenderWidgetHostView::InstallTransparency() {
|
|
if (transparent_) {
|
|
SetBackgroundColor(SkColor());
|
|
compositor_->SetBackgroundColor(SK_ColorTRANSPARENT);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#if BUILDFLAG(IS_MAC)
|
|
bool OffScreenRenderWidgetHostView::UpdateNSViewAndDisplay() {
|
|
return false;
|
|
}
|
|
|
|
uint64_t OffScreenRenderWidgetHostView::GetNSViewId() const {
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
void OffScreenRenderWidgetHostView::OnPaint(
|
|
const gfx::Rect& damage_rect,
|
|
const SkBitmap& bitmap,
|
|
const OffscreenSharedTexture& texture) {
|
|
if (texture.has_value()) {
|
|
callback_.Run(damage_rect, {}, texture);
|
|
return;
|
|
}
|
|
|
|
backing_ = std::make_unique<SkBitmap>();
|
|
backing_->allocN32Pixels(bitmap.width(), bitmap.height(), !transparent_);
|
|
bitmap.readPixels(backing_->pixmap());
|
|
|
|
if (IsPopupWidget() && parent_callback_) {
|
|
parent_callback_.Run(this->popup_position_);
|
|
} else {
|
|
CompositeFrame(damage_rect);
|
|
}
|
|
}
|
|
|
|
gfx::Size OffScreenRenderWidgetHostView::SizeInPixels() {
|
|
float sf = GetDeviceScaleFactor();
|
|
return gfx::ToFlooredSize(
|
|
gfx::ConvertSizeToPixels(GetViewBounds().size(), sf));
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::CompositeFrame(
|
|
const gfx::Rect& damage_rect) {
|
|
HoldResize();
|
|
|
|
gfx::Size size_in_pixels = SizeInPixels();
|
|
|
|
SkBitmap frame;
|
|
|
|
// Optimize for the case when there is no popup
|
|
if (proxy_views_.empty() && !popup_host_view_) {
|
|
frame = GetBacking();
|
|
} else {
|
|
float sf = GetDeviceScaleFactor();
|
|
frame.allocN32Pixels(size_in_pixels.width(), size_in_pixels.height(),
|
|
false);
|
|
if (!GetBacking().drawsNothing()) {
|
|
SkCanvas canvas(frame);
|
|
canvas.writePixels(GetBacking(), 0, 0);
|
|
|
|
if (popup_host_view_ && !popup_host_view_->GetBacking().drawsNothing()) {
|
|
gfx::Rect rect = popup_host_view_->popup_position_;
|
|
gfx::Point origin_in_pixels =
|
|
gfx::ToFlooredPoint(gfx::ConvertPointToPixels(rect.origin(), sf));
|
|
canvas.writePixels(popup_host_view_->GetBacking(), origin_in_pixels.x(),
|
|
origin_in_pixels.y());
|
|
}
|
|
|
|
for (auto* proxy_view : proxy_views_) {
|
|
gfx::Rect rect = proxy_view->bounds();
|
|
gfx::Point origin_in_pixels =
|
|
gfx::ToFlooredPoint(gfx::ConvertPointToPixels(rect.origin(), sf));
|
|
canvas.writePixels(*proxy_view->bitmap(), origin_in_pixels.x(),
|
|
origin_in_pixels.y());
|
|
}
|
|
}
|
|
}
|
|
|
|
callback_.Run(gfx::IntersectRects(gfx::Rect(size_in_pixels), damage_rect),
|
|
frame, {});
|
|
|
|
ReleaseResize();
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::OnPopupPaint(const gfx::Rect& damage_rect) {
|
|
InvalidateBounds(gfx::ToEnclosingRect(
|
|
gfx::ConvertRectToPixels(damage_rect, GetDeviceScaleFactor())));
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::OnProxyViewPaint(
|
|
const gfx::Rect& damage_rect) {
|
|
InvalidateBounds(gfx::ToEnclosingRect(
|
|
gfx::ConvertRectToPixels(damage_rect, GetDeviceScaleFactor())));
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::HoldResize() {
|
|
if (!hold_resize_)
|
|
hold_resize_ = true;
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::ReleaseResize() {
|
|
if (!hold_resize_)
|
|
return;
|
|
|
|
hold_resize_ = false;
|
|
if (pending_resize_) {
|
|
pending_resize_ = false;
|
|
content::GetUIThreadTaskRunner({})->PostTask(
|
|
FROM_HERE,
|
|
base::BindOnce(
|
|
&OffScreenRenderWidgetHostView::SynchronizeVisualProperties,
|
|
weak_ptr_factory_.GetWeakPtr()));
|
|
}
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::SynchronizeVisualProperties() {
|
|
if (hold_resize_) {
|
|
if (!pending_resize_)
|
|
pending_resize_ = true;
|
|
return;
|
|
}
|
|
|
|
ResizeRootLayer(true);
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::SendMouseEvent(
|
|
const blink::WebMouseEvent& event) {
|
|
for (auto* proxy_view : proxy_views_) {
|
|
gfx::Rect bounds = proxy_view->bounds();
|
|
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());
|
|
|
|
ui::MouseEvent ui_event = UiMouseEventFromWebMouseEvent(proxy_event);
|
|
proxy_view->OnEvent(&ui_event);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!IsPopupWidget()) {
|
|
if (popup_host_view_ &&
|
|
popup_host_view_->popup_position_.Contains(
|
|
event.PositionInWidget().x(), event.PositionInWidget().y())) {
|
|
blink::WebMouseEvent popup_event(event);
|
|
popup_event.SetPositionInWidget(
|
|
popup_event.PositionInWidget().x() -
|
|
popup_host_view_->popup_position_.x(),
|
|
popup_event.PositionInWidget().y() -
|
|
popup_host_view_->popup_position_.y());
|
|
|
|
popup_host_view_->ProcessMouseEvent(popup_event, ui::LatencyInfo());
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!render_widget_host_)
|
|
return;
|
|
render_widget_host_->ForwardMouseEvent(event);
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::SendMouseWheelEvent(
|
|
const blink::WebMouseWheelEvent& event) {
|
|
for (auto* proxy_view : proxy_views_) {
|
|
gfx::Rect bounds = proxy_view->bounds();
|
|
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());
|
|
|
|
ui::MouseWheelEvent ui_event =
|
|
UiMouseWheelEventFromWebMouseEvent(proxy_event);
|
|
proxy_view->OnEvent(&ui_event);
|
|
return;
|
|
}
|
|
}
|
|
|
|
blink::WebMouseWheelEvent mouse_wheel_event(event);
|
|
|
|
bool should_route_event =
|
|
render_widget_host_->delegate() &&
|
|
render_widget_host_->delegate()->GetInputEventRouter();
|
|
mouse_wheel_phase_handler_.SendWheelEndForTouchpadScrollingIfNeeded(
|
|
should_route_event);
|
|
mouse_wheel_phase_handler_.AddPhaseIfNeededAndScheduleEndEvent(
|
|
mouse_wheel_event, false, true);
|
|
|
|
if (!IsPopupWidget()) {
|
|
if (popup_host_view_) {
|
|
if (popup_host_view_->popup_position_.Contains(
|
|
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() -
|
|
popup_host_view_->popup_position_.x(),
|
|
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_host_view_->SendMouseWheelEvent(popup_mouse_wheel_event);
|
|
return;
|
|
} else {
|
|
// Scrolling outside of the popup widget so destroy it.
|
|
// Execute asynchronously to avoid deleting the widget from inside some
|
|
// other callback.
|
|
content::GetUIThreadTaskRunner({})->PostTask(
|
|
FROM_HERE,
|
|
base::BindOnce(&OffScreenRenderWidgetHostView::CancelWidget,
|
|
popup_host_view_->weak_ptr_factory_.GetWeakPtr()));
|
|
}
|
|
} else if (!guest_host_views_.empty()) {
|
|
for (auto* guest_host_view : guest_host_views_) {
|
|
if (!guest_host_view->render_widget_host_ ||
|
|
!guest_host_view->render_widget_host_->GetView()) {
|
|
continue;
|
|
}
|
|
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())) {
|
|
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());
|
|
guest_mouse_wheel_event.SetPositionInScreen(
|
|
guest_mouse_wheel_event.PositionInWidget().x(),
|
|
guest_mouse_wheel_event.PositionInWidget().y());
|
|
|
|
guest_host_view->SendMouseWheelEvent(guest_mouse_wheel_event);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!render_widget_host_)
|
|
return;
|
|
render_widget_host_->ForwardWheelEvent(event);
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::SetPainting(bool painting) {
|
|
painting_ = painting;
|
|
|
|
if (popup_host_view_) {
|
|
popup_host_view_->SetPainting(painting);
|
|
}
|
|
|
|
for (auto* guest_host_view : guest_host_views_)
|
|
guest_host_view->SetPainting(painting);
|
|
|
|
if (video_consumer_) {
|
|
video_consumer_->SetActive(is_painting());
|
|
} else if (host_display_client_) {
|
|
host_display_client_->SetActive(is_painting());
|
|
}
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::SetFrameRate(int frame_rate) {
|
|
if (parent_host_view_) {
|
|
if (parent_host_view_->frame_rate() == this->frame_rate())
|
|
return;
|
|
|
|
frame_rate_ = parent_host_view_->frame_rate();
|
|
} else {
|
|
if (frame_rate <= 0)
|
|
frame_rate = 1;
|
|
if (!offscreen_use_shared_texture_ && frame_rate > 240)
|
|
frame_rate = 240;
|
|
|
|
frame_rate_ = frame_rate;
|
|
}
|
|
|
|
SetupFrameRate(true);
|
|
|
|
if (video_consumer_) {
|
|
video_consumer_->SetFrameRate(this->frame_rate());
|
|
}
|
|
|
|
for (auto* guest_host_view : guest_host_views_)
|
|
guest_host_view->SetFrameRate(frame_rate);
|
|
}
|
|
|
|
const viz::LocalSurfaceId& OffScreenRenderWidgetHostView::GetLocalSurfaceId()
|
|
const {
|
|
return delegated_frame_host_surface_id_;
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) {
|
|
if (!force && frame_rate_threshold_us_ != 0)
|
|
return;
|
|
|
|
frame_rate_threshold_us_ = 1000000 / frame_rate_;
|
|
|
|
if (compositor_) {
|
|
compositor_->SetDisplayVSyncParameters(
|
|
base::TimeTicks::Now(), base::Microseconds(frame_rate_threshold_us_));
|
|
}
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::Invalidate() {
|
|
InvalidateBounds(gfx::Rect(GetRequestedRendererSize()));
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::InvalidateBounds(const gfx::Rect& bounds) {
|
|
CompositeFrame(bounds);
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
|
|
SetupFrameRate(false);
|
|
|
|
display::Display display =
|
|
display::Screen::Get()->GetDisplayNearestView(GetNativeView());
|
|
const float scaleFactor = display.device_scale_factor();
|
|
float sf = GetDeviceScaleFactor();
|
|
const bool sf_did_change = scaleFactor != sf;
|
|
|
|
// Initialize a screen_infos_ struct as needed, to cache the scale factor.
|
|
if (screen_infos_.screen_infos.empty()) {
|
|
UpdateScreenInfo();
|
|
}
|
|
screen_infos_.mutable_current().device_scale_factor = scaleFactor;
|
|
|
|
gfx::Size size = GetViewBounds().size();
|
|
|
|
if (!force && !sf_did_change && size == root_layer()->bounds().size())
|
|
return;
|
|
|
|
root_layer()->SetBounds(gfx::Rect(size));
|
|
|
|
const gfx::Size& size_in_pixels =
|
|
gfx::ToFlooredSize(gfx::ConvertSizeToPixels(size, sf));
|
|
|
|
if (compositor_) {
|
|
compositor_allocator_.GenerateId();
|
|
compositor_surface_id_ = compositor_allocator_.GetCurrentLocalSurfaceId();
|
|
compositor_->SetScaleAndSize(sf, size_in_pixels, compositor_surface_id_);
|
|
}
|
|
|
|
delegated_frame_host_allocator_.GenerateId();
|
|
delegated_frame_host_surface_id_ =
|
|
delegated_frame_host_allocator_.GetCurrentLocalSurfaceId();
|
|
|
|
delegated_frame_host()->EmbedSurface(
|
|
delegated_frame_host_surface_id_, size,
|
|
cc::DeadlinePolicy::UseDefaultDeadline());
|
|
|
|
// Note that |render_widget_host_| will retrieve resize parameters from the
|
|
// DelegatedFrameHost, so it must have SynchronizeVisualProperties called
|
|
// after.
|
|
if (render_widget_host_) {
|
|
render_widget_host_->SynchronizeVisualProperties();
|
|
}
|
|
}
|
|
|
|
viz::FrameSinkId OffScreenRenderWidgetHostView::AllocateFrameSinkId() {
|
|
return viz::FrameSinkId(
|
|
base::checked_cast<uint32_t>(
|
|
render_widget_host_->GetProcess()->GetDeprecatedID()),
|
|
base::checked_cast<uint32_t>(render_widget_host_->GetRoutingID()));
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::UpdateBackgroundColorFromRenderer(
|
|
SkColor color) {
|
|
if (color == background_color_)
|
|
return;
|
|
background_color_ = color;
|
|
|
|
root_layer()->SetColor(color);
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::NotifyHostAndDelegateOnWasShown(
|
|
blink::mojom::RecordContentToVisibleTimeRequestPtr) {
|
|
NOTREACHED();
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::
|
|
RequestSuccessfulPresentationTimeFromHostOrDelegate(
|
|
blink::mojom::RecordContentToVisibleTimeRequestPtr) {
|
|
NOTREACHED();
|
|
}
|
|
|
|
void OffScreenRenderWidgetHostView::
|
|
CancelSuccessfulPresentationTimeRequestForHostAndDelegate() {
|
|
NOTREACHED();
|
|
}
|
|
|
|
} // namespace electron
|