Merge branch 'speedup-gpu' of https://github.com/MaxWhere/electron into speedup-gpu

This commit is contained in:
Heilig Benedek 2016-07-31 05:12:34 +02:00
commit 3e7ff466cd
15 changed files with 188 additions and 143 deletions

View file

@ -402,14 +402,6 @@ void WebContents::OnCreateWindow(const GURL& target_url,
Emit("new-window", target_url, frame_name, disposition); Emit("new-window", target_url, frame_name, disposition);
} }
void WebContents::RenderViewReady() {
// if (IsOffScreen()) {
// const auto rwhv = web_contents()->GetRenderWidgetHostView();
// auto osr_rwhv = static_cast<OffScreenRenderWidgetHostView *>(rwhv);
// osr_rwhv->SetPaintCallback(&paint_callback_);
// }
}
content::WebContents* WebContents::OpenURLFromTab( content::WebContents* WebContents::OpenURLFromTab(
content::WebContents* source, content::WebContents* source,
const content::OpenURLParams& params) { const content::OpenURLParams& params) {
@ -445,12 +437,6 @@ void WebContents::MoveContents(content::WebContents* source,
void WebContents::CloseContents(content::WebContents* source) { void WebContents::CloseContents(content::WebContents* source) {
Emit("close"); Emit("close");
if (IsOffScreen()) {
const auto osr_rwhv = static_cast<OffScreenRenderWidgetHostView*>(
web_contents()->GetRenderWidgetHostView());
osr_rwhv->SetPainting(false);
}
if ((type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) && owner_window()) if ((type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) && owner_window())
owner_window()->CloseContents(source); owner_window()->CloseContents(source);
} }
@ -1412,8 +1398,8 @@ void WebContents::OnPaint(
v8::MaybeLocal<v8::Object> buffer = node::Buffer::New(isolate v8::MaybeLocal<v8::Object> buffer = node::Buffer::New(isolate
, (char *)bitmap_pixels, sizeof(bitmap_pixels)); , (char *)bitmap_pixels, sizeof(bitmap_pixels));
Emit("paint", damage_rect, bitmap_width, bitmap_height, const gfx::Size bitmap_size = gfx::Size(bitmap_width, bitmap_height);
buffer.ToLocalChecked()); Emit("paint", damage_rect, buffer.ToLocalChecked(), bitmap_size);
} }
void WebContents::StartPainting() { void WebContents::StartPainting() {

View file

@ -278,7 +278,6 @@ class WebContents : public mate::TrackableObject<WebContents>,
void MediaStartedPlaying(const MediaPlayerId& id) override; void MediaStartedPlaying(const MediaPlayerId& id) override;
void MediaStoppedPlaying(const MediaPlayerId& id) override; void MediaStoppedPlaying(const MediaPlayerId& id) override;
void DidChangeThemeColor(SkColor theme_color) override; void DidChangeThemeColor(SkColor theme_color) override;
void RenderViewReady() override;
// brightray::InspectableWebContentsDelegate: // brightray::InspectableWebContentsDelegate:
void DevToolsReloadPage() override; void DevToolsReloadPage() override;

View file

@ -1,18 +1,17 @@
// Copyright (c) 2013 GitHub, Inc. // Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be // Use of this source code is governed by the MIT license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "atom/browser/osr_output_device.h" #include "atom/browser/osr_output_device.h"
#include <iostream>
#include "third_party/skia/include/core/SkDevice.h" #include "third_party/skia/include/core/SkDevice.h"
#include "ui/gfx/skia_util.h" #include "ui/gfx/skia_util.h"
namespace atom { namespace atom {
OffScreenOutputDevice::OffScreenOutputDevice(bool transparent, OffScreenOutputDevice::OffScreenOutputDevice(bool transparent,
const OnPaintCallback& callback) const OnPaintCallback& callback):
: transparent_(transparent), transparent_(transparent),
callback_(callback), callback_(callback),
active_(false) { active_(false) {
DCHECK(!callback_.is_null()); DCHECK(!callback_.is_null());
@ -21,9 +20,7 @@ OffScreenOutputDevice::OffScreenOutputDevice(bool transparent,
OffScreenOutputDevice::~OffScreenOutputDevice() { } OffScreenOutputDevice::~OffScreenOutputDevice() { }
void OffScreenOutputDevice::Resize( void OffScreenOutputDevice::Resize(
const gfx::Size& pixel_size, float scale_factor) { const gfx::Size& pixel_size, float scale_factor) {
std::cout << pixel_size.width() << "x" << pixel_size.height() << std::endl;
scale_factor_ = scale_factor; scale_factor_ = scale_factor;
if (viewport_pixel_size_ == pixel_size) return; if (viewport_pixel_size_ == pixel_size) return;
@ -47,7 +44,6 @@ void OffScreenOutputDevice::Resize(
} }
SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) { SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) {
// std::cout << "BeginPaint" << std::endl;
DCHECK(canvas_.get()); DCHECK(canvas_.get());
DCHECK(bitmap_.get()); DCHECK(bitmap_.get());
@ -57,8 +53,6 @@ SkCanvas* OffScreenOutputDevice::BeginPaint(const gfx::Rect& damage_rect) {
} }
void OffScreenOutputDevice::EndPaint() { void OffScreenOutputDevice::EndPaint() {
// std::cout << "EndPaint" << std::endl;
DCHECK(canvas_.get()); DCHECK(canvas_.get());
DCHECK(bitmap_.get()); DCHECK(bitmap_.get());
@ -75,7 +69,6 @@ void OffScreenOutputDevice::SetActive(bool active) {
return; return;
active_ = active; active_ = active;
// Call OnPaint immediately if deactivated while a damage rect is pending.
if (!active_ && !pending_damage_rect_.IsEmpty()) if (!active_ && !pending_damage_rect_.IsEmpty())
OnPaint(pending_damage_rect_); OnPaint(pending_damage_rect_);
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2013 GitHub, Inc. // Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be // Use of this source code is governed by the MIT license that can be
// found in the LICENSE file. // found in the LICENSE file.
@ -9,7 +9,6 @@
#include "cc/output/software_output_device.h" #include "cc/output/software_output_device.h"
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkCanvas.h"
#include "base/callback.h"
namespace atom { namespace atom {

View file

@ -1,4 +1,4 @@
// Copyright (c) 2013 GitHub, Inc. // Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be // Use of this source code is governed by the MIT license that can be
// found in the LICENSE file. // found in the LICENSE file.
@ -26,14 +26,10 @@
#include "cc/scheduler/delay_based_time_source.h" #include "cc/scheduler/delay_based_time_source.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include <iostream>
const float kDefaultScaleFactor = 1.0; const float kDefaultScaleFactor = 1.0;
const int kFrameRetryLimit = 2; const int kFrameRetryLimit = 2;
// const int kResizeLockTimeoutMs = 67;
namespace atom { namespace atom {
class AtomCopyFrameGenerator { class AtomCopyFrameGenerator {
@ -619,6 +615,7 @@ void OffScreenRenderWidgetHostView::RenderProcessGone(base::TerminationStatus,in
} }
void OffScreenRenderWidgetHostView::Destroy() { void OffScreenRenderWidgetHostView::Destroy() {
delete this;
} }
void OffScreenRenderWidgetHostView::SetTooltipText(const base::string16 &) { void OffScreenRenderWidgetHostView::SetTooltipText(const base::string16 &) {
@ -740,7 +737,7 @@ void OffScreenRenderWidgetHostView::DelegatedFrameHostSendCompositorSwapAck(
} }
void OffScreenRenderWidgetHostView::DelegatedFrameHostSendReclaimCompositorResources( void OffScreenRenderWidgetHostView::DelegatedFrameHostSendReclaimCompositorResources(
int output_surface_id, const cc::CompositorFrameAck& ack) { int output_surface_id, const cc::CompositorFrameAck& ack) {
render_widget_host_->Send(new ViewMsg_ReclaimCompositorResources( render_widget_host_->Send(new ViewMsg_ReclaimCompositorResources(
render_widget_host_->GetRoutingID(), render_widget_host_->GetRoutingID(),
output_surface_id, ack)); output_surface_id, ack));

View file

@ -1,4 +1,4 @@
// Copyright (c) 2013 GitHub, Inc. // Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be // Use of this source code is governed by the MIT license that can be
// found in the LICENSE file. // found in the LICENSE file.

View file

@ -1,17 +1,13 @@
#include "atom/browser/osr_render_widget_host_view.h" // Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.
#include <algorithm> #include "atom/browser/osr_render_widget_host_view.h"
#include <limits>
#include <utility>
#include <iostream>
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#include "base/compiler_specific.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "content/common/view_messages.h"
#include "ui/accelerated_widget_mac/accelerated_widget_mac.h" #include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
#include "ui/events/latency_info.h"
ui::AcceleratedWidgetMac* atom::OffScreenRenderWidgetHostView::GetAcceleratedWidgetMac() ui::AcceleratedWidgetMac* atom::OffScreenRenderWidgetHostView::GetAcceleratedWidgetMac()
const { const {
@ -20,7 +16,8 @@ ui::AcceleratedWidgetMac* atom::OffScreenRenderWidgetHostView::GetAcceleratedWid
return nullptr; return nullptr;
} }
NSView* atom::OffScreenRenderWidgetHostView::AcceleratedWidgetGetNSView() const { NSView* atom::OffScreenRenderWidgetHostView::AcceleratedWidgetGetNSView()
const {
return [window_ contentView]; return [window_ contentView];
} }
@ -75,13 +72,11 @@ void atom::OffScreenRenderWidgetHostView::SelectionChanged(
} }
void atom::OffScreenRenderWidgetHostView::CreatePlatformWidget() { void atom::OffScreenRenderWidgetHostView::CreatePlatformWidget() {
// Create a borderless non-visible 1x1 window.
window_ = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 1, 1) window_ = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 1, 1)
styleMask:NSBorderlessWindowMask styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
defer:NO]; defer:NO];
// Create a CALayer which is used by BrowserCompositorViewMac for rendering.
background_layer_ = [[[CALayer alloc] init] retain]; background_layer_ = [[[CALayer alloc] init] retain];
[background_layer_ setBackgroundColor:CGColorGetConstantColor(kCGColorClear)]; [background_layer_ setBackgroundColor:CGColorGetConstantColor(kCGColorClear)];
NSView* content_view = [window_ contentView]; NSView* content_view = [window_ contentView];
@ -95,9 +90,6 @@ void atom::OffScreenRenderWidgetHostView::CreatePlatformWidget() {
browser_compositor_->accelerated_widget_mac()->SetNSView(this); browser_compositor_->accelerated_widget_mac()->SetNSView(this);
browser_compositor_->compositor()->SetVisible(true); browser_compositor_->compositor()->SetVisible(true);
// CEF needs the browser compositor to remain responsive whereas normal
// rendering on OS X does not. This effectively reverts the changes from
// https://crbug.com/463988#c6
compositor_->SetLocksWillTimeOut(true); compositor_->SetLocksWillTimeOut(true);
browser_compositor_->Unsuspend(); browser_compositor_->Unsuspend();
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) 2013 GitHub, Inc. // Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be // Use of this source code is governed by the MIT license that can be
// found in the LICENSE file. // found in the LICENSE file.

View file

@ -1,11 +1,9 @@
// Copyright (c) 2013 GitHub, Inc. // Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be // Use of this source code is governed by the MIT license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "atom/browser/osr_web_contents_view.h" #include "atom/browser/osr_web_contents_view.h"
#include "atom/browser/osr_render_widget_host_view.h" #include "atom/browser/osr_render_widget_host_view.h"
#include <iostream>
namespace atom { namespace atom {
@ -21,138 +19,79 @@ void OffScreenWebContentsView::SetWebContents(
web_contents_ = web_contents; web_contents_ = web_contents;
} }
// Returns the native widget that contains the contents of the tab. gfx::NativeView OffScreenWebContentsView::GetNativeView() const {
gfx::NativeView OffScreenWebContentsView::GetNativeView() const{
// std::cout << "GetNativeView" << std::endl;
return gfx::NativeView(); return gfx::NativeView();
} }
// Returns the native widget with the main content of the tab (i.e. the main gfx::NativeView OffScreenWebContentsView::GetContentNativeView() const {
// render view host, though there may be many popups in the tab as children of
// the container).
gfx::NativeView OffScreenWebContentsView::GetContentNativeView() const{
// std::cout << "GetContentNativeView" << std::endl;
return gfx::NativeView(); return gfx::NativeView();
} }
// Returns the outermost native view. This will be used as the parent for gfx::NativeWindow OffScreenWebContentsView::GetTopLevelNativeWindow() const {
// dialog boxes.
gfx::NativeWindow OffScreenWebContentsView::GetTopLevelNativeWindow() const{
// std::cout << "GetTopLevelNativeWindow" << std::endl;
return gfx::NativeWindow(); return gfx::NativeWindow();
} }
// Computes the rectangle for the native widget that contains the contents of void OffScreenWebContentsView::GetContainerBounds(gfx::Rect* out) const {
// the tab in the screen coordinate system.
void OffScreenWebContentsView::GetContainerBounds(gfx::Rect* out) const{
// std::cout << "GetContainerBounds" << std::endl;
*out = GetViewBounds(); *out = GetViewBounds();
} }
// TODO(brettw) this is a hack. It's used in two places at the time of this void OffScreenWebContentsView::SizeContents(const gfx::Size& size) {
// writing: (1) when render view hosts switch, we need to size the replaced
// one to be correct, since it wouldn't have known about sizes that happened
// while it was hidden; (2) in constrained windows.
//
// (1) will be fixed once interstitials are cleaned up. (2) seems like it
// should be cleaned up or done some other way, since this works for normal
// WebContents without the special code.
void OffScreenWebContentsView::SizeContents(const gfx::Size& size){
// std::cout << "SizeContents" << std::endl;
} }
// Sets focus to the native widget for this tab. void OffScreenWebContentsView::Focus() {
void OffScreenWebContentsView::Focus(){
// std::cout << "OffScreenWebContentsView::Focus" << std::endl;
} }
// Sets focus to the appropriate element when the WebContents is shown the void OffScreenWebContentsView::SetInitialFocus() {
// first time.
void OffScreenWebContentsView::SetInitialFocus(){
// std::cout << "SetInitialFocus" << std::endl;
} }
// Stores the currently focused view. void OffScreenWebContentsView::StoreFocus() {
void OffScreenWebContentsView::StoreFocus(){
// std::cout << "StoreFocus" << std::endl;
} }
// Restores focus to the last focus view. If StoreFocus has not yet been void OffScreenWebContentsView::RestoreFocus() {
// invoked, SetInitialFocus is invoked.
void OffScreenWebContentsView::RestoreFocus(){
// std::cout << "RestoreFocus" << std::endl;
} }
// Returns the current drop data, if any. content::DropData* OffScreenWebContentsView::GetDropData() const {
content::DropData* OffScreenWebContentsView::GetDropData() const{
// std::cout << "GetDropData" << std::endl;
return nullptr; return nullptr;
} }
// Get the bounds of the View, relative to the parent. gfx::Rect OffScreenWebContentsView::GetViewBounds() const {
gfx::Rect OffScreenWebContentsView::GetViewBounds() const{
// std::cout << "OffScreenWebContentsView::GetViewBounds" << std::endl;
return view_ ? view_->GetViewBounds() : gfx::Rect(); return view_ ? view_->GetViewBounds() : gfx::Rect();
} }
void OffScreenWebContentsView::CreateView( void OffScreenWebContentsView::CreateView(const gfx::Size& initial_size,
const gfx::Size& initial_size, gfx::NativeView context){ gfx::NativeView context) {
std::cout << context << std::endl;
// std::cout << "CreateView" << std::endl;
// std::cout << initial_size.width() << "x" << initial_size.height() << std::endl;
} }
// Sets up the View that holds the rendered web page, receives messages for
// it and contains page plugins. The host view should be sized to the current
// size of the WebContents.
//
// |is_guest_view_hack| is temporary hack and will be removed once
// RenderWidgetHostViewGuest is not dependent on platform view.
// TODO(lazyboy): Remove |is_guest_view_hack| once http://crbug.com/330264 is
// fixed.
content::RenderWidgetHostViewBase* content::RenderWidgetHostViewBase*
OffScreenWebContentsView::CreateViewForWidget( OffScreenWebContentsView::CreateViewForWidget(
content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack){ content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack) {
auto relay = NativeWindowRelay::FromWebContents(web_contents_); auto relay = NativeWindowRelay::FromWebContents(web_contents_);
view_ = new OffScreenRenderWidgetHostView(render_widget_host, view_ = new OffScreenRenderWidgetHostView(render_widget_host,
relay->window.get()); relay->window.get());
return view_; return view_;
} }
// Creates a new View that holds a popup and receives messages for it.
content::RenderWidgetHostViewBase* content::RenderWidgetHostViewBase*
OffScreenWebContentsView::CreateViewForPopupWidget( OffScreenWebContentsView::CreateViewForPopupWidget(
content::RenderWidgetHost* render_widget_host){ content::RenderWidgetHost* render_widget_host) {
auto relay = NativeWindowRelay::FromWebContents(web_contents_); auto relay = NativeWindowRelay::FromWebContents(web_contents_);
view_ = new OffScreenRenderWidgetHostView(render_widget_host, view_ = new OffScreenRenderWidgetHostView(render_widget_host,
relay->window.get()); relay->window.get());
return view_; return view_;
} }
// Sets the page title for the native widgets corresponding to the view. This void OffScreenWebContentsView::SetPageTitle(const base::string16& title) {
// is not strictly necessary and isn't expected to be displayed anywhere, but
// can aid certain debugging tools such as Spy++ on Windows where you are
// trying to find a specific window.
void OffScreenWebContentsView::SetPageTitle(const base::string16& title){
// std::cout << "SetPageTitle" << std::endl;
// std::cout << title << std::endl;
} }
// Invoked when the WebContents is notified that the RenderView has been void OffScreenWebContentsView::RenderViewCreated(
// fully created. content::RenderViewHost* host) {
void OffScreenWebContentsView::RenderViewCreated(content::RenderViewHost* host){
// std::cout << "RenderViewCreated" << std::endl;
} }
// Invoked when the WebContents is notified that the RenderView has been void OffScreenWebContentsView::RenderViewSwappedIn(
// swapped in. content::RenderViewHost* host) {
void OffScreenWebContentsView::RenderViewSwappedIn(content::RenderViewHost* host){
// std::cout << "RenderViewSwappedIn" << std::endl;
} }
// Invoked to enable/disable overscroll gesture navigation. void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled) {
void OffScreenWebContentsView::SetOverscrollControllerEnabled(bool enabled){
// std::cout << "SetOverscrollControllerEnabled" << std::endl;
} }
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
@ -183,5 +122,4 @@ void OffScreenWebContentsView::UpdateDragCursor(
blink::WebDragOperation operation) { blink::WebDragOperation operation) {
} }
} // namespace atom } // namespace atom

View file

@ -1,4 +1,4 @@
// Copyright (c) 2013 GitHub, Inc. // Copyright (c) 2016 GitHub, Inc.
// Use of this source code is governed by the MIT license that can be // Use of this source code is governed by the MIT license that can be
// found in the LICENSE file. // found in the LICENSE file.
@ -20,10 +20,10 @@ public:
void SetWebContents(content::WebContents*); void SetWebContents(content::WebContents*);
// content::WebContentsView
gfx::NativeView GetNativeView() const override; gfx::NativeView GetNativeView() const override;
gfx::NativeView GetContentNativeView() const override; gfx::NativeView GetContentNativeView() const override;
gfx::NativeWindow GetTopLevelNativeWindow() const override; gfx::NativeWindow GetTopLevelNativeWindow() const override;
void GetContainerBounds(gfx::Rect* out) const override; void GetContainerBounds(gfx::Rect* out) const override;
void SizeContents(const gfx::Size& size) override; void SizeContents(const gfx::Size& size) override;
void Focus() override; void Focus() override;
@ -32,16 +32,13 @@ public:
void RestoreFocus() override; void RestoreFocus() override;
content::DropData* GetDropData() const override; content::DropData* GetDropData() const override;
gfx::Rect GetViewBounds() const override; gfx::Rect GetViewBounds() const override;
void CreateView( void CreateView(
const gfx::Size& initial_size, gfx::NativeView context) override; const gfx::Size& initial_size, gfx::NativeView context) override;
content::RenderWidgetHostViewBase* CreateViewForWidget( content::RenderWidgetHostViewBase* CreateViewForWidget(
content::RenderWidgetHost* render_widget_host, content::RenderWidgetHost* render_widget_host,
bool is_guest_view_hack) override; bool is_guest_view_hack) override;
content::RenderWidgetHostViewBase* CreateViewForPopupWidget( content::RenderWidgetHostViewBase* CreateViewForPopupWidget(
content::RenderWidgetHost* render_widget_host) override; content::RenderWidgetHost* render_widget_host) override;
void SetPageTitle(const base::string16& title) override; void SetPageTitle(const base::string16& title) override;
void RenderViewCreated(content::RenderViewHost* host) override; void RenderViewCreated(content::RenderViewHost* host) override;
void RenderViewSwappedIn(content::RenderViewHost* host) override; void RenderViewSwappedIn(content::RenderViewHost* host) override;

View file

@ -189,8 +189,6 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches(
command_line->AppendSwitch(cc::switches::kEnableBeginFrameScheduling); command_line->AppendSwitch(cc::switches::kEnableBeginFrameScheduling);
command_line->AppendSwitch(cc::switches::kShowFPSCounter); command_line->AppendSwitch(cc::switches::kShowFPSCounter);
// command_line->AppendSwitch("disable-gpu");
// command_line->AppendSwitch("disable-gpu-compositing");
} }
// static // static

View file

@ -274,6 +274,8 @@ The `webPreferences` option is an object that can have the following properties:
* `defaultEncoding` String - Defaults to `ISO-8859-1`. * `defaultEncoding` String - Defaults to `ISO-8859-1`.
* `backgroundThrottling` Boolean - Whether to throttle animations and timers * `backgroundThrottling` Boolean - Whether to throttle animations and timers
when the page becomes background. Defaults to `true`. when the page becomes background. Defaults to `true`.
* `offscreen` Boolean - Whether to enable offscreen rendering for the browser
window. Defaults to `false`.
### Instance Events ### Instance Events

View file

@ -174,6 +174,36 @@ logging level for all code in the source files under a `foo/bar` directory.
This switch only works when `--enable-logging` is also passed. This switch only works when `--enable-logging` is also passed.
## --disable-gpu
Disables the use of the GPU in the renderer process. If this is set with the
`--disable-gpu-compositing` switch, *offscreen rendering* will use a software
output device, which has much better overall performance but lacks of WebGL
and 3D CSS support.
## --disable-gpu-compositing
Disables the use of the GPU compositing in the renderer process. This should be
set with the `--disable-gpu` switch for *offscreen rendering*.
``` javascript
const {app, BrowserWindow} = require('electron');
app.commandLine.appendSwitch('disable-gpu');
app.commandLine.appendSwitch('disable-gpu-compositing');
let win = new BrowserWindow({
webPreferences: {
offscreen: true
}
});
win.loadURL('http://github.com');
win.webContents.on('paint', (event, dirty, data) => {
updateBitmap(dirty, data);
});
```
[app]: app.md [app]: app.md
[append-switch]: app.md#appcommandlineappendswitchswitch-value [append-switch]: app.md#appcommandlineappendswitchswitch-value
[ready]: app.md#event-ready [ready]: app.md#event-ready

View file

@ -452,6 +452,41 @@ app.on('ready', () => {
Emitted when a page's view is repainted. Emitted when a page's view is repainted.
#### Event: 'paint'
Returns:
* `event` Event
* `dirtyRect` Object
* `x` Number - the x coordinate on the bitmap
* `y` Number - the y coordinate on the bitmap
* `width` Number - the width of the dirty area
* `height` Number - the height of the dirty area
* `data` Buffer - the bitmap data of the dirty rect
* `bitmapSize` Object
* `width` Number - the width of the whole bitmap
* `height` Number - the height of the whole bitmap
Emitted when a new frame is generated. Only the dirty area is passed in the
buffer.
```javascript
const {BrowserWindow} = require('electron');
let win = new BrowserWindow({
width: 800,
height: 1500,
webPreferences: {
offscreen: true
}
});
win.loadURL('http://github.com');
win.webContents.on('paint', (event, dirty, data) => {
updateBitmap(dirty, data);
});
```
### Instance Methods ### Instance Methods
#### `contents.loadURL(url[, options])` #### `contents.loadURL(url[, options])`
@ -1024,6 +1059,27 @@ win.webContents.on('did-finish-load', () => {
Shows pop-up dictionary that searches the selected word on the page. Shows pop-up dictionary that searches the selected word on the page.
#### `contents.startPainting()`
If *offscreen rendering* is enabled and not painting, start painting.
#### `contents.stopPainting()`
If *offscreen rendering* is enabled and painting, stop painting.
#### `contents.isPainting()`
If *offscreen rendering* is enabled returns whether it is currently painting.
#### `contents.setFrameRate(fps)`
If *offscreen rendering* is enabled sets the frame rate to the specified number.
Only values between 1 and 60 are accepted.
#### `contents.getFrameRate()`
If *offscreen rendering* is enabled returns the current frame rate.
### Instance Properties ### Instance Properties
#### `contents.id` #### `contents.id`

View file

@ -0,0 +1,58 @@
# Offscreen Rendering
Offscreen rendering lets you obtain the content of a browser window in a bitmap,
so it can be rendered anywhere, for example on a texture in a 3D scene. The
offscreen rendering in Electron uses a similar approach than the [Chromium
Embedded Framework](https://bitbucket.org/chromiumembedded/cef) project.
Two modes of rendering can be used and only the dirty area is passed in the
`'paint'` event to be more efficient. The rendering can be stopped, continued
and the frame rate can be set. The specified frame rate is a top limit value,
when there is nothing happening on a webpage, no frames are generated. The
maximum frame rate is 60, because above that there is no benefit, just
performance loss.
## Two modes of rendering
### GPU accelerated
GPU accelerated rendering means that the GPU is used for composition. Because of
that the frame has to be copied from the GPU which requires more performance,
thus this mode is quite a bit slower than the other one. The benefit of this
mode that WebGL and 3D CSS animations are supported.
### Software output device
This mode uses a software output device for rendering in the CPU, so the frame
generation is much faster, thus this mode is preferred over the GPU accelerated
one. To enable this mode GPU acceleration has to be disabled like this:
``` javascript
const {app} = require('electron');
app.commandLine.appendSwitch('disable-gpu');
app.commandLine.appendSwitch('disable-gpu-compositing');
```
## Usage
``` javascript
const {app, BrowserWindow} = require('electron');
app.commandLine.appendSwitch('disable-gpu');
app.commandLine.appendSwitch('disable-gpu-compositing');
let win = new BrowserWindow({
width: 800,
height: 1500,
webPreferences: {
offscreen: true
}
});
win.loadURL('http://github.com');
win.webContents.setFrameRate(30);
win.webContents.on('paint', (event, dirty, data) => {
updateBitmap(dirty, data);
});
```