Offscreen render support base
This commit is contained in:
parent
0efdb448b6
commit
e4c01f3187
10 changed files with 112 additions and 6 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -12,7 +12,7 @@
|
|||
url = https://github.com/atom/chromium-breakpad.git
|
||||
[submodule "vendor/native_mate"]
|
||||
path = vendor/native_mate
|
||||
url = https://github.com/zcbenz/native-mate.git
|
||||
url = https://github.com/brenca/native-mate.git
|
||||
[submodule "vendor/crashpad"]
|
||||
path = vendor/crashpad
|
||||
url = https://github.com/atom/crashpad.git
|
||||
|
|
|
@ -90,9 +90,11 @@ int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t* cmd, int) {
|
|||
if (env->GetVar("OS", &os) && os != "cygwin") {
|
||||
AttachConsole(ATTACH_PARENT_PROCESS);
|
||||
|
||||
FILE* dontcare;
|
||||
freopen_s(&dontcare, "CON", "w", stdout);
|
||||
freopen_s(&dontcare, "CON", "w", stderr);
|
||||
FILE* dontcare, *out, *err;
|
||||
out = fopen("out.txt", "w");
|
||||
err = fopen("err.txt", "w");
|
||||
freopen_s(&out, "CON", "w", stdout);
|
||||
freopen_s(&err, "CON", "w", stderr);
|
||||
freopen_s(&dontcare, "CON", "r", stdin);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "native_mate/constructor.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "atom/browser/native_window_views.h"
|
||||
|
@ -92,6 +93,16 @@ 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::Local<v8::ArrayBuffer> data = v8::ArrayBuffer::New(isolate(), rgb.get(), size);
|
||||
v8::Local<v8::Uint8ClampedArray> uint_data = v8::Uint8ClampedArray::New(data, 0, size);
|
||||
|
||||
Emit("frame-rendered", uint_data, size);
|
||||
}
|
||||
|
||||
void Window::OnWindowClosed() {
|
||||
if (api_web_contents_) {
|
||||
api_web_contents_->DestroyWebContents();
|
||||
|
|
|
@ -53,6 +53,7 @@ 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;
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
|
||||
#include "media/base/video_frame.h"
|
||||
#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"
|
||||
|
@ -147,8 +150,9 @@ NativeWindow* NativeWindow::FromWebContents(
|
|||
content::WebContents* web_contents) {
|
||||
WindowList& window_list = *WindowList::GetInstance();
|
||||
for (NativeWindow* window : window_list) {
|
||||
if (window->web_contents() == web_contents)
|
||||
if (window->web_contents() == web_contents){
|
||||
return window;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -201,6 +205,9 @@ void NativeWindow::InitFromOptions(const mate::Dictionary& options) {
|
|||
options.Get(switches::kTitle, &title);
|
||||
SetTitle(title);
|
||||
|
||||
offscreen_ = false;
|
||||
options.Get(switches::kOffScreenRender, &offscreen_);
|
||||
|
||||
// Then show it.
|
||||
bool show = true;
|
||||
options.Get(switches::kShow, &show);
|
||||
|
@ -540,6 +547,18 @@ void NativeWindow::DevToolsClosed() {
|
|||
FOR_EACH_OBSERVER(NativeWindowObserver, observers_, OnDevToolsClosed());
|
||||
}
|
||||
|
||||
void NativeWindow::RenderViewReady(){
|
||||
if(offscreen_){
|
||||
const auto view = web_contents()->GetRenderWidgetHostView();
|
||||
|
||||
scoped_ptr<content::RenderWidgetHostViewFrameSubscriber> subscriber(new RenderSubscriber(
|
||||
view->GetVisibleViewportSize(), base::Bind(&NativeWindow::OnFrameReceived, base::Unretained(this))
|
||||
));
|
||||
|
||||
view->BeginFrameSubscription(subscriber.Pass());
|
||||
}
|
||||
}
|
||||
|
||||
void NativeWindow::RenderViewCreated(
|
||||
content::RenderViewHost* render_view_host) {
|
||||
if (!transparent_)
|
||||
|
@ -617,4 +636,41 @@ 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
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#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"
|
||||
|
@ -232,6 +234,8 @@ 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);
|
||||
|
@ -243,6 +247,7 @@ class NativeWindow : public content::WebContentsObserver,
|
|||
|
||||
// content::WebContentsObserver:
|
||||
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
|
||||
void RenderViewReady() override;
|
||||
void BeforeUnloadDialogCancelled() override;
|
||||
void TitleWasSet(content::NavigationEntry* entry, bool explicit_set) override;
|
||||
bool OnMessageReceived(const IPC::Message& message) override;
|
||||
|
@ -263,6 +268,8 @@ class NativeWindow : public content::WebContentsObserver,
|
|||
const SkBitmap& bitmap,
|
||||
content::ReadbackResponse response);
|
||||
|
||||
bool offscreen_;
|
||||
|
||||
// Whether window has standard frame.
|
||||
bool has_frame_;
|
||||
|
||||
|
@ -317,6 +324,29 @@ class NativeWindow : public content::WebContentsObserver,
|
|||
DISALLOW_COPY_AND_ASSIGN(NativeWindow);
|
||||
};
|
||||
|
||||
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 :
|
||||
|
|
|
@ -27,6 +27,8 @@ 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) {}
|
||||
|
||||
|
|
|
@ -110,6 +110,8 @@ const char kRegisterStandardSchemes[] = "register-standard-schemes";
|
|||
// The browser process app model ID
|
||||
const char kAppUserModelId[] = "app-user-model-id";
|
||||
|
||||
const char kOffScreenRender[] = "offscreen-render";
|
||||
|
||||
} // namespace switches
|
||||
|
||||
} // namespace atom
|
||||
|
|
|
@ -60,6 +60,8 @@ extern const char kRegisterStandardSchemes[];
|
|||
|
||||
extern const char kAppUserModelId[];
|
||||
|
||||
extern const char kOffScreenRender[];
|
||||
|
||||
} // namespace switches
|
||||
|
||||
} // namespace atom
|
||||
|
|
2
vendor/native_mate
vendored
2
vendor/native_mate
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 67d9eaa215e8727d86dc7b1f7a10be8699848f1f
|
||||
Subproject commit 31b6395d9938558ea39a77ef2f432beaf2dcd4cb
|
Loading…
Add table
Add a link
Reference in a new issue