From 0ad0c79202fe28fde19bcd44393aa884b8839d0c Mon Sep 17 00:00:00 2001 From: gellert Date: Fri, 22 Jul 2016 13:55:58 +0200 Subject: [PATCH] adds beginframe scheduling --- atom/browser/api/atom_api_web_contents.cc | 7 + atom/browser/common_web_contents_delegate.cc | 10 +- atom/browser/osr_web_contents_view.cc | 44 +-- atom/browser/osr_window.cc | 271 +++++++++++-------- atom/browser/osr_window.h | 6 + atom/browser/web_contents_preferences.cc | 8 + default_app/default_app.js | 242 ++++++++++++++++- default_app/main.js | 2 +- 8 files changed, 433 insertions(+), 157 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index caf7bcbc1932..134c2936f0f4 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -68,6 +68,9 @@ #include "third_party/WebKit/public/web/WebFindOptions.h" #include "ui/display/screen.h" +#include "content/browser/web_contents/web_contents_impl.h" +#include "atom/browser/osr_web_contents_view.h" + #include "atom/common/node_includes.h" namespace { @@ -309,6 +312,10 @@ WebContents::WebContents(v8::Isolate* isolate, web_contents = content::WebContents::Create(params); } + content::WebContentsImpl* impl = + reinterpret_cast(web_contents); + impl->SetView(new OffScreenWebContentsView); + Observe(web_contents); InitWithWebContents(web_contents, session->browser_context()); diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index 5f32bf65c38a..8e4f79a2d684 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -33,8 +33,8 @@ #include "content/public/browser/security_style_explanations.h" #include "storage/browser/fileapi/isolated_context.h" -#include "content/browser/web_contents/web_contents_impl.h" -#include "atom/browser/osr_web_contents_view.h" +// #include "content/browser/web_contents/web_contents_impl.h" +// #include "atom/browser/osr_web_contents_view.h" #include "atom/browser/native_window_views.h" using content::BrowserThread; @@ -188,15 +188,15 @@ void CommonWebContentsDelegate::InitWithWebContents( printing::PrintViewManagerBasic::CreateForWebContents(web_contents); printing::PrintPreviewMessageHandler::CreateForWebContents(web_contents); - content::WebContentsImpl* impl = - reinterpret_cast(web_contents); + // content::WebContentsImpl* impl = + // reinterpret_cast(web_contents); std::cout << "end" << std::endl; // Create InspectableWebContents. web_contents_.reset(brightray::InspectableWebContents::Create(web_contents)); web_contents_->SetDelegate(this); - impl->SetView(new OffScreenWebContentsView); + // impl->SetView(new OffScreenWebContentsView); std::cout << "end" << std::endl; } diff --git a/atom/browser/osr_web_contents_view.cc b/atom/browser/osr_web_contents_view.cc index 226340b0d246..90d425c7ca1f 100644 --- a/atom/browser/osr_web_contents_view.cc +++ b/atom/browser/osr_web_contents_view.cc @@ -10,16 +10,16 @@ namespace atom { OffScreenWebContentsView::OffScreenWebContentsView() { - std::cout << "OffScreenWebContentsView" << std::endl; + // std::cout << "OffScreenWebContentsView" << std::endl; //std::this_thread::sleep_for(std::chrono::milliseconds(10000)); } OffScreenWebContentsView::~OffScreenWebContentsView() { - std::cout << "~OffScreenWebContentsView" << std::endl; + // std::cout << "~OffScreenWebContentsView" << std::endl; } // Returns the native widget that contains the contents of the tab. gfx::NativeView OffScreenWebContentsView::GetNativeView() const{ - std::cout << "GetNativeView" << std::endl; + // std::cout << "GetNativeView" << std::endl; return gfx::NativeView(); } @@ -27,21 +27,21 @@ gfx::NativeView OffScreenWebContentsView::GetNativeView() const{ // render view host, though there may be many popups in the tab as children of // the container). gfx::NativeView OffScreenWebContentsView::GetContentNativeView() const{ - std::cout << "GetContentNativeView" << std::endl; + // std::cout << "GetContentNativeView" << std::endl; return gfx::NativeView(); } // Returns the outermost native view. This will be used as the parent for // dialog boxes. gfx::NativeWindow OffScreenWebContentsView::GetTopLevelNativeWindow() const{ - std::cout << "GetTopLevelNativeWindow" << std::endl; + // std::cout << "GetTopLevelNativeWindow" << std::endl; return gfx::NativeWindow(); } // Computes the rectangle for the native widget that contains the contents of // the tab in the screen coordinate system. void OffScreenWebContentsView::GetContainerBounds(gfx::Rect* out) const{ - std::cout << "GetContainerBounds" << std::endl; + // std::cout << "GetContainerBounds" << std::endl; *out = GetViewBounds(); } @@ -54,47 +54,47 @@ void OffScreenWebContentsView::GetContainerBounds(gfx::Rect* out) const{ // should be cleaned up or done some other way, since this works for normal // WebContents without the special code. void OffScreenWebContentsView::SizeContents(const gfx::Size& size){ - std::cout << "SizeContents" << std::endl; + // std::cout << "SizeContents" << std::endl; } // Sets focus to the native widget for this tab. void OffScreenWebContentsView::Focus(){ - std::cout << "OffScreenWebContentsView::Focus" << std::endl; + // std::cout << "OffScreenWebContentsView::Focus" << std::endl; } // Sets focus to the appropriate element when the WebContents is shown the // first time. void OffScreenWebContentsView::SetInitialFocus(){ - std::cout << "SetInitialFocus" << std::endl; + // std::cout << "SetInitialFocus" << std::endl; } // Stores the currently focused view. void OffScreenWebContentsView::StoreFocus(){ - std::cout << "StoreFocus" << std::endl; + // std::cout << "StoreFocus" << std::endl; } // Restores focus to the last focus view. If StoreFocus has not yet been // invoked, SetInitialFocus is invoked. void OffScreenWebContentsView::RestoreFocus(){ - std::cout << "RestoreFocus" << std::endl; + // std::cout << "RestoreFocus" << std::endl; } // Returns the current drop data, if any. content::DropData* OffScreenWebContentsView::GetDropData() const{ - std::cout << "GetDropData" << std::endl; + // std::cout << "GetDropData" << std::endl; return nullptr; } // Get the bounds of the View, relative to the parent. gfx::Rect OffScreenWebContentsView::GetViewBounds() const{ - std::cout << "OffScreenWebContentsView::GetViewBounds" << std::endl; + // std::cout << "OffScreenWebContentsView::GetViewBounds" << std::endl; return view_ ? view_->GetViewBounds() : gfx::Rect(); } void OffScreenWebContentsView::CreateView( const gfx::Size& initial_size, gfx::NativeView context){ - std::cout << "CreateView" << std::endl; - std::cout << initial_size.width() << "x" << initial_size.height() << std::endl; + // std::cout << "CreateView" << std::endl; + // std::cout << initial_size.width() << "x" << initial_size.height() << std::endl; } // Sets up the View that holds the rendered web page, receives messages for @@ -108,7 +108,7 @@ void OffScreenWebContentsView::CreateView( content::RenderWidgetHostViewBase* OffScreenWebContentsView::CreateViewForWidget( content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack){ - std::cout << "CreateViewForWidget" << std::endl; + // std::cout << "CreateViewForWidget" << std::endl; view_ = new OffScreenWindow(render_widget_host); return view_; } @@ -117,7 +117,7 @@ content::RenderWidgetHostViewBase* content::RenderWidgetHostViewBase* OffScreenWebContentsView::CreateViewForPopupWidget( content::RenderWidgetHost* render_widget_host){ - std::cout << "CreateViewForPopupWidget" << std::endl; + // std::cout << "CreateViewForPopupWidget" << std::endl; view_ = new OffScreenWindow(render_widget_host); return view_; } @@ -127,25 +127,25 @@ content::RenderWidgetHostViewBase* // can aid certain debugging tools such as Spy++ on Windows where you are // trying to find a specific window. void OffScreenWebContentsView::SetPageTitle(const base::string16& title){ - std::cout << "SetPageTitle" << std::endl; - std::cout << title << std::endl; + // std::cout << "SetPageTitle" << std::endl; + // std::cout << title << std::endl; } // Invoked when the WebContents is notified that the RenderView has been // fully created. void OffScreenWebContentsView::RenderViewCreated(content::RenderViewHost* host){ - std::cout << "RenderViewCreated" << std::endl; + // std::cout << "RenderViewCreated" << std::endl; } // Invoked when the WebContents is notified that the RenderView has been // swapped in. void OffScreenWebContentsView::RenderViewSwappedIn(content::RenderViewHost* host){ - std::cout << "RenderViewSwappedIn" << std::endl; + // std::cout << "RenderViewSwappedIn" << std::endl; } // Invoked to enable/disable overscroll gesture navigation. void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled){ - std::cout << "SetOverscrollControllerEnabled" << std::endl; + // std::cout << "SetOverscrollControllerEnabled" << std::endl; } #if defined(OS_MACOSX) diff --git a/atom/browser/osr_window.cc b/atom/browser/osr_window.cc index 1efd0d9ce842..1e62fb761cd7 100644 --- a/atom/browser/osr_window.cc +++ b/atom/browser/osr_window.cc @@ -128,7 +128,7 @@ class CefCopyFrameGenerator { weak_ptr_factory_.GetWeakPtr(), damage_rect)); - // request->set_area(gfx::Rect(view_->GetPhysicalBackingSize())); + request->set_area(gfx::Rect(view_->GetPhysicalBackingSize())); view_->DelegatedFrameHostGetLayer()->RequestCopyOfOutput( std::move(request)); @@ -137,7 +137,7 @@ class CefCopyFrameGenerator { void CopyFromCompositingSurfaceHasResult( const gfx::Rect& damage_rect, std::unique_ptr result) { - std::cout << "has result" << std::endl; + // std::cout << "has result" << std::endl; if (result->IsEmpty() || result->size().IsEmpty() || !view_->render_widget_host()) { OnCopyFrameCaptureFailure(damage_rect); @@ -292,17 +292,12 @@ class CefCopyFrameGenerator { const SkBitmap& bitmap, std::unique_ptr bitmap_pixels_lock) { - - // view_->OnPaint(damage_rect, bitmap.width(), bitmap.height(), - // bitmap.getPixels()); - uint8_t* pixels = reinterpret_cast(bitmap.getPixels()); - for (int i = 0; i<4; i++) { - int x = static_cast(pixels[i]); - std::cout << std::hex << x << std::dec << std::endl; - } + // for (int i = 0; i<4; i++) { + // int x = static_cast(pixels[i]); + // std::cout << std::hex << x << std::dec << std::endl; + // } if (view_->paintCallback) { - std::cout << "FRAME COPY ARRIVED" << std::endl; view_->paintCallback->Run(damage_rect, bitmap.width(), bitmap.height(), pixels); } @@ -386,6 +381,7 @@ class CefBeginFrameTimer : public cc::DelayBasedTimeSourceClient { OffScreenWindow::OffScreenWindow(content::RenderWidgetHost* host) : render_widget_host_(content::RenderWidgetHostImpl::From(host)), + software_output_device_(NULL), frame_rate_threshold_ms_(0), scale_factor_(1.0f), is_showing_(!render_widget_host_->is_hidden()), @@ -394,7 +390,7 @@ OffScreenWindow::OffScreenWindow(content::RenderWidgetHost* host) compositor_widget_(gfx::kNullAcceleratedWidget), weak_ptr_factory_(this) { DCHECK(render_widget_host_); - std::cout << "OffScreenWindow" << std::endl; + // std::cout << "OffScreenWindow" << std::endl; render_widget_host_->SetView(this); root_layer_.reset(new ui::Layer(ui::LAYER_SOLID_COLOR)); @@ -410,14 +406,29 @@ OffScreenWindow::OffScreenWindow(content::RenderWidgetHost* host) #endif // compositor_->SetDelegate(this); compositor_->SetRootLayer(root_layer_.get()); +} - frame_rate_threshold_ms_ = 1000 / 24; - begin_frame_timer_.reset(new CefBeginFrameTimer( - frame_rate_threshold_ms_, - base::Bind(&OffScreenWindow::OnBeginFrameTimerTick, - weak_ptr_factory_.GetWeakPtr()))); +void OffScreenWindow::ResizeRootLayer() { + SetFrameRate(); - // begin_frame_timer_->SetActive(true); + // const float orgScaleFactor = scale_factor_; + // SetDeviceScaleFactor(); + // const bool scaleFactorDidChange = (orgScaleFactor != scale_factor_); + // + // gfx::Size size; + // if (!IsPopupWidget()) + // size = GetViewBounds().size(); + // else + // size = popup_position_.size(); + // + // if (!scaleFactorDidChange && size == root_layer_->bounds().size()) + // return; + // + // const gfx::Size& size_in_pixels = + // gfx::ConvertSizeToPixel(scale_factor_, size); + // + // root_layer_->SetBounds(gfx::Rect(size)); + // compositor_->SetScaleAndSize(scale_factor_, size_in_pixels); } void OffScreenWindow::OnBeginFrameTimerTick() { @@ -425,9 +436,6 @@ void OffScreenWindow::OnBeginFrameTimerTick() { const base::TimeDelta vsync_period = base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms_); SendBeginFrame(frame_time, vsync_period); - - std::cout << "tickkkk" << std::endl; - // copy_frame_generator_->GenerateCopyFrame(true, damage_rect); } void OffScreenWindow::SendBeginFrame(base::TimeTicks frame_time, @@ -445,6 +453,7 @@ void OffScreenWindow::SendBeginFrame(base::TimeTicks frame_time, render_widget_host_->GetRoutingID(), cc::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline, vsync_period, cc::BeginFrameArgs::NORMAL))); + // std::cout << "sent begin frame" << std::endl; } void OffScreenWindow::SetPaintCallback(const OnPaintCallback *callback) { @@ -452,7 +461,7 @@ void OffScreenWindow::SetPaintCallback(const OnPaintCallback *callback) { } OffScreenWindow::~OffScreenWindow() { - std::cout << "~OffScreenWindow" << std::endl; + // std::cout << "~OffScreenWindow" << std::endl; if (is_showing_) delegated_frame_host_->WasHidden(); @@ -464,7 +473,7 @@ OffScreenWindow::~OffScreenWindow() { } bool OffScreenWindow::OnMessageReceived(const IPC::Message& message) { - std::cout << "OnMessageReceived" << std::endl; + // std::cout << "OnMessageReceived" << std::endl; bool handled = true; IPC_BEGIN_MESSAGE_MAP(OffScreenWindow, message) @@ -479,19 +488,19 @@ bool OffScreenWindow::OnMessageReceived(const IPC::Message& message) { } void OffScreenWindow::InitAsChild(gfx::NativeView) { - std::cout << "InitAsChild" << std::endl; + // std::cout << "InitAsChild" << std::endl; } content::RenderWidgetHost* OffScreenWindow::GetRenderWidgetHost() const { - std::cout << "GetRenderWidgetHost" << std::endl; + // std::cout << "GetRenderWidgetHost" << std::endl; return render_widget_host_; } void OffScreenWindow::SetSize(const gfx::Size& size) { - std::cout << "SetSize" << std::endl; + // std::cout << "SetSize" << std::endl; size_ = size; - std::cout << size.width() << "x" << size.height() << std::endl; + // std::cout << size.width() << "x" << size.height() << std::endl; const gfx::Size& size_in_pixels = gfx::ConvertSizeToPixel(scale_factor_, size); @@ -501,50 +510,50 @@ void OffScreenWindow::SetSize(const gfx::Size& size) { } void OffScreenWindow::SetBounds(const gfx::Rect& new_bounds) { - std::cout << "SetBounds" << std::endl; + // std::cout << "SetBounds" << std::endl; } gfx::Vector2dF OffScreenWindow::GetLastScrollOffset() const { - std::cout << "GetLastScrollOffset" << std::endl; + // std::cout << "GetLastScrollOffset" << std::endl; return last_scroll_offset_; } gfx::NativeView OffScreenWindow::GetNativeView() const { - std::cout << "GetNativeView" << std::endl; + // std::cout << "GetNativeView" << std::endl; return gfx::NativeView(); } gfx::NativeViewId OffScreenWindow::GetNativeViewId() const { - std::cout << "GetNativeViewId" << std::endl; + // std::cout << "GetNativeViewId" << std::endl; return gfx::NativeViewId(); } gfx::NativeViewAccessible OffScreenWindow::GetNativeViewAccessible() { - std::cout << "GetNativeViewAccessible" << std::endl; + // std::cout << "GetNativeViewAccessible" << std::endl; return gfx::NativeViewAccessible(); } ui::TextInputClient* OffScreenWindow::GetTextInputClient() { - std::cout << "GetTextInputClient" << std::endl; + // std::cout << "GetTextInputClient" << std::endl; return nullptr; } void OffScreenWindow::Focus() { - std::cout << "Focus" << std::endl; + // std::cout << "Focus" << std::endl; } bool OffScreenWindow::HasFocus() const { - std::cout << "HasFocus" << std::endl; + // std::cout << "HasFocus" << std::endl; return false; } bool OffScreenWindow::IsSurfaceAvailableForCopy() const { - std::cout << "IsSurfaceAvailableForCopy" << std::endl; + // std::cout << "IsSurfaceAvailableForCopy" << std::endl; return delegated_frame_host_->CanCopyToBitmap(); } void OffScreenWindow::Show() { - std::cout << "Show" << std::endl; + // std::cout << "Show" << std::endl; if (is_showing_) return; @@ -556,7 +565,7 @@ void OffScreenWindow::Show() { } void OffScreenWindow::Hide() { - std::cout << "Hide" << std::endl; + // std::cout << "Hide" << std::endl; if (!is_showing_) return; @@ -568,54 +577,65 @@ void OffScreenWindow::Hide() { } bool OffScreenWindow::IsShowing() { - std::cout << "IsShowing" << std::endl; + // std::cout << "IsShowing" << std::endl; return is_showing_; } gfx::Rect OffScreenWindow::GetViewBounds() const { - std::cout << "GetViewBounds" << std::endl; - std::cout << size_.width() << "x" << size_.height() << std::endl; + // std::cout << "GetViewBounds" << std::endl; + // std::cout << size_.width() << "x" << size_.height() << std::endl; return gfx::Rect(size_); } gfx::Size OffScreenWindow::GetVisibleViewportSize() const { - std::cout << "GetVisibleViewportSize" << std::endl; - std::cout << size_.width() << "x" << size_.height() << std::endl; + // std::cout << "GetVisibleViewportSize" << std::endl; + // std::cout << size_.width() << "x" << size_.height() << std::endl; return size_; } void OffScreenWindow::SetInsets(const gfx::Insets& insets) { - std::cout << "SetInsets" << std::endl; + // std::cout << "SetInsets" << std::endl; } bool OffScreenWindow::LockMouse() { - std::cout << "LockMouse" << std::endl; + // std::cout << "LockMouse" << std::endl; return false; } void OffScreenWindow::UnlockMouse() { - std::cout << "UnlockMouse" << std::endl; + // std::cout << "UnlockMouse" << std::endl; } bool OffScreenWindow::GetScreenColorProfile(std::vector*) { - std::cout << "GetScreenColorProfile" << std::endl; + // std::cout << "GetScreenColorProfile" << std::endl; return false; } void OffScreenWindow::OnSwapCompositorFrame( uint32_t output_surface_id, std::unique_ptr frame) { - std::cout << "OnSwapCompositorFrame" << std::endl; + // std::cout << "OnSwapCompositorFrame" << std::endl; - std::cout << output_surface_id << std::endl; - - if (frame->delegated_frame_data) - std::cout << "delegated_frame_data" << std::endl; + // std::cout << output_surface_id << std::endl; if (frame->metadata.root_scroll_offset != last_scroll_offset_) { last_scroll_offset_ = frame->metadata.root_scroll_offset; } + if (!frame->delegated_frame_data) { + return; + } + + if (software_output_device_) { + // if (!begin_frame_timer_.get()) { + // software_output_device_->SetActive(true); + // } + + delegated_frame_host_->SwapDelegatedFrame(output_surface_id, + std::move(frame)); + return; + } + if (!copy_frame_generator_.get()) { copy_frame_generator_.reset( new CefCopyFrameGenerator(frame_rate_threshold_ms_, this)); @@ -629,7 +649,6 @@ void OffScreenWindow::OnSwapCompositorFrame( gfx::Rect damage_rect = gfx::ToEnclosingRect(gfx::RectF(root_pass->damage_rect)); damage_rect.Intersect(gfx::Rect(frame_size)); - // gfx::Rect damage_rect = gfx::Rect(GetVisibleViewportSize()); if (frame->delegated_frame_data) delegated_frame_host_->SwapDelegatedFrame(output_surface_id, @@ -637,78 +656,64 @@ void OffScreenWindow::OnSwapCompositorFrame( // Request a copy of the last compositor frame which will eventually call // OnPaint asynchronously. - std::cout << "FRAME COPY REQUESTED" << std::endl; + // std::cout << "FRAME COPY REQUESTED" << std::endl; copy_frame_generator_->GenerateCopyFrame(true, damage_rect); - - // gfx::Rect rect = gfx::Rect(GetVisibleViewportSize()); - // // The below code is similar in functionality to - // // DelegatedFrameHost::CopyFromCompositingSurface but we reuse the same - // // SkBitmap in the GPU codepath and avoid scaling where possible. - // std::unique_ptr request = - // cc::CopyOutputRequest::CreateRequest(base::Bind( - // &OffScreenWindow::CopyFromCompositingSurfaceHasResult, - // weak_ptr_factory_.GetWeakPtr(), - // rect)); - // - // request->set_area(gfx::Rect(GetPhysicalBackingSize())); - // DelegatedFrameHostGetLayer()->RequestCopyOfOutput( - // std::move(request)); } void OffScreenWindow::ClearCompositorFrame() { - std::cout << "ClearCompositorFrame" << std::endl; + // std::cout << "ClearCompositorFrame" << std::endl; delegated_frame_host_->ClearDelegatedFrame(); } void OffScreenWindow::InitAsPopup( content::RenderWidgetHostView *, const gfx::Rect &) { - std::cout << "InitAsPopup" << std::endl; + // std::cout << "InitAsPopup" << std::endl; } void OffScreenWindow::InitAsFullscreen(content::RenderWidgetHostView *) { - std::cout << "InitAsFullscreen" << std::endl; + // std::cout << "InitAsFullscreen" << std::endl; } void OffScreenWindow::UpdateCursor(const content::WebCursor &) { - std::cout << "UpdateCursor" << std::endl; + // std::cout << "UpdateCursor" << std::endl; } void OffScreenWindow::SetIsLoading(bool loading) { - std::cout << "SetIsLoading" << std::endl; + // std::cout << "SetIsLoading" << std::endl; } void OffScreenWindow::TextInputStateChanged( const ViewHostMsg_TextInputState_Params &) { - std::cout << "TextInputStateChanged" << std::endl; + // std::cout << "TextInputStateChanged" << std::endl; } void OffScreenWindow::ImeCancelComposition() { - std::cout << "ImeCancelComposition" << std::endl; + // std::cout << "ImeCancelComposition" << std::endl; } void OffScreenWindow::RenderProcessGone(base::TerminationStatus,int) { - std::cout << "RenderProcessGone" << std::endl; + // std::cout << "RenderProcessGone" << std::endl; Destroy(); } void OffScreenWindow::Destroy() { - std::cout << "Destroy" << std::endl; + // std::cout << "Destroy" << std::endl; } void OffScreenWindow::SetTooltipText(const base::string16 &) { - std::cout << "SetTooltipText" << std::endl; + // std::cout << "SetTooltipText" << std::endl; } void OffScreenWindow::SelectionBoundsChanged( const ViewHostMsg_SelectionBounds_Params &) { - std::cout << "SelectionBoundsChanged" << std::endl; + // std::cout << "SelectionBoundsChanged" << std::endl; } void OffScreenWindow::CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, const content::ReadbackRequestCallback& callback, const SkColorType preferred_color_type) { - std::cout << "CopyFromCompositingSurface" << std::endl; + // std::cout << "CopyFromCompositingSurface" << std::endl; delegated_frame_host_->CopyFromCompositingSurface( src_subrect, dst_size, callback, preferred_color_type); } @@ -717,35 +722,35 @@ void OffScreenWindow::CopyFromCompositingSurfaceToVideoFrame( const gfx::Rect& src_subrect, const scoped_refptr& target, const base::Callback& callback) { - std::cout << "CopyFromCompositingSurfaceToVideoFrame" << std::endl; + // std::cout << "CopyFromCompositingSurfaceToVideoFrame" << std::endl; delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame( src_subrect, target, callback); } bool OffScreenWindow::CanCopyToVideoFrame() const { - std::cout << "CanCopyToVideoFrame" << std::endl; + // std::cout << "CanCopyToVideoFrame" << std::endl; return delegated_frame_host_->CanCopyToVideoFrame(); } void OffScreenWindow::BeginFrameSubscription( std::unique_ptr subscriber) { - std::cout << "BeginFrameSubscription" << std::endl; + // std::cout << "BeginFrameSubscription" << std::endl; delegated_frame_host_->BeginFrameSubscription(std::move(subscriber)); } void OffScreenWindow::EndFrameSubscription() { - std::cout << "EndFrameSubscription" << std::endl; + // std::cout << "EndFrameSubscription" << std::endl; delegated_frame_host_->EndFrameSubscription(); } bool OffScreenWindow::HasAcceleratedSurface(const gfx::Size &) { - std::cout << "HasAcceleratedSurface" << std::endl; + // std::cout << "HasAcceleratedSurface" << std::endl; return false; } void OffScreenWindow::GetScreenInfo(blink::WebScreenInfo* results) { - std::cout << "GetScreenInfo" << std::endl; - std::cout << size_.width() << "x" << size_.height() << std::endl; + // std::cout << "GetScreenInfo" << std::endl; + // std::cout << size_.width() << "x" << size_.height() << std::endl; results->rect = gfx::Rect(size_); results->availableRect = gfx::Rect(size_); results->depth = 24; @@ -756,86 +761,86 @@ void OffScreenWindow::GetScreenInfo(blink::WebScreenInfo* results) { } bool OffScreenWindow::GetScreenColorProfile(blink::WebVector*) { - std::cout << "GetScreenColorProfile" << std::endl; + // std::cout << "GetScreenColorProfile" << std::endl; return false; } gfx::Rect OffScreenWindow::GetBoundsInRootWindow() { - std::cout << "GetBoundsInRootWindow" << std::endl; - std::cout << size_.width() << "x" << size_.height() << std::endl; + // std::cout << "GetBoundsInRootWindow" << std::endl; + // std::cout << size_.width() << "x" << size_.height() << std::endl; return gfx::Rect(size_); } void OffScreenWindow::LockCompositingSurface() { - std::cout << "LockCompositingSurface" << std::endl; + // std::cout << "LockCompositingSurface" << std::endl; } void OffScreenWindow::UnlockCompositingSurface() { - std::cout << "UnlockCompositingSurface" << std::endl; + // std::cout << "UnlockCompositingSurface" << std::endl; } void OffScreenWindow::ImeCompositionRangeChanged( const gfx::Range &, const std::vector&) { - std::cout << "ImeCompositionRangeChanged" << std::endl; + // std::cout << "ImeCompositionRangeChanged" << std::endl; } gfx::Size OffScreenWindow::GetPhysicalBackingSize() const { - std::cout << "GetPhysicalBackingSize" << std::endl; + // std::cout << "GetPhysicalBackingSize" << std::endl; return size_; } gfx::Size OffScreenWindow::GetRequestedRendererSize() const { - std::cout << "GetRequestedRendererSize" << std::endl; + // std::cout << "GetRequestedRendererSize" << std::endl; return size_; } int OffScreenWindow::DelegatedFrameHostGetGpuMemoryBufferClientId() const { - std::cout << "DelegatedFrameHostGetGpuMemoryBufferClientId" << std::endl; + // std::cout << "DelegatedFrameHostGetGpuMemoryBufferClientId" << std::endl; return render_widget_host_->GetProcess()->GetID(); } ui::Layer* OffScreenWindow::DelegatedFrameHostGetLayer() const { - std::cout << "DelegatedFrameHostGetLayer" << std::endl; + // std::cout << "DelegatedFrameHostGetLayer" << std::endl; return const_cast(root_layer_.get()); } bool OffScreenWindow::DelegatedFrameHostIsVisible() const { - std::cout << "DelegatedFrameHostIsVisible" << std::endl; - std::cout << !render_widget_host_->is_hidden() << std::endl; + // std::cout << "DelegatedFrameHostIsVisible" << std::endl; + // std::cout << !render_widget_host_->is_hidden() << std::endl; return !render_widget_host_->is_hidden(); } SkColor OffScreenWindow::DelegatedFrameHostGetGutterColor(SkColor color) const { - std::cout << "DelegatedFrameHostGetGutterColor" << std::endl; + // std::cout << "DelegatedFrameHostGetGutterColor" << std::endl; return color; } gfx::Size OffScreenWindow::DelegatedFrameHostDesiredSizeInDIP() const { - std::cout << "DelegatedFrameHostDesiredSizeInDIP" << std::endl; - std::cout << size_.width() << "x" << size_.height() << std::endl; + // std::cout << "DelegatedFrameHostDesiredSizeInDIP" << std::endl; + // std::cout << size_.width() << "x" << size_.height() << std::endl; return size_; } bool OffScreenWindow::DelegatedFrameCanCreateResizeLock() const { - std::cout << "DelegatedFrameCanCreateResizeLock" << std::endl; + // std::cout << "DelegatedFrameCanCreateResizeLock" << std::endl; return false; } std::unique_ptr OffScreenWindow::DelegatedFrameHostCreateResizeLock(bool) { - std::cout << "DelegatedFrameHostCreateResizeLock" << std::endl; + // std::cout << "DelegatedFrameHostCreateResizeLock" << std::endl; return nullptr; } void OffScreenWindow::DelegatedFrameHostResizeLockWasReleased() { - std::cout << "DelegatedFrameHostResizeLockWasReleased" << std::endl; + // std::cout << "DelegatedFrameHostResizeLockWasReleased" << std::endl; return render_widget_host_->WasResized(); } void OffScreenWindow::DelegatedFrameHostSendCompositorSwapAck( int output_surface_id, const cc::CompositorFrameAck& ack) { - std::cout << "DelegatedFrameHostSendCompositorSwapAck" << std::endl; - std::cout << output_surface_id << std::endl; + // std::cout << "DelegatedFrameHostSendCompositorSwapAck" << std::endl; + // std::cout << output_surface_id << std::endl; render_widget_host_->Send(new ViewMsg_SwapCompositorFrameAck( render_widget_host_->GetRoutingID(), output_surface_id, ack)); @@ -843,32 +848,68 @@ void OffScreenWindow::DelegatedFrameHostSendCompositorSwapAck( void OffScreenWindow::DelegatedFrameHostSendReclaimCompositorResources( int output_surface_id, const cc::CompositorFrameAck& ack) { - std::cout << "DelegatedFrameHostSendReclaimCompositorResources" << std::endl; - std::cout << output_surface_id << std::endl; + // std::cout << "DelegatedFrameHostSendReclaimCompositorResources" << std::endl; + // std::cout << output_surface_id << std::endl; render_widget_host_->Send(new ViewMsg_ReclaimCompositorResources( render_widget_host_->GetRoutingID(), output_surface_id, ack)); } void OffScreenWindow::DelegatedFrameHostOnLostCompositorResources() { - std::cout << "DelegatedFrameHostOnLostCompositorResources" << std::endl; + // std::cout << "DelegatedFrameHostOnLostCompositorResources" << std::endl; render_widget_host_->ScheduleComposite(); } void OffScreenWindow::DelegatedFrameHostUpdateVSyncParameters( const base::TimeTicks& timebase, const base::TimeDelta& interval) { - std::cout << "DelegatedFrameHostUpdateVSyncParameters" << std::endl; + // std::cout << "DelegatedFrameHostUpdateVSyncParameters" << std::endl; render_widget_host_->UpdateVSyncParameters(timebase, interval); } std::unique_ptr - OffScreenWindow::CreateSoftwareOutputDevice(ui::Compositor* compositor) { - std::cout << "CreateSoftwareOutputDevice" << std::endl; - return std::unique_ptr(new OffScreenOutputDevice); +OffScreenWindow::CreateSoftwareOutputDevice( + ui::Compositor* compositor) { + DCHECK_EQ(compositor_.get(), compositor); + DCHECK(!copy_frame_generator_); + DCHECK(!software_output_device_); + std::cout << "CREATED" << std::endl; + software_output_device_ = new OffScreenOutputDevice(); + return base::WrapUnique(software_output_device_); } void OffScreenWindow::OnSetNeedsBeginFrames(bool enabled) { - std::cout << "OnSetNeedsBeginFrames" << std::endl; + SetFrameRate(); + + begin_frame_timer_->SetActive(enabled); + + // std::cout << "OnSetNeedsBeginFrames" << enabled << std::endl; +} + +void OffScreenWindow::SetFrameRate() { + // Only set the frame rate one time. + if (frame_rate_threshold_ms_ != 0) + return; + + const int frame_rate = 120; + frame_rate_threshold_ms_ = 1000 / frame_rate; + + // Configure the VSync interval for the browser process. + compositor_->vsync_manager()->SetAuthoritativeVSyncInterval( + base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms_)); + + if (copy_frame_generator_.get()) { + copy_frame_generator_->set_frame_rate_threshold_ms( + frame_rate_threshold_ms_); + } + + if (begin_frame_timer_.get()) { + begin_frame_timer_->SetFrameRateThresholdMs(frame_rate_threshold_ms_); + } else { + begin_frame_timer_.reset(new CefBeginFrameTimer( + frame_rate_threshold_ms_, + base::Bind(&OffScreenWindow::OnBeginFrameTimerTick, + weak_ptr_factory_.GetWeakPtr()))); + } } } // namespace atom diff --git a/atom/browser/osr_window.h b/atom/browser/osr_window.h index 0418a62c2c75..74fdd64af730 100644 --- a/atom/browser/osr_window.h +++ b/atom/browser/osr_window.h @@ -190,12 +190,18 @@ public: std::unique_ptr paintCallback; void SetPaintCallback(const OnPaintCallback*); + private: + void SetFrameRate(); + void ResizeRootLayer(); + content::RenderWidgetHostImpl* render_widget_host_; std::unique_ptr copy_frame_generator_; std::unique_ptr begin_frame_timer_; + OffScreenOutputDevice* software_output_device_; + int frame_rate_threshold_ms_; float scale_factor_; diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index 978ca22e86bc..078dc27c05fe 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -19,11 +19,14 @@ #include "content/public/common/web_preferences.h" #include "native_mate/dictionary.h" #include "net/base/filename_util.h" +#include "cc/base/switches.h" #if defined(OS_WIN) #include "ui/gfx/switches.h" #endif +#include + DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::WebContentsPreferences); namespace atom { @@ -185,6 +188,11 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches( if (!visible) // Default state is visible. command_line->AppendSwitch("hidden-page"); } + + command_line->AppendSwitch(cc::switches::kEnableBeginFrameScheduling); + command_line->AppendSwitch(cc::switches::kShowFPSCounter); + // command_line->AppendSwitch("disable-gpu"); + // command_line->AppendSwitch("disable-gpu-compositing"); } // static diff --git a/default_app/default_app.js b/default_app/default_app.js index dd44cbe3005d..ebc352c4df98 100644 --- a/default_app/default_app.js +++ b/default_app/default_app.js @@ -1,7 +1,14 @@ const {app, BrowserWindow} = require('electron') const path = require('path') -let mainWindow = null +let mainWindow1 = null +let mainWindow2 = null +let mainWindow3 = null +let mainWindow4 = null +let mainWindow5 = null +let mainWindow6 = null +let mainWindow7 = null +let mainWindow8 = null // Quit when all windows are closed. app.on('window-all-closed', () => { @@ -10,28 +17,235 @@ app.on('window-all-closed', () => { exports.load = (appUrl) => { app.on('ready', () => { - const options = { + mainWindow1 = new BrowserWindow({ width: 800, height: 600, autoHideMenuBar: true, backgroundColor: '#FFFFFF', - useContentSize: true - } - if (process.platform === 'linux') { - options.icon = path.join(__dirname, 'icon.png') - } + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow1.loadURL(appUrl) + mainWindow1.focus() + mainWindow1.webContents.on('dom-ready', () => { + mainWindow1.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + var start1, end1 + start1 = +new Date(); + mainWindow1.webContents.on('paint', (e, rect, w, h, data) => { + end1 = +new Date(); - mainWindow = new BrowserWindow(options) - mainWindow.loadURL(appUrl) - mainWindow.focus() - mainWindow.webContents.on('dom-ready', () => { - mainWindow.webContents.beginFrameSubscription(() => { + const d = end1 - start1 + console.log(`browser #1: ${d < 10 ? ` ${d}` : d} ms`) + + start1 = end1 + }) + + mainWindow2 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow2.loadURL(appUrl) + mainWindow2.focus() + mainWindow2.webContents.on('dom-ready', () => { + mainWindow2.webContents.beginFrameSubscription(() => { console.log("asd") }) }) - mainWindow.webContents.on('paint', (e, rect, w, h, data) => { - console.log('ELECTRON EVENT', rect, w, h, data) + var start2, end2 + start2 = +new Date(); + mainWindow2.webContents.on('paint', (e, rect, w, h, data) => { + end2 = +new Date(); + + const d = end2 - start2 + console.log(`browser #2: ${d < 10 ? ` ${d}` : d} ms`) + + start2 = end2 + }) + + mainWindow3 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow3.loadURL(appUrl) + mainWindow3.focus() + mainWindow3.webContents.on('dom-ready', () => { + mainWindow3.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + + var start3, end3 + start3 = +new Date(); + mainWindow3.webContents.on('paint', (e, rect, w, h, data) => { + end3 = +new Date(); + + const d = end3 - start3 + console.log(`browser #3: ${d < 10 ? ` ${d}` : d} ms`) + + start3 = end3 + }) + + mainWindow4 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow4.loadURL(appUrl) + mainWindow4.focus() + mainWindow4.webContents.on('dom-ready', () => { + mainWindow4.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + + var start4, end4 + start4 = +new Date(); + mainWindow4.webContents.on('paint', (e, rect, w, h, data) => { + end4 = +new Date(); + + const d = end4 - start4 + console.log(`browser #4: ${d < 10 ? ` ${d}` : d} ms`) + + start4 = end4 + }) + + mainWindow5 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow5.loadURL(appUrl) + mainWindow5.focus() + mainWindow5.webContents.on('dom-ready', () => { + mainWindow5.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + + var start5, end5 + start5 = +new Date(); + mainWindow5.webContents.on('paint', (e, rect, w, h, data) => { + end5 = +new Date(); + + const d = end5 - start5 + console.log(`browser #5: ${d < 10 ? ` ${d}` : d} ms`) + + start5 = end5 + }) + + mainWindow6 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow6.loadURL(appUrl) + mainWindow6.focus() + mainWindow6.webContents.on('dom-ready', () => { + mainWindow6.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + + var start6, end6 + start6 = +new Date(); + mainWindow6.webContents.on('paint', (e, rect, w, h, data) => { + end6 = +new Date(); + + const d = end6 - start6 + console.log(`browser #6: ${d < 10 ? ` ${d}` : d} ms`) + + start6 = end6 + }) + + mainWindow7 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow7.loadURL(appUrl) + mainWindow7.focus() + mainWindow7.webContents.on('dom-ready', () => { + mainWindow7.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + + var start7, end7 + start7 = +new Date(); + mainWindow7.webContents.on('paint', (e, rect, w, h, data) => { + end7 = +new Date(); + + const d = end7 - start7 + console.log(`browser #7: ${d < 10 ? ` ${d}` : d} ms`) + + start7 = end7 + }) + + mainWindow8 = new BrowserWindow({ + width: 800, + height: 600, + autoHideMenuBar: true, + backgroundColor: '#FFFFFF', + useContentSize: true, + webPreferences: { + nodeIntegration: false + } + }) + mainWindow8.loadURL(appUrl) + mainWindow8.focus() + mainWindow8.webContents.on('dom-ready', () => { + mainWindow8.webContents.beginFrameSubscription(() => { + console.log("asd") + }) + }) + + var start8, end8 + start8 = +new Date(); + mainWindow8.webContents.on('paint', (e, rect, w, h, data) => { + end8 = +new Date(); + + const d = end8 - start8 + console.log(`browser #8: ${d < 10 ? ` ${d}` : d} ms`) + + start8 = end8 }) }) } diff --git a/default_app/main.js b/default_app/main.js index 7c5ffadd0bb5..6ac00e72c8b0 100644 --- a/default_app/main.js +++ b/default_app/main.js @@ -329,5 +329,5 @@ if (option.file && !option.webdriver) { startRepl() } else { const indexPath = path.join(__dirname, '/index.html') - loadApplicationByUrl(`https://vimeo.com/channels/staffpicks/174711575#t=7s`) + loadApplicationByUrl(`http://mrdoob.com/lab/javascript/requestanimationframe/`) }