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 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 | 175 |
| 176 gpu::gles2::GLES2Interface* gl = context_3d.gl; | 176 gpu::gles2::GLES2Interface* gl = context_3d.gl; |
| 177 unsigned source_texture = 0; | 177 unsigned source_texture = 0; |
| 178 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { | 178 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { |
| 179 // TODO(dcastagna): At the moment Skia doesn't support targets different | 179 // TODO(dcastagna): At the moment Skia doesn't support targets different |
| 180 // than GL_TEXTURE_2D. Avoid this copy once | 180 // than GL_TEXTURE_2D. Avoid this copy once |
| 181 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed. | 181 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed. |
| 182 gl->GenTextures(1, &source_texture); | 182 gl->GenTextures(1, &source_texture); |
| 183 DCHECK(source_texture); | 183 DCHECK(source_texture); |
| 184 gl->BindTexture(GL_TEXTURE_2D, source_texture); | 184 gl->BindTexture(GL_TEXTURE_2D, source_texture); |
| 185 SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( | 185 SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( |
| 186 gl, video_frame, source_texture, GL_RGBA, GL_UNSIGNED_BYTE, true, | 186 context_3d, gl, video_frame, source_texture, GL_RGBA, GL_UNSIGNED_BYTE, |
| 187 false); | 187 true, false); |
| 188 } else { | 188 } else { |
| 189 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); | 189 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); |
| 190 source_texture = gl->CreateAndConsumeTextureCHROMIUM( | 190 source_texture = gl->CreateAndConsumeTextureCHROMIUM( |
| 191 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 191 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
| 192 } | 192 } |
| 193 GrBackendTextureDesc desc; | 193 GrBackendTextureDesc desc; |
| 194 desc.fFlags = kRenderTarget_GrBackendTextureFlag; | 194 desc.fFlags = kRenderTarget_GrBackendTextureFlag; |
| 195 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | 195 desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
| 196 desc.fWidth = video_frame->coded_size().width(); | 196 desc.fWidth = video_frame->coded_size().width(); |
| 197 desc.fHeight = video_frame->coded_size().height(); | 197 desc.fHeight = video_frame->coded_size().height(); |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 635 case PIXEL_FORMAT_RGB24: | 635 case PIXEL_FORMAT_RGB24: |
| 636 case PIXEL_FORMAT_RGB32: | 636 case PIXEL_FORMAT_RGB32: |
| 637 case PIXEL_FORMAT_MJPEG: | 637 case PIXEL_FORMAT_MJPEG: |
| 638 case PIXEL_FORMAT_MT21: | 638 case PIXEL_FORMAT_MT21: |
| 639 case PIXEL_FORMAT_UNKNOWN: | 639 case PIXEL_FORMAT_UNKNOWN: |
| 640 NOTREACHED(); | 640 NOTREACHED(); |
| 641 } | 641 } |
| 642 } | 642 } |
| 643 | 643 |
| 644 // static | 644 // static |
| 645 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( | 645 bool SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( |
| 646 gpu::gles2::GLES2Interface* gl, | 646 const Context3D& context_3d, |
| 647 gpu::gles2::GLES2Interface* destination_gl, | |
| 647 VideoFrame* video_frame, | 648 VideoFrame* video_frame, |
| 648 unsigned int texture, | 649 unsigned int texture, |
| 649 unsigned int internal_format, | 650 unsigned int internal_format, |
| 650 unsigned int type, | 651 unsigned int type, |
| 651 bool premultiply_alpha, | 652 bool premultiply_alpha, |
| 652 bool flip_y) { | 653 bool flip_y) { |
| 653 DCHECK(video_frame); | 654 DCHECK(video_frame); |
| 654 DCHECK(video_frame->HasTextures()); | 655 DCHECK(video_frame->HasTextures()); |
| 656 if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) { | |
| 657 if (!context_3d.gr_context) | |
| 658 return false; | |
| 659 sk_sp<SkImage> image = | |
| 660 NewSkImageFromVideoFrameYUVTextures(video_frame, context_3d); | |
| 655 | 661 |
| 656 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); | 662 const GrGLTextureInfo* texture_info = |
| 657 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || | 663 skia::GrBackendObjectToGrGLTextureInfo(image->getTextureHandle(true)); |
| 658 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || | |
| 659 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) | |
| 660 << mailbox_holder.texture_target; | |
| 661 | 664 |
| 662 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); | 665 gpu::gles2::GLES2Interface* canvas_gl = context_3d.gl; |
| 663 uint32_t source_texture = gl->CreateAndConsumeTextureCHROMIUM( | 666 gpu::MailboxHolder mailbox_holder; |
| 664 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 667 mailbox_holder.texture_target = texture_info->fTarget; |
| 668 canvas_gl->GenMailboxCHROMIUM(mailbox_holder.mailbox.name); | |
| 669 canvas_gl->ProduceTextureDirectCHROMIUM(texture_info->fID, | |
|
Daniele Castagna
2016/07/11 18:23:36
Isn't this assuming that SkImage has only one text
| |
| 670 mailbox_holder.texture_target, | |
| 671 mailbox_holder.mailbox.name); | |
| 665 | 672 |
| 666 // The video is stored in a unmultiplied format, so premultiply | 673 // Wait for mailbox creation on canvas context before consuming it and |
| 667 // if necessary. | 674 // copying from it on the consumer context. |
| 668 // Application itself needs to take care of setting the right |flip_y| | 675 const GLuint64 fence_sync = canvas_gl->InsertFenceSyncCHROMIUM(); |
| 669 // value down to get the expected result. | 676 canvas_gl->ShallowFlushCHROMIUM(); |
| 670 // "flip_y == true" means to reverse the video orientation while | 677 canvas_gl->GenSyncTokenCHROMIUM(fence_sync, |
| 671 // "flip_y == false" means to keep the intrinsic orientation. | 678 mailbox_holder.sync_token.GetData()); |
| 672 gl->CopyTextureCHROMIUM(source_texture, texture, internal_format, type, | |
| 673 flip_y, premultiply_alpha, false); | |
| 674 gl->DeleteTextures(1, &source_texture); | |
| 675 gl->Flush(); | |
| 676 | 679 |
| 677 SyncTokenClientImpl client(gl); | 680 destination_gl->WaitSyncTokenCHROMIUM( |
| 678 video_frame->UpdateReleaseSyncToken(&client); | 681 mailbox_holder.sync_token.GetConstData()); |
| 682 uint32_t source_texture2 = destination_gl->CreateAndConsumeTextureCHROMIUM( | |
| 683 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | |
| 684 | |
| 685 destination_gl->CopyTextureCHROMIUM(source_texture2, texture, | |
|
Daniele Castagna
2016/07/11 18:23:36
We're not validating internal_format anywhere if n
| |
| 686 internal_format, type, flip_y, | |
| 687 premultiply_alpha, false); | |
| 688 destination_gl->DeleteTextures(1, &source_texture2); | |
| 689 | |
| 690 // Wait for copy to complete before source texture destruction. | |
| 691 const GLuint64 dest_fence_sync = destination_gl->InsertFenceSyncCHROMIUM(); | |
| 692 destination_gl->ShallowFlushCHROMIUM(); | |
| 693 gpu::SyncToken dest_sync_token; | |
| 694 destination_gl->GenSyncTokenCHROMIUM(dest_fence_sync, | |
| 695 dest_sync_token.GetData()); | |
| 696 canvas_gl->WaitSyncTokenCHROMIUM(dest_sync_token.GetConstData()); | |
| 697 | |
| 698 SyncTokenClientImpl client(canvas_gl); | |
| 699 video_frame->UpdateReleaseSyncToken(&client); | |
| 700 } else { | |
| 701 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); | |
| 702 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || | |
| 703 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || | |
| 704 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) | |
| 705 << mailbox_holder.texture_target; | |
| 706 | |
| 707 destination_gl->WaitSyncTokenCHROMIUM( | |
| 708 mailbox_holder.sync_token.GetConstData()); | |
| 709 uint32_t source_texture = destination_gl->CreateAndConsumeTextureCHROMIUM( | |
| 710 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | |
| 711 | |
| 712 // The video is stored in a unmultiplied format, so premultiply | |
| 713 // if necessary. | |
| 714 // Application itself needs to take care of setting the right |flip_y| | |
| 715 // value down to get the expected result. | |
| 716 // "flip_y == true" means to reverse the video orientation while | |
| 717 // "flip_y == false" means to keep the intrinsic orientation. | |
| 718 destination_gl->CopyTextureCHROMIUM(source_texture, texture, | |
| 719 internal_format, type, flip_y, | |
| 720 premultiply_alpha, false); | |
| 721 destination_gl->DeleteTextures(1, &source_texture); | |
| 722 destination_gl->Flush(); | |
| 723 | |
| 724 SyncTokenClientImpl client(destination_gl); | |
| 725 video_frame->UpdateReleaseSyncToken(&client); | |
| 726 } | |
| 727 | |
| 728 return true; | |
| 679 } | 729 } |
| 680 | 730 |
| 681 void SkCanvasVideoRenderer::ResetCache() { | 731 void SkCanvasVideoRenderer::ResetCache() { |
| 682 DCHECK(thread_checker_.CalledOnValidThread()); | 732 DCHECK(thread_checker_.CalledOnValidThread()); |
| 683 // Clear cached values. | 733 // Clear cached values. |
| 684 last_image_ = nullptr; | 734 last_image_ = nullptr; |
| 685 last_timestamp_ = kNoTimestamp(); | 735 last_timestamp_ = kNoTimestamp(); |
| 686 } | 736 } |
| 687 | 737 |
| 688 } // namespace media | 738 } // namespace media |
| OLD | NEW |