| 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 |