OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/basictypes.h" | 5 #include "base/basictypes.h" |
6 #include "base/compiler_specific.h" | 6 #include "base/compiler_specific.h" |
7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
13 #include "ui/gfx/canvas_skia.h" | 13 #include "ui/gfx/canvas_skia.h" |
14 #include "ui/gfx/codec/png_codec.h" | 14 #include "ui/gfx/codec/png_codec.h" |
15 #include "ui/gfx/compositor/compositor_observer.h" | 15 #include "ui/gfx/compositor/compositor_observer.h" |
16 #include "ui/gfx/compositor/layer.h" | 16 #include "ui/gfx/compositor/layer.h" |
17 #include "ui/gfx/compositor/layer_animation_sequence.h" | 17 #include "ui/gfx/compositor/layer_animation_sequence.h" |
18 #include "ui/gfx/compositor/test_compositor.h" | 18 #include "ui/gfx/compositor/test/test_compositor.h" |
19 #include "ui/gfx/compositor/test_compositor_host.h" | 19 #include "ui/gfx/compositor/test/test_compositor_host.h" |
20 #include "ui/gfx/gfx_paths.h" | |
20 | 21 |
21 namespace ui { | 22 namespace ui { |
22 | 23 |
23 namespace { | 24 namespace { |
24 | 25 |
26 // Encodes a bitmap into a PNG and write to disk. Returns true on success. The | |
27 // parent directory does not have to exist. | |
28 bool WritePNGFile(const SkBitmap& bitmap, const FilePath& file_path) { | |
29 std::vector<unsigned char> png_data; | |
30 if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data) && | |
31 file_util::CreateDirectory(file_path.DirName())) { | |
32 int bytes_written = file_util::WriteFile( | |
sky
2011/11/14 21:44:26
nit: make this one statement,
return file_util::Wr
| |
33 file_path, reinterpret_cast<char*>(&png_data[0]), png_data.size()); | |
34 if (bytes_written == static_cast<int>(png_data.size())) | |
35 return true; | |
36 } | |
37 return false; | |
38 } | |
39 | |
40 // Reads and decodes a PNG image to a bitmap. Returns true on success. The PNG | |
41 // should have been encoded using |gfx::PNGCodec::Encode|. | |
42 bool ReadPNGFile(const FilePath& file_path, SkBitmap* bitmap) { | |
43 DCHECK(bitmap); | |
44 std::string png_data; | |
45 return file_util::ReadFileToString(file_path, &png_data) && | |
46 gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&png_data[0]), | |
47 png_data.length(), | |
48 bitmap); | |
49 } | |
50 | |
25 // There are three test classes in here that configure the Compositor and | 51 // There are three test classes in here that configure the Compositor and |
26 // Layer's slightly differently: | 52 // Layer's slightly differently: |
27 // - LayerWithNullDelegateTest uses TestCompositor and NullLayerDelegate as the | 53 // - LayerWithNullDelegateTest uses TestCompositor and NullLayerDelegate as the |
28 // LayerDelegate. This is typically the base class you want to use. | 54 // LayerDelegate. This is typically the base class you want to use. |
29 // - LayerWithDelegateTest uses TestCompositor and does not set a LayerDelegate | 55 // - LayerWithDelegateTest uses TestCompositor and does not set a LayerDelegate |
30 // on the delegates. | 56 // on the delegates. |
31 // - LayerWithRealCompositorTest when a real compositor is required for testing. | 57 // - LayerWithRealCompositorTest when a real compositor is required for testing. |
32 // - Slow because they bring up a window and run the real compositor. This | 58 // - Slow because they bring up a window and run the real compositor. This |
33 // is typically not what you want. | 59 // is typically not what you want. |
34 | 60 |
(...skipping 11 matching lines...) Expand all Loading... | |
46 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE { | 72 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE { |
47 canvas->GetSkCanvas()->drawColor(color_); | 73 canvas->GetSkCanvas()->drawColor(color_); |
48 } | 74 } |
49 | 75 |
50 private: | 76 private: |
51 SkColor color_; | 77 SkColor color_; |
52 }; | 78 }; |
53 | 79 |
54 class LayerWithRealCompositorTest : public testing::Test { | 80 class LayerWithRealCompositorTest : public testing::Test { |
55 public: | 81 public: |
56 LayerWithRealCompositorTest() {} | 82 LayerWithRealCompositorTest() { |
83 if (PathService::Get(gfx::DIR_TEST_DATA, &test_data_directory_)) { | |
84 test_data_directory_ = test_data_directory_.AppendASCII("compositor"); | |
85 } | |
86 } | |
57 virtual ~LayerWithRealCompositorTest() {} | 87 virtual ~LayerWithRealCompositorTest() {} |
58 | 88 |
59 // Overridden from testing::Test: | 89 // Overridden from testing::Test: |
60 virtual void SetUp() OVERRIDE { | 90 virtual void SetUp() OVERRIDE { |
61 const gfx::Rect host_bounds(10, 10, 500, 500); | 91 const gfx::Rect host_bounds(10, 10, 500, 500); |
62 window_.reset(TestCompositorHost::Create(host_bounds)); | 92 window_.reset(TestCompositorHost::Create(host_bounds)); |
63 window_->Show(); | 93 window_->Show(); |
64 } | 94 } |
65 | 95 |
66 virtual void TearDown() OVERRIDE { | 96 virtual void TearDown() OVERRIDE { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
98 void RunPendingMessages() { | 128 void RunPendingMessages() { |
99 MessageLoopForUI::current()->RunAllPending(); | 129 MessageLoopForUI::current()->RunAllPending(); |
100 } | 130 } |
101 | 131 |
102 // Invalidates the entire contents of the layer. | 132 // Invalidates the entire contents of the layer. |
103 void SchedulePaintForLayer(Layer* layer) { | 133 void SchedulePaintForLayer(Layer* layer) { |
104 layer->SchedulePaint( | 134 layer->SchedulePaint( |
105 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height())); | 135 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height())); |
106 } | 136 } |
107 | 137 |
138 // Compares with a ping file on disk, and returns true if it is the same as | |
jonathan.backer
2011/11/14 20:22:40
s/ping/PNG
| |
139 // the given image. | |
jonathan.backer
2011/11/14 20:22:40
Your call. Seems like something that belongs in th
| |
140 bool IsSameAsPNGFile(const SkBitmap& gen_bmp, const char* file) { | |
sky
2011/11/14 21:44:26
Document what file is relative to.
| |
141 SkBitmap ref_bmp; | |
142 bool should_compare = true; | |
143 FilePath ref_img_path = test_data_directory_.AppendASCII(file); | |
144 if (!ReadPNGFile(ref_img_path, &ref_bmp)) { | |
145 LOG(ERROR) << "Cannot read reference image: " << ref_img_path.value(); | |
146 should_compare = false; | |
sky
2011/11/14 21:44:26
Is there any point on continuing on if you can't r
| |
147 } | |
148 | |
149 if (should_compare && | |
150 (ref_bmp.width() != gen_bmp.width() || | |
151 ref_bmp.height() != gen_bmp.height())) { | |
152 LOG(ERROR) | |
153 << "Dimensions do not match (Expected) vs (Actual):" | |
154 << "(" << ref_bmp.width() << "x" << ref_bmp.height() | |
155 << ") vs. " | |
156 << "(" << gen_bmp.width() << "x" << gen_bmp.height() << ")"; | |
157 should_compare = false; | |
sky
2011/11/14 21:44:26
Return here too?
| |
158 } | |
159 | |
160 // Compare pixels and create a simple diff image. | |
161 int diff_pixels_count = 0; | |
162 if (should_compare) { | |
163 SkAutoLockPixels lock_bmp(gen_bmp); | |
164 SkAutoLockPixels lock_ref_bmp(ref_bmp); | |
165 // The reference images were saved with no alpha channel. Use the mask to | |
166 // set alpha to 0. | |
167 uint32_t kAlphaMask = 0x00FFFFFF; | |
168 for (int x = 0; x < gen_bmp.width(); ++x) { | |
169 for (int y = 0; y < gen_bmp.height(); ++y) { | |
170 if ((*gen_bmp.getAddr32(x, y) & kAlphaMask) != | |
171 (*ref_bmp.getAddr32(x, y) & kAlphaMask)) { | |
172 ++diff_pixels_count; | |
173 } | |
174 } | |
175 } | |
176 } | |
177 | |
178 // Write the generated and diff images if the comparison failed. | |
jonathan.backer
2011/11/14 20:22:40
Stale comment?
| |
179 if (diff_pixels_count != 0) { | |
180 LOG(ERROR) << "Images differ by pixel count: " << diff_pixels_count; | |
181 return false; | |
182 } | |
183 | |
184 return true; | |
185 } | |
186 | |
108 private: | 187 private: |
109 scoped_ptr<TestCompositorHost> window_; | 188 scoped_ptr<TestCompositorHost> window_; |
110 | 189 |
190 // The root directory for test files. | |
191 FilePath test_data_directory_; | |
192 | |
111 DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest); | 193 DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest); |
112 }; | 194 }; |
113 | 195 |
114 // LayerDelegate that paints colors to the layer. | 196 // LayerDelegate that paints colors to the layer. |
115 class TestLayerDelegate : public LayerDelegate { | 197 class TestLayerDelegate : public LayerDelegate { |
116 public: | 198 public: |
117 explicit TestLayerDelegate() : color_index_(0) {} | 199 explicit TestLayerDelegate() : color_index_(0) {} |
118 virtual ~TestLayerDelegate() {} | 200 virtual ~TestLayerDelegate() {} |
119 | 201 |
120 void AddColor(SkColor color) { | 202 void AddColor(SkColor color) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
171 virtual ~NullLayerDelegate() {} | 253 virtual ~NullLayerDelegate() {} |
172 | 254 |
173 private: | 255 private: |
174 // Overridden from LayerDelegate: | 256 // Overridden from LayerDelegate: |
175 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE { | 257 virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE { |
176 } | 258 } |
177 | 259 |
178 DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate); | 260 DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate); |
179 }; | 261 }; |
180 | 262 |
181 // Encodes a bitmap into a PNG and write to disk. Returns true on success. The | |
182 // parent directory does not have to exist. | |
183 bool WritePNGFile(const SkBitmap& bitmap, const FilePath& file_path) { | |
184 std::vector<unsigned char> png_data; | |
185 if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data) && | |
186 file_util::CreateDirectory(file_path.DirName())) { | |
187 int bytes_written = file_util::WriteFile( | |
188 file_path, reinterpret_cast<char*>(&png_data[0]), png_data.size()); | |
189 if (bytes_written == static_cast<int>(png_data.size())) | |
190 return true; | |
191 } | |
192 return false; | |
193 } | |
194 | |
195 } | 263 } |
196 | 264 |
197 #if defined(OS_WIN) | 265 #if defined(OS_WIN) |
198 // These are disabled on windows as they don't run correctly on the buildbot. | 266 // These are disabled on windows as they don't run correctly on the buildbot. |
199 // Reenable once we move to the real compositor. | 267 // Reenable once we move to the real compositor. |
200 #define MAYBE_Delegate DISABLED_Delegate | 268 #define MAYBE_Delegate DISABLED_Delegate |
201 #define MAYBE_Draw DISABLED_Draw | 269 #define MAYBE_Draw DISABLED_Draw |
202 #define MAYBE_DrawTree DISABLED_DrawTree | 270 #define MAYBE_DrawTree DISABLED_DrawTree |
203 #define MAYBE_Hierarchy DISABLED_Hierarchy | 271 #define MAYBE_Hierarchy DISABLED_Hierarchy |
204 #define MAYBE_HierarchyNoTexture DISABLED_HierarchyNoTexture | 272 #define MAYBE_HierarchyNoTexture DISABLED_HierarchyNoTexture |
205 #define MAYBE_DrawPixels DISABLED_DrawPixels | 273 #define MAYBE_DrawPixels DISABLED_DrawPixels |
274 #define MAYBE_ModifyHierarchy DISABLED_ModifyHierarchy | |
275 #define MAYBE_Opacity DISABLED_Opacity | |
206 #else | 276 #else |
207 #define MAYBE_Delegate Delegate | 277 #define MAYBE_Delegate Delegate |
208 #define MAYBE_Draw Draw | 278 #define MAYBE_Draw Draw |
209 #define MAYBE_DrawTree DrawTree | 279 #define MAYBE_DrawTree DrawTree |
210 #define MAYBE_Hierarchy Hierarchy | 280 #define MAYBE_Hierarchy Hierarchy |
211 #define MAYBE_HierarchyNoTexture HierarchyNoTexture | 281 #define MAYBE_HierarchyNoTexture HierarchyNoTexture |
212 #define MAYBE_DrawPixels DrawPixels | 282 #define MAYBE_DrawPixels DrawPixels |
283 #define MAYBE_ModifyHierarchy ModifyHierarchy | |
284 #define MAYBE_Opacity Opacity | |
213 #endif | 285 #endif |
214 | 286 |
215 TEST_F(LayerWithRealCompositorTest, MAYBE_Draw) { | 287 TEST_F(LayerWithRealCompositorTest, MAYBE_Draw) { |
216 scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED, | 288 scoped_ptr<Layer> layer(CreateColorLayer(SK_ColorRED, |
217 gfx::Rect(20, 20, 50, 50))); | 289 gfx::Rect(20, 20, 50, 50))); |
218 DrawTree(layer.get()); | 290 DrawTree(layer.get()); |
219 } | 291 } |
220 | 292 |
221 // Create this hierarchy: | 293 // Create this hierarchy: |
222 // L1 - red | 294 // L1 - red |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
816 | 888 |
817 SkAutoLockPixels lock(bitmap); | 889 SkAutoLockPixels lock(bitmap); |
818 bool is_all_red = true; | 890 bool is_all_red = true; |
819 for (int x = 0; is_all_red && x < 500; x++) | 891 for (int x = 0; is_all_red && x < 500; x++) |
820 for (int y = 0; is_all_red && y < 500; y++) | 892 for (int y = 0; is_all_red && y < 500; y++) |
821 is_all_red = is_all_red && (bitmap.getColor(x, y) == SK_ColorRED); | 893 is_all_red = is_all_red && (bitmap.getColor(x, y) == SK_ColorRED); |
822 | 894 |
823 EXPECT_TRUE(is_all_red); | 895 EXPECT_TRUE(is_all_red); |
824 } | 896 } |
825 | 897 |
898 // Checks that modifying the hierarchy correctly affects final composite. | |
899 TEST_F(LayerWithRealCompositorTest, MAYBE_ModifyHierarchy) { | |
900 GetCompositor()->WidgetSizeChanged(gfx::Size(50, 50)); | |
901 | |
902 // l0 | |
903 // +-l11 | |
904 // | +-l21 | |
905 // +-l12 | |
906 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED, | |
907 gfx::Rect(0, 0, 50, 50))); | |
908 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN, | |
909 gfx::Rect(0, 0, 25, 25))); | |
910 scoped_ptr<Layer> l21(CreateColorLayer(SK_ColorMAGENTA, | |
911 gfx::Rect(0, 0, 15, 15))); | |
912 scoped_ptr<Layer> l12(CreateColorLayer(SK_ColorBLUE, | |
913 gfx::Rect(10, 10, 25, 25))); | |
914 | |
915 l0->Add(l11.get()); | |
916 l11->Add(l21.get()); | |
917 l0->Add(l12.get()); | |
918 | |
919 DrawTree(l0.get()); | |
920 | |
921 SkBitmap bitmap; | |
922 ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap)); | |
923 ASSERT_FALSE(bitmap.empty()); | |
924 | |
925 //WritePNGFile(bitmap, | |
926 // FilePath("ui/gfx/test/data/compositor/ModifyHierarchy1.png")); | |
jonathan.backer
2011/11/14 20:22:40
This is probably OK. But I'm guessing that you nee
| |
927 ASSERT_TRUE(IsSameAsPNGFile(bitmap, "ModifyHierarchy1.png")); | |
928 | |
929 l0->MoveToFront(l11.get()); | |
930 | |
931 DrawTree(l0.get()); | |
932 | |
933 ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap)); | |
934 ASSERT_FALSE(bitmap.empty()); | |
935 | |
936 //WritePNGFile(bitmap, | |
937 // FilePath("ui/gfx/test/data/compositor/ModifyHierarchy2.png")); | |
938 ASSERT_TRUE(IsSameAsPNGFile(bitmap, "ModifyHierarchy2.png")); | |
939 | |
940 // l11 is already at the front, should have no effect. | |
941 l0->MoveToFront(l11.get()); | |
942 | |
943 DrawTree(l0.get()); | |
944 | |
945 ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap)); | |
946 ASSERT_FALSE(bitmap.empty()); | |
947 | |
948 ASSERT_TRUE(IsSameAsPNGFile(bitmap, "ModifyHierarchy2.png")); | |
949 | |
950 // l11 is already at the front, should have no effect. | |
951 l0->MoveAbove(l11.get(), l12.get()); | |
952 | |
953 DrawTree(l0.get()); | |
954 | |
955 ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap)); | |
956 ASSERT_FALSE(bitmap.empty()); | |
957 | |
958 ASSERT_TRUE(IsSameAsPNGFile(bitmap, "ModifyHierarchy2.png")); | |
959 | |
960 // should restore to original configuration | |
961 l0->MoveAbove(l12.get(), l11.get()); | |
962 | |
963 DrawTree(l0.get()); | |
964 | |
965 ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap)); | |
966 ASSERT_FALSE(bitmap.empty()); | |
967 | |
968 ASSERT_TRUE(IsSameAsPNGFile(bitmap, "ModifyHierarchy1.png")); | |
969 } | |
970 | |
971 // Opacity is rendered correctly. | |
972 // Checks that modifying the hierarchy correctly affects final composite. | |
973 TEST_F(LayerWithRealCompositorTest, MAYBE_Opacity) { | |
974 GetCompositor()->WidgetSizeChanged(gfx::Size(50, 50)); | |
975 | |
976 // l0 | |
977 // +-l11 | |
978 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED, | |
979 gfx::Rect(0, 0, 50, 50))); | |
980 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN, | |
981 gfx::Rect(0, 0, 25, 25))); | |
982 | |
983 l11->SetOpacity(0.75); | |
984 | |
985 l0->Add(l11.get()); | |
986 DrawTree(l0.get()); | |
987 | |
988 SkBitmap bitmap; | |
989 ASSERT_TRUE(GetCompositor()->ReadPixels(&bitmap)); | |
990 ASSERT_FALSE(bitmap.empty()); | |
991 | |
992 //WritePNGFile(bitmap, FilePath("ui/gfx/test/data/compositor/Opacity.png")); | |
993 ASSERT_TRUE(IsSameAsPNGFile(bitmap, "Opacity.png")); | |
994 } | |
995 | |
826 } // namespace ui | 996 } // namespace ui |
OLD | NEW |