Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: offscreen rendering crash on input select #34091

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 8 additions & 21 deletions shell/browser/osr/osr_render_widget_host_view.cc
Expand Up @@ -397,7 +397,7 @@ void OffScreenRenderWidgetHostView::ResetFallbackToFirstNavigationSurface() {

void OffScreenRenderWidgetHostView::InitAsPopup(
content::RenderWidgetHostView* parent_host_view,
const gfx::Rect& pos,
const gfx::Rect& bounds,
const gfx::Rect& anchor_rect) {
DCHECK_EQ(parent_host_view_, parent_host_view);
DCHECK_EQ(widget_type_, content::WidgetType::kPopup);
Expand All @@ -411,13 +411,10 @@ void OffScreenRenderWidgetHostView::InitAsPopup(
base::BindRepeating(&OffScreenRenderWidgetHostView::OnPopupPaint,
parent_host_view_->weak_ptr_factory_.GetWeakPtr());

popup_position_ = pos;
popup_position_ = bounds;

ResizeRootLayer(false);
ResizeRootLayer(true);
SetPainting(parent_host_view_->IsPainting());
if (video_consumer_) {
video_consumer_->SizeChanged();
}
Show();
}

Expand Down Expand Up @@ -688,13 +685,8 @@ void OffScreenRenderWidgetHostView::OnPaint(const gfx::Rect& damage_rect,

gfx::Size OffScreenRenderWidgetHostView::SizeInPixels() {
float sf = GetDeviceScaleFactor();
if (IsPopupWidget()) {
return gfx::ToFlooredSize(
gfx::ConvertSizeToPixels(popup_position_.size(), sf));
} else {
return gfx::ToFlooredSize(
gfx::ConvertSizeToPixels(GetViewBounds().size(), sf));
}
return gfx::ToFlooredSize(
gfx::ConvertSizeToPixels(GetViewBounds().size(), sf));
}

void OffScreenRenderWidgetHostView::CompositeFrame(
Expand Down Expand Up @@ -995,22 +987,17 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer(bool force) {
display::Screen::GetScreen()->GetDisplayNearestView(GetNativeView());
const float scaleFactor = display.device_scale_factor();
float sf = GetDeviceScaleFactor();
const bool scaleFactorDidChange = scaleFactor != sf;
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;
if (!IsPopupWidget())
size = GetViewBounds().size();
else
size = popup_position_.size();
gfx::Size size = GetViewBounds().size();

if (!force && !scaleFactorDidChange &&
size == GetRootLayer()->bounds().size())
if (!force && !sf_did_change && size == GetRootLayer()->bounds().size())
return;

GetRootLayer()->SetBounds(gfx::Rect(size));
Expand Down
2 changes: 1 addition & 1 deletion shell/browser/osr/osr_render_widget_host_view.h
Expand Up @@ -119,7 +119,7 @@ class OffScreenRenderWidgetHostView : public content::RenderWidgetHostViewBase,

void ResetFallbackToFirstNavigationSurface() override;
void InitAsPopup(content::RenderWidgetHostView* parent_host_view,
const gfx::Rect& pos,
const gfx::Rect& bounds,
const gfx::Rect& anchor_rect) override;
void UpdateCursor(const content::WebCursor&) override;
void SetIsLoading(bool is_loading) override;
Expand Down
31 changes: 23 additions & 8 deletions shell/browser/osr/osr_video_consumer.cc
Expand Up @@ -6,13 +6,29 @@

#include <utility>

#include "media/base/limits.h"
#include "media/base/video_frame_metadata.h"
#include "media/capture/mojom/video_capture_buffer.mojom.h"
#include "media/capture/mojom/video_capture_types.mojom.h"
#include "services/viz/privileged/mojom/compositing/frame_sink_video_capture.mojom-shared.h"
#include "shell/browser/osr/osr_render_widget_host_view.h"
#include "ui/gfx/skbitmap_operations.h"

namespace {

bool IsValidMinAndMaxFrameSize(gfx::Size min_frame_size,
gfx::Size max_frame_size) {
// Returns true if
// 0 < |min_frame_size| <= |max_frame_size| <= media::limits::kMaxDimension.
return 0 < min_frame_size.width() && 0 < min_frame_size.height() &&
min_frame_size.width() <= max_frame_size.width() &&
min_frame_size.height() <= max_frame_size.height() &&
max_frame_size.width() <= media::limits::kMaxDimension &&
max_frame_size.height() <= media::limits::kMaxDimension;
}

} // namespace

namespace electron {

OffScreenVideoConsumer::OffScreenVideoConsumer(
Expand All @@ -21,11 +37,11 @@ OffScreenVideoConsumer::OffScreenVideoConsumer(
: callback_(callback),
view_(view),
video_capturer_(view->CreateVideoCapturer()) {
video_capturer_->SetResolutionConstraints(view_->SizeInPixels(),
view_->SizeInPixels(), true);
video_capturer_->SetAutoThrottlingEnabled(false);
video_capturer_->SetMinSizeChangePeriod(base::TimeDelta());
video_capturer_->SetFormat(media::PIXEL_FORMAT_ARGB);

SizeChanged(view_->SizeInPixels());
SetFrameRate(view_->GetFrameRate());
}

Expand All @@ -43,9 +59,10 @@ void OffScreenVideoConsumer::SetFrameRate(int frame_rate) {
video_capturer_->SetMinCapturePeriod(base::Seconds(1) / frame_rate);
}

void OffScreenVideoConsumer::SizeChanged() {
video_capturer_->SetResolutionConstraints(view_->SizeInPixels(),
view_->SizeInPixels(), true);
void OffScreenVideoConsumer::SizeChanged(const gfx::Size& size_in_pixels) {
DCHECK(IsValidMinAndMaxFrameSize(size_in_pixels, size_in_pixels));
video_capturer_->SetResolutionConstraints(size_in_pixels, size_in_pixels,
true);
video_capturer_->RequestRefreshFrame();
}

Expand All @@ -58,9 +75,7 @@ void OffScreenVideoConsumer::OnFrameCaptured(
auto& data_region = data->get_read_only_shmem_region();

if (!CheckContentRect(content_rect)) {
gfx::Size view_size = view_->SizeInPixels();
video_capturer_->SetResolutionConstraints(view_size, view_size, true);
video_capturer_->RequestRefreshFrame();
SizeChanged(view_->SizeInPixels());
return;
}

Expand Down
2 changes: 1 addition & 1 deletion shell/browser/osr/osr_video_consumer.h
Expand Up @@ -33,7 +33,7 @@ class OffScreenVideoConsumer : public viz::mojom::FrameSinkVideoConsumer {

void SetActive(bool active);
void SetFrameRate(int frame_rate);
void SizeChanged();
void SizeChanged(const gfx::Size& size_in_pixels);

private:
// viz::mojom::FrameSinkVideoConsumer implementation.
Expand Down