Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / media / blink / skcanvas_video_renderer_unittest.cc
blobdec29bf7eb8370ac38dae653b0443c1e94a91c56
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
3 // found in the LICENSE file.
5 #include "base/message_loop/message_loop.h"
6 #include "gpu/GLES2/gl2extchromium.h"
7 #include "gpu/command_buffer/client/gles2_interface_stub.h"
8 #include "media/base/timestamp_constants.h"
9 #include "media/base/video_frame.h"
10 #include "media/base/video_util.h"
11 #include "media/blink/skcanvas_video_renderer.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/skia/include/core/SkCanvas.h"
14 #include "third_party/skia/include/gpu/GrContext.h"
15 #include "third_party/skia/include/gpu/gl/GrGLInterface.h"
16 #include "ui/gfx/geometry/rect_f.h"
18 using media::VideoFrame;
20 namespace media {
22 static const int kWidth = 320;
23 static const int kHeight = 240;
24 static const gfx::RectF kNaturalRect(kWidth, kHeight);
26 // Helper for filling a |canvas| with a solid |color|.
27 void FillCanvas(SkCanvas* canvas, SkColor color) {
28 canvas->clear(color);
31 // Helper for returning the color of a solid |canvas|.
32 SkColor GetColorAt(SkCanvas* canvas, int x, int y) {
33 SkBitmap bitmap;
34 if (!bitmap.tryAllocN32Pixels(1, 1))
35 return 0;
36 if (!canvas->readPixels(&bitmap, x, y))
37 return 0;
38 return bitmap.getColor(0, 0);
41 SkColor GetColor(SkCanvas* canvas) {
42 return GetColorAt(canvas, 0, 0);
45 class SkCanvasVideoRendererTest : public testing::Test {
46 public:
47 enum Color {
48 kNone,
49 kRed,
50 kGreen,
51 kBlue,
54 SkCanvasVideoRendererTest();
55 ~SkCanvasVideoRendererTest() override;
57 // Paints to |canvas| using |renderer_| without any frame data.
58 void PaintWithoutFrame(SkCanvas* canvas);
60 // Paints the |video_frame| to the |canvas| using |renderer_|, setting the
61 // color of |video_frame| to |color| first.
62 void Paint(const scoped_refptr<VideoFrame>& video_frame,
63 SkCanvas* canvas,
64 Color color);
65 void PaintRotated(const scoped_refptr<VideoFrame>& video_frame,
66 SkCanvas* canvas,
67 const gfx::RectF& dest_rect,
68 Color color,
69 SkXfermode::Mode mode,
70 VideoRotation video_rotation);
72 void Copy(const scoped_refptr<VideoFrame>& video_frame, SkCanvas* canvas);
74 // Getters for various frame sizes.
75 scoped_refptr<VideoFrame> natural_frame() { return natural_frame_; }
76 scoped_refptr<VideoFrame> larger_frame() { return larger_frame_; }
77 scoped_refptr<VideoFrame> smaller_frame() { return smaller_frame_; }
78 scoped_refptr<VideoFrame> cropped_frame() { return cropped_frame_; }
80 // Standard canvas.
81 SkCanvas* target_canvas() { return &target_canvas_; }
83 protected:
84 SkCanvasVideoRenderer renderer_;
86 scoped_refptr<VideoFrame> natural_frame_;
87 scoped_refptr<VideoFrame> larger_frame_;
88 scoped_refptr<VideoFrame> smaller_frame_;
89 scoped_refptr<VideoFrame> cropped_frame_;
91 SkCanvas target_canvas_;
92 base::MessageLoop message_loop_;
94 DISALLOW_COPY_AND_ASSIGN(SkCanvasVideoRendererTest);
97 static SkBitmap AllocBitmap(int width, int height) {
98 SkBitmap bitmap;
99 bitmap.allocPixels(SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType));
100 bitmap.eraseColor(0);
101 return bitmap;
104 SkCanvasVideoRendererTest::SkCanvasVideoRendererTest()
105 : natural_frame_(VideoFrame::CreateBlackFrame(gfx::Size(kWidth, kHeight))),
106 larger_frame_(
107 VideoFrame::CreateBlackFrame(gfx::Size(kWidth * 2, kHeight * 2))),
108 smaller_frame_(
109 VideoFrame::CreateBlackFrame(gfx::Size(kWidth / 2, kHeight / 2))),
110 cropped_frame_(
111 VideoFrame::CreateFrame(PIXEL_FORMAT_YV12,
112 gfx::Size(16, 16),
113 gfx::Rect(6, 6, 8, 6),
114 gfx::Size(8, 6),
115 base::TimeDelta::FromMilliseconds(4))),
116 target_canvas_(AllocBitmap(kWidth, kHeight)) {
117 // Give each frame a unique timestamp.
118 natural_frame_->set_timestamp(base::TimeDelta::FromMilliseconds(1));
119 larger_frame_->set_timestamp(base::TimeDelta::FromMilliseconds(2));
120 smaller_frame_->set_timestamp(base::TimeDelta::FromMilliseconds(3));
122 // Make sure the cropped video frame's aspect ratio matches the output device.
123 // Update cropped_frame_'s crop dimensions if this is not the case.
124 EXPECT_EQ(cropped_frame()->visible_rect().width() * kHeight,
125 cropped_frame()->visible_rect().height() * kWidth);
127 // Fill in the cropped frame's entire data with colors:
129 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
130 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
131 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
132 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
133 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
134 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
135 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
136 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
137 // G G G G G G G G B B B B B B B B
138 // G G G G G G G G B B B B B B B B
139 // G G G G G G G G B B B B B B B B
140 // G G G G G G G G B B B B B B B B
141 // G G G G G G G G B B B B B B B B
142 // G G G G G G G G B B B B B B B B
143 // G G G G G G G G B B B B B B B B
144 // G G G G G G G G B B B B B B B B
146 // The visible crop of the frame (as set by its visible_rect_) has contents:
148 // Bl Bl R R R R R R
149 // Bl Bl R R R R R R
150 // G G B B B B B B
151 // G G B B B B B B
152 // G G B B B B B B
153 // G G B B B B B B
155 // Each color region in the cropped frame is on a 2x2 block granularity, to
156 // avoid sharing UV samples between regions.
158 static const uint8 cropped_y_plane[] = {
159 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
160 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
161 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
162 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
163 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
164 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
165 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
166 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
167 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
168 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
169 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
170 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
171 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
172 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
173 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
174 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
177 static const uint8 cropped_u_plane[] = {
178 128, 128, 128, 128, 84, 84, 84, 84,
179 128, 128, 128, 128, 84, 84, 84, 84,
180 128, 128, 128, 128, 84, 84, 84, 84,
181 128, 128, 128, 128, 84, 84, 84, 84,
182 43, 43, 43, 43, 255, 255, 255, 255,
183 43, 43, 43, 43, 255, 255, 255, 255,
184 43, 43, 43, 43, 255, 255, 255, 255,
185 43, 43, 43, 43, 255, 255, 255, 255,
187 static const uint8 cropped_v_plane[] = {
188 128, 128, 128, 128, 255, 255, 255, 255,
189 128, 128, 128, 128, 255, 255, 255, 255,
190 128, 128, 128, 128, 255, 255, 255, 255,
191 128, 128, 128, 128, 255, 255, 255, 255,
192 21, 21, 21, 21, 107, 107, 107, 107,
193 21, 21, 21, 21, 107, 107, 107, 107,
194 21, 21, 21, 21, 107, 107, 107, 107,
195 21, 21, 21, 21, 107, 107, 107, 107,
198 media::CopyYPlane(cropped_y_plane, 16, 16, cropped_frame().get());
199 media::CopyUPlane(cropped_u_plane, 8, 8, cropped_frame().get());
200 media::CopyVPlane(cropped_v_plane, 8, 8, cropped_frame().get());
203 SkCanvasVideoRendererTest::~SkCanvasVideoRendererTest() {}
205 void SkCanvasVideoRendererTest::PaintWithoutFrame(SkCanvas* canvas) {
206 renderer_.Paint(nullptr, canvas, kNaturalRect, 0xFF,
207 SkXfermode::kSrcOver_Mode, VIDEO_ROTATION_0, Context3D());
210 void SkCanvasVideoRendererTest::Paint(
211 const scoped_refptr<VideoFrame>& video_frame,
212 SkCanvas* canvas,
213 Color color) {
214 PaintRotated(video_frame,
215 canvas,
216 kNaturalRect,
217 color,
218 SkXfermode::kSrcOver_Mode,
219 VIDEO_ROTATION_0);
222 void SkCanvasVideoRendererTest::PaintRotated(
223 const scoped_refptr<VideoFrame>& video_frame,
224 SkCanvas* canvas,
225 const gfx::RectF& dest_rect,
226 Color color,
227 SkXfermode::Mode mode,
228 VideoRotation video_rotation) {
229 switch (color) {
230 case kNone:
231 break;
232 case kRed:
233 media::FillYUV(video_frame.get(), 76, 84, 255);
234 break;
235 case kGreen:
236 media::FillYUV(video_frame.get(), 149, 43, 21);
237 break;
238 case kBlue:
239 media::FillYUV(video_frame.get(), 29, 255, 107);
240 break;
242 renderer_.Paint(video_frame, canvas, dest_rect, 0xFF, mode, video_rotation,
243 Context3D());
246 void SkCanvasVideoRendererTest::Copy(
247 const scoped_refptr<VideoFrame>& video_frame,
248 SkCanvas* canvas) {
249 renderer_.Copy(video_frame, canvas, Context3D());
252 TEST_F(SkCanvasVideoRendererTest, NoFrame) {
253 // Test that black gets painted over canvas.
254 FillCanvas(target_canvas(), SK_ColorRED);
255 PaintWithoutFrame(target_canvas());
256 EXPECT_EQ(SK_ColorBLACK, GetColor(target_canvas()));
259 TEST_F(SkCanvasVideoRendererTest, TransparentFrame) {
260 FillCanvas(target_canvas(), SK_ColorRED);
261 PaintRotated(
262 VideoFrame::CreateTransparentFrame(gfx::Size(kWidth, kHeight)).get(),
263 target_canvas(),
264 kNaturalRect,
265 kNone,
266 SkXfermode::kSrcOver_Mode,
267 VIDEO_ROTATION_0);
268 EXPECT_EQ(static_cast<SkColor>(SK_ColorRED), GetColor(target_canvas()));
271 TEST_F(SkCanvasVideoRendererTest, TransparentFrameSrcMode) {
272 FillCanvas(target_canvas(), SK_ColorRED);
273 // SRC mode completely overwrites the buffer.
274 PaintRotated(
275 VideoFrame::CreateTransparentFrame(gfx::Size(kWidth, kHeight)).get(),
276 target_canvas(),
277 kNaturalRect,
278 kNone,
279 SkXfermode::kSrc_Mode,
280 VIDEO_ROTATION_0);
281 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
282 GetColor(target_canvas()));
285 TEST_F(SkCanvasVideoRendererTest, CopyTransparentFrame) {
286 FillCanvas(target_canvas(), SK_ColorRED);
287 Copy(VideoFrame::CreateTransparentFrame(gfx::Size(kWidth, kHeight)).get(),
288 target_canvas());
289 EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
290 GetColor(target_canvas()));
293 TEST_F(SkCanvasVideoRendererTest, Natural) {
294 Paint(natural_frame(), target_canvas(), kRed);
295 EXPECT_EQ(SK_ColorRED, GetColor(target_canvas()));
298 TEST_F(SkCanvasVideoRendererTest, Larger) {
299 Paint(natural_frame(), target_canvas(), kRed);
300 EXPECT_EQ(SK_ColorRED, GetColor(target_canvas()));
302 Paint(larger_frame(), target_canvas(), kBlue);
303 EXPECT_EQ(SK_ColorBLUE, GetColor(target_canvas()));
306 TEST_F(SkCanvasVideoRendererTest, Smaller) {
307 Paint(natural_frame(), target_canvas(), kRed);
308 EXPECT_EQ(SK_ColorRED, GetColor(target_canvas()));
310 Paint(smaller_frame(), target_canvas(), kBlue);
311 EXPECT_EQ(SK_ColorBLUE, GetColor(target_canvas()));
314 TEST_F(SkCanvasVideoRendererTest, NoTimestamp) {
315 VideoFrame* video_frame = natural_frame().get();
316 video_frame->set_timestamp(media::kNoTimestamp());
317 Paint(video_frame, target_canvas(), kRed);
318 EXPECT_EQ(SK_ColorRED, GetColor(target_canvas()));
321 TEST_F(SkCanvasVideoRendererTest, CroppedFrame) {
322 Paint(cropped_frame(), target_canvas(), kNone);
323 // Check the corners.
324 EXPECT_EQ(SK_ColorBLACK, GetColorAt(target_canvas(), 0, 0));
325 EXPECT_EQ(SK_ColorRED, GetColorAt(target_canvas(), kWidth - 1, 0));
326 EXPECT_EQ(SK_ColorGREEN, GetColorAt(target_canvas(), 0, kHeight - 1));
327 EXPECT_EQ(SK_ColorBLUE, GetColorAt(target_canvas(), kWidth - 1,
328 kHeight - 1));
329 // Check the interior along the border between color regions. Note that we're
330 // bilinearly upscaling, so we'll need to take care to pick sample points that
331 // are just outside the "zone of resampling".
332 EXPECT_EQ(SK_ColorBLACK, GetColorAt(target_canvas(), kWidth * 1 / 8 - 1,
333 kHeight * 1 / 6 - 1));
334 EXPECT_EQ(SK_ColorRED, GetColorAt(target_canvas(), kWidth * 3 / 8,
335 kHeight * 1 / 6 - 1));
336 EXPECT_EQ(SK_ColorGREEN, GetColorAt(target_canvas(), kWidth * 1 / 8 - 1,
337 kHeight * 3 / 6));
338 EXPECT_EQ(SK_ColorBLUE, GetColorAt(target_canvas(), kWidth * 3 / 8,
339 kHeight * 3 / 6));
342 TEST_F(SkCanvasVideoRendererTest, CroppedFrame_NoScaling) {
343 SkCanvas canvas(AllocBitmap(kWidth, kHeight));
344 const gfx::Rect crop_rect = cropped_frame()->visible_rect();
346 // Force painting to a non-zero position on the destination bitmap, to check
347 // if the coordinates are calculated properly.
348 const int offset_x = 10;
349 const int offset_y = 15;
350 canvas.translate(offset_x, offset_y);
352 // Create a destination canvas with dimensions and scale which would not
353 // cause scaling.
354 canvas.scale(static_cast<SkScalar>(crop_rect.width()) / kWidth,
355 static_cast<SkScalar>(crop_rect.height()) / kHeight);
357 Paint(cropped_frame(), &canvas, kNone);
359 // Check the corners.
360 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, offset_x, offset_y));
361 EXPECT_EQ(SK_ColorRED,
362 GetColorAt(&canvas, offset_x + crop_rect.width() - 1, offset_y));
363 EXPECT_EQ(SK_ColorGREEN,
364 GetColorAt(&canvas, offset_x, offset_y + crop_rect.height() - 1));
365 EXPECT_EQ(SK_ColorBLUE,
366 GetColorAt(&canvas,
367 offset_x + crop_rect.width() - 1,
368 offset_y + crop_rect.height() - 1));
371 TEST_F(SkCanvasVideoRendererTest, Video_Rotation_90) {
372 SkCanvas canvas(AllocBitmap(kWidth, kHeight));
373 PaintRotated(cropped_frame(),
374 &canvas,
375 kNaturalRect,
376 kNone,
377 SkXfermode::kSrcOver_Mode,
378 VIDEO_ROTATION_90);
379 // Check the corners.
380 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, 0, 0));
381 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth - 1, 0));
382 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, kWidth - 1, kHeight - 1));
383 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, 0, kHeight - 1));
386 TEST_F(SkCanvasVideoRendererTest, Video_Rotation_180) {
387 SkCanvas canvas(AllocBitmap(kWidth, kHeight));
388 PaintRotated(cropped_frame(),
389 &canvas,
390 kNaturalRect,
391 kNone,
392 SkXfermode::kSrcOver_Mode,
393 VIDEO_ROTATION_180);
394 // Check the corners.
395 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, 0, 0));
396 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth - 1, 0));
397 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth - 1, kHeight - 1));
398 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, 0, kHeight - 1));
401 TEST_F(SkCanvasVideoRendererTest, Video_Rotation_270) {
402 SkCanvas canvas(AllocBitmap(kWidth, kHeight));
403 PaintRotated(cropped_frame(),
404 &canvas,
405 kNaturalRect,
406 kNone,
407 SkXfermode::kSrcOver_Mode,
408 VIDEO_ROTATION_270);
409 // Check the corners.
410 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, 0, 0));
411 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, kWidth - 1, 0));
412 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth - 1, kHeight - 1));
413 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, 0, kHeight - 1));
416 TEST_F(SkCanvasVideoRendererTest, Video_Translate) {
417 SkCanvas canvas(AllocBitmap(kWidth, kHeight));
418 FillCanvas(&canvas, SK_ColorMAGENTA);
420 PaintRotated(cropped_frame(), &canvas,
421 gfx::RectF(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2),
422 kNone, SkXfermode::kSrcOver_Mode, VIDEO_ROTATION_0);
423 // Check the corners of quadrant 2 and 4.
424 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, 0));
425 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, (kWidth / 2) - 1, 0));
426 EXPECT_EQ(SK_ColorMAGENTA,
427 GetColorAt(&canvas, (kWidth / 2) - 1, (kHeight / 2) - 1));
428 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, (kHeight / 2) - 1));
429 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth / 2, kHeight / 2));
430 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, kWidth - 1, kHeight / 2));
431 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, kWidth - 1, kHeight - 1));
432 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth / 2, kHeight - 1));
435 TEST_F(SkCanvasVideoRendererTest, Video_Translate_Rotation_90) {
436 SkCanvas canvas(AllocBitmap(kWidth, kHeight));
437 FillCanvas(&canvas, SK_ColorMAGENTA);
439 const gfx::Rect crop_rect = cropped_frame()->visible_rect();
440 PaintRotated(cropped_frame(), &canvas,
441 gfx::RectF(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2),
442 kNone, SkXfermode::kSrcOver_Mode, VIDEO_ROTATION_90);
443 // Check the corners of quadrant 2 and 4.
444 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, 0));
445 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, (kWidth / 2) - 1, 0));
446 EXPECT_EQ(SK_ColorMAGENTA,
447 GetColorAt(&canvas, (kWidth / 2) - 1, (kHeight / 2) - 1));
448 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, (kHeight / 2) - 1));
449 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth / 2, kHeight / 2));
450 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth - 1, kHeight / 2));
451 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, kWidth - 1, kHeight - 1));
452 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, kWidth / 2, kHeight - 1));
455 TEST_F(SkCanvasVideoRendererTest, Video_Translate_Rotation_180) {
456 SkCanvas canvas(AllocBitmap(kWidth, kHeight));
457 FillCanvas(&canvas, SK_ColorMAGENTA);
459 PaintRotated(cropped_frame(), &canvas,
460 gfx::RectF(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2),
461 kNone, SkXfermode::kSrcOver_Mode, VIDEO_ROTATION_180);
462 // Check the corners of quadrant 2 and 4.
463 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, 0));
464 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, (kWidth / 2) - 1, 0));
465 EXPECT_EQ(SK_ColorMAGENTA,
466 GetColorAt(&canvas, (kWidth / 2) - 1, (kHeight / 2) - 1));
467 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, (kHeight / 2) - 1));
468 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, kWidth / 2, kHeight / 2));
469 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth - 1, kHeight / 2));
470 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth - 1, kHeight - 1));
471 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, kWidth / 2, kHeight - 1));
474 TEST_F(SkCanvasVideoRendererTest, Video_Translate_Rotation_270) {
475 SkCanvas canvas(AllocBitmap(kWidth, kHeight));
476 FillCanvas(&canvas, SK_ColorMAGENTA);
478 PaintRotated(cropped_frame(), &canvas,
479 gfx::RectF(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2),
480 kNone, SkXfermode::kSrcOver_Mode, VIDEO_ROTATION_270);
481 // Check the corners of quadrant 2 and 4.
482 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, 0));
483 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, (kWidth / 2) - 1, 0));
484 EXPECT_EQ(SK_ColorMAGENTA,
485 GetColorAt(&canvas, (kWidth / 2) - 1, (kHeight / 2) - 1));
486 EXPECT_EQ(SK_ColorMAGENTA, GetColorAt(&canvas, 0, (kHeight / 2) - 1));
487 EXPECT_EQ(SK_ColorRED, GetColorAt(&canvas, kWidth / 2, kHeight / 2));
488 EXPECT_EQ(SK_ColorBLUE, GetColorAt(&canvas, kWidth - 1, kHeight / 2));
489 EXPECT_EQ(SK_ColorGREEN, GetColorAt(&canvas, kWidth - 1, kHeight - 1));
490 EXPECT_EQ(SK_ColorBLACK, GetColorAt(&canvas, kWidth / 2, kHeight - 1));
493 namespace {
494 class TestGLES2Interface : public gpu::gles2::GLES2InterfaceStub {
495 public:
496 void GenTextures(GLsizei n, GLuint* textures) override {
497 DCHECK_EQ(1, n);
498 *textures = 1;
501 void MailboxHoldersReleased(uint32 sync_point) {}
502 } // namespace
504 // Test that SkCanvasVideoRendererTest::Paint doesn't crash when GrContext is
505 // abandoned.
506 TEST_F(SkCanvasVideoRendererTest, ContextLost) {
507 skia::RefPtr<const GrGLInterface> null_interface =
508 skia::AdoptRef(GrGLCreateNullInterface());
509 auto gr_context = skia::AdoptRef(GrContext::Create(
510 kOpenGL_GrBackend,
511 reinterpret_cast<GrBackendContext>(null_interface.get())));
512 gr_context->abandonContext();
514 SkCanvas canvas(AllocBitmap(kWidth, kHeight));
516 TestGLES2Interface gles2;
517 Context3D context_3d(&gles2, gr_context.get());
518 gfx::Size size(kWidth, kHeight);
519 gpu::MailboxHolder mailbox(gpu::Mailbox::Generate(), GL_TEXTURE_RECTANGLE_ARB,
521 auto video_frame = VideoFrame::WrapNativeTexture(
522 PIXEL_FORMAT_UYVY, mailbox, base::Bind(MailboxHoldersReleased), size,
523 gfx::Rect(size), size, kNoTimestamp());
525 renderer_.Paint(video_frame, &canvas, kNaturalRect, 0xFF,
526 SkXfermode::kSrcOver_Mode, VIDEO_ROTATION_90, context_3d);
528 } // namespace media