From 20d2ab29ab51cafc1c8b391c19134fbb7f711779 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Sat, 4 Mar 2017 03:09:16 +0100 Subject: [PATCH 01/24] Add support for child and popup windows in OSR --- atom/browser/api/atom_api_web_contents.cc | 41 +- atom/browser/api/atom_api_web_contents.h | 1 + atom/browser/native_window.h | 1 + atom/browser/native_window_views.cc | 4 + atom/browser/native_window_views.h | 1 + .../osr/osr_render_widget_host_view.cc | 386 ++++++++++++++++-- .../browser/osr/osr_render_widget_host_view.h | 57 ++- atom/browser/osr/osr_web_contents_view.cc | 99 ++++- atom/browser/osr/osr_web_contents_view.h | 6 +- 9 files changed, 541 insertions(+), 55 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index bedc0976969a..e5f8bfe9d292 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -48,6 +48,7 @@ #include "chrome/browser/ssl/security_state_tab_helper.h" #include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/view_messages.h" #include "content/public/browser/favicon_status.h" @@ -315,6 +316,9 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options) else if (options.Get("offscreen", &b) && b) type_ = OFF_SCREEN; + // Init embedder earlier + options.Get("embedder", &embedder_); + // Whether to enable DevTools. options.Get("devTools", &enable_devtools_); @@ -339,7 +343,18 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options) session->browser_context(), site_instance); guest_delegate_.reset(new WebViewGuestDelegate); params.guest_delegate = guest_delegate_.get(); - web_contents = content::WebContents::Create(params); + + if (embedder_ && embedder_->IsOffScreen()) { + auto* view = new OffScreenWebContentsView(false, + base::Bind(&WebContents::OnPaint, base::Unretained(this))); + params.view = view; + params.delegate_view = view; + + web_contents = content::WebContents::Create(params); + view->SetWebContents(web_contents); + } else { + web_contents = content::WebContents::Create(params); + } } else if (IsOffScreen()) { bool transparent = false; options.Get("transparent", &transparent); @@ -389,7 +404,7 @@ void WebContents::InitWithSessionAndOptions(v8::Isolate* isolate, guest_delegate_->Initialize(this); NativeWindow* owner_window = nullptr; - if (options.Get("embedder", &embedder_) && embedder_) { + if (embedder_) { // New WebContents's owner_window is the embedder's owner_window. auto relay = NativeWindowRelay::FromWebContents(embedder_->web_contents()); @@ -1402,18 +1417,16 @@ bool WebContents::SendIPCMessage(bool all_frames, void WebContents::SendInputEvent(v8::Isolate* isolate, v8::Local input_event) { - const auto view = web_contents()->GetRenderWidgetHostView(); + const auto view = static_cast( + web_contents()->GetRenderWidgetHostView()); if (!view) return; - const auto host = view->GetRenderWidgetHost(); - if (!host) - return; int type = mate::GetWebInputEventType(isolate, input_event); if (blink::WebInputEvent::isMouseEventType(type)) { blink::WebMouseEvent mouse_event; if (mate::ConvertFromV8(isolate, input_event, &mouse_event)) { - host->ForwardMouseEvent(mouse_event); + view->ProcessMouseEvent(mouse_event, ui::LatencyInfo()); return; } } else if (blink::WebInputEvent::isKeyboardEventType(type)) { @@ -1422,13 +1435,13 @@ void WebContents::SendInputEvent(v8::Isolate* isolate, blink::WebInputEvent::NoModifiers, ui::EventTimeForNow()); if (mate::ConvertFromV8(isolate, input_event, &keyboard_event)) { - host->ForwardKeyboardEvent(keyboard_event); + view->ProcessKeyboardEvent(keyboard_event); return; } } else if (type == blink::WebInputEvent::MouseWheel) { blink::WebMouseWheelEvent mouse_wheel_event; if (mate::ConvertFromV8(isolate, input_event, &mouse_wheel_event)) { - host->ForwardWheelEvent(mouse_wheel_event); + view->ProcessMouseEvent(mouse_wheel_event, ui::LatencyInfo()); return; } } @@ -1631,6 +1644,16 @@ void WebContents::Invalidate() { } } +gfx::Size WebContents::GetSizeForNewRenderView( + content::WebContents* web_contents) const { + auto relay = NativeWindowRelay::FromWebContents(web_contents); + if (relay) { + return relay->window->GetSize(); + } + + return gfx::Size(); +} + void WebContents::SetZoomLevel(double level) { zoom_controller_->SetZoomLevel(level); } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 1f926dbd7a5a..1916964fa254 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -183,6 +183,7 @@ class WebContents : public mate::TrackableObject, void SetFrameRate(int frame_rate); int GetFrameRate() const; void Invalidate(); + gfx::Size GetSizeForNewRenderView(content::WebContents*) const override; // Methods for zoom handling. void SetZoomLevel(double level); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index d3f18d8fb95c..b0d25e03f232 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -147,6 +147,7 @@ class NativeWindow : public base::SupportsUserData, virtual void SetMenu(AtomMenuModel* menu); virtual void SetParentWindow(NativeWindow* parent); virtual void SetBrowserView(NativeBrowserView* browser_view) = 0; + virtual gfx::NativeView GetNativeView() = 0; virtual gfx::NativeWindow GetNativeWindow() = 0; virtual gfx::AcceleratedWidget GetAcceleratedWidget() = 0; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index ed524cbdcbc1..00f0befd50fa 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -924,6 +924,10 @@ void NativeWindowViews::SetParentWindow(NativeWindow* parent) { #endif } +gfx::NativeView NativeWindowViews::GetNativeView() { + return window_->GetNativeView(); +} + gfx::NativeWindow NativeWindowViews::GetNativeWindow() { return window_->GetNativeWindow(); } diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 276cd4adde2d..15bdbad18808 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -106,6 +106,7 @@ class NativeWindowViews : public NativeWindow, void SetMenu(AtomMenuModel* menu_model) override; void SetBrowserView(NativeBrowserView* browser_view) override; void SetParentWindow(NativeWindow* parent) override; + gfx::NativeView GetNativeView() override; gfx::NativeWindow GetNativeWindow() override; void SetOverlayIcon(const gfx::Image& overlay, const std::string& description) override; diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index c41a6805c068..6719b7b45458 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -17,6 +17,7 @@ #include "content/browser/renderer_host/render_widget_host_delegate.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_frame_subscriber.h" +#include "content/browser/renderer_host/resize_lock.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/context_factory.h" @@ -25,6 +26,7 @@ #include "ui/compositor/layer.h" #include "ui/compositor/layer_type.h" #include "ui/events/latency_info.h" +#include "ui/gfx/skbitmap_operations.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/native_widget_types.h" @@ -35,6 +37,66 @@ namespace { const float kDefaultScaleFactor = 1.0; const int kFrameRetryLimit = 2; +#if !defined(OS_MACOSX) + +const int kResizeLockTimeoutMs = 67; + +class AtomResizeLock : public content::ResizeLock { + public: + AtomResizeLock(OffScreenRenderWidgetHostView* host, + const gfx::Size new_size, + bool defer_compositor_lock) + : ResizeLock(new_size, defer_compositor_lock), + host_(host), + cancelled_(false), + weak_ptr_factory_(this) { + DCHECK(host_); + host_->HoldResize(); + + content::BrowserThread::PostDelayedTask(content::BrowserThread::UI, + FROM_HERE, base::Bind(&AtomResizeLock::CancelLock, + weak_ptr_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs)); + } + + ~AtomResizeLock() override { + CancelLock(); + } + + bool GrabDeferredLock() override { + return ResizeLock::GrabDeferredLock(); + } + + void UnlockCompositor() override { + ResizeLock::UnlockCompositor(); + compositor_lock_ = NULL; + } + + protected: + void LockCompositor() override { + ResizeLock::LockCompositor(); + compositor_lock_ = host_->GetCompositor()->GetCompositorLock(); + } + + void CancelLock() { + if (cancelled_) + return; + cancelled_ = true; + UnlockCompositor(); + host_->ReleaseResize(); + } + + private: + OffScreenRenderWidgetHostView* host_; + scoped_refptr compositor_lock_; + bool cancelled_; + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(AtomResizeLock); +}; + +#endif // !defined(OS_MACOSX) + } // namespace class AtomCopyFrameGenerator { @@ -338,24 +400,30 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView( bool transparent, const OnPaintCallback& callback, content::RenderWidgetHost* host, - bool is_guest_view_hack, + OffScreenRenderWidgetHostView* parent_host_view, NativeWindow* native_window) : render_widget_host_(content::RenderWidgetHostImpl::From(host)), + parent_host_view_(parent_host_view), + popup_host_view_(nullptr), + child_host_view_(nullptr), native_window_(native_window), software_output_device_(nullptr), transparent_(transparent), callback_(callback), + parent_callback_(nullptr), frame_rate_(60), frame_rate_threshold_ms_(0), last_time_(base::Time::Now()), scale_factor_(kDefaultScaleFactor), - is_showing_(!render_widget_host_->is_hidden()), - size_(native_window->GetSize()), painting_(true), + is_showing_(!render_widget_host_->is_hidden()), + is_destroyed_(false), + popup_position_(gfx::Rect()), + hold_resize_(false), + pending_resize_(false), + size_(native_window->GetSize()), weak_ptr_factory_(this) { DCHECK(render_widget_host_); - render_widget_host_->SetView(this); - #if !defined(OS_MACOSX) delegated_frame_host_ = base::MakeUnique( AllocateFrameSinkId(is_guest_view_hack), this); @@ -383,6 +451,8 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView( native_window_->AddObserver(this); ResizeRootLayer(); + render_widget_host_->SetView(this); + InstallTransparency(); } OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() { @@ -400,8 +470,15 @@ OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() { delegated_frame_host_->ResetCompositor(); #endif + if (copy_frame_generator_.get()) + copy_frame_generator_.reset(NULL); + #if defined(OS_MACOSX) DestroyPlatformWidget(); +#else + delegated_frame_host_.reset(NULL); + compositor_.reset(NULL); + root_layer_.reset(NULL); #endif } @@ -461,6 +538,17 @@ bool OffScreenRenderWidgetHostView::OnMessageReceived( } void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) { + DCHECK(parent_host_view_); + + if (parent_host_view_->child_host_view_) { + parent_host_view_->child_host_view_->CancelWidget(); + } + + parent_host_view_->set_child_host_view(this); + parent_host_view_->Hide(); + + ResizeRootLayer(); + Show(); } content::RenderWidgetHost* OffScreenRenderWidgetHostView::GetRenderWidgetHost() @@ -470,14 +558,11 @@ content::RenderWidgetHost* OffScreenRenderWidgetHostView::GetRenderWidgetHost() void OffScreenRenderWidgetHostView::SetSize(const gfx::Size& size) { size_ = size; - - ResizeRootLayer(); - if (render_widget_host_) - render_widget_host_->WasResized(); - GetDelegatedFrameHost()->WasResized(); + WasResized(); } void OffScreenRenderWidgetHostView::SetBounds(const gfx::Rect& new_bounds) { + SetSize(new_bounds.size()); } gfx::Vector2dF OffScreenRenderWidgetHostView::GetLastScrollOffset() const { @@ -547,6 +632,9 @@ bool OffScreenRenderWidgetHostView::IsShowing() { } gfx::Rect OffScreenRenderWidgetHostView::GetViewBounds() const { + if (IsPopupWidget()) + return popup_position_; + return gfx::Rect(size_); } @@ -587,7 +675,7 @@ void OffScreenRenderWidgetHostView::OnSwapCompositorFrame( if (!frame.render_pass_list.empty()) { if (software_output_device_) { - if (!begin_frame_timer_.get()) { + if (!begin_frame_timer_.get() || IsPopupWidget()) { software_output_device_->SetActive(painting_); } @@ -631,10 +719,25 @@ void OffScreenRenderWidgetHostView::ClearCompositorFrame() { void OffScreenRenderWidgetHostView::InitAsPopup( content::RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) { + DCHECK_EQ(parent_host_view_, parent_host_view); + + if (parent_host_view_->popup_host_view_) { + parent_host_view_->popup_host_view_->CancelWidget(); + } + + parent_host_view_->set_popup_host_view(this); + parent_host_view_->popup_bitmap_.reset(new SkBitmap); + parent_callback_ = base::Bind(&OffScreenRenderWidgetHostView::OnPopupPaint, + parent_host_view_->weak_ptr_factory_.GetWeakPtr()); + + popup_position_ = pos; + + ResizeRootLayer(); + Show(); } void OffScreenRenderWidgetHostView::InitAsFullscreen( - content::RenderWidgetHostView *) { + content::RenderWidgetHostView *) { } void OffScreenRenderWidgetHostView::UpdateCursor(const content::WebCursor &) { @@ -656,6 +759,23 @@ void OffScreenRenderWidgetHostView::RenderProcessGone(base::TerminationStatus, } void OffScreenRenderWidgetHostView::Destroy() { + if (!is_destroyed_) { + is_destroyed_ = true; + + if (parent_host_view_ != NULL) { + CancelWidget(); + } else { + if (popup_host_view_) + popup_host_view_->CancelWidget(); + popup_bitmap_.reset(); + if (child_host_view_) + child_host_view_->CancelWidget(); + for (auto guest_host_view : guest_host_views_) + guest_host_view->CancelWidget(); + Hide(); + } + } + delete this; } @@ -692,6 +812,13 @@ void OffScreenRenderWidgetHostView::EndFrameSubscription() { GetDelegatedFrameHost()->EndFrameSubscription(); } +void OffScreenRenderWidgetHostView::InitAsGuest( + content::RenderWidgetHostView* parent_host_view, + content::RenderWidgetHostViewGuest* guest_view) { + parent_host_view_->AddGuestHostView(this); + parent_host_view_->RegisterGuestViewFrameSwappedCallback(guest_view); +} + bool OffScreenRenderWidgetHostView::HasAcceleratedSurface(const gfx::Size &) { return false; } @@ -705,11 +832,11 @@ void OffScreenRenderWidgetHostView::ImeCompositionRangeChanged( } gfx::Size OffScreenRenderWidgetHostView::GetPhysicalBackingSize() const { - return size_; + return gfx::ConvertSizeToPixel(scale_factor_, GetRequestedRendererSize()); } gfx::Size OffScreenRenderWidgetHostView::GetRequestedRendererSize() const { - return size_; + return GetDelegatedFrameHost()->GetRequestedRendererSize(); } #if !defined(OS_MACOSX) @@ -723,22 +850,29 @@ bool OffScreenRenderWidgetHostView::DelegatedFrameHostIsVisible() const { SkColor OffScreenRenderWidgetHostView::DelegatedFrameHostGetGutterColor( SkColor color) const { + if (render_widget_host_->delegate() && + render_widget_host_->delegate()->IsFullscreenForCurrentTab()) { + return SK_ColorBLACK; + } return color; } gfx::Size OffScreenRenderWidgetHostView::DelegatedFrameHostDesiredSizeInDIP() const { - return size_; + return GetRootLayer()->bounds().size(); } bool OffScreenRenderWidgetHostView::DelegatedFrameCanCreateResizeLock() const { - return false; + return !render_widget_host_->auto_resize_enabled(); } std::unique_ptr OffScreenRenderWidgetHostView::DelegatedFrameHostCreateResizeLock( bool defer_compositor_lock) { - return nullptr; + return std::unique_ptr(new AtomResizeLock( + this, + DelegatedFrameHostDesiredSizeInDIP(), + defer_compositor_lock)); } void OffScreenRenderWidgetHostView::DelegatedFrameHostResizeLockWasReleased() { @@ -795,6 +929,57 @@ bool OffScreenRenderWidgetHostView::TransformPointToCoordSpaceForView( point, target_view, transformed_point); } +void OffScreenRenderWidgetHostView::CancelWidget() { + if (render_widget_host_) + render_widget_host_->LostCapture(); + Hide(); + + if (parent_host_view_) { + if (parent_host_view_->popup_host_view_ == this) { + parent_host_view_->set_popup_host_view(NULL); + parent_host_view_->popup_bitmap_.reset(); + } else if (parent_host_view_->child_host_view_ == this) { + parent_host_view_->set_child_host_view(NULL); + parent_host_view_->Show(); + } else { + parent_host_view_->RemoveGuestHostView(this); + } + parent_host_view_ = NULL; + } + + if (render_widget_host_ && !is_destroyed_) { + is_destroyed_ = true; + // Results in a call to Destroy(). + render_widget_host_->ShutdownAndDestroyWidget(true); + } +} + +void OffScreenRenderWidgetHostView::AddGuestHostView( + OffScreenRenderWidgetHostView* guest_host) { + guest_host_views_.insert(guest_host); +} + +void OffScreenRenderWidgetHostView::RemoveGuestHostView( + OffScreenRenderWidgetHostView* guest_host) { + guest_host_views_.erase(guest_host); +} + +void OffScreenRenderWidgetHostView::RegisterGuestViewFrameSwappedCallback( + content::RenderWidgetHostViewGuest* guest_host_view) { + guest_host_view->RegisterFrameSwappedCallback(base::MakeUnique( + base::Bind(&OffScreenRenderWidgetHostView::OnGuestViewFrameSwapped, + weak_ptr_factory_.GetWeakPtr(), + base::Unretained(guest_host_view)))); +} + +void OffScreenRenderWidgetHostView::OnGuestViewFrameSwapped( + content::RenderWidgetHostViewGuest* guest_host_view) { + InvalidateBounds( + gfx::ConvertRectToPixel(scale_factor_, guest_host_view->GetViewBounds())); + + RegisterGuestViewFrameSwappedCallback(guest_host_view); +} + std::unique_ptr OffScreenRenderWidgetHostView::CreateSoftwareOutputDevice( ui::Compositor* compositor) { @@ -823,7 +1008,7 @@ bool OffScreenRenderWidgetHostView::InstallTransparency() { } bool OffScreenRenderWidgetHostView::IsAutoResizeEnabled() const { - return false; + return render_widget_host_->auto_resize_enabled(); } void OffScreenRenderWidgetHostView::SetNeedsBeginFrames( @@ -837,10 +1022,143 @@ void OffScreenRenderWidgetHostView::SetNeedsBeginFrames( } } +void CopyBitmapTo( + const SkBitmap& destination, + const SkBitmap& source, + const gfx::Rect& pos) { + SkAutoLockPixels source_pixels_lock(source); + SkAutoLockPixels destination_pixels_lock(destination); + + char* src = static_cast(source.getPixels()); + char* dest = static_cast(destination.getPixels()); + int pixelsize = source.bytesPerPixel(); + + if (pos.x() + pos.width() <= destination.width() && + pos.y() + pos.height() <= destination.height()) { + for (int i = 0; i < pos.height(); i++) { + memcpy(dest + ((pos.y() + i) * destination.width() + pos.x()) * pixelsize, + src + (i * source.width()) * pixelsize, + source.width() * pixelsize); + } + } + + destination.notifyPixelsChanged(); +} + void OffScreenRenderWidgetHostView::OnPaint( const gfx::Rect& damage_rect, const SkBitmap& bitmap) { TRACE_EVENT0("electron", "OffScreenRenderWidgetHostView::OnPaint"); - callback_.Run(damage_rect, bitmap); + + HoldResize(); + + if (parent_callback_) + parent_callback_.Run(damage_rect, bitmap); + else if (popup_host_view_ && popup_bitmap_.get()) { + gfx::Rect pos = popup_host_view_->popup_position_; + SkBitmap copy = SkBitmapOperations::CreateTiledBitmap(bitmap, + pos.x(), pos.y(), pos.width(), pos.height()); + + CopyBitmapTo(bitmap, *popup_bitmap_, pos); + callback_.Run(damage_rect, bitmap); + CopyBitmapTo(bitmap, copy, pos); + } else { + callback_.Run(damage_rect, bitmap); + } + + ReleaseResize(); +} + +void OffScreenRenderWidgetHostView::OnPopupPaint( + const gfx::Rect& damage_rect, const SkBitmap& bitmap) { + if (popup_host_view_ && popup_bitmap_.get()) + bitmap.deepCopyTo(popup_bitmap_.get()); +} + +void OffScreenRenderWidgetHostView::HoldResize() { + if (!hold_resize_) + hold_resize_ = true; +} + +void OffScreenRenderWidgetHostView::ReleaseResize() { + if (!hold_resize_) + return; + + hold_resize_ = false; + if (pending_resize_) { + pending_resize_ = false; + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&OffScreenRenderWidgetHostView::WasResized, + weak_ptr_factory_.GetWeakPtr())); + } +} + +void OffScreenRenderWidgetHostView::WasResized() { + if (hold_resize_) { + if (!pending_resize_) + pending_resize_ = true; + return; + } + + ResizeRootLayer(); + if (render_widget_host_) + render_widget_host_->WasResized(); + GetDelegatedFrameHost()->WasResized(); +} + +void OffScreenRenderWidgetHostView::ProcessKeyboardEvent( + const content::NativeWebKeyboardEvent& event) { + if (!render_widget_host_) + return; + render_widget_host_->ForwardKeyboardEvent(event); +} + +void OffScreenRenderWidgetHostView::ProcessMouseEvent( + const blink::WebMouseEvent& event, + const ui::LatencyInfo& latency) { + if (!IsPopupWidget()) { + if (popup_host_view_ && + popup_host_view_->popup_position_.Contains(event.x, event.y)) { + blink::WebMouseEvent popup_event(event); + popup_event.x -= popup_host_view_->popup_position_.x(); + popup_event.y -= popup_host_view_->popup_position_.y(); + popup_event.windowX = popup_event.x; + popup_event.windowY = popup_event.y; + + popup_host_view_->ProcessMouseEvent(popup_event, latency); + return; + } + } + if (!render_widget_host_) + return; + render_widget_host_->ForwardMouseEvent(event); +} + +void OffScreenRenderWidgetHostView::ProcessMouseWheelEvent( + const blink::WebMouseWheelEvent& event, + const ui::LatencyInfo& latency) { + if (!IsPopupWidget()) { + if (popup_host_view_) { + if (popup_host_view_->popup_position_.Contains(event.x, event.y)) { + blink::WebMouseWheelEvent popup_event(event); + popup_event.x -= popup_host_view_->popup_position_.x(); + popup_event.y -= popup_host_view_->popup_position_.y(); + popup_event.windowX = popup_event.x; + popup_event.windowY = popup_event.y; + popup_host_view_->ProcessMouseWheelEvent(popup_event, latency); + return; + } else { + // Scrolling outside of the popup widget so destroy it. + // Execute asynchronously to avoid deleting the widget from inside some + // other callback. + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&OffScreenRenderWidgetHostView::CancelWidget, + popup_host_view_->weak_ptr_factory_.GetWeakPtr())); + } + } + } + if (!render_widget_host_) + return; + render_widget_host_->ForwardWheelEvent(event); } void OffScreenRenderWidgetHostView::SetPainting(bool painting) { @@ -856,12 +1174,22 @@ bool OffScreenRenderWidgetHostView::IsPainting() const { } void OffScreenRenderWidgetHostView::SetFrameRate(int frame_rate) { - if (frame_rate <= 0) - frame_rate = 1; - if (frame_rate > 60) - frame_rate = 60; + if (parent_host_view_) { + if (parent_host_view_->GetFrameRate() == GetFrameRate()) + return; - frame_rate_ = frame_rate; + frame_rate_ = parent_host_view_->GetFrameRate(); + } else { + if (frame_rate <= 0) + frame_rate = 1; + if (frame_rate > 60) + frame_rate = 60; + + frame_rate_ = frame_rate; + } + + for (auto guest_host_view : guest_host_views_) + guest_host_view->SetFrameRate(frame_rate); SetupFrameRate(true); } @@ -910,8 +1238,10 @@ void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) { } void OffScreenRenderWidgetHostView::Invalidate() { - const gfx::Rect& bounds_in_pixels = GetViewBounds(); + InvalidateBounds(GetViewBounds()); +} +void OffScreenRenderWidgetHostView::InvalidateBounds(const gfx::Rect& bounds) { if (software_output_device_) { software_output_device_->OnPaint(bounds_in_pixels); } else if (copy_frame_generator_) { @@ -925,7 +1255,11 @@ void OffScreenRenderWidgetHostView::ResizeRootLayer() { const float orgScaleFactor = scale_factor_; const bool scaleFactorDidChange = (orgScaleFactor != scale_factor_); - gfx::Size size = GetViewBounds().size(); + gfx::Size size; + if (!IsPopupWidget()) + size = GetViewBounds().size(); + else + size = popup_position_.size(); if (!scaleFactorDidChange && size == GetRootLayer()->bounds().size()) return; diff --git a/atom/browser/osr/osr_render_widget_host_view.h b/atom/browser/osr/osr_render_widget_host_view.h index d215d73ab9c4..aa7a0577778c 100644 --- a/atom/browser/osr/osr_render_widget_host_view.h +++ b/atom/browser/osr/osr_render_widget_host_view.h @@ -20,10 +20,12 @@ #include "base/time/time.h" #include "cc/output/compositor_frame.h" #include "cc/scheduler/begin_frame_source.h" +#include "content/browser/frame_host/render_widget_host_view_guest.h" #include "content/browser/renderer_host/delegated_frame_host.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/renderer_host/resize_lock.h" +#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/WebKit/public/platform/WebVector.h" #include "ui/base/ime/text_input_client.h" #include "ui/compositor/compositor.h" @@ -69,7 +71,7 @@ class OffScreenRenderWidgetHostView OffScreenRenderWidgetHostView(bool transparent, const OnPaintCallback& callback, content::RenderWidgetHost* render_widget_host, - bool is_guest_view_hack, + OffScreenRenderWidgetHostView* parent_host_view, NativeWindow* native_window); ~OffScreenRenderWidgetHostView() override; @@ -139,6 +141,9 @@ class OffScreenRenderWidgetHostView void BeginFrameSubscription( std::unique_ptr) override; void EndFrameSubscription() override; + void InitAsGuest( + content::RenderWidgetHostView*, + content::RenderWidgetHostViewGuest*) override; bool HasAcceleratedSurface(const gfx::Size &) override; gfx::Rect GetBoundsInRootWindow(void) override; void ImeCompositionRangeChanged( @@ -193,7 +198,32 @@ class OffScreenRenderWidgetHostView void DestroyPlatformWidget(); #endif + void CancelWidget(); + void AddGuestHostView(OffScreenRenderWidgetHostView* guest_host); + void RemoveGuestHostView(OffScreenRenderWidgetHostView* guest_host); + + void RegisterGuestViewFrameSwappedCallback( + content::RenderWidgetHostViewGuest* guest_host_view); + void OnGuestViewFrameSwapped( + content::RenderWidgetHostViewGuest* guest_host_view); + void OnPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap); + void OnPopupPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap); + + bool IsPopupWidget() const { + return popup_type_ != blink::WebPopupTypeNone; + } + + void HoldResize(); + void ReleaseResize(); + void WasResized(); + + void ProcessKeyboardEvent( + const content::NativeWebKeyboardEvent& event) override; + void ProcessMouseEvent(const blink::WebMouseEvent& event, + const ui::LatencyInfo& latency) override; + void ProcessMouseWheelEvent(const blink::WebMouseWheelEvent& event, + const ui::LatencyInfo& latency) override; void SetPainting(bool painting); bool IsPainting() const; @@ -206,6 +236,7 @@ class OffScreenRenderWidgetHostView content::DelegatedFrameHost* GetDelegatedFrameHost() const; void Invalidate(); + void InvalidateBounds(const gfx::Rect&); content::RenderWidgetHostImpl* render_widget_host() const { return render_widget_host_; } @@ -213,6 +244,14 @@ class OffScreenRenderWidgetHostView gfx::Size size() const { return size_; } float scale_factor() const { return scale_factor_; } + void set_popup_host_view(OffScreenRenderWidgetHostView* popup_view) { + popup_host_view_ = popup_view; + } + + void set_child_host_view(OffScreenRenderWidgetHostView* child_view) { + child_host_view_ = child_view; + } + private: void SetupFrameRate(bool force); void ResizeRootLayer(); @@ -221,11 +260,19 @@ class OffScreenRenderWidgetHostView // Weak ptrs. content::RenderWidgetHostImpl* render_widget_host_; + + OffScreenRenderWidgetHostView* parent_host_view_; + OffScreenRenderWidgetHostView* popup_host_view_; + std::unique_ptr popup_bitmap_; + OffScreenRenderWidgetHostView* child_host_view_; + std::set guest_host_views_; + NativeWindow* native_window_; OffScreenOutputDevice* software_output_device_; const bool transparent_; OnPaintCallback callback_; + OnPaintCallback parent_callback_; int frame_rate_; int frame_rate_threshold_ms_; @@ -233,10 +280,16 @@ class OffScreenRenderWidgetHostView base::Time last_time_; float scale_factor_; - bool is_showing_; gfx::Vector2dF last_scroll_offset_; gfx::Size size_; bool painting_; + + bool is_showing_; + bool is_destroyed_; + gfx::Rect popup_position_; + + bool hold_resize_; + bool pending_resize_; std::unique_ptr root_layer_; std::unique_ptr compositor_; diff --git a/atom/browser/osr/osr_web_contents_view.cc b/atom/browser/osr/osr_web_contents_view.cc index 8d95017b0e64..18b24c1c1ce3 100644 --- a/atom/browser/osr/osr_web_contents_view.cc +++ b/atom/browser/osr/osr_web_contents_view.cc @@ -4,7 +4,9 @@ #include "atom/browser/osr/osr_web_contents_view.h" +#include "content/public/browser/render_view_host.h" #include "third_party/WebKit/public/platform/WebScreenInfo.h" +#include "ui/display/screen.h" namespace atom { @@ -31,15 +33,27 @@ void OffScreenWebContentsView::SetWebContents( #if !defined(OS_MACOSX) gfx::NativeView OffScreenWebContentsView::GetNativeView() const { - return gfx::NativeView(); + if (!web_contents_) return gfx::NativeView(); + + auto relay = NativeWindowRelay::FromWebContents(web_contents_); + if (!relay) return gfx::NativeView(); + return relay->window->GetNativeView(); } gfx::NativeView OffScreenWebContentsView::GetContentNativeView() const { - return gfx::NativeView(); + if (!web_contents_) return gfx::NativeView(); + + auto relay = NativeWindowRelay::FromWebContents(web_contents_); + if (!relay) return gfx::NativeView(); + return relay->window->GetNativeView(); } gfx::NativeWindow OffScreenWebContentsView::GetTopLevelNativeWindow() const { - return gfx::NativeWindow(); + if (!web_contents_) return gfx::NativeWindow(); + + auto relay = NativeWindowRelay::FromWebContents(web_contents_); + if (!relay) return gfx::NativeWindow(); + return relay->window->GetNativeWindow(); } #endif @@ -67,7 +81,7 @@ content::DropData* OffScreenWebContentsView::GetDropData() const { } gfx::Rect OffScreenWebContentsView::GetViewBounds() const { - return view_ ? view_->GetViewBounds() : gfx::Rect(); + return GetView() ? GetView()->GetViewBounds() : gfx::Rect(); } void OffScreenWebContentsView::CreateView(const gfx::Size& initial_size, @@ -76,21 +90,55 @@ void OffScreenWebContentsView::CreateView(const gfx::Size& initial_size, content::RenderWidgetHostViewBase* OffScreenWebContentsView::CreateViewForWidget( - content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack) { + content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack) { + if (render_widget_host->GetView()) { + return static_cast( + render_widget_host->GetView()); + } + auto relay = NativeWindowRelay::FromWebContents(web_contents_); - view_ = new OffScreenRenderWidgetHostView( - transparent_, callback_, render_widget_host, - is_guest_view_hack, relay->window.get()); - return view_; + return new OffScreenRenderWidgetHostView( + transparent_, + callback_, + render_widget_host, + nullptr, + relay->window.get()); +} + +content::RenderWidgetHostViewBase* + OffScreenWebContentsView::CreateViewForWidget( + content::RenderWidgetHost* render_widget_host, + content::RenderWidgetHost* embedder_render_widget_host) { + if (render_widget_host->GetView()) { + return static_cast( + render_widget_host->GetView()); + } + + OffScreenRenderWidgetHostView* embedder_host_view = nullptr; + if (embedder_render_widget_host) { + embedder_host_view = static_cast( + embedder_render_widget_host->GetView()); + } + + auto relay = NativeWindowRelay::FromWebContents(web_contents_); + return new OffScreenRenderWidgetHostView( + transparent_, + callback_, + render_widget_host, + embedder_host_view, + relay->window.get()); } content::RenderWidgetHostViewBase* OffScreenWebContentsView::CreateViewForPopupWidget( content::RenderWidgetHost* render_widget_host) { auto relay = NativeWindowRelay::FromWebContents(web_contents_); - view_ = new OffScreenRenderWidgetHostView( - transparent_, callback_, render_widget_host, false, relay->window.get()); - return view_; + return new OffScreenRenderWidgetHostView( + transparent_, + callback_, + render_widget_host, + GetView(), + relay->window.get()); } void OffScreenWebContentsView::SetPageTitle(const base::string16& title) { @@ -98,8 +146,8 @@ void OffScreenWebContentsView::SetPageTitle(const base::string16& title) { void OffScreenWebContentsView::RenderViewCreated( content::RenderViewHost* host) { - if (view_) - view_->InstallTransparency(); + if (GetView()) + GetView()->InstallTransparency(); } void OffScreenWebContentsView::RenderViewSwappedIn( @@ -111,14 +159,23 @@ void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled) { void OffScreenWebContentsView::GetScreenInfo( content::ScreenInfo* screen_info) const { - screen_info->rect = gfx::Rect(view_->size()); - screen_info->available_rect = gfx::Rect(view_->size()); screen_info->depth = 24; screen_info->depth_per_component = 8; - screen_info->device_scale_factor = view_->scale_factor(); screen_info->orientation_angle = 0; screen_info->orientation_type = content::SCREEN_ORIENTATION_VALUES_LANDSCAPE_PRIMARY; + + if (GetView()) { + screen_info->rect = gfx::Rect(GetView()->size()); + screen_info->available_rect = gfx::Rect(GetView()->size()); + screen_info->device_scale_factor = GetView()->scale_factor(); + } else { + const display::Display display = + display::Screen::GetScreen()->GetPrimaryDisplay(); + screen_info->rect = display.bounds(); + screen_info->available_rect = display.work_area(); + screen_info->device_scale_factor = display.device_scale_factor(); + } } #if defined(OS_MACOSX) @@ -152,4 +209,12 @@ void OffScreenWebContentsView::UpdateDragCursor( blink::WebDragOperation operation) { } +OffScreenRenderWidgetHostView* OffScreenWebContentsView::GetView() const { + if (web_contents_) { + return static_cast( + web_contents_->GetRenderViewHost()->GetWidget()->GetView()); + } + return nullptr; +} + } // namespace atom diff --git a/atom/browser/osr/osr_web_contents_view.h b/atom/browser/osr/osr_web_contents_view.h index 8e4e24299473..57aee80d91f9 100644 --- a/atom/browser/osr/osr_web_contents_view.h +++ b/atom/browser/osr/osr_web_contents_view.h @@ -45,6 +45,9 @@ class OffScreenWebContentsView : public content::WebContentsView, content::RenderWidgetHostViewBase* CreateViewForWidget( content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack) override; + content::RenderWidgetHostViewBase* CreateViewForWidget( + content::RenderWidgetHost* render_widget_host, + content::RenderWidgetHost* embedder_render_widget_host) override; content::RenderWidgetHostViewBase* CreateViewForPopupWidget( content::RenderWidgetHost* render_widget_host) override; void SetPageTitle(const base::string16& title) override; @@ -75,11 +78,12 @@ class OffScreenWebContentsView : public content::WebContentsView, void PlatformDestroy(); #endif + OffScreenRenderWidgetHostView* GetView() const; + const bool transparent_; OnPaintCallback callback_; // Weak refs. - OffScreenRenderWidgetHostView* view_; content::WebContents* web_contents_; #if defined(OS_MACOSX) From c9fa71bdb31874196f671d039310a61b5f41de90 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Sun, 5 Mar 2017 16:18:57 +0100 Subject: [PATCH 02/24] lint fix --- atom/browser/api/atom_api_web_contents.cc | 8 +-- .../osr/osr_render_widget_host_view.cc | 54 +++++++++---------- .../browser/osr/osr_render_widget_host_view.h | 17 +++--- atom/browser/osr/osr_web_contents_view.cc | 42 +++++++-------- 4 files changed, 61 insertions(+), 60 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index e5f8bfe9d292..b6fb523c1613 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -343,13 +343,13 @@ WebContents::WebContents(v8::Isolate* isolate, const mate::Dictionary& options) session->browser_context(), site_instance); guest_delegate_.reset(new WebViewGuestDelegate); params.guest_delegate = guest_delegate_.get(); - + if (embedder_ && embedder_->IsOffScreen()) { - auto* view = new OffScreenWebContentsView(false, + auto* view = new OffScreenWebContentsView(false, base::Bind(&WebContents::OnPaint, base::Unretained(this))); params.view = view; params.delegate_view = view; - + web_contents = content::WebContents::Create(params); view->SetWebContents(web_contents); } else { @@ -1650,7 +1650,7 @@ gfx::Size WebContents::GetSizeForNewRenderView( if (relay) { return relay->window->GetSize(); } - + return gfx::Size(); } diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index 6719b7b45458..f20e96f89d62 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -26,9 +26,9 @@ #include "ui/compositor/layer.h" #include "ui/compositor/layer_type.h" #include "ui/events/latency_info.h" -#include "ui/gfx/skbitmap_operations.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/native_widget_types.h" +#include "ui/gfx/skbitmap_operations.h" namespace atom { @@ -53,9 +53,9 @@ class AtomResizeLock : public content::ResizeLock { DCHECK(host_); host_->HoldResize(); - content::BrowserThread::PostDelayedTask(content::BrowserThread::UI, + content::BrowserThread::PostDelayedTask(content::BrowserThread::UI, FROM_HERE, base::Bind(&AtomResizeLock::CancelLock, - weak_ptr_factory_.GetWeakPtr()), + weak_ptr_factory_.GetWeakPtr()), base::TimeDelta::FromMilliseconds(kResizeLockTimeoutMs)); } @@ -472,7 +472,7 @@ OffScreenRenderWidgetHostView::~OffScreenRenderWidgetHostView() { if (copy_frame_generator_.get()) copy_frame_generator_.reset(NULL); - + #if defined(OS_MACOSX) DestroyPlatformWidget(); #else @@ -543,7 +543,7 @@ void OffScreenRenderWidgetHostView::InitAsChild(gfx::NativeView) { if (parent_host_view_->child_host_view_) { parent_host_view_->child_host_view_->CancelWidget(); } - + parent_host_view_->set_child_host_view(this); parent_host_view_->Hide(); @@ -720,18 +720,18 @@ void OffScreenRenderWidgetHostView::ClearCompositorFrame() { void OffScreenRenderWidgetHostView::InitAsPopup( content::RenderWidgetHostView* parent_host_view, const gfx::Rect& pos) { DCHECK_EQ(parent_host_view_, parent_host_view); - + if (parent_host_view_->popup_host_view_) { parent_host_view_->popup_host_view_->CancelWidget(); } - + parent_host_view_->set_popup_host_view(this); parent_host_view_->popup_bitmap_.reset(new SkBitmap); parent_callback_ = base::Bind(&OffScreenRenderWidgetHostView::OnPopupPaint, parent_host_view_->weak_ptr_factory_.GetWeakPtr()); - + popup_position_ = pos; - + ResizeRootLayer(); Show(); } @@ -775,7 +775,7 @@ void OffScreenRenderWidgetHostView::Destroy() { Hide(); } } - + delete this; } @@ -813,8 +813,8 @@ void OffScreenRenderWidgetHostView::EndFrameSubscription() { } void OffScreenRenderWidgetHostView::InitAsGuest( - content::RenderWidgetHostView* parent_host_view, - content::RenderWidgetHostViewGuest* guest_view) { + content::RenderWidgetHostView* parent_host_view, + content::RenderWidgetHostViewGuest* guest_view) { parent_host_view_->AddGuestHostView(this); parent_host_view_->RegisterGuestViewFrameSwappedCallback(guest_view); } @@ -931,9 +931,9 @@ bool OffScreenRenderWidgetHostView::TransformPointToCoordSpaceForView( void OffScreenRenderWidgetHostView::CancelWidget() { if (render_widget_host_) - render_widget_host_->LostCapture(); + render_widget_host_->LostCapture(); Hide(); - + if (parent_host_view_) { if (parent_host_view_->popup_host_view_ == this) { parent_host_view_->set_popup_host_view(NULL); @@ -946,7 +946,7 @@ void OffScreenRenderWidgetHostView::CancelWidget() { } parent_host_view_ = NULL; } - + if (render_widget_host_ && !is_destroyed_) { is_destroyed_ = true; // Results in a call to Destroy(). @@ -976,7 +976,7 @@ void OffScreenRenderWidgetHostView::OnGuestViewFrameSwapped( content::RenderWidgetHostViewGuest* guest_host_view) { InvalidateBounds( gfx::ConvertRectToPixel(scale_factor_, guest_host_view->GetViewBounds())); - + RegisterGuestViewFrameSwappedCallback(guest_host_view); } @@ -1023,16 +1023,16 @@ void OffScreenRenderWidgetHostView::SetNeedsBeginFrames( } void CopyBitmapTo( - const SkBitmap& destination, - const SkBitmap& source, + const SkBitmap& destination, + const SkBitmap& source, const gfx::Rect& pos) { SkAutoLockPixels source_pixels_lock(source); SkAutoLockPixels destination_pixels_lock(destination); - + char* src = static_cast(source.getPixels()); char* dest = static_cast(destination.getPixels()); int pixelsize = source.bytesPerPixel(); - + if (pos.x() + pos.width() <= destination.width() && pos.y() + pos.height() <= destination.height()) { for (int i = 0; i < pos.height(); i++) { @@ -1041,14 +1041,14 @@ void CopyBitmapTo( source.width() * pixelsize); } } - + destination.notifyPixelsChanged(); } void OffScreenRenderWidgetHostView::OnPaint( const gfx::Rect& damage_rect, const SkBitmap& bitmap) { TRACE_EVENT0("electron", "OffScreenRenderWidgetHostView::OnPaint"); - + HoldResize(); if (parent_callback_) @@ -1057,14 +1057,14 @@ void OffScreenRenderWidgetHostView::OnPaint( gfx::Rect pos = popup_host_view_->popup_position_; SkBitmap copy = SkBitmapOperations::CreateTiledBitmap(bitmap, pos.x(), pos.y(), pos.width(), pos.height()); - + CopyBitmapTo(bitmap, *popup_bitmap_, pos); callback_.Run(damage_rect, bitmap); CopyBitmapTo(bitmap, copy, pos); } else { callback_.Run(damage_rect, bitmap); } - + ReleaseResize(); } @@ -1098,7 +1098,7 @@ void OffScreenRenderWidgetHostView::WasResized() { pending_resize_ = true; return; } - + ResizeRootLayer(); if (render_widget_host_) render_widget_host_->WasResized(); @@ -1184,10 +1184,10 @@ void OffScreenRenderWidgetHostView::SetFrameRate(int frame_rate) { frame_rate = 1; if (frame_rate > 60) frame_rate = 60; - + frame_rate_ = frame_rate; } - + for (auto guest_host_view : guest_host_views_) guest_host_view->SetFrameRate(frame_rate); diff --git a/atom/browser/osr/osr_render_widget_host_view.h b/atom/browser/osr/osr_render_widget_host_view.h index aa7a0577778c..f1d6a0066dc6 100644 --- a/atom/browser/osr/osr_render_widget_host_view.h +++ b/atom/browser/osr/osr_render_widget_host_view.h @@ -5,6 +5,7 @@ #ifndef ATOM_BROWSER_OSR_OSR_RENDER_WIDGET_HOST_VIEW_H_ #define ATOM_BROWSER_OSR_OSR_RENDER_WIDGET_HOST_VIEW_H_ +#include #include #include @@ -142,7 +143,7 @@ class OffScreenRenderWidgetHostView std::unique_ptr) override; void EndFrameSubscription() override; void InitAsGuest( - content::RenderWidgetHostView*, + content::RenderWidgetHostView*, content::RenderWidgetHostViewGuest*) override; bool HasAcceleratedSurface(const gfx::Size &) override; gfx::Rect GetBoundsInRootWindow(void) override; @@ -209,15 +210,15 @@ class OffScreenRenderWidgetHostView void OnPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap); void OnPopupPaint(const gfx::Rect& damage_rect, const SkBitmap& bitmap); - + bool IsPopupWidget() const { return popup_type_ != blink::WebPopupTypeNone; } - + void HoldResize(); void ReleaseResize(); void WasResized(); - + void ProcessKeyboardEvent( const content::NativeWebKeyboardEvent& event) override; void ProcessMouseEvent(const blink::WebMouseEvent& event, @@ -247,7 +248,7 @@ class OffScreenRenderWidgetHostView void set_popup_host_view(OffScreenRenderWidgetHostView* popup_view) { popup_host_view_ = popup_view; } - + void set_child_host_view(OffScreenRenderWidgetHostView* child_view) { child_host_view_ = child_view; } @@ -260,13 +261,13 @@ class OffScreenRenderWidgetHostView // Weak ptrs. content::RenderWidgetHostImpl* render_widget_host_; - + OffScreenRenderWidgetHostView* parent_host_view_; OffScreenRenderWidgetHostView* popup_host_view_; std::unique_ptr popup_bitmap_; OffScreenRenderWidgetHostView* child_host_view_; std::set guest_host_views_; - + NativeWindow* native_window_; OffScreenOutputDevice* software_output_device_; @@ -283,7 +284,7 @@ class OffScreenRenderWidgetHostView gfx::Vector2dF last_scroll_offset_; gfx::Size size_; bool painting_; - + bool is_showing_; bool is_destroyed_; gfx::Rect popup_position_; diff --git a/atom/browser/osr/osr_web_contents_view.cc b/atom/browser/osr/osr_web_contents_view.cc index 18b24c1c1ce3..38dbbe00440d 100644 --- a/atom/browser/osr/osr_web_contents_view.cc +++ b/atom/browser/osr/osr_web_contents_view.cc @@ -34,7 +34,7 @@ void OffScreenWebContentsView::SetWebContents( #if !defined(OS_MACOSX) gfx::NativeView OffScreenWebContentsView::GetNativeView() const { if (!web_contents_) return gfx::NativeView(); - + auto relay = NativeWindowRelay::FromWebContents(web_contents_); if (!relay) return gfx::NativeView(); return relay->window->GetNativeView(); @@ -42,7 +42,7 @@ gfx::NativeView OffScreenWebContentsView::GetNativeView() const { gfx::NativeView OffScreenWebContentsView::GetContentNativeView() const { if (!web_contents_) return gfx::NativeView(); - + auto relay = NativeWindowRelay::FromWebContents(web_contents_); if (!relay) return gfx::NativeView(); return relay->window->GetNativeView(); @@ -50,7 +50,7 @@ gfx::NativeView OffScreenWebContentsView::GetContentNativeView() const { gfx::NativeWindow OffScreenWebContentsView::GetTopLevelNativeWindow() const { if (!web_contents_) return gfx::NativeWindow(); - + auto relay = NativeWindowRelay::FromWebContents(web_contents_); if (!relay) return gfx::NativeWindow(); return relay->window->GetNativeWindow(); @@ -90,18 +90,18 @@ void OffScreenWebContentsView::CreateView(const gfx::Size& initial_size, content::RenderWidgetHostViewBase* OffScreenWebContentsView::CreateViewForWidget( - content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack) { + content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack) { if (render_widget_host->GetView()) { return static_cast( render_widget_host->GetView()); } - + auto relay = NativeWindowRelay::FromWebContents(web_contents_); return new OffScreenRenderWidgetHostView( - transparent_, - callback_, - render_widget_host, - nullptr, + transparent_, + callback_, + render_widget_host, + nullptr, relay->window.get()); } @@ -113,19 +113,19 @@ content::RenderWidgetHostViewBase* return static_cast( render_widget_host->GetView()); } - + OffScreenRenderWidgetHostView* embedder_host_view = nullptr; if (embedder_render_widget_host) { embedder_host_view = static_cast( embedder_render_widget_host->GetView()); } - + auto relay = NativeWindowRelay::FromWebContents(web_contents_); return new OffScreenRenderWidgetHostView( - transparent_, - callback_, - render_widget_host, - embedder_host_view, + transparent_, + callback_, + render_widget_host, + embedder_host_view, relay->window.get()); } @@ -134,10 +134,10 @@ content::RenderWidgetHostViewBase* content::RenderWidgetHost* render_widget_host) { auto relay = NativeWindowRelay::FromWebContents(web_contents_); return new OffScreenRenderWidgetHostView( - transparent_, - callback_, - render_widget_host, - GetView(), + transparent_, + callback_, + render_widget_host, + GetView(), relay->window.get()); } @@ -164,13 +164,13 @@ void OffScreenWebContentsView::GetScreenInfo( screen_info->orientation_angle = 0; screen_info->orientation_type = content::SCREEN_ORIENTATION_VALUES_LANDSCAPE_PRIMARY; - + if (GetView()) { screen_info->rect = gfx::Rect(GetView()->size()); screen_info->available_rect = gfx::Rect(GetView()->size()); screen_info->device_scale_factor = GetView()->scale_factor(); } else { - const display::Display display = + const display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay(); screen_info->rect = display.bounds(); screen_info->available_rect = display.work_area(); From 8f546313b66cad4ee3d38ff01bff0e956cac18ae Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Sun, 5 Mar 2017 16:19:51 +0100 Subject: [PATCH 03/24] add popup window bounds to damage_rect --- atom/browser/osr/osr_render_widget_host_view.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index f20e96f89d62..7d370fbed651 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -1050,16 +1050,19 @@ void OffScreenRenderWidgetHostView::OnPaint( TRACE_EVENT0("electron", "OffScreenRenderWidgetHostView::OnPaint"); HoldResize(); - - if (parent_callback_) + + if (parent_callback_) { parent_callback_.Run(damage_rect, bitmap); - else if (popup_host_view_ && popup_bitmap_.get()) { + } else if (popup_host_view_ && popup_bitmap_.get()) { gfx::Rect pos = popup_host_view_->popup_position_; + gfx::Rect damage(damage_rect); + damage.Union(pos); + SkBitmap copy = SkBitmapOperations::CreateTiledBitmap(bitmap, pos.x(), pos.y(), pos.width(), pos.height()); CopyBitmapTo(bitmap, *popup_bitmap_, pos); - callback_.Run(damage_rect, bitmap); + callback_.Run(damage, bitmap); CopyBitmapTo(bitmap, copy, pos); } else { callback_.Run(damage_rect, bitmap); From bccc25165d1d7d9745eb29643ab99e850a34eb25 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Sun, 5 Mar 2017 16:20:32 +0100 Subject: [PATCH 04/24] fix mouse wheel event sending typo --- atom/browser/api/atom_api_web_contents.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index b6fb523c1613..880cdddedf3d 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1441,7 +1441,7 @@ void WebContents::SendInputEvent(v8::Isolate* isolate, } else if (type == blink::WebInputEvent::MouseWheel) { blink::WebMouseWheelEvent mouse_wheel_event; if (mate::ConvertFromV8(isolate, input_event, &mouse_wheel_event)) { - view->ProcessMouseEvent(mouse_wheel_event, ui::LatencyInfo()); + view->ProcessMouseWheelEvent(mouse_wheel_event, ui::LatencyInfo()); return; } } From 062b1ed43e1ef952234d017ac476e06dc85486ea Mon Sep 17 00:00:00 2001 From: gellert Date: Tue, 14 Mar 2017 12:56:24 +0100 Subject: [PATCH 05/24] moves createviewfordwidget method to osrrwhv --- atom/browser/native_window_mac.h | 1 + atom/browser/native_window_mac.mm | 4 +++ .../osr/osr_render_widget_host_view.cc | 26 ++++++++++++++++++- .../browser/osr/osr_render_widget_host_view.h | 6 +++++ atom/browser/osr/osr_web_contents_view.cc | 24 ----------------- atom/browser/osr/osr_web_contents_view.h | 3 --- 6 files changed, 36 insertions(+), 28 deletions(-) diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index af0f157ecaef..69bf3afef65a 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -89,6 +89,7 @@ class NativeWindowMac : public NativeWindow, void SetContentProtection(bool enable) override; void SetBrowserView(NativeBrowserView* browser_view) override; void SetParentWindow(NativeWindow* parent) override; + gfx::NativeView GetNativeView() override; gfx::NativeWindow GetNativeWindow() override; gfx::AcceleratedWidget GetAcceleratedWidget() override; void SetProgressBar(double progress, const ProgressState state) override; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 330d48226dc4..755e46c4f326 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -1314,6 +1314,10 @@ void NativeWindowMac::SetParentWindow(NativeWindow* parent) { [parent->GetNativeWindow() addChildWindow:window_ ordered:NSWindowAbove]; } +gfx::NativeView NativeWindowMac::GetNativeView() { + return inspectable_web_contents()->GetView()->GetNativeView(); +} + gfx::NativeWindow NativeWindowMac::GetNativeWindow() { return window_; } diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index 7d370fbed651..22cbd7a15c58 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -415,13 +415,13 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView( frame_rate_threshold_ms_(0), last_time_(base::Time::Now()), scale_factor_(kDefaultScaleFactor), + size_(native_window->GetSize()), painting_(true), is_showing_(!render_widget_host_->is_hidden()), is_destroyed_(false), popup_position_(gfx::Rect()), hold_resize_(false), pending_resize_(false), - size_(native_window->GetSize()), weak_ptr_factory_(this) { DCHECK(render_widget_host_); #if !defined(OS_MACOSX) @@ -839,6 +839,30 @@ gfx::Size OffScreenRenderWidgetHostView::GetRequestedRendererSize() const { return GetDelegatedFrameHost()->GetRequestedRendererSize(); } +content::RenderWidgetHostViewBase* + OffScreenRenderWidgetHostView::CreateViewForWidget( + content::RenderWidgetHost* render_widget_host, + content::RenderWidgetHost* embedder_render_widget_host, + content::WebContentsView* web_contents_view) { + if (render_widget_host->GetView()) { + return static_cast( + render_widget_host->GetView()); + } + + OffScreenRenderWidgetHostView* embedder_host_view = nullptr; + if (embedder_render_widget_host) { + embedder_host_view = static_cast( + embedder_render_widget_host->GetView()); + } + + return new OffScreenRenderWidgetHostView( + transparent_, + callback_, + render_widget_host, + embedder_host_view, + native_window_); +} + #if !defined(OS_MACOSX) ui::Layer* OffScreenRenderWidgetHostView::DelegatedFrameHostGetLayer() const { return const_cast(root_layer_.get()); diff --git a/atom/browser/osr/osr_render_widget_host_view.h b/atom/browser/osr/osr_render_widget_host_view.h index f1d6a0066dc6..0c2ece40ad39 100644 --- a/atom/browser/osr/osr_render_widget_host_view.h +++ b/atom/browser/osr/osr_render_widget_host_view.h @@ -26,6 +26,7 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/renderer_host/resize_lock.h" +#include "content/browser/web_contents/web_contents_view.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/WebKit/public/platform/WebVector.h" #include "ui/base/ime/text_input_client.h" @@ -152,6 +153,11 @@ class OffScreenRenderWidgetHostView gfx::Size GetPhysicalBackingSize() const override; gfx::Size GetRequestedRendererSize() const override; + content::RenderWidgetHostViewBase* CreateViewForWidget( + content::RenderWidgetHost*, + content::RenderWidgetHost*, + content::WebContentsView*) override; + #if !defined(OS_MACOSX) // content::DelegatedFrameHostClient: int DelegatedFrameHostGetGpuMemoryBufferClientId(void) const; diff --git a/atom/browser/osr/osr_web_contents_view.cc b/atom/browser/osr/osr_web_contents_view.cc index 38dbbe00440d..303a73ec5ac0 100644 --- a/atom/browser/osr/osr_web_contents_view.cc +++ b/atom/browser/osr/osr_web_contents_view.cc @@ -105,30 +105,6 @@ content::RenderWidgetHostViewBase* relay->window.get()); } -content::RenderWidgetHostViewBase* - OffScreenWebContentsView::CreateViewForWidget( - content::RenderWidgetHost* render_widget_host, - content::RenderWidgetHost* embedder_render_widget_host) { - if (render_widget_host->GetView()) { - return static_cast( - render_widget_host->GetView()); - } - - OffScreenRenderWidgetHostView* embedder_host_view = nullptr; - if (embedder_render_widget_host) { - embedder_host_view = static_cast( - embedder_render_widget_host->GetView()); - } - - auto relay = NativeWindowRelay::FromWebContents(web_contents_); - return new OffScreenRenderWidgetHostView( - transparent_, - callback_, - render_widget_host, - embedder_host_view, - relay->window.get()); -} - content::RenderWidgetHostViewBase* OffScreenWebContentsView::CreateViewForPopupWidget( content::RenderWidgetHost* render_widget_host) { diff --git a/atom/browser/osr/osr_web_contents_view.h b/atom/browser/osr/osr_web_contents_view.h index 57aee80d91f9..ffb3b38619c4 100644 --- a/atom/browser/osr/osr_web_contents_view.h +++ b/atom/browser/osr/osr_web_contents_view.h @@ -45,9 +45,6 @@ class OffScreenWebContentsView : public content::WebContentsView, content::RenderWidgetHostViewBase* CreateViewForWidget( content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack) override; - content::RenderWidgetHostViewBase* CreateViewForWidget( - content::RenderWidgetHost* render_widget_host, - content::RenderWidgetHost* embedder_render_widget_host) override; content::RenderWidgetHostViewBase* CreateViewForPopupWidget( content::RenderWidgetHost* render_widget_host) override; void SetPageTitle(const base::string16& title) override; From ff053bbe06ba499faab2ecf208cb6e5ff943c6b6 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Sun, 9 Apr 2017 01:24:09 +0200 Subject: [PATCH 06/24] call InvalidateBounds when popup updates --- atom/browser/osr/osr_render_widget_host_view.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index 22cbd7a15c58..b203d0db96cd 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -1099,6 +1099,7 @@ void OffScreenRenderWidgetHostView::OnPopupPaint( const gfx::Rect& damage_rect, const SkBitmap& bitmap) { if (popup_host_view_ && popup_bitmap_.get()) bitmap.deepCopyTo(popup_bitmap_.get()); + InvalidateBounds(popup_host_view_->popup_position_); } void OffScreenRenderWidgetHostView::HoldResize() { From 6b33564056bd18c9661f47dfd61797add6d584fb Mon Sep 17 00:00:00 2001 From: gellert Date: Sun, 9 Apr 2017 23:02:02 +0200 Subject: [PATCH 07/24] adds ipc send to disable external popups on macos --- atom/browser/osr/osr_web_contents_view.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/atom/browser/osr/osr_web_contents_view.cc b/atom/browser/osr/osr_web_contents_view.cc index 303a73ec5ac0..f5c07c8ed1f6 100644 --- a/atom/browser/osr/osr_web_contents_view.cc +++ b/atom/browser/osr/osr_web_contents_view.cc @@ -4,6 +4,7 @@ #include "atom/browser/osr/osr_web_contents_view.h" +#include "content/common/worker_messages.h" #include "content/public/browser/render_view_host.h" #include "third_party/WebKit/public/platform/WebScreenInfo.h" #include "ui/display/screen.h" @@ -124,6 +125,11 @@ void OffScreenWebContentsView::RenderViewCreated( content::RenderViewHost* host) { if (GetView()) GetView()->InstallTransparency(); + +#if defined(OS_MACOSX) + host->Send(new WorkerProcessMsg_DisableExternalPopupMenus( + host->GetRoutingID())); +#endif } void OffScreenWebContentsView::RenderViewSwappedIn( From 155fef99aede6b2314a3c602ec4501c050219401 Mon Sep 17 00:00:00 2001 From: gellert Date: Tue, 11 Apr 2017 14:19:34 +0200 Subject: [PATCH 08/24] adds offscreen renderer ipc message to disable external popups --- atom/browser/osr/osr_web_contents_view.cc | 5 ++--- atom/common/api/api_messages.h | 2 ++ atom/renderer/atom_render_view_observer.cc | 5 +++++ atom/renderer/atom_render_view_observer.h | 2 ++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/atom/browser/osr/osr_web_contents_view.cc b/atom/browser/osr/osr_web_contents_view.cc index f5c07c8ed1f6..8fe696831950 100644 --- a/atom/browser/osr/osr_web_contents_view.cc +++ b/atom/browser/osr/osr_web_contents_view.cc @@ -4,7 +4,7 @@ #include "atom/browser/osr/osr_web_contents_view.h" -#include "content/common/worker_messages.h" +#include "atom/common/api/api_messages.h" #include "content/public/browser/render_view_host.h" #include "third_party/WebKit/public/platform/WebScreenInfo.h" #include "ui/display/screen.h" @@ -127,8 +127,7 @@ void OffScreenWebContentsView::RenderViewCreated( GetView()->InstallTransparency(); #if defined(OS_MACOSX) - host->Send(new WorkerProcessMsg_DisableExternalPopupMenus( - host->GetRoutingID())); + host->Send(new AtomViewMsg_Offscreen(host->GetRoutingID())); #endif } diff --git a/atom/common/api/api_messages.h b/atom/common/api/api_messages.h index ef945d9eebe9..e25089b869a9 100644 --- a/atom/common/api/api_messages.h +++ b/atom/common/api/api_messages.h @@ -35,6 +35,8 @@ IPC_MESSAGE_ROUTED3(AtomViewMsg_Message, base::string16 /* channel */, base::ListValue /* arguments */) +IPC_MESSAGE_ROUTED0(AtomViewMsg_Offscreen) + // Sent by the renderer when the draggable regions are updated. IPC_MESSAGE_ROUTED1(AtomViewHostMsg_UpdateDraggableRegions, std::vector /* regions */) diff --git a/atom/renderer/atom_render_view_observer.cc b/atom/renderer/atom_render_view_observer.cc index a68238ba4ced..6aa26cccaf01 100644 --- a/atom/renderer/atom_render_view_observer.cc +++ b/atom/renderer/atom_render_view_observer.cc @@ -136,6 +136,7 @@ bool AtomRenderViewObserver::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(AtomRenderViewObserver, message) IPC_MESSAGE_HANDLER(AtomViewMsg_Message, OnBrowserMessage) + IPC_MESSAGE_HANDLER(AtomViewMsg_Offscreen, OnOffscreen) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -169,4 +170,8 @@ void AtomRenderViewObserver::OnBrowserMessage(bool send_to_all, } } +void AtomRenderViewObserver::OnOffscreen() { + blink::WebView::setUseExternalPopupMenus(false); +} + } // namespace atom diff --git a/atom/renderer/atom_render_view_observer.h b/atom/renderer/atom_render_view_observer.h index e642bbe94224..4751db2d8c6c 100644 --- a/atom/renderer/atom_render_view_observer.h +++ b/atom/renderer/atom_render_view_observer.h @@ -40,6 +40,8 @@ class AtomRenderViewObserver : public content::RenderViewObserver { const base::string16& channel, const base::ListValue& args); + void OnOffscreen(); + AtomRendererClient* renderer_client_; // Whether the document object has been created. From 2f32311292117f5eda05d1f1403548bbaa653eb8 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 12 Apr 2017 04:11:49 +0200 Subject: [PATCH 09/24] fix black bars around popups and scaled images when using gpu rendering --- atom/browser/osr/osr_web_contents_view.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/atom/browser/osr/osr_web_contents_view.cc b/atom/browser/osr/osr_web_contents_view.cc index 8fe696831950..efcdafd51c35 100644 --- a/atom/browser/osr/osr_web_contents_view.cc +++ b/atom/browser/osr/osr_web_contents_view.cc @@ -30,6 +30,8 @@ OffScreenWebContentsView::~OffScreenWebContentsView() { void OffScreenWebContentsView::SetWebContents( content::WebContents* web_contents) { web_contents_ = web_contents; + + RenderViewCreated(web_contents_->GetRenderViewHost()); } #if !defined(OS_MACOSX) @@ -139,23 +141,22 @@ void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled) { } void OffScreenWebContentsView::GetScreenInfo( - content::ScreenInfo* screen_info) const { + content::ScreenInfo* screen_info) const { screen_info->depth = 24; screen_info->depth_per_component = 8; screen_info->orientation_angle = 0; + screen_info->device_scale_factor = 1.0; screen_info->orientation_type = content::SCREEN_ORIENTATION_VALUES_LANDSCAPE_PRIMARY; if (GetView()) { screen_info->rect = gfx::Rect(GetView()->size()); screen_info->available_rect = gfx::Rect(GetView()->size()); - screen_info->device_scale_factor = GetView()->scale_factor(); } else { const display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay(); screen_info->rect = display.bounds(); screen_info->available_rect = display.work_area(); - screen_info->device_scale_factor = display.device_scale_factor(); } } From 704fde1939ff4c41ee2af37e570c8e98b9435e93 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 12 Apr 2017 16:15:58 +0200 Subject: [PATCH 10/24] port CEF pr that speeds up and simplifies GPU rendering --- .../osr/osr_render_widget_host_view.cc | 302 +++++------------- .../browser/osr/osr_render_widget_host_view.h | 2 +- 2 files changed, 75 insertions(+), 229 deletions(-) diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index b203d0db96cd..5827a04c31b9 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -101,68 +101,23 @@ class AtomResizeLock : public content::ResizeLock { class AtomCopyFrameGenerator { public: - AtomCopyFrameGenerator(int frame_rate_threshold_ms, - OffScreenRenderWidgetHostView* view) - : frame_rate_threshold_ms_(frame_rate_threshold_ms), - view_(view), - frame_pending_(false), - frame_in_progress_(false), + AtomCopyFrameGenerator(OffScreenRenderWidgetHostView* view, + int frame_rate_threshold_us) + : view_(view), frame_retry_count_(0), + next_frame_time_(base::TimeTicks::Now()), + frame_duration_(base::TimeDelta::FromMicroseconds( + frame_rate_threshold_us)), weak_ptr_factory_(this) { last_time_ = base::Time::Now(); } - void GenerateCopyFrame( - bool force_frame, - const gfx::Rect& damage_rect) { - if (force_frame && !frame_pending_) - frame_pending_ = true; - - if (!frame_pending_) - return; - - if (!damage_rect.IsEmpty()) - pending_damage_rect_.Union(damage_rect); - - if (frame_in_progress_) - return; - - frame_in_progress_ = true; - - const int64_t frame_rate_delta = - (base::TimeTicks::Now() - frame_start_time_).InMilliseconds(); - if (frame_rate_delta < frame_rate_threshold_ms_) { - content::BrowserThread::PostDelayedTask(content::BrowserThread::UI, - FROM_HERE, - base::Bind(&AtomCopyFrameGenerator::InternalGenerateCopyFrame, - weak_ptr_factory_.GetWeakPtr()), - base::TimeDelta::FromMilliseconds( - frame_rate_threshold_ms_ - frame_rate_delta)); - return; - } - - InternalGenerateCopyFrame(); - } - - bool frame_pending() const { return frame_pending_; } - - void set_frame_rate_threshold_ms(int frame_rate_threshold_ms) { - frame_rate_threshold_ms_ = frame_rate_threshold_ms; - } - - private: - void InternalGenerateCopyFrame() { - frame_pending_ = false; - frame_start_time_ = base::TimeTicks::Now(); - + void GenerateCopyFrame(const gfx::Rect& damage_rect) { if (!view_->render_widget_host()) return; - const gfx::Rect damage_rect = pending_damage_rect_; - pending_damage_rect_.SetRect(0, 0, 0, 0); - std::unique_ptr request = - cc::CopyOutputRequest::CreateRequest(base::Bind( + cc::CopyOutputRequest::CreateBitmapRequest(base::Bind( &AtomCopyFrameGenerator::CopyFromCompositingSurfaceHasResult, weak_ptr_factory_.GetWeakPtr(), damage_rect)); @@ -170,7 +125,13 @@ class AtomCopyFrameGenerator { request->set_area(gfx::Rect(view_->GetPhysicalBackingSize())); view_->GetRootLayer()->RequestCopyOfOutput(std::move(request)); } + + void set_frame_rate_threshold_us(int frame_rate_threshold_us) { + frame_duration_ = base::TimeDelta::FromMicroseconds( + frame_rate_threshold_us); + } +private: void CopyFromCompositingSurfaceHasResult( const gfx::Rect& damage_rect, std::unique_ptr result) { @@ -179,181 +140,63 @@ class AtomCopyFrameGenerator { OnCopyFrameCaptureFailure(damage_rect); return; } - - if (result->HasTexture()) { - PrepareTextureCopyOutputResult(damage_rect, std::move(result)); - return; - } - - DCHECK(result->HasBitmap()); - PrepareBitmapCopyOutputResult(damage_rect, std::move(result)); - } - - void PrepareTextureCopyOutputResult( - const gfx::Rect& damage_rect, - std::unique_ptr result) { - DCHECK(result->HasTexture()); - base::ScopedClosureRunner scoped_callback_runner( - base::Bind(&AtomCopyFrameGenerator::OnCopyFrameCaptureFailure, - weak_ptr_factory_.GetWeakPtr(), - damage_rect)); - - const gfx::Size& result_size = result->size(); - SkIRect bitmap_size; - if (bitmap_) - bitmap_->getBounds(&bitmap_size); - - if (!bitmap_ || - bitmap_size.width() != result_size.width() || - bitmap_size.height() != result_size.height()) { - bitmap_.reset(new SkBitmap); - bitmap_->allocN32Pixels(result_size.width(), - result_size.height(), - true); - if (bitmap_->drawsNothing()) - return; - } - - content::ImageTransportFactory* factory = - content::ImageTransportFactory::GetInstance(); - display_compositor::GLHelper* gl_helper = factory->GetGLHelper(); - if (!gl_helper) - return; - - std::unique_ptr bitmap_pixels_lock( - new SkAutoLockPixels(*bitmap_)); - uint8_t* pixels = static_cast(bitmap_->getPixels()); - - cc::TextureMailbox texture_mailbox; - std::unique_ptr release_callback; - result->TakeTexture(&texture_mailbox, &release_callback); - DCHECK(texture_mailbox.IsTexture()); - if (!texture_mailbox.IsTexture()) - return; - - ignore_result(scoped_callback_runner.Release()); - - gl_helper->CropScaleReadbackAndCleanMailbox( - texture_mailbox.mailbox(), - texture_mailbox.sync_token(), - result_size, - gfx::Rect(result_size), - result_size, - pixels, - kN32_SkColorType, - base::Bind( - &AtomCopyFrameGenerator::CopyFromCompositingSurfaceFinishedProxy, - weak_ptr_factory_.GetWeakPtr(), - base::Passed(&release_callback), - damage_rect, - base::Passed(&bitmap_), - base::Passed(&bitmap_pixels_lock)), - display_compositor::GLHelper::SCALER_QUALITY_FAST); - } - - static void CopyFromCompositingSurfaceFinishedProxy( - base::WeakPtr generator, - std::unique_ptr release_callback, - const gfx::Rect& damage_rect, - std::unique_ptr bitmap, - std::unique_ptr bitmap_pixels_lock, - bool result) { - gpu::SyncToken sync_token; - if (result) { - display_compositor::GLHelper* gl_helper = - content::ImageTransportFactory::GetInstance()->GetGLHelper(); - if (gl_helper) - gl_helper->GenerateSyncToken(&sync_token); - } - const bool lost_resource = !sync_token.HasData(); - release_callback->Run(sync_token, lost_resource); - - if (generator) { - generator->CopyFromCompositingSurfaceFinished( - damage_rect, std::move(bitmap), std::move(bitmap_pixels_lock), - result); - } else { - bitmap_pixels_lock.reset(); - bitmap.reset(); - } - } - - void CopyFromCompositingSurfaceFinished( - const gfx::Rect& damage_rect, - std::unique_ptr bitmap, - std::unique_ptr bitmap_pixels_lock, - bool result) { - DCHECK(!bitmap_); - bitmap_ = std::move(bitmap); - - if (result) { - OnCopyFrameCaptureSuccess(damage_rect, *bitmap_, - std::move(bitmap_pixels_lock)); - } else { - bitmap_pixels_lock.reset(); - OnCopyFrameCaptureFailure(damage_rect); - } - } - - void PrepareBitmapCopyOutputResult( - const gfx::Rect& damage_rect, - std::unique_ptr result) { + DCHECK(result->HasBitmap()); std::unique_ptr source = result->TakeBitmap(); DCHECK(source); if (source) { - std::unique_ptr bitmap_pixels_lock( - new SkAutoLockPixels(*source)); - OnCopyFrameCaptureSuccess(damage_rect, *source, - std::move(bitmap_pixels_lock)); + base::AutoLock autolock(lock_); + std::shared_ptr bitmap(source.release()); + + base::TimeTicks now = base::TimeTicks::Now(); + base::TimeDelta next_frame_in = next_frame_time_ - now; + if (next_frame_in > frame_duration_ / 4) { + next_frame_time_ += frame_duration_; + content::BrowserThread::PostDelayedTask(content::BrowserThread::UI, + FROM_HERE, + base::Bind(&AtomCopyFrameGenerator::OnCopyFrameCaptureSuccess, + weak_ptr_factory_.GetWeakPtr(), + damage_rect, + bitmap), + next_frame_in); + } else { + next_frame_time_ = now + frame_duration_; + OnCopyFrameCaptureSuccess(damage_rect, bitmap); + } + + frame_retry_count_ = 0; } else { OnCopyFrameCaptureFailure(damage_rect); } } - void OnCopyFrameCaptureFailure( - const gfx::Rect& damage_rect) { - pending_damage_rect_.Union(damage_rect); - + void OnCopyFrameCaptureFailure(const gfx::Rect& damage_rect) { const bool force_frame = (++frame_retry_count_ <= kFrameRetryLimit); - OnCopyFrameCaptureCompletion(force_frame); + if (force_frame) { + // Retry with the same |damage_rect|. + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&AtomCopyFrameGenerator::GenerateCopyFrame, + weak_ptr_factory_.GetWeakPtr(), + damage_rect)); + } } void OnCopyFrameCaptureSuccess( const gfx::Rect& damage_rect, - const SkBitmap& bitmap, - std::unique_ptr bitmap_pixels_lock) { - view_->OnPaint(damage_rect, bitmap); - - if (frame_retry_count_ > 0) - frame_retry_count_ = 0; - - OnCopyFrameCaptureCompletion(false); + std::shared_ptr bitmap) { + base::AutoLock lock(onPaintLock_); + view_->OnPaint(damage_rect, *bitmap); } - - void OnCopyFrameCaptureCompletion(bool force_frame) { - frame_in_progress_ = false; - - if (frame_pending_) { - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, - base::Bind(&AtomCopyFrameGenerator::GenerateCopyFrame, - weak_ptr_factory_.GetWeakPtr(), - force_frame, - gfx::Rect())); - } - } - - int frame_rate_threshold_ms_; + + base::Lock lock_; + base::Lock onPaintLock_; OffScreenRenderWidgetHostView* view_; base::Time last_time_; - base::TimeTicks frame_start_time_; - bool frame_pending_; - bool frame_in_progress_; int frame_retry_count_; - std::unique_ptr bitmap_; - gfx::Rect pending_damage_rect_; + base::TimeTicks next_frame_time_; + base::TimeDelta frame_duration_; base::WeakPtrFactory weak_ptr_factory_; @@ -362,12 +205,15 @@ class AtomCopyFrameGenerator { class AtomBeginFrameTimer : public cc::DelayBasedTimeSourceClient { public: - AtomBeginFrameTimer(int frame_rate_threshold_ms, + AtomBeginFrameTimer(int frame_rate_threshold_us, const base::Closure& callback) : callback_(callback) { time_source_.reset(new cc::DelayBasedTimeSource( content::BrowserThread::GetTaskRunnerForThread( content::BrowserThread::UI).get())); + time_source_->SetTimebaseAndInterval( + base::TimeTicks(), + base::TimeDelta::FromMicroseconds(frame_rate_threshold_us)); time_source_->SetClient(this); } @@ -379,10 +225,10 @@ class AtomBeginFrameTimer : public cc::DelayBasedTimeSourceClient { return time_source_->Active(); } - void SetFrameRateThresholdMs(int frame_rate_threshold_ms) { + void SetFrameRateThresholdUs(int frame_rate_threshold_us) { time_source_->SetTimebaseAndInterval( base::TimeTicks::Now(), - base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms)); + base::TimeDelta::FromMicroseconds(frame_rate_threshold_us)); } private: @@ -412,7 +258,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView( callback_(callback), parent_callback_(nullptr), frame_rate_(60), - frame_rate_threshold_ms_(0), + frame_rate_threshold_us_(0), last_time_(base::Time::Now()), scale_factor_(kDefaultScaleFactor), size_(native_window->GetSize()), @@ -496,7 +342,7 @@ void OffScreenRenderWidgetHostView::OnWindowClosed() { void OffScreenRenderWidgetHostView::OnBeginFrameTimerTick() { const base::TimeTicks frame_time = base::TimeTicks::Now(); const base::TimeDelta vsync_period = - base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms_); + base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_); SendBeginFrame(frame_time, vsync_period); } @@ -689,7 +535,7 @@ void OffScreenRenderWidgetHostView::OnSwapCompositorFrame( } else { if (!copy_frame_generator_.get()) { copy_frame_generator_.reset( - new AtomCopyFrameGenerator(frame_rate_threshold_ms_, this)); + new AtomCopyFrameGenerator(this, frame_rate_threshold_us_)); } // Determine the damage rectangle for the current frame. This is the same @@ -708,7 +554,7 @@ void OffScreenRenderWidgetHostView::OnSwapCompositorFrame( // Request a copy of the last compositor frame which will eventually call // OnPaint asynchronously. - copy_frame_generator_->GenerateCopyFrame(true, damage_rect); + copy_frame_generator_->GenerateCopyFrame(damage_rect); } } } @@ -1062,7 +908,7 @@ void CopyBitmapTo( for (int i = 0; i < pos.height(); i++) { memcpy(dest + ((pos.y() + i) * destination.width() + pos.x()) * pixelsize, src + (i * source.width()) * pixelsize, - source.width() * pixelsize); + pos.width() * pixelsize); } } @@ -1081,10 +927,10 @@ void OffScreenRenderWidgetHostView::OnPaint( gfx::Rect pos = popup_host_view_->popup_position_; gfx::Rect damage(damage_rect); damage.Union(pos); - + SkBitmap copy = SkBitmapOperations::CreateTiledBitmap(bitmap, pos.x(), pos.y(), pos.width(), pos.height()); - + CopyBitmapTo(bitmap, *popup_bitmap_, pos); callback_.Run(damage, bitmap); CopyBitmapTo(bitmap, copy, pos); @@ -1242,24 +1088,24 @@ OffScreenRenderWidgetHostView::GetDelegatedFrameHost() const { #endif void OffScreenRenderWidgetHostView::SetupFrameRate(bool force) { - if (!force && frame_rate_threshold_ms_ != 0) + if (!force && frame_rate_threshold_us_ != 0) return; - frame_rate_threshold_ms_ = 1000 / frame_rate_; + frame_rate_threshold_us_ = 1000000 / frame_rate_; GetCompositor()->vsync_manager()->SetAuthoritativeVSyncInterval( - base::TimeDelta::FromMilliseconds(frame_rate_threshold_ms_)); + base::TimeDelta::FromMicroseconds(frame_rate_threshold_us_)); - if (copy_frame_generator_) { - copy_frame_generator_->set_frame_rate_threshold_ms( - frame_rate_threshold_ms_); + if (copy_frame_generator_.get()) { + copy_frame_generator_->set_frame_rate_threshold_us( + frame_rate_threshold_us_); } - if (begin_frame_timer_) { - begin_frame_timer_->SetFrameRateThresholdMs(frame_rate_threshold_ms_); + if (begin_frame_timer_.get()) { + begin_frame_timer_->SetFrameRateThresholdUs(frame_rate_threshold_us_); } else { begin_frame_timer_.reset(new AtomBeginFrameTimer( - frame_rate_threshold_ms_, + frame_rate_threshold_us_, base::Bind(&OffScreenRenderWidgetHostView::OnBeginFrameTimerTick, weak_ptr_factory_.GetWeakPtr()))); } @@ -1273,7 +1119,7 @@ void OffScreenRenderWidgetHostView::InvalidateBounds(const gfx::Rect& bounds) { if (software_output_device_) { software_output_device_->OnPaint(bounds_in_pixels); } else if (copy_frame_generator_) { - copy_frame_generator_->GenerateCopyFrame(true, bounds_in_pixels); + copy_frame_generator_->GenerateCopyFrame(bounds_in_pixels); } } diff --git a/atom/browser/osr/osr_render_widget_host_view.h b/atom/browser/osr/osr_render_widget_host_view.h index 0c2ece40ad39..1f8558db1f9e 100644 --- a/atom/browser/osr/osr_render_widget_host_view.h +++ b/atom/browser/osr/osr_render_widget_host_view.h @@ -282,7 +282,7 @@ class OffScreenRenderWidgetHostView OnPaintCallback parent_callback_; int frame_rate_; - int frame_rate_threshold_ms_; + int frame_rate_threshold_us_; base::Time last_time_; From 89277dda9054009ebf2bf967ca3f79cd720860fe Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 12 Apr 2017 16:16:27 +0200 Subject: [PATCH 11/24] fix leaking of NativeImage instances --- atom/browser/api/atom_api_web_contents.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 880cdddedf3d..48473d75c61b 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1578,9 +1578,7 @@ bool WebContents::IsOffScreen() const { } void WebContents::OnPaint(const gfx::Rect& dirty_rect, const SkBitmap& bitmap) { - mate::Handle image = - NativeImage::Create(isolate(), gfx::Image::CreateFrom1xBitmap(bitmap)); - Emit("paint", dirty_rect, image); + Emit("paint", dirty_rect, gfx::Image::CreateFrom1xBitmap(bitmap)); } void WebContents::StartPainting() { From 1fcf6ea73f5a0412774197e405fa47ad8d5d6143 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 12 Apr 2017 16:17:07 +0200 Subject: [PATCH 12/24] add size hints to NativeImages to make node GC aware of the high amount of memory used by the instances --- atom/common/api/atom_api_native_image.cc | 18 ++++++++++++++---- atom/common/api/atom_api_native_image.h | 1 + 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 6811ab919303..4e3a37f9e866 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -200,22 +200,29 @@ void Noop(char*, void*) { } // namespace NativeImage::NativeImage(v8::Isolate* isolate, const gfx::Image& image) - : image_(image) { - Init(isolate); + : image_(image), isolate_(isolate) { + Init(isolate_); + isolate_->AdjustAmountOfExternalAllocatedMemory( + image_.Width() * image_.Height() * 4); } #if defined(OS_WIN) NativeImage::NativeImage(v8::Isolate* isolate, const base::FilePath& hicon_path) - : hicon_path_(hicon_path) { + : hicon_path_(hicon_path), isolate_(isolate) { // Use the 256x256 icon as fallback icon. gfx::ImageSkia image_skia; ReadImageSkiaFromICO(&image_skia, GetHICON(256)); image_ = gfx::Image(image_skia); Init(isolate); + isolate_->AdjustAmountOfExternalAllocatedMemory( + image_.Width() * image_.Height() * 4); } #endif -NativeImage::~NativeImage() {} +NativeImage::~NativeImage() { + isolate_->AdjustAmountOfExternalAllocatedMemory( + - image_.Width() * image_.Height() * 4); +} #if defined(OS_WIN) HICON NativeImage::GetHICON(int size) { @@ -352,6 +359,9 @@ mate::Handle NativeImage::Resize( bool width_set = options.GetInteger("width", &width); bool height_set = options.GetInteger("height", &height); size.SetSize(width, height); + + isolate_->AdjustAmountOfExternalAllocatedMemory( + (width_set * height_set - width * height) * 4); if (width_set && !height_set) { // Scale height to preserve original aspect ratio diff --git a/atom/common/api/atom_api_native_image.h b/atom/common/api/atom_api_native_image.h index 6ff7a0e29f37..0c2890d86f5c 100644 --- a/atom/common/api/atom_api_native_image.h +++ b/atom/common/api/atom_api_native_image.h @@ -99,6 +99,7 @@ class NativeImage : public mate::Wrappable { #endif gfx::Image image_; + v8::Isolate* isolate_; DISALLOW_COPY_AND_ASSIGN(NativeImage); }; From c54f7f2a8d5e04b1d3c168f3d21954a1396bbf2f Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 12 Apr 2017 19:34:52 +0200 Subject: [PATCH 13/24] use bounds instead of bounds_in_pixel --- atom/browser/osr/osr_render_widget_host_view.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index 5827a04c31b9..a5de6cfd103d 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -1117,9 +1117,9 @@ void OffScreenRenderWidgetHostView::Invalidate() { void OffScreenRenderWidgetHostView::InvalidateBounds(const gfx::Rect& bounds) { if (software_output_device_) { - software_output_device_->OnPaint(bounds_in_pixels); + software_output_device_->OnPaint(bounds); } else if (copy_frame_generator_) { - copy_frame_generator_->GenerateCopyFrame(bounds_in_pixels); + copy_frame_generator_->GenerateCopyFrame(bounds); } } From 3b94d268ebae907c6b9c78cc5cd95a69e8a026a1 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 12 Apr 2017 20:54:03 +0200 Subject: [PATCH 14/24] lint fix :memo: --- .../osr/osr_render_widget_host_view.cc | 20 +++++++++---------- atom/browser/osr/osr_web_contents_view.cc | 4 ++-- atom/common/api/atom_api_native_image.cc | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index a5de6cfd103d..a4faa1b6a7e1 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -125,13 +125,13 @@ class AtomCopyFrameGenerator { request->set_area(gfx::Rect(view_->GetPhysicalBackingSize())); view_->GetRootLayer()->RequestCopyOfOutput(std::move(request)); } - + void set_frame_rate_threshold_us(int frame_rate_threshold_us) { frame_duration_ = base::TimeDelta::FromMicroseconds( frame_rate_threshold_us); } -private: + private: void CopyFromCompositingSurfaceHasResult( const gfx::Rect& damage_rect, std::unique_ptr result) { @@ -140,22 +140,22 @@ private: OnCopyFrameCaptureFailure(damage_rect); return; } - + DCHECK(result->HasBitmap()); std::unique_ptr source = result->TakeBitmap(); DCHECK(source); if (source) { base::AutoLock autolock(lock_); std::shared_ptr bitmap(source.release()); - + base::TimeTicks now = base::TimeTicks::Now(); base::TimeDelta next_frame_in = next_frame_time_ - now; if (next_frame_in > frame_duration_ / 4) { next_frame_time_ += frame_duration_; content::BrowserThread::PostDelayedTask(content::BrowserThread::UI, - FROM_HERE, + FROM_HERE, base::Bind(&AtomCopyFrameGenerator::OnCopyFrameCaptureSuccess, - weak_ptr_factory_.GetWeakPtr(), + weak_ptr_factory_.GetWeakPtr(), damage_rect, bitmap), next_frame_in); @@ -163,7 +163,7 @@ private: next_frame_time_ = now + frame_duration_; OnCopyFrameCaptureSuccess(damage_rect, bitmap); } - + frame_retry_count_ = 0; } else { OnCopyFrameCaptureFailure(damage_rect); @@ -187,7 +187,7 @@ private: base::AutoLock lock(onPaintLock_); view_->OnPaint(damage_rect, *bitmap); } - + base::Lock lock_; base::Lock onPaintLock_; OffScreenRenderWidgetHostView* view_; @@ -927,10 +927,10 @@ void OffScreenRenderWidgetHostView::OnPaint( gfx::Rect pos = popup_host_view_->popup_position_; gfx::Rect damage(damage_rect); damage.Union(pos); - + SkBitmap copy = SkBitmapOperations::CreateTiledBitmap(bitmap, pos.x(), pos.y(), pos.width(), pos.height()); - + CopyBitmapTo(bitmap, *popup_bitmap_, pos); callback_.Run(damage, bitmap); CopyBitmapTo(bitmap, copy, pos); diff --git a/atom/browser/osr/osr_web_contents_view.cc b/atom/browser/osr/osr_web_contents_view.cc index efcdafd51c35..b9219f17122f 100644 --- a/atom/browser/osr/osr_web_contents_view.cc +++ b/atom/browser/osr/osr_web_contents_view.cc @@ -30,7 +30,7 @@ OffScreenWebContentsView::~OffScreenWebContentsView() { void OffScreenWebContentsView::SetWebContents( content::WebContents* web_contents) { web_contents_ = web_contents; - + RenderViewCreated(web_contents_->GetRenderViewHost()); } @@ -141,7 +141,7 @@ void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled) { } void OffScreenWebContentsView::GetScreenInfo( - content::ScreenInfo* screen_info) const { + content::ScreenInfo* screen_info) const { screen_info->depth = 24; screen_info->depth_per_component = 8; screen_info->orientation_angle = 0; diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 4e3a37f9e866..c2e5bba67e4b 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -359,7 +359,7 @@ mate::Handle NativeImage::Resize( bool width_set = options.GetInteger("width", &width); bool height_set = options.GetInteger("height", &height); size.SetSize(width, height); - + isolate_->AdjustAmountOfExternalAllocatedMemory( (width_set * height_set - width * height) * 4); From f03dccadb31d421b18cce5a7a703f96238bf2e04 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Thu, 13 Apr 2017 01:30:46 +0200 Subject: [PATCH 15/24] use white gutter color and paint damage rects over when paint starts in software osr --- atom/browser/osr/osr_output_device.cc | 21 +++++++++++++++++-- .../osr/osr_render_widget_host_view.cc | 2 +- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/atom/browser/osr/osr_output_device.cc b/atom/browser/osr/osr_output_device.cc index 49c4191e21ef..d418634272d7 100644 --- a/atom/browser/osr/osr_output_device.cc +++ b/atom/browser/osr/osr_output_device.cc @@ -4,7 +4,9 @@ #include "atom/browser/osr/osr_output_device.h" +#include "third_party/skia/src/core/SkColor.h" #include "third_party/skia/src/core/SkDevice.h" +#include "third_party/skia/src/core/SkRect.h" #include "ui/gfx/skia_util.h" namespace atom { @@ -36,8 +38,11 @@ void OffScreenOutputDevice::Resize( return; } - if (transparent_) - bitmap_->eraseARGB(0, 0, 0, 0); + if (transparent_) { + bitmap_->eraseColor(SK_ColorTRANSPARENT); + } else { + bitmap_->eraseColor(SK_ColorWHITE); + } canvas_.reset(new SkCanvas(*bitmap_)); } @@ -47,6 +52,18 @@ SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) { DCHECK(bitmap_.get()); damage_rect_ = damage_rect; + SkIRect damage = SkIRect::MakeXYWH( + damage_rect_.x(), + damage_rect_.y(), + damage_rect_.width(), + damage_rect_.height() + ); + + if (transparent_) { + bitmap_->erase(SK_ColorTRANSPARENT, damage); + } else { + bitmap_->erase(SK_ColorWHITE, damage); + } return canvas_.get(); } diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index a4faa1b6a7e1..3d3729d1ebf7 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -722,7 +722,7 @@ SkColor OffScreenRenderWidgetHostView::DelegatedFrameHostGetGutterColor( SkColor color) const { if (render_widget_host_->delegate() && render_widget_host_->delegate()->IsFullscreenForCurrentTab()) { - return SK_ColorBLACK; + return SK_ColorWHITE; } return color; } From aa89bc0bb871a883d1da63ad44a3b1ee17f7ad57 Mon Sep 17 00:00:00 2001 From: gellert Date: Fri, 14 Apr 2017 23:32:33 +0200 Subject: [PATCH 16/24] use outer webcontents for popups --- atom/browser/osr/osr_web_contents_view.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/atom/browser/osr/osr_web_contents_view.cc b/atom/browser/osr/osr_web_contents_view.cc index b9219f17122f..0e10abf6a034 100644 --- a/atom/browser/osr/osr_web_contents_view.cc +++ b/atom/browser/osr/osr_web_contents_view.cc @@ -5,6 +5,7 @@ #include "atom/browser/osr/osr_web_contents_view.h" #include "atom/common/api/api_messages.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/render_view_host.h" #include "third_party/WebKit/public/platform/WebScreenInfo.h" #include "ui/display/screen.h" @@ -112,11 +113,21 @@ content::RenderWidgetHostViewBase* OffScreenWebContentsView::CreateViewForPopupWidget( content::RenderWidgetHost* render_widget_host) { auto relay = NativeWindowRelay::FromWebContents(web_contents_); + + content::WebContentsImpl *web_contents_impl = + static_cast(web_contents_); + + OffScreenRenderWidgetHostView *view = + static_cast( + web_contents_impl->GetOuterWebContents() + ? web_contents_impl->GetOuterWebContents()->GetRenderWidgetHostView() + : web_contents_impl->GetRenderWidgetHostView()); + return new OffScreenRenderWidgetHostView( transparent_, callback_, render_widget_host, - GetView(), + view, relay->window.get()); } From 92cc6746b1322e00255b881eb767c2ba729da487 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Tue, 2 May 2017 03:57:40 +0200 Subject: [PATCH 17/24] resolve errors introduced during rebase --- atom/browser/osr/osr_output_device.cc | 4 ++-- atom/browser/osr/osr_render_widget_host_view.cc | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/atom/browser/osr/osr_output_device.cc b/atom/browser/osr/osr_output_device.cc index d418634272d7..c930cb7de983 100644 --- a/atom/browser/osr/osr_output_device.cc +++ b/atom/browser/osr/osr_output_device.cc @@ -4,9 +4,9 @@ #include "atom/browser/osr/osr_output_device.h" -#include "third_party/skia/src/core/SkColor.h" +#include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/src/core/SkDevice.h" -#include "third_party/skia/src/core/SkRect.h" #include "ui/gfx/skia_util.h" namespace atom { diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index 3d3729d1ebf7..f9ea13440fbc 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -271,6 +271,7 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView( weak_ptr_factory_(this) { DCHECK(render_widget_host_); #if !defined(OS_MACOSX) + bool is_guest_view_hack = parent_host_view_ != nullptr; delegated_frame_host_ = base::MakeUnique( AllocateFrameSinkId(is_guest_view_hack), this); From 576b702e8bf80c530adf3e3da83d100ef23afe65 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Tue, 2 May 2017 04:28:32 +0200 Subject: [PATCH 18/24] update native_mate and use the MarkHighMemoryUsage API to speed up garbage collection --- atom/common/api/atom_api_native_image.cc | 2 ++ vendor/native_mate | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index c2e5bba67e4b..a2e86186e7ae 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -204,6 +204,7 @@ NativeImage::NativeImage(v8::Isolate* isolate, const gfx::Image& image) Init(isolate_); isolate_->AdjustAmountOfExternalAllocatedMemory( image_.Width() * image_.Height() * 4); + MarkHighMemoryUsage(); } #if defined(OS_WIN) @@ -216,6 +217,7 @@ NativeImage::NativeImage(v8::Isolate* isolate, const base::FilePath& hicon_path) Init(isolate); isolate_->AdjustAmountOfExternalAllocatedMemory( image_.Width() * image_.Height() * 4); + MarkHighMemoryUsage(); } #endif diff --git a/vendor/native_mate b/vendor/native_mate index fd0e7dc4ab77..7d9c1a80f025 160000 --- a/vendor/native_mate +++ b/vendor/native_mate @@ -1 +1 @@ -Subproject commit fd0e7dc4ab778f0d1ccda6c9640464ea06ee771e +Subproject commit 7d9c1a80f025f4c46f7da8ea73246fe0f1968579 From 5c690ea46e0e6a06ec85e93813253a8eeeaceb9c Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Tue, 2 May 2017 04:29:16 +0200 Subject: [PATCH 19/24] don't store isolate_ in NativeImage and tune size hints --- atom/common/api/atom_api_native_image.cc | 25 ++++++++++++------------ atom/common/api/atom_api_native_image.h | 1 - 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index a2e86186e7ae..6bc012bc3abd 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -200,30 +200,34 @@ void Noop(char*, void*) { } // namespace NativeImage::NativeImage(v8::Isolate* isolate, const gfx::Image& image) - : image_(image), isolate_(isolate) { - Init(isolate_); - isolate_->AdjustAmountOfExternalAllocatedMemory( - image_.Width() * image_.Height() * 4); + : image_(image) { + Init(isolate); + if (image_.HasRepresentation(gfx::Image::kImageRepSkia)) { + isolate->AdjustAmountOfExternalAllocatedMemory( + image_.ToImageSkia()->bitmap()->getSize()); + } MarkHighMemoryUsage(); } #if defined(OS_WIN) NativeImage::NativeImage(v8::Isolate* isolate, const base::FilePath& hicon_path) - : hicon_path_(hicon_path), isolate_(isolate) { + : hicon_path_(hicon_path) { // Use the 256x256 icon as fallback icon. gfx::ImageSkia image_skia; ReadImageSkiaFromICO(&image_skia, GetHICON(256)); image_ = gfx::Image(image_skia); Init(isolate); - isolate_->AdjustAmountOfExternalAllocatedMemory( - image_.Width() * image_.Height() * 4); + isolate->AdjustAmountOfExternalAllocatedMemory( + image_.ToImageSkia()->bitmap()->getSize()); MarkHighMemoryUsage(); } #endif NativeImage::~NativeImage() { - isolate_->AdjustAmountOfExternalAllocatedMemory( - - image_.Width() * image_.Height() * 4); + if (image_.HasRepresentation(gfx::Image::kImageRepSkia)) { + isolate()->AdjustAmountOfExternalAllocatedMemory( + - static_cast(image_.ToImageSkia()->bitmap()->getSize())); + } } #if defined(OS_WIN) @@ -362,9 +366,6 @@ mate::Handle NativeImage::Resize( bool height_set = options.GetInteger("height", &height); size.SetSize(width, height); - isolate_->AdjustAmountOfExternalAllocatedMemory( - (width_set * height_set - width * height) * 4); - if (width_set && !height_set) { // Scale height to preserve original aspect ratio size.set_height(width); diff --git a/atom/common/api/atom_api_native_image.h b/atom/common/api/atom_api_native_image.h index 0c2890d86f5c..6ff7a0e29f37 100644 --- a/atom/common/api/atom_api_native_image.h +++ b/atom/common/api/atom_api_native_image.h @@ -99,7 +99,6 @@ class NativeImage : public mate::Wrappable { #endif gfx::Image image_; - v8::Isolate* isolate_; DISALLOW_COPY_AND_ASSIGN(NativeImage); }; From 8d1c17e036af88fe0a22d5489eabd62ba538a2c4 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Tue, 2 May 2017 04:44:30 +0200 Subject: [PATCH 20/24] remove GetSizeForNewRenderView --- atom/browser/api/atom_api_web_contents.cc | 10 ---------- atom/browser/api/atom_api_web_contents.h | 1 - 2 files changed, 11 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 48473d75c61b..92157e127276 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1642,16 +1642,6 @@ void WebContents::Invalidate() { } } -gfx::Size WebContents::GetSizeForNewRenderView( - content::WebContents* web_contents) const { - auto relay = NativeWindowRelay::FromWebContents(web_contents); - if (relay) { - return relay->window->GetSize(); - } - - return gfx::Size(); -} - void WebContents::SetZoomLevel(double level) { zoom_controller_->SetZoomLevel(level); } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 1916964fa254..1f926dbd7a5a 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -183,7 +183,6 @@ class WebContents : public mate::TrackableObject, void SetFrameRate(int frame_rate); int GetFrameRate() const; void Invalidate(); - gfx::Size GetSizeForNewRenderView(content::WebContents*) const override; // Methods for zoom handling. void SetZoomLevel(double level); From 6f80379b30fc2bc50be1ac3455ffd6d4d4f8243c Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Tue, 2 May 2017 06:08:33 +0200 Subject: [PATCH 21/24] use computeSize64 instead of getSize --- atom/common/api/atom_api_native_image.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 6bc012bc3abd..8597c22bbcb6 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -204,7 +204,7 @@ NativeImage::NativeImage(v8::Isolate* isolate, const gfx::Image& image) Init(isolate); if (image_.HasRepresentation(gfx::Image::kImageRepSkia)) { isolate->AdjustAmountOfExternalAllocatedMemory( - image_.ToImageSkia()->bitmap()->getSize()); + image_.ToImageSkia()->bitmap()->computeSize64()); } MarkHighMemoryUsage(); } @@ -218,7 +218,7 @@ NativeImage::NativeImage(v8::Isolate* isolate, const base::FilePath& hicon_path) image_ = gfx::Image(image_skia); Init(isolate); isolate->AdjustAmountOfExternalAllocatedMemory( - image_.ToImageSkia()->bitmap()->getSize()); + image_.ToImageSkia()->bitmap()->computeSize64()); MarkHighMemoryUsage(); } #endif @@ -226,7 +226,7 @@ NativeImage::NativeImage(v8::Isolate* isolate, const base::FilePath& hicon_path) NativeImage::~NativeImage() { if (image_.HasRepresentation(gfx::Image::kImageRepSkia)) { isolate()->AdjustAmountOfExternalAllocatedMemory( - - static_cast(image_.ToImageSkia()->bitmap()->getSize())); + - image_.ToImageSkia()->bitmap()->computeSize64()); } } From b1095faa712d90f23c0842ec0cedca5aa9a54269 Mon Sep 17 00:00:00 2001 From: gellert Date: Tue, 2 May 2017 20:46:07 +0200 Subject: [PATCH 22/24] minor fix for macos --- atom/browser/osr/osr_render_widget_host_view.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom/browser/osr/osr_render_widget_host_view.cc b/atom/browser/osr/osr_render_widget_host_view.cc index f9ea13440fbc..77002358154f 100644 --- a/atom/browser/osr/osr_render_widget_host_view.cc +++ b/atom/browser/osr/osr_render_widget_host_view.cc @@ -270,8 +270,8 @@ OffScreenRenderWidgetHostView::OffScreenRenderWidgetHostView( pending_resize_(false), weak_ptr_factory_(this) { DCHECK(render_widget_host_); -#if !defined(OS_MACOSX) bool is_guest_view_hack = parent_host_view_ != nullptr; +#if !defined(OS_MACOSX) delegated_frame_host_ = base::MakeUnique( AllocateFrameSinkId(is_guest_view_hack), this); From a76a4ddff2a7ed48f5bcd5e9379c14cd77b3e377 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Wed, 10 May 2017 23:04:19 +0200 Subject: [PATCH 23/24] :art: lint fix --- atom/browser/osr/osr_output_device.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/atom/browser/osr/osr_output_device.cc b/atom/browser/osr/osr_output_device.cc index c930cb7de983..c35e364236f6 100644 --- a/atom/browser/osr/osr_output_device.cc +++ b/atom/browser/osr/osr_output_device.cc @@ -53,12 +53,11 @@ SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) { damage_rect_ = damage_rect; SkIRect damage = SkIRect::MakeXYWH( - damage_rect_.x(), - damage_rect_.y(), - damage_rect_.width(), - damage_rect_.height() - ); - + damage_rect_.x(), + damage_rect_.y(), + damage_rect_.width(), + damage_rect_.height()); + if (transparent_) { bitmap_->erase(SK_ColorTRANSPARENT, damage); } else { From bf58373a407c49df6f036a1e00d945ee525ba798 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Thu, 11 May 2017 11:38:34 +0200 Subject: [PATCH 24/24] fix NativeImage size hint crashing when image is created from path --- atom/common/api/atom_api_native_image.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 8597c22bbcb6..c15e47407b64 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -217,8 +217,10 @@ NativeImage::NativeImage(v8::Isolate* isolate, const base::FilePath& hicon_path) ReadImageSkiaFromICO(&image_skia, GetHICON(256)); image_ = gfx::Image(image_skia); Init(isolate); - isolate->AdjustAmountOfExternalAllocatedMemory( - image_.ToImageSkia()->bitmap()->computeSize64()); + if (image_.HasRepresentation(gfx::Image::kImageRepSkia)) { + isolate->AdjustAmountOfExternalAllocatedMemory( + image_.ToImageSkia()->bitmap()->computeSize64()); + } MarkHighMemoryUsage(); } #endif