diff options
author | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-08 23:54:51 +0000 |
---|---|---|
committer | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-01-08 23:54:51 +0000 |
commit | c051d5a56b838d1a1ac552dffa93f52e24ab1fd3 (patch) | |
tree | ce035b27081a80678409816f20ccaf058f1edfe5 | |
parent | 914d8bfcdd14160de78bd6db47bb453a160c9a52 (diff) | |
download | chromium_src-c051d5a56b838d1a1ac552dffa93f52e24ab1fd3.zip chromium_src-c051d5a56b838d1a1ac552dffa93f52e24ab1fd3.tar.gz chromium_src-c051d5a56b838d1a1ac552dffa93f52e24ab1fd3.tar.bz2 |
Add GrabWindowSnapshotAsync aura tests
This adds a version of GrabWindowSnapshotAsync that behaves identically
to GrabWindowSnapshot except with a callback. The snapshot aura unit
tests are updated to use this new async function instead of the sync
one.
In order to make the snapshot tests work properly, they also now have to
use a real gl context so that real drawing and readback can occur
through the compositor.
BUG=331410, 332167
Review URL: https://codereview.chromium.org/119753007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@243700 0039d316-1c4b-4281-b951-d872f2087c98
28 files changed, 268 insertions, 88 deletions
diff --git a/chrome/browser/media/desktop_media_list_ash.cc b/chrome/browser/media/desktop_media_list_ash.cc index d013c95..98b05c8 100644 --- a/chrome/browser/media/desktop_media_list_ash.cc +++ b/chrome/browser/media/desktop_media_list_ash.cc @@ -181,8 +181,9 @@ void DesktopMediaListAsh::CaptureThumbnail(content::DesktopMediaID id, gfx::Rect(thumbnail_size_), window_rect.size()); ++pending_window_capture_requests_; - ui::GrabWindowSnapshotAsync( - window, window_rect, + ui::GrabWindowSnapshotAndScaleAsync( + window, + window_rect, scaled_rect.size(), BrowserThread::GetBlockingPool(), base::Bind(&DesktopMediaListAsh::OnThumbnailCaptured, diff --git a/chrome/browser/ui/views/accessibility/accessibility_event_router_views_unittest.cc b/chrome/browser/ui/views/accessibility/accessibility_event_router_views_unittest.cc index 7afb9b2..b41cc94 100644 --- a/chrome/browser/ui/views/accessibility/accessibility_event_router_views_unittest.cc +++ b/chrome/browser/ui/views/accessibility/accessibility_event_router_views_unittest.cc @@ -121,7 +121,8 @@ class AccessibilityEventRouterViewsTest views::ViewsDelegate::views_delegate = new AccessibilityViewsDelegate(); #if defined(USE_AURA) aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_)); - aura_test_helper_->SetUp(); + bool allow_test_contexts = true; + aura_test_helper_->SetUp(allow_test_contexts); #endif // USE_AURA EnableAccessibilityAndListenToFocusNotifications(); } diff --git a/chrome/test/base/browser_with_test_window_test.cc b/chrome/test/base/browser_with_test_window_test.cc index 296e263..0ec7d96 100644 --- a/chrome/test/base/browser_with_test_window_test.cc +++ b/chrome/test/base/browser_with_test_window_test.cc @@ -59,7 +59,8 @@ void BrowserWithTestWindowTest::SetUp() { #elif defined(USE_AURA) aura_test_helper_.reset(new aura::test::AuraTestHelper( base::MessageLoopForUI::current())); - aura_test_helper_->SetUp(); + bool allow_test_contexts = true; + aura_test_helper_->SetUp(allow_test_contexts); #endif // USE_AURA #if defined(TOOLKIT_VIEWS) views_delegate_.reset(CreateViewsDelegate()); diff --git a/chrome/test/base/view_event_test_base.cc b/chrome/test/base/view_event_test_base.cc index be058ef2..8d4f9ca 100644 --- a/chrome/test/base/view_event_test_base.cc +++ b/chrome/test/base/view_event_test_base.cc @@ -141,7 +141,8 @@ void ViewEventTestBase::SetUp() { // the test screen. aura_test_helper_.reset( new aura::test::AuraTestHelper(base::MessageLoopForUI::current())); - aura_test_helper_->SetUp(); + bool allow_test_contexts = true; + aura_test_helper_->SetUp(allow_test_contexts); context = aura_test_helper_->root_window(); #endif // !USE_ASH && USE_AURA diff --git a/content/browser/renderer_host/media/desktop_capture_device_aura_unittest.cc b/content/browser/renderer_host/media/desktop_capture_device_aura_unittest.cc index ad391e7..2dd75f7 100644 --- a/content/browser/renderer_host/media/desktop_capture_device_aura_unittest.cc +++ b/content/browser/renderer_host/media/desktop_capture_device_aura_unittest.cc @@ -57,7 +57,8 @@ class DesktopCaptureDeviceAuraTest : public testing::Test { protected: virtual void SetUp() OVERRIDE { helper_.reset(new aura::test::AuraTestHelper(&message_loop_)); - helper_->SetUp(); + bool allow_test_contexts = true; + helper_->SetUp(allow_test_contexts); // We need a window to cover desktop area so that DesktopCaptureDeviceAura // can use gfx::NativeWindow::GetWindowAtScreenPoint() to locate the diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index 5f9aaf5..4a29c22 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc @@ -157,7 +157,8 @@ class RenderWidgetHostViewAuraTest : public testing::Test { ImageTransportFactory::InitializeForUnitTests( scoped_ptr<ui::ContextFactory>(new ui::TestContextFactory)); aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_)); - aura_test_helper_->SetUp(); + bool allow_test_contexts = true; + aura_test_helper_->SetUp(allow_test_contexts); browser_context_.reset(new TestBrowserContext); process_host_ = new MockRenderProcessHost(browser_context_.get()); diff --git a/content/public/test/test_renderer_host.cc b/content/public/test/test_renderer_host.cc index 1f9290c..c837a76 100644 --- a/content/public/test/test_renderer_host.cc +++ b/content/public/test/test_renderer_host.cc @@ -167,7 +167,8 @@ void RenderViewHostTestHarness::SetUp() { #if defined(USE_AURA) aura_test_helper_.reset( new aura::test::AuraTestHelper(base::MessageLoopForUI::current())); - aura_test_helper_->SetUp(); + bool allow_test_contexts = true; + aura_test_helper_->SetUp(allow_test_contexts); #endif DCHECK(!browser_context_); diff --git a/ui/aura/remote_root_window_host_win.cc b/ui/aura/remote_root_window_host_win.cc index a91fed4..5628e13 100644 --- a/ui/aura/remote_root_window_host_win.cc +++ b/ui/aura/remote_root_window_host_win.cc @@ -167,6 +167,7 @@ RemoteWindowTreeHostWin::RemoteWindowTreeHostWin(const gfx::Rect& bounds) } RemoteWindowTreeHostWin::~RemoteWindowTreeHostWin() { + DestroyCompositor(); g_instance = NULL; } diff --git a/ui/aura/root_window_host_ozone.cc b/ui/aura/root_window_host_ozone.cc index 9bb2a2b..5d17f83 100644 --- a/ui/aura/root_window_host_ozone.cc +++ b/ui/aura/root_window_host_ozone.cc @@ -33,6 +33,7 @@ WindowTreeHostOzone::WindowTreeHostOzone(const gfx::Rect& bounds) WindowTreeHostOzone::~WindowTreeHostOzone() { base::MessagePumpOzone::Current()->RemoveDispatcherForRootWindow(0); + DestroyCompositor(); } bool WindowTreeHostOzone::Dispatch(const base::NativeEvent& ne) { diff --git a/ui/aura/root_window_host_win.cc b/ui/aura/root_window_host_win.cc index e4ae7f6..90bed7a 100644 --- a/ui/aura/root_window_host_win.cc +++ b/ui/aura/root_window_host_win.cc @@ -52,6 +52,7 @@ WindowTreeHostWin::WindowTreeHostWin(const gfx::Rect& bounds) } WindowTreeHostWin::~WindowTreeHostWin() { + DestroyCompositor(); DestroyWindow(hwnd()); } diff --git a/ui/aura/root_window_host_x11.cc b/ui/aura/root_window_host_x11.cc index ce248e8..aad11ff 100644 --- a/ui/aura/root_window_host_x11.cc +++ b/ui/aura/root_window_host_x11.cc @@ -389,6 +389,7 @@ WindowTreeHostX11::~WindowTreeHostX11() { UnConfineCursor(); + DestroyCompositor(); XDestroyWindow(xdisplay_, xwindow_); } diff --git a/ui/aura/test/aura_test_base.cc b/ui/aura/test/aura_test_base.cc index ed8f512..7dfe74d 100644 --- a/ui/aura/test/aura_test_base.cc +++ b/ui/aura/test/aura_test_base.cc @@ -69,7 +69,8 @@ void AuraTestBase::SetUp() { ui::GestureConfiguration::set_fling_velocity_cap(15000.0f); helper_.reset(new AuraTestHelper(&message_loop_)); - helper_->SetUp(); + bool allow_test_contexts = true; + helper_->SetUp(allow_test_contexts); } void AuraTestBase::TearDown() { diff --git a/ui/aura/test/aura_test_helper.cc b/ui/aura/test/aura_test_helper.cc index f04b46b..6cef5d9 100644 --- a/ui/aura/test/aura_test_helper.cc +++ b/ui/aura/test/aura_test_helper.cc @@ -62,11 +62,10 @@ AuraTestHelper::~AuraTestHelper() { << "AuraTestHelper::TearDown() never called."; } -void AuraTestHelper::SetUp() { +void AuraTestHelper::SetUp(bool allow_test_contexts) { setup_called_ = true; // The ContextFactory must exist before any Compositors are created. - bool allow_test_contexts = true; ui::InitializeContextFactoryForTests(allow_test_contexts); Env::CreateInstance(); diff --git a/ui/aura/test/aura_test_helper.h b/ui/aura/test/aura_test_helper.h index adcff269..1f201a6 100644 --- a/ui/aura/test/aura_test_helper.h +++ b/ui/aura/test/aura_test_helper.h @@ -41,7 +41,7 @@ class AuraTestHelper { ~AuraTestHelper(); // Creates and initializes (shows and sizes) the RootWindow for use in tests. - void SetUp(); + void SetUp(bool allow_test_contexts); // Clean up objects that are created for tests. This also deletes the Env // object. diff --git a/ui/aura/window_tree_host.cc b/ui/aura/window_tree_host.cc index f4fcbb8..c7bc4ca 100644 --- a/ui/aura/window_tree_host.cc +++ b/ui/aura/window_tree_host.cc @@ -73,12 +73,7 @@ class SimpleRootWindowTransformer : public RootWindowTransformer { // WindowTreeHost, public: WindowTreeHost::~WindowTreeHost() { - // TODO(beng): this represents an ordering change. In the old code, the - // compositor was reset before the window hierarchy was destroyed. - // verify that this has no adverse effects. - // Make sure to destroy the compositor before terminating so that state is - // cleared and we don't hit asserts. - compositor_.reset(); + DCHECK(!compositor_) << "compositor must be destroyed before root window"; } void WindowTreeHost::InitHost() { @@ -172,6 +167,8 @@ WindowTreeHost::WindowTreeHost() : delegate_(NULL) { } +void WindowTreeHost::DestroyCompositor() { compositor_.reset(); } + void WindowTreeHost::CreateCompositor( gfx::AcceleratedWidget accelerated_widget) { compositor_.reset(new ui::Compositor(GetAcceleratedWidget())); diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h index 8006484..c6fd308 100644 --- a/ui/aura/window_tree_host.h +++ b/ui/aura/window_tree_host.h @@ -152,6 +152,7 @@ class AURA_EXPORT WindowTreeHost { friend class TestScreen; // TODO(beng): see if we can remove/consolidate. WindowTreeHost(); + void DestroyCompositor(); void CreateCompositor(gfx::AcceleratedWidget accelerated_widget); diff --git a/ui/keyboard/keyboard_controller_unittest.cc b/ui/keyboard/keyboard_controller_unittest.cc index 80296f0..32856a7 100644 --- a/ui/keyboard/keyboard_controller_unittest.cc +++ b/ui/keyboard/keyboard_controller_unittest.cc @@ -198,7 +198,8 @@ class KeyboardControllerTest : public testing::Test { virtual void SetUp() OVERRIDE { aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_)); - aura_test_helper_->SetUp(); + bool allow_test_contexts = true; + aura_test_helper_->SetUp(allow_test_contexts); ui::SetUpInputMethodFactoryForTesting(); focus_controller_.reset(new TestFocusController(root_window())); proxy_ = new TestKeyboardControllerProxy(); diff --git a/ui/snapshot/snapshot.h b/ui/snapshot/snapshot.h index d6fb6b8..7ccd8b4 100644 --- a/ui/snapshot/snapshot.h +++ b/ui/snapshot/snapshot.h @@ -28,7 +28,7 @@ namespace ui { // intended to be used for debugging purposes where no BrowserProcess instance // is available (ie. tests). This function is synchronous, so it should NOT be // used in a result of user action. Use asynchronous GrabWindowSnapshotAsync() -// instead. +// instead on supported platforms. SNAPSHOT_EXPORT bool GrabWindowSnapshot( gfx::NativeWindow window, std::vector<unsigned char>* png_representation, @@ -39,16 +39,21 @@ SNAPSHOT_EXPORT bool GrabViewSnapshot( std::vector<unsigned char>* png_representation, const gfx::Rect& snapshot_bounds); -// GrabWindowSnapshotAsync() copies snapshot of |source_rect| from window and -// scales it to |target_size| asynchronously. typedef base::Callback<void(const gfx::Image& snapshot)> GrabWindowSnapshotAsyncCallback; -SNAPSHOT_EXPORT void GrabWindowSnapshotAsync( +// GrabWindowSnapshotAndScaleAsync() copies snapshot of |source_rect| from +// window and scales it to |target_size| asynchronously. +SNAPSHOT_EXPORT void GrabWindowSnapshotAndScaleAsync( gfx::NativeWindow window, const gfx::Rect& source_rect, const gfx::Size& target_size, scoped_refptr<base::TaskRunner> background_task_runner, const GrabWindowSnapshotAsyncCallback& callback); +SNAPSHOT_EXPORT void GrabWindowSnapshotAsync( + gfx::NativeWindow window, + const gfx::Rect& source_rect, + scoped_refptr<base::TaskRunner> background_task_runner, + const GrabWindowSnapshotAsyncCallback& callback); } // namespace ui diff --git a/ui/snapshot/snapshot_android.cc b/ui/snapshot/snapshot_android.cc index 3ae0be7..83c5efe 100644 --- a/ui/snapshot/snapshot_android.cc +++ b/ui/snapshot/snapshot_android.cc @@ -33,7 +33,7 @@ bool GrabWindowSnapshot(gfx::NativeWindow window, scaled_bounds.height(), png_representation); } -SNAPSHOT_EXPORT void GrabWindowSnapshotAsync( +void GrabWindowSnapshotAndScaleAsync( gfx::NativeWindow window, const gfx::Rect& snapshot_bounds, const gfx::Size& target_size, @@ -42,4 +42,12 @@ SNAPSHOT_EXPORT void GrabWindowSnapshotAsync( NOTIMPLEMENTED(); } +void GrabWindowSnapshotAsync( + gfx::NativeWindow window, + const gfx::Rect& source_rect, + scoped_refptr<base::TaskRunner> background_task_runner, + const GrabWindowSnapshotAsyncCallback& callback) { + NOTIMPLEMENTED(); +} + } // namespace ui diff --git a/ui/snapshot/snapshot_aura.cc b/ui/snapshot/snapshot_aura.cc index 5fdd4dc..620d312 100644 --- a/ui/snapshot/snapshot_aura.cc +++ b/ui/snapshot/snapshot_aura.cc @@ -40,9 +40,43 @@ void OnFrameScalingFinished( callback.Run(gfx::Image(gfx::ImageSkia::CreateFrom1xBitmap(scaled_bitmap))); } -void ScaleCopyOutputResult( +void RotateBitmap(SkBitmap* bitmap, gfx::Display::Rotation rotation) { + switch (rotation) { + case gfx::Display::ROTATE_0: + break; + case gfx::Display::ROTATE_90: + *bitmap = SkBitmapOperations::Rotate(*bitmap, + SkBitmapOperations::ROTATION_270_CW); + break; + case gfx::Display::ROTATE_180: + *bitmap = SkBitmapOperations::Rotate(*bitmap, + SkBitmapOperations::ROTATION_180_CW); + break; + case gfx::Display::ROTATE_270: + *bitmap = SkBitmapOperations::Rotate(*bitmap, + SkBitmapOperations::ROTATION_90_CW); + break; + } +} + +SkBitmap ScaleAndRotateBitmap(const SkBitmap& input_bitmap, + gfx::Size target_size_pre_rotation, + gfx::Display::Rotation rotation) { + SkBitmap bitmap; + bitmap = + skia::ImageOperations::Resize(input_bitmap, + skia::ImageOperations::RESIZE_GOOD, + target_size_pre_rotation.width(), + target_size_pre_rotation.height(), + static_cast<SkBitmap::Allocator*>(NULL)); + RotateBitmap(&bitmap, rotation); + return bitmap; +} + +void ScaleAndRotateCopyOutputResult( const GrabWindowSnapshotAsyncCallback& 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()) { @@ -50,40 +84,20 @@ void ScaleCopyOutputResult( 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)), + background_task_runner, + FROM_HERE, + base::Bind( + ScaleAndRotateBitmap, *result->TakeBitmap(), target_size, rotation), base::Bind(&OnFrameScalingFinished, callback)); } -} // namespace - -bool GrabViewSnapshot(gfx::NativeView view, - std::vector<unsigned char>* png_representation, - const gfx::Rect& snapshot_bounds) { - return GrabWindowSnapshot(view, png_representation, snapshot_bounds); -} - -bool GrabWindowSnapshot(gfx::NativeWindow window, - std::vector<unsigned char>* png_representation, - const gfx::Rect& snapshot_bounds) { - ui::Compositor* compositor = window->layer()->GetCompositor(); - +gfx::Rect GetTargetBoundsFromWindow(gfx::NativeWindow window, + gfx::Rect snapshot_bounds) { gfx::RectF read_pixels_bounds = snapshot_bounds; // We must take into account the window's position on the desktop. @@ -98,33 +112,37 @@ bool GrabWindowSnapshot(gfx::NativeWindow window, // Sometimes (i.e. when using Aero on Windows) the compositor's size is // smaller than the window bounds. So trim appropriately. + ui::Compositor* compositor = window->layer()->GetCompositor(); read_pixels_bounds_in_pixel.Intersect(gfx::Rect(compositor->size())); DCHECK_LE(0, read_pixels_bounds.x()); DCHECK_LE(0, read_pixels_bounds.y()); + return read_pixels_bounds_in_pixel; +} + +} // namespace + +bool GrabViewSnapshot(gfx::NativeView view, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + return GrabWindowSnapshot(view, png_representation, snapshot_bounds); +} + +bool GrabWindowSnapshot(gfx::NativeWindow window, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + gfx::Rect read_pixels_bounds_in_pixel = + GetTargetBoundsFromWindow(window, snapshot_bounds); + + ui::Compositor* compositor = window->layer()->GetCompositor(); SkBitmap bitmap; if (!compositor->ReadPixels(&bitmap, read_pixels_bounds_in_pixel)) return false; gfx::Display display = gfx::Screen::GetScreenFor(window)->GetDisplayNearestWindow(window); - switch (display.rotation()) { - case gfx::Display::ROTATE_0: - break; - case gfx::Display::ROTATE_90: - bitmap = SkBitmapOperations::Rotate( - bitmap, SkBitmapOperations::ROTATION_270_CW); - break; - case gfx::Display::ROTATE_180: - bitmap = SkBitmapOperations::Rotate( - bitmap, SkBitmapOperations::ROTATION_180_CW); - break; - case gfx::Display::ROTATE_270: - bitmap = SkBitmapOperations::Rotate( - bitmap, SkBitmapOperations::ROTATION_90_CW); - break; - } + RotateBitmap(&bitmap, display.rotation()); unsigned char* pixels = reinterpret_cast<unsigned char*>( bitmap.pixelRef()->pixels()); @@ -136,18 +154,66 @@ bool GrabWindowSnapshot(gfx::NativeWindow window, png_representation); } -SNAPSHOT_EXPORT void GrabWindowSnapshotAsync( +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(); scoped_ptr<cc::CopyOutputRequest> request = cc::CopyOutputRequest::CreateBitmapRequest( - base::Bind(&ScaleCopyOutputResult, callback, target_size, + base::Bind(&ScaleAndRotateCopyOutputResult, + callback, + target_size, + rotation, background_task_runner)); request->set_area(ui::ConvertRectToPixel(window->layer(), source_rect)); window->layer()->RequestCopyOfOutput(request.Pass()); } +void GrabWindowSnapshotAndScaleAsync( + gfx::NativeWindow window, + const gfx::Rect& source_rect, + const gfx::Size& target_size, + scoped_refptr<base::TaskRunner> background_task_runner, + const GrabWindowSnapshotAsyncCallback& callback) { + // target_size is post-rotation, and so logically this is a rotate and then + // scale operation. However, it will usually be more efficient to scale first + // (given that this is mostly used for thumbnails) and then rotate. + gfx::Display::Rotation rotation = gfx::Screen::GetScreenFor(window) + ->GetDisplayNearestWindow(window) + .rotation(); + gfx::Size rotated_target_size; + switch (rotation) { + case gfx::Display::ROTATE_0: + case gfx::Display::ROTATE_180: + rotated_target_size = target_size; + break; + case gfx::Display::ROTATE_90: + case gfx::Display::ROTATE_270: + rotated_target_size = + gfx::Size(target_size.height(), target_size.width()); + break; + }; + + MakeAsyncCopyRequest(window, + source_rect, + rotated_target_size, + background_task_runner, + callback); +} + +void GrabWindowSnapshotAsync( + gfx::NativeWindow window, + const gfx::Rect& source_rect, + scoped_refptr<base::TaskRunner> background_task_runner, + const GrabWindowSnapshotAsyncCallback& callback) { + gfx::Size target_size = GetTargetBoundsFromWindow(window, source_rect).size(); + MakeAsyncCopyRequest( + window, source_rect, target_size, background_task_runner, callback); +} + } // namespace ui diff --git a/ui/snapshot/snapshot_aura_unittest.cc b/ui/snapshot/snapshot_aura_unittest.cc index 856be55..6e5705a 100644 --- a/ui/snapshot/snapshot_aura_unittest.cc +++ b/ui/snapshot/snapshot_aura_unittest.cc @@ -4,6 +4,8 @@ #include "ui/snapshot/snapshot.h" +#include "base/bind.h" +#include "base/test/test_simple_task_runner.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/root_window.h" #include "ui/aura/test/aura_test_helper.h" @@ -58,7 +60,7 @@ size_t GetFailedPixelsCount(const gfx::Image& image) { } // namespace -class SnapshotAuraTest : public testing::Test { +class SnapshotAuraTest : public testing::TestWithParam<bool> { public: SnapshotAuraTest() {} virtual ~SnapshotAuraTest() {} @@ -67,7 +69,9 @@ class SnapshotAuraTest : public testing::Test { testing::Test::SetUp(); helper_.reset( new aura::test::AuraTestHelper(base::MessageLoopForUI::current())); - helper_->SetUp(); + // Snapshot test tests real drawing and readback, so needs a real context. + bool allow_test_contexts = false; + helper_->SetUp(allow_test_contexts); } virtual void TearDown() OVERRIDE { @@ -95,15 +99,65 @@ class SnapshotAuraTest : public testing::Test { delegate_.get(), 0, window_bounds, root_window())); } + bool is_async_test() const { return GetParam(); } + gfx::Image GrabSnapshotForTestWindow() { - std::vector<unsigned char> png_representation; - gfx::Rect local_bounds(test_window_->bounds().size()); - ui::GrabWindowSnapshot(test_window(), &png_representation, local_bounds); - return gfx::Image::CreateFrom1xPNGBytes( - base::RefCountedBytes::TakeVector(&png_representation)); + gfx::Rect source_rect(test_window_->bounds().size()); + if (!is_async_test()) { + std::vector<unsigned char> png_representation; + ui::GrabWindowSnapshot(test_window(), &png_representation, source_rect); + return gfx::Image::CreateFrom1xPNGBytes(&(png_representation[0]), + png_representation.size()); + } + + scoped_refptr<base::TestSimpleTaskRunner> task_runner( + new base::TestSimpleTaskRunner()); + scoped_refptr<SnapshotHolder> holder(new SnapshotHolder); + ui::GrabWindowSnapshotAsync( + test_window(), + source_rect, + task_runner, + base::Bind(&SnapshotHolder::SnapshotCallback, holder)); + + // Wait for copy response. + WaitForDraw(); + // Run internal snapshot callback to scale/rotate response image. + task_runner->RunUntilIdle(); + // Run SnapshotHolder callback. + helper_->RunAllPendingInMessageLoop(); + + if (holder->completed()) + return holder->image(); + + // Callback never called. + NOTREACHED(); + return gfx::Image(); } private: + class SnapshotHolder : public base::RefCountedThreadSafe<SnapshotHolder> { + public: + SnapshotHolder() : completed_(false) {} + + void SnapshotCallback(const gfx::Image& image) { + DCHECK(!completed_); + image_ = image; + completed_ = true; + } + bool completed() const { + return completed_; + }; + const gfx::Image& image() const { return image_; } + + private: + friend class base::RefCountedThreadSafe<SnapshotHolder>; + + virtual ~SnapshotHolder() {} + + gfx::Image image_; + bool completed_; + }; + scoped_ptr<aura::test::AuraTestHelper> helper_; scoped_ptr<aura::Window> test_window_; scoped_ptr<TestPaintingWindowDelegate> delegate_; @@ -112,7 +166,9 @@ class SnapshotAuraTest : public testing::Test { DISALLOW_COPY_AND_ASSIGN(SnapshotAuraTest); }; -TEST_F(SnapshotAuraTest, FullScreenWindow) { +INSTANTIATE_TEST_CASE_P(SnapshotAuraTest, SnapshotAuraTest, ::testing::Bool()); + +TEST_P(SnapshotAuraTest, FullScreenWindow) { SetupTestWindow(root_window()->bounds()); WaitForDraw(); @@ -122,7 +178,7 @@ TEST_F(SnapshotAuraTest, FullScreenWindow) { EXPECT_EQ(0u, GetFailedPixelsCount(snapshot)); } -TEST_F(SnapshotAuraTest, PartialBounds) { +TEST_P(SnapshotAuraTest, PartialBounds) { gfx::Rect test_bounds(100, 100, 300, 200); SetupTestWindow(test_bounds); WaitForDraw(); @@ -133,7 +189,7 @@ TEST_F(SnapshotAuraTest, PartialBounds) { EXPECT_EQ(0u, GetFailedPixelsCount(snapshot)); } -TEST_F(SnapshotAuraTest, Rotated) { +TEST_P(SnapshotAuraTest, Rotated) { test_screen()->SetDisplayRotation(gfx::Display::ROTATE_90); gfx::Rect test_bounds(100, 100, 300, 200); @@ -146,7 +202,7 @@ TEST_F(SnapshotAuraTest, Rotated) { EXPECT_EQ(0u, GetFailedPixelsCount(snapshot)); } -TEST_F(SnapshotAuraTest, UIScale) { +TEST_P(SnapshotAuraTest, UIScale) { const float kUIScale = 1.25f; test_screen()->SetUIScale(kUIScale); @@ -164,7 +220,7 @@ TEST_F(SnapshotAuraTest, UIScale) { EXPECT_EQ(0u, GetFailedPixelsCount(snapshot)); } -TEST_F(SnapshotAuraTest, DeviceScaleFactor) { +TEST_P(SnapshotAuraTest, DeviceScaleFactor) { test_screen()->SetDeviceScaleFactor(2.0f); gfx::Rect test_bounds(100, 100, 150, 100); @@ -181,7 +237,7 @@ TEST_F(SnapshotAuraTest, DeviceScaleFactor) { EXPECT_EQ(0u, GetFailedPixelsCount(snapshot)); } -TEST_F(SnapshotAuraTest, RotateAndUIScale) { +TEST_P(SnapshotAuraTest, RotateAndUIScale) { const float kUIScale = 1.25f; test_screen()->SetUIScale(kUIScale); test_screen()->SetDisplayRotation(gfx::Display::ROTATE_90); @@ -200,7 +256,7 @@ TEST_F(SnapshotAuraTest, RotateAndUIScale) { EXPECT_EQ(0u, GetFailedPixelsCount(snapshot)); } -TEST_F(SnapshotAuraTest, RotateAndUIScaleAndScaleFactor) { +TEST_P(SnapshotAuraTest, RotateAndUIScaleAndScaleFactor) { test_screen()->SetDeviceScaleFactor(2.0f); const float kUIScale = 1.25f; test_screen()->SetUIScale(kUIScale); diff --git a/ui/snapshot/snapshot_gtk.cc b/ui/snapshot/snapshot_gtk.cc index bf05a33..c904500 100644 --- a/ui/snapshot/snapshot_gtk.cc +++ b/ui/snapshot/snapshot_gtk.cc @@ -83,7 +83,7 @@ bool GrabWindowSnapshot(gfx::NativeWindow window_handle, snapshot_bounds); } -SNAPSHOT_EXPORT void GrabWindowSnapshotAsync( +void GrabWindowSnapshotAndScaleAsync( gfx::NativeWindow window, const gfx::Rect& snapshot_bounds, const gfx::Size& target_size, @@ -92,4 +92,12 @@ SNAPSHOT_EXPORT void GrabWindowSnapshotAsync( NOTIMPLEMENTED(); } +void GrabWindowSnapshotAsync( + gfx::NativeWindow window, + const gfx::Rect& source_rect, + scoped_refptr<base::TaskRunner> background_task_runner, + const GrabWindowSnapshotAsyncCallback& callback) { + NOTIMPLEMENTED(); +} + } // namespace ui diff --git a/ui/snapshot/snapshot_ios.mm b/ui/snapshot/snapshot_ios.mm index b121d42..425192f 100644 --- a/ui/snapshot/snapshot_ios.mm +++ b/ui/snapshot/snapshot_ios.mm @@ -23,7 +23,7 @@ bool GrabWindowSnapshot(gfx::NativeWindow window, return false; } -SNAPSHOT_EXPORT void GrabWindowSnapshotAsync( +void GrabWindowSnapshotAndScaleAsync( gfx::NativeWindow window, const gfx::Rect& snapshot_bounds, const gfx::Size& target_size, @@ -32,4 +32,12 @@ SNAPSHOT_EXPORT void GrabWindowSnapshotAsync( NOTIMPLEMENTED(); } +void GrabWindowSnapshotAsync( + gfx::NativeWindow window, + const gfx::Rect& source_rect, + scoped_refptr<base::TaskRunner> background_task_runner, + const GrabWindowSnapshotAsyncCallback& callback) { + NOTIMPLEMENTED(); +} + } // namespace ui diff --git a/ui/snapshot/snapshot_mac.mm b/ui/snapshot/snapshot_mac.mm index 9057e66..2ebdf54 100644 --- a/ui/snapshot/snapshot_mac.mm +++ b/ui/snapshot/snapshot_mac.mm @@ -73,7 +73,7 @@ bool GrabWindowSnapshot(gfx::NativeWindow window, snapshot_bounds); } -SNAPSHOT_EXPORT void GrabWindowSnapshotAsync( +void GrabWindowSnapshotAndScaleAsync( gfx::NativeWindow window, const gfx::Rect& snapshot_bounds, const gfx::Size& target_size, @@ -82,4 +82,12 @@ SNAPSHOT_EXPORT void GrabWindowSnapshotAsync( NOTIMPLEMENTED(); } +void GrabWindowSnapshotAsync( + gfx::NativeWindow window, + const gfx::Rect& source_rect, + scoped_refptr<base::TaskRunner> background_task_runner, + const GrabWindowSnapshotAsyncCallback& callback) { + NOTIMPLEMENTED(); +} + } // namespace ui diff --git a/ui/snapshot/snapshot_win.cc b/ui/snapshot/snapshot_win.cc index fc157be..da9f1cc 100644 --- a/ui/snapshot/snapshot_win.cc +++ b/ui/snapshot/snapshot_win.cc @@ -119,7 +119,7 @@ bool GrabWindowSnapshot(gfx::NativeWindow window_handle, png_representation); } -SNAPSHOT_EXPORT void GrapWindowSnapshotAsync( +void GrapWindowSnapshotAsync( gfx::NativeWindow window, const gfx::Rect& snapshot_bounds, const gfx::Size& target_size, @@ -128,6 +128,14 @@ SNAPSHOT_EXPORT void GrapWindowSnapshotAsync( NOTIMPLEMENTED(); } +void GrabWindowSnapshotAsync( + gfx::NativeWindow window, + const gfx::Rect& source_rect, + scoped_refptr<base::TaskRunner> background_task_runner, + const GrabWindowSnapshotAsyncCallback& callback) { + NOTIMPLEMENTED(); +} + #endif // !defined(USE_AURA) } // namespace ui diff --git a/ui/views/test/views_test_base.cc b/ui/views/test/views_test_base.cc index e02826c..37085e3 100644 --- a/ui/views/test/views_test_base.cc +++ b/ui/views/test/views_test_base.cc @@ -37,7 +37,8 @@ void ViewsTestBase::SetUp() { views_delegate_.reset(new TestViewsDelegate()); #if defined(USE_AURA) aura_test_helper_.reset(new aura::test::AuraTestHelper(&message_loop_)); - aura_test_helper_->SetUp(); + bool allow_test_contexts = true; + aura_test_helper_->SetUp(allow_test_contexts); wm_state_.reset(new views::corewm::WMState); #endif // USE_AURA ui::InitializeInputMethodForTesting(); diff --git a/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc b/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc index f82b915..0a8596d 100644 --- a/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc +++ b/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc @@ -88,6 +88,7 @@ DesktopWindowTreeHostWin::DesktopWindowTreeHostWin( } DesktopWindowTreeHostWin::~DesktopWindowTreeHostWin() { + DestroyCompositor(); // WARNING: |content_window_| has been destroyed by the time we get here. desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed( root_window_); diff --git a/ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc b/ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc index 6128940..3c9d8c1 100644 --- a/ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc +++ b/ui/views/widget/desktop_aura/desktop_root_window_host_x11.cc @@ -142,6 +142,7 @@ DesktopWindowTreeHostX11::DesktopWindowTreeHostX11( } DesktopWindowTreeHostX11::~DesktopWindowTreeHostX11() { + DestroyCompositor(); root_window_->window()->ClearProperty(kHostForRootWindow); aura::client::SetWindowMoveClient(root_window_->window(), NULL); desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(root_window_); |