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" |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 | 179 |
180 gpu::gles2::GLES2Interface* gl = context_3d.gl; | 180 gpu::gles2::GLES2Interface* gl = context_3d.gl; |
181 unsigned source_texture = 0; | 181 unsigned source_texture = 0; |
182 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { | 182 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { |
183 // TODO(dcastagna): At the moment Skia doesn't support targets different | 183 // TODO(dcastagna): At the moment Skia doesn't support targets different |
184 // than GL_TEXTURE_2D. Avoid this copy once | 184 // than GL_TEXTURE_2D. Avoid this copy once |
185 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed. | 185 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed. |
186 gl->GenTextures(1, &source_texture); | 186 gl->GenTextures(1, &source_texture); |
187 DCHECK(source_texture); | 187 DCHECK(source_texture); |
188 gl->BindTexture(GL_TEXTURE_2D, source_texture); | 188 gl->BindTexture(GL_TEXTURE_2D, source_texture); |
| 189 const gfx::Size& natural_size = video_frame->natural_size(); |
| 190 gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, natural_size.width(), |
| 191 natural_size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| 192 nullptr); |
189 SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( | 193 SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
190 gl, video_frame, source_texture, GL_RGBA, GL_UNSIGNED_BYTE, true, | 194 gl, video_frame, source_texture, true, false); |
191 false); | |
192 } else { | 195 } else { |
193 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); | 196 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); |
194 source_texture = gl->CreateAndConsumeTextureCHROMIUM( | 197 source_texture = gl->CreateAndConsumeTextureCHROMIUM( |
195 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 198 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
196 } | 199 } |
197 GrBackendTextureDesc desc; | 200 GrBackendTextureDesc desc; |
198 desc.fFlags = kRenderTarget_GrBackendTextureFlag; | 201 desc.fFlags = kRenderTarget_GrBackendTextureFlag; |
199 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | 202 desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
200 desc.fWidth = video_frame->coded_size().width(); | 203 desc.fWidth = video_frame->coded_size().width(); |
201 desc.fHeight = video_frame->coded_size().height(); | 204 desc.fHeight = video_frame->coded_size().height(); |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 case PIXEL_FORMAT_UNKNOWN: | 749 case PIXEL_FORMAT_UNKNOWN: |
747 NOTREACHED() << "Only YUV formats and Y16 are supported."; | 750 NOTREACHED() << "Only YUV formats and Y16 are supported."; |
748 } | 751 } |
749 } | 752 } |
750 | 753 |
751 // static | 754 // static |
752 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( | 755 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
753 gpu::gles2::GLES2Interface* gl, | 756 gpu::gles2::GLES2Interface* gl, |
754 VideoFrame* video_frame, | 757 VideoFrame* video_frame, |
755 unsigned int texture, | 758 unsigned int texture, |
756 unsigned int internal_format, | |
757 unsigned int type, | |
758 bool premultiply_alpha, | 759 bool premultiply_alpha, |
759 bool flip_y) { | 760 bool flip_y) { |
760 DCHECK(video_frame); | 761 DCHECK(video_frame); |
761 DCHECK(video_frame->HasTextures()); | 762 DCHECK(video_frame->HasTextures()); |
762 | 763 |
763 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); | 764 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); |
764 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || | 765 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || |
765 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || | 766 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || |
766 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) | 767 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) |
767 << mailbox_holder.texture_target; | 768 << mailbox_holder.texture_target; |
768 | 769 |
769 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); | 770 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); |
770 uint32_t source_texture = gl->CreateAndConsumeTextureCHROMIUM( | 771 uint32_t source_texture = gl->CreateAndConsumeTextureCHROMIUM( |
771 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 772 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
772 | 773 |
773 // The video is stored in a unmultiplied format, so premultiply | 774 // The video is stored in a unmultiplied format, so premultiply |
774 // if necessary. | 775 // if necessary. |
775 // Application itself needs to take care of setting the right |flip_y| | 776 // Application itself needs to take care of setting the right |flip_y| |
776 // value down to get the expected result. | 777 // value down to get the expected result. |
777 // "flip_y == true" means to reverse the video orientation while | 778 // "flip_y == true" means to reverse the video orientation while |
778 // "flip_y == false" means to keep the intrinsic orientation. | 779 // "flip_y == false" means to keep the intrinsic orientation. |
779 gl->CopyTextureCHROMIUM(source_texture, 0, texture, 0, internal_format, type, | 780 |
780 flip_y, premultiply_alpha, false); | 781 // The video's texture might be larger than the natural size because |
| 782 // the encoder might have had to round up to the size of a macroblock. |
| 783 // Make sure to only copy the natural size to avoid putting garbage |
| 784 // into the bottom of the destination texture. |
| 785 const gfx::Size& natural_size = video_frame->natural_size(); |
| 786 gl->CopySubTextureCHROMIUM(source_texture, 0, texture, 0, 0, 0, 0, 0, |
| 787 natural_size.width(), natural_size.height(), |
| 788 flip_y, premultiply_alpha, false); |
781 gl->DeleteTextures(1, &source_texture); | 789 gl->DeleteTextures(1, &source_texture); |
782 gl->Flush(); | 790 gl->Flush(); |
783 | 791 |
784 SyncTokenClientImpl client(gl); | 792 SyncTokenClientImpl client(gl); |
785 video_frame->UpdateReleaseSyncToken(&client); | 793 video_frame->UpdateReleaseSyncToken(&client); |
786 } | 794 } |
787 | 795 |
788 bool SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( | 796 bool SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( |
789 const Context3D& context_3d, | 797 const Context3D& context_3d, |
790 gpu::gles2::GLES2Interface* destination_gl, | 798 gpu::gles2::GLES2Interface* destination_gl, |
791 const scoped_refptr<VideoFrame>& video_frame, | 799 const scoped_refptr<VideoFrame>& video_frame, |
792 unsigned int texture, | 800 unsigned int texture, |
793 unsigned int internal_format, | |
794 unsigned int type, | |
795 bool premultiply_alpha, | 801 bool premultiply_alpha, |
796 bool flip_y) { | 802 bool flip_y) { |
797 DCHECK(thread_checker_.CalledOnValidThread()); | 803 DCHECK(thread_checker_.CalledOnValidThread()); |
798 DCHECK(video_frame); | 804 DCHECK(video_frame); |
799 DCHECK(video_frame->HasTextures()); | 805 DCHECK(video_frame->HasTextures()); |
800 if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) { | 806 if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) { |
801 if (!context_3d.gr_context) | 807 if (!context_3d.gr_context) |
802 return false; | 808 return false; |
803 if (!UpdateLastImage(video_frame, context_3d)) | 809 if (!UpdateLastImage(video_frame, context_3d)) |
804 return false; | 810 return false; |
(...skipping 16 matching lines...) Expand all Loading... |
821 canvas_gl->ShallowFlushCHROMIUM(); | 827 canvas_gl->ShallowFlushCHROMIUM(); |
822 canvas_gl->GenSyncTokenCHROMIUM(fence_sync, | 828 canvas_gl->GenSyncTokenCHROMIUM(fence_sync, |
823 mailbox_holder.sync_token.GetData()); | 829 mailbox_holder.sync_token.GetData()); |
824 | 830 |
825 destination_gl->WaitSyncTokenCHROMIUM( | 831 destination_gl->WaitSyncTokenCHROMIUM( |
826 mailbox_holder.sync_token.GetConstData()); | 832 mailbox_holder.sync_token.GetConstData()); |
827 uint32_t intermediate_texture = | 833 uint32_t intermediate_texture = |
828 destination_gl->CreateAndConsumeTextureCHROMIUM( | 834 destination_gl->CreateAndConsumeTextureCHROMIUM( |
829 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 835 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
830 | 836 |
831 destination_gl->CopyTextureCHROMIUM(intermediate_texture, 0, texture, 0, | 837 // The video's texture might be larger than the natural size because |
832 internal_format, type, flip_y, | 838 // the encoder might have had to round up to the size of a macroblock. |
833 premultiply_alpha, false); | 839 // Make sure to only copy the natural size to avoid putting garbage |
| 840 // into the bottom of the destination texture. |
| 841 const gfx::Size& natural_size = video_frame->natural_size(); |
| 842 destination_gl->CopySubTextureCHROMIUM( |
| 843 intermediate_texture, 0, texture, 0, 0, 0, 0, 0, natural_size.width(), |
| 844 natural_size.height(), flip_y, premultiply_alpha, false); |
834 destination_gl->DeleteTextures(1, &intermediate_texture); | 845 destination_gl->DeleteTextures(1, &intermediate_texture); |
835 | 846 |
836 // Wait for destination context to consume mailbox before deleting it in | 847 // Wait for destination context to consume mailbox before deleting it in |
837 // canvas context. | 848 // canvas context. |
838 const GLuint64 dest_fence_sync = destination_gl->InsertFenceSyncCHROMIUM(); | 849 const GLuint64 dest_fence_sync = destination_gl->InsertFenceSyncCHROMIUM(); |
839 destination_gl->ShallowFlushCHROMIUM(); | 850 destination_gl->ShallowFlushCHROMIUM(); |
840 gpu::SyncToken dest_sync_token; | 851 gpu::SyncToken dest_sync_token; |
841 destination_gl->GenSyncTokenCHROMIUM(dest_fence_sync, | 852 destination_gl->GenSyncTokenCHROMIUM(dest_fence_sync, |
842 dest_sync_token.GetData()); | 853 dest_sync_token.GetData()); |
843 canvas_gl->WaitSyncTokenCHROMIUM(dest_sync_token.GetConstData()); | 854 canvas_gl->WaitSyncTokenCHROMIUM(dest_sync_token.GetConstData()); |
844 | 855 |
845 SyncTokenClientImpl client(canvas_gl); | 856 SyncTokenClientImpl client(canvas_gl); |
846 video_frame->UpdateReleaseSyncToken(&client); | 857 video_frame->UpdateReleaseSyncToken(&client); |
847 } else { | 858 } else { |
848 CopyVideoFrameSingleTextureToGLTexture(destination_gl, video_frame.get(), | 859 CopyVideoFrameSingleTextureToGLTexture(destination_gl, video_frame.get(), |
849 texture, internal_format, type, | 860 texture, premultiply_alpha, flip_y); |
850 premultiply_alpha, flip_y); | |
851 } | 861 } |
852 | 862 |
853 return true; | 863 return true; |
854 } | 864 } |
855 | 865 |
856 bool SkCanvasVideoRenderer::TexImage2D(unsigned target, | 866 bool SkCanvasVideoRenderer::TexImage2D(unsigned target, |
857 gpu::gles2::GLES2Interface* gl, | 867 gpu::gles2::GLES2Interface* gl, |
858 VideoFrame* frame, | 868 VideoFrame* frame, |
859 int level, | 869 int level, |
860 int internalformat, | 870 int internalformat, |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 last_image_->bounds().contains(visible_rect)) { | 958 last_image_->bounds().contains(visible_rect)) { |
949 last_image_ = last_image_->makeSubset(visible_rect); | 959 last_image_ = last_image_->makeSubset(visible_rect); |
950 } | 960 } |
951 } | 961 } |
952 | 962 |
953 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { | 963 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { |
954 return last_image_dimensions_for_testing_; | 964 return last_image_dimensions_for_testing_; |
955 } | 965 } |
956 | 966 |
957 } // namespace media | 967 } // namespace media |
OLD | NEW |