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
;
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
) {
31 // Helper for returning the color of a solid |canvas|.
32 SkColor
GetColorAt(SkCanvas
* canvas
, int x
, int y
) {
34 if (!bitmap
.tryAllocN32Pixels(1, 1))
36 if (!canvas
->readPixels(&bitmap
, x
, y
))
38 return bitmap
.getColor(0, 0);
41 SkColor
GetColor(SkCanvas
* canvas
) {
42 return GetColorAt(canvas
, 0, 0);
45 class SkCanvasVideoRendererTest
: public testing::Test
{
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
,
65 void PaintRotated(const scoped_refptr
<VideoFrame
>& video_frame
,
67 const gfx::RectF
& dest_rect
,
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_
; }
81 SkCanvas
* target_canvas() { return &target_canvas_
; }
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
) {
99 bitmap
.allocPixels(SkImageInfo::MakeN32(width
, height
, kPremul_SkAlphaType
));
100 bitmap
.eraseColor(0);
104 SkCanvasVideoRendererTest::SkCanvasVideoRendererTest()
105 : natural_frame_(VideoFrame::CreateBlackFrame(gfx::Size(kWidth
, kHeight
))),
107 VideoFrame::CreateBlackFrame(gfx::Size(kWidth
* 2, kHeight
* 2))),
109 VideoFrame::CreateBlackFrame(gfx::Size(kWidth
/ 2, kHeight
/ 2))),
111 VideoFrame::CreateFrame(PIXEL_FORMAT_YV12
,
113 gfx::Rect(6, 6, 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:
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
,
214 PaintRotated(video_frame
,
218 SkXfermode::kSrcOver_Mode
,
222 void SkCanvasVideoRendererTest::PaintRotated(
223 const scoped_refptr
<VideoFrame
>& video_frame
,
225 const gfx::RectF
& dest_rect
,
227 SkXfermode::Mode mode
,
228 VideoRotation video_rotation
) {
233 media::FillYUV(video_frame
.get(), 76, 84, 255);
236 media::FillYUV(video_frame
.get(), 149, 43, 21);
239 media::FillYUV(video_frame
.get(), 29, 255, 107);
242 renderer_
.Paint(video_frame
, canvas
, dest_rect
, 0xFF, mode
, video_rotation
,
246 void SkCanvasVideoRendererTest::Copy(
247 const scoped_refptr
<VideoFrame
>& video_frame
,
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
);
262 VideoFrame::CreateTransparentFrame(gfx::Size(kWidth
, kHeight
)).get(),
266 SkXfermode::kSrcOver_Mode
,
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.
275 VideoFrame::CreateTransparentFrame(gfx::Size(kWidth
, kHeight
)).get(),
279 SkXfermode::kSrc_Mode
,
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(),
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,
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,
338 EXPECT_EQ(SK_ColorBLUE
, GetColorAt(target_canvas(), kWidth
* 3 / 8,
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
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
,
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(),
377 SkXfermode::kSrcOver_Mode
,
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(),
392 SkXfermode::kSrcOver_Mode
,
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(),
407 SkXfermode::kSrcOver_Mode
,
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));
494 class TestGLES2Interface
: public gpu::gles2::GLES2InterfaceStub
{
496 void GenTextures(GLsizei n
, GLuint
* textures
) override
{
501 void MailboxHoldersReleased(uint32 sync_point
) {}
504 // Test that SkCanvasVideoRendererTest::Paint doesn't crash when GrContext is
506 TEST_F(SkCanvasVideoRendererTest
, ContextLost
) {
507 skia::RefPtr
<const GrGLInterface
> null_interface
=
508 skia::AdoptRef(GrGLCreateNullInterface());
509 auto gr_context
= skia::AdoptRef(GrContext::Create(
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
);