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