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 <stdio.h> | 5 #include <stdio.h> |
6 #include <cmath> | 6 #include <cmath> |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include <GLES2/gl2.h> | 10 #include <GLES2/gl2.h> |
11 #include <GLES2/gl2ext.h> | 11 #include <GLES2/gl2ext.h> |
12 #include <GLES2/gl2extchromium.h> | 12 #include <GLES2/gl2extchromium.h> |
13 | 13 |
14 #include "base/at_exit.h" | 14 #include "base/at_exit.h" |
15 #include "base/bind.h" | 15 #include "base/bind.h" |
16 #include "base/command_line.h" | 16 #include "base/command_line.h" |
| 17 #include "base/debug/trace_event.h" |
17 #include "base/file_util.h" | 18 #include "base/file_util.h" |
| 19 #include "base/json/json_reader.h" |
18 #include "base/message_loop/message_loop.h" | 20 #include "base/message_loop/message_loop.h" |
19 #include "base/run_loop.h" | 21 #include "base/run_loop.h" |
20 #include "base/strings/stringprintf.h" | 22 #include "base/strings/stringprintf.h" |
| 23 #include "base/synchronization/waitable_event.h" |
21 #include "base/time/time.h" | 24 #include "base/time/time.h" |
22 #include "content/common/gpu/client/gl_helper.h" | 25 #include "content/common/gpu/client/gl_helper.h" |
23 #include "content/common/gpu/client/gl_helper_scaling.h" | 26 #include "content/common/gpu/client/gl_helper_scaling.h" |
24 #include "content/public/test/unittest_test_suite.h" | 27 #include "content/public/test/unittest_test_suite.h" |
25 #include "content/test/content_test_suite.h" | 28 #include "content/test/content_test_suite.h" |
26 #include "gpu/config/gpu_util.h" | 29 #include "gpu/config/gpu_util.h" |
27 #include "media/base/video_frame.h" | 30 #include "media/base/video_frame.h" |
28 #include "testing/gtest/include/gtest/gtest.h" | 31 #include "testing/gtest/include/gtest/gtest.h" |
29 #include "third_party/skia/include/core/SkBitmap.h" | 32 #include "third_party/skia/include/core/SkBitmap.h" |
30 #include "third_party/skia/include/core/SkTypes.h" | 33 #include "third_party/skia/include/core/SkTypes.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 context_.get(), | 73 context_.get(), |
71 helper_.get())); | 74 helper_.get())); |
72 } | 75 } |
73 | 76 |
74 virtual void TearDown() { | 77 virtual void TearDown() { |
75 helper_scaling_.reset(NULL); | 78 helper_scaling_.reset(NULL); |
76 helper_.reset(NULL); | 79 helper_.reset(NULL); |
77 context_.reset(NULL); | 80 context_.reset(NULL); |
78 } | 81 } |
79 | 82 |
| 83 void StartTracing(const std::string& filter) { |
| 84 base::debug::TraceLog::GetInstance()->SetEnabled( |
| 85 base::debug::CategoryFilter(filter), |
| 86 base::debug::TraceLog::RECORD_UNTIL_FULL); |
| 87 } |
| 88 |
| 89 static void TraceDataCB( |
| 90 const base::Callback<void()>& callback, |
| 91 std::string* output, |
| 92 const scoped_refptr<base::RefCountedString>& json_events_str, |
| 93 bool has_more_events) { |
| 94 if (output->size() > 1) { |
| 95 output->append(","); |
| 96 } |
| 97 output->append(json_events_str->data()); |
| 98 if (!has_more_events) { |
| 99 callback.Run(); |
| 100 } |
| 101 } |
| 102 |
| 103 // End tracing, return tracing data in a simple map |
| 104 // of event name->counts. |
| 105 void EndTracing(std::map<std::string, int> *event_counts) { |
| 106 std::string json_data = "["; |
| 107 base::debug::TraceLog::GetInstance()->SetDisabled(); |
| 108 base::RunLoop run_loop; |
| 109 base::debug::TraceLog::GetInstance()->Flush( |
| 110 base::Bind(&GLHelperTest::TraceDataCB, |
| 111 run_loop.QuitClosure(), |
| 112 base::Unretained(&json_data))); |
| 113 run_loop.Run(); |
| 114 json_data.append("]"); |
| 115 |
| 116 scoped_ptr<Value> trace_data(base::JSONReader::Read(json_data)); |
| 117 ListValue* list; |
| 118 CHECK(trace_data->GetAsList(&list)); |
| 119 for (size_t i = 0; i < list->GetSize(); i++) { |
| 120 base::Value *item = NULL; |
| 121 if (list->Get(i, &item)) { |
| 122 base::DictionaryValue *dict; |
| 123 CHECK(item->GetAsDictionary(&dict)); |
| 124 std::string name; |
| 125 CHECK(dict->GetString("name", &name)); |
| 126 (*event_counts)[name]++; |
| 127 VLOG(1) << "trace name: " << name; |
| 128 } |
| 129 } |
| 130 } |
| 131 |
80 // Bicubic filter kernel function. | 132 // Bicubic filter kernel function. |
81 static float Bicubic(float x) { | 133 static float Bicubic(float x) { |
82 const float a = -0.5; | 134 const float a = -0.5; |
83 x = std::abs(x); | 135 x = std::abs(x); |
84 float x2 = x * x; | 136 float x2 = x * x; |
85 float x3 = x2 * x; | 137 float x3 = x2 * x; |
86 if (x <= 1) { | 138 if (x <= 1) { |
87 return (a + 2) * x3 - (a + 3) * x2 + 1; | 139 return (a + 2) * x3 - (a + 3) * x2 + 1; |
88 } else if (x < 2) { | 140 } else if (x < 2) { |
89 return a * x3 - 5 * a * x2 + 8 * a * x - 4 * a; | 141 return a * x3 - 5 * a * x2 + 8 * a * x - 4 * a; |
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 // with reference implementation and compare to what gl_helper | 840 // with reference implementation and compare to what gl_helper |
789 // returns. | 841 // returns. |
790 void TestYUVReadback(int xsize, | 842 void TestYUVReadback(int xsize, |
791 int ysize, | 843 int ysize, |
792 int output_xsize, | 844 int output_xsize, |
793 int output_ysize, | 845 int output_ysize, |
794 int xmargin, | 846 int xmargin, |
795 int ymargin, | 847 int ymargin, |
796 int test_pattern, | 848 int test_pattern, |
797 bool flip, | 849 bool flip, |
798 bool use_mrt) { | 850 bool use_mrt, |
| 851 content::GLHelper::ScalerQuality quality) { |
799 WebGLId src_texture = context_->createTexture(); | 852 WebGLId src_texture = context_->createTexture(); |
800 SkBitmap input_pixels; | 853 SkBitmap input_pixels; |
801 input_pixels.setConfig(SkBitmap::kARGB_8888_Config, xsize, ysize); | 854 input_pixels.setConfig(SkBitmap::kARGB_8888_Config, xsize, ysize); |
802 input_pixels.allocPixels(); | 855 input_pixels.allocPixels(); |
803 SkAutoLockPixels lock(input_pixels); | 856 SkAutoLockPixels lock(input_pixels); |
804 | 857 |
805 for (int x = 0; x < xsize; ++x) { | 858 for (int x = 0; x < xsize; ++x) { |
806 for (int y = 0; y < ysize; ++y) { | 859 for (int y = 0; y < ysize; ++y) { |
807 switch (test_pattern) { | 860 switch (test_pattern) { |
808 case 0: // Smooth test pattern | 861 case 0: // Smooth test pattern |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 "margin: %dx%d " | 902 "margin: %dx%d " |
850 "pattern: %d %s %s", | 903 "pattern: %d %s %s", |
851 xsize, ysize, | 904 xsize, ysize, |
852 output_xsize, output_ysize, | 905 output_xsize, output_ysize, |
853 xmargin, ymargin, | 906 xmargin, ymargin, |
854 test_pattern, | 907 test_pattern, |
855 flip ? "flip" : "noflip", | 908 flip ? "flip" : "noflip", |
856 flip ? "mrt" : "nomrt"); | 909 flip ? "mrt" : "nomrt"); |
857 scoped_ptr<ReadbackYUVInterface> yuv_reader( | 910 scoped_ptr<ReadbackYUVInterface> yuv_reader( |
858 helper_->CreateReadbackPipelineYUV( | 911 helper_->CreateReadbackPipelineYUV( |
859 content::GLHelper::SCALER_QUALITY_GOOD, | 912 quality, |
860 gfx::Size(xsize, ysize), | 913 gfx::Size(xsize, ysize), |
861 gfx::Rect(0, 0, xsize, ysize), | 914 gfx::Rect(0, 0, xsize, ysize), |
862 gfx::Size(output_xsize, output_ysize), | 915 gfx::Size(output_xsize, output_ysize), |
863 gfx::Rect(xmargin, ymargin, xsize, ysize), | 916 gfx::Rect(xmargin, ymargin, xsize, ysize), |
864 flip, | 917 flip, |
865 use_mrt)); | 918 use_mrt)); |
866 | 919 |
867 scoped_refptr<media::VideoFrame> output_frame = | 920 scoped_refptr<media::VideoFrame> output_frame = |
868 media::VideoFrame::CreateFrame( | 921 media::VideoFrame::CreateFrame( |
869 media::VideoFrame::YV12, | 922 media::VideoFrame::YV12, |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1144 "8x1 -> 1x1 bilinear4 X\n"); | 1197 "8x1 -> 1x1 bilinear4 X\n"); |
1145 } | 1198 } |
1146 | 1199 |
1147 scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> context_; | 1200 scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> context_; |
1148 gpu::ContextSupport* context_support_; | 1201 gpu::ContextSupport* context_support_; |
1149 scoped_ptr<content::GLHelper> helper_; | 1202 scoped_ptr<content::GLHelper> helper_; |
1150 scoped_ptr<content::GLHelperScaling> helper_scaling_; | 1203 scoped_ptr<content::GLHelperScaling> helper_scaling_; |
1151 std::deque<GLHelperScaling::ScaleOp> x_ops_, y_ops_; | 1204 std::deque<GLHelperScaling::ScaleOp> x_ops_, y_ops_; |
1152 }; | 1205 }; |
1153 | 1206 |
| 1207 TEST_F(GLHelperTest, YUVReadbackOptTest) { |
| 1208 // This test uses the cb_command tracing events to detect how many |
| 1209 // scaling passes are actually performed by the YUV readback pipeline. |
| 1210 StartTracing(TRACE_DISABLED_BY_DEFAULT("cb_command")); |
| 1211 |
| 1212 TestYUVReadback( |
| 1213 800, 400, |
| 1214 800, 400, |
| 1215 0, 0, |
| 1216 1, |
| 1217 false, |
| 1218 true, |
| 1219 content::GLHelper::SCALER_QUALITY_FAST); |
| 1220 |
| 1221 std::map<std::string, int> event_counts; |
| 1222 EndTracing(&event_counts); |
| 1223 int draw_buffer_calls = event_counts["kDrawBuffersEXTImmediate"]; |
| 1224 int draw_arrays_calls = event_counts["kDrawArrays"]; |
| 1225 VLOG(1) << "Draw buffer calls: " << draw_buffer_calls; |
| 1226 VLOG(1) << "DrawArrays calls: " << draw_arrays_calls; |
| 1227 |
| 1228 if (draw_buffer_calls) { |
| 1229 // When using MRT, the YUV readback code should only |
| 1230 // execute two draw arrays, and scaling should be integrated |
| 1231 // into those two calls since we are using the FAST scalign |
| 1232 // quality. |
| 1233 EXPECT_EQ(2, draw_arrays_calls); |
| 1234 } else { |
| 1235 // When not using MRT, there are three passes for the YUV, |
| 1236 // and one for the scaling. |
| 1237 EXPECT_EQ(4, draw_arrays_calls); |
| 1238 } |
| 1239 } |
| 1240 |
1154 TEST_F(GLHelperTest, YUVReadbackTest) { | 1241 TEST_F(GLHelperTest, YUVReadbackTest) { |
1155 int sizes[] = { 2, 4, 14 }; | 1242 int sizes[] = { 2, 4, 14 }; |
1156 for (int flip = 0; flip <= 1; flip++) { | 1243 for (int flip = 0; flip <= 1; flip++) { |
1157 for (int use_mrt = 0; use_mrt <= 1; use_mrt++) { | 1244 for (int use_mrt = 0; use_mrt <= 1; use_mrt++) { |
1158 for (unsigned int x = 0; x < arraysize(sizes); x++) { | 1245 for (unsigned int x = 0; x < arraysize(sizes); x++) { |
1159 for (unsigned int y = 0; y < arraysize(sizes); y++) { | 1246 for (unsigned int y = 0; y < arraysize(sizes); y++) { |
1160 for (unsigned int ox = x; ox < arraysize(sizes); ox++) { | 1247 for (unsigned int ox = x; ox < arraysize(sizes); ox++) { |
1161 for (unsigned int oy = y; oy < arraysize(sizes); oy++) { | 1248 for (unsigned int oy = y; oy < arraysize(sizes); oy++) { |
1162 // If output is a subsection of the destination frame, (letterbox) | 1249 // If output is a subsection of the destination frame, (letterbox) |
1163 // then try different variations of where the subsection goes. | 1250 // then try different variations of where the subsection goes. |
1164 for (Margin xm = x < ox ? MarginLeft : MarginRight; | 1251 for (Margin xm = x < ox ? MarginLeft : MarginRight; |
1165 xm <= MarginRight; | 1252 xm <= MarginRight; |
1166 xm = NextMargin(xm)) { | 1253 xm = NextMargin(xm)) { |
1167 for (Margin ym = y < oy ? MarginLeft : MarginRight; | 1254 for (Margin ym = y < oy ? MarginLeft : MarginRight; |
1168 ym <= MarginRight; | 1255 ym <= MarginRight; |
1169 ym = NextMargin(ym)) { | 1256 ym = NextMargin(ym)) { |
1170 for (int pattern = 0; pattern < 3; pattern++) { | 1257 for (int pattern = 0; pattern < 3; pattern++) { |
1171 TestYUVReadback( | 1258 TestYUVReadback( |
1172 sizes[x], | 1259 sizes[x], |
1173 sizes[y], | 1260 sizes[y], |
1174 sizes[ox], | 1261 sizes[ox], |
1175 sizes[oy], | 1262 sizes[oy], |
1176 compute_margin(sizes[x], sizes[ox], xm), | 1263 compute_margin(sizes[x], sizes[ox], xm), |
1177 compute_margin(sizes[y], sizes[oy], ym), | 1264 compute_margin(sizes[y], sizes[oy], ym), |
1178 pattern, | 1265 pattern, |
1179 flip == 1, | 1266 flip == 1, |
1180 use_mrt == 1); | 1267 use_mrt == 1, |
| 1268 content::GLHelper::SCALER_QUALITY_GOOD); |
1181 if (HasFailure()) { | 1269 if (HasFailure()) { |
1182 return; | 1270 return; |
1183 } | 1271 } |
1184 } | 1272 } |
1185 } | 1273 } |
1186 } | 1274 } |
1187 } | 1275 } |
1188 } | 1276 } |
1189 } | 1277 } |
1190 } | 1278 } |
1191 } | 1279 } |
1192 } | 1280 } |
1193 } | 1281 } |
1194 | 1282 |
1195 | |
1196 // Per pixel tests, all sizes are small so that we can print | 1283 // Per pixel tests, all sizes are small so that we can print |
1197 // out the generated bitmaps. | 1284 // out the generated bitmaps. |
1198 TEST_F(GLHelperTest, ScaleTest) { | 1285 TEST_F(GLHelperTest, ScaleTest) { |
1199 int sizes[] = {3, 6, 16}; | 1286 int sizes[] = {3, 6, 16}; |
1200 for (int flip = 0; flip <= 1; flip++) { | 1287 for (int flip = 0; flip <= 1; flip++) { |
1201 for (size_t q = 0; q < arraysize(kQualities); q++) { | 1288 for (size_t q = 0; q < arraysize(kQualities); q++) { |
1202 for (int x = 0; x < 3; x++) { | 1289 for (int x = 0; x < 3; x++) { |
1203 for (int y = 0; y < 3; y++) { | 1290 for (int y = 0; y < 3; y++) { |
1204 for (int dst_x = 0; dst_x < 3; dst_x++) { | 1291 for (int dst_x = 0; dst_x < 3; dst_x++) { |
1205 for (int dst_y = 0; dst_y < 3; dst_y++) { | 1292 for (int dst_y = 0; dst_y < 3; dst_y++) { |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1297 #if defined(TOOLKIT_GTK) | 1384 #if defined(TOOLKIT_GTK) |
1298 gfx::GtkInitFromCommandLine(*CommandLine::ForCurrentProcess()); | 1385 gfx::GtkInitFromCommandLine(*CommandLine::ForCurrentProcess()); |
1299 #endif | 1386 #endif |
1300 gfx::GLSurface::InitializeOneOff(); | 1387 gfx::GLSurface::InitializeOneOff(); |
1301 gpu::ApplyGpuDriverBugWorkarounds(CommandLine::ForCurrentProcess()); | 1388 gpu::ApplyGpuDriverBugWorkarounds(CommandLine::ForCurrentProcess()); |
1302 | 1389 |
1303 content::UnitTestTestSuite runner(suite); | 1390 content::UnitTestTestSuite runner(suite); |
1304 base::MessageLoop message_loop; | 1391 base::MessageLoop message_loop; |
1305 return runner.Run(); | 1392 return runner.Run(); |
1306 } | 1393 } |
OLD | NEW |