summaryrefslogtreecommitdiffstats
path: root/ui/snapshot
diff options
context:
space:
mode:
authorenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-15 09:54:59 +0000
committerenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-15 09:54:59 +0000
commit24e4cac9b53c6bebf0bafc40213ff67fa9caedb2 (patch)
tree48f0dc561da445ccdbbd7e8b68a615796de26310 /ui/snapshot
parent3518cf1c81f097113a6d4dfa7abffcdc860ee3a4 (diff)
downloadchromium_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.h6
-rw-r--r--ui/snapshot/snapshot_android.cc2
-rw-r--r--ui/snapshot/snapshot_aura.cc81
-rw-r--r--ui/snapshot/snapshot_aura_unittest.cc5
-rw-r--r--ui/snapshot/snapshot_gtk.cc2
-rw-r--r--ui/snapshot/snapshot_ios.mm2
-rw-r--r--ui/snapshot/snapshot_mac.mm2
-rw-r--r--ui/snapshot/snapshot_win.cc4
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();
}