OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/bind.h" | 6 #include "base/bind.h" |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
125 layer->SetBounds(bounds); | 125 layer->SetBounds(bounds); |
126 return layer; | 126 return layer; |
127 } | 127 } |
128 | 128 |
129 void DrawTree(Layer* root) { | 129 void DrawTree(Layer* root) { |
130 GetCompositor()->SetRootLayer(root); | 130 GetCompositor()->SetRootLayer(root); |
131 GetCompositor()->ScheduleDraw(); | 131 GetCompositor()->ScheduleDraw(); |
132 WaitForSwap(); | 132 WaitForSwap(); |
133 } | 133 } |
134 | 134 |
135 bool ReadPixels(SkBitmap* bitmap) { | 135 void ReadPixels(SkBitmap* bitmap) { |
136 return ReadPixels(bitmap, gfx::Rect(GetCompositor()->size())); | 136 ReadPixels(bitmap, gfx::Rect(GetCompositor()->size())); |
137 } | 137 } |
138 | 138 |
139 bool ReadPixels(SkBitmap* bitmap, gfx::Rect source_rect) { | 139 void ReadPixels(SkBitmap* bitmap, gfx::Rect source_rect) { |
140 scoped_refptr<ReadbackHolder> holder(new ReadbackHolder); | 140 scoped_refptr<ReadbackHolder> holder(new ReadbackHolder); |
141 scoped_ptr<cc::CopyOutputRequest> request = | 141 scoped_ptr<cc::CopyOutputRequest> request = |
142 cc::CopyOutputRequest::CreateBitmapRequest( | 142 cc::CopyOutputRequest::CreateBitmapRequest( |
143 base::Bind(&ReadbackHolder::OutputRequestCallback, holder)); | 143 base::Bind(&ReadbackHolder::OutputRequestCallback, holder)); |
144 request->set_area(source_rect); | 144 request->set_area(source_rect); |
145 | 145 |
146 GetCompositor()->root_layer()->RequestCopyOfOutput(request.Pass()); | 146 GetCompositor()->root_layer()->RequestCopyOfOutput(request.Pass()); |
147 | 147 |
148 // Wait for copy response. The copy output request will get committed | 148 // Wait for copy response. The copy output request will get committed |
149 // before the first draw, but may not be part of the first draw's frame. | 149 // before the first draw, but may not be part of the first draw's frame. |
150 // The second draw will perform the async copy request, post the callback. | 150 // The second draw will perform the async copy request, post the callback. |
151 // The second loop finishes before the callback is run, so a third | 151 for (int i = 0; i < 2; i++) { |
152 // loop is needed. | |
153 for (int i = 0; i < 3; i++) { | |
154 GetCompositor()->ScheduleFullRedraw(); | 152 GetCompositor()->ScheduleFullRedraw(); |
155 WaitForDraw(); | 153 WaitForDraw(); |
156 } | 154 } |
157 | 155 |
158 if (holder->completed()) { | 156 // Waits for the callback to finish run and return result. |
159 *bitmap = holder->result(); | 157 holder->WaitForReadback(); |
160 return true; | |
161 } | |
162 | 158 |
163 // Callback never called. | 159 *bitmap = holder->result(); |
164 NOTREACHED(); | |
165 return false; | |
166 } | 160 } |
167 | 161 |
168 void WaitForDraw() { | 162 void WaitForDraw() { |
169 ui::DrawWaiterForTest::WaitForCompositingStarted(GetCompositor()); | 163 ui::DrawWaiterForTest::WaitForCompositingStarted(GetCompositor()); |
170 } | 164 } |
171 | 165 |
172 void WaitForSwap() { | 166 void WaitForSwap() { |
173 DrawWaiterForTest::WaitForCompositingEnded(GetCompositor()); | 167 DrawWaiterForTest::WaitForCompositingEnded(GetCompositor()); |
174 } | 168 } |
175 | 169 |
176 void WaitForCommit() { | 170 void WaitForCommit() { |
177 ui::DrawWaiterForTest::WaitForCommit(GetCompositor()); | 171 ui::DrawWaiterForTest::WaitForCommit(GetCompositor()); |
178 } | 172 } |
179 | 173 |
180 // Invalidates the entire contents of the layer. | 174 // Invalidates the entire contents of the layer. |
181 void SchedulePaintForLayer(Layer* layer) { | 175 void SchedulePaintForLayer(Layer* layer) { |
182 layer->SchedulePaint( | 176 layer->SchedulePaint( |
183 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height())); | 177 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height())); |
184 } | 178 } |
185 | 179 |
186 const base::FilePath& test_data_directory() const { | 180 const base::FilePath& test_data_directory() const { |
187 return test_data_directory_; | 181 return test_data_directory_; |
188 } | 182 } |
189 | 183 |
190 private: | 184 private: |
191 class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> { | 185 class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> { |
192 public: | 186 public: |
193 ReadbackHolder() : completed_(false) {} | 187 ReadbackHolder() : run_loop_(new base::RunLoop) {} |
194 | 188 |
195 void OutputRequestCallback(scoped_ptr<cc::CopyOutputResult> result) { | 189 void OutputRequestCallback(scoped_ptr<cc::CopyOutputResult> result) { |
196 DCHECK(!completed_); | |
197 result_ = result->TakeBitmap(); | 190 result_ = result->TakeBitmap(); |
198 completed_ = true; | 191 base::MessageLoop::current()->PostTask(FROM_HERE, |
danakj
2014/09/19 22:51:15
you could just QuitClosure().Run() instead of post
danakj
2014/09/19 23:36:17
LGTM once you Quit() more directly here.
| |
192 run_loop_->QuitClosure()); | |
199 } | 193 } |
200 bool completed() const { | 194 |
201 return completed_; | 195 void WaitForReadback() { run_loop_->Run(); } |
202 }; | 196 |
203 const SkBitmap& result() const { return *result_; } | 197 const SkBitmap& result() const { return *result_; } |
204 | 198 |
205 private: | 199 private: |
206 friend class base::RefCountedThreadSafe<ReadbackHolder>; | 200 friend class base::RefCountedThreadSafe<ReadbackHolder>; |
207 | 201 |
208 virtual ~ReadbackHolder() {} | 202 virtual ~ReadbackHolder() {} |
209 | 203 |
210 scoped_ptr<SkBitmap> result_; | 204 scoped_ptr<SkBitmap> result_; |
211 bool completed_; | 205 scoped_ptr<base::RunLoop> run_loop_; |
212 }; | 206 }; |
213 | 207 |
214 scoped_ptr<TestCompositorHost> compositor_host_; | 208 scoped_ptr<TestCompositorHost> compositor_host_; |
215 | 209 |
216 // The root directory for test files. | 210 // The root directory for test files. |
217 base::FilePath test_data_directory_; | 211 base::FilePath test_data_directory_; |
218 | 212 |
219 DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest); | 213 DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest); |
220 }; | 214 }; |
221 | 215 |
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
887 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size))); | 881 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size))); |
888 scoped_ptr<Layer> layer2( | 882 scoped_ptr<Layer> layer2( |
889 CreateColorLayer(SK_ColorBLUE, | 883 CreateColorLayer(SK_ColorBLUE, |
890 gfx::Rect(0, 0, viewport_size.width(), blue_height))); | 884 gfx::Rect(0, 0, viewport_size.width(), blue_height))); |
891 | 885 |
892 layer->Add(layer2.get()); | 886 layer->Add(layer2.get()); |
893 | 887 |
894 DrawTree(layer.get()); | 888 DrawTree(layer.get()); |
895 | 889 |
896 SkBitmap bitmap; | 890 SkBitmap bitmap; |
897 ASSERT_TRUE(ReadPixels(&bitmap, gfx::Rect(viewport_size))); | 891 ReadPixels(&bitmap, gfx::Rect(viewport_size)); |
898 ASSERT_FALSE(bitmap.empty()); | 892 ASSERT_FALSE(bitmap.empty()); |
899 | 893 |
900 SkAutoLockPixels lock(bitmap); | 894 SkAutoLockPixels lock(bitmap); |
901 for (int x = 0; x < viewport_size.width(); x++) { | 895 for (int x = 0; x < viewport_size.width(); x++) { |
902 for (int y = 0; y < viewport_size.height(); y++) { | 896 for (int y = 0; y < viewport_size.height(); y++) { |
903 SkColor actual_color = bitmap.getColor(x, y); | 897 SkColor actual_color = bitmap.getColor(x, y); |
904 SkColor expected_color = y < blue_height ? SK_ColorBLUE : SK_ColorRED; | 898 SkColor expected_color = y < blue_height ? SK_ColorBLUE : SK_ColorRED; |
905 ExpectRgba(x, y, expected_color, actual_color); | 899 ExpectRgba(x, y, expected_color, actual_color); |
906 } | 900 } |
907 } | 901 } |
(...skipping 17 matching lines...) Expand all Loading... | |
925 scoped_ptr<Layer> foreground_layer( | 919 scoped_ptr<Layer> foreground_layer( |
926 CreateColorLayer(blue_with_alpha, gfx::Rect(viewport_size))); | 920 CreateColorLayer(blue_with_alpha, gfx::Rect(viewport_size))); |
927 | 921 |
928 // This must be set to false for layers with alpha to be blended correctly. | 922 // This must be set to false for layers with alpha to be blended correctly. |
929 foreground_layer->SetFillsBoundsOpaquely(false); | 923 foreground_layer->SetFillsBoundsOpaquely(false); |
930 | 924 |
931 background_layer->Add(foreground_layer.get()); | 925 background_layer->Add(foreground_layer.get()); |
932 DrawTree(background_layer.get()); | 926 DrawTree(background_layer.get()); |
933 | 927 |
934 SkBitmap bitmap; | 928 SkBitmap bitmap; |
935 ASSERT_TRUE(ReadPixels(&bitmap, gfx::Rect(viewport_size))); | 929 ReadPixels(&bitmap, gfx::Rect(viewport_size)); |
936 ASSERT_FALSE(bitmap.empty()); | 930 ASSERT_FALSE(bitmap.empty()); |
937 | 931 |
938 SkAutoLockPixels lock(bitmap); | 932 SkAutoLockPixels lock(bitmap); |
939 for (int x = 0; x < test_size; x++) { | 933 for (int x = 0; x < test_size; x++) { |
940 for (int y = 0; y < test_size; y++) { | 934 for (int y = 0; y < test_size; y++) { |
941 SkColor actual_color = bitmap.getColor(x, y); | 935 SkColor actual_color = bitmap.getColor(x, y); |
942 ExpectRgba(x, y, blend_color, actual_color); | 936 ExpectRgba(x, y, blend_color, actual_color); |
943 } | 937 } |
944 } | 938 } |
945 } | 939 } |
(...skipping 20 matching lines...) Expand all Loading... | |
966 SkRegion shape; | 960 SkRegion shape; |
967 shape.setRect(0, 0, viewport_size.width(), blue_height); | 961 shape.setRect(0, 0, viewport_size.width(), blue_height); |
968 foreground_layer->SetAlphaShape(make_scoped_ptr(new SkRegion(shape))); | 962 foreground_layer->SetAlphaShape(make_scoped_ptr(new SkRegion(shape))); |
969 | 963 |
970 foreground_layer->SetFillsBoundsOpaquely(false); | 964 foreground_layer->SetFillsBoundsOpaquely(false); |
971 | 965 |
972 background_layer->Add(foreground_layer.get()); | 966 background_layer->Add(foreground_layer.get()); |
973 DrawTree(background_layer.get()); | 967 DrawTree(background_layer.get()); |
974 | 968 |
975 SkBitmap bitmap; | 969 SkBitmap bitmap; |
976 ASSERT_TRUE(ReadPixels(&bitmap, gfx::Rect(viewport_size))); | 970 ReadPixels(&bitmap, gfx::Rect(viewport_size)); |
977 ASSERT_FALSE(bitmap.empty()); | 971 ASSERT_FALSE(bitmap.empty()); |
978 | 972 |
979 SkAutoLockPixels lock(bitmap); | 973 SkAutoLockPixels lock(bitmap); |
980 for (int x = 0; x < test_size; x++) { | 974 for (int x = 0; x < test_size; x++) { |
981 for (int y = 0; y < test_size; y++) { | 975 for (int y = 0; y < test_size; y++) { |
982 SkColor actual_color = bitmap.getColor(x, y); | 976 SkColor actual_color = bitmap.getColor(x, y); |
983 ExpectRgba(x, y, actual_color, | 977 ExpectRgba(x, y, actual_color, |
984 y < blue_height ? blend_color : SK_ColorRED); | 978 y < blue_height ? blend_color : SK_ColorRED); |
985 } | 979 } |
986 } | 980 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1112 base::FilePath ref_img1 = | 1106 base::FilePath ref_img1 = |
1113 test_data_directory().AppendASCII("ModifyHierarchy1.png"); | 1107 test_data_directory().AppendASCII("ModifyHierarchy1.png"); |
1114 base::FilePath ref_img2 = | 1108 base::FilePath ref_img2 = |
1115 test_data_directory().AppendASCII("ModifyHierarchy2.png"); | 1109 test_data_directory().AppendASCII("ModifyHierarchy2.png"); |
1116 SkBitmap bitmap; | 1110 SkBitmap bitmap; |
1117 | 1111 |
1118 l0->Add(l11.get()); | 1112 l0->Add(l11.get()); |
1119 l11->Add(l21.get()); | 1113 l11->Add(l21.get()); |
1120 l0->Add(l12.get()); | 1114 l0->Add(l12.get()); |
1121 DrawTree(l0.get()); | 1115 DrawTree(l0.get()); |
1122 ASSERT_TRUE(ReadPixels(&bitmap)); | 1116 ReadPixels(&bitmap); |
1123 ASSERT_FALSE(bitmap.empty()); | 1117 ASSERT_FALSE(bitmap.empty()); |
1124 // WritePNGFile(bitmap, ref_img1); | 1118 // WritePNGFile(bitmap, ref_img1); |
1125 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); | 1119 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); |
1126 | 1120 |
1127 l0->StackAtTop(l11.get()); | 1121 l0->StackAtTop(l11.get()); |
1128 DrawTree(l0.get()); | 1122 DrawTree(l0.get()); |
1129 ASSERT_TRUE(ReadPixels(&bitmap)); | 1123 ReadPixels(&bitmap); |
1130 ASSERT_FALSE(bitmap.empty()); | 1124 ASSERT_FALSE(bitmap.empty()); |
1131 // WritePNGFile(bitmap, ref_img2); | 1125 // WritePNGFile(bitmap, ref_img2); |
1132 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); | 1126 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); |
1133 | 1127 |
1134 // should restore to original configuration | 1128 // should restore to original configuration |
1135 l0->StackAbove(l12.get(), l11.get()); | 1129 l0->StackAbove(l12.get(), l11.get()); |
1136 DrawTree(l0.get()); | 1130 DrawTree(l0.get()); |
1137 ASSERT_TRUE(ReadPixels(&bitmap)); | 1131 ReadPixels(&bitmap); |
1138 ASSERT_FALSE(bitmap.empty()); | 1132 ASSERT_FALSE(bitmap.empty()); |
1139 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); | 1133 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); |
1140 | 1134 |
1141 // l11 back to front | 1135 // l11 back to front |
1142 l0->StackAtTop(l11.get()); | 1136 l0->StackAtTop(l11.get()); |
1143 DrawTree(l0.get()); | 1137 DrawTree(l0.get()); |
1144 ASSERT_TRUE(ReadPixels(&bitmap)); | 1138 ReadPixels(&bitmap); |
1145 ASSERT_FALSE(bitmap.empty()); | 1139 ASSERT_FALSE(bitmap.empty()); |
1146 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); | 1140 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); |
1147 | 1141 |
1148 // should restore to original configuration | 1142 // should restore to original configuration |
1149 l0->StackAbove(l12.get(), l11.get()); | 1143 l0->StackAbove(l12.get(), l11.get()); |
1150 DrawTree(l0.get()); | 1144 DrawTree(l0.get()); |
1151 ASSERT_TRUE(ReadPixels(&bitmap)); | 1145 ReadPixels(&bitmap); |
1152 ASSERT_FALSE(bitmap.empty()); | 1146 ASSERT_FALSE(bitmap.empty()); |
1153 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); | 1147 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); |
1154 | 1148 |
1155 // l11 back to front | 1149 // l11 back to front |
1156 l0->StackAbove(l11.get(), l12.get()); | 1150 l0->StackAbove(l11.get(), l12.get()); |
1157 DrawTree(l0.get()); | 1151 DrawTree(l0.get()); |
1158 ASSERT_TRUE(ReadPixels(&bitmap)); | 1152 ReadPixels(&bitmap); |
1159 ASSERT_FALSE(bitmap.empty()); | 1153 ASSERT_FALSE(bitmap.empty()); |
1160 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); | 1154 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); |
1161 } | 1155 } |
1162 | 1156 |
1163 // Opacity is rendered correctly. | 1157 // Opacity is rendered correctly. |
1164 // Checks that modifying the hierarchy correctly affects final composite. | 1158 // Checks that modifying the hierarchy correctly affects final composite. |
1165 TEST_F(LayerWithRealCompositorTest, Opacity) { | 1159 TEST_F(LayerWithRealCompositorTest, Opacity) { |
1166 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50)); | 1160 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50)); |
1167 | 1161 |
1168 // l0 | 1162 // l0 |
1169 // +-l11 | 1163 // +-l11 |
1170 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED, | 1164 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED, |
1171 gfx::Rect(0, 0, 50, 50))); | 1165 gfx::Rect(0, 0, 50, 50))); |
1172 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN, | 1166 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN, |
1173 gfx::Rect(0, 0, 25, 25))); | 1167 gfx::Rect(0, 0, 25, 25))); |
1174 | 1168 |
1175 base::FilePath ref_img = test_data_directory().AppendASCII("Opacity.png"); | 1169 base::FilePath ref_img = test_data_directory().AppendASCII("Opacity.png"); |
1176 | 1170 |
1177 l11->SetOpacity(0.75); | 1171 l11->SetOpacity(0.75); |
1178 l0->Add(l11.get()); | 1172 l0->Add(l11.get()); |
1179 DrawTree(l0.get()); | 1173 DrawTree(l0.get()); |
1180 SkBitmap bitmap; | 1174 SkBitmap bitmap; |
1181 ASSERT_TRUE(ReadPixels(&bitmap)); | 1175 ReadPixels(&bitmap); |
1182 ASSERT_FALSE(bitmap.empty()); | 1176 ASSERT_FALSE(bitmap.empty()); |
1183 // WritePNGFile(bitmap, ref_img); | 1177 // WritePNGFile(bitmap, ref_img); |
1184 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img, cc::ExactPixelComparator(true))); | 1178 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img, cc::ExactPixelComparator(true))); |
1185 } | 1179 } |
1186 | 1180 |
1187 namespace { | 1181 namespace { |
1188 | 1182 |
1189 class SchedulePaintLayerDelegate : public LayerDelegate { | 1183 class SchedulePaintLayerDelegate : public LayerDelegate { |
1190 public: | 1184 public: |
1191 SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL) {} | 1185 SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL) {} |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1732 MakeFrameData(gfx::Size(10, 10)))); | 1726 MakeFrameData(gfx::Size(10, 10)))); |
1733 layer->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10)); | 1727 layer->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10)); |
1734 | 1728 |
1735 EXPECT_FALSE(delegate.delegated_frame_damage_called()); | 1729 EXPECT_FALSE(delegate.delegated_frame_damage_called()); |
1736 layer->OnDelegatedFrameDamage(damage_rect); | 1730 layer->OnDelegatedFrameDamage(damage_rect); |
1737 EXPECT_TRUE(delegate.delegated_frame_damage_called()); | 1731 EXPECT_TRUE(delegate.delegated_frame_damage_called()); |
1738 EXPECT_EQ(damage_rect, delegate.delegated_frame_damage_rect()); | 1732 EXPECT_EQ(damage_rect, delegate.delegated_frame_damage_rect()); |
1739 } | 1733 } |
1740 | 1734 |
1741 } // namespace ui | 1735 } // namespace ui |
OLD | NEW |