blit_unittest.cc 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // Copyright (c) 2010 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <stdint.h>
  5. #include "base/memory/platform_shared_memory_region.h"
  6. #include "build/build_config.h"
  7. #include "skia/ext/platform_canvas.h"
  8. #include "testing/gtest/include/gtest/gtest.h"
  9. #include "ui/gfx/blit.h"
  10. #include "ui/gfx/geometry/point.h"
  11. #include "ui/gfx/geometry/rect.h"
  12. namespace {
  13. // Fills the given canvas with the values by duplicating the values into each
  14. // color channel for the corresponding pixel.
  15. //
  16. // Example values = {{0x0, 0x01}, {0x12, 0xFF}} would give a canvas with:
  17. // 0x00000000 0x01010101
  18. // 0x12121212 0xFFFFFFFF
  19. template <int w, int h>
  20. void SetToCanvas(SkCanvas* canvas, uint8_t values[h][w]) {
  21. ASSERT_EQ(w, canvas->imageInfo().width());
  22. ASSERT_EQ(h, canvas->imageInfo().height());
  23. // This wouldn't be necessary if we extended the values in the inputs, but
  24. // the uint8_t values are a little bit easier to read and maintain.
  25. uint32_t extendedValues[w*h];
  26. for (int y = 0; y < h; y++) {
  27. for (int x = 0; x < w; x++) {
  28. uint8_t value = values[y][x];
  29. extendedValues[y*w+x] =
  30. (value << 24) | (value << 16) | (value << 8) | value;
  31. }
  32. }
  33. SkImageInfo info = SkImageInfo::MakeN32Premul(w, h);
  34. canvas->writePixels(info, extendedValues, w*4, 0, 0);
  35. }
  36. // Checks each pixel in the given canvas and see if it is made up of the given
  37. // values, where each value has been duplicated into each channel of the given
  38. // bitmap (see SetToCanvas above).
  39. template <int w, int h>
  40. void VerifyCanvasValues(SkCanvas* canvas, uint8_t values[h][w]) {
  41. SkBitmap bitmap = skia::ReadPixels(canvas);
  42. ASSERT_EQ(w, bitmap.width());
  43. ASSERT_EQ(h, bitmap.height());
  44. for (int y = 0; y < h; y++) {
  45. for (int x = 0; x < w; x++) {
  46. uint8_t value = values[y][x];
  47. uint32_t expected = (value << 24) | (value << 16) | (value << 8) | value;
  48. ASSERT_EQ(expected, *bitmap.getAddr32(x, y));
  49. }
  50. }
  51. }
  52. } // namespace
  53. TEST(Blit, ScrollCanvas) {
  54. static const int kCanvasWidth = 5;
  55. static const int kCanvasHeight = 5;
  56. std::unique_ptr<SkCanvas> canvas =
  57. skia::CreatePlatformCanvas(kCanvasWidth, kCanvasHeight, false);
  58. uint8_t initial_values[kCanvasHeight][kCanvasWidth] = {
  59. {0x00, 0x01, 0x02, 0x03, 0x04},
  60. {0x10, 0x11, 0x12, 0x13, 0x14},
  61. {0x20, 0x21, 0x22, 0x23, 0x24},
  62. {0x30, 0x31, 0x32, 0x33, 0x34},
  63. {0x40, 0x41, 0x42, 0x43, 0x44}};
  64. SetToCanvas<5, 5>(canvas.get(), initial_values);
  65. // Sanity check on input.
  66. VerifyCanvasValues<5, 5>(canvas.get(), initial_values);
  67. // Scroll none and make sure it's a NOP.
  68. gfx::ScrollCanvas(canvas.get(),
  69. gfx::Rect(0, 0, kCanvasWidth, kCanvasHeight),
  70. gfx::Vector2d(0, 0));
  71. VerifyCanvasValues<5, 5>(canvas.get(), initial_values);
  72. // Scroll with a empty clip and make sure it's a NOP.
  73. gfx::Rect empty_clip(1, 1, 0, 0);
  74. gfx::ScrollCanvas(canvas.get(), empty_clip, gfx::Vector2d(0, 1));
  75. VerifyCanvasValues<5, 5>(canvas.get(), initial_values);
  76. // Scroll the center 3 pixels up one.
  77. gfx::Rect center_three(1, 1, 3, 3);
  78. gfx::ScrollCanvas(canvas.get(), center_three, gfx::Vector2d(0, -1));
  79. uint8_t scroll_up_expected[kCanvasHeight][kCanvasWidth] = {
  80. {0x00, 0x01, 0x02, 0x03, 0x04},
  81. {0x10, 0x21, 0x22, 0x23, 0x14},
  82. {0x20, 0x31, 0x32, 0x33, 0x24},
  83. {0x30, 0x31, 0x32, 0x33, 0x34},
  84. {0x40, 0x41, 0x42, 0x43, 0x44}};
  85. VerifyCanvasValues<5, 5>(canvas.get(), scroll_up_expected);
  86. // Reset and scroll the center 3 pixels down one.
  87. SetToCanvas<5, 5>(canvas.get(), initial_values);
  88. gfx::ScrollCanvas(canvas.get(), center_three, gfx::Vector2d(0, 1));
  89. uint8_t scroll_down_expected[kCanvasHeight][kCanvasWidth] = {
  90. {0x00, 0x01, 0x02, 0x03, 0x04},
  91. {0x10, 0x11, 0x12, 0x13, 0x14},
  92. {0x20, 0x11, 0x12, 0x13, 0x24},
  93. {0x30, 0x21, 0x22, 0x23, 0x34},
  94. {0x40, 0x41, 0x42, 0x43, 0x44}};
  95. VerifyCanvasValues<5, 5>(canvas.get(), scroll_down_expected);
  96. // Reset and scroll the center 3 pixels right one.
  97. SetToCanvas<5, 5>(canvas.get(), initial_values);
  98. gfx::ScrollCanvas(canvas.get(), center_three, gfx::Vector2d(1, 0));
  99. uint8_t scroll_right_expected[kCanvasHeight][kCanvasWidth] = {
  100. {0x00, 0x01, 0x02, 0x03, 0x04},
  101. {0x10, 0x11, 0x11, 0x12, 0x14},
  102. {0x20, 0x21, 0x21, 0x22, 0x24},
  103. {0x30, 0x31, 0x31, 0x32, 0x34},
  104. {0x40, 0x41, 0x42, 0x43, 0x44}};
  105. VerifyCanvasValues<5, 5>(canvas.get(), scroll_right_expected);
  106. // Reset and scroll the center 3 pixels left one.
  107. SetToCanvas<5, 5>(canvas.get(), initial_values);
  108. gfx::ScrollCanvas(canvas.get(), center_three, gfx::Vector2d(-1, 0));
  109. uint8_t scroll_left_expected[kCanvasHeight][kCanvasWidth] = {
  110. {0x00, 0x01, 0x02, 0x03, 0x04},
  111. {0x10, 0x12, 0x13, 0x13, 0x14},
  112. {0x20, 0x22, 0x23, 0x23, 0x24},
  113. {0x30, 0x32, 0x33, 0x33, 0x34},
  114. {0x40, 0x41, 0x42, 0x43, 0x44}};
  115. VerifyCanvasValues<5, 5>(canvas.get(), scroll_left_expected);
  116. // Diagonal scroll.
  117. SetToCanvas<5, 5>(canvas.get(), initial_values);
  118. gfx::ScrollCanvas(canvas.get(), center_three, gfx::Vector2d(2, 2));
  119. uint8_t scroll_diagonal_expected[kCanvasHeight][kCanvasWidth] = {
  120. {0x00, 0x01, 0x02, 0x03, 0x04},
  121. {0x10, 0x11, 0x12, 0x13, 0x14},
  122. {0x20, 0x21, 0x22, 0x23, 0x24},
  123. {0x30, 0x31, 0x32, 0x11, 0x34},
  124. {0x40, 0x41, 0x42, 0x43, 0x44}};
  125. VerifyCanvasValues<5, 5>(canvas.get(), scroll_diagonal_expected);
  126. }
  127. #if BUILDFLAG(IS_WIN)
  128. TEST(Blit, WithSharedMemory) {
  129. const int kCanvasWidth = 5;
  130. const int kCanvasHeight = 5;
  131. base::subtle::PlatformSharedMemoryRegion section =
  132. base::subtle::PlatformSharedMemoryRegion::CreateWritable(kCanvasWidth *
  133. kCanvasHeight);
  134. ASSERT_TRUE(section.IsValid());
  135. std::unique_ptr<SkCanvas> canvas =
  136. skia::CreatePlatformCanvasWithSharedSection(
  137. kCanvasWidth, kCanvasHeight, false, section.GetPlatformHandle(),
  138. skia::RETURN_NULL_ON_FAILURE);
  139. ASSERT_TRUE(canvas);
  140. // Closes a HANDLE associated with |section|, |canvas| must remain valid.
  141. section = base::subtle::PlatformSharedMemoryRegion();
  142. uint8_t initial_values[kCanvasHeight][kCanvasWidth] = {
  143. {0x00, 0x01, 0x02, 0x03, 0x04},
  144. {0x10, 0x11, 0x12, 0x13, 0x14},
  145. {0x20, 0x21, 0x22, 0x23, 0x24},
  146. {0x30, 0x31, 0x32, 0x33, 0x34},
  147. {0x40, 0x41, 0x42, 0x43, 0x44}};
  148. SetToCanvas<5, 5>(canvas.get(), initial_values);
  149. // Sanity check on input.
  150. VerifyCanvasValues<5, 5>(canvas.get(), initial_values);
  151. }
  152. #endif