summaryrefslogtreecommitdiffstats
path: root/ui/snapshot
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-15 19:36:36 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-15 19:36:36 +0000
commit2e6f39e1739c4e408a6f635e31678376187c232e (patch)
tree96869e634bb6d0c521579bb82927a6d45de48405 /ui/snapshot
parentc276c7a47a7777522eac0d2675d8cba3d32e56dd (diff)
downloadchromium_src-2e6f39e1739c4e408a6f635e31678376187c232e.zip
chromium_src-2e6f39e1739c4e408a6f635e31678376187c232e.tar.gz
chromium_src-2e6f39e1739c4e408a6f635e31678376187c232e.tar.bz2
Make ui::Snapshot asynchronous on Android, remove CompositeAndReadback.
The android pixel tests use the ui::Snapshot code to get a pixel copy of the content_shell's output. Make this behaviour match the aura implementation of ui::Snapshot by returning false in the synchronous verion, causing callsites to fall back to the async one. This implements the async snapshots by moving the aura implementation out into snapshot_async.cc and reusing that code (with one #if for RGBA vs BGRA ordering). After this, the pixel tests get a bitmap from cc instead of creating their own bitmap. The result is that the bitmap has a slightly different size (384x528) which is the size of the root layer. The pixel tests were previously trying to crop to 400x300, which is outside the bounds of this bitmap, so change them to crop to 300x300 instead, and increment their versions to pick up the new pngs. BUG=252046, 371592 Review URL: https://codereview.chromium.org/281003002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270778 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/snapshot')
-rw-r--r--ui/snapshot/snapshot.gyp17
-rw-r--r--ui/snapshot/snapshot_android.cc58
-rw-r--r--ui/snapshot/snapshot_async.cc103
-rw-r--r--ui/snapshot/snapshot_async.h42
-rw-r--r--ui/snapshot/snapshot_aura.cc100
5 files changed, 200 insertions, 120 deletions
diff --git a/ui/snapshot/snapshot.gyp b/ui/snapshot/snapshot.gyp
index a6a997e..3aa1fca 100644
--- a/ui/snapshot/snapshot.gyp
+++ b/ui/snapshot/snapshot.gyp
@@ -11,8 +11,8 @@
'target_name': 'snapshot',
'type': '<(component)',
'dependencies': [
- '../../skia/skia.gyp:skia',
'../../base/base.gyp:base',
+ '../../skia/skia.gyp:skia',
'../base/ui_base.gyp:ui_base',
'../gfx/gfx.gyp:gfx',
'../gfx/gfx.gyp:gfx_geometry',
@@ -23,6 +23,8 @@
'sources': [
'snapshot.h',
'snapshot_android.cc',
+ 'snapshot_async.cc',
+ 'snapshot_async.h',
'snapshot_aura.cc',
'snapshot_export.h',
'snapshot_ios.mm',
@@ -34,9 +36,20 @@
'..',
],
'conditions': [
- ['use_aura==1', {
+ ['use_aura==1 or OS=="android"', {
'dependencies': [
'../../cc/cc.gyp:cc',
+ '../../gpu/gpu.gyp:command_buffer_common',
+ ],
+ }],
+ ['use_aura!=1 and OS!="android"', {
+ 'sources!': [
+ 'snapshot_async.cc',
+ 'snapshot_async.h',
+ ],
+ }],
+ ['use_aura==1', {
+ 'dependencies': [
'../aura/aura.gyp:aura',
'../compositor/compositor.gyp:compositor',
],
diff --git a/ui/snapshot/snapshot_android.cc b/ui/snapshot/snapshot_android.cc
index 837c13c..49e276c 100644
--- a/ui/snapshot/snapshot_android.cc
+++ b/ui/snapshot/snapshot_android.cc
@@ -4,13 +4,13 @@
#include "ui/snapshot/snapshot.h"
-#include "base/callback.h"
+#include "base/bind.h"
+#include "cc/output/copy_output_request.h"
+#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/android/view_android.h"
#include "ui/base/android/window_android.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/image/image.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/screen.h"
+#include "ui/base/android/window_android_compositor.h"
+#include "ui/snapshot/snapshot_async.h"
namespace ui {
@@ -24,39 +24,53 @@ bool GrabViewSnapshot(gfx::NativeView view,
bool GrabWindowSnapshot(gfx::NativeWindow window,
std::vector<unsigned char>* png_representation,
const gfx::Rect& snapshot_bounds) {
- gfx::Display display =
- gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
- gfx::Rect scaled_bounds =
- gfx::ScaleToEnclosingRect(snapshot_bounds,
- display.device_scale_factor());
- return window->GrabSnapshot(
- scaled_bounds.x(), scaled_bounds.y(), scaled_bounds.width(),
- scaled_bounds.height(), png_representation);
+ // Not supported in Android. Callers should fall back to the async version.
+ return false;
+}
+
+static void MakeAsyncCopyRequest(
+ gfx::NativeWindow window,
+ const gfx::Rect& source_rect,
+ const cc::CopyOutputRequest::CopyOutputRequestCallback& callback) {
+ scoped_ptr<cc::CopyOutputRequest> request =
+ cc::CopyOutputRequest::CreateBitmapRequest(callback);
+ request->set_area(source_rect);
+ window->GetCompositor()->RequestCopyOfOutputOnRootLayer(request.Pass());
}
void GrabWindowSnapshotAndScaleAsync(
gfx::NativeWindow window,
- const gfx::Rect& snapshot_bounds,
+ const gfx::Rect& source_rect,
const gfx::Size& target_size,
scoped_refptr<base::TaskRunner> background_task_runner,
- GrabWindowSnapshotAsyncCallback callback) {
- callback.Run(gfx::Image());
+ const GrabWindowSnapshotAsyncCallback& callback) {
+ MakeAsyncCopyRequest(window,
+ source_rect,
+ base::Bind(&SnapshotAsync::ScaleCopyOutputResult,
+ callback,
+ target_size,
+ background_task_runner));
}
-void GrabViewSnapshotAsync(
- gfx::NativeView view,
+void GrabWindowSnapshotAsync(
+ gfx::NativeWindow window,
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback) {
- callback.Run(scoped_refptr<base::RefCountedBytes>());
+ MakeAsyncCopyRequest(window,
+ source_rect,
+ base::Bind(&SnapshotAsync::EncodeCopyOutputResult,
+ callback,
+ background_task_runner));
}
-void GrabWindowSnapshotAsync(
- gfx::NativeWindow window,
+void GrabViewSnapshotAsync(
+ gfx::NativeView view,
const gfx::Rect& source_rect,
scoped_refptr<base::TaskRunner> background_task_runner,
const GrabWindowSnapshotAsyncPNGCallback& callback) {
- callback.Run(scoped_refptr<base::RefCountedBytes>());
+ GrabWindowSnapshotAsync(
+ view->GetWindowAndroid(), source_rect, background_task_runner, callback);
}
} // namespace ui
diff --git a/ui/snapshot/snapshot_async.cc b/ui/snapshot/snapshot_async.cc
new file mode 100644
index 0000000..5f18225
--- /dev/null
+++ b/ui/snapshot/snapshot_async.cc
@@ -0,0 +1,103 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/snapshot/snapshot_async.h"
+
+#include "base/location.h"
+#include "base/memory/ref_counted.h"
+#include "base/numerics/safe_conversions.h"
+#include "base/task_runner_util.h"
+#include "skia/ext/image_operations.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkPixelRef.h"
+#include "ui/gfx/codec/png_codec.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/skbitmap_operations.h"
+
+namespace ui {
+
+namespace {
+
+void OnFrameScalingFinished(const GrabWindowSnapshotAsyncCallback& callback,
+ const SkBitmap& scaled_bitmap) {
+ callback.Run(gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(scaled_bitmap)));
+}
+
+SkBitmap ScaleBitmap(const SkBitmap& input_bitmap,
+ const gfx::Size& target_size) {
+ return skia::ImageOperations::Resize(input_bitmap,
+ skia::ImageOperations::RESIZE_GOOD,
+ target_size.width(),
+ target_size.height(),
+ static_cast<SkBitmap::Allocator*>(NULL));
+}
+
+scoped_refptr<base::RefCountedBytes> EncodeBitmap(const SkBitmap& bitmap) {
+ scoped_refptr<base::RefCountedBytes> png_data(new base::RefCountedBytes);
+ SkAutoLockPixels lock(bitmap);
+ unsigned char* pixels = reinterpret_cast<unsigned char*>(bitmap.getPixels());
+#if SK_A32_SHIFT == 24 && SK_R32_SHIFT == 16 && SK_G32_SHIFT == 8
+ gfx::PNGCodec::ColorFormat kColorFormat = gfx::PNGCodec::FORMAT_BGRA;
+#elif SK_A32_SHIFT == 24 && SK_B32_SHIFT == 16 && SK_G32_SHIFT == 8
+ gfx::PNGCodec::ColorFormat kColorFormat = gfx::PNGCodec::FORMAT_RGBA;
+#else
+#error Unknown color format
+#endif
+ if (!gfx::PNGCodec::Encode(pixels,
+ kColorFormat,
+ gfx::Size(bitmap.width(), bitmap.height()),
+ base::checked_cast<int>(bitmap.rowBytes()),
+ true,
+ std::vector<gfx::PNGCodec::Comment>(),
+ &png_data->data())) {
+ return scoped_refptr<base::RefCountedBytes>();
+ }
+ return png_data;
+}
+
+} // namespace
+
+void SnapshotAsync::ScaleCopyOutputResult(
+ const GrabWindowSnapshotAsyncCallback& callback,
+ const gfx::Size& target_size,
+ scoped_refptr<base::TaskRunner> background_task_runner,
+ scoped_ptr<cc::CopyOutputResult> result) {
+ if (result->IsEmpty()) {
+ callback.Run(gfx::Image());
+ 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(ScaleBitmap, *result->TakeBitmap(), target_size),
+ base::Bind(&OnFrameScalingFinished, callback));
+}
+
+void SnapshotAsync::EncodeCopyOutputResult(
+ const GrabWindowSnapshotAsyncPNGCallback& callback,
+ 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(EncodeBitmap, *result->TakeBitmap()),
+ callback);
+}
+
+} // namespace ui
diff --git a/ui/snapshot/snapshot_async.h b/ui/snapshot/snapshot_async.h
new file mode 100644
index 0000000..41da62b
--- /dev/null
+++ b/ui/snapshot/snapshot_async.h
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_SNAPSHOT_SNAPSHOT_ASYNC_H_
+#define UI_SNAPSHOT_SNAPSHOT_ASYNC_H_
+
+#include "cc/output/copy_output_result.h"
+#include "ui/snapshot/snapshot.h"
+
+namespace base {
+class TaskRunner;
+}
+
+namespace gfx {
+class Size;
+}
+
+namespace ui {
+
+// Helper methods for async snapshots to convert a cc::CopyOutputResult into a
+// ui::GrabWindowSnapshot callback.
+class SnapshotAsync {
+ public:
+ static void ScaleCopyOutputResult(
+ const GrabWindowSnapshotAsyncCallback& callback,
+ const gfx::Size& target_size,
+ scoped_refptr<base::TaskRunner> background_task_runner,
+ scoped_ptr<cc::CopyOutputResult> result);
+
+ static void EncodeCopyOutputResult(
+ const GrabWindowSnapshotAsyncPNGCallback& callback,
+ scoped_refptr<base::TaskRunner> background_task_runner,
+ scoped_ptr<cc::CopyOutputResult> result);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(SnapshotAsync);
+};
+
+} // namespace ui
+
+#endif // UI_SNAPSHOT_SNAPSHOT_ASYNC_H_
diff --git a/ui/snapshot/snapshot_aura.cc b/ui/snapshot/snapshot_aura.cc
index a360b87..fc7e6e7 100644
--- a/ui/snapshot/snapshot_aura.cc
+++ b/ui/snapshot/snapshot_aura.cc
@@ -6,109 +6,17 @@
#include "base/bind.h"
#include "base/callback.h"
-#include "base/logging.h"
-#include "base/numerics/safe_conversions.h"
#include "base/task_runner_util.h"
#include "cc/output/copy_output_request.h"
-#include "cc/output/copy_output_result.h"
-#include "skia/ext/image_operations.h"
#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkPixelRef.h"
#include "ui/aura/window.h"
-#include "ui/aura/window_event_dispatcher.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/dip_util.h"
#include "ui/compositor/layer.h"
-#include "ui/gfx/codec/png_codec.h"
-#include "ui/gfx/display.h"
-#include "ui/gfx/image/image.h"
-#include "ui/gfx/image/image_skia.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/rect_conversions.h"
-#include "ui/gfx/rect_f.h"
-#include "ui/gfx/screen.h"
-#include "ui/gfx/skbitmap_operations.h"
-#include "ui/gfx/transform.h"
+#include "ui/snapshot/snapshot_async.h"
namespace ui {
-namespace {
-
-void OnFrameScalingFinished(
- const GrabWindowSnapshotAsyncCallback& callback,
- const SkBitmap& scaled_bitmap) {
- callback.Run(gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(scaled_bitmap)));
-}
-
-SkBitmap ScaleBitmap(const SkBitmap& input_bitmap,
- const gfx::Size& target_size) {
- return skia::ImageOperations::Resize(
- input_bitmap,
- skia::ImageOperations::RESIZE_GOOD,
- target_size.width(),
- target_size.height(),
- static_cast<SkBitmap::Allocator*>(NULL));
-}
-
-scoped_refptr<base::RefCountedBytes> EncodeBitmap(const SkBitmap& bitmap) {
- 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_cast<int>(bitmap.rowBytes()),
- true,
- std::vector<gfx::PNGCodec::Comment>(),
- &png_data->data())) {
- return scoped_refptr<base::RefCountedBytes>();
- }
- return png_data;
-}
-
-void ScaleCopyOutputResult(
- const GrabWindowSnapshotAsyncCallback& callback,
- const gfx::Size& target_size,
- scoped_refptr<base::TaskRunner> background_task_runner,
- scoped_ptr<cc::CopyOutputResult> result) {
- if (result->IsEmpty()) {
- callback.Run(gfx::Image());
- 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(ScaleBitmap, *result->TakeBitmap(), target_size),
- base::Bind(&OnFrameScalingFinished, callback));
-}
-
-void EncodeCopyOutputResult(
- const GrabWindowSnapshotAsyncPNGCallback& callback,
- 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(EncodeBitmap,
- *result->TakeBitmap()),
- callback);
-}
-
-} // namespace
-
bool GrabViewSnapshot(gfx::NativeView view,
std::vector<unsigned char>* png_representation,
const gfx::Rect& snapshot_bounds) {
@@ -122,7 +30,7 @@ bool GrabWindowSnapshot(gfx::NativeWindow window,
return false;
}
-void MakeAsyncCopyRequest(
+static void MakeAsyncCopyRequest(
gfx::NativeWindow window,
const gfx::Rect& source_rect,
const cc::CopyOutputRequest::CopyOutputRequestCallback& callback) {
@@ -140,7 +48,7 @@ void GrabWindowSnapshotAndScaleAsync(
const GrabWindowSnapshotAsyncCallback& callback) {
MakeAsyncCopyRequest(window,
source_rect,
- base::Bind(&ScaleCopyOutputResult,
+ base::Bind(&SnapshotAsync::ScaleCopyOutputResult,
callback,
target_size,
background_task_runner));
@@ -153,7 +61,7 @@ void GrabWindowSnapshotAsync(
const GrabWindowSnapshotAsyncPNGCallback& callback) {
MakeAsyncCopyRequest(window,
source_rect,
- base::Bind(&EncodeCopyOutputResult,
+ base::Bind(&SnapshotAsync::EncodeCopyOutputResult,
callback,
background_task_runner));
}