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

Side by Side Diff: content/common/gpu/client/gl_helper_unittest.cc

Issue 388953002: Improving GestureNav screenshotting performance - Part 1 - gl_helper (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: git cl format 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 | « content/common/gpu/client/gl_helper.cc ('k') | 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 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 <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>
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 float x3 = x2 * x; 132 float x3 = x2 * x;
133 if (x <= 1) { 133 if (x <= 1) {
134 return (a + 2) * x3 - (a + 3) * x2 + 1; 134 return (a + 2) * x3 - (a + 3) * x2 + 1;
135 } else if (x < 2) { 135 } else if (x < 2) {
136 return a * x3 - 5 * a * x2 + 8 * a * x - 4 * a; 136 return a * x3 - 5 * a * x2 + 8 * a * x - 4 * a;
137 } else { 137 } else {
138 return 0.0f; 138 return 0.0f;
139 } 139 }
140 } 140 }
141 141
142 // Look up a single R/G/B/A value. 142 // Look up a single channel value. Works for 4-channel and single channel
143 // Clamp x/y. 143 // bitmaps. Clamp x/y.
144 int Channel(SkBitmap* pixels, int x, int y, int c) { 144 int Channel(SkBitmap* pixels, int x, int y, int c) {
145 uint32* data = 145 if (pixels->bytesPerPixel() == 4) {
146 pixels->getAddr32(std::max(0, std::min(x, pixels->width() - 1)), 146 uint32* data =
147 std::max(0, std::min(y, pixels->height() - 1))); 147 pixels->getAddr32(std::max(0, std::min(x, pixels->width() - 1)),
148 return (*data) >> (c * 8) & 0xff; 148 std::max(0, std::min(y, pixels->height() - 1)));
149 return (*data) >> (c * 8) & 0xff;
150 } else {
151 DCHECK_EQ(pixels->bytesPerPixel(), 1);
152 DCHECK_EQ(c, 0);
153 return *pixels->getAddr8(std::max(0, std::min(x, pixels->width() - 1)),
154 std::max(0, std::min(y, pixels->height() - 1)));
155 }
149 } 156 }
150 157
151 // Set a single R/G/B/A value. 158 // Set a single channel value. Works for 4-channel and single channel
159 // bitmaps. Clamp x/y.
152 void SetChannel(SkBitmap* pixels, int x, int y, int c, int v) { 160 void SetChannel(SkBitmap* pixels, int x, int y, int c, int v) {
153 DCHECK_GE(x, 0); 161 DCHECK_GE(x, 0);
154 DCHECK_GE(y, 0); 162 DCHECK_GE(y, 0);
155 DCHECK_LT(x, pixels->width()); 163 DCHECK_LT(x, pixels->width());
156 DCHECK_LT(y, pixels->height()); 164 DCHECK_LT(y, pixels->height());
157 uint32* data = pixels->getAddr32(x, y); 165 if (pixels->bytesPerPixel() == 4) {
158 v = std::max(0, std::min(v, 255)); 166 uint32* data = pixels->getAddr32(x, y);
159 *data = (*data & ~(0xffu << (c * 8))) | (v << (c * 8)); 167 v = std::max(0, std::min(v, 255));
168 *data = (*data & ~(0xffu << (c * 8))) | (v << (c * 8));
169 } else {
170 DCHECK_EQ(pixels->bytesPerPixel(), 1);
171 DCHECK_EQ(c, 0);
172 uint8* data = pixels->getAddr8(x, y);
173 v = std::max(0, std::min(v, 255));
174 *data = v;
175 }
160 } 176 }
161 177
162 // Print all the R, G, B or A values from an SkBitmap in a 178 // Print all the R, G, B or A values from an SkBitmap in a
163 // human-readable format. 179 // human-readable format.
164 void PrintChannel(SkBitmap* pixels, int c) { 180 void PrintChannel(SkBitmap* pixels, int c) {
165 for (int y = 0; y < pixels->height(); y++) { 181 for (int y = 0; y < pixels->height(); y++) {
166 std::string formatted; 182 std::string formatted;
167 for (int x = 0; x < pixels->width(); x++) { 183 for (int x = 0; x < pixels->width(); x++) {
168 formatted.append(base::StringPrintf("%3d, ", Channel(pixels, x, y, c))); 184 formatted.append(base::StringPrintf("%3d, ", Channel(pixels, x, y, c)));
169 } 185 }
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 } 387 }
372 } 388 }
373 389
374 if (HasFailure() && !previous_error) { 390 if (HasFailure() && !previous_error) {
375 LOG(ERROR) << "Invalid scaler stages: " << message; 391 LOG(ERROR) << "Invalid scaler stages: " << message;
376 LOG(ERROR) << "Scaler stages:"; 392 LOG(ERROR) << "Scaler stages:";
377 LOG(ERROR) << PrintStages(scaler_stages); 393 LOG(ERROR) << PrintStages(scaler_stages);
378 } 394 }
379 } 395 }
380 396
381 // Compare two bitmaps, make sure that each component of each pixel 397 // Compares two bitmaps taking color types into account. Checks whether each
382 // is no more than |maxdiff| apart. If they are not similar enough, 398 // component of each pixel is no more than |maxdiff| apart. If bitmaps are not
383 // prints out |truth|, |other|, |source|, |scaler_stages| and |message|. 399 // similar enough, prints out |truth|, |other|, |source|, |scaler_stages|
400 // and |message|.
384 void Compare(SkBitmap* truth, 401 void Compare(SkBitmap* truth,
385 SkBitmap* other, 402 SkBitmap* other,
386 int maxdiff, 403 int maxdiff,
387 SkBitmap* source, 404 SkBitmap* source,
388 const std::vector<GLHelperScaling::ScalerStage>& scaler_stages, 405 const std::vector<GLHelperScaling::ScalerStage>& scaler_stages,
389 std::string message) { 406 std::string message) {
390 EXPECT_EQ(truth->width(), other->width()); 407 EXPECT_EQ(truth->width(), other->width());
391 EXPECT_EQ(truth->height(), other->height()); 408 EXPECT_EQ(truth->height(), other->height());
409 bool swizzle = (truth->colorType() == kRGBA_8888_SkColorType &&
410 other->colorType() == kBGRA_8888_SkColorType) ||
411 (truth->colorType() == kBGRA_8888_SkColorType &&
412 other->colorType() == kRGBA_8888_SkColorType);
413 EXPECT_TRUE(swizzle || truth->colorType() == other->colorType());
414 int bpp = truth->bytesPerPixel();
392 for (int x = 0; x < truth->width(); x++) { 415 for (int x = 0; x < truth->width(); x++) {
393 for (int y = 0; y < truth->height(); y++) { 416 for (int y = 0; y < truth->height(); y++) {
394 for (int c = 0; c < 4; c++) { 417 for (int c = 0; c < bpp; c++) {
395 int a = Channel(truth, x, y, c); 418 int a = Channel(truth, x, y, c);
396 int b = Channel(other, x, y, c); 419 // swizzle when comparing if needed
420 int b = swizzle && (c == 0 || c == 2)
421 ? Channel(other, x, y, (c + 2) & 2)
422 : Channel(other, x, y, c);
397 EXPECT_NEAR(a, b, maxdiff) << " x=" << x << " y=" << y << " c=" << c 423 EXPECT_NEAR(a, b, maxdiff) << " x=" << x << " y=" << y << " c=" << c
398 << " " << message; 424 << " " << message;
399 if (std::abs(a - b) > maxdiff) { 425 if (std::abs(a - b) > maxdiff) {
400 LOG(ERROR) << "-------expected--------"; 426 LOG(ERROR) << "-------expected--------";
401 PrintChannel(truth, c); 427 for (int i = 0; i < bpp; i++) {
428 LOG(ERROR) << "Channel " << i << ":";
429 PrintChannel(truth, i);
430 }
402 LOG(ERROR) << "-------actual--------"; 431 LOG(ERROR) << "-------actual--------";
403 PrintChannel(other, c); 432 for (int i = 0; i < bpp; i++) {
433 LOG(ERROR) << "Channel " << i << ":";
434 PrintChannel(other, i);
435 }
404 if (source) { 436 if (source) {
405 LOG(ERROR) << "-------before scaling--------"; 437 LOG(ERROR) << "-------original--------";
406 PrintChannel(source, c); 438 for (int i = 0; i < source->bytesPerPixel(); i++) {
439 LOG(ERROR) << "Channel " << i << ":";
440 PrintChannel(source, i);
441 }
407 } 442 }
408 LOG(ERROR) << "-----Scaler stages------"; 443 LOG(ERROR) << "-----Scaler stages------";
409 LOG(ERROR) << PrintStages(scaler_stages); 444 LOG(ERROR) << PrintStages(scaler_stages);
410 return; 445 return;
411 } 446 }
412 } 447 }
413 } 448 }
414 } 449 }
415 } 450 }
416 451
417 // Get a single R, G, B or A value as a float. 452 // Get a single R, G, B or A value as a float.
418 float ChannelAsFloat(SkBitmap* pixels, int x, int y, int c) { 453 float ChannelAsFloat(SkBitmap* pixels, int x, int y, int c) {
419 return Channel(pixels, x, y, c) / 255.0; 454 return Channel(pixels, x, y, c) / 255.0;
420 } 455 }
421 456
422 // Works like a GL_LINEAR lookup on an SkBitmap. 457 // Works like a GL_LINEAR lookup on an SkBitmap.
423 float Bilinear(SkBitmap* pixels, float x, float y, int c) { 458 float Bilinear(SkBitmap* pixels, float x, float y, int c) {
424 x -= 0.5; 459 x -= 0.5;
425 y -= 0.5; 460 y -= 0.5;
426 int base_x = static_cast<int>(floorf(x)); 461 int base_x = static_cast<int>(floorf(x));
427 int base_y = static_cast<int>(floorf(y)); 462 int base_y = static_cast<int>(floorf(y));
428 x -= base_x; 463 x -= base_x;
429 y -= base_y; 464 y -= base_y;
430 return (ChannelAsFloat(pixels, base_x, base_y, c) * (1 - x) * (1 - y) + 465 return (ChannelAsFloat(pixels, base_x, base_y, c) * (1 - x) * (1 - y) +
431 ChannelAsFloat(pixels, base_x + 1, base_y, c) * x * (1 - y) + 466 ChannelAsFloat(pixels, base_x + 1, base_y, c) * x * (1 - y) +
432 ChannelAsFloat(pixels, base_x, base_y + 1, c) * (1 - x) * y + 467 ChannelAsFloat(pixels, base_x, base_y + 1, c) * (1 - x) * y +
433 ChannelAsFloat(pixels, base_x + 1, base_y + 1, c) * x * y); 468 ChannelAsFloat(pixels, base_x + 1, base_y + 1, c) * x * y);
434 } 469 }
435 470
471 // Encodes an RGBA bitmap to grayscale.
472 // Reference implementation for
473 // GLHelper::CopyToTextureImpl::EncodeTextureAsGrayscale.
474 void EncodeToGrayscaleSlow(SkBitmap* input, SkBitmap* output) {
475 const float kRGBtoGrayscaleColorWeights[3] = {0.213f, 0.715f, 0.072f};
476 CHECK_EQ(kAlpha_8_SkColorType, output->colorType());
477 CHECK_EQ(input->width(), output->width());
478 CHECK_EQ(input->height(), output->height());
479 CHECK_EQ(input->colorType(), kRGBA_8888_SkColorType);
480
481 for (int dst_y = 0; dst_y < output->height(); dst_y++) {
482 for (int dst_x = 0; dst_x < output->width(); dst_x++) {
483 float c0 = ChannelAsFloat(input, dst_x, dst_y, 0);
484 float c1 = ChannelAsFloat(input, dst_x, dst_y, 1);
485 float c2 = ChannelAsFloat(input, dst_x, dst_y, 2);
486 float value = c0 * kRGBtoGrayscaleColorWeights[0] +
487 c1 * kRGBtoGrayscaleColorWeights[1] +
488 c2 * kRGBtoGrayscaleColorWeights[2];
489 SetChannel(
490 output, dst_x, dst_y, 0, static_cast<int>(value * 255.0f + 0.5f));
491 }
492 }
493 }
494
436 // Very slow bicubic / bilinear scaler for reference. 495 // Very slow bicubic / bilinear scaler for reference.
437 void ScaleSlow(SkBitmap* input, 496 void ScaleSlow(SkBitmap* input,
438 SkBitmap* output, 497 SkBitmap* output,
439 content::GLHelper::ScalerQuality quality) { 498 content::GLHelper::ScalerQuality quality) {
440 float xscale = static_cast<float>(input->width()) / output->width(); 499 float xscale = static_cast<float>(input->width()) / output->width();
441 float yscale = static_cast<float>(input->height()) / output->height(); 500 float yscale = static_cast<float>(input->height()) / output->height();
442 float clamped_xscale = xscale < 1.0 ? 1.0 : 1.0 / xscale; 501 float clamped_xscale = xscale < 1.0 ? 1.0 : 1.0 / xscale;
443 float clamped_yscale = yscale < 1.0 ? 1.0 : 1.0 / yscale; 502 float clamped_yscale = yscale < 1.0 ? 1.0 : 1.0 / yscale;
444 for (int dst_y = 0; dst_y < output->height(); dst_y++) { 503 for (int dst_y = 0; dst_y < output->height(); dst_y++) {
445 for (int dst_x = 0; dst_x < output->width(); dst_x++) { 504 for (int dst_x = 0; dst_x < output->width(); dst_x++) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 dst_x, 567 dst_x,
509 dst_y, 568 dst_y,
510 channel, 569 channel,
511 static_cast<int>(value * 255.0f + 0.5f)); 570 static_cast<int>(value * 255.0f + 0.5f));
512 } 571 }
513 } 572 }
514 } 573 }
515 } 574 }
516 575
517 void FlipSKBitmap(SkBitmap* bitmap) { 576 void FlipSKBitmap(SkBitmap* bitmap) {
577 int bpp = bitmap->bytesPerPixel();
578 DCHECK(bpp == 4 || bpp == 1);
518 int top_line = 0; 579 int top_line = 0;
519 int bottom_line = bitmap->height() - 1; 580 int bottom_line = bitmap->height() - 1;
520 while (top_line < bottom_line) { 581 while (top_line < bottom_line) {
521 for (int x = 0; x < bitmap->width(); x++) { 582 for (int x = 0; x < bitmap->width(); x++) {
522 std::swap(*bitmap->getAddr32(x, top_line), 583 bpp == 4 ? std::swap(*bitmap->getAddr32(x, top_line),
523 *bitmap->getAddr32(x, bottom_line)); 584 *bitmap->getAddr32(x, bottom_line))
585 : std::swap(*bitmap->getAddr8(x, top_line),
586 *bitmap->getAddr8(x, bottom_line));
524 } 587 }
525 top_line++; 588 top_line++;
526 bottom_line--; 589 bottom_line--;
527 } 590 }
528 } 591 }
529 592
593 // Swaps red and blue channels in each pixel in a 32-bit bitmap.
594 void SwizzleSKBitmap(SkBitmap* bitmap) {
595 int bpp = bitmap->bytesPerPixel();
596 DCHECK(bpp == 4);
597 for (int y = 0; y < bitmap->height(); y++) {
598 for (int x = 0; x < bitmap->width(); x++) {
599 // Swap channels 0 and 2 (red and blue)
600 int c0 = Channel(bitmap, x, y, 0);
601 int c2 = Channel(bitmap, x, y, 2);
602 SetChannel(bitmap, x, y, 2, c0);
603 SetChannel(bitmap, x, y, 0, c2);
604 }
605 }
606 }
607
530 // gl_helper scales recursively, so we'll need to do that 608 // gl_helper scales recursively, so we'll need to do that
531 // in the reference implementation too. 609 // in the reference implementation too.
532 void ScaleSlowRecursive(SkBitmap* input, 610 void ScaleSlowRecursive(SkBitmap* input,
533 SkBitmap* output, 611 SkBitmap* output,
534 content::GLHelper::ScalerQuality quality) { 612 content::GLHelper::ScalerQuality quality) {
535 if (quality == content::GLHelper::SCALER_QUALITY_FAST || 613 if (quality == content::GLHelper::SCALER_QUALITY_FAST ||
536 quality == content::GLHelper::SCALER_QUALITY_GOOD) { 614 quality == content::GLHelper::SCALER_QUALITY_GOOD) {
537 ScaleSlow(input, output, quality); 615 ScaleSlow(input, output, quality);
538 return; 616 return;
539 } 617 }
(...skipping 28 matching lines...) Expand all
568 } 646 }
569 } 647 }
570 648
571 SkBitmap tmp; 649 SkBitmap tmp;
572 tmp.allocN32Pixels(xtmp, ytmp); 650 tmp.allocN32Pixels(xtmp, ytmp);
573 651
574 ScaleSlowRecursive(input, &tmp, quality); 652 ScaleSlowRecursive(input, &tmp, quality);
575 ScaleSlowRecursive(&tmp, output, quality); 653 ScaleSlowRecursive(&tmp, output, quality);
576 } 654 }
577 655
656 // Creates an RGBA SkBitmap
657 scoped_ptr<SkBitmap> CreateTestBitmap(int width,
658 int height,
659 int test_pattern) {
660 scoped_ptr<SkBitmap> bitmap(new SkBitmap);
661 bitmap->allocPixels(SkImageInfo::Make(
662 width, height, kRGBA_8888_SkColorType, kPremul_SkAlphaType));
663
664 for (int x = 0; x < width; ++x) {
665 for (int y = 0; y < height; ++y) {
666 switch (test_pattern) {
667 case 0: // Smooth test pattern
668 SetChannel(bitmap.get(), x, y, 0, x * 10);
669 SetChannel(bitmap.get(), x, y, 0, y == 0 ? x * 50 : x * 10);
670 SetChannel(bitmap.get(), x, y, 1, y * 10);
671 SetChannel(bitmap.get(), x, y, 2, (x + y) * 10);
672 SetChannel(bitmap.get(), x, y, 3, 255);
673 break;
674 case 1: // Small blocks
675 SetChannel(bitmap.get(), x, y, 0, x & 1 ? 255 : 0);
676 SetChannel(bitmap.get(), x, y, 1, y & 1 ? 255 : 0);
677 SetChannel(bitmap.get(), x, y, 2, (x + y) & 1 ? 255 : 0);
678 SetChannel(bitmap.get(), x, y, 3, 255);
679 break;
680 case 2: // Medium blocks
681 SetChannel(bitmap.get(), x, y, 0, 10 + x / 2 * 50);
682 SetChannel(bitmap.get(), x, y, 1, 10 + y / 3 * 50);
683 SetChannel(bitmap.get(), x, y, 2, (x + y) / 5 * 50 + 5);
684 SetChannel(bitmap.get(), x, y, 3, 255);
685 break;
686 }
687 }
688 }
689 return bitmap.Pass();
690 }
691
692 // Binds texture and framebuffer and loads the bitmap pixels into the texture.
693 void BindTextureAndFrameBuffer(WebGLId texture,
694 WebGLId framebuffer,
695 SkBitmap* bitmap,
696 int width,
697 int height) {
698 context_->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
699 context_->bindTexture(GL_TEXTURE_2D, texture);
700 context_->texImage2D(GL_TEXTURE_2D,
701 0,
702 GL_RGBA,
703 width,
704 height,
705 0,
706 GL_RGBA,
707 GL_UNSIGNED_BYTE,
708 bitmap->getPixels());
709 }
710
711 // Create a test image, transform it using
712 // GLHelper::CropScaleReadbackAndCleanTexture and a reference implementation
713 // and compare the results.
714 void TestCropScaleReadbackAndCleanTexture(int xsize,
715 int ysize,
716 int scaled_xsize,
717 int scaled_ysize,
718 int test_pattern,
719 SkColorType out_color_type,
720 bool swizzle,
721 size_t quality_index) {
722 DCHECK(out_color_type == kAlpha_8_SkColorType ||
723 out_color_type == kRGBA_8888_SkColorType ||
724 out_color_type == kBGRA_8888_SkColorType);
725 WebGLId src_texture = context_->createTexture();
726 WebGLId framebuffer = context_->createFramebuffer();
727 scoped_ptr<SkBitmap> input_pixels =
728 CreateTestBitmap(xsize, ysize, test_pattern).Pass();
729 BindTextureAndFrameBuffer(
730 src_texture, framebuffer, input_pixels.get(), xsize, ysize);
731
732 std::string message = base::StringPrintf(
733 "input size: %dx%d "
734 "output size: %dx%d "
735 "pattern: %d , quality: %s, "
736 "out_color_type: %d",
737 xsize,
738 ysize,
739 scaled_xsize,
740 scaled_ysize,
741 test_pattern,
742 kQualityNames[quality_index],
743 out_color_type);
744
745 // Transform the bitmap using GLHelper::CropScaleReadbackAndCleanTexture.
746 SkBitmap output_pixels;
747 output_pixels.allocPixels(SkImageInfo::Make(
748 scaled_xsize, scaled_ysize, out_color_type, kPremul_SkAlphaType));
749 base::RunLoop run_loop;
750 gfx::Size encoded_texture_size;
751 helper_->CropScaleReadbackAndCleanTexture(
752 src_texture,
753 gfx::Size(xsize, ysize),
754 gfx::Rect(xsize, ysize),
755 gfx::Size(scaled_xsize, scaled_ysize),
756 static_cast<unsigned char*>(output_pixels.getPixels()),
757 out_color_type,
758 base::Bind(&callcallback, run_loop.QuitClosure()),
759 kQualities[quality_index]);
760 run_loop.Run();
761 // CropScaleReadbackAndCleanTexture flips the pixels. Flip them back.
762 FlipSKBitmap(&output_pixels);
763
764 // If the bitmap shouldn't have changed - compare against input.
765 if (xsize == scaled_xsize && ysize == scaled_ysize &&
766 out_color_type != kAlpha_8_SkColorType) {
767 const std::vector<GLHelperScaling::ScalerStage> dummy_stages;
768 Compare(input_pixels.get(),
769 &output_pixels,
770 2,
no sievers 2014/08/25 19:34:52 If there was no scaling should the tolerance be 0?
mfomitchev 2014/08/25 20:05:04 Done.
771 NULL,
772 dummy_stages,
773 message + " comparing against input");
774 return;
775 }
776
777 // Now transform the bitmap using the reference implementation.
778 SkBitmap scaled_pixels;
779 scaled_pixels.allocPixels(SkImageInfo::Make(scaled_xsize,
780 scaled_ysize,
781 kRGBA_8888_SkColorType,
782 kPremul_SkAlphaType));
783 SkBitmap truth_pixels;
784 // Step 1: Scale
785 ScaleSlowRecursive(
786 input_pixels.get(), &scaled_pixels, kQualities[quality_index]);
787 // Step 2: Encode to grayscale if needed.
788 if (out_color_type == kAlpha_8_SkColorType) {
789 truth_pixels.allocPixels(SkImageInfo::Make(
790 scaled_xsize, scaled_ysize, out_color_type, kPremul_SkAlphaType));
791 EncodeToGrayscaleSlow(&scaled_pixels, &truth_pixels);
792 } else {
793 truth_pixels = scaled_pixels;
794 }
795
796 // Now compare the results.
797 SkAutoLockPixels lock_input(truth_pixels);
798 const std::vector<GLHelperScaling::ScalerStage> dummy_stages;
799 Compare(&truth_pixels,
800 &output_pixels,
801 2,
802 input_pixels.get(),
803 dummy_stages,
804 message + " comparing against transformed/scaled");
805
806 context_->deleteTexture(src_texture);
807 context_->deleteFramebuffer(framebuffer);
808 }
809
578 // Scaling test: Create a test image, scale it using GLHelperScaling 810 // Scaling test: Create a test image, scale it using GLHelperScaling
579 // and a reference implementation and compare the results. 811 // and a reference implementation and compare the results.
580 void TestScale(int xsize, 812 void TestScale(int xsize,
581 int ysize, 813 int ysize,
582 int scaled_xsize, 814 int scaled_xsize,
583 int scaled_ysize, 815 int scaled_ysize,
584 int test_pattern, 816 int test_pattern,
585 size_t quality, 817 size_t quality_index,
586 bool flip) { 818 bool flip) {
587 WebGLId src_texture = context_->createTexture(); 819 WebGLId src_texture = context_->createTexture();
588 WebGLId framebuffer = context_->createFramebuffer(); 820 WebGLId framebuffer = context_->createFramebuffer();
589 SkBitmap input_pixels; 821 scoped_ptr<SkBitmap> input_pixels =
590 input_pixels.allocN32Pixels(xsize, ysize); 822 CreateTestBitmap(xsize, ysize, test_pattern).Pass();
591 823 BindTextureAndFrameBuffer(
592 for (int x = 0; x < xsize; ++x) { 824 src_texture, framebuffer, input_pixels.get(), xsize, ysize);
593 for (int y = 0; y < ysize; ++y) {
594 switch (test_pattern) {
595 case 0: // Smooth test pattern
596 SetChannel(&input_pixels, x, y, 0, x * 10);
597 SetChannel(&input_pixels, x, y, 1, y * 10);
598 SetChannel(&input_pixels, x, y, 2, (x + y) * 10);
599 SetChannel(&input_pixels, x, y, 3, 255);
600 break;
601 case 1: // Small blocks
602 SetChannel(&input_pixels, x, y, 0, x & 1 ? 255 : 0);
603 SetChannel(&input_pixels, x, y, 1, y & 1 ? 255 : 0);
604 SetChannel(&input_pixels, x, y, 2, (x + y) & 1 ? 255 : 0);
605 SetChannel(&input_pixels, x, y, 3, 255);
606 break;
607 case 2: // Medium blocks
608 SetChannel(&input_pixels, x, y, 0, 10 + x / 2 * 50);
609 SetChannel(&input_pixels, x, y, 1, 10 + y / 3 * 50);
610 SetChannel(&input_pixels, x, y, 2, (x + y) / 5 * 50 + 5);
611 SetChannel(&input_pixels, x, y, 3, 255);
612 break;
613 }
614 }
615 }
616
617 context_->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
618 context_->bindTexture(GL_TEXTURE_2D, src_texture);
619 context_->texImage2D(GL_TEXTURE_2D,
620 0,
621 GL_RGBA,
622 xsize,
623 ysize,
624 0,
625 GL_RGBA,
626 GL_UNSIGNED_BYTE,
627 input_pixels.getPixels());
628 825
629 std::string message = base::StringPrintf( 826 std::string message = base::StringPrintf(
630 "input size: %dx%d " 827 "input size: %dx%d "
631 "output size: %dx%d " 828 "output size: %dx%d "
632 "pattern: %d quality: %s", 829 "pattern: %d quality: %s",
633 xsize, 830 xsize,
634 ysize, 831 ysize,
635 scaled_xsize, 832 scaled_xsize,
636 scaled_ysize, 833 scaled_ysize,
637 test_pattern, 834 test_pattern,
638 kQualityNames[quality]); 835 kQualityNames[quality_index]);
639 836
640 std::vector<GLHelperScaling::ScalerStage> stages; 837 std::vector<GLHelperScaling::ScalerStage> stages;
641 helper_scaling_->ComputeScalerStages(kQualities[quality], 838 helper_scaling_->ComputeScalerStages(kQualities[quality_index],
642 gfx::Size(xsize, ysize), 839 gfx::Size(xsize, ysize),
643 gfx::Rect(0, 0, xsize, ysize), 840 gfx::Rect(0, 0, xsize, ysize),
644 gfx::Size(scaled_xsize, scaled_ysize), 841 gfx::Size(scaled_xsize, scaled_ysize),
645 flip, 842 flip,
646 false, 843 false,
647 &stages); 844 &stages);
648 ValidateScalerStages(kQualities[quality], 845 ValidateScalerStages(kQualities[quality_index],
649 stages, 846 stages,
650 gfx::Size(scaled_xsize, scaled_ysize), 847 gfx::Size(scaled_xsize, scaled_ysize),
651 message); 848 message);
652 849
653 WebGLId dst_texture = 850 WebGLId dst_texture =
654 helper_->CopyAndScaleTexture(src_texture, 851 helper_->CopyAndScaleTexture(src_texture,
655 gfx::Size(xsize, ysize), 852 gfx::Size(xsize, ysize),
656 gfx::Size(scaled_xsize, scaled_ysize), 853 gfx::Size(scaled_xsize, scaled_ysize),
657 flip, 854 flip,
658 kQualities[quality]); 855 kQualities[quality_index]);
659 856
660 SkBitmap output_pixels; 857 SkBitmap output_pixels;
661 output_pixels.allocN32Pixels(scaled_xsize, scaled_ysize); 858 output_pixels.allocPixels(SkImageInfo::Make(scaled_xsize,
859 scaled_ysize,
860 kRGBA_8888_SkColorType,
861 kPremul_SkAlphaType));
662 862
663 helper_->ReadbackTextureSync( 863 helper_->ReadbackTextureSync(
664 dst_texture, 864 dst_texture,
665 gfx::Rect(0, 0, scaled_xsize, scaled_ysize), 865 gfx::Rect(0, 0, scaled_xsize, scaled_ysize),
666 static_cast<unsigned char*>(output_pixels.getPixels()), 866 static_cast<unsigned char*>(output_pixels.getPixels()),
667 kRGBA_8888_SkColorType); 867 kRGBA_8888_SkColorType);
668 if (flip) { 868 if (flip) {
669 // Flip the pixels back. 869 // Flip the pixels back.
670 FlipSKBitmap(&output_pixels); 870 FlipSKBitmap(&output_pixels);
671 } 871 }
872
873 // If the bitmap shouldn't have changed - compare against input.
672 if (xsize == scaled_xsize && ysize == scaled_ysize) { 874 if (xsize == scaled_xsize && ysize == scaled_ysize) {
673 Compare(&input_pixels, 875 Compare(input_pixels.get(),
674 &output_pixels, 876 &output_pixels,
675 2, 877 2,
676 NULL, 878 NULL,
677 stages, 879 stages,
678 message + " comparing against input"); 880 message + " comparing against input");
881 return;
679 } 882 }
883
884 // Now scale the bitmap using the reference implementation.
680 SkBitmap truth_pixels; 885 SkBitmap truth_pixels;
681 truth_pixels.allocN32Pixels(scaled_xsize, scaled_ysize); 886 truth_pixels.allocPixels(SkImageInfo::Make(scaled_xsize,
682 887 scaled_ysize,
683 ScaleSlowRecursive(&input_pixels, &truth_pixels, kQualities[quality]); 888 kRGBA_8888_SkColorType,
889 kPremul_SkAlphaType));
890 ScaleSlowRecursive(
891 input_pixels.get(), &truth_pixels, kQualities[quality_index]);
684 Compare(&truth_pixels, 892 Compare(&truth_pixels,
685 &output_pixels, 893 &output_pixels,
686 2, 894 2,
687 &input_pixels, 895 input_pixels.get(),
688 stages, 896 stages,
689 message + " comparing against scaled"); 897 message + " comparing against scaled");
690 898
691 context_->deleteTexture(src_texture); 899 context_->deleteTexture(src_texture);
692 context_->deleteTexture(dst_texture); 900 context_->deleteTexture(dst_texture);
693 context_->deleteFramebuffer(framebuffer); 901 context_->deleteFramebuffer(framebuffer);
694 } 902 }
695 903
696 // Create a scaling pipeline and check that it is made up of 904 // Create a scaling pipeline and check that it is made up of
697 // valid scaling operations. 905 // valid scaling operations.
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
1006 base::Bind(&callcallback, 1214 base::Bind(&callcallback,
1007 run_loop.QuitClosure())); 1215 run_loop.QuitClosure()));
1008 run_loop.Run(); 1216 run_loop.Run();
1009 } else { 1217 } else {
1010 helper_->ReadbackTextureSync(src_texture, 1218 helper_->ReadbackTextureSync(src_texture,
1011 gfx::Rect(src_size), 1219 gfx::Rect(src_size),
1012 pixels, 1220 pixels,
1013 color_type); 1221 color_type);
1014 } 1222 }
1015 } 1223 }
1016
1017 // Test basic format readback. 1224 // Test basic format readback.
1018 bool TestTextureFormatReadback(const gfx::Size& src_size, 1225 bool TestTextureFormatReadback(const gfx::Size& src_size,
1019 SkColorType color_type, 1226 SkColorType color_type,
1020 bool async) { 1227 bool async) {
1021 SkImageInfo info = 1228 SkImageInfo info =
1022 SkImageInfo::Make(src_size.width(), 1229 SkImageInfo::Make(src_size.width(),
1023 src_size.height(), 1230 src_size.height(),
1024 color_type, 1231 color_type,
1025 kPremul_SkAlphaType); 1232 kPremul_SkAlphaType);
1026 if (!helper_->IsReadbackConfigSupported(color_type)) { 1233 if (!helper_->IsReadbackConfigSupported(color_type)) {
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 } 1800 }
1594 } 1801 }
1595 } 1802 }
1596 } 1803 }
1597 1804
1598 // Per pixel tests, all sizes are small so that we can print 1805 // Per pixel tests, all sizes are small so that we can print
1599 // out the generated bitmaps. 1806 // out the generated bitmaps.
1600 TEST_F(GLHelperPixelTest, ScaleTest) { 1807 TEST_F(GLHelperPixelTest, ScaleTest) {
1601 int sizes[] = {3, 6, 16}; 1808 int sizes[] = {3, 6, 16};
1602 for (int flip = 0; flip <= 1; flip++) { 1809 for (int flip = 0; flip <= 1; flip++) {
1603 for (size_t q = 0; q < arraysize(kQualities); q++) { 1810 for (size_t q_index = 0; q_index < arraysize(kQualities); q_index++) {
1604 for (int x = 0; x < 3; x++) { 1811 for (int x = 0; x < 3; x++) {
1605 for (int y = 0; y < 3; y++) { 1812 for (int y = 0; y < 3; y++) {
1606 for (int dst_x = 0; dst_x < 3; dst_x++) { 1813 for (int dst_x = 0; dst_x < 3; dst_x++) {
1607 for (int dst_y = 0; dst_y < 3; dst_y++) { 1814 for (int dst_y = 0; dst_y < 3; dst_y++) {
1608 for (int pattern = 0; pattern < 3; pattern++) { 1815 for (int pattern = 0; pattern < 3; pattern++) {
1609 TestScale(sizes[x], 1816 TestScale(sizes[x],
1610 sizes[y], 1817 sizes[y],
1611 sizes[dst_x], 1818 sizes[dst_x],
1612 sizes[dst_y], 1819 sizes[dst_y],
1613 pattern, 1820 pattern,
1614 q, 1821 q_index,
1615 flip == 1); 1822 flip == 1);
1616 if (HasFailure()) { 1823 if (HasFailure()) {
1617 return; 1824 return;
1618 } 1825 }
1619 } 1826 }
1620 } 1827 }
1621 } 1828 }
1622 } 1829 }
1623 } 1830 }
1624 } 1831 }
1625 } 1832 }
1626 } 1833 }
1627 1834
1835 // Per pixel tests, all sizes are small so that we can print
1836 // out the generated bitmaps.
1837 TEST_F(GLHelperPixelTest, CropScaleReadbackAndCleanTextureTest) {
1838 const int kSizes[] = {3, 6, 16};
1839 const SkColorType kColorTypes[] = {
1840 kAlpha_8_SkColorType, kRGBA_8888_SkColorType, kBGRA_8888_SkColorType};
1841 for (size_t color_type = 0; color_type < arraysize(kColorTypes);
1842 color_type++) {
1843 // Test BEST and FAST qualities, skip GOOD
1844 for (size_t q_index = 0; q_index < arraysize(kQualities); q_index += 2) {
1845 for (size_t x = 0; x < arraysize(kSizes); x++) {
1846 for (size_t y = 0; y < arraysize(kSizes); y++) {
1847 for (size_t dst_x = 0; dst_x < arraysize(kSizes); dst_x++) {
1848 for (size_t dst_y = 0; dst_y < arraysize(kSizes); dst_y++) {
1849 for (int pattern = 0; pattern < 3; pattern++) {
1850 TestCropScaleReadbackAndCleanTexture(kSizes[x],
1851 kSizes[y],
1852 kSizes[dst_x],
1853 kSizes[dst_y],
1854 pattern,
1855 kColorTypes[color_type],
1856 false,
1857 q_index);
1858 if (HasFailure())
1859 return;
1860 }
1861 }
1862 }
1863 }
1864 }
1865 }
1866 }
1867 }
1868
1628 // Validate that all scaling generates valid pipelines. 1869 // Validate that all scaling generates valid pipelines.
1629 TEST_F(GLHelperTest, ValidateScalerPipelines) { 1870 TEST_F(GLHelperTest, ValidateScalerPipelines) {
1630 int sizes[] = {7, 99, 128, 256, 512, 719, 720, 721, 1920, 2011, 3217, 4096}; 1871 int sizes[] = {7, 99, 128, 256, 512, 719, 720, 721, 1920, 2011, 3217, 4096};
1631 for (size_t q = 0; q < arraysize(kQualities); q++) { 1872 for (size_t q = 0; q < arraysize(kQualities); q++) {
1632 for (size_t x = 0; x < arraysize(sizes); x++) { 1873 for (size_t x = 0; x < arraysize(sizes); x++) {
1633 for (size_t y = 0; y < arraysize(sizes); y++) { 1874 for (size_t y = 0; y < arraysize(sizes); y++) {
1634 for (size_t dst_x = 0; dst_x < arraysize(sizes); dst_x++) { 1875 for (size_t dst_x = 0; dst_x < arraysize(sizes); dst_x++) {
1635 for (size_t dst_y = 0; dst_y < arraysize(sizes); dst_y++) { 1876 for (size_t dst_y = 0; dst_y < arraysize(sizes); dst_y++) {
1636 TestScalerPipeline( 1877 TestScalerPipeline(
1637 q, sizes[x], sizes[y], sizes[dst_x], sizes[dst_y]); 1878 q, sizes[x], sizes[y], sizes[dst_x], sizes[dst_y]);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 base::CommandLine::Init(argc, argv); 1942 base::CommandLine::Init(argc, argv);
1702 base::TestSuite* suite = new content::ContentTestSuite(argc, argv); 1943 base::TestSuite* suite = new content::ContentTestSuite(argc, argv);
1703 #if defined(OS_MACOSX) 1944 #if defined(OS_MACOSX)
1704 base::mac::ScopedNSAutoreleasePool pool; 1945 base::mac::ScopedNSAutoreleasePool pool;
1705 #endif 1946 #endif
1706 1947
1707 content::UnitTestTestSuite runner(suite); 1948 content::UnitTestTestSuite runner(suite);
1708 base::MessageLoop message_loop; 1949 base::MessageLoop message_loop;
1709 return runner.Run(); 1950 return runner.Run();
1710 } 1951 }
OLDNEW
« no previous file with comments | « content/common/gpu/client/gl_helper.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698