diff options
author | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-15 09:54:59 +0000 |
---|---|---|
committer | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-15 09:54:59 +0000 |
commit | 24e4cac9b53c6bebf0bafc40213ff67fa9caedb2 (patch) | |
tree | 48f0dc561da445ccdbbd7e8b68a615796de26310 /ui/snapshot | |
parent | 3518cf1c81f097113a6d4dfa7abffcdc860ee3a4 (diff) | |
download | chromium_src-24e4cac9b53c6bebf0bafc40213ff67fa9caedb2.zip chromium_src-24e4cac9b53c6bebf0bafc40213ff67fa9caedb2.tar.gz chromium_src-24e4cac9b53c6bebf0bafc40213ff67fa9caedb2.tar.bz2 |
Make ChromeOS screenshots use async readback path
The synchronous readback path adds complexity through ui and cc
compositors and will ideally be removed. The screenshots already use a
post task mechanism to save to disk, so making them use the asynchronous
readback path instead is straightforward.
BUG=332167
Review URL: https://codereview.chromium.org/126373002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244859 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/snapshot')
-rw-r--r-- | ui/snapshot/snapshot.h | 6 | ||||
-rw-r--r-- | ui/snapshot/snapshot_android.cc | 2 | ||||
-rw-r--r-- | ui/snapshot/snapshot_aura.cc | 81 | ||||
-rw-r--r-- | ui/snapshot/snapshot_aura_unittest.cc | 5 | ||||
-rw-r--r-- | ui/snapshot/snapshot_gtk.cc | 2 | ||||
-rw-r--r-- | ui/snapshot/snapshot_ios.mm | 2 | ||||
-rw-r--r-- | ui/snapshot/snapshot_mac.mm | 2 | ||||
-rw-r--r-- | ui/snapshot/snapshot_win.cc | 4 |
8 files changed, 77 insertions, 27 deletions
diff --git a/ui/snapshot/snapshot.h b/ui/snapshot/snapshot.h index 7ccd8b4..53a6983 100644 --- a/ui/snapshot/snapshot.h +++ b/ui/snapshot/snapshot.h @@ -9,6 +9,7 @@ #include "base/callback_forward.h" #include "base/memory/ref_counted.h" +#include "base/memory/ref_counted_memory.h" #include "ui/gfx/native_widget_types.h" #include "ui/snapshot/snapshot_export.h" @@ -49,11 +50,14 @@ SNAPSHOT_EXPORT void GrabWindowSnapshotAndScaleAsync( const gfx::Size& target_size, scoped_refptr<base::TaskRunner> background_task_runner, const GrabWindowSnapshotAsyncCallback& callback); + +typedef base::Callback<void(scoped_refptr<base::RefCountedBytes> png_data)> + GrabWindowSnapshotAsyncPNGCallback; SNAPSHOT_EXPORT void GrabWindowSnapshotAsync( gfx::NativeWindow window, const gfx::Rect& source_rect, scoped_refptr<base::TaskRunner> background_task_runner, - const GrabWindowSnapshotAsyncCallback& callback); + const GrabWindowSnapshotAsyncPNGCallback& callback); } // namespace ui diff --git a/ui/snapshot/snapshot_android.cc b/ui/snapshot/snapshot_android.cc index 83c5efe..0189553 100644 --- a/ui/snapshot/snapshot_android.cc +++ b/ui/snapshot/snapshot_android.cc @@ -46,7 +46,7 @@ void GrabWindowSnapshotAsync( gfx::NativeWindow window, const gfx::Rect& source_rect, scoped_refptr<base::TaskRunner> background_task_runner, - const GrabWindowSnapshotAsyncCallback& callback) { + const GrabWindowSnapshotAsyncPNGCallback& callback) { NOTIMPLEMENTED(); } diff --git a/ui/snapshot/snapshot_aura.cc b/ui/snapshot/snapshot_aura.cc index 620d312..25eb73e 100644 --- a/ui/snapshot/snapshot_aura.cc +++ b/ui/snapshot/snapshot_aura.cc @@ -73,6 +73,27 @@ SkBitmap ScaleAndRotateBitmap(const SkBitmap& input_bitmap, return bitmap; } +scoped_refptr<base::RefCountedBytes> ScaleRotateAndEncodeBitmap( + const SkBitmap& input_bitmap, + gfx::Size target_size_pre_rotation, + gfx::Display::Rotation rotation) { + SkBitmap bitmap = + ScaleAndRotateBitmap(input_bitmap, target_size_pre_rotation, rotation); + scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes); + unsigned char* pixels = + reinterpret_cast<unsigned char*>(bitmap.pixelRef()->pixels()); + if (!gfx::PNGCodec::Encode(pixels, + gfx::PNGCodec::FORMAT_BGRA, + gfx::Size(bitmap.width(), bitmap.height()), + base::checked_numeric_cast<int>(bitmap.rowBytes()), + true, + std::vector<gfx::PNGCodec::Comment>(), + &png_data->data())) { + return scoped_refptr<base::RefCountedBytes>(); + } + return png_data; +} + void ScaleAndRotateCopyOutputResult( const GrabWindowSnapshotAsyncCallback& callback, const gfx::Size& target_size, @@ -96,6 +117,30 @@ void ScaleAndRotateCopyOutputResult( base::Bind(&OnFrameScalingFinished, callback)); } +void ScaleRotateAndEncodeCopyOutputResult( + const GrabWindowSnapshotAsyncPNGCallback& callback, + const gfx::Size& target_size, + gfx::Display::Rotation rotation, + scoped_refptr<base::TaskRunner> background_task_runner, + scoped_ptr<cc::CopyOutputResult> result) { + if (result->IsEmpty()) { + callback.Run(scoped_refptr<base::RefCountedBytes>()); + return; + } + + // TODO(sergeyu): Potentially images can be scaled on GPU before reading it + // from GPU. Image scaling is implemented in content::GlHelper, but it's can't + // be used here because it's not in content/public. Move the scaling code + // somewhere so that it can be reused here. + base::PostTaskAndReplyWithResult(background_task_runner, + FROM_HERE, + base::Bind(ScaleRotateAndEncodeBitmap, + *result->TakeBitmap(), + target_size, + rotation), + callback); +} + gfx::Rect GetTargetBoundsFromWindow(gfx::NativeWindow window, gfx::Rect snapshot_bounds) { gfx::RectF read_pixels_bounds = snapshot_bounds; @@ -157,19 +202,9 @@ bool GrabWindowSnapshot(gfx::NativeWindow window, void MakeAsyncCopyRequest( gfx::NativeWindow window, const gfx::Rect& source_rect, - const gfx::Size& target_size, - scoped_refptr<base::TaskRunner> background_task_runner, - const GrabWindowSnapshotAsyncCallback& callback) { - gfx::Display::Rotation rotation = gfx::Screen::GetScreenFor(window) - ->GetDisplayNearestWindow(window) - .rotation(); + const cc::CopyOutputRequest::CopyOutputRequestCallback& callback) { scoped_ptr<cc::CopyOutputRequest> request = - cc::CopyOutputRequest::CreateBitmapRequest( - base::Bind(&ScaleAndRotateCopyOutputResult, - callback, - target_size, - rotation, - background_task_runner)); + cc::CopyOutputRequest::CreateBitmapRequest(callback); request->set_area(ui::ConvertRectToPixel(window->layer(), source_rect)); window->layer()->RequestCopyOfOutput(request.Pass()); } @@ -201,19 +236,29 @@ void GrabWindowSnapshotAndScaleAsync( MakeAsyncCopyRequest(window, source_rect, - rotated_target_size, - background_task_runner, - callback); + base::Bind(&ScaleAndRotateCopyOutputResult, + callback, + rotated_target_size, + rotation, + background_task_runner)); } void GrabWindowSnapshotAsync( gfx::NativeWindow window, const gfx::Rect& source_rect, scoped_refptr<base::TaskRunner> background_task_runner, - const GrabWindowSnapshotAsyncCallback& callback) { + const GrabWindowSnapshotAsyncPNGCallback& callback) { gfx::Size target_size = GetTargetBoundsFromWindow(window, source_rect).size(); - MakeAsyncCopyRequest( - window, source_rect, target_size, background_task_runner, callback); + gfx::Display::Rotation rotation = gfx::Screen::GetScreenFor(window) + ->GetDisplayNearestWindow(window) + .rotation(); + MakeAsyncCopyRequest(window, + source_rect, + base::Bind(&ScaleRotateAndEncodeCopyOutputResult, + callback, + target_size, + rotation, + background_task_runner)); } } // namespace ui diff --git a/ui/snapshot/snapshot_aura_unittest.cc b/ui/snapshot/snapshot_aura_unittest.cc index 6e5705a..97a86c4 100644 --- a/ui/snapshot/snapshot_aura_unittest.cc +++ b/ui/snapshot/snapshot_aura_unittest.cc @@ -139,9 +139,10 @@ class SnapshotAuraTest : public testing::TestWithParam<bool> { public: SnapshotHolder() : completed_(false) {} - void SnapshotCallback(const gfx::Image& image) { + void SnapshotCallback(scoped_refptr<base::RefCountedBytes> png_data) { DCHECK(!completed_); - image_ = image; + image_ = gfx::Image::CreateFrom1xPNGBytes(&(png_data->data()[0]), + png_data->size()); completed_ = true; } bool completed() const { diff --git a/ui/snapshot/snapshot_gtk.cc b/ui/snapshot/snapshot_gtk.cc index c904500..82598d9 100644 --- a/ui/snapshot/snapshot_gtk.cc +++ b/ui/snapshot/snapshot_gtk.cc @@ -96,7 +96,7 @@ void GrabWindowSnapshotAsync( gfx::NativeWindow window, const gfx::Rect& source_rect, scoped_refptr<base::TaskRunner> background_task_runner, - const GrabWindowSnapshotAsyncCallback& callback) { + const GrabWindowSnapshotAsyncPNGCallback& callback) { NOTIMPLEMENTED(); } diff --git a/ui/snapshot/snapshot_ios.mm b/ui/snapshot/snapshot_ios.mm index 425192f..6637d28 100644 --- a/ui/snapshot/snapshot_ios.mm +++ b/ui/snapshot/snapshot_ios.mm @@ -36,7 +36,7 @@ void GrabWindowSnapshotAsync( gfx::NativeWindow window, const gfx::Rect& source_rect, scoped_refptr<base::TaskRunner> background_task_runner, - const GrabWindowSnapshotAsyncCallback& callback) { + const GrabWindowSnapshotAsyncPNGCallback& callback) { NOTIMPLEMENTED(); } diff --git a/ui/snapshot/snapshot_mac.mm b/ui/snapshot/snapshot_mac.mm index 2ebdf54..e39db56 100644 --- a/ui/snapshot/snapshot_mac.mm +++ b/ui/snapshot/snapshot_mac.mm @@ -86,7 +86,7 @@ void GrabWindowSnapshotAsync( gfx::NativeWindow window, const gfx::Rect& source_rect, scoped_refptr<base::TaskRunner> background_task_runner, - const GrabWindowSnapshotAsyncCallback& callback) { + const GrabWindowSnapshotAsyncPNGCallback& callback) { NOTIMPLEMENTED(); } diff --git a/ui/snapshot/snapshot_win.cc b/ui/snapshot/snapshot_win.cc index da9f1cc..23cc497e 100644 --- a/ui/snapshot/snapshot_win.cc +++ b/ui/snapshot/snapshot_win.cc @@ -124,7 +124,7 @@ void GrapWindowSnapshotAsync( const gfx::Rect& snapshot_bounds, const gfx::Size& target_size, scoped_refptr<base::TaskRunner> background_task_runner, - GrapWindowSnapshotAsyncCallback callback) { + GrabWindowSnapshotAsyncCallback callback) { NOTIMPLEMENTED(); } @@ -132,7 +132,7 @@ void GrabWindowSnapshotAsync( gfx::NativeWindow window, const gfx::Rect& source_rect, scoped_refptr<base::TaskRunner> background_task_runner, - const GrabWindowSnapshotAsyncCallback& callback) { + const GrabWindowSnapshotAsyncPNGCallback& callback) { NOTIMPLEMENTED(); } |