diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 52d24084d4b3..1a2318f4047e 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1195,11 +1195,18 @@ void WebContents::SendInputEvent(v8::Isolate* isolate, } void WebContents::BeginFrameSubscription( - const FrameSubscriber::FrameCaptureCallback& callback) { + mate::Arguments* args) { + FrameSubscriber::FrameCaptureCallback callback; + if (!args->GetNext(&callback)) + return; + + bool only_damaged = false; + args->GetNext(&only_damaged); + const auto view = web_contents()->GetRenderWidgetHostView(); if (view) { std::unique_ptr frame_subscriber(new FrameSubscriber( - isolate(), view, callback)); + isolate(), view, callback, only_damaged)); view->BeginFrameSubscription(std::move(frame_subscriber)); } } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 6151110887aa..dd91360c5fea 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -139,8 +139,7 @@ class WebContents : public mate::TrackableObject, void SendInputEvent(v8::Isolate* isolate, v8::Local input_event); // Subscribe to the frame updates. - void BeginFrameSubscription( - const FrameSubscriber::FrameCaptureCallback& callback); + void BeginFrameSubscription(mate::Arguments* args); void EndFrameSubscription(); // Methods for creating . diff --git a/atom/browser/api/frame_subscriber.cc b/atom/browser/api/frame_subscriber.cc index f81a8bea8b1a..364a146d7825 100644 --- a/atom/browser/api/frame_subscriber.cc +++ b/atom/browser/api/frame_subscriber.cc @@ -6,6 +6,7 @@ #include "base/bind.h" #include "atom/common/node_includes.h" +#include "atom/common/native_mate_converters/gfx_converter.h" #include "content/public/browser/render_widget_host.h" namespace atom { @@ -14,8 +15,10 @@ namespace api { FrameSubscriber::FrameSubscriber(v8::Isolate* isolate, content::RenderWidgetHostView* view, - const FrameCaptureCallback& callback) - : isolate_(isolate), view_(view), callback_(callback), weak_factory_(this) { + const FrameCaptureCallback& callback, + const bool& only_damaged) + : isolate_(isolate), view_(view), only_damaged_(only_damaged), + callback_(callback), weak_factory_(this) { } bool FrameSubscriber::ShouldCaptureFrame( @@ -27,21 +30,27 @@ bool FrameSubscriber::ShouldCaptureFrame( if (!view_ || !host) return false; - const auto size = view_->GetVisibleViewportSize(); + if (damage_rect.width() == 0 || damage_rect.height() == 0) + return false; + + gfx::Rect rect = gfx::Rect(view_->GetVisibleViewportSize()); + if (only_damaged_) + rect = damage_rect; host->CopyFromBackingStore( - gfx::Rect(size), - size, + rect, + rect.size(), base::Bind(&FrameSubscriber::OnFrameDelivered, - weak_factory_.GetWeakPtr(), callback_), + weak_factory_.GetWeakPtr(), callback_, rect), kBGRA_8888_SkColorType); return false; } void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback, - const SkBitmap& bitmap, content::ReadbackResponse response) { - if (bitmap.computeSize64() == 0) + const gfx::Rect& damage_rect, const SkBitmap& bitmap, + content::ReadbackResponse response) { + if (response != content::ReadbackResponse::READBACK_SUCCESS) return; v8::Locker locker(isolate_); @@ -57,7 +66,10 @@ void FrameSubscriber::OnFrameDelivered(const FrameCaptureCallback& callback, reinterpret_cast(node::Buffer::Data(buffer.ToLocalChecked())), rgb_arr_size); - callback_.Run(buffer.ToLocalChecked()); + v8::Local damage = + mate::Converter::ToV8(isolate_, damage_rect); + + callback_.Run(buffer.ToLocalChecked(), damage); } } // namespace api diff --git a/atom/browser/api/frame_subscriber.h b/atom/browser/api/frame_subscriber.h index a803d75dff20..9ab7f1eb9bd3 100644 --- a/atom/browser/api/frame_subscriber.h +++ b/atom/browser/api/frame_subscriber.h @@ -20,11 +20,13 @@ namespace api { class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { public: - using FrameCaptureCallback = base::Callback)>; + using FrameCaptureCallback = + base::Callback, v8::Local)>; FrameSubscriber(v8::Isolate* isolate, content::RenderWidgetHostView* view, - const FrameCaptureCallback& callback); + const FrameCaptureCallback& callback, + const bool& only_damaged); bool ShouldCaptureFrame(const gfx::Rect& damage_rect, base::TimeTicks present_time, @@ -33,11 +35,13 @@ class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber { private: void OnFrameDelivered(const FrameCaptureCallback& callback, - const SkBitmap& bitmap, content::ReadbackResponse response); + const gfx::Rect& damage_rect, const SkBitmap& bitmap, + content::ReadbackResponse response); v8::Isolate* isolate_; content::RenderWidgetHostView* view_; FrameCaptureCallback callback_; + bool only_damaged_; base::WeakPtrFactory weak_factory_;