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

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: address review comments 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 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
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
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
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
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
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
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