From 8c4ebdc88e4146bb75b4d22c72824c3c1251d763 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 4 Aug 2016 13:47:52 +0900 Subject: [PATCH 1/6] Emit NativeImage objects in paint event --- atom/browser/api/atom_api_web_contents.cc | 13 ++++------- docs/api/web-contents.md | 28 +++++++---------------- docs/tutorial/offscreen-rendering.md | 25 ++++++++++---------- 3 files changed, 24 insertions(+), 42 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index a5360c633975..a95dcf666e60 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1337,15 +1337,10 @@ bool WebContents::IsOffScreen() const { return type_ == OFF_SCREEN; } -void WebContents::OnPaint(const gfx::Rect& dirty_rect, - const SkBitmap& bitmap) { - v8::MaybeLocal buffer = node::Buffer::Copy( - isolate(), - reinterpret_cast(bitmap.getPixels()), bitmap.getSize()); - if (!buffer.IsEmpty()) { - Emit("paint", dirty_rect, buffer.ToLocalChecked(), - gfx::Size(bitmap.width(), bitmap.height())); - } +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); } void WebContents::StartPainting() { diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 81e5a14b0745..6a1193e62e0e 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -463,33 +463,21 @@ 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 + * `x` Integer - The x coordinate on the image. + * `y` Integer - The y coordinate on the image. + * `width` Integer - The width of the dirty area. + * `height` Integer - The height of the dirty area. +* `image` [NativeImage](native-image.md) - The image data of the dirty rect 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 - } +let win = new BrowserWindow({webPreferences: {offscreen: true}}) +win.webContents.on('paint', (event, dirty, image) => { + fs.writeSync('frame.png', image.toPNG()) }) win.loadURL('http://github.com') - -win.webContents.on('paint', (event, dirty, data) => { - // updateBitmap(dirty, data) -}) ``` ### Instance Methods diff --git a/docs/tutorial/offscreen-rendering.md b/docs/tutorial/offscreen-rendering.md index 8edcb573756e..8d75e74012eb 100644 --- a/docs/tutorial/offscreen-rendering.md +++ b/docs/tutorial/offscreen-rendering.md @@ -37,19 +37,18 @@ const {app, BrowserWindow} = require('electron') app.disableHardwareAcceleration() -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) +let win +app.once('ready', () => { + win = new BrowserWindow({ + webPreferences: { + offscreen: true + } + }) + win.loadURL('http://github.com') + win.webContents.on('paint', (event, dirty, image) => { + fs.writeSync('frame.png', image.toPNG()) + }) + win.webContents.setFrameRate(30) }) ``` From 736fbd46c61126c434c34e905ccb1f014099ecc6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 4 Aug 2016 13:58:50 +0900 Subject: [PATCH 2/6] docs: Show how to use bitmap data directly --- docs/api/web-contents.md | 4 +++- docs/tutorial/offscreen-rendering.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 6a1193e62e0e..1ca64d9efcb7 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -473,9 +473,11 @@ 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({webPreferences: {offscreen: true}}) win.webContents.on('paint', (event, dirty, image) => { - fs.writeSync('frame.png', image.toPNG()) + // updateBitmap(dirty, image.toBitmap()) }) win.loadURL('http://github.com') ``` diff --git a/docs/tutorial/offscreen-rendering.md b/docs/tutorial/offscreen-rendering.md index 8d75e74012eb..0f8a6b3ee48d 100644 --- a/docs/tutorial/offscreen-rendering.md +++ b/docs/tutorial/offscreen-rendering.md @@ -46,7 +46,7 @@ app.once('ready', () => { }) win.loadURL('http://github.com') win.webContents.on('paint', (event, dirty, image) => { - fs.writeSync('frame.png', image.toPNG()) + // updateBitmap(dirty, image.toBitmap()) }) win.webContents.setFrameRate(30) }) From 37f5ef571225c95518d5fd3b78ba8c4994338cb2 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Thu, 4 Aug 2016 19:36:01 +0200 Subject: [PATCH 3/6] add getBitmap to NativeImage --- atom/common/api/atom_api_native_image.cc | 13 +++++++++++++ atom/common/api/atom_api_native_image.h | 1 + 2 files changed, 14 insertions(+) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index bd97ea338504..6aeb2fbebb70 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -228,6 +228,18 @@ v8::Local NativeImage::ToBitmap(v8::Isolate* isolate) { bitmap->getSafeSize()).ToLocalChecked(); } +void noop(char*, void*) {} + +v8::Local NativeImage::GetBitmap(v8::Isolate* isolate) { + const SkBitmap* bitmap = image_.ToSkBitmap(); + SkPixelRef* ref = bitmap->pixelRef(); + return node::Buffer::New(isolate, + reinterpret_cast(ref->pixels()), + bitmap->getSafeSize(), + &noop, + nullptr).ToLocalChecked(); +} + v8::Local NativeImage::ToJPEG(v8::Isolate* isolate, int quality) { std::vector output; gfx::JPEG1xEncodedDataFromImage(image_, quality, &output); @@ -361,6 +373,7 @@ void NativeImage::BuildPrototype( .SetMethod("toPNG", &NativeImage::ToPNG) .SetMethod("toJPEG", &NativeImage::ToJPEG) .SetMethod("toBitmap", &NativeImage::ToBitmap) + .SetMethod("getBitmap", &NativeImage::GetBitmap) .SetMethod("getNativeHandle", &NativeImage::GetNativeHandle) .SetMethod("toDataURL", &NativeImage::ToDataURL) .SetMethod("isEmpty", &NativeImage::IsEmpty) diff --git a/atom/common/api/atom_api_native_image.h b/atom/common/api/atom_api_native_image.h index d6fddd10763d..743a3c599b7e 100644 --- a/atom/common/api/atom_api_native_image.h +++ b/atom/common/api/atom_api_native_image.h @@ -71,6 +71,7 @@ class NativeImage : public mate::Wrappable { v8::Local ToPNG(v8::Isolate* isolate); v8::Local ToJPEG(v8::Isolate* isolate, int quality); v8::Local ToBitmap(v8::Isolate* isolate); + v8::Local GetBitmap(v8::Isolate* isolate); v8::Local GetNativeHandle( v8::Isolate* isolate, mate::Arguments* args); From b5c19a9c6db3dc6e474d7e12741170bed5143f31 Mon Sep 17 00:00:00 2001 From: Heilig Benedek Date: Thu, 4 Aug 2016 19:45:06 +0200 Subject: [PATCH 4/6] update docs --- docs/api/native-image.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/api/native-image.md b/docs/api/native-image.md index d0c9a3b62f97..c78b1d636f64 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -163,12 +163,17 @@ Returns a [Buffer][buffer] that contains the image's `JPEG` encoded data. #### `image.toBitmap()` -Returns a [Buffer][buffer] that contains the image's raw pixel data. +Returns a [Buffer][buffer] that contains a copy of the image's raw pixel data. #### `image.toDataURL()` Returns the data URL of the image. +#### `image.getBitmap()` + +Returns a [Buffer][buffer] that contains the image's raw pixel data. The pixel +data is not owned by the `Buffer` object. + #### `image.getNativeHandle()` _macOS_ Returns a [Buffer][buffer] that stores C pointer to underlying native handle of From 1be253e1aa967477c23e352a425a780edc383a77 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 5 Aug 2016 17:55:57 +0900 Subject: [PATCH 5/6] Cleanup the code of getBitmap --- atom/common/api/atom_api_native_image.cc | 25 ++++++++++++------------ docs/api/native-image.md | 10 +++++++--- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/atom/common/api/atom_api_native_image.cc b/atom/common/api/atom_api_native_image.cc index 6aeb2fbebb70..b08c9a95d3a7 100644 --- a/atom/common/api/atom_api_native_image.cc +++ b/atom/common/api/atom_api_native_image.cc @@ -172,6 +172,9 @@ bool ReadImageSkiaFromICO(gfx::ImageSkia* image, HICON icon) { } #endif +void Noop(char*, void*) { +} + } // namespace NativeImage::NativeImage(v8::Isolate* isolate, const gfx::Image& image) @@ -228,18 +231,6 @@ v8::Local NativeImage::ToBitmap(v8::Isolate* isolate) { bitmap->getSafeSize()).ToLocalChecked(); } -void noop(char*, void*) {} - -v8::Local NativeImage::GetBitmap(v8::Isolate* isolate) { - const SkBitmap* bitmap = image_.ToSkBitmap(); - SkPixelRef* ref = bitmap->pixelRef(); - return node::Buffer::New(isolate, - reinterpret_cast(ref->pixels()), - bitmap->getSafeSize(), - &noop, - nullptr).ToLocalChecked(); -} - v8::Local NativeImage::ToJPEG(v8::Isolate* isolate, int quality) { std::vector output; gfx::JPEG1xEncodedDataFromImage(image_, quality, &output); @@ -258,6 +249,16 @@ std::string NativeImage::ToDataURL() { return data_url; } +v8::Local NativeImage::GetBitmap(v8::Isolate* isolate) { + const SkBitmap* bitmap = image_.ToSkBitmap(); + SkPixelRef* ref = bitmap->pixelRef(); + return node::Buffer::New(isolate, + reinterpret_cast(ref->pixels()), + bitmap->getSafeSize(), + &Noop, + nullptr).ToLocalChecked(); +} + v8::Local NativeImage::GetNativeHandle(v8::Isolate* isolate, mate::Arguments* args) { #if defined(OS_MACOSX) diff --git a/docs/api/native-image.md b/docs/api/native-image.md index c78b1d636f64..947a5b77b038 100644 --- a/docs/api/native-image.md +++ b/docs/api/native-image.md @@ -163,7 +163,8 @@ Returns a [Buffer][buffer] that contains the image's `JPEG` encoded data. #### `image.toBitmap()` -Returns a [Buffer][buffer] that contains a copy of the image's raw pixel data. +Returns a [Buffer][buffer] that contains a copy of the image's raw bitmap pixel +data. #### `image.toDataURL()` @@ -171,8 +172,11 @@ Returns the data URL of the image. #### `image.getBitmap()` -Returns a [Buffer][buffer] that contains the image's raw pixel data. The pixel -data is not owned by the `Buffer` object. +Returns a [Buffer][buffer] that contains the image's raw bitmap pixel data. + +The difference between `getBitmap()` and `toBitmap()` is, `getBitmap()` does not +copy the bitmap data, so you have to use the returned Buffer immediately in +current event loop tick, otherwise the data might be changed or destroyed. #### `image.getNativeHandle()` _macOS_ From 7173d8b01b009ee4cb6c86d393568cab763648c6 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 5 Aug 2016 18:08:36 +0900 Subject: [PATCH 6/6] Use getBitmap in docs --- docs/api/web-contents.md | 4 ++-- docs/tutorial/offscreen-rendering.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 1ca64d9efcb7..f000193b8390 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -467,7 +467,7 @@ Returns: * `y` Integer - The y coordinate on the image. * `width` Integer - The width of the dirty area. * `height` Integer - The height of the dirty area. -* `image` [NativeImage](native-image.md) - The image data of the dirty rect +* `image` [NativeImage](native-image.md) - The image data of the whole frame. Emitted when a new frame is generated. Only the dirty area is passed in the buffer. @@ -477,7 +477,7 @@ const {BrowserWindow} = require('electron') let win = new BrowserWindow({webPreferences: {offscreen: true}}) win.webContents.on('paint', (event, dirty, image) => { - // updateBitmap(dirty, image.toBitmap()) + // updateBitmap(dirty, image.getBitmap()) }) win.loadURL('http://github.com') ``` diff --git a/docs/tutorial/offscreen-rendering.md b/docs/tutorial/offscreen-rendering.md index 0f8a6b3ee48d..e47967bd35bb 100644 --- a/docs/tutorial/offscreen-rendering.md +++ b/docs/tutorial/offscreen-rendering.md @@ -46,7 +46,7 @@ app.once('ready', () => { }) win.loadURL('http://github.com') win.webContents.on('paint', (event, dirty, image) => { - // updateBitmap(dirty, image.toBitmap()) + // updateBitmap(dirty, image.getBitmap()) }) win.webContents.setFrameRate(30) })