Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: ui/compositor/layer_unittest.cc

Issue 587863002: Use RunLoop to wait for readback on compositor unittest (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@compositorScheduler
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 return ReadPixels(bitmap, gfx::Rect(GetCompositor()->size()));
danakj 2014/09/19 20:52:26 remove return
weiliangc 2014/09/19 21:02:46 Done.
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_); 190 DCHECK(run_loop_->running());
danakj 2014/09/19 20:52:26 what if the result comes before the wait starts, t
weiliangc 2014/09/19 21:02:46 Make sense. Removed.
197 result_ = result->TakeBitmap(); 191 result_ = result->TakeBitmap();
198 completed_ = true; 192 base::MessageLoop::current()->PostTask(FROM_HERE,
193 run_loop_->QuitClosure());
199 } 194 }
200 bool completed() const { 195
201 return completed_; 196 void WaitForReadback() { run_loop_->Run(); }
danakj 2014/09/19 20:52:26 can you verify that Run() will exit if you called
weiliangc 2014/09/19 21:02:46 RunLoop's comment on its Quit and QuitClose functi
202 }; 197
203 const SkBitmap& result() const { return *result_; } 198 const SkBitmap& result() const { return *result_; }
204 199
205 private: 200 private:
206 friend class base::RefCountedThreadSafe<ReadbackHolder>; 201 friend class base::RefCountedThreadSafe<ReadbackHolder>;
207 202
208 virtual ~ReadbackHolder() {} 203 virtual ~ReadbackHolder() {}
209 204
210 scoped_ptr<SkBitmap> result_; 205 scoped_ptr<SkBitmap> result_;
211 bool completed_; 206 scoped_ptr<base::RunLoop> run_loop_;
212 }; 207 };
213 208
214 scoped_ptr<TestCompositorHost> compositor_host_; 209 scoped_ptr<TestCompositorHost> compositor_host_;
215 210
216 // The root directory for test files. 211 // The root directory for test files.
217 base::FilePath test_data_directory_; 212 base::FilePath test_data_directory_;
218 213
219 DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest); 214 DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest);
220 }; 215 };
221 216
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size))); 882 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size)));
888 scoped_ptr<Layer> layer2( 883 scoped_ptr<Layer> layer2(
889 CreateColorLayer(SK_ColorBLUE, 884 CreateColorLayer(SK_ColorBLUE,
890 gfx::Rect(0, 0, viewport_size.width(), blue_height))); 885 gfx::Rect(0, 0, viewport_size.width(), blue_height)));
891 886
892 layer->Add(layer2.get()); 887 layer->Add(layer2.get());
893 888
894 DrawTree(layer.get()); 889 DrawTree(layer.get());
895 890
896 SkBitmap bitmap; 891 SkBitmap bitmap;
897 ASSERT_TRUE(ReadPixels(&bitmap, gfx::Rect(viewport_size))); 892 ReadPixels(&bitmap, gfx::Rect(viewport_size));
898 ASSERT_FALSE(bitmap.empty()); 893 ASSERT_FALSE(bitmap.empty());
899 894
900 SkAutoLockPixels lock(bitmap); 895 SkAutoLockPixels lock(bitmap);
901 for (int x = 0; x < viewport_size.width(); x++) { 896 for (int x = 0; x < viewport_size.width(); x++) {
902 for (int y = 0; y < viewport_size.height(); y++) { 897 for (int y = 0; y < viewport_size.height(); y++) {
903 SkColor actual_color = bitmap.getColor(x, y); 898 SkColor actual_color = bitmap.getColor(x, y);
904 SkColor expected_color = y < blue_height ? SK_ColorBLUE : SK_ColorRED; 899 SkColor expected_color = y < blue_height ? SK_ColorBLUE : SK_ColorRED;
905 ExpectRgba(x, y, expected_color, actual_color); 900 ExpectRgba(x, y, expected_color, actual_color);
906 } 901 }
907 } 902 }
(...skipping 17 matching lines...) Expand all
925 scoped_ptr<Layer> foreground_layer( 920 scoped_ptr<Layer> foreground_layer(
926 CreateColorLayer(blue_with_alpha, gfx::Rect(viewport_size))); 921 CreateColorLayer(blue_with_alpha, gfx::Rect(viewport_size)));
927 922
928 // This must be set to false for layers with alpha to be blended correctly. 923 // This must be set to false for layers with alpha to be blended correctly.
929 foreground_layer->SetFillsBoundsOpaquely(false); 924 foreground_layer->SetFillsBoundsOpaquely(false);
930 925
931 background_layer->Add(foreground_layer.get()); 926 background_layer->Add(foreground_layer.get());
932 DrawTree(background_layer.get()); 927 DrawTree(background_layer.get());
933 928
934 SkBitmap bitmap; 929 SkBitmap bitmap;
935 ASSERT_TRUE(ReadPixels(&bitmap, gfx::Rect(viewport_size))); 930 ReadPixels(&bitmap, gfx::Rect(viewport_size));
936 ASSERT_FALSE(bitmap.empty()); 931 ASSERT_FALSE(bitmap.empty());
937 932
938 SkAutoLockPixels lock(bitmap); 933 SkAutoLockPixels lock(bitmap);
939 for (int x = 0; x < test_size; x++) { 934 for (int x = 0; x < test_size; x++) {
940 for (int y = 0; y < test_size; y++) { 935 for (int y = 0; y < test_size; y++) {
941 SkColor actual_color = bitmap.getColor(x, y); 936 SkColor actual_color = bitmap.getColor(x, y);
942 ExpectRgba(x, y, blend_color, actual_color); 937 ExpectRgba(x, y, blend_color, actual_color);
943 } 938 }
944 } 939 }
945 } 940 }
(...skipping 20 matching lines...) Expand all
966 SkRegion shape; 961 SkRegion shape;
967 shape.setRect(0, 0, viewport_size.width(), blue_height); 962 shape.setRect(0, 0, viewport_size.width(), blue_height);
968 foreground_layer->SetAlphaShape(make_scoped_ptr(new SkRegion(shape))); 963 foreground_layer->SetAlphaShape(make_scoped_ptr(new SkRegion(shape)));
969 964
970 foreground_layer->SetFillsBoundsOpaquely(false); 965 foreground_layer->SetFillsBoundsOpaquely(false);
971 966
972 background_layer->Add(foreground_layer.get()); 967 background_layer->Add(foreground_layer.get());
973 DrawTree(background_layer.get()); 968 DrawTree(background_layer.get());
974 969
975 SkBitmap bitmap; 970 SkBitmap bitmap;
976 ASSERT_TRUE(ReadPixels(&bitmap, gfx::Rect(viewport_size))); 971 ReadPixels(&bitmap, gfx::Rect(viewport_size));
977 ASSERT_FALSE(bitmap.empty()); 972 ASSERT_FALSE(bitmap.empty());
978 973
979 SkAutoLockPixels lock(bitmap); 974 SkAutoLockPixels lock(bitmap);
980 for (int x = 0; x < test_size; x++) { 975 for (int x = 0; x < test_size; x++) {
981 for (int y = 0; y < test_size; y++) { 976 for (int y = 0; y < test_size; y++) {
982 SkColor actual_color = bitmap.getColor(x, y); 977 SkColor actual_color = bitmap.getColor(x, y);
983 ExpectRgba(x, y, actual_color, 978 ExpectRgba(x, y, actual_color,
984 y < blue_height ? blend_color : SK_ColorRED); 979 y < blue_height ? blend_color : SK_ColorRED);
985 } 980 }
986 } 981 }
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 base::FilePath ref_img1 = 1107 base::FilePath ref_img1 =
1113 test_data_directory().AppendASCII("ModifyHierarchy1.png"); 1108 test_data_directory().AppendASCII("ModifyHierarchy1.png");
1114 base::FilePath ref_img2 = 1109 base::FilePath ref_img2 =
1115 test_data_directory().AppendASCII("ModifyHierarchy2.png"); 1110 test_data_directory().AppendASCII("ModifyHierarchy2.png");
1116 SkBitmap bitmap; 1111 SkBitmap bitmap;
1117 1112
1118 l0->Add(l11.get()); 1113 l0->Add(l11.get());
1119 l11->Add(l21.get()); 1114 l11->Add(l21.get());
1120 l0->Add(l12.get()); 1115 l0->Add(l12.get());
1121 DrawTree(l0.get()); 1116 DrawTree(l0.get());
1122 ASSERT_TRUE(ReadPixels(&bitmap)); 1117 ReadPixels(&bitmap);
1123 ASSERT_FALSE(bitmap.empty()); 1118 ASSERT_FALSE(bitmap.empty());
1124 // WritePNGFile(bitmap, ref_img1); 1119 // WritePNGFile(bitmap, ref_img1);
1125 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); 1120 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1126 1121
1127 l0->StackAtTop(l11.get()); 1122 l0->StackAtTop(l11.get());
1128 DrawTree(l0.get()); 1123 DrawTree(l0.get());
1129 ASSERT_TRUE(ReadPixels(&bitmap)); 1124 ReadPixels(&bitmap);
1130 ASSERT_FALSE(bitmap.empty()); 1125 ASSERT_FALSE(bitmap.empty());
1131 // WritePNGFile(bitmap, ref_img2); 1126 // WritePNGFile(bitmap, ref_img2);
1132 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); 1127 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1133 1128
1134 // should restore to original configuration 1129 // should restore to original configuration
1135 l0->StackAbove(l12.get(), l11.get()); 1130 l0->StackAbove(l12.get(), l11.get());
1136 DrawTree(l0.get()); 1131 DrawTree(l0.get());
1137 ASSERT_TRUE(ReadPixels(&bitmap)); 1132 ReadPixels(&bitmap);
1138 ASSERT_FALSE(bitmap.empty()); 1133 ASSERT_FALSE(bitmap.empty());
1139 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); 1134 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1140 1135
1141 // l11 back to front 1136 // l11 back to front
1142 l0->StackAtTop(l11.get()); 1137 l0->StackAtTop(l11.get());
1143 DrawTree(l0.get()); 1138 DrawTree(l0.get());
1144 ASSERT_TRUE(ReadPixels(&bitmap)); 1139 ReadPixels(&bitmap);
1145 ASSERT_FALSE(bitmap.empty()); 1140 ASSERT_FALSE(bitmap.empty());
1146 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); 1141 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1147 1142
1148 // should restore to original configuration 1143 // should restore to original configuration
1149 l0->StackAbove(l12.get(), l11.get()); 1144 l0->StackAbove(l12.get(), l11.get());
1150 DrawTree(l0.get()); 1145 DrawTree(l0.get());
1151 ASSERT_TRUE(ReadPixels(&bitmap)); 1146 ReadPixels(&bitmap);
1152 ASSERT_FALSE(bitmap.empty()); 1147 ASSERT_FALSE(bitmap.empty());
1153 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); 1148 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
1154 1149
1155 // l11 back to front 1150 // l11 back to front
1156 l0->StackAbove(l11.get(), l12.get()); 1151 l0->StackAbove(l11.get(), l12.get());
1157 DrawTree(l0.get()); 1152 DrawTree(l0.get());
1158 ASSERT_TRUE(ReadPixels(&bitmap)); 1153 ReadPixels(&bitmap);
1159 ASSERT_FALSE(bitmap.empty()); 1154 ASSERT_FALSE(bitmap.empty());
1160 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); 1155 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
1161 } 1156 }
1162 1157
1163 // Opacity is rendered correctly. 1158 // Opacity is rendered correctly.
1164 // Checks that modifying the hierarchy correctly affects final composite. 1159 // Checks that modifying the hierarchy correctly affects final composite.
1165 TEST_F(LayerWithRealCompositorTest, Opacity) { 1160 TEST_F(LayerWithRealCompositorTest, Opacity) {
1166 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50)); 1161 GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(50, 50));
1167 1162
1168 // l0 1163 // l0
1169 // +-l11 1164 // +-l11
1170 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED, 1165 scoped_ptr<Layer> l0(CreateColorLayer(SK_ColorRED,
1171 gfx::Rect(0, 0, 50, 50))); 1166 gfx::Rect(0, 0, 50, 50)));
1172 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN, 1167 scoped_ptr<Layer> l11(CreateColorLayer(SK_ColorGREEN,
1173 gfx::Rect(0, 0, 25, 25))); 1168 gfx::Rect(0, 0, 25, 25)));
1174 1169
1175 base::FilePath ref_img = test_data_directory().AppendASCII("Opacity.png"); 1170 base::FilePath ref_img = test_data_directory().AppendASCII("Opacity.png");
1176 1171
1177 l11->SetOpacity(0.75); 1172 l11->SetOpacity(0.75);
1178 l0->Add(l11.get()); 1173 l0->Add(l11.get());
1179 DrawTree(l0.get()); 1174 DrawTree(l0.get());
1180 SkBitmap bitmap; 1175 SkBitmap bitmap;
1181 ASSERT_TRUE(ReadPixels(&bitmap)); 1176 ReadPixels(&bitmap);
1182 ASSERT_FALSE(bitmap.empty()); 1177 ASSERT_FALSE(bitmap.empty());
1183 // WritePNGFile(bitmap, ref_img); 1178 // WritePNGFile(bitmap, ref_img);
1184 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img, cc::ExactPixelComparator(true))); 1179 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img, cc::ExactPixelComparator(true)));
1185 } 1180 }
1186 1181
1187 namespace { 1182 namespace {
1188 1183
1189 class SchedulePaintLayerDelegate : public LayerDelegate { 1184 class SchedulePaintLayerDelegate : public LayerDelegate {
1190 public: 1185 public:
1191 SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL) {} 1186 SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL) {}
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
1732 MakeFrameData(gfx::Size(10, 10)))); 1727 MakeFrameData(gfx::Size(10, 10))));
1733 layer->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10)); 1728 layer->SetShowDelegatedContent(frame_provider.get(), gfx::Size(10, 10));
1734 1729
1735 EXPECT_FALSE(delegate.delegated_frame_damage_called()); 1730 EXPECT_FALSE(delegate.delegated_frame_damage_called());
1736 layer->OnDelegatedFrameDamage(damage_rect); 1731 layer->OnDelegatedFrameDamage(damage_rect);
1737 EXPECT_TRUE(delegate.delegated_frame_damage_called()); 1732 EXPECT_TRUE(delegate.delegated_frame_damage_called());
1738 EXPECT_EQ(damage_rect, delegate.delegated_frame_damage_rect()); 1733 EXPECT_EQ(damage_rect, delegate.delegated_frame_damage_rect());
1739 } 1734 }
1740 1735
1741 } // namespace ui 1736 } // namespace ui
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698