Index: ui/snapshot/snapshot_aura.cc |
diff --git a/ui/snapshot/snapshot_aura.cc b/ui/snapshot/snapshot_aura.cc |
index 8f7baa008bdbc1906f00879ae8543bf2f8b542e7..8e7ba3101db76b2a2090cad0d6601a8009da8017 100644 |
--- a/ui/snapshot/snapshot_aura.cc |
+++ b/ui/snapshot/snapshot_aura.cc |
@@ -4,8 +4,14 @@ |
#include "ui/snapshot/snapshot.h" |
+#include "base/bind.h" |
+#include "base/callback.h" |
#include "base/logging.h" |
#include "base/safe_numerics.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/root_window.h" |
@@ -15,6 +21,8 @@ |
#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" |
@@ -24,6 +32,47 @@ |
namespace ui { |
+namespace { |
+ |
+void OnFrameScalingFinished( |
+ const GrapWindowSnapshotAsyncCallback& callback, |
+ const SkBitmap& scaled_bitmap) { |
+ callback.Run(gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(scaled_bitmap))); |
+} |
+ |
+void ScaleCopyOutputResult( |
+ const GrapWindowSnapshotAsyncCallback& 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; |
+ } |
+ |
+ // There are two overrides for skia::ImageOperations::Resize(), so we need get |
+ // pointer to the right override explicitly (otherwise the base::Bind() call |
+ // below won't compile). |
+ SkBitmap (*resize_function)(const SkBitmap&, |
+ skia::ImageOperations::ResizeMethod, int, int, |
+ SkBitmap::Allocator* allocator) = |
+ &skia::ImageOperations::Resize; |
+ |
+ // 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(resize_function, *result->TakeBitmap(), |
+ skia::ImageOperations::RESIZE_GOOD, |
+ target_size.width(), target_size.height(), |
+ static_cast<SkBitmap::Allocator*>(NULL)), |
+ base::Bind(&OnFrameScalingFinished, callback)); |
+} |
+ |
+} // namespace |
+ |
bool GrabViewSnapshot(gfx::NativeView view, |
std::vector<unsigned char>* png_representation, |
const gfx::Rect& snapshot_bounds) { |
@@ -87,4 +136,18 @@ bool GrabWindowSnapshot(gfx::NativeWindow window, |
png_representation); |
} |
+SNAPSHOT_EXPORT void GrapWindowSnapshotAsync( |
+ gfx::NativeWindow window, |
+ const gfx::Rect& source_rect, |
+ const gfx::Size& target_size, |
+ scoped_refptr<base::TaskRunner> background_task_runner, |
+ const GrapWindowSnapshotAsyncCallback& callback) { |
+ scoped_ptr<cc::CopyOutputRequest> request = |
+ cc::CopyOutputRequest::CreateBitmapRequest( |
+ base::Bind(&ScaleCopyOutputResult, callback, target_size, |
+ background_task_runner)); |
+ request->set_area(ui::ConvertRectToPixel(window->layer(), source_rect)); |
+ window->layer()->RequestCopyOfOutput(request.Pass()); |
+} |
+ |
} // namespace ui |