Move BeginFrameSubscription to WebContents

This commit is contained in:
Cheng Zhao 2015-09-18 15:57:43 +08:00
parent 42863e4700
commit 86f523d3c1
10 changed files with 137 additions and 121 deletions

View file

@ -850,7 +850,21 @@ void WebContents::SendInputEvent(v8::Isolate* isolate,
isolate, "Invalid event type")));
}
void WebContents::BeginFrameSubscription(
const FrameSubscriber::FrameCaptureCallback& callback) {
const auto view = web_contents()->GetRenderWidgetHostView();
if (view) {
scoped_ptr<FrameSubscriber> frame_subscriber(new FrameSubscriber(
isolate(), view->GetVisibleViewportSize(), callback));
view->BeginFrameSubscription(frame_subscriber.Pass());
}
}
void WebContents::EndFrameSubscription() {
const auto view = web_contents()->GetRenderWidgetHostView();
if (view)
view->EndFrameSubscription();
}
void WebContents::SetSize(const SetSizeParams& params) {
if (guest_delegate_)
@ -915,6 +929,9 @@ mate::ObjectTemplateBuilder WebContents::GetObjectTemplateBuilder(
.SetMethod("tabTraverse", &WebContents::TabTraverse)
.SetMethod("_send", &WebContents::SendIPCMessage, true)
.SetMethod("sendInputEvent", &WebContents::SendInputEvent)
.SetMethod("beginFrameSubscription",
&WebContents::BeginFrameSubscription)
.SetMethod("endFrameSubscription", &WebContents::EndFrameSubscription)
.SetMethod("setSize", &WebContents::SetSize)
.SetMethod("setAllowTransparency", &WebContents::SetAllowTransparency)
.SetMethod("isGuest", &WebContents::IsGuest)

View file

@ -8,6 +8,7 @@
#include <string>
#include <vector>
#include "atom/browser/api/frame_subscriber.h"
#include "atom/browser/api/trackable_object.h"
#include "atom/browser/common_web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
@ -121,6 +122,11 @@ class WebContents : public mate::TrackableObject<WebContents>,
// Send WebInputEvent to the page.
void SendInputEvent(v8::Isolate* isolate, v8::Local<v8::Value> input_event);
// Subscribe to the frame updates.
void BeginFrameSubscription(
const FrameSubscriber::FrameCaptureCallback& callback);
void EndFrameSubscription();
// Methods for creating <webview>.
void SetSize(const SetSizeParams& params);
void SetAllowTransparency(bool allow);

View file

@ -13,6 +13,7 @@
#include "atom/common/native_mate_converters/gurl_converter.h"
#include "atom/common/native_mate_converters/image_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/node_includes.h"
#include "atom/common/options_switches.h"
#include "content/public/browser/render_process_host.h"
#include "native_mate/constructor.h"
@ -24,8 +25,6 @@
#include "atom/browser/ui/win/taskbar_host.h"
#endif
#include "atom/common/node_includes.h"
#if defined(OS_WIN)
namespace mate {
@ -105,16 +104,6 @@ void Window::WillCloseWindow(bool* prevent_default) {
*prevent_default = Emit("close");
}
void Window::OnFrameRendered(scoped_ptr<uint8[]> rgb, const int size) {
v8::Locker locker(isolate());
v8::HandleScope handle_scope(isolate());
v8::MaybeLocal<v8::Object> data = node::Buffer::New(
isolate(),
reinterpret_cast<char*>(rgb.release()),
static_cast<size_t>(size));
Emit("frame-rendered", data.ToLocalChecked(), size);
}
void Window::OnWindowClosed() {
if (api_web_contents_) {
api_web_contents_->DestroyWebContents();
@ -536,14 +525,6 @@ bool Window::IsVisibleOnAllWorkspaces() {
return window_->IsVisibleOnAllWorkspaces();
}
void Window::BeginFrameSubscription() {
window_->SetFrameSubscription(true);
}
void Window::EndFrameSubscription() {
window_->SetFrameSubscription(false);
}
int32_t Window::ID() const {
return weak_map_id();
}
@ -628,8 +609,6 @@ void Window::BuildPrototype(v8::Isolate* isolate,
&Window::SetVisibleOnAllWorkspaces)
.SetMethod("isVisibleOnAllWorkspaces",
&Window::IsVisibleOnAllWorkspaces)
.SetMethod("beginFrameSubscription", &Window::BeginFrameSubscription)
.SetMethod("endFrameSubscription", &Window::EndFrameSubscription)
#if defined(OS_MACOSX)
.SetMethod("showDefinitionForSelection",
&Window::ShowDefinitionForSelection)

View file

@ -53,7 +53,6 @@ class Window : public mate::TrackableObject<Window>,
void OnPageTitleUpdated(bool* prevent_default,
const std::string& title) override;
void WillCloseWindow(bool* prevent_default) override;
void OnFrameRendered(scoped_ptr<uint8[]> rgb, const int size) override;
void OnWindowClosed() override;
void OnWindowBlur() override;
void OnWindowFocus() override;
@ -142,9 +141,6 @@ class Window : public mate::TrackableObject<Window>,
bool IsMenuBarVisible();
void SetAspectRatio(double aspect_ratio, mate::Arguments* args);
void BeginFrameSubscription();
void EndFrameSubscription();
#if defined(OS_MACOSX)
void ShowDefinitionForSelection();
#endif

View file

@ -0,0 +1,66 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include "atom/browser/api/frame_subscriber.h"
#include "atom/common/node_includes.h"
#include "base/bind.h"
#include "media/base/video_frame.h"
#include "media/base/yuv_convert.h"
namespace atom {
namespace api {
FrameSubscriber::FrameSubscriber(v8::Isolate* isolate,
const gfx::Size& size,
const FrameCaptureCallback& callback)
: isolate_(isolate), size_(size), callback_(callback) {
}
bool FrameSubscriber::ShouldCaptureFrame(
const gfx::Rect& damage_rect,
base::TimeTicks present_time,
scoped_refptr<media::VideoFrame>* storage,
DeliverFrameCallback* callback) {
*storage = media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_,
gfx::Rect(size_), size_,
base::TimeDelta());
*callback = base::Bind(&FrameSubscriber::OnFrameDelivered,
base::Unretained(this),
*storage);
return true;
}
void FrameSubscriber::OnFrameDelivered(
scoped_refptr<media::VideoFrame> frame, base::TimeTicks, bool result) {
if (!result)
return;
gfx::Rect rect = frame->visible_rect();
size_t rgb_arr_size = rect.width() * rect.height() * 4;
v8::MaybeLocal<v8::Object> buffer = node::Buffer::New(isolate_, rgb_arr_size);
if (buffer.IsEmpty())
return;
// Convert a frame of YUV to 32 bit ARGB.
media::ConvertYUVToRGB32(frame->data(media::VideoFrame::kYPlane),
frame->data(media::VideoFrame::kUPlane),
frame->data(media::VideoFrame::kVPlane),
reinterpret_cast<uint8*>(
node::Buffer::Data(buffer.ToLocalChecked())),
rect.width(), rect.height(),
frame->stride(media::VideoFrame::kYPlane),
frame->stride(media::VideoFrame::kUVPlane),
rect.width() * 4,
media::YV12);
v8::Locker locker(isolate_);
v8::HandleScope handle_scope(isolate_);
callback_.Run(buffer.ToLocalChecked());
}
} // namespace api
} // namespace atom

View file

@ -0,0 +1,45 @@
// Copyright (c) 2015 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#ifndef ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_
#define ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_
#include "base/callback.h"
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
#include "ui/gfx/geometry/size.h"
#include "v8/include/v8.h"
namespace atom {
namespace api {
class FrameSubscriber : public content::RenderWidgetHostViewFrameSubscriber {
public:
using FrameCaptureCallback = base::Callback<void(v8::Local<v8::Value>)>;
FrameSubscriber(v8::Isolate* isolate,
const gfx::Size& size,
const FrameCaptureCallback& callback);
bool ShouldCaptureFrame(const gfx::Rect& damage_rect,
base::TimeTicks present_time,
scoped_refptr<media::VideoFrame>* storage,
DeliverFrameCallback* callback) override;
private:
void OnFrameDelivered(
scoped_refptr<media::VideoFrame> frame, base::TimeTicks, bool);
v8::Isolate* isolate_;
gfx::Size size_;
FrameCaptureCallback callback_;
DISALLOW_COPY_AND_ASSIGN(FrameSubscriber);
};
} // namespace api
} // namespace atom
#endif // ATOM_BROWSER_API_FRAME_SUBSCRIBER_H_

View file

@ -8,7 +8,6 @@
#include <utility>
#include <vector>
#include "media/base/yuv_convert.h"
#include "atom/browser/atom_browser_context.h"
#include "atom/browser/atom_browser_main_parts.h"
#include "atom/browser/window_list.h"
@ -283,21 +282,6 @@ void NativeWindow::SetAspectRatio(double aspect_ratio,
aspect_ratio_extraSize_ = extra_size;
}
void NativeWindow::SetFrameSubscription(bool isOffscreen) {
const auto view = web_contents()->GetRenderWidgetHostView();
if (view) {
if (isOffscreen) {
scoped_ptr<content::RenderWidgetHostViewFrameSubscriber> subscriber(
new RenderSubscriber(
view->GetVisibleViewportSize(),
base::Bind(&NativeWindow::OnFrameReceived, base::Unretained(this))));
view->BeginFrameSubscription(subscriber.Pass());
} else {
view->EndFrameSubscription();
}
}
}
void NativeWindow::RequestToClosePage() {
bool prevent_default = false;
FOR_EACH_OBSERVER(NativeWindowObserver,
@ -517,44 +501,4 @@ void NativeWindow::OnCapturePageDone(const CapturePageCallback& callback,
callback.Run(bitmap);
}
void NativeWindow::OnFrameReceived(bool result,
scoped_refptr<media::VideoFrame> frame) {
if (result) {
gfx::Rect rect = frame->visible_rect();
const int rgb_arr_size = rect.width() * rect.height() * 4;
scoped_ptr<uint8[]> rgb_bytes(new uint8[rgb_arr_size]);
// Convert a frame of YUV to 32 bit ARGB.
media::ConvertYUVToRGB32(frame->data(media::VideoFrame::kYPlane),
frame->data(media::VideoFrame::kUPlane),
frame->data(media::VideoFrame::kVPlane),
rgb_bytes.get(),
rect.width(), rect.height(),
frame->stride(media::VideoFrame::kYPlane),
frame->stride(media::VideoFrame::kUVPlane),
rect.width() * 4,
media::YV12);
FOR_EACH_OBSERVER(NativeWindowObserver,
observers_,
OnFrameRendered(rgb_bytes.Pass(), rgb_arr_size));
}
}
bool RenderSubscriber::ShouldCaptureFrame(
const gfx::Rect& damage_rect,
base::TimeTicks present_time,
scoped_refptr<media::VideoFrame>* storage,
DeliverFrameCallback* callback) {
last_present_time_ = present_time;
*storage = media::VideoFrame::CreateFrame(media::VideoFrame::YV12, size_,
gfx::Rect(size_), size_,
base::TimeDelta());
*callback =
base::Bind(&RenderSubscriber::CallbackMethod, callback_, *storage);
return true;
}
} // namespace atom

View file

@ -9,8 +9,6 @@
#include <string>
#include <vector>
#include "media/base/video_frame.h"
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
#include "atom/browser/native_window_observer.h"
#include "atom/browser/ui/accelerator_util.h"
#include "base/cancelable_callback.h"
@ -171,9 +169,6 @@ class NativeWindow : public content::WebContentsObserver,
gfx::Size GetAspectRatioExtraSize();
void SetAspectRatio(double aspect_ratio, const gfx::Size& extra_size);
// Subscribe to the frame updates.
void SetFrameSubscription(bool isOffscreen);
base::WeakPtr<NativeWindow> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
@ -228,8 +223,6 @@ class NativeWindow : public content::WebContentsObserver,
has_dialog_attached_ = has_dialog_attached;
}
void OnFrameReceived(bool result, scoped_refptr<media::VideoFrame> frame);
protected:
NativeWindow(brightray::InspectableWebContents* inspectable_web_contents,
const mate::Dictionary& options);
@ -303,36 +296,6 @@ class NativeWindow : public content::WebContentsObserver,
DISALLOW_COPY_AND_ASSIGN(NativeWindow);
};
// This class provides a way to listen to frame renders and to use the rendered
// frames for offscreen rendering
class RenderSubscriber : public content::RenderWidgetHostViewFrameSubscriber {
public:
RenderSubscriber(
gfx::Size size,
base::Callback<void(bool, scoped_refptr<media::VideoFrame>)> callback)
: size_(size), callback_(callback) {}
bool ShouldCaptureFrame(const gfx::Rect& damage_rect,
base::TimeTicks present_time,
scoped_refptr<media::VideoFrame>* storage,
DeliverFrameCallback* callback) override;
base::TimeTicks last_present_time() const { return last_present_time_; }
static void CallbackMethod(
base::Callback<void(bool, scoped_refptr<media::VideoFrame>)> callback,
scoped_refptr<media::VideoFrame> frame,
base::TimeTicks present_time,
bool success) {
callback.Run(success, frame);
}
private:
gfx::Size size_;
base::Callback<void(bool, scoped_refptr<media::VideoFrame>)> callback_;
base::TimeTicks last_present_time_;
};
// This class provides a hook to get a NativeWindow from a WebContents.
class NativeWindowRelay :
public content::WebContentsUserData<NativeWindowRelay> {

View file

@ -27,8 +27,6 @@ class NativeWindowObserver {
const std::string& partition_id,
WindowOpenDisposition disposition) {}
virtual void OnFrameRendered(scoped_ptr<uint8[]> rgb, const int size) {}
// Called when user is starting an navigation in web page.
virtual void WillNavigate(bool* prevent_default, const GURL& url) {}

View file

@ -103,6 +103,8 @@
'atom/browser/api/event_emitter.h',
'atom/browser/api/trackable_object.cc',
'atom/browser/api/trackable_object.h',
'atom/browser/api/frame_subscriber.cc',
'atom/browser/api/frame_subscriber.h',
'atom/browser/auto_updater.cc',
'atom/browser/auto_updater.h',
'atom/browser/auto_updater_delegate.h',