| 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 <GLES3/gl3.h> | 7 #include <GLES3/gl3.h> |
| 8 #include <limits> | 8 #include <limits> |
| 9 | 9 |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "cc/paint/paint_canvas.h" |
| 12 #include "cc/paint/paint_flags.h" |
| 11 #include "gpu/GLES2/gl2extchromium.h" | 13 #include "gpu/GLES2/gl2extchromium.h" |
| 12 #include "gpu/command_buffer/client/gles2_interface.h" | 14 #include "gpu/command_buffer/client/gles2_interface.h" |
| 13 #include "gpu/command_buffer/common/mailbox_holder.h" | 15 #include "gpu/command_buffer/common/mailbox_holder.h" |
| 14 #include "media/base/data_buffer.h" | 16 #include "media/base/data_buffer.h" |
| 15 #include "media/base/video_frame.h" | 17 #include "media/base/video_frame.h" |
| 16 #include "media/base/yuv_convert.h" | 18 #include "media/base/yuv_convert.h" |
| 17 #include "skia/ext/texture_handle.h" | 19 #include "skia/ext/texture_handle.h" |
| 18 #include "third_party/libyuv/include/libyuv.h" | 20 #include "third_party/libyuv/include/libyuv.h" |
| 19 #include "third_party/skia/include/core/SkCanvas.h" | |
| 20 #include "third_party/skia/include/core/SkImage.h" | 21 #include "third_party/skia/include/core/SkImage.h" |
| 21 #include "third_party/skia/include/core/SkImageGenerator.h" | 22 #include "third_party/skia/include/core/SkImageGenerator.h" |
| 22 #include "third_party/skia/include/gpu/GrContext.h" | 23 #include "third_party/skia/include/gpu/GrContext.h" |
| 23 #include "third_party/skia/include/gpu/GrPaint.h" | 24 #include "third_party/skia/include/gpu/GrPaint.h" |
| 24 #include "third_party/skia/include/gpu/GrTexture.h" | 25 #include "third_party/skia/include/gpu/GrTexture.h" |
| 25 #include "third_party/skia/include/gpu/GrTextureProvider.h" | 26 #include "third_party/skia/include/gpu/GrTextureProvider.h" |
| 26 #include "third_party/skia/include/gpu/SkGr.h" | 27 #include "third_party/skia/include/gpu/SkGr.h" |
| 27 #include "third_party/skia/include/gpu/gl/GrGLTypes.h" | 28 #include "third_party/skia/include/gpu/gl/GrGLTypes.h" |
| 28 #include "ui/gfx/geometry/rect_f.h" | 29 #include "ui/gfx/geometry/rect_f.h" |
| 29 #include "ui/gfx/skia_util.h" | 30 #include "ui/gfx/skia_util.h" |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 FROM_HERE, | 332 FROM_HERE, |
| 332 base::TimeDelta::FromSeconds(kTemporaryResourceDeletionDelay), | 333 base::TimeDelta::FromSeconds(kTemporaryResourceDeletionDelay), |
| 333 this, | 334 this, |
| 334 &SkCanvasVideoRenderer::ResetCache) {} | 335 &SkCanvasVideoRenderer::ResetCache) {} |
| 335 | 336 |
| 336 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() { | 337 SkCanvasVideoRenderer::~SkCanvasVideoRenderer() { |
| 337 ResetCache(); | 338 ResetCache(); |
| 338 } | 339 } |
| 339 | 340 |
| 340 void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame, | 341 void SkCanvasVideoRenderer::Paint(const scoped_refptr<VideoFrame>& video_frame, |
| 341 SkCanvas* canvas, | 342 cc::PaintCanvas* canvas, |
| 342 const gfx::RectF& dest_rect, | 343 const gfx::RectF& dest_rect, |
| 343 SkPaint& paint, | 344 cc::PaintFlags& paint, |
| 344 VideoRotation video_rotation, | 345 VideoRotation video_rotation, |
| 345 const Context3D& context_3d) { | 346 const Context3D& context_3d) { |
| 346 DCHECK(thread_checker_.CalledOnValidThread()); | 347 DCHECK(thread_checker_.CalledOnValidThread()); |
| 347 if (paint.getAlpha() == 0) { | 348 if (paint.getAlpha() == 0) { |
| 348 return; | 349 return; |
| 349 } | 350 } |
| 350 | 351 |
| 351 SkRect dest; | 352 SkRect dest; |
| 352 dest.set(dest_rect.x(), dest_rect.y(), dest_rect.right(), dest_rect.bottom()); | 353 dest.set(dest_rect.x(), dest_rect.y(), dest_rect.right(), dest_rect.bottom()); |
| 353 | 354 |
| 354 // Paint black rectangle if there isn't a frame available or the | 355 // Paint black rectangle if there isn't a frame available or the |
| 355 // frame has an unexpected format. | 356 // frame has an unexpected format. |
| 356 if (!video_frame.get() || video_frame->natural_size().IsEmpty() || | 357 if (!video_frame.get() || video_frame->natural_size().IsEmpty() || |
| 357 !(media::IsYuvPlanar(video_frame->format()) || | 358 !(media::IsYuvPlanar(video_frame->format()) || |
| 358 video_frame->format() == media::PIXEL_FORMAT_Y16 || | 359 video_frame->format() == media::PIXEL_FORMAT_Y16 || |
| 359 video_frame->HasTextures())) { | 360 video_frame->HasTextures())) { |
| 360 SkPaint blackWithAlphaPaint; | 361 cc::PaintFlags black_with_alpha_flags; |
| 361 blackWithAlphaPaint.setAlpha(paint.getAlpha()); | 362 black_with_alpha_flags.setAlpha(paint.getAlpha()); |
| 362 canvas->drawRect(dest, blackWithAlphaPaint); | 363 canvas->drawRect(dest, black_with_alpha_flags); |
| 363 canvas->flush(); | 364 canvas->flush(); |
| 364 return; | 365 return; |
| 365 } | 366 } |
| 366 | 367 |
| 367 gpu::gles2::GLES2Interface* gl = context_3d.gl; | 368 gpu::gles2::GLES2Interface* gl = context_3d.gl; |
| 368 if (!UpdateLastImage(video_frame, context_3d)) | 369 if (!UpdateLastImage(video_frame, context_3d)) |
| 369 return; | 370 return; |
| 370 | 371 |
| 371 SkPaint videoPaint; | 372 cc::PaintFlags video_flags; |
| 372 videoPaint.setAlpha(paint.getAlpha()); | 373 video_flags.setAlpha(paint.getAlpha()); |
| 373 videoPaint.setBlendMode(paint.getBlendMode()); | 374 video_flags.setBlendMode(paint.getBlendMode()); |
| 374 videoPaint.setFilterQuality(paint.getFilterQuality()); | 375 video_flags.setFilterQuality(paint.getFilterQuality()); |
| 375 | 376 |
| 376 const bool need_rotation = video_rotation != VIDEO_ROTATION_0; | 377 const bool need_rotation = video_rotation != VIDEO_ROTATION_0; |
| 377 const bool need_scaling = | 378 const bool need_scaling = |
| 378 dest_rect.size() != | 379 dest_rect.size() != |
| 379 gfx::SizeF(gfx::SkISizeToSize(last_image_->dimensions())); | 380 gfx::SizeF(gfx::SkISizeToSize(last_image_->dimensions())); |
| 380 const bool need_translation = !dest_rect.origin().IsOrigin(); | 381 const bool need_translation = !dest_rect.origin().IsOrigin(); |
| 381 bool need_transform = need_rotation || need_scaling || need_translation; | 382 bool need_transform = need_rotation || need_scaling || need_translation; |
| 382 if (need_transform) { | 383 if (need_transform) { |
| 383 canvas->save(); | 384 canvas->save(); |
| 384 canvas->translate( | 385 canvas->translate( |
| (...skipping 29 matching lines...) Expand all Loading... |
| 414 } | 415 } |
| 415 | 416 |
| 416 // This is a workaround for crbug.com/524717. A texture backed image is not | 417 // This is a workaround for crbug.com/524717. A texture backed image is not |
| 417 // safe to access on another thread or GL context. So if we're drawing into a | 418 // safe to access on another thread or GL context. So if we're drawing into a |
| 418 // recording canvas we read the texture back into CPU memory and record that | 419 // recording canvas we read the texture back into CPU memory and record that |
| 419 // sw image into the SkPicture. The long term solution is for Skia to provide | 420 // sw image into the SkPicture. The long term solution is for Skia to provide |
| 420 // a SkPicture filter that makes a picture safe for multiple CPU raster | 421 // a SkPicture filter that makes a picture safe for multiple CPU raster |
| 421 // threads. (skbug.com/4321). | 422 // threads. (skbug.com/4321). |
| 422 if (canvas->imageInfo().colorType() == kUnknown_SkColorType) { | 423 if (canvas->imageInfo().colorType() == kUnknown_SkColorType) { |
| 423 sk_sp<SkImage> swImage = last_image_->makeNonTextureImage(); | 424 sk_sp<SkImage> swImage = last_image_->makeNonTextureImage(); |
| 424 canvas->drawImage(swImage, 0, 0, &videoPaint); | 425 canvas->drawImage(swImage, 0, 0, &video_flags); |
| 425 } else { | 426 } else { |
| 426 canvas->drawImage(last_image_.get(), 0, 0, &videoPaint); | 427 canvas->drawImage(last_image_.get(), 0, 0, &video_flags); |
| 427 } | 428 } |
| 428 | 429 |
| 429 if (need_transform) | 430 if (need_transform) |
| 430 canvas->restore(); | 431 canvas->restore(); |
| 431 // Make sure to flush so we can remove the videoframe from the generator. | 432 // Make sure to flush so we can remove the videoframe from the generator. |
| 432 canvas->flush(); | 433 canvas->flush(); |
| 433 | 434 |
| 434 if (video_frame->HasTextures()) { | 435 if (video_frame->HasTextures()) { |
| 435 DCHECK(gl); | 436 DCHECK(gl); |
| 436 SyncTokenClientImpl client(gl); | 437 SyncTokenClientImpl client(gl); |
| 437 video_frame->UpdateReleaseSyncToken(&client); | 438 video_frame->UpdateReleaseSyncToken(&client); |
| 438 } | 439 } |
| 439 } | 440 } |
| 440 | 441 |
| 441 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, | 442 void SkCanvasVideoRenderer::Copy(const scoped_refptr<VideoFrame>& video_frame, |
| 442 SkCanvas* canvas, | 443 cc::PaintCanvas* canvas, |
| 443 const Context3D& context_3d) { | 444 const Context3D& context_3d) { |
| 444 SkPaint paint; | 445 cc::PaintFlags flags; |
| 445 paint.setBlendMode(SkBlendMode::kSrc); | 446 flags.setBlendMode(SkBlendMode::kSrc); |
| 446 paint.setFilterQuality(kLow_SkFilterQuality); | 447 flags.setFilterQuality(kLow_SkFilterQuality); |
| 447 Paint(video_frame, canvas, gfx::RectF(video_frame->visible_rect()), paint, | 448 Paint(video_frame, canvas, gfx::RectF(video_frame->visible_rect()), flags, |
| 448 media::VIDEO_ROTATION_0, context_3d); | 449 media::VIDEO_ROTATION_0, context_3d); |
| 449 } | 450 } |
| 450 | 451 |
| 451 namespace { | 452 namespace { |
| 452 | 453 |
| 453 // libyuv doesn't support 9- and 10-bit video frames yet. This function | 454 // libyuv doesn't support 9- and 10-bit video frames yet. This function |
| 454 // creates a regular 8-bit video frame which we can give to libyuv. | 455 // creates a regular 8-bit video frame which we can give to libyuv. |
| 455 scoped_refptr<VideoFrame> DownShiftHighbitVideoFrame( | 456 scoped_refptr<VideoFrame> DownShiftHighbitVideoFrame( |
| 456 const VideoFrame* video_frame) { | 457 const VideoFrame* video_frame) { |
| 457 VideoPixelFormat format; | 458 VideoPixelFormat format; |
| (...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 960 last_image_->bounds().contains(visible_rect)) { | 961 last_image_->bounds().contains(visible_rect)) { |
| 961 last_image_ = last_image_->makeSubset(visible_rect); | 962 last_image_ = last_image_->makeSubset(visible_rect); |
| 962 } | 963 } |
| 963 } | 964 } |
| 964 | 965 |
| 965 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { | 966 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { |
| 966 return last_image_dimensions_for_testing_; | 967 return last_image_dimensions_for_testing_; |
| 967 } | 968 } |
| 968 | 969 |
| 969 } // namespace media | 970 } // namespace media |
| OLD | NEW |