gl_scaler_test_util.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. // Copyright 2018 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 "components/viz/test/gl_scaler_test_util.h"
  5. #include <algorithm>
  6. #include <cmath>
  7. #include <ostream>
  8. #include "base/check_op.h"
  9. #include "base/notreached.h"
  10. #include "third_party/skia/include/core/SkColor.h"
  11. #include "third_party/skia/include/core/SkImageInfo.h"
  12. #include "ui/gfx/geometry/rect.h"
  13. namespace viz {
  14. using ColorBar = GLScalerTestUtil::ColorBar;
  15. // static
  16. SkBitmap GLScalerTestUtil::AllocateRGBABitmap(const gfx::Size& size) {
  17. SkBitmap bitmap;
  18. bitmap.allocPixels(SkImageInfo::Make(size.width(), size.height(),
  19. kRGBA_8888_SkColorType,
  20. kUnpremul_SkAlphaType));
  21. return bitmap;
  22. }
  23. // static
  24. uint8_t GLScalerTestUtil::ToClamped255(float value) {
  25. value = std::fma(value, 255.0f, 0.5f /* rounding */);
  26. return base::saturated_cast<uint8_t>(value);
  27. }
  28. // static
  29. std::vector<ColorBar> GLScalerTestUtil::GetScaledSMPTEColorBars(
  30. const gfx::Size& size) {
  31. std::vector<ColorBar> rects;
  32. const SkScalar scale_x =
  33. static_cast<SkScalar>(size.width()) / kSMPTEFullSize.width();
  34. const SkScalar scale_y =
  35. static_cast<SkScalar>(size.height()) / kSMPTEFullSize.height();
  36. for (const auto& cr : kSMPTEColorBars) {
  37. const SkRect rect =
  38. SkRect{cr.rect.fLeft * scale_x, cr.rect.fTop * scale_y,
  39. cr.rect.fRight * scale_x, cr.rect.fBottom * scale_y};
  40. rects.push_back(ColorBar{rect.round(), cr.color});
  41. }
  42. return rects;
  43. }
  44. // static
  45. SkBitmap GLScalerTestUtil::CreateSMPTETestImage(const gfx::Size& size) {
  46. SkBitmap result = AllocateRGBABitmap(size);
  47. // Set all pixels to a color that should not exist in the result. Later, a
  48. // sanity-check will ensure all pixels have been overwritten.
  49. constexpr SkColor4f kDeadColor = SkColor4f{0.678f, 0.745f, 0.937f, 0.871f};
  50. result.eraseColor(kDeadColor);
  51. // Set the pixels corresponding to each color bar.
  52. for (const auto& cr : GetScaledSMPTEColorBars(size)) {
  53. result.erase(cr.color, cr.rect);
  54. }
  55. // Validate that every pixel in the result bitmap has been touched by one of
  56. // the color bars.
  57. for (int y = 0; y < result.height(); ++y) {
  58. for (int x = 0; x < result.width(); ++x) {
  59. if (result.getColor4f(x, y) == kDeadColor) {
  60. NOTREACHED() << "TEST BUG: Error creating SMPTE test image. Bad size ("
  61. << size.ToString() << ")?";
  62. return result;
  63. }
  64. }
  65. }
  66. return result;
  67. }
  68. // static
  69. bool GLScalerTestUtil::LooksLikeSMPTETestImage(const SkBitmap& image,
  70. const gfx::Size& src_size,
  71. const gfx::Rect& src_rect,
  72. int fuzzy_pixels,
  73. float* max_color_diff) {
  74. if (image.width() <= 0 || image.height() <= 0) {
  75. return false;
  76. }
  77. const SkScalar offset_x = static_cast<SkScalar>(src_rect.x());
  78. const SkScalar offset_y = static_cast<SkScalar>(src_rect.y());
  79. const SkScalar scale_x =
  80. static_cast<SkScalar>(image.width()) / src_rect.width();
  81. const SkScalar scale_y =
  82. static_cast<SkScalar>(image.height()) / src_rect.height();
  83. float measured_max_diff = 0.0f;
  84. for (const auto& cr : GetScaledSMPTEColorBars(src_size)) {
  85. const SkIRect offset_rect = cr.rect.makeOffset(-offset_x, -offset_y);
  86. const SkIRect rect =
  87. SkRect{offset_rect.fLeft * scale_x, offset_rect.fTop * scale_y,
  88. offset_rect.fRight * scale_x, offset_rect.fBottom * scale_y}
  89. .round()
  90. .makeInset(fuzzy_pixels, fuzzy_pixels);
  91. for (int y = std::max(0, rect.fTop),
  92. y_end = std::min(image.height(), rect.fBottom);
  93. y < y_end; ++y) {
  94. for (int x = std::max(0, rect.fLeft),
  95. x_end = std::min(image.width(), rect.fRight);
  96. x < x_end; ++x) {
  97. const SkColor4f actual = image.getColor4f(x, y);
  98. measured_max_diff =
  99. std::max({measured_max_diff, std::abs((cr.color.fR) - (actual.fR)),
  100. std::abs((cr.color.fG) - (actual.fG)),
  101. std::abs((cr.color.fB) - (actual.fB)),
  102. std::abs((cr.color.fA) - (actual.fA))});
  103. }
  104. }
  105. }
  106. if (max_color_diff) {
  107. const int threshold = *max_color_diff;
  108. *max_color_diff = measured_max_diff;
  109. return measured_max_diff <= threshold;
  110. }
  111. return measured_max_diff == 0.0f;
  112. }
  113. // static
  114. SkBitmap GLScalerTestUtil::CreateCyclicalTestImage(
  115. const gfx::Size& size,
  116. CyclicalPattern pattern,
  117. const std::vector<SkColor4f>& cycle,
  118. size_t rotation) {
  119. CHECK(!cycle.empty());
  120. // Map SkColors to RGBA data. Also, applies the cycle |rotation| to simplify
  121. // the rest of the code below.
  122. std::vector<uint32_t> cycle_as_rgba(cycle.size());
  123. for (size_t i = 0; i < cycle.size(); ++i) {
  124. const SkColor4f color = cycle[(i + rotation) % cycle.size()];
  125. cycle_as_rgba[i] = ((static_cast<int>(color.fR * 255) << kRedShift) |
  126. (static_cast<int>(color.fG * 255) << kGreenShift) |
  127. (static_cast<int>(color.fB * 255) << kBlueShift) |
  128. (static_cast<int>(color.fA * 255) << kAlphaShift));
  129. }
  130. SkBitmap result = AllocateRGBABitmap(size);
  131. switch (pattern) {
  132. case HORIZONTAL_STRIPES:
  133. for (int y = 0; y < size.height(); ++y) {
  134. uint32_t* const pixels = result.getAddr32(0, y);
  135. const uint32_t stripe_rgba = cycle_as_rgba[y % cycle_as_rgba.size()];
  136. for (int x = 0; x < size.width(); ++x) {
  137. pixels[x] = stripe_rgba;
  138. }
  139. }
  140. break;
  141. case VERTICAL_STRIPES:
  142. for (int y = 0; y < size.height(); ++y) {
  143. uint32_t* const pixels = result.getAddr32(0, y);
  144. for (int x = 0; x < size.width(); ++x) {
  145. pixels[x] = cycle_as_rgba[x % cycle_as_rgba.size()];
  146. }
  147. }
  148. break;
  149. case STAGGERED:
  150. for (int y = 0; y < size.height(); ++y) {
  151. uint32_t* const pixels = result.getAddr32(0, y);
  152. for (int x = 0; x < size.width(); ++x) {
  153. pixels[x] = cycle_as_rgba[(x + y) % cycle_as_rgba.size()];
  154. }
  155. }
  156. break;
  157. }
  158. return result;
  159. }
  160. // static
  161. gfx::ColorSpace GLScalerTestUtil::DefaultRGBColorSpace() {
  162. return gfx::ColorSpace::CreateSRGB();
  163. }
  164. // static
  165. gfx::ColorSpace GLScalerTestUtil::DefaultYUVColorSpace() {
  166. return gfx::ColorSpace::CreateREC709();
  167. }
  168. // static
  169. void GLScalerTestUtil::ConvertRGBABitmapToYUV(SkBitmap* image) {
  170. CHECK_EQ(image->colorType(), kRGBA_8888_SkColorType);
  171. const auto transform = gfx::ColorTransform::NewColorTransform(
  172. DefaultRGBColorSpace(), DefaultYUVColorSpace());
  173. // Loop, transforming one row of pixels at a time.
  174. std::vector<gfx::ColorTransform::TriStim> stims(image->width());
  175. for (int y = 0; y < image->height(); ++y) {
  176. uint32_t* const pixels = image->getAddr32(0, y);
  177. for (int x = 0; x < image->width(); ++x) {
  178. stims[x].set_x(((pixels[x] >> kRedShift) & 0xff) / 255.0f);
  179. stims[x].set_y(((pixels[x] >> kGreenShift) & 0xff) / 255.0f);
  180. stims[x].set_z(((pixels[x] >> kBlueShift) & 0xff) / 255.0f);
  181. }
  182. transform->Transform(stims.data(), stims.size());
  183. for (int x = 0; x < image->width(); ++x) {
  184. pixels[x] = ((ToClamped255(stims[x].x()) << kRedShift) |
  185. (ToClamped255(stims[x].y()) << kGreenShift) |
  186. (ToClamped255(stims[x].z()) << kBlueShift) |
  187. (((pixels[x] >> kAlphaShift) & 0xff) << kAlphaShift));
  188. }
  189. }
  190. }
  191. // static
  192. SkBitmap GLScalerTestUtil::CopyAndConvertToRGBA(const SkBitmap& bitmap) {
  193. SkBitmap result;
  194. result.allocPixels(SkImageInfo::Make(
  195. bitmap.dimensions(), kRGBA_8888_SkColorType, kPremul_SkAlphaType));
  196. SkPixmap pixmap;
  197. bool success = bitmap.peekPixels(&pixmap) && result.writePixels(pixmap, 0, 0);
  198. CHECK(success);
  199. return result;
  200. }
  201. // static
  202. void GLScalerTestUtil::SwizzleBitmap(SkBitmap* image) {
  203. for (int y = 0; y < image->height(); ++y) {
  204. uint32_t* const pixels = image->getAddr32(0, y);
  205. for (int x = 0; x < image->width(); ++x) {
  206. pixels[x] = ((((pixels[x] >> kBlueShift) & 0xff) << kRedShift) |
  207. (((pixels[x] >> kGreenShift) & 0xff) << kGreenShift) |
  208. (((pixels[x] >> kRedShift) & 0xff) << kBlueShift) |
  209. (((pixels[x] >> kAlphaShift) & 0xff) << kAlphaShift));
  210. }
  211. }
  212. }
  213. // static
  214. SkBitmap GLScalerTestUtil::CreatePackedPlanarBitmap(const SkBitmap& source,
  215. int channel) {
  216. CHECK_EQ(source.width() % 4, 0);
  217. SkBitmap result =
  218. AllocateRGBABitmap(gfx::Size(source.width() / 4, source.height()));
  219. constexpr int kShiftForChannel[4] = {kRedShift, kGreenShift, kBlueShift,
  220. kAlphaShift};
  221. const int shift = kShiftForChannel[channel];
  222. for (int y = 0; y < result.height(); ++y) {
  223. const uint32_t* const src = source.getAddr32(0, y);
  224. uint32_t* const dst = result.getAddr32(0, y);
  225. for (int x = 0; x < result.width(); ++x) {
  226. // (src[0..3]) (dst)
  227. // RGBA RGBA RGBA RGBA --> RRRR (if channel is 0)
  228. dst[x] = ((((src[x * 4 + 0] >> shift) & 0xff) << kRedShift) |
  229. (((src[x * 4 + 1] >> shift) & 0xff) << kGreenShift) |
  230. (((src[x * 4 + 2] >> shift) & 0xff) << kBlueShift) |
  231. (((src[x * 4 + 3] >> shift) & 0xff) << kAlphaShift));
  232. }
  233. }
  234. return result;
  235. }
  236. // static
  237. void GLScalerTestUtil::UnpackPlanarBitmap(const SkBitmap& plane,
  238. int channel,
  239. SkBitmap* out) {
  240. // The heuristic below auto-adapts to subsampled plane sizes. However, there
  241. // are two cricital requirements: 1) |plane| cannot be empty; 2) |plane| must
  242. // have a size that cleanly unpacks to |out|'s size.
  243. CHECK_GT(plane.width(), 0);
  244. CHECK_GT(plane.height(), 0);
  245. const int col_sampling_ratio = out->width() / plane.width();
  246. CHECK_EQ(out->width() % plane.width(), 0)
  247. << " out->width()=" << out->width()
  248. << ", plane.width()=" << plane.width();
  249. CHECK_GT(col_sampling_ratio, 0);
  250. const int row_sampling_ratio = out->height() / plane.height();
  251. CHECK_EQ(out->height() % plane.height(), 0);
  252. CHECK_GT(row_sampling_ratio, 0);
  253. const int ch_sampling_ratio = col_sampling_ratio / 4;
  254. CHECK_GT(ch_sampling_ratio, 0);
  255. // These determine which single byte in each of |out|'s uint32_t-valued pixels
  256. // will be modified.
  257. constexpr int kShiftForChannel[4] = {kRedShift, kGreenShift, kBlueShift,
  258. kAlphaShift};
  259. const int output_shift = kShiftForChannel[channel];
  260. const uint32_t output_retain_mask = ~(UINT32_C(0xff) << output_shift);
  261. // Iterate over the pixels of |out|, sampling each of the 4 components of each
  262. // of |plane|'s pixels.
  263. for (int y = 0; y < out->height(); ++y) {
  264. const uint32_t* const src = plane.getAddr32(0, y / row_sampling_ratio);
  265. uint32_t* const dst = out->getAddr32(0, y);
  266. for (int x = 0; x < out->width(); ++x) {
  267. // Zero-out the existing byte (e.g., if channel==1, then "RGBA" → "R0BA").
  268. dst[x] &= output_retain_mask;
  269. // From |src|, grab one of "XYZW". Then, copy it to the target byte in
  270. // |dst| (e.g., if x_src_ch=3, then grab "W" from |src|, and |dst| changes
  271. // from "R0BA" to "RWBA").
  272. const int x_src = x / col_sampling_ratio;
  273. const int x_src_ch = (x / ch_sampling_ratio) % 4;
  274. dst[x] |= ((src[x_src] >> kShiftForChannel[x_src_ch]) & 0xff)
  275. << output_shift;
  276. }
  277. }
  278. }
  279. // static
  280. void GLScalerTestUtil::UnpackUVBitmap(const SkBitmap& plane, SkBitmap* out) {
  281. CHECK_GT(plane.width(), 0);
  282. CHECK_GT(plane.height(), 0);
  283. // The format of data in |plane| is as follows:
  284. //
  285. // UVUV UVUV UVUV
  286. // UVUV UVUV UVUV
  287. // UVUV UVUV UVUV
  288. //
  289. // One row of source of size |plane.width()| contains information about
  290. // 2 * |plane.width()| texels, and we want to sample them to populate
  291. // one row of |out->width()|, so we'll sample at the rate of
  292. //
  293. // col_sampling_ratio = out->width() / (2 * plane.width())
  294. //
  295. // This will allow us to find which "half-texel" in the source row to look at
  296. // for a corresponding texel in the output.
  297. const int col_sampling_ratio = out->width() / (2 * plane.width());
  298. CHECK_EQ(out->width() % (2 * plane.width()), 0);
  299. CHECK_GT(col_sampling_ratio, 0);
  300. const int row_sampling_ratio = out->height() / plane.height();
  301. CHECK_EQ(out->height() % plane.height(), 0);
  302. CHECK_GT(row_sampling_ratio, 0);
  303. // These determine which single byte in each of |out|'s uint32_t-valued pixels
  304. // will be modified.
  305. constexpr int kShiftForChannel[4] = {kRedShift, kGreenShift, kBlueShift,
  306. kAlphaShift};
  307. constexpr uint32_t zero_green_mask = ~(UINT32_C(0xff) << kGreenShift);
  308. constexpr uint32_t zero_blue_mask = ~(UINT32_C(0xff) << kBlueShift);
  309. constexpr uint32_t zero_green_blue_mask = zero_green_mask & zero_blue_mask;
  310. // Iterate over all the pixels of |out|, calculate where the data for that
  311. // said pixel is.
  312. for (int y = 0; y < out->height(); ++y) {
  313. const uint32_t* const src = plane.getAddr32(0, y / row_sampling_ratio);
  314. uint32_t* const dst = out->getAddr32(0, y);
  315. for (int x = 0; x < out->width(); ++x) {
  316. // Zero-out the existing byte (e.g., "RGBA" → "R00A").
  317. dst[x] &= zero_green_blue_mask;
  318. // Find which half-texel to look at:
  319. const int src_half_texel = x / col_sampling_ratio;
  320. // The |src_half_texel| belongs to a texel:
  321. const int src_texel = src_half_texel / 2;
  322. // The |src_half_texel| spans 2 channels and starts at channel:
  323. const int src_channel = 2 * (src_half_texel % 2);
  324. // Grab the 2 consecutive channels, starting at |src_channel|:
  325. dst[x] |= ((src[src_texel] >> kShiftForChannel[src_channel]) & 0xff)
  326. << kGreenShift;
  327. dst[x] |= ((src[src_texel] >> kShiftForChannel[src_channel + 1]) & 0xff)
  328. << kBlueShift;
  329. }
  330. }
  331. }
  332. // static
  333. SkBitmap GLScalerTestUtil::CreateVerticallyFlippedBitmap(
  334. const SkBitmap& source) {
  335. SkBitmap bitmap;
  336. bitmap.allocPixels(source.info());
  337. CHECK_EQ(bitmap.rowBytes(), source.rowBytes());
  338. for (int y = 0; y < bitmap.height(); ++y) {
  339. const int src_y = bitmap.height() - y - 1;
  340. memcpy(bitmap.getAddr32(0, y), source.getAddr32(0, src_y),
  341. bitmap.rowBytes());
  342. }
  343. return bitmap;
  344. }
  345. // The area and color of the bars in a 1920x1080 HD SMPTE color bars test image
  346. // (https://commons.wikimedia.org/wiki/File:SMPTE_Color_Bars_16x9.svg). The gray
  347. // linear gradient bar is defined as half solid 0-level black and half solid
  348. // full-intensity white).
  349. const ColorBar GLScalerTestUtil::kSMPTEColorBars[30] = {
  350. {{0, 240, 630}, SkColor4f{0.4f, 0.4f, 0.4f, 1.0f}},
  351. {{240, 0, 445, 630}, SkColor4f{0.749f, 0.749f, 0.749f, 1.0f}},
  352. {{0, 651, 445, 630}, SkColor4f{0.749f, 0.749f, 0.0f, 1.0f}},
  353. {{0, 857, 651, 630}, SkColor4f{0.0f, 0.749f, 0.749f, 1.0f}},
  354. {{0, 857, 630, 1063}, SkColor4f{0.0f, 0.749f, 0.0f, 1.0f}},
  355. {{0, 1269, 630, 1063}, SkColor4f{0.749f, 0.0f, 0.749f, 1.0f}},
  356. {{0, 1475, 1269, 630}, SkColor4f{0.749f, 0.0f, 0.0f, 1.0f}},
  357. {{0, 1475, 1680, 630}, SkColor4f{0.0f, 0.0f, 0.749f, 1.0f}},
  358. {{1680, 0, 1920, 630}, SkColor4f{0.4f, 0.4f, 0.4f, 1.0f}},
  359. {{0, 240, 630, 720}, SkColor4f{0.0f, 1.0f, 1.0f, 1.0f}},
  360. {{240, 445, 630, 720}, SkColor4f{0.0f, 0.129f, 0.298f, 1.0f}},
  361. {{1680, 445, 630, 720}, SkColor4f{0.749f, 0.749f, 0.749f, 1.0f}},
  362. {{1680, 1920, 630, 720}, SkColor4f{0.0f, 0.0f, 1.0f, 1.0f}},
  363. {{0, 240, 810, 720}, SkColor4f{1.0f, 1.0f, 0.0f, 1.0f}},
  364. {{240, 810, 445, 720}, SkColor4f{0.196f, 0.0f, 0.416f, 1.0f}},
  365. {{720, 810, 445, 1063}, SkColor4f{0.0f, 0.0f, 0.0f, 1.0f}},
  366. {{720, 810, 1680, 1063}, SkColor4f{1.0f, 1.0f, 1.0f, 1.0f}},
  367. {{1680, 810, 1920, 720}, SkColor4f{1.0f, 0.0f, 0.0f, 1.0f}},
  368. {{0, 240, 810, 1080}, SkColor4f{0.149f, 0.149f, 0.149f, 1.0f}},
  369. {{240, 810, 1080, 549}, SkColor4f{0.0f, 0.0f, 0.0f, 1.0f}},
  370. {{960, 810, 1080, 549}, SkColor4f{1.0f, 1.0f, 1.0f, 1.0f}},
  371. {{960, 810, 1131, 1080}, SkColor4f{0.0f, 0.0f, 0.0f, 1.0f}},
  372. {{1200, 810, 1131, 1080}, SkColor4f{0.0f, 0.0f, 0.0f, 1.0f}},
  373. {{1200, 810, 1268, 1080}, SkColor4f{0.0f, 0.0f, 0.0f, 1.0f}},
  374. {{1080, 1337, 810, 1268}, SkColor4f{0.02f, 0.02f, 0.02f, 1.0f}},
  375. {{1080, 1337, 810, 1405}, SkColor4f{0.0f, 0.0f, 0.0f, 1.0f}},
  376. {{1080, 1474, 810, 1405}, SkColor4f{0.039f, 0.039f, 0.039f, 1.0f}},
  377. {{1680, 1474, 810, 1080}, SkColor4f{0.0f, 0.0f, 0.0f, 1.0f}},
  378. {{1680, 810, 1080, 1920}, SkColor4f{0.149f, 0.149f, 0.149f, 1.0f}},
  379. };
  380. constexpr gfx::Size GLScalerTestUtil::kSMPTEFullSize;
  381. GLScalerTestTextureHelper::GLScalerTestTextureHelper(
  382. gpu::gles2::GLES2Interface* gl)
  383. : gl_(gl) {
  384. CHECK(gl_);
  385. }
  386. GLScalerTestTextureHelper::~GLScalerTestTextureHelper() {
  387. gl_->DeleteTextures(textures_to_delete_.size(), textures_to_delete_.data());
  388. textures_to_delete_.clear();
  389. }
  390. GLuint GLScalerTestTextureHelper::CreateTexture(const gfx::Size& size) {
  391. GLuint texture = 0;
  392. gl_->GenTextures(1, &texture);
  393. gl_->BindTexture(GL_TEXTURE_2D, texture);
  394. gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  395. gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  396. gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  397. gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  398. gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0,
  399. GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
  400. gl_->BindTexture(GL_TEXTURE_2D, 0);
  401. if (texture) {
  402. textures_to_delete_.push_back(texture);
  403. }
  404. return texture;
  405. }
  406. GLuint GLScalerTestTextureHelper::UploadTexture(const SkBitmap& bitmap) {
  407. CHECK_EQ(bitmap.colorType(), kRGBA_8888_SkColorType);
  408. GLuint texture = 0;
  409. gl_->GenTextures(1, &texture);
  410. gl_->BindTexture(GL_TEXTURE_2D, texture);
  411. gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  412. gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  413. gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  414. gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  415. gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap.width(), bitmap.height(), 0,
  416. GL_RGBA, GL_UNSIGNED_BYTE, bitmap.getAddr32(0, 0));
  417. gl_->BindTexture(GL_TEXTURE_2D, 0);
  418. if (texture) {
  419. textures_to_delete_.push_back(texture);
  420. }
  421. return texture;
  422. }
  423. SkBitmap GLScalerTestTextureHelper::DownloadTexture(GLuint texture,
  424. const gfx::Size& size) {
  425. GLuint framebuffer = 0;
  426. gl_->GenFramebuffers(1, &framebuffer);
  427. gl_->BindFramebuffer(GL_FRAMEBUFFER, framebuffer);
  428. gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  429. texture, 0);
  430. SkBitmap result = GLScalerTestUtil::AllocateRGBABitmap(size);
  431. gl_->ReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_BYTE,
  432. result.getAddr32(0, 0));
  433. gl_->DeleteFramebuffers(1, &framebuffer);
  434. return result;
  435. }
  436. } // namespace viz