mirror of
https://github.com/electron/electron.git
synced 2026-02-19 03:14:51 -05:00
fix: offscreen rendering with correct screen info. (#48730)
fix: osr use correct screen info.
This commit is contained in:
@@ -826,6 +826,8 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
&offscreen_use_shared_texture_);
|
||||
use_offscreen_dict.Get(options::kSharedTexturePixelFormat,
|
||||
&offscreen_shared_texture_pixel_format_);
|
||||
use_offscreen_dict.Get(options::kDeviceScaleFactor,
|
||||
&offscreen_device_scale_factor_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -864,6 +866,7 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
auto* view = new OffScreenWebContentsView(
|
||||
false, offscreen_use_shared_texture_,
|
||||
offscreen_shared_texture_pixel_format_,
|
||||
offscreen_device_scale_factor_,
|
||||
base::BindRepeating(&WebContents::OnPaint, base::Unretained(this)));
|
||||
params.view = view;
|
||||
params.delegate_view = view;
|
||||
@@ -885,7 +888,7 @@ WebContents::WebContents(v8::Isolate* isolate,
|
||||
content::WebContents::CreateParams params(session->browser_context());
|
||||
auto* view = new OffScreenWebContentsView(
|
||||
transparent, offscreen_use_shared_texture_,
|
||||
offscreen_shared_texture_pixel_format_,
|
||||
offscreen_shared_texture_pixel_format_, offscreen_device_scale_factor_,
|
||||
base::BindRepeating(&WebContents::OnPaint, base::Unretained(this)));
|
||||
params.view = view;
|
||||
params.delegate_view = view;
|
||||
@@ -1249,6 +1252,7 @@ void WebContents::MaybeOverrideCreateParamsForNewWindow(
|
||||
auto* view = new OffScreenWebContentsView(
|
||||
false, offscreen_use_shared_texture_,
|
||||
offscreen_shared_texture_pixel_format_,
|
||||
offscreen_device_scale_factor_,
|
||||
base::BindRepeating(&WebContents::OnPaint, base::Unretained(this)));
|
||||
create_params->view = view;
|
||||
create_params->delegate_view = view;
|
||||
|
||||
@@ -820,6 +820,13 @@ class WebContents final : public ExclusiveAccessContext,
|
||||
bool offscreen_use_shared_texture_ = false;
|
||||
std::string offscreen_shared_texture_pixel_format_ = "argb";
|
||||
|
||||
// TODO(reito): 0.0f means the device scale factor is not set, it's a
|
||||
// migration of the breaking change so that we can read the device scale
|
||||
// factor from physical primary screen's info. In Electron 42, we need to set
|
||||
// this to 1.0f so that the offscreen rendering use 1.0 as default when
|
||||
// `deviceScaleFactor` is not specified in webPreferences.
|
||||
float offscreen_device_scale_factor_ = 0.0f;
|
||||
|
||||
// Whether window is fullscreened by HTML5 api.
|
||||
bool html_fullscreen_ = false;
|
||||
|
||||
|
||||
@@ -53,8 +53,6 @@ namespace electron {
|
||||
|
||||
namespace {
|
||||
|
||||
const float kDefaultScaleFactor = 1.0;
|
||||
|
||||
ui::MouseEvent UiMouseEventFromWebMouseEvent(blink::WebMouseEvent event) {
|
||||
int button_flags = 0;
|
||||
switch (event.button) {
|
||||
@@ -96,6 +94,15 @@ ui::MouseWheelEvent UiMouseWheelEventFromWebMouseEvent(
|
||||
base::ClampFloor<int>(event.delta_y)};
|
||||
}
|
||||
|
||||
// TODO(reito): Remove this function and use default 1.0f when Electron 42.
|
||||
float GetDefaultDeviceScaleFactorFromDisplayInfo() {
|
||||
display::Display display =
|
||||
display::Screen::Get()->GetDisplayNearestView(gfx::NativeView());
|
||||
|
||||
const float factor = display.device_scale_factor();
|
||||
return factor > 0 ? factor : 1.0f;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class ElectronDelegatedFrameHostClient
|
||||
@@ -155,6 +162,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
bool transparent,
|
||||
bool offscreen_use_shared_texture,
|
||||
const std::string& offscreen_shared_texture_pixel_format,
|
||||
float offscreen_device_scale_factor,
|
||||
bool painting,
|
||||
int frame_rate,
|
||||
const OnPaintCallback& callback,
|
||||
@@ -168,6 +176,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
offscreen_use_shared_texture_(offscreen_use_shared_texture),
|
||||
offscreen_shared_texture_pixel_format_(
|
||||
offscreen_shared_texture_pixel_format),
|
||||
offscreen_device_scale_factor_(offscreen_device_scale_factor),
|
||||
callback_(callback),
|
||||
frame_rate_(frame_rate),
|
||||
size_(initial_size),
|
||||
@@ -184,11 +193,11 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
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();
|
||||
// TODO(reito): Remove this when Electron 42.
|
||||
if (cc::MathUtil::IsWithinEpsilon(offscreen_device_scale_factor_, 0.0f)) {
|
||||
offscreen_device_scale_factor_ =
|
||||
GetDefaultDeviceScaleFactorFromDisplayInfo();
|
||||
}
|
||||
screen_infos_.mutable_current().device_scale_factor = kDefaultScaleFactor;
|
||||
|
||||
delegated_frame_host_allocator_.GenerateId();
|
||||
delegated_frame_host_surface_id_ =
|
||||
@@ -210,15 +219,6 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView(
|
||||
compositor_->SetDelegate(this);
|
||||
compositor_->SetRootLayer(root_layer_.get());
|
||||
|
||||
// For offscreen rendering with format rgbaf16, we need to set correct display
|
||||
// color spaces to the compositor, otherwise it won't support hdr.
|
||||
if (offscreen_use_shared_texture_ &&
|
||||
offscreen_shared_texture_pixel_format_ == "rgbaf16") {
|
||||
gfx::DisplayColorSpaces hdr_display_color_spaces(
|
||||
gfx::ColorSpace::CreateSRGBLinear(), viz::SinglePlaneFormat::kRGBA_F16);
|
||||
compositor_->SetDisplayColorSpaces(hdr_display_color_spaces);
|
||||
}
|
||||
|
||||
ResizeRootLayer(false);
|
||||
|
||||
render_widget_host_->SetView(this);
|
||||
@@ -504,19 +504,6 @@ void OffScreenRenderWidgetHostView::CopyFromSurface(
|
||||
src_rect, output_size, base::TimeDelta(), 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_);
|
||||
}
|
||||
@@ -562,8 +549,8 @@ OffScreenRenderWidgetHostView::CreateViewForWidget(
|
||||
|
||||
return new OffScreenRenderWidgetHostView(
|
||||
transparent_, offscreen_use_shared_texture_,
|
||||
offscreen_shared_texture_pixel_format_, true,
|
||||
embedder_host_view->frame_rate(), callback_, render_widget_host,
|
||||
offscreen_shared_texture_pixel_format_, offscreen_device_scale_factor_,
|
||||
true, embedder_host_view->frame_rate(), callback_, render_widget_host,
|
||||
embedder_host_view, size());
|
||||
}
|
||||
|
||||
@@ -971,35 +958,55 @@ void OffScreenRenderWidgetHostView::InvalidateBounds(const gfx::Rect& bounds) {
|
||||
CompositeFrame(bounds);
|
||||
}
|
||||
|
||||
display::ScreenInfos
|
||||
OffScreenRenderWidgetHostView::GetNewScreenInfosForUpdate() {
|
||||
display::ScreenInfo screen_info;
|
||||
screen_info.depth = 24;
|
||||
screen_info.depth_per_component = 8;
|
||||
screen_info.orientation_angle = 0;
|
||||
screen_info.orientation_type =
|
||||
display::mojom::ScreenOrientation::kLandscapePrimary;
|
||||
screen_info.rect = gfx::Rect(size_);
|
||||
screen_info.available_rect = gfx::Rect(size_);
|
||||
screen_info.device_scale_factor = offscreen_device_scale_factor_;
|
||||
|
||||
// When pixel format is 'rgbaf16', we need to set screen info to support HDR.
|
||||
if (offscreen_use_shared_texture_ &&
|
||||
offscreen_shared_texture_pixel_format_ == "rgbaf16") {
|
||||
gfx::DisplayColorSpaces hdr_display_color_spaces{
|
||||
gfx::ColorSpace::CreateSRGBLinear(), viz::SinglePlaneFormat::kRGBA_F16};
|
||||
// The max luminance value doesn't matter so we set to a large value.
|
||||
hdr_display_color_spaces.SetHDRMaxLuminanceRelative(100.0f);
|
||||
screen_info.display_color_spaces = hdr_display_color_spaces;
|
||||
}
|
||||
|
||||
display::ScreenInfos screen_infos{screen_info};
|
||||
return screen_infos;
|
||||
}
|
||||
|
||||
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;
|
||||
auto old_screen_info = screen_infos_.current();
|
||||
UpdateScreenInfo();
|
||||
|
||||
auto new_screen_info = screen_infos_.current();
|
||||
gfx::Size size = GetViewBounds().size();
|
||||
|
||||
if (!force && !sf_did_change && size == root_layer()->bounds().size())
|
||||
if (!force && size == root_layer()->bounds().size() &&
|
||||
old_screen_info == new_screen_info)
|
||||
return;
|
||||
|
||||
root_layer()->SetBounds(gfx::Rect(size));
|
||||
|
||||
const gfx::Size& size_in_pixels =
|
||||
gfx::ToFlooredSize(gfx::ConvertSizeToPixels(size, sf));
|
||||
auto sf = GetDeviceScaleFactor();
|
||||
const gfx::Size& size_in_pixels = SizeInPixels();
|
||||
|
||||
if (compositor_) {
|
||||
compositor_allocator_.GenerateId();
|
||||
compositor_surface_id_ = compositor_allocator_.GetCurrentLocalSurfaceId();
|
||||
compositor_->SetScaleAndSize(sf, size_in_pixels, compositor_surface_id_);
|
||||
compositor_->SetDisplayColorSpaces(new_screen_info.display_color_spaces);
|
||||
}
|
||||
|
||||
delegated_frame_host_allocator_.GenerateId();
|
||||
|
||||
@@ -73,6 +73,7 @@ class OffScreenRenderWidgetHostView
|
||||
bool transparent,
|
||||
bool offscreen_use_shared_texture,
|
||||
const std::string& offscreen_shared_texture_pixel_format,
|
||||
float offscreen_device_scale_factor,
|
||||
bool painting,
|
||||
int frame_rate,
|
||||
const OnPaintCallback& callback,
|
||||
@@ -151,7 +152,6 @@ class OffScreenRenderWidgetHostView
|
||||
base::TimeDelta timeout,
|
||||
base::OnceCallback<void(const content::CopyFromSurfaceResult&)> callback)
|
||||
override;
|
||||
display::ScreenInfo GetScreenInfo() const override;
|
||||
void TransformPointToRootSurface(gfx::PointF* point) override {}
|
||||
gfx::Rect GetBoundsInRootWindow() override;
|
||||
std::optional<content::DisplayFeature> GetDisplayFeature() override;
|
||||
@@ -171,6 +171,7 @@ class OffScreenRenderWidgetHostView
|
||||
const std::optional<std::vector<gfx::Rect>>& character_bounds) override {}
|
||||
gfx::Size GetCompositorViewportPixelSize() override;
|
||||
ui::Compositor* GetCompositor() override;
|
||||
display::ScreenInfos GetNewScreenInfosForUpdate() override;
|
||||
|
||||
content::RenderWidgetHostViewBase* CreateViewForWidget(
|
||||
content::RenderWidgetHost*,
|
||||
@@ -293,6 +294,8 @@ class OffScreenRenderWidgetHostView
|
||||
const bool transparent_;
|
||||
const bool offscreen_use_shared_texture_;
|
||||
const std::string offscreen_shared_texture_pixel_format_;
|
||||
float offscreen_device_scale_factor_;
|
||||
|
||||
OnPaintCallback callback_;
|
||||
OnPopupPaintCallback parent_callback_;
|
||||
|
||||
|
||||
@@ -17,11 +17,13 @@ OffScreenWebContentsView::OffScreenWebContentsView(
|
||||
bool transparent,
|
||||
bool offscreen_use_shared_texture,
|
||||
const std::string& offscreen_shared_texture_pixel_format,
|
||||
float offscreen_device_scale_factor,
|
||||
const OnPaintCallback& callback)
|
||||
: transparent_(transparent),
|
||||
offscreen_use_shared_texture_(offscreen_use_shared_texture),
|
||||
offscreen_shared_texture_pixel_format_(
|
||||
offscreen_shared_texture_pixel_format),
|
||||
offscreen_device_scale_factor_(offscreen_device_scale_factor),
|
||||
callback_(callback) {
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
PlatformCreate();
|
||||
@@ -116,8 +118,9 @@ OffScreenWebContentsView::CreateViewForWidget(
|
||||
|
||||
return new OffScreenRenderWidgetHostView(
|
||||
transparent_, offscreen_use_shared_texture_,
|
||||
offscreen_shared_texture_pixel_format_, painting_, GetFrameRate(),
|
||||
callback_, render_widget_host, nullptr, GetSize());
|
||||
offscreen_shared_texture_pixel_format_, offscreen_device_scale_factor_,
|
||||
painting_, GetFrameRate(), callback_, render_widget_host, nullptr,
|
||||
GetSize());
|
||||
}
|
||||
|
||||
content::RenderWidgetHostViewBase*
|
||||
@@ -137,9 +140,9 @@ OffScreenWebContentsView::CreateViewForChildWidget(
|
||||
|
||||
return new OffScreenRenderWidgetHostView(
|
||||
transparent_, offscreen_use_shared_texture_,
|
||||
offscreen_shared_texture_pixel_format_, painting_,
|
||||
embedder_host_view->frame_rate(), callback_, render_widget_host,
|
||||
embedder_host_view, GetSize());
|
||||
offscreen_shared_texture_pixel_format_, offscreen_device_scale_factor_,
|
||||
painting_, embedder_host_view->frame_rate(), callback_,
|
||||
render_widget_host, embedder_host_view, GetSize());
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::RenderViewReady() {
|
||||
|
||||
@@ -38,6 +38,7 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
||||
bool transparent,
|
||||
bool offscreen_use_shared_texture,
|
||||
const std::string& offscreen_shared_texture_pixel_format,
|
||||
float offscreen_device_scale_factor,
|
||||
const OnPaintCallback& callback);
|
||||
~OffScreenWebContentsView() override;
|
||||
|
||||
@@ -113,6 +114,7 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
||||
const bool transparent_;
|
||||
const bool offscreen_use_shared_texture_;
|
||||
const std::string offscreen_shared_texture_pixel_format_;
|
||||
const float offscreen_device_scale_factor_;
|
||||
bool painting_ = true;
|
||||
int frame_rate_ = 60;
|
||||
OnPaintCallback callback_;
|
||||
|
||||
@@ -186,6 +186,8 @@ inline constexpr std::string_view kUseSharedTexture = "useSharedTexture";
|
||||
inline constexpr std::string_view kSharedTexturePixelFormat =
|
||||
"sharedTexturePixelFormat";
|
||||
|
||||
inline constexpr std::string_view kDeviceScaleFactor = "deviceScaleFactor";
|
||||
|
||||
inline constexpr std::string_view kNodeIntegrationInSubFrames =
|
||||
"nodeIntegrationInSubFrames";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user