Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/renderers/skcanvas_video_renderer.h" | 5 #include "media/renderers/skcanvas_video_renderer.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/macros.h" | 9 #include "base/macros.h" |
| 10 #include "gpu/GLES2/gl2extchromium.h" | 10 #include "gpu/GLES2/gl2extchromium.h" |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 325 this, | 325 this, |
| 326 &SkCanvasVideoRenderer::ResetCache) {} | 326 &SkCanvasVideoRenderer::ResetCache) {} |
| 327 | 327 |
| 328 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() { | 328 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() { |
| 329 ResetCache(); | 329 ResetCache(); |
| 330 } | 330 } |
| 331 | 331 |
| 332 void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame, | 332 void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame, |
| 333 SkCanvas* canvas, | 333 SkCanvas* canvas, |
| 334 const gfx::RectF& dest_rect, | 334 const gfx::RectF& dest_rect, |
| 335 uint8_t alpha, | 335 const SkPaint* paint, |
|
Justin Novosad
2016/08/25 19:18:18
since the code is not mean to support nullptr for
| |
| 336 SkXfermode::Mode mode, | |
| 337 VideoRotation video_rotation, | 336 VideoRotation video_rotation, |
| 338 const Context3D& context_3d) { | 337 const Context3D& context_3d) { |
| 339 DCHECK(thread_checker_.CalledOnValidThread()); | 338 DCHECK(thread_checker_.CalledOnValidThread()); |
| 340 if (alpha == 0) { | 339 if (paint->getAlpha() == 0) { |
| 341 return; | 340 return; |
| 342 } | 341 } |
| 343 | 342 |
| 344 SkRect dest; | 343 SkRect dest; |
| 345 dest.set(dest_rect.x(), dest_rect.y(), dest_rect.right(), dest_rect.bottom()); | 344 dest.set(dest_rect.x(), dest_rect.y(), dest_rect.right(), dest_rect.bottom()); |
| 346 | 345 |
| 347 SkPaint paint; | 346 SkPaint freshPaint; |
|
Justin Novosad
2016/08/25 19:18:19
this is a funny name. What do you mean by fresh?
xidachen
2016/08/26 02:21:39
It is basically explaining that we are creating a
Justin Novosad
2016/08/26 14:25:25
Think of the person reading this code trying to un
| |
| 348 paint.setAlpha(alpha); | 347 freshPaint.setAlpha(paint->getAlpha()); |
| 349 | 348 |
| 350 // Paint black rectangle if there isn't a frame available or the | 349 // Paint black rectangle if there isn't a frame available or the |
| 351 // frame has an unexpected format. | 350 // frame has an unexpected format. |
| 352 if (!video_frame.get() || video_frame->natural_size().IsEmpty() || | 351 if (!video_frame.get() || video_frame->natural_size().IsEmpty() || |
| 353 !(media::IsYuvPlanar(video_frame->format()) || | 352 !(media::IsYuvPlanar(video_frame->format()) || |
| 354 video_frame->HasTextures())) { | 353 video_frame->HasTextures())) { |
| 355 canvas->drawRect(dest, paint); | 354 canvas->drawRect(dest, freshPaint); |
| 356 canvas->flush(); | 355 canvas->flush(); |
| 357 return; | 356 return; |
| 358 } | 357 } |
| 359 | 358 |
| 360 gpu::gles2::GLES2Interface* gl = context_3d.gl; | 359 gpu::gles2::GLES2Interface* gl = context_3d.gl; |
| 361 if (!UpdateLastImage(video_frame, context_3d)) | 360 if (!UpdateLastImage(video_frame, context_3d)) |
| 362 return; | 361 return; |
| 363 | 362 |
| 364 paint.setXfermodeMode(mode); | 363 SkXfermode::Mode mode; |
| 365 paint.setFilterQuality(kLow_SkFilterQuality); | 364 if (!paint || !SkXfermode::AsMode(paint->getXfermode(), &mode)) |
| 365 mode = SkXfermode::kSrcOver_Mode; | |
| 366 freshPaint.setXfermodeMode(mode); | |
| 367 freshPaint.setFilterQuality(paint->getFilterQuality()); | |
| 366 | 368 |
| 367 const bool need_rotation = video_rotation != VIDEO_ROTATION_0; | 369 const bool need_rotation = video_rotation != VIDEO_ROTATION_0; |
| 368 const bool need_scaling = | 370 const bool need_scaling = |
| 369 dest_rect.size() != | 371 dest_rect.size() != |
| 370 gfx::SizeF(gfx::SkISizeToSize(last_image_->dimensions())); | 372 gfx::SizeF(gfx::SkISizeToSize(last_image_->dimensions())); |
| 371 const bool need_translation = !dest_rect.origin().IsOrigin(); | 373 const bool need_translation = !dest_rect.origin().IsOrigin(); |
| 372 bool need_transform = need_rotation || need_scaling || need_translation; | 374 bool need_transform = need_rotation || need_scaling || need_translation; |
| 373 if (need_transform) { | 375 if (need_transform) { |
| 374 canvas->save(); | 376 canvas->save(); |
| 375 canvas->translate( | 377 canvas->translate( |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 405 } | 407 } |
| 406 | 408 |
| 407 // This is a workaround for crbug.com/524717. A texture backed image is not | 409 // This is a workaround for crbug.com/524717. A texture backed image is not |
| 408 // safe to access on another thread or GL context. So if we're drawing into a | 410 // safe to access on another thread or GL context. So if we're drawing into a |
| 409 // recording canvas we read the texture back into CPU memory and record that | 411 // recording canvas we read the texture back into CPU memory and record that |
| 410 // sw image into the SkPicture. The long term solution is for Skia to provide | 412 // sw image into the SkPicture. The long term solution is for Skia to provide |
| 411 // a SkPicture filter that makes a picture safe for multiple CPU raster | 413 // a SkPicture filter that makes a picture safe for multiple CPU raster |
| 412 // threads. (skbug.com/4321). | 414 // threads. (skbug.com/4321). |
| 413 if (canvas->imageInfo().colorType() == kUnknown_SkColorType) { | 415 if (canvas->imageInfo().colorType() == kUnknown_SkColorType) { |
| 414 sk_sp<SkImage> swImage = last_image_->makeNonTextureImage(); | 416 sk_sp<SkImage> swImage = last_image_->makeNonTextureImage(); |
| 415 canvas->drawImage(swImage, 0, 0, &paint); | 417 canvas->drawImage(swImage, 0, 0, &freshPaint); |
| 416 } else { | 418 } else { |
| 417 canvas->drawImage(last_image_.get(), 0, 0, &paint); | 419 canvas->drawImage(last_image_.get(), 0, 0, &freshPaint); |
| 418 } | 420 } |
| 419 | 421 |
| 420 if (need_transform) | 422 if (need_transform) |
| 421 canvas->restore(); | 423 canvas->restore(); |
| 422 // Make sure to flush so we can remove the videoframe from the generator. | 424 // Make sure to flush so we can remove the videoframe from the generator. |
| 423 canvas->flush(); | 425 canvas->flush(); |
| 424 | 426 |
| 425 if (video_frame->HasTextures()) { | 427 if (video_frame->HasTextures()) { |
| 426 DCHECK(gl); | 428 DCHECK(gl); |
| 427 SyncTokenClientImpl client(gl); | 429 SyncTokenClientImpl client(gl); |
| 428 video_frame->UpdateReleaseSyncToken(&client); | 430 video_frame->UpdateReleaseSyncToken(&client); |
| 429 } | 431 } |
| 430 } | 432 } |
| 431 | 433 |
| 432 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, | 434 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, |
| 433 SkCanvas* canvas, | 435 SkCanvas* canvas, |
| 434 const Context3D& context_3d) { | 436 const Context3D& context_3d) { |
| 435 Paint(video_frame, canvas, gfx::RectF(video_frame->visible_rect()), 0xff, | 437 SkPaint paint; |
| 436 SkXfermode::kSrc_Mode, media::VIDEO_ROTATION_0, context_3d); | 438 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| 439 paint.setAlpha(0xFF); | |
|
Justin Novosad
2016/08/25 19:18:18
not necessary
xidachen
2016/08/26 02:21:39
Done.
| |
| 440 paint.setFilterQuality(kLow_SkFilterQuality); | |
|
Justin Novosad
2016/08/25 19:18:18
not necessary
xidachen
2016/08/26 02:21:39
But without this line, the default filter quality
| |
| 441 Paint(video_frame, canvas, gfx::RectF(video_frame->visible_rect()), &paint, | |
| 442 media::VIDEO_ROTATION_0, context_3d); | |
| 437 } | 443 } |
| 438 | 444 |
| 439 namespace { | 445 namespace { |
| 440 | 446 |
| 441 // libyuv doesn't support 9- and 10-bit video frames yet. This function | 447 // libyuv doesn't support 9- and 10-bit video frames yet. This function |
| 442 // creates a regular 8-bit video frame which we can give to libyuv. | 448 // creates a regular 8-bit video frame which we can give to libyuv. |
| 443 scoped_refptr<VideoFrame> DownShiftHighbitVideoFrame( | 449 scoped_refptr<VideoFrame> DownShiftHighbitVideoFrame( |
| 444 const VideoFrame* video_frame) { | 450 const VideoFrame* video_frame) { |
| 445 VideoPixelFormat format; | 451 VideoPixelFormat format; |
| 446 int shift = 1; | 452 int shift = 1; |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 748 if (!last_image_) // Couldn't create the SkImage. | 754 if (!last_image_) // Couldn't create the SkImage. |
| 749 return false; | 755 return false; |
| 750 last_timestamp_ = video_frame->timestamp(); | 756 last_timestamp_ = video_frame->timestamp(); |
| 751 } | 757 } |
| 752 last_image_deleting_timer_.Reset(); | 758 last_image_deleting_timer_.Reset(); |
| 753 DCHECK(!!last_image_); | 759 DCHECK(!!last_image_); |
| 754 return true; | 760 return true; |
| 755 } | 761 } |
| 756 | 762 |
| 757 } // namespace media | 763 } // namespace media |
| OLD | NEW |