Home | History | Annotate | Download | only in snapshot
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ui/snapshot/snapshot.h"
      6 
      7 #include "testing/gtest/include/gtest/gtest.h"
      8 #include "ui/aura/root_window.h"
      9 #include "ui/aura/test/aura_test_helper.h"
     10 #include "ui/aura/test/test_screen.h"
     11 #include "ui/aura/test/test_window_delegate.h"
     12 #include "ui/aura/test/test_windows.h"
     13 #include "ui/aura/window.h"
     14 #include "ui/compositor/layer.h"
     15 #include "ui/gfx/canvas.h"
     16 #include "ui/gfx/gfx_paths.h"
     17 #include "ui/gfx/image/image.h"
     18 #include "ui/gfx/rect.h"
     19 #include "ui/gfx/size_conversions.h"
     20 #include "ui/gfx/transform.h"
     21 #include "ui/gl/gl_implementation.h"
     22 
     23 namespace ui {
     24 namespace {
     25 const SkColor kPaintColor = SK_ColorRED;
     26 
     27 // Paint simple rectangle on the specified aura window.
     28 class TestPaintingWindowDelegate : public aura::test::TestWindowDelegate {
     29  public:
     30   explicit TestPaintingWindowDelegate(const gfx::Size& window_size)
     31       : window_size_(window_size) {
     32   }
     33 
     34   virtual ~TestPaintingWindowDelegate() {
     35   }
     36 
     37   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
     38     canvas->FillRect(gfx::Rect(window_size_), kPaintColor);
     39   }
     40 
     41  private:
     42   gfx::Size window_size_;
     43 
     44   DISALLOW_COPY_AND_ASSIGN(TestPaintingWindowDelegate);
     45 };
     46 
     47 size_t GetFailedPixelsCount(const gfx::Image& image) {
     48   const SkBitmap* bitmap = image.ToSkBitmap();
     49   uint32* bitmap_data = reinterpret_cast<uint32*>(
     50       bitmap->pixelRef()->pixels());
     51   size_t result = 0;
     52   for (int i = 0; i < bitmap->width() * bitmap->height(); ++i) {
     53     if (static_cast<SkColor>(bitmap_data[i]) != kPaintColor)
     54       ++result;
     55   }
     56   return result;
     57 }
     58 
     59 }  // namespace
     60 
     61 class SnapshotAuraTest : public testing::Test {
     62  public:
     63   SnapshotAuraTest() {}
     64   virtual ~SnapshotAuraTest() {}
     65 
     66   virtual void SetUp() OVERRIDE {
     67     testing::Test::SetUp();
     68     helper_.reset(
     69         new aura::test::AuraTestHelper(base::MessageLoopForUI::current()));
     70     helper_->SetUp();
     71   }
     72 
     73   virtual void TearDown() OVERRIDE {
     74     test_window_.reset();
     75     delegate_.reset();
     76     helper_->RunAllPendingInMessageLoop();
     77     helper_->TearDown();
     78     testing::Test::TearDown();
     79   }
     80 
     81  protected:
     82   aura::Window* test_window() { return test_window_.get(); }
     83   aura::Window* root_window() { return helper_->root_window(); }
     84   aura::WindowEventDispatcher* dispatcher() { return helper_->dispatcher(); }
     85   aura::TestScreen* test_screen() { return helper_->test_screen(); }
     86 
     87   void WaitForDraw() {
     88     dispatcher()->compositor()->ScheduleDraw();
     89     ui::DrawWaiterForTest::Wait(dispatcher()->compositor());
     90   }
     91 
     92   void SetupTestWindow(const gfx::Rect& window_bounds) {
     93     delegate_.reset(new TestPaintingWindowDelegate(window_bounds.size()));
     94     test_window_.reset(aura::test::CreateTestWindowWithDelegate(
     95         delegate_.get(), 0, window_bounds, root_window()));
     96   }
     97 
     98   gfx::Image GrabSnapshotForTestWindow() {
     99     std::vector<unsigned char> png_representation;
    100     gfx::Rect local_bounds(test_window_->bounds().size());
    101     ui::GrabWindowSnapshot(test_window(), &png_representation, local_bounds);
    102     return gfx::Image::CreateFrom1xPNGBytes(
    103       &(png_representation[0]), png_representation.size());
    104   }
    105 
    106  private:
    107   scoped_ptr<aura::test::AuraTestHelper> helper_;
    108   scoped_ptr<aura::Window> test_window_;
    109   scoped_ptr<TestPaintingWindowDelegate> delegate_;
    110   std::vector<unsigned char> png_representation_;
    111 
    112   DISALLOW_COPY_AND_ASSIGN(SnapshotAuraTest);
    113 };
    114 
    115 TEST_F(SnapshotAuraTest, FullScreenWindow) {
    116   SetupTestWindow(root_window()->bounds());
    117   WaitForDraw();
    118 
    119   gfx::Image snapshot = GrabSnapshotForTestWindow();
    120   EXPECT_EQ(test_window()->bounds().size().ToString(),
    121             snapshot.Size().ToString());
    122   EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
    123 }
    124 
    125 TEST_F(SnapshotAuraTest, PartialBounds) {
    126   gfx::Rect test_bounds(100, 100, 300, 200);
    127   SetupTestWindow(test_bounds);
    128   WaitForDraw();
    129 
    130   gfx::Image snapshot = GrabSnapshotForTestWindow();
    131   EXPECT_EQ(test_bounds.size().ToString(),
    132             snapshot.Size().ToString());
    133   EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
    134 }
    135 
    136 TEST_F(SnapshotAuraTest, Rotated) {
    137   test_screen()->SetDisplayRotation(gfx::Display::ROTATE_90);
    138 
    139   gfx::Rect test_bounds(100, 100, 300, 200);
    140   SetupTestWindow(test_bounds);
    141   WaitForDraw();
    142 
    143   gfx::Image snapshot = GrabSnapshotForTestWindow();
    144   EXPECT_EQ(test_bounds.size().ToString(),
    145             snapshot.Size().ToString());
    146   EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
    147 }
    148 
    149 TEST_F(SnapshotAuraTest, UIScale) {
    150   const float kUIScale = 1.25f;
    151   test_screen()->SetUIScale(kUIScale);
    152 
    153   gfx::Rect test_bounds(100, 100, 300, 200);
    154   SetupTestWindow(test_bounds);
    155   WaitForDraw();
    156 
    157   // Snapshot always captures the physical pixels.
    158   gfx::SizeF snapshot_size(test_bounds.size());
    159   snapshot_size.Scale(1.0f / kUIScale);
    160 
    161   gfx::Image snapshot = GrabSnapshotForTestWindow();
    162   EXPECT_EQ(gfx::ToRoundedSize(snapshot_size).ToString(),
    163             snapshot.Size().ToString());
    164   EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
    165 }
    166 
    167 TEST_F(SnapshotAuraTest, DeviceScaleFactor) {
    168   test_screen()->SetDeviceScaleFactor(2.0f);
    169 
    170   gfx::Rect test_bounds(100, 100, 150, 100);
    171   SetupTestWindow(test_bounds);
    172   WaitForDraw();
    173 
    174   // Snapshot always captures the physical pixels.
    175   gfx::SizeF snapshot_size(test_bounds.size());
    176   snapshot_size.Scale(2.0f);
    177 
    178   gfx::Image snapshot = GrabSnapshotForTestWindow();
    179   EXPECT_EQ(gfx::ToRoundedSize(snapshot_size).ToString(),
    180             snapshot.Size().ToString());
    181   EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
    182 }
    183 
    184 TEST_F(SnapshotAuraTest, RotateAndUIScale) {
    185   const float kUIScale = 1.25f;
    186   test_screen()->SetUIScale(kUIScale);
    187   test_screen()->SetDisplayRotation(gfx::Display::ROTATE_90);
    188 
    189   gfx::Rect test_bounds(100, 100, 300, 200);
    190   SetupTestWindow(test_bounds);
    191   WaitForDraw();
    192 
    193   // Snapshot always captures the physical pixels.
    194   gfx::SizeF snapshot_size(test_bounds.size());
    195   snapshot_size.Scale(1.0f / kUIScale);
    196 
    197   gfx::Image snapshot = GrabSnapshotForTestWindow();
    198   EXPECT_EQ(gfx::ToRoundedSize(snapshot_size).ToString(),
    199             snapshot.Size().ToString());
    200   EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
    201 }
    202 
    203 TEST_F(SnapshotAuraTest, RotateAndUIScaleAndScaleFactor) {
    204   test_screen()->SetDeviceScaleFactor(2.0f);
    205   const float kUIScale = 1.25f;
    206   test_screen()->SetUIScale(kUIScale);
    207   test_screen()->SetDisplayRotation(gfx::Display::ROTATE_90);
    208 
    209   gfx::Rect test_bounds(20, 30, 150, 100);
    210   SetupTestWindow(test_bounds);
    211   WaitForDraw();
    212 
    213   // Snapshot always captures the physical pixels.
    214   gfx::SizeF snapshot_size(test_bounds.size());
    215   snapshot_size.Scale(2.0f / kUIScale);
    216 
    217   gfx::Image snapshot = GrabSnapshotForTestWindow();
    218   EXPECT_EQ(gfx::ToRoundedSize(snapshot_size).ToString(),
    219             snapshot.Size().ToString());
    220   EXPECT_EQ(0u, GetFailedPixelsCount(snapshot));
    221 }
    222 
    223 }  // namespace ui
    224