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