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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { | 197 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { |
198 // TODO(dcastagna): At the moment Skia doesn't support targets different | 198 // TODO(dcastagna): At the moment Skia doesn't support targets different |
199 // than GL_TEXTURE_2D. Avoid this copy once | 199 // than GL_TEXTURE_2D. Avoid this copy once |
200 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed. | 200 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed. |
201 gl->GenTextures(1, &source_texture); | 201 gl->GenTextures(1, &source_texture); |
202 DCHECK(source_texture); | 202 DCHECK(source_texture); |
203 gl->BindTexture(GL_TEXTURE_2D, source_texture); | 203 gl->BindTexture(GL_TEXTURE_2D, source_texture); |
204 SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( | 204 SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
205 gl, video_frame, | 205 gl, video_frame, |
206 SkCanvasVideoRenderer::SingleFrameForVideoElementOrCanvas, | 206 SkCanvasVideoRenderer::SingleFrameForVideoElementOrCanvas, |
207 source_texture, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, true, false); | 207 GL_TEXTURE_2D, source_texture, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 0, |
| 208 true, false); |
208 context_3d.gr_context->resetContext(kTextureBinding_GrGLBackendState); | 209 context_3d.gr_context->resetContext(kTextureBinding_GrGLBackendState); |
209 } else { | 210 } else { |
210 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); | 211 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); |
211 source_texture = gl->CreateAndConsumeTextureCHROMIUM( | 212 source_texture = gl->CreateAndConsumeTextureCHROMIUM( |
212 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 213 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
213 } | 214 } |
214 GrBackendTextureDesc desc; | 215 GrBackendTextureDesc desc; |
215 desc.fFlags = kNone_GrBackendTextureFlag; | 216 desc.fFlags = kNone_GrBackendTextureFlag; |
216 desc.fOrigin = kTopLeft_GrSurfaceOrigin; | 217 desc.fOrigin = kTopLeft_GrSurfaceOrigin; |
217 desc.fWidth = video_frame->coded_size().width(); | 218 desc.fWidth = video_frame->coded_size().width(); |
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 case PIXEL_FORMAT_UNKNOWN: | 799 case PIXEL_FORMAT_UNKNOWN: |
799 NOTREACHED() << "Only YUV formats and Y16 are supported."; | 800 NOTREACHED() << "Only YUV formats and Y16 are supported."; |
800 } | 801 } |
801 } | 802 } |
802 | 803 |
803 // static | 804 // static |
804 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( | 805 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( |
805 gpu::gles2::GLES2Interface* gl, | 806 gpu::gles2::GLES2Interface* gl, |
806 VideoFrame* video_frame, | 807 VideoFrame* video_frame, |
807 SingleFrameCopyMode copy_mode, | 808 SingleFrameCopyMode copy_mode, |
| 809 unsigned int target, |
808 unsigned int texture, | 810 unsigned int texture, |
809 unsigned int internal_format, | 811 unsigned int internal_format, |
810 unsigned int format, | 812 unsigned int format, |
811 unsigned int type, | 813 unsigned int type, |
| 814 int level, |
812 bool premultiply_alpha, | 815 bool premultiply_alpha, |
813 bool flip_y) { | 816 bool flip_y) { |
814 DCHECK(video_frame); | 817 DCHECK(video_frame); |
815 DCHECK(video_frame->HasTextures()); | 818 DCHECK(video_frame->HasTextures()); |
816 | 819 |
817 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); | 820 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); |
818 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || | 821 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || |
819 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || | 822 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || |
820 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) | 823 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) |
821 << mailbox_holder.texture_target; | 824 << mailbox_holder.texture_target; |
822 | 825 |
823 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); | 826 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); |
824 uint32_t source_texture = gl->CreateAndConsumeTextureCHROMIUM( | 827 uint32_t source_texture = gl->CreateAndConsumeTextureCHROMIUM( |
825 mailbox_holder.texture_target, mailbox_holder.mailbox.name); | 828 mailbox_holder.texture_target, mailbox_holder.mailbox.name); |
826 | 829 |
827 // The video is stored in a unmultiplied format, so premultiply | 830 // The video is stored in a unmultiplied format, so premultiply |
828 // if necessary. | 831 // if necessary. |
829 // Application itself needs to take care of setting the right |flip_y| | 832 // Application itself needs to take care of setting the right |flip_y| |
830 // value down to get the expected result. | 833 // value down to get the expected result. |
831 // "flip_y == true" means to reverse the video orientation while | 834 // "flip_y == true" means to reverse the video orientation while |
832 // "flip_y == false" means to keep the intrinsic orientation. | 835 // "flip_y == false" means to keep the intrinsic orientation. |
833 | 836 |
834 if (copy_mode == SingleFrameForVideoElementOrCanvas || | 837 if (copy_mode == SingleFrameForVideoElementOrCanvas || |
835 !VideoTextureNeedsClipping(video_frame)) { | 838 !VideoTextureNeedsClipping(video_frame)) { |
836 // No need to clip the source video texture. | 839 // No need to clip the source video texture. |
837 gl->CopyTextureCHROMIUM(source_texture, 0, GL_TEXTURE_2D, texture, 0, | 840 gl->CopyTextureCHROMIUM(source_texture, 0, target, texture, level, |
838 internal_format, type, flip_y, premultiply_alpha, | 841 internal_format, type, flip_y, premultiply_alpha, |
839 false); | 842 false); |
840 } else { | 843 } else { |
841 // Must reallocate the destination texture and copy only a sub-portion. | 844 // Must reallocate the destination texture and copy only a sub-portion. |
842 gfx::Rect dest_rect = video_frame->visible_rect(); | 845 gfx::Rect dest_rect = video_frame->visible_rect(); |
843 #if DCHECK_IS_ON() | 846 #if DCHECK_IS_ON() |
844 // The caller should have bound _texture_ to the GL_TEXTURE_2D | 847 // The caller should have bound _texture_ to the GL_TEXTURE_2D |
845 // binding point already. | 848 // binding point already. |
846 GLuint current_texture = 0; | 849 GLuint current_texture = 0; |
847 gl->GetIntegerv(GL_TEXTURE_BINDING_2D, | 850 gl->GetIntegerv(GL_TEXTURE_BINDING_2D, |
848 reinterpret_cast<GLint*>(¤t_texture)); | 851 reinterpret_cast<GLint*>(¤t_texture)); |
849 DCHECK_EQ(current_texture, texture); | 852 DCHECK_EQ(current_texture, texture); |
850 // There should always be enough data in the source texture to | 853 // There should always be enough data in the source texture to |
851 // cover this copy. | 854 // cover this copy. |
852 DCHECK_LE(dest_rect.width(), video_frame->coded_size().width()); | 855 DCHECK_LE(dest_rect.width(), video_frame->coded_size().width()); |
853 DCHECK_LE(dest_rect.height(), video_frame->coded_size().height()); | 856 DCHECK_LE(dest_rect.height(), video_frame->coded_size().height()); |
854 #endif | 857 #endif |
855 gl->TexImage2D(GL_TEXTURE_2D, 0, internal_format, dest_rect.width(), | 858 gl->TexImage2D(target, level, internal_format, dest_rect.width(), |
856 dest_rect.height(), 0, format, type, nullptr); | 859 dest_rect.height(), 0, format, type, nullptr); |
857 gl->CopySubTextureCHROMIUM(source_texture, 0, GL_TEXTURE_2D, texture, 0, 0, | 860 gl->CopySubTextureCHROMIUM(source_texture, 0, target, texture, level, 0, 0, |
858 0, dest_rect.x(), dest_rect.y(), | 861 dest_rect.x(), dest_rect.y(), dest_rect.width(), |
859 dest_rect.width(), dest_rect.height(), flip_y, | 862 dest_rect.height(), flip_y, premultiply_alpha, |
860 premultiply_alpha, false); | 863 false); |
861 } | 864 } |
862 | 865 |
863 gl->DeleteTextures(1, &source_texture); | 866 gl->DeleteTextures(1, &source_texture); |
864 gl->Flush(); | 867 gl->Flush(); |
865 | 868 |
866 SyncTokenClientImpl client(gl); | 869 SyncTokenClientImpl client(gl); |
867 video_frame->UpdateReleaseSyncToken(&client); | 870 video_frame->UpdateReleaseSyncToken(&client); |
868 } | 871 } |
869 | 872 |
870 bool SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( | 873 bool SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( |
871 const Context3D& context_3d, | 874 const Context3D& context_3d, |
872 gpu::gles2::GLES2Interface* destination_gl, | 875 gpu::gles2::GLES2Interface* destination_gl, |
873 const scoped_refptr<VideoFrame>& video_frame, | 876 const scoped_refptr<VideoFrame>& video_frame, |
| 877 unsigned int target, |
874 unsigned int texture, | 878 unsigned int texture, |
875 unsigned int internal_format, | 879 unsigned int internal_format, |
876 unsigned int format, | 880 unsigned int format, |
877 unsigned int type, | 881 unsigned int type, |
| 882 int level, |
878 bool premultiply_alpha, | 883 bool premultiply_alpha, |
879 bool flip_y) { | 884 bool flip_y) { |
880 DCHECK(thread_checker_.CalledOnValidThread()); | 885 DCHECK(thread_checker_.CalledOnValidThread()); |
881 DCHECK(video_frame); | 886 DCHECK(video_frame); |
882 DCHECK(video_frame->HasTextures()); | 887 DCHECK(video_frame->HasTextures()); |
883 if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) { | 888 if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) { |
884 if (!context_3d.gr_context) | 889 if (!context_3d.gr_context) |
885 return false; | 890 return false; |
886 if (!UpdateLastImage(video_frame, context_3d)) | 891 if (!UpdateLastImage(video_frame, context_3d)) |
887 return false; | 892 return false; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 // binding point already. | 925 // binding point already. |
921 GLuint current_texture = 0; | 926 GLuint current_texture = 0; |
922 destination_gl->GetIntegerv(GL_TEXTURE_BINDING_2D, | 927 destination_gl->GetIntegerv(GL_TEXTURE_BINDING_2D, |
923 reinterpret_cast<GLint*>(¤t_texture)); | 928 reinterpret_cast<GLint*>(¤t_texture)); |
924 DCHECK_EQ(current_texture, texture); | 929 DCHECK_EQ(current_texture, texture); |
925 // There should always be enough data in the source texture to | 930 // There should always be enough data in the source texture to |
926 // cover this copy. | 931 // cover this copy. |
927 DCHECK_LE(dest_rect.width(), video_frame->coded_size().width()); | 932 DCHECK_LE(dest_rect.width(), video_frame->coded_size().width()); |
928 DCHECK_LE(dest_rect.height(), video_frame->coded_size().height()); | 933 DCHECK_LE(dest_rect.height(), video_frame->coded_size().height()); |
929 #endif | 934 #endif |
930 destination_gl->TexImage2D(GL_TEXTURE_2D, 0, internal_format, | 935 destination_gl->TexImage2D(target, level, internal_format, |
931 dest_rect.width(), dest_rect.height(), 0, | 936 dest_rect.width(), dest_rect.height(), 0, |
932 format, type, nullptr); | 937 format, type, nullptr); |
933 destination_gl->CopySubTextureCHROMIUM( | 938 destination_gl->CopySubTextureCHROMIUM( |
934 intermediate_texture, 0, GL_TEXTURE_2D, texture, 0, 0, 0, | 939 intermediate_texture, 0, target, texture, level, 0, 0, dest_rect.x(), |
935 dest_rect.x(), dest_rect.y(), dest_rect.width(), dest_rect.height(), | 940 dest_rect.y(), dest_rect.width(), dest_rect.height(), flip_y, |
936 flip_y, premultiply_alpha, false); | 941 premultiply_alpha, false); |
937 } else { | 942 } else { |
938 destination_gl->CopyTextureCHROMIUM( | 943 destination_gl->CopyTextureCHROMIUM(intermediate_texture, 0, target, |
939 intermediate_texture, 0, GL_TEXTURE_2D, texture, 0, internal_format, | 944 texture, level, internal_format, type, |
940 type, flip_y, premultiply_alpha, false); | 945 flip_y, premultiply_alpha, false); |
941 } | 946 } |
942 | 947 |
943 destination_gl->DeleteTextures(1, &intermediate_texture); | 948 destination_gl->DeleteTextures(1, &intermediate_texture); |
944 | 949 |
945 // Wait for destination context to consume mailbox before deleting it in | 950 // Wait for destination context to consume mailbox before deleting it in |
946 // canvas context. | 951 // canvas context. |
947 const GLuint64 dest_fence_sync = destination_gl->InsertFenceSyncCHROMIUM(); | 952 const GLuint64 dest_fence_sync = destination_gl->InsertFenceSyncCHROMIUM(); |
948 destination_gl->ShallowFlushCHROMIUM(); | 953 destination_gl->ShallowFlushCHROMIUM(); |
949 gpu::SyncToken dest_sync_token; | 954 gpu::SyncToken dest_sync_token; |
950 destination_gl->GenSyncTokenCHROMIUM(dest_fence_sync, | 955 destination_gl->GenSyncTokenCHROMIUM(dest_fence_sync, |
951 dest_sync_token.GetData()); | 956 dest_sync_token.GetData()); |
952 canvas_gl->WaitSyncTokenCHROMIUM(dest_sync_token.GetConstData()); | 957 canvas_gl->WaitSyncTokenCHROMIUM(dest_sync_token.GetConstData()); |
953 | 958 |
954 SyncTokenClientImpl client(canvas_gl); | 959 SyncTokenClientImpl client(canvas_gl); |
955 video_frame->UpdateReleaseSyncToken(&client); | 960 video_frame->UpdateReleaseSyncToken(&client); |
956 } else { | 961 } else { |
957 CopyVideoFrameSingleTextureToGLTexture( | 962 CopyVideoFrameSingleTextureToGLTexture( |
958 destination_gl, video_frame.get(), SingleFrameForWebGL, texture, | 963 destination_gl, video_frame.get(), SingleFrameForWebGL, target, texture, |
959 internal_format, format, type, premultiply_alpha, flip_y); | 964 internal_format, format, type, level, premultiply_alpha, flip_y); |
960 } | 965 } |
961 | 966 |
962 return true; | 967 return true; |
963 } | 968 } |
964 | 969 |
965 bool SkCanvasVideoRenderer::TexImage2D( | 970 bool SkCanvasVideoRenderer::TexImage2D( |
966 unsigned target, | 971 unsigned target, |
967 unsigned texture, | 972 unsigned texture, |
968 gpu::gles2::GLES2Interface* gl, | 973 gpu::gles2::GLES2Interface* gl, |
969 const gpu::Capabilities& gpu_capabilities, | 974 const gpu::Capabilities& gpu_capabilities, |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 last_image_->bounds().contains(visible_rect)) { | 1089 last_image_->bounds().contains(visible_rect)) { |
1085 last_image_ = last_image_->makeSubset(visible_rect); | 1090 last_image_ = last_image_->makeSubset(visible_rect); |
1086 } | 1091 } |
1087 } | 1092 } |
1088 | 1093 |
1089 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { | 1094 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { |
1090 return last_image_dimensions_for_testing_; | 1095 return last_image_dimensions_for_testing_; |
1091 } | 1096 } |
1092 | 1097 |
1093 } // namespace media | 1098 } // namespace media |
OLD | NEW |