Skip to content

Commit

Permalink
fix: offscreen rendering crash on input select (#34092)
Browse files Browse the repository at this point in the history
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
  • Loading branch information
trop[bot] and codebytere committed May 5, 2022
1 parent 8acf68c commit fe96879
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 31 deletions.
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 @@ -121,7 +121,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

0 comments on commit fe96879

Please sign in to comment.