| 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" |
| 11 #include "gpu/command_buffer/client/gles2_interface.h" | 11 #include "gpu/command_buffer/client/gles2_interface.h" |
| 12 #include "gpu/command_buffer/common/mailbox_holder.h" | 12 #include "gpu/command_buffer/common/mailbox_holder.h" |
| 13 #include "media/base/video_frame.h" | 13 #include "media/base/video_frame.h" |
| 14 #include "media/base/yuv_convert.h" | 14 #include "media/base/yuv_convert.h" |
| 15 #include "skia/ext/texture_handle.h" | 15 #include "skia/ext/texture_handle.h" |
| 16 #include "skia/ext/cdl_canvas.h" |
| 17 #include "skia/ext/cdl_paint.h" |
| 16 #include "third_party/libyuv/include/libyuv.h" | 18 #include "third_party/libyuv/include/libyuv.h" |
| 17 #include "third_party/skia/include/core/SkCanvas.h" | 19 #include "third_party/skia/include/core/SkCanvas.h" |
| 18 #include "third_party/skia/include/core/SkImage.h" | 20 #include "third_party/skia/include/core/SkImage.h" |
| 19 #include "third_party/skia/include/core/SkImageGenerator.h" | 21 #include "third_party/skia/include/core/SkImageGenerator.h" |
| 20 #include "third_party/skia/include/gpu/GrContext.h" | 22 #include "third_party/skia/include/gpu/GrContext.h" |
| 21 #include "third_party/skia/include/gpu/GrPaint.h" | 23 #include "third_party/skia/include/gpu/GrPaint.h" |
| 22 #include "third_party/skia/include/gpu/GrTexture.h" | 24 #include "third_party/skia/include/gpu/GrTexture.h" |
| 23 #include "third_party/skia/include/gpu/GrTextureProvider.h" | 25 #include "third_party/skia/include/gpu/GrTextureProvider.h" |
| 24 #include "third_party/skia/include/gpu/SkGr.h" | 26 #include "third_party/skia/include/gpu/SkGr.h" |
| 25 #include "third_party/skia/include/gpu/gl/GrGLTypes.h" | 27 #include "third_party/skia/include/gpu/gl/GrGLTypes.h" |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 FROM_HERE, | 326 FROM_HERE, |
| 325 base::TimeDelta::FromSeconds(kTemporaryResourceDeletionDelay), | 327 base::TimeDelta::FromSeconds(kTemporaryResourceDeletionDelay), |
| 326 this, | 328 this, |
| 327 &SkCanvasVideoRenderer::ResetCache) {} | 329 &SkCanvasVideoRenderer::ResetCache) {} |
| 328 | 330 |
| 329 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() { | 331 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() { |
| 330 ResetCache(); | 332 ResetCache(); |
| 331 } | 333 } |
| 332 | 334 |
| 333 void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame, | 335 void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame, |
| 334 SkCanvas* canvas, | 336 CdlCanvas* canvas, |
| 335 const gfx::RectF& dest_rect, | 337 const gfx::RectF& dest_rect, |
| 336 SkPaint& paint, | 338 CdlPaint& paint, |
| 337 VideoRotation video_rotation, | 339 VideoRotation video_rotation, |
| 338 const Context3D& context_3d) { | 340 const Context3D& context_3d) { |
| 339 DCHECK(thread_checker_.CalledOnValidThread()); | 341 DCHECK(thread_checker_.CalledOnValidThread()); |
| 340 if (paint.getAlpha() == 0) { | 342 if (paint.getAlpha() == 0) { |
| 341 return; | 343 return; |
| 342 } | 344 } |
| 343 | 345 |
| 344 SkRect dest; | 346 SkRect dest; |
| 345 dest.set(dest_rect.x(), dest_rect.y(), dest_rect.right(), dest_rect.bottom()); | 347 dest.set(dest_rect.x(), dest_rect.y(), dest_rect.right(), dest_rect.bottom()); |
| 346 | 348 |
| 347 // 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 |
| 348 // frame has an unexpected format. | 350 // frame has an unexpected format. |
| 349 if (!video_frame.get() || video_frame->natural_size().IsEmpty() || | 351 if (!video_frame.get() || video_frame->natural_size().IsEmpty() || |
| 350 !(media::IsYuvPlanar(video_frame->format()) || | 352 !(media::IsYuvPlanar(video_frame->format()) || |
| 351 video_frame->format() == media::PIXEL_FORMAT_Y16 || | 353 video_frame->format() == media::PIXEL_FORMAT_Y16 || |
| 352 video_frame->HasTextures())) { | 354 video_frame->HasTextures())) { |
| 353 SkPaint blackWithAlphaPaint; | 355 CdlPaint blackWithAlphaPaint; |
| 354 blackWithAlphaPaint.setAlpha(paint.getAlpha()); | 356 blackWithAlphaPaint.setAlpha(paint.getAlpha()); |
| 355 canvas->drawRect(dest, blackWithAlphaPaint); | 357 canvas->drawRect(dest, blackWithAlphaPaint); |
| 356 canvas->flush(); | 358 canvas->flush(); |
| 357 return; | 359 return; |
| 358 } | 360 } |
| 359 | 361 |
| 360 gpu::gles2::GLES2Interface* gl = context_3d.gl; | 362 gpu::gles2::GLES2Interface* gl = context_3d.gl; |
| 361 if (!UpdateLastImage(video_frame, context_3d)) | 363 if (!UpdateLastImage(video_frame, context_3d)) |
| 362 return; | 364 return; |
| 363 | 365 |
| 364 SkPaint videoPaint; | 366 CdlPaint videoPaint; |
| 365 videoPaint.setAlpha(paint.getAlpha()); | 367 videoPaint.setAlpha(paint.getAlpha()); |
| 366 videoPaint.setBlendMode(paint.getBlendMode()); | 368 videoPaint.setBlendMode(paint.getBlendMode()); |
| 367 videoPaint.setFilterQuality(paint.getFilterQuality()); | 369 videoPaint.setFilterQuality(paint.getFilterQuality()); |
| 368 | 370 |
| 369 const bool need_rotation = video_rotation != VIDEO_ROTATION_0; | 371 const bool need_rotation = video_rotation != VIDEO_ROTATION_0; |
| 370 const bool need_scaling = | 372 const bool need_scaling = |
| 371 dest_rect.size() != | 373 dest_rect.size() != |
| 372 gfx::SizeF(gfx::SkISizeToSize(last_image_->dimensions())); | 374 gfx::SizeF(gfx::SkISizeToSize(last_image_->dimensions())); |
| 373 const bool need_translation = !dest_rect.origin().IsOrigin(); | 375 const bool need_translation = !dest_rect.origin().IsOrigin(); |
| 374 bool need_transform = need_rotation || need_scaling || need_translation; | 376 bool need_transform = need_rotation || need_scaling || need_translation; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 405 canvas->translate(-SkFloatToScalar(last_image_->width() * 0.5f), | 407 canvas->translate(-SkFloatToScalar(last_image_->width() * 0.5f), |
| 406 -SkFloatToScalar(last_image_->height() * 0.5f)); | 408 -SkFloatToScalar(last_image_->height() * 0.5f)); |
| 407 } | 409 } |
| 408 | 410 |
| 409 // This is a workaround for crbug.com/524717. A texture backed image is not | 411 // This is a workaround for crbug.com/524717. A texture backed image is not |
| 410 // safe to access on another thread or GL context. So if we're drawing into a | 412 // safe to access on another thread or GL context. So if we're drawing into a |
| 411 // recording canvas we read the texture back into CPU memory and record that | 413 // recording canvas we read the texture back into CPU memory and record that |
| 412 // sw image into the SkPicture. The long term solution is for Skia to provide | 414 // sw image into the SkPicture. The long term solution is for Skia to provide |
| 413 // a SkPicture filter that makes a picture safe for multiple CPU raster | 415 // a SkPicture filter that makes a picture safe for multiple CPU raster |
| 414 // threads. (skbug.com/4321). | 416 // threads. (skbug.com/4321). |
| 415 if (canvas->imageInfo().colorType() == kUnknown_SkColorType) { | 417 if (GetSkCanvas(canvas)->imageInfo().colorType() == kUnknown_SkColorType) { |
| 416 sk_sp<SkImage> swImage = last_image_->makeNonTextureImage(); | 418 sk_sp<SkImage> swImage = last_image_->makeNonTextureImage(); |
| 419 |
| 417 canvas->drawImage(swImage, 0, 0, &videoPaint); | 420 canvas->drawImage(swImage, 0, 0, &videoPaint); |
| 418 } else { | 421 } else { |
| 419 canvas->drawImage(last_image_.get(), 0, 0, &videoPaint); | 422 canvas->drawImage(last_image_.get(), 0, 0, &videoPaint); |
| 420 } | 423 } |
| 421 | 424 |
| 422 if (need_transform) | 425 if (need_transform) |
| 423 canvas->restore(); | 426 canvas->restore(); |
| 424 // Make sure to flush so we can remove the videoframe from the generator. | 427 // Make sure to flush so we can remove the videoframe from the generator. |
| 425 canvas->flush(); | 428 canvas->flush(); |
| 426 | 429 |
| 427 if (video_frame->HasTextures()) { | 430 if (video_frame->HasTextures()) { |
| 428 DCHECK(gl); | 431 DCHECK(gl); |
| 429 SyncTokenClientImpl client(gl); | 432 SyncTokenClientImpl client(gl); |
| 430 video_frame->UpdateReleaseSyncToken(&client); | 433 video_frame->UpdateReleaseSyncToken(&client); |
| 431 } | 434 } |
| 432 } | 435 } |
| 433 | 436 |
| 434 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, | 437 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, |
| 435 SkCanvas* canvas, | 438 CdlCanvas* canvas, |
| 436 const Context3D& context_3d) { | 439 const Context3D& context_3d) { |
| 437 SkPaint paint; | 440 CdlPaint paint; |
| 438 paint.setBlendMode(SkBlendMode::kSrc); | 441 paint.setBlendMode(SkBlendMode::kSrc); |
| 439 paint.setFilterQuality(kLow_SkFilterQuality); | 442 paint.setFilterQuality(kLow_SkFilterQuality); |
| 440 Paint(video_frame, canvas, gfx::RectF(video_frame->visible_rect()), paint, | 443 Paint(video_frame, canvas, gfx::RectF(video_frame->visible_rect()), paint, |
| 441 media::VIDEO_ROTATION_0, context_3d); | 444 media::VIDEO_ROTATION_0, context_3d); |
| 442 } | 445 } |
| 443 | 446 |
| 444 namespace { | 447 namespace { |
| 445 | 448 |
| 446 // libyuv doesn't support 9- and 10-bit video frames yet. This function | 449 // libyuv doesn't support 9- and 10-bit video frames yet. This function |
| 447 // creates a regular 8-bit video frame which we can give to libyuv. | 450 // creates a regular 8-bit video frame which we can give to libyuv. |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 841 last_image_->bounds().contains(visible_rect)) { | 844 last_image_->bounds().contains(visible_rect)) { |
| 842 last_image_ = last_image_->makeSubset(visible_rect); | 845 last_image_ = last_image_->makeSubset(visible_rect); |
| 843 } | 846 } |
| 844 } | 847 } |
| 845 | 848 |
| 846 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { | 849 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { |
| 847 return last_image_dimensions_for_testing_; | 850 return last_image_dimensions_for_testing_; |
| 848 } | 851 } |
| 849 | 852 |
| 850 } // namespace media | 853 } // namespace media |
| OLD | NEW |