diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 2426de7ac3435..c1881db488ef9 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -378,8 +378,8 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options) options.Get("transparent", &transparent); content::WebContents::CreateParams params(session->browser_context()); - auto* view = new OffScreenWebContentsView( - transparent, base::Bind(&WebContents::OnPaint, base::Unretained(this))); + auto* view = new OffScreenWebContentsView(transparent, + base::Bind(&WebContents::OnPaint, base::Unretained(this))); params.view = view; params.delegate_view = view; @@ -1652,10 +1652,10 @@ void WebContents::StartPainting() { return; #if defined(ENABLE_OSR) - auto* osr_rwhv = static_cast( - web_contents()->GetRenderWidgetHostView()); - if (osr_rwhv) - osr_rwhv->SetPainting(true); + const auto* wc_impl = static_cast(web_contents()); + auto* osr_wcv = static_cast(wc_impl->GetView()); + if (osr_wcv) + osr_wcv->SetPainting(true); #endif } @@ -1664,10 +1664,10 @@ void WebContents::StopPainting() { return; #if defined(ENABLE_OSR) - auto* osr_rwhv = static_cast( - web_contents()->GetRenderWidgetHostView()); - if (osr_rwhv) - osr_rwhv->SetPainting(false); + const auto* wc_impl = static_cast(web_contents()); + auto* osr_wcv = static_cast(wc_impl->GetView()); + if (osr_wcv) + osr_wcv->SetPainting(false); #endif } @@ -1676,9 +1676,10 @@ bool WebContents::IsPainting() const { return false; #if defined(ENABLE_OSR) - const auto* osr_rwhv = static_cast( - web_contents()->GetRenderWidgetHostView()); - return osr_rwhv && osr_rwhv->IsPainting(); + const auto* wc_impl = static_cast(web_contents()); + auto* osr_wcv = static_cast(wc_impl->GetView()); + + return osr_wcv && osr_wcv->IsPainting(); #else return false; #endif @@ -1689,10 +1690,11 @@ void WebContents::SetFrameRate(int frame_rate) { return; #if defined(ENABLE_OSR) - auto* osr_rwhv = static_cast( - web_contents()->GetRenderWidgetHostView()); - if (osr_rwhv) - osr_rwhv->SetFrameRate(frame_rate); + const auto* wc_impl = static_cast(web_contents()); + auto* osr_wcv = static_cast(wc_impl->GetView()); + + if (osr_wcv) + osr_wcv->SetFrameRate(frame_rate); #endif } @@ -1701,9 +1703,10 @@ int WebContents::GetFrameRate() const { return 0; #if defined(ENABLE_OSR) - const auto* osr_rwhv = static_cast( - web_contents()->GetRenderWidgetHostView()); - return osr_rwhv ? osr_rwhv->GetFrameRate() : 0; + const auto* wc_impl = static_cast(web_contents()); + auto* osr_wcv = static_cast(wc_impl->GetView()); + + return osr_wcv ? osr_wcv->GetFrameRate() : 0; #else return 0; #endif diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index 295b3f886dbfd..a2f54076657f2 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -124,7 +124,7 @@ class AtomCopyFrameGenerator { } void GenerateCopyFrame(const gfx::Rect& damage_rect) { - if (!view_->render_widget_host()) + if (!view_->render_widget_host() || !view_->IsPainting()) return; std::unique_ptr request = @@ -255,6 +255,8 @@ class AtomBeginFrameTimer : public cc::DelayBasedTimeSourceClient { OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView( bool transparent, + bool painting, + int frame_rate, const OnPaintCallback& callback, content::RenderWidgetHost* host, OffScreenRenderWidgetHostView* parent_host_view, @@ -268,17 +270,18 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView( transparent_(transparent), callback_(callback), parent_callback_(nullptr), - frame_rate_(60), + frame_rate_(frame_rate), frame_rate_threshold_us_(0), last_time_(base::Time::Now()), scale_factor_(kDefaultScaleFactor), size_(native_window->GetSize()), - painting_(true), + painting_(painting), is_showing_(!render_widget_host_->is_hidden()), is_destroyed_(false), popup_position_(gfx::Rect()), hold_resize_(false), pending_resize_(false), + paint_callback_running_(false), renderer_compositor_frame_sink_(nullptr), background_color_(SkColor()), weak_ptr_factory_(this) { @@ -303,7 +306,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView( new ui::Compositor(context_factory_private->AllocateFrameSinkId(), content::GetContextFactory(), context_factory_private, base::ThreadTaskRunnerHandle::Get(), false)); - compositor_->SetAcceleratedWidget(native_window_->GetAcceleratedWidget()); + compositor_->SetAcceleratedWidget(gfx::kNullAcceleratedWidget); compositor_->SetRootLayer(root_layer_.get()); #endif GetCompositor()->SetDelegate(this); @@ -737,6 +740,8 @@ content::RenderWidgetHostViewBase* return new OffScreenRenderWidgetHostView( transparent_, + true, + embedder_host_view->GetFrameRate(), callback_, render_widget_host, embedder_host_view, @@ -928,7 +933,7 @@ bool OffScreenRenderWidgetHostView::IsAutoResizeEnabled() const { void OffScreenRenderWidgetHostView::SetNeedsBeginFrames( bool needs_begin_frames) { - SetupFrameRate(false); + SetupFrameRate(true); begin_frame_timer_->SetActive(needs_begin_frames); @@ -999,7 +1004,9 @@ void OffScreenRenderWidgetHostView::OnPaint( } damage.Intersect(GetViewBounds()); + paint_callback_running_ = true; callback_.Run(damage, bitmap); + paint_callback_running_ = false; for (size_t i = 0; i < damages.size(); i++) { CopyBitmapTo(bitmap, originals[i], damages[i]); @@ -1147,7 +1154,7 @@ void OffScreenRenderWidgetHostView::SetPainting(bool painting) { painting_ = painting; if (software_output_device_) { - software_output_device_->SetActive(painting_, true); + software_output_device_->SetActive(painting_, !paint_callback_running_); } } @@ -1164,16 +1171,16 @@ void OffScreenRenderWidgetHostView::SetFrameRate(int frame_rate) { } else { if (frame_rate <= 0) frame_rate = 1; - if (frame_rate > 60) - frame_rate = 60; + if (frame_rate > 240) + frame_rate = 240; frame_rate_ = frame_rate; } + SetupFrameRate(true); + for (auto guest_host_view : guest_host_views_) guest_host_view->SetFrameRate(frame_rate); - - SetupFrameRate(true); } int OffScreenRenderWidgetHostView::GetFrameRate() const { @@ -1201,7 +1208,7 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) { frame_rate_threshold_us_ = 1000000 / frame_rate_; - GetCompositor()->vsync_manager()->SetAuthoritativeVSyncInterval( + GetCompositor()->SetAuthoritativeVSyncInterval( base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_)); if (copy_frame_generator_.get()) { diff --git a/atom/browser/osr/osr_render_widget_host_view.h b/atom/browser/osr/osr_render_widget_host_view.h index ed4b160440e6b..3858d69eba63c 100644 --- a/atom/browser/osr/osr_render_widget_host_view.h +++ b/atom/browser/osr/osr_render_widget_host_view.h @@ -74,6 +74,8 @@ class OffScreenRenderWidgetHostView public OffscreenViewProxyObserver { public: OffScreenRenderWidgetHostView(bool transparent, + bool painting, + int frame_rate, const OnPaintCallback& callback, content::RenderWidgetHost* render_widget_host, OffScreenRenderWidgetHostView* parent_host_view, @@ -315,6 +317,8 @@ class OffScreenRenderWidgetHostView bool hold_resize_; bool pending_resize_; + bool paint_callback_running_; + std::unique_ptr root_layer_; std::unique_ptr compositor_; std::unique_ptr delegated_frame_host_; diff --git a/atom/browser/osr/osr_web_contents_view.cc b/atom/browser/osr/osr_web_contents_view.cc index 0e10abf6a034a..4cbc6a5c42f97 100644 --- a/atom/browser/osr/osr_web_contents_view.cc +++ b/atom/browser/osr/osr_web_contents_view.cc @@ -15,6 +15,8 @@ namespace atom { OffScreenWebContentsView::OffScreenWebContentsView( bool transparent, const OnPaintCallback& callback) : transparent_(transparent), + painting_(true), + frame_rate_(60), callback_(callback), web_contents_(nullptr) { #if defined(OS_MACOSX) @@ -103,6 +105,8 @@ content::RenderWidgetHostViewBase* auto relay = NativeWindowRelay::FromWebContents(web_contents_); return new OffScreenRenderWidgetHostView( transparent_, + painting_, + GetFrameRate(), callback_, render_widget_host, nullptr, @@ -125,6 +129,8 @@ content::RenderWidgetHostViewBase* return new OffScreenRenderWidgetHostView( transparent_, + true, + view->GetFrameRate(), callback_, render_widget_host, view, @@ -202,6 +208,42 @@ void OffScreenWebContentsView::UpdateDragCursor( blink::WebDragOperation operation) { } +void OffScreenWebContentsView::SetPainting(bool painting) { + auto* view = GetView(); + if (view != nullptr) { + view->SetPainting(painting); + } else { + painting_ = painting; + } +} + +bool OffScreenWebContentsView::IsPainting() const { + auto* view = GetView(); + if (view != nullptr) { + return view->IsPainting(); + } else { + return painting_; + } +} + +void OffScreenWebContentsView::SetFrameRate(int frame_rate) { + auto* view = GetView(); + if (view != nullptr) { + view->SetFrameRate(frame_rate); + } else { + frame_rate_ = frame_rate; + } +} + +int OffScreenWebContentsView::GetFrameRate() const { + auto* view = GetView(); + if (view != nullptr) { + return view->GetFrameRate(); + } else { + return frame_rate_; + } +} + OffScreenRenderWidgetHostView* OffScreenWebContentsView::GetView() const { if (web_contents_) { return static_cast( diff --git a/atom/browser/osr/osr_web_contents_view.h b/atom/browser/osr/osr_web_contents_view.h index ffb3b38619c45..788e55bf316d8 100644 --- a/atom/browser/osr/osr_web_contents_view.h +++ b/atom/browser/osr/osr_web_contents_view.h @@ -69,6 +69,11 @@ class OffScreenWebContentsView : public content::WebContentsView, content::RenderWidgetHostImpl* source_rwh) override; void UpdateDragCursor(blink::WebDragOperation operation) override; + void SetPainting(bool painting); + bool IsPainting() const; + void SetFrameRate(int frame_rate); + int GetFrameRate() const; + private: #if defined(OS_MACOSX) void PlatformCreate(); @@ -78,6 +83,8 @@ class OffScreenWebContentsView : public content::WebContentsView, OffScreenRenderWidgetHostView* GetView() const; const bool transparent_; + bool painting_; + int frame_rate_; OnPaintCallback callback_; // Weak refs.