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 |