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

Side by Side Diff: content/browser/compositor/gl_helper_unittest.cc

Issue 1895443004: Pull YUV Readback tests out of gl_helper_unittest (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase + Cleanup Created 4 years, 8 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 | content/browser/compositor/yuv_readback_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 <stddef.h> 5 #include <stddef.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 #include <stdio.h> 7 #include <stdio.h>
8 #include <string.h> 8 #include <string.h>
9 #include <cmath> 9 #include <cmath>
10 #include <string> 10 #include <string>
(...skipping 16 matching lines...) Expand all
27 #include "base/synchronization/waitable_event.h" 27 #include "base/synchronization/waitable_event.h"
28 #include "base/test/launcher/unit_test_launcher.h" 28 #include "base/test/launcher/unit_test_launcher.h"
29 #include "base/test/test_suite.h" 29 #include "base/test/test_suite.h"
30 #include "base/time/time.h" 30 #include "base/time/time.h"
31 #include "base/trace_event/trace_event.h" 31 #include "base/trace_event/trace_event.h"
32 #include "content/browser/compositor/gl_helper.h" 32 #include "content/browser/compositor/gl_helper.h"
33 #include "content/browser/compositor/gl_helper_readback_support.h" 33 #include "content/browser/compositor/gl_helper_readback_support.h"
34 #include "content/browser/compositor/gl_helper_scaling.h" 34 #include "content/browser/compositor/gl_helper_scaling.h"
35 #include "gpu/command_buffer/client/gl_in_process_context.h" 35 #include "gpu/command_buffer/client/gl_in_process_context.h"
36 #include "gpu/command_buffer/client/gles2_implementation.h" 36 #include "gpu/command_buffer/client/gles2_implementation.h"
37 #include "media/base/video_frame.h"
38 #include "media/base/video_util.h"
39 #include "testing/gtest/include/gtest/gtest.h" 37 #include "testing/gtest/include/gtest/gtest.h"
40 #include "third_party/skia/include/core/SkBitmap.h" 38 #include "third_party/skia/include/core/SkBitmap.h"
41 #include "third_party/skia/include/core/SkTypes.h" 39 #include "third_party/skia/include/core/SkTypes.h"
42 #include "ui/gl/gl_implementation.h" 40 #include "ui/gl/gl_implementation.h"
43 41
44 namespace content { 42 namespace content {
45 43
46 content::GLHelper::ScalerQuality kQualities[] = { 44 content::GLHelper::ScalerQuality kQualities[] = {
47 content::GLHelper::SCALER_QUALITY_BEST, 45 content::GLHelper::SCALER_QUALITY_BEST,
48 content::GLHelper::SCALER_QUALITY_GOOD, 46 content::GLHelper::SCALER_QUALITY_GOOD,
(...skipping 30 matching lines...) Expand all
79 nullptr, /* gpu_memory_buffer_manager */ 77 nullptr, /* gpu_memory_buffer_manager */
80 nullptr /* image_factory */)); 78 nullptr /* image_factory */));
81 gl_ = context_->GetImplementation(); 79 gl_ = context_->GetImplementation();
82 gpu::ContextSupport* support = context_->GetImplementation(); 80 gpu::ContextSupport* support = context_->GetImplementation();
83 81
84 helper_.reset(new content::GLHelper(gl_, support)); 82 helper_.reset(new content::GLHelper(gl_, support));
85 helper_scaling_.reset(new content::GLHelperScaling(gl_, helper_.get())); 83 helper_scaling_.reset(new content::GLHelperScaling(gl_, helper_.get()));
86 } 84 }
87 85
88 void TearDown() override { 86 void TearDown() override {
89 helper_scaling_.reset(NULL); 87 helper_scaling_.reset(nullptr);
90 helper_.reset(NULL); 88 helper_.reset(nullptr);
91 context_.reset(NULL); 89 context_.reset(nullptr);
92 }
93
94 void StartTracing(const std::string& filter) {
95 base::trace_event::TraceLog::GetInstance()->SetEnabled(
96 base::trace_event::TraceConfig(filter,
97 base::trace_event::RECORD_UNTIL_FULL),
98 base::trace_event::TraceLog::RECORDING_MODE);
99 }
100
101 static void TraceDataCB(
102 const base::Callback<void()>& callback,
103 std::string* output,
104 const scoped_refptr<base::RefCountedString>& json_events_str,
105 bool has_more_events) {
106 if (output->size() > 1 && !json_events_str->data().empty()) {
107 output->append(",");
108 }
109 output->append(json_events_str->data());
110 if (!has_more_events) {
111 callback.Run();
112 }
113 }
114
115 // End tracing, return tracing data in a simple map
116 // of event name->counts.
117 void EndTracing(std::map<std::string, int>* event_counts) {
118 std::string json_data = "[";
119 base::trace_event::TraceLog::GetInstance()->SetDisabled();
120 base::RunLoop run_loop;
121 base::trace_event::TraceLog::GetInstance()->Flush(
122 base::Bind(&GLHelperTest::TraceDataCB, run_loop.QuitClosure(),
123 base::Unretained(&json_data)));
124 run_loop.Run();
125 json_data.append("]");
126
127 std::string error_msg;
128 std::unique_ptr<base::Value> trace_data =
129 base::JSONReader::ReadAndReturnError(json_data, 0, NULL, &error_msg);
130 CHECK(trace_data) << "JSON parsing failed (" << error_msg
131 << ") JSON data:" << std::endl
132 << json_data;
133
134 base::ListValue* list;
135 CHECK(trace_data->GetAsList(&list));
136 for (size_t i = 0; i < list->GetSize(); i++) {
137 base::Value* item = NULL;
138 if (list->Get(i, &item)) {
139 base::DictionaryValue* dict;
140 CHECK(item->GetAsDictionary(&dict));
141 std::string name;
142 CHECK(dict->GetString("name", &name));
143 std::string trace_type;
144 CHECK(dict->GetString("ph", &trace_type));
145 // Count all except END traces, as they come in BEGIN/END pairs.
146 if (trace_type != "E" && trace_type != "e")
147 (*event_counts)[name]++;
148 VLOG(1) << "trace name: " << name;
149 }
150 }
151 } 90 }
152 91
153 // Bicubic filter kernel function. 92 // Bicubic filter kernel function.
154 static float Bicubic(float x) { 93 static float Bicubic(float x) {
155 const float a = -0.5; 94 const float a = -0.5;
156 x = std::abs(x); 95 x = std::abs(x);
157 float x2 = x * x; 96 float x2 = x * x;
158 float x3 = x2 * x; 97 float x3 = x2 * x;
159 if (x <= 1) { 98 if (x <= 1) {
160 return (a + 2) * x3 - (a + 3) * x2 + 1; 99 return (a + 2) * x3 - (a + 3) * x2 + 1;
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 base::Bind(&callcallback, run_loop.QuitClosure()), 705 base::Bind(&callcallback, run_loop.QuitClosure()),
767 kQualities[quality_index]); 706 kQualities[quality_index]);
768 run_loop.Run(); 707 run_loop.Run();
769 // CropScaleReadbackAndCleanTexture flips the pixels. Flip them back. 708 // CropScaleReadbackAndCleanTexture flips the pixels. Flip them back.
770 FlipSKBitmap(&output_pixels); 709 FlipSKBitmap(&output_pixels);
771 710
772 // If the bitmap shouldn't have changed - compare against input. 711 // If the bitmap shouldn't have changed - compare against input.
773 if (xsize == scaled_xsize && ysize == scaled_ysize && 712 if (xsize == scaled_xsize && ysize == scaled_ysize &&
774 out_color_type != kAlpha_8_SkColorType) { 713 out_color_type != kAlpha_8_SkColorType) {
775 const std::vector<GLHelperScaling::ScalerStage> dummy_stages; 714 const std::vector<GLHelperScaling::ScalerStage> dummy_stages;
776 Compare(input_pixels.get(), &output_pixels, 0, NULL, dummy_stages, 715 Compare(input_pixels.get(), &output_pixels, 0, nullptr, dummy_stages,
777 message + " comparing against input"); 716 message + " comparing against input");
778 return; 717 return;
779 } 718 }
780 719
781 // Now transform the bitmap using the reference implementation. 720 // Now transform the bitmap using the reference implementation.
782 SkBitmap scaled_pixels; 721 SkBitmap scaled_pixels;
783 scaled_pixels.allocPixels(SkImageInfo::Make(scaled_xsize, scaled_ysize, 722 scaled_pixels.allocPixels(SkImageInfo::Make(scaled_xsize, scaled_ysize,
784 kRGBA_8888_SkColorType, 723 kRGBA_8888_SkColorType,
785 kPremul_SkAlphaType)); 724 kPremul_SkAlphaType));
786 SkBitmap truth_pixels; 725 SkBitmap truth_pixels;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 dst_texture, gfx::Rect(0, 0, scaled_xsize, scaled_ysize), 796 dst_texture, gfx::Rect(0, 0, scaled_xsize, scaled_ysize),
858 static_cast<unsigned char*>(output_pixels.getPixels()), 797 static_cast<unsigned char*>(output_pixels.getPixels()),
859 kRGBA_8888_SkColorType); 798 kRGBA_8888_SkColorType);
860 if (flip) { 799 if (flip) {
861 // Flip the pixels back. 800 // Flip the pixels back.
862 FlipSKBitmap(&output_pixels); 801 FlipSKBitmap(&output_pixels);
863 } 802 }
864 803
865 // If the bitmap shouldn't have changed - compare against input. 804 // If the bitmap shouldn't have changed - compare against input.
866 if (xsize == scaled_xsize && ysize == scaled_ysize) { 805 if (xsize == scaled_xsize && ysize == scaled_ysize) {
867 Compare(input_pixels.get(), &output_pixels, 0, NULL, stages, 806 Compare(input_pixels.get(), &output_pixels, 0, nullptr, stages,
868 message + " comparing against input"); 807 message + " comparing against input");
869 return; 808 return;
870 } 809 }
871 810
872 // Now scale the bitmap using the reference implementation. 811 // Now scale the bitmap using the reference implementation.
873 SkBitmap truth_pixels; 812 SkBitmap truth_pixels;
874 truth_pixels.allocPixels(SkImageInfo::Make(scaled_xsize, scaled_ysize, 813 truth_pixels.allocPixels(SkImageInfo::Make(scaled_xsize, scaled_ysize,
875 kRGBA_8888_SkColorType, 814 kRGBA_8888_SkColorType,
876 kPremul_SkAlphaType)); 815 kPremul_SkAlphaType));
877 ScaleSlowRecursive(input_pixels.get(), &truth_pixels, 816 ScaleSlowRecursive(input_pixels.get(), &truth_pixels,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 const std::string& description) { 854 const std::string& description) {
916 std::vector<GLHelperScaling::ScalerStage> stages; 855 std::vector<GLHelperScaling::ScalerStage> stages;
917 helper_scaling_->ComputeScalerStages( 856 helper_scaling_->ComputeScalerStages(
918 quality, gfx::Size(xsize, ysize), gfx::Rect(0, 0, xsize, ysize), 857 quality, gfx::Size(xsize, ysize), gfx::Rect(0, 0, xsize, ysize),
919 gfx::Size(dst_xsize, dst_ysize), false, false, &stages); 858 gfx::Size(dst_xsize, dst_ysize), false, false, &stages);
920 ValidateScalerStages(content::GLHelper::SCALER_QUALITY_GOOD, stages, 859 ValidateScalerStages(content::GLHelper::SCALER_QUALITY_GOOD, stages,
921 gfx::Size(dst_xsize, dst_ysize), ""); 860 gfx::Size(dst_xsize, dst_ysize), "");
922 EXPECT_EQ(PrintStages(stages), description); 861 EXPECT_EQ(PrintStages(stages), description);
923 } 862 }
924 863
925 // Note: Left/Right means Top/Bottom when used for Y dimension.
926 enum Margin {
927 MarginLeft,
928 MarginMiddle,
929 MarginRight,
930 MarginInvalid,
931 };
932
933 static Margin NextMargin(Margin m) {
934 switch (m) {
935 case MarginLeft:
936 return MarginMiddle;
937 case MarginMiddle:
938 return MarginRight;
939 case MarginRight:
940 return MarginInvalid;
941 default:
942 return MarginInvalid;
943 }
944 }
945
946 int compute_margin(int insize, int outsize, Margin m) {
947 int available = outsize - insize;
948 switch (m) {
949 default:
950 EXPECT_TRUE(false) << "This should not happen.";
951 return 0;
952 case MarginLeft:
953 return 0;
954 case MarginMiddle:
955 return (available / 2) & ~1;
956 case MarginRight:
957 return available;
958 }
959 }
960
961 // Convert 0.0 - 1.0 to 0 - 255
962 int float_to_byte(float v) {
963 int ret = static_cast<int>(floorf(v * 255.0f + 0.5f));
964 if (ret < 0) {
965 return 0;
966 }
967 if (ret > 255) {
968 return 255;
969 }
970 return ret;
971 }
972
973 static void callcallback(const base::Callback<void()>& callback, 864 static void callcallback(const base::Callback<void()>& callback,
974 bool result) { 865 bool result) {
975 callback.Run(); 866 callback.Run();
976 } 867 }
977 868
978 void PrintPlane(unsigned char* plane, int xsize, int stride, int ysize) {
979 for (int y = 0; y < ysize; y++) {
980 std::string formatted;
981 for (int x = 0; x < xsize; x++) {
982 formatted.append(base::StringPrintf("%3d, ", plane[y * stride + x]));
983 }
984 LOG(ERROR) << formatted << " (" << (plane + y * stride) << ")";
985 }
986 }
987
988 // Compare two planes make sure that each component of each pixel
989 // is no more than |maxdiff| apart.
990 void ComparePlane(unsigned char* truth,
991 int truth_stride,
992 unsigned char* other,
993 int other_stride,
994 int maxdiff,
995 int xsize,
996 int ysize,
997 SkBitmap* source,
998 std::string message) {
999 for (int x = 0; x < xsize; x++) {
1000 for (int y = 0; y < ysize; y++) {
1001 int a = other[y * other_stride + x];
1002 int b = truth[y * truth_stride + x];
1003 EXPECT_NEAR(a, b, maxdiff) << " x=" << x << " y=" << y << " "
1004 << message;
1005 if (std::abs(a - b) > maxdiff) {
1006 LOG(ERROR) << "-------expected--------";
1007 PrintPlane(truth, xsize, truth_stride, ysize);
1008 LOG(ERROR) << "-------actual--------";
1009 PrintPlane(other, xsize, other_stride, ysize);
1010 if (source) {
1011 LOG(ERROR) << "-------before yuv conversion: red--------";
1012 PrintChannel(source, 0);
1013 LOG(ERROR) << "-------before yuv conversion: green------";
1014 PrintChannel(source, 1);
1015 LOG(ERROR) << "-------before yuv conversion: blue-------";
1016 PrintChannel(source, 2);
1017 }
1018 return;
1019 }
1020 }
1021 }
1022 }
1023
1024 void DrawGridToBitmap(int w, 869 void DrawGridToBitmap(int w,
1025 int h, 870 int h,
1026 SkColor background_color, 871 SkColor background_color,
1027 SkColor grid_color, 872 SkColor grid_color,
1028 int grid_pitch, 873 int grid_pitch,
1029 int grid_width, 874 int grid_width,
1030 SkBitmap& bmp) { 875 SkBitmap& bmp) {
1031 ASSERT_GT(grid_pitch, 0); 876 ASSERT_GT(grid_pitch, 0);
1032 ASSERT_GT(grid_width, 0); 877 ASSERT_GT(grid_width, 0);
1033 ASSERT_NE(background_color, grid_color); 878 ASSERT_NE(background_color, grid_color);
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 LOG(ERROR) << "Bitmap comparision failure Pattern-3"; 1081 LOG(ERROR) << "Bitmap comparision failure Pattern-3";
1237 return false; 1082 return false;
1238 } 1083 }
1239 gl_->DeleteTextures(1, &src_texture); 1084 gl_->DeleteTextures(1, &src_texture);
1240 if (HasFailure()) { 1085 if (HasFailure()) {
1241 return false; 1086 return false;
1242 } 1087 }
1243 return true; 1088 return true;
1244 } 1089 }
1245 1090
1246 // YUV readback test. Create a test pattern, convert to YUV
1247 // with reference implementation and compare to what gl_helper
1248 // returns.
1249 void TestYUVReadback(int xsize,
1250 int ysize,
1251 int output_xsize,
1252 int output_ysize,
1253 int xmargin,
1254 int ymargin,
1255 int test_pattern,
1256 bool flip,
1257 bool use_mrt,
1258 content::GLHelper::ScalerQuality quality) {
1259 GLuint src_texture;
1260 gl_->GenTextures(1, &src_texture);
1261 SkBitmap input_pixels;
1262 input_pixels.allocN32Pixels(xsize, ysize);
1263
1264 for (int x = 0; x < xsize; ++x) {
1265 for (int y = 0; y < ysize; ++y) {
1266 switch (test_pattern) {
1267 case 0: // Smooth test pattern
1268 SetChannel(&input_pixels, x, y, 0, x * 10);
1269 SetChannel(&input_pixels, x, y, 1, y * 10);
1270 SetChannel(&input_pixels, x, y, 2, (x + y) * 10);
1271 SetChannel(&input_pixels, x, y, 3, 255);
1272 break;
1273 case 1: // Small blocks
1274 SetChannel(&input_pixels, x, y, 0, x & 1 ? 255 : 0);
1275 SetChannel(&input_pixels, x, y, 1, y & 1 ? 255 : 0);
1276 SetChannel(&input_pixels, x, y, 2, (x + y) & 1 ? 255 : 0);
1277 SetChannel(&input_pixels, x, y, 3, 255);
1278 break;
1279 case 2: // Medium blocks
1280 SetChannel(&input_pixels, x, y, 0, 10 + x / 2 * 50);
1281 SetChannel(&input_pixels, x, y, 1, 10 + y / 3 * 50);
1282 SetChannel(&input_pixels, x, y, 2, (x + y) / 5 * 50 + 5);
1283 SetChannel(&input_pixels, x, y, 3, 255);
1284 break;
1285 }
1286 }
1287 }
1288
1289 gl_->BindTexture(GL_TEXTURE_2D, src_texture);
1290 gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xsize, ysize, 0, GL_RGBA,
1291 GL_UNSIGNED_BYTE, input_pixels.getPixels());
1292
1293 gpu::Mailbox mailbox;
1294 gl_->GenMailboxCHROMIUM(mailbox.name);
1295 EXPECT_FALSE(mailbox.IsZero());
1296 gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
1297 const GLuint64 fence_sync = gl_->InsertFenceSyncCHROMIUM();
1298 gl_->ShallowFlushCHROMIUM();
1299
1300 gpu::SyncToken sync_token;
1301 gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
1302
1303 std::string message = base::StringPrintf(
1304 "input size: %dx%d "
1305 "output size: %dx%d "
1306 "margin: %dx%d "
1307 "pattern: %d %s %s",
1308 xsize, ysize, output_xsize, output_ysize, xmargin, ymargin,
1309 test_pattern, flip ? "flip" : "noflip", flip ? "mrt" : "nomrt");
1310 std::unique_ptr<ReadbackYUVInterface> yuv_reader(
1311 helper_->CreateReadbackPipelineYUV(
1312 quality, gfx::Size(xsize, ysize), gfx::Rect(0, 0, xsize, ysize),
1313 gfx::Size(xsize, ysize), flip, use_mrt));
1314
1315 scoped_refptr<media::VideoFrame> output_frame =
1316 media::VideoFrame::CreateFrame(
1317 media::PIXEL_FORMAT_YV12,
1318 // The coded size of the output frame is rounded up to the next
1319 // 16-byte boundary. This tests that the readback is being
1320 // positioned inside the frame's visible region, and not dependent
1321 // on its coded size.
1322 gfx::Size((output_xsize + 15) & ~15, (output_ysize + 15) & ~15),
1323 gfx::Rect(0, 0, output_xsize, output_ysize),
1324 gfx::Size(output_xsize, output_ysize),
1325 base::TimeDelta::FromSeconds(0));
1326 scoped_refptr<media::VideoFrame> truth_frame =
1327 media::VideoFrame::CreateFrame(
1328 media::PIXEL_FORMAT_YV12, gfx::Size(output_xsize, output_ysize),
1329 gfx::Rect(0, 0, output_xsize, output_ysize),
1330 gfx::Size(output_xsize, output_ysize),
1331 base::TimeDelta::FromSeconds(0));
1332
1333 base::RunLoop run_loop;
1334 yuv_reader->ReadbackYUV(mailbox, sync_token, output_frame->visible_rect(),
1335 output_frame->stride(media::VideoFrame::kYPlane),
1336 output_frame->data(media::VideoFrame::kYPlane),
1337 output_frame->stride(media::VideoFrame::kUPlane),
1338 output_frame->data(media::VideoFrame::kUPlane),
1339 output_frame->stride(media::VideoFrame::kVPlane),
1340 output_frame->data(media::VideoFrame::kVPlane),
1341 gfx::Point(xmargin, ymargin),
1342 base::Bind(&callcallback, run_loop.QuitClosure()));
1343
1344 const gfx::Rect paste_rect(gfx::Point(xmargin, ymargin),
1345 gfx::Size(xsize, ysize));
1346 media::LetterboxYUV(output_frame.get(), paste_rect);
1347 run_loop.Run();
1348
1349 if (flip) {
1350 FlipSKBitmap(&input_pixels);
1351 }
1352
1353 unsigned char* Y = truth_frame->visible_data(media::VideoFrame::kYPlane);
1354 unsigned char* U = truth_frame->visible_data(media::VideoFrame::kUPlane);
1355 unsigned char* V = truth_frame->visible_data(media::VideoFrame::kVPlane);
1356 int32_t y_stride = truth_frame->stride(media::VideoFrame::kYPlane);
1357 int32_t u_stride = truth_frame->stride(media::VideoFrame::kUPlane);
1358 int32_t v_stride = truth_frame->stride(media::VideoFrame::kVPlane);
1359 memset(Y, 0x00, y_stride * output_ysize);
1360 memset(U, 0x80, u_stride * output_ysize / 2);
1361 memset(V, 0x80, v_stride * output_ysize / 2);
1362
1363 const float kRGBtoYColorWeights[] = {0.257f, 0.504f, 0.098f, 0.0625f};
1364 const float kRGBtoUColorWeights[] = {-0.148f, -0.291f, 0.439f, 0.5f};
1365 const float kRGBtoVColorWeights[] = {0.439f, -0.368f, -0.071f, 0.5f};
1366
1367 for (int y = 0; y < ysize; y++) {
1368 for (int x = 0; x < xsize; x++) {
1369 Y[(y + ymargin) * y_stride + x + xmargin] = float_to_byte(
1370 ChannelAsFloat(&input_pixels, x, y, 0) * kRGBtoYColorWeights[0] +
1371 ChannelAsFloat(&input_pixels, x, y, 1) * kRGBtoYColorWeights[1] +
1372 ChannelAsFloat(&input_pixels, x, y, 2) * kRGBtoYColorWeights[2] +
1373 kRGBtoYColorWeights[3]);
1374 }
1375 }
1376
1377 for (int y = 0; y < ysize / 2; y++) {
1378 for (int x = 0; x < xsize / 2; x++) {
1379 U[(y + ymargin / 2) * u_stride + x + xmargin / 2] =
1380 float_to_byte(Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 0) *
1381 kRGBtoUColorWeights[0] +
1382 Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 1) *
1383 kRGBtoUColorWeights[1] +
1384 Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 2) *
1385 kRGBtoUColorWeights[2] +
1386 kRGBtoUColorWeights[3]);
1387 V[(y + ymargin / 2) * v_stride + x + xmargin / 2] =
1388 float_to_byte(Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 0) *
1389 kRGBtoVColorWeights[0] +
1390 Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 1) *
1391 kRGBtoVColorWeights[1] +
1392 Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 2) *
1393 kRGBtoVColorWeights[2] +
1394 kRGBtoVColorWeights[3]);
1395 }
1396 }
1397
1398 ComparePlane(
1399 Y, y_stride, output_frame->visible_data(media::VideoFrame::kYPlane),
1400 output_frame->stride(media::VideoFrame::kYPlane), 2, output_xsize,
1401 output_ysize, &input_pixels, message + " Y plane");
1402 ComparePlane(
1403 U, u_stride, output_frame->visible_data(media::VideoFrame::kUPlane),
1404 output_frame->stride(media::VideoFrame::kUPlane), 2, output_xsize / 2,
1405 output_ysize / 2, &input_pixels, message + " U plane");
1406 ComparePlane(
1407 V, v_stride, output_frame->visible_data(media::VideoFrame::kVPlane),
1408 output_frame->stride(media::VideoFrame::kVPlane), 2, output_xsize / 2,
1409 output_ysize / 2, &input_pixels, message + " V plane");
1410
1411 gl_->DeleteTextures(1, &src_texture);
1412 }
1413
1414 void TestAddOps(int src, int dst, bool scale_x, bool allow3) { 1091 void TestAddOps(int src, int dst, bool scale_x, bool allow3) {
1415 std::deque<GLHelperScaling::ScaleOp> ops; 1092 std::deque<GLHelperScaling::ScaleOp> ops;
1416 GLHelperScaling::ScaleOp::AddOps(src, dst, scale_x, allow3, &ops); 1093 GLHelperScaling::ScaleOp::AddOps(src, dst, scale_x, allow3, &ops);
1417 // Scale factor 3 is a special case. 1094 // Scale factor 3 is a special case.
1418 // It is currently only allowed by itself. 1095 // It is currently only allowed by itself.
1419 if (allow3 && dst * 3 >= src && dst * 2 < src) { 1096 if (allow3 && dst * 3 >= src && dst * 2 < src) {
1420 EXPECT_EQ(ops[0].scale_factor, 3); 1097 EXPECT_EQ(ops[0].scale_factor, 3);
1421 EXPECT_EQ(ops.size(), 1U); 1098 EXPECT_EQ(ops.size(), 1U);
1422 EXPECT_EQ(ops[0].scale_x, scale_x); 1099 EXPECT_EQ(ops[0].scale_x, scale_x);
1423 EXPECT_EQ(ops[0].scale_size, dst); 1100 EXPECT_EQ(ops[0].scale_size, dst);
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 EXPECT_EQ(result, true); 1308 EXPECT_EQ(result, true);
1632 } 1309 }
1633 1310
1634 TEST_F(GLHelperTest, RGB565ASyncReadbackTest) { 1311 TEST_F(GLHelperTest, RGB565ASyncReadbackTest) {
1635 const int kTestSize = 64; 1312 const int kTestSize = 64;
1636 bool result = TestTextureFormatReadback(gfx::Size(kTestSize, kTestSize), 1313 bool result = TestTextureFormatReadback(gfx::Size(kTestSize, kTestSize),
1637 kRGB_565_SkColorType, true); 1314 kRGB_565_SkColorType, true);
1638 EXPECT_EQ(result, true); 1315 EXPECT_EQ(result, true);
1639 } 1316 }
1640 1317
1641 TEST_F(GLHelperPixelTest, YUVReadbackOptTest) {
1642 // This test uses the gpu.service/gpu_decoder tracing events to detect how
1643 // many scaling passes are actually performed by the YUV readback pipeline.
1644 StartTracing(TRACE_DISABLED_BY_DEFAULT(
1645 "gpu.service") "," TRACE_DISABLED_BY_DEFAULT("gpu_decoder"));
1646
1647 TestYUVReadback(800, 400, 800, 400, 0, 0, 1, false, true,
1648 content::GLHelper::SCALER_QUALITY_FAST);
1649
1650 std::map<std::string, int> event_counts;
1651 EndTracing(&event_counts);
1652 int draw_buffer_calls = event_counts["kDrawBuffersEXTImmediate"];
1653 int draw_arrays_calls = event_counts["kDrawArrays"];
1654 VLOG(1) << "Draw buffer calls: " << draw_buffer_calls;
1655 VLOG(1) << "DrawArrays calls: " << draw_arrays_calls;
1656
1657 if (draw_buffer_calls) {
1658 // When using MRT, the YUV readback code should only
1659 // execute two draw arrays, and scaling should be integrated
1660 // into those two calls since we are using the FAST scalign
1661 // quality.
1662 EXPECT_EQ(2, draw_arrays_calls);
1663 } else {
1664 // When not using MRT, there are three passes for the YUV,
1665 // and one for the scaling.
1666 EXPECT_EQ(4, draw_arrays_calls);
1667 }
1668 }
1669
1670 class GLHelperPixelYuvReadback
1671 : public GLHelperPixelTest,
1672 public ::testing::WithParamInterface<
1673 std::tr1::tuple<bool, bool, unsigned int, unsigned int>> {};
1674
1675 int kYUVReadBackSizes[] = {2, 4, 14};
1676
1677 TEST_P(GLHelperPixelYuvReadback, Test) {
1678 bool flip = std::tr1::get<0>(GetParam());
1679 bool use_mrt = std::tr1::get<1>(GetParam());
1680 unsigned int x = std::tr1::get<2>(GetParam());
1681 unsigned int y = std::tr1::get<3>(GetParam());
1682
1683 for (unsigned int ox = x; ox < arraysize(kYUVReadBackSizes); ox++) {
1684 for (unsigned int oy = y; oy < arraysize(kYUVReadBackSizes); oy++) {
1685 // If output is a subsection of the destination frame, (letterbox)
1686 // then try different variations of where the subsection goes.
1687 for (Margin xm = x < ox ? MarginLeft : MarginRight; xm <= MarginRight;
1688 xm = NextMargin(xm)) {
1689 for (Margin ym = y < oy ? MarginLeft : MarginRight; ym <= MarginRight;
1690 ym = NextMargin(ym)) {
1691 for (int pattern = 0; pattern < 3; pattern++) {
1692 TestYUVReadback(
1693 kYUVReadBackSizes[x], kYUVReadBackSizes[y],
1694 kYUVReadBackSizes[ox], kYUVReadBackSizes[oy],
1695 compute_margin(kYUVReadBackSizes[x], kYUVReadBackSizes[ox], xm),
1696 compute_margin(kYUVReadBackSizes[y], kYUVReadBackSizes[oy], ym),
1697 pattern, flip, use_mrt, content::GLHelper::SCALER_QUALITY_GOOD);
1698 if (HasFailure()) {
1699 return;
1700 }
1701 }
1702 }
1703 }
1704 }
1705 }
1706 }
1707
1708 // First argument is intentionally empty.
1709 INSTANTIATE_TEST_CASE_P(
1710 ,
1711 GLHelperPixelYuvReadback,
1712 ::testing::Combine(
1713 ::testing::Bool(),
1714 ::testing::Bool(),
1715 ::testing::Range<unsigned int>(0, arraysize(kYUVReadBackSizes)),
1716 ::testing::Range<unsigned int>(0, arraysize(kYUVReadBackSizes))));
1717
1718 int kRGBReadBackSizes[] = {3, 6, 16}; 1318 int kRGBReadBackSizes[] = {3, 6, 16};
1719 1319
1720 class GLHelperPixelReadbackTest 1320 class GLHelperPixelReadbackTest
1721 : public GLHelperPixelTest, 1321 : public GLHelperPixelTest,
1722 public ::testing::WithParamInterface<std::tr1::tuple<unsigned int, 1322 public ::testing::WithParamInterface<std::tr1::tuple<unsigned int,
1723 unsigned int, 1323 unsigned int,
1724 unsigned int, 1324 unsigned int,
1725 unsigned int, 1325 unsigned int,
1726 unsigned int>> {}; 1326 unsigned int>> {};
1727 1327
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1830 } 1430 }
1831 } 1431 }
1832 } 1432 }
1833 1433
1834 TEST_F(GLHelperTest, CheckOptimizations) { 1434 TEST_F(GLHelperTest, CheckOptimizations) {
1835 // Test in baseclass since it is friends with GLHelperScaling 1435 // Test in baseclass since it is friends with GLHelperScaling
1836 CheckOptimizationsTest(); 1436 CheckOptimizationsTest();
1837 } 1437 }
1838 1438
1839 } // namespace content 1439 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/browser/compositor/yuv_readback_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698