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 "media/base/video_frame.h"
7 #include "media/base/video_util.h"
8 #include "media/blink/skcanvas_video_renderer.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/skia/include/core/SkCanvas.h"
12 using media::VideoFrame
;
16 static const int kWidth
= 320;
17 static const int kHeight
= 240;
18 static const gfx::Rect
kNaturalRect(0, 0, kWidth
, kHeight
);
20 // Helper for filling a |canvas| with a solid |color|.
21 void FillCanvas(SkCanvas
* canvas
, SkColor color
) {
25 // Helper for returning the color of a solid |canvas|.
26 SkColor
GetColorAt(SkCanvas
* canvas
, int x
, int y
) {
28 if (!bitmap
.tryAllocN32Pixels(1, 1))
30 if (!canvas
->readPixels(&bitmap
, x
, y
))
32 return bitmap
.getColor(0, 0);
35 SkColor
GetColor(SkCanvas
* canvas
) {
36 return GetColorAt(canvas
, 0, 0);
39 class SkCanvasVideoRendererTest
: public testing::Test
{
48 SkCanvasVideoRendererTest();
49 ~SkCanvasVideoRendererTest() override
;
51 // Paints to |canvas| using |renderer_| without any frame data.
52 void PaintWithoutFrame(SkCanvas
* canvas
);
54 // Paints the |video_frame| to the |canvas| using |renderer_|, setting the
55 // color of |video_frame| to |color| first.
56 void Paint(const scoped_refptr
<VideoFrame
>& video_frame
,
59 void PaintRotated(const scoped_refptr
<VideoFrame
>& video_frame
,
61 const gfx::RectF
& dest_rect
,
63 SkXfermode::Mode mode
,
64 VideoRotation video_rotation
);
66 void Copy(const scoped_refptr
<VideoFrame
>& video_frame
, SkCanvas
* canvas
);
68 // Getters for various frame sizes.
69 scoped_refptr
<VideoFrame
> natural_frame() { return natural_frame_
; }
70 scoped_refptr
<VideoFrame
> larger_frame() { return larger_frame_
; }
71 scoped_refptr
<VideoFrame
> smaller_frame() { return smaller_frame_
; }
72 scoped_refptr
<VideoFrame
> cropped_frame() { return cropped_frame_
; }
75 SkCanvas
* target_canvas() { return &target_canvas_
; }
78 SkCanvasVideoRenderer renderer_
;
80 scoped_refptr
<VideoFrame
> natural_frame_
;
81 scoped_refptr
<VideoFrame
> larger_frame_
;
82 scoped_refptr
<VideoFrame
> smaller_frame_
;
83 scoped_refptr
<VideoFrame
> cropped_frame_
;
85 SkCanvas target_canvas_
;
86 base::MessageLoop message_loop_
;
88 DISALLOW_COPY_AND_ASSIGN(SkCanvasVideoRendererTest
);
91 static SkBitmap
AllocBitmap(int width
, int height
) {
93 bitmap
.allocPixels(SkImageInfo::MakeN32(width
, height
, kPremul_SkAlphaType
));
98 SkCanvasVideoRendererTest::SkCanvasVideoRendererTest()
99 : natural_frame_(VideoFrame::CreateBlackFrame(gfx::Size(kWidth
, kHeight
))),
101 VideoFrame::CreateBlackFrame(gfx::Size(kWidth
* 2, kHeight
* 2))),
103 VideoFrame::CreateBlackFrame(gfx::Size(kWidth
/ 2, kHeight
/ 2))),
105 VideoFrame::CreateFrame(PIXEL_FORMAT_YV12
,
107 gfx::Rect(6, 6, 8, 6),
109 base::TimeDelta::FromMilliseconds(4))),
110 target_canvas_(AllocBitmap(kWidth
, kHeight
)) {
111 // Give each frame a unique timestamp.
112 natural_frame_
->set_timestamp(base::TimeDelta::FromMilliseconds(1));
113 larger_frame_
->set_timestamp(base::TimeDelta::FromMilliseconds(2));
114 smaller_frame_
->set_timestamp(base::TimeDelta::FromMilliseconds(3));
116 // Make sure the cropped video frame's aspect ratio matches the output device.
117 // Update cropped_frame_'s crop dimensions if this is not the case.
118 EXPECT_EQ(cropped_frame()->visible_rect().width() * kHeight
,
119 cropped_frame()->visible_rect().height() * kWidth
);
121 // Fill in the cropped frame's entire data with colors:
123 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
124 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
125 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
126 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
127 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
128 // Bl Bl Bl Bl Bl Bl Bl Bl R R R R R R R R
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 // G G G G G G G G B B B B B B B B
132 // G G G G G G G G B B B B B B B B
133 // G G G G G G G G B B B B B B B B
134 // G G G G G G G G B B B B B B B B
135 // G G G G G G G G B B B B B B B B
136 // G G G G G G G G B B B B B B B B
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
140 // The visible crop of the frame (as set by its visible_rect_) has contents:
149 // Each color region in the cropped frame is on a 2x2 block granularity, to
150 // avoid sharing UV samples between regions.
152 static const uint8 cropped_y_plane
[] = {
153 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
154 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
155 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
156 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
157 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
158 0, 0, 0, 0, 0, 0, 0, 0, 76, 76, 76, 76, 76, 76, 76, 76,
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 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
162 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
163 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
164 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
165 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
166 149, 149, 149, 149, 149, 149, 149, 149, 29, 29, 29, 29, 29, 29, 29, 29,
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,
171 static const uint8 cropped_u_plane
[] = {
172 128, 128, 128, 128, 84, 84, 84, 84,
173 128, 128, 128, 128, 84, 84, 84, 84,
174 128, 128, 128, 128, 84, 84, 84, 84,
175 128, 128, 128, 128, 84, 84, 84, 84,
176 43, 43, 43, 43, 255, 255, 255, 255,
177 43, 43, 43, 43, 255, 255, 255, 255,
178 43, 43, 43, 43, 255, 255, 255, 255,
179 43, 43, 43, 43, 255, 255, 255, 255,
181 static const uint8 cropped_v_plane
[] = {
182 128, 128, 128, 128, 255, 255, 255, 255,
183 128, 128, 128, 128, 255, 255, 255, 255,
184 128, 128, 128, 128, 255, 255, 255, 255,
185 128, 128, 128, 128, 255, 255, 255, 255,
186 21, 21, 21, 21, 107, 107, 107, 107,
187 21, 21, 21, 21, 107, 107, 107, 107,
188 21, 21, 21, 21, 107, 107, 107, 107,
189 21, 21, 21, 21, 107, 107, 107, 107,
192 media::CopyYPlane(cropped_y_plane
, 16, 16, cropped_frame().get());
193 media::CopyUPlane(cropped_u_plane
, 8, 8, cropped_frame().get());
194 media::CopyVPlane(cropped_v_plane
, 8, 8, cropped_frame().get());
197 SkCanvasVideoRendererTest::~SkCanvasVideoRendererTest() {}
199 void SkCanvasVideoRendererTest::PaintWithoutFrame(SkCanvas
* canvas
) {
200 renderer_
.Paint(nullptr, canvas
, kNaturalRect
, 0xFF,
201 SkXfermode::kSrcOver_Mode
, VIDEO_ROTATION_0
, Context3D());
204 void SkCanvasVideoRendererTest::Paint(
205 const scoped_refptr
<VideoFrame
>& video_frame
,
208 PaintRotated(video_frame
,
212 SkXfermode::kSrcOver_Mode
,
216 void SkCanvasVideoRendererTest::PaintRotated(
217 const scoped_refptr
<VideoFrame
>& video_frame
,
219 const gfx::RectF
& dest_rect
,
221 SkXfermode::Mode mode
,
222 VideoRotation video_rotation
) {
227 media::FillYUV(video_frame
.get(), 76, 84, 255);
230 media::FillYUV(video_frame
.get(), 149, 43, 21);
233 media::FillYUV(video_frame
.get(), 29, 255, 107);
236 renderer_
.Paint(video_frame
, canvas
, dest_rect
, 0xFF, mode
, video_rotation
,
240 void SkCanvasVideoRendererTest::Copy(
241 const scoped_refptr
<VideoFrame
>& video_frame
,
243 renderer_
.Copy(video_frame
, canvas
, Context3D());
246 TEST_F(SkCanvasVideoRendererTest
, NoFrame
) {
247 // Test that black gets painted over canvas.
248 FillCanvas(target_canvas(), SK_ColorRED
);
249 PaintWithoutFrame(target_canvas());
250 EXPECT_EQ(SK_ColorBLACK
, GetColor(target_canvas()));
253 TEST_F(SkCanvasVideoRendererTest
, TransparentFrame
) {
254 FillCanvas(target_canvas(), SK_ColorRED
);
256 VideoFrame::CreateTransparentFrame(gfx::Size(kWidth
, kHeight
)).get(),
260 SkXfermode::kSrcOver_Mode
,
262 EXPECT_EQ(static_cast<SkColor
>(SK_ColorRED
), GetColor(target_canvas()));
265 TEST_F(SkCanvasVideoRendererTest
, TransparentFrameSrcMode
) {
266 FillCanvas(target_canvas(), SK_ColorRED
);
267 // SRC mode completely overwrites the buffer.
269 VideoFrame::CreateTransparentFrame(gfx::Size(kWidth
, kHeight
)).get(),
273 SkXfermode::kSrc_Mode
,
275 EXPECT_EQ(static_cast<SkColor
>(SK_ColorTRANSPARENT
),
276 GetColor(target_canvas()));
279 TEST_F(SkCanvasVideoRendererTest
, CopyTransparentFrame
) {
280 FillCanvas(target_canvas(), SK_ColorRED
);
281 Copy(VideoFrame::CreateTransparentFrame(gfx::Size(kWidth
, kHeight
)).get(),
283 EXPECT_EQ(static_cast<SkColor
>(SK_ColorTRANSPARENT
),
284 GetColor(target_canvas()));
287 TEST_F(SkCanvasVideoRendererTest
, Natural
) {
288 Paint(natural_frame(), target_canvas(), kRed
);
289 EXPECT_EQ(SK_ColorRED
, GetColor(target_canvas()));
292 TEST_F(SkCanvasVideoRendererTest
, Larger
) {
293 Paint(natural_frame(), target_canvas(), kRed
);
294 EXPECT_EQ(SK_ColorRED
, GetColor(target_canvas()));
296 Paint(larger_frame(), target_canvas(), kBlue
);
297 EXPECT_EQ(SK_ColorBLUE
, GetColor(target_canvas()));
300 TEST_F(SkCanvasVideoRendererTest
, Smaller
) {
301 Paint(natural_frame(), target_canvas(), kRed
);
302 EXPECT_EQ(SK_ColorRED
, GetColor(target_canvas()));
304 Paint(smaller_frame(), target_canvas(), kBlue
);
305 EXPECT_EQ(SK_ColorBLUE
, GetColor(target_canvas()));
308 TEST_F(SkCanvasVideoRendererTest
, NoTimestamp
) {
309 VideoFrame
* video_frame
= natural_frame().get();
310 video_frame
->set_timestamp(media::kNoTimestamp());
311 Paint(video_frame
, target_canvas(), kRed
);
312 EXPECT_EQ(SK_ColorRED
, GetColor(target_canvas()));
315 TEST_F(SkCanvasVideoRendererTest
, CroppedFrame
) {
316 Paint(cropped_frame(), target_canvas(), kNone
);
317 // Check the corners.
318 EXPECT_EQ(SK_ColorBLACK
, GetColorAt(target_canvas(), 0, 0));
319 EXPECT_EQ(SK_ColorRED
, GetColorAt(target_canvas(), kWidth
- 1, 0));
320 EXPECT_EQ(SK_ColorGREEN
, GetColorAt(target_canvas(), 0, kHeight
- 1));
321 EXPECT_EQ(SK_ColorBLUE
, GetColorAt(target_canvas(), kWidth
- 1,
323 // Check the interior along the border between color regions. Note that we're
324 // bilinearly upscaling, so we'll need to take care to pick sample points that
325 // are just outside the "zone of resampling".
326 EXPECT_EQ(SK_ColorBLACK
, GetColorAt(target_canvas(), kWidth
* 1 / 8 - 1,
327 kHeight
* 1 / 6 - 1));
328 EXPECT_EQ(SK_ColorRED
, GetColorAt(target_canvas(), kWidth
* 3 / 8,
329 kHeight
* 1 / 6 - 1));
330 EXPECT_EQ(SK_ColorGREEN
, GetColorAt(target_canvas(), kWidth
* 1 / 8 - 1,
332 EXPECT_EQ(SK_ColorBLUE
, GetColorAt(target_canvas(), kWidth
* 3 / 8,
336 TEST_F(SkCanvasVideoRendererTest
, CroppedFrame_NoScaling
) {
337 SkCanvas
canvas(AllocBitmap(kWidth
, kHeight
));
338 const gfx::Rect crop_rect
= cropped_frame()->visible_rect();
340 // Force painting to a non-zero position on the destination bitmap, to check
341 // if the coordinates are calculated properly.
342 const int offset_x
= 10;
343 const int offset_y
= 15;
344 canvas
.translate(offset_x
, offset_y
);
346 // Create a destination canvas with dimensions and scale which would not
348 canvas
.scale(static_cast<SkScalar
>(crop_rect
.width()) / kWidth
,
349 static_cast<SkScalar
>(crop_rect
.height()) / kHeight
);
351 Paint(cropped_frame(), &canvas
, kNone
);
353 // Check the corners.
354 EXPECT_EQ(SK_ColorBLACK
, GetColorAt(&canvas
, offset_x
, offset_y
));
355 EXPECT_EQ(SK_ColorRED
,
356 GetColorAt(&canvas
, offset_x
+ crop_rect
.width() - 1, offset_y
));
357 EXPECT_EQ(SK_ColorGREEN
,
358 GetColorAt(&canvas
, offset_x
, offset_y
+ crop_rect
.height() - 1));
359 EXPECT_EQ(SK_ColorBLUE
,
361 offset_x
+ crop_rect
.width() - 1,
362 offset_y
+ crop_rect
.height() - 1));
365 TEST_F(SkCanvasVideoRendererTest
, Video_Rotation_90
) {
366 SkCanvas
canvas(AllocBitmap(kWidth
, kHeight
));
367 PaintRotated(cropped_frame(),
371 SkXfermode::kSrcOver_Mode
,
373 // Check the corners.
374 EXPECT_EQ(SK_ColorGREEN
, GetColorAt(&canvas
, 0, 0));
375 EXPECT_EQ(SK_ColorBLACK
, GetColorAt(&canvas
, kWidth
- 1, 0));
376 EXPECT_EQ(SK_ColorRED
, GetColorAt(&canvas
, kWidth
- 1, kHeight
- 1));
377 EXPECT_EQ(SK_ColorBLUE
, GetColorAt(&canvas
, 0, kHeight
- 1));
380 TEST_F(SkCanvasVideoRendererTest
, Video_Rotation_180
) {
381 SkCanvas
canvas(AllocBitmap(kWidth
, kHeight
));
382 PaintRotated(cropped_frame(),
386 SkXfermode::kSrcOver_Mode
,
388 // Check the corners.
389 EXPECT_EQ(SK_ColorBLUE
, GetColorAt(&canvas
, 0, 0));
390 EXPECT_EQ(SK_ColorGREEN
, GetColorAt(&canvas
, kWidth
- 1, 0));
391 EXPECT_EQ(SK_ColorBLACK
, GetColorAt(&canvas
, kWidth
- 1, kHeight
- 1));
392 EXPECT_EQ(SK_ColorRED
, GetColorAt(&canvas
, 0, kHeight
- 1));
395 TEST_F(SkCanvasVideoRendererTest
, Video_Rotation_270
) {
396 SkCanvas
canvas(AllocBitmap(kWidth
, kHeight
));
397 PaintRotated(cropped_frame(),
401 SkXfermode::kSrcOver_Mode
,
403 // Check the corners.
404 EXPECT_EQ(SK_ColorRED
, GetColorAt(&canvas
, 0, 0));
405 EXPECT_EQ(SK_ColorBLUE
, GetColorAt(&canvas
, kWidth
- 1, 0));
406 EXPECT_EQ(SK_ColorGREEN
, GetColorAt(&canvas
, kWidth
- 1, kHeight
- 1));
407 EXPECT_EQ(SK_ColorBLACK
, GetColorAt(&canvas
, 0, kHeight
- 1));
410 TEST_F(SkCanvasVideoRendererTest
, Video_Translate
) {
411 SkCanvas
canvas(AllocBitmap(kWidth
, kHeight
));
412 FillCanvas(&canvas
, SK_ColorMAGENTA
);
414 PaintRotated(cropped_frame(),
416 gfx::Rect(kWidth
/ 2, kHeight
/ 2, kWidth
/ 2, kHeight
/ 2),
418 SkXfermode::kSrcOver_Mode
,
420 // Check the corners of quadrant 2 and 4.
421 EXPECT_EQ(SK_ColorMAGENTA
, GetColorAt(&canvas
, 0, 0));
422 EXPECT_EQ(SK_ColorMAGENTA
, GetColorAt(&canvas
, (kWidth
/ 2) - 1, 0));
423 EXPECT_EQ(SK_ColorMAGENTA
,
424 GetColorAt(&canvas
, (kWidth
/ 2) - 1, (kHeight
/ 2) - 1));
425 EXPECT_EQ(SK_ColorMAGENTA
, GetColorAt(&canvas
, 0, (kHeight
/ 2) - 1));
426 EXPECT_EQ(SK_ColorBLACK
, GetColorAt(&canvas
, kWidth
/ 2, kHeight
/ 2));
427 EXPECT_EQ(SK_ColorRED
, GetColorAt(&canvas
, kWidth
- 1, kHeight
/ 2));
428 EXPECT_EQ(SK_ColorBLUE
, GetColorAt(&canvas
, kWidth
- 1, kHeight
- 1));
429 EXPECT_EQ(SK_ColorGREEN
, GetColorAt(&canvas
, kWidth
/ 2, kHeight
- 1));
432 TEST_F(SkCanvasVideoRendererTest
, Video_Translate_Rotation_90
) {
433 SkCanvas
canvas(AllocBitmap(kWidth
, kHeight
));
434 FillCanvas(&canvas
, SK_ColorMAGENTA
);
436 const gfx::Rect crop_rect
= cropped_frame()->visible_rect();
437 PaintRotated(cropped_frame(),
439 gfx::Rect(kWidth
/ 2, kHeight
/ 2, kWidth
/ 2, kHeight
/ 2),
441 SkXfermode::kSrcOver_Mode
,
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(),
461 gfx::Rect(kWidth
/ 2, kHeight
/ 2, kWidth
/ 2, kHeight
/ 2),
463 SkXfermode::kSrcOver_Mode
,
465 // Check the corners of quadrant 2 and 4.
466 EXPECT_EQ(SK_ColorMAGENTA
, GetColorAt(&canvas
, 0, 0));
467 EXPECT_EQ(SK_ColorMAGENTA
, GetColorAt(&canvas
, (kWidth
/ 2) - 1, 0));
468 EXPECT_EQ(SK_ColorMAGENTA
,
469 GetColorAt(&canvas
, (kWidth
/ 2) - 1, (kHeight
/ 2) - 1));
470 EXPECT_EQ(SK_ColorMAGENTA
, GetColorAt(&canvas
, 0, (kHeight
/ 2) - 1));
471 EXPECT_EQ(SK_ColorBLUE
, GetColorAt(&canvas
, kWidth
/ 2, kHeight
/ 2));
472 EXPECT_EQ(SK_ColorGREEN
, GetColorAt(&canvas
, kWidth
- 1, kHeight
/ 2));
473 EXPECT_EQ(SK_ColorBLACK
, GetColorAt(&canvas
, kWidth
- 1, kHeight
- 1));
474 EXPECT_EQ(SK_ColorRED
, GetColorAt(&canvas
, kWidth
/ 2, kHeight
- 1));
477 TEST_F(SkCanvasVideoRendererTest
, Video_Translate_Rotation_270
) {
478 SkCanvas
canvas(AllocBitmap(kWidth
, kHeight
));
479 FillCanvas(&canvas
, SK_ColorMAGENTA
);
481 PaintRotated(cropped_frame(),
483 gfx::Rect(kWidth
/ 2, kHeight
/ 2, kWidth
/ 2, kHeight
/ 2),
485 SkXfermode::kSrcOver_Mode
,
487 // Check the corners of quadrant 2 and 4.
488 EXPECT_EQ(SK_ColorMAGENTA
, GetColorAt(&canvas
, 0, 0));
489 EXPECT_EQ(SK_ColorMAGENTA
, GetColorAt(&canvas
, (kWidth
/ 2) - 1, 0));
490 EXPECT_EQ(SK_ColorMAGENTA
,
491 GetColorAt(&canvas
, (kWidth
/ 2) - 1, (kHeight
/ 2) - 1));
492 EXPECT_EQ(SK_ColorMAGENTA
, GetColorAt(&canvas
, 0, (kHeight
/ 2) - 1));
493 EXPECT_EQ(SK_ColorRED
, GetColorAt(&canvas
, kWidth
/ 2, kHeight
/ 2));
494 EXPECT_EQ(SK_ColorBLUE
, GetColorAt(&canvas
, kWidth
- 1, kHeight
/ 2));
495 EXPECT_EQ(SK_ColorGREEN
, GetColorAt(&canvas
, kWidth
- 1, kHeight
- 1));
496 EXPECT_EQ(SK_ColorBLACK
, GetColorAt(&canvas
, kWidth
/ 2, kHeight
- 1));