Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: media/renderers/skcanvas_video_renderer.cc

Issue 2818493002: Revert of Fix broken draw/upload paths from videos to 2D canvas and WebGL. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 handles, yuvSizes, 153 handles, yuvSizes,
154 kTopLeft_GrSurfaceOrigin); 154 kTopLeft_GrSurfaceOrigin);
155 } 155 }
156 for (size_t i = 0; i < media::VideoFrame::NumPlanes(video_frame->format()); 156 for (size_t i = 0; i < media::VideoFrame::NumPlanes(video_frame->format());
157 ++i) { 157 ++i) {
158 gl->DeleteTextures(1, &source_textures[i].fID); 158 gl->DeleteTextures(1, &source_textures[i].fID);
159 } 159 }
160 return img; 160 return img;
161 } 161 }
162 162
163 bool VideoTextureNeedsClipping(const VideoFrame* video_frame) {
164 // There are multiple reasons that the size of the video frame's
165 // visible rectangle may differ from the coded size, including the
166 // encoder rounding up to the size of a macroblock, or use of
167 // non-square pixels.
168 //
169 // Some callers of these APIs (HTMLVideoElement and the 2D canvas
170 // context) already clip to the video frame's visible rectangle.
171 // WebGL on the other hand assumes that only the valid pixels are
172 // contained in the destination texture. This helper function
173 // determines whether this slower path is needed.
174 return video_frame->visible_rect().size() != video_frame->coded_size();
175 }
176
177 // Creates a SkImage from a |video_frame| backed by native resources. 163 // Creates a SkImage from a |video_frame| backed by native resources.
178 // The SkImage will take ownership of the underlying resource. 164 // The SkImage will take ownership of the underlying resource.
179 sk_sp<SkImage> NewSkImageFromVideoFrameNative(VideoFrame* video_frame, 165 sk_sp<SkImage> NewSkImageFromVideoFrameNative(VideoFrame* video_frame,
180 const Context3D& context_3d) { 166 const Context3D& context_3d) {
181 DCHECK(PIXEL_FORMAT_ARGB == video_frame->format() || 167 DCHECK(PIXEL_FORMAT_ARGB == video_frame->format() ||
182 PIXEL_FORMAT_XRGB == video_frame->format() || 168 PIXEL_FORMAT_XRGB == video_frame->format() ||
183 PIXEL_FORMAT_NV12 == video_frame->format() || 169 PIXEL_FORMAT_NV12 == video_frame->format() ||
184 PIXEL_FORMAT_UYVY == video_frame->format()); 170 PIXEL_FORMAT_UYVY == video_frame->format());
185 171
186 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); 172 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0);
187 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || 173 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D ||
188 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || 174 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB ||
189 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) 175 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES)
190 << mailbox_holder.texture_target; 176 << mailbox_holder.texture_target;
191 177
192 gpu::gles2::GLES2Interface* gl = context_3d.gl; 178 gpu::gles2::GLES2Interface* gl = context_3d.gl;
193 unsigned source_texture = 0; 179 unsigned source_texture = 0;
194 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { 180 if (mailbox_holder.texture_target != GL_TEXTURE_2D) {
195 // TODO(dcastagna): At the moment Skia doesn't support targets different 181 // TODO(dcastagna): At the moment Skia doesn't support targets different
196 // than GL_TEXTURE_2D. Avoid this copy once 182 // than GL_TEXTURE_2D. Avoid this copy once
197 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed. 183 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed.
198 gl->GenTextures(1, &source_texture); 184 gl->GenTextures(1, &source_texture);
199 DCHECK(source_texture); 185 DCHECK(source_texture);
200 gl->BindTexture(GL_TEXTURE_2D, source_texture); 186 gl->BindTexture(GL_TEXTURE_2D, source_texture);
187 const gfx::Size& natural_size = video_frame->natural_size();
188 gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, natural_size.width(),
189 natural_size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
190 nullptr);
201 SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( 191 SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture(
202 gl, video_frame, 192 gl, video_frame, source_texture, true, false);
203 SkCanvasVideoRenderer::SingleFrameForVideoElementOrCanvas,
204 source_texture, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, true, false);
205 } else { 193 } else {
206 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); 194 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData());
207 source_texture = gl->CreateAndConsumeTextureCHROMIUM( 195 source_texture = gl->CreateAndConsumeTextureCHROMIUM(
208 mailbox_holder.texture_target, mailbox_holder.mailbox.name); 196 mailbox_holder.texture_target, mailbox_holder.mailbox.name);
209 } 197 }
210 GrBackendTextureDesc desc; 198 GrBackendTextureDesc desc;
211 desc.fFlags = kRenderTarget_GrBackendTextureFlag; 199 desc.fFlags = kRenderTarget_GrBackendTextureFlag;
212 desc.fOrigin = kTopLeft_GrSurfaceOrigin; 200 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
213 desc.fWidth = video_frame->coded_size().width(); 201 desc.fWidth = video_frame->coded_size().width();
214 desc.fHeight = video_frame->coded_size().height(); 202 desc.fHeight = video_frame->coded_size().height();
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 case PIXEL_FORMAT_Y8: 746 case PIXEL_FORMAT_Y8:
759 case PIXEL_FORMAT_UNKNOWN: 747 case PIXEL_FORMAT_UNKNOWN:
760 NOTREACHED() << "Only YUV formats and Y16 are supported."; 748 NOTREACHED() << "Only YUV formats and Y16 are supported.";
761 } 749 }
762 } 750 }
763 751
764 // static 752 // static
765 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( 753 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture(
766 gpu::gles2::GLES2Interface* gl, 754 gpu::gles2::GLES2Interface* gl,
767 VideoFrame* video_frame, 755 VideoFrame* video_frame,
768 SingleFrameCopyMode copy_mode,
769 unsigned int texture, 756 unsigned int texture,
770 unsigned int internal_format,
771 unsigned int format,
772 unsigned int type,
773 bool premultiply_alpha, 757 bool premultiply_alpha,
774 bool flip_y) { 758 bool flip_y) {
775 DCHECK(video_frame); 759 DCHECK(video_frame);
776 DCHECK(video_frame->HasTextures()); 760 DCHECK(video_frame->HasTextures());
777 761
778 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); 762 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0);
779 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || 763 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D ||
780 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || 764 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB ||
781 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) 765 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES)
782 << mailbox_holder.texture_target; 766 << mailbox_holder.texture_target;
783 767
784 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); 768 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData());
785 uint32_t source_texture = gl->CreateAndConsumeTextureCHROMIUM( 769 uint32_t source_texture = gl->CreateAndConsumeTextureCHROMIUM(
786 mailbox_holder.texture_target, mailbox_holder.mailbox.name); 770 mailbox_holder.texture_target, mailbox_holder.mailbox.name);
787 771
788 // The video is stored in a unmultiplied format, so premultiply 772 // The video is stored in a unmultiplied format, so premultiply
789 // if necessary. 773 // if necessary.
790 // Application itself needs to take care of setting the right |flip_y| 774 // Application itself needs to take care of setting the right |flip_y|
791 // value down to get the expected result. 775 // value down to get the expected result.
792 // "flip_y == true" means to reverse the video orientation while 776 // "flip_y == true" means to reverse the video orientation while
793 // "flip_y == false" means to keep the intrinsic orientation. 777 // "flip_y == false" means to keep the intrinsic orientation.
794 778
795 if (copy_mode == SingleFrameForVideoElementOrCanvas || 779 // The video's texture might be larger than the natural size because
796 !VideoTextureNeedsClipping(video_frame)) { 780 // the encoder might have had to round up to the size of a macroblock.
797 // No need to clip the source video texture. 781 // Make sure to only copy the natural size to avoid putting garbage
798 gl->CopyTextureCHROMIUM(source_texture, 0, GL_TEXTURE_2D, texture, 0, 782 // into the bottom of the destination texture.
799 internal_format, type, flip_y, premultiply_alpha, 783 const gfx::Size& natural_size = video_frame->natural_size();
800 false); 784 gl->CopySubTextureCHROMIUM(source_texture, 0, GL_TEXTURE_2D, texture, 0, 0, 0,
801 } else { 785 0, 0, natural_size.width(), natural_size.height(),
802 // Must reallocate the destination texture and copy only a sub-portion. 786 flip_y, premultiply_alpha, false);
803 gfx::Rect dest_rect = video_frame->visible_rect();
804 #if DCHECK_IS_ON()
805 // The caller should have bound _texture_ to the GL_TEXTURE_2D
806 // binding point already.
807 GLuint current_texture = 0;
808 gl->GetIntegerv(GL_TEXTURE_BINDING_2D,
809 reinterpret_cast<GLint*>(&current_texture));
810 DCHECK_EQ(current_texture, texture);
811 // There should always be enough data in the source texture to
812 // cover this copy.
813 DCHECK_LE(dest_rect.width(), video_frame->coded_size().width());
814 DCHECK_LE(dest_rect.height(), video_frame->coded_size().height());
815 #endif
816 gl->TexImage2D(GL_TEXTURE_2D, 0, internal_format, dest_rect.width(),
817 dest_rect.height(), 0, format, type, nullptr);
818 gl->CopySubTextureCHROMIUM(source_texture, 0, GL_TEXTURE_2D, texture, 0, 0,
819 0, dest_rect.x(), dest_rect.y(),
820 dest_rect.width(), dest_rect.height(), flip_y,
821 premultiply_alpha, false);
822 }
823
824 gl->DeleteTextures(1, &source_texture); 787 gl->DeleteTextures(1, &source_texture);
825 gl->Flush(); 788 gl->Flush();
826 789
827 SyncTokenClientImpl client(gl); 790 SyncTokenClientImpl client(gl);
828 video_frame->UpdateReleaseSyncToken(&client); 791 video_frame->UpdateReleaseSyncToken(&client);
829 } 792 }
830 793
831 bool SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( 794 bool SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture(
832 const Context3D& context_3d, 795 const Context3D& context_3d,
833 gpu::gles2::GLES2Interface* destination_gl, 796 gpu::gles2::GLES2Interface* destination_gl,
834 const scoped_refptr<VideoFrame>& video_frame, 797 const scoped_refptr<VideoFrame>& video_frame,
835 unsigned int texture, 798 unsigned int texture,
836 unsigned int internal_format,
837 unsigned int format,
838 unsigned int type,
839 bool premultiply_alpha, 799 bool premultiply_alpha,
840 bool flip_y) { 800 bool flip_y) {
841 DCHECK(thread_checker_.CalledOnValidThread()); 801 DCHECK(thread_checker_.CalledOnValidThread());
842 DCHECK(video_frame); 802 DCHECK(video_frame);
843 DCHECK(video_frame->HasTextures()); 803 DCHECK(video_frame->HasTextures());
844 if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) { 804 if (media::VideoFrame::NumPlanes(video_frame->format()) > 1) {
845 if (!context_3d.gr_context) 805 if (!context_3d.gr_context)
846 return false; 806 return false;
847 if (!UpdateLastImage(video_frame, context_3d)) 807 if (!UpdateLastImage(video_frame, context_3d))
848 return false; 808 return false;
(...skipping 16 matching lines...) Expand all
865 canvas_gl->ShallowFlushCHROMIUM(); 825 canvas_gl->ShallowFlushCHROMIUM();
866 canvas_gl->GenSyncTokenCHROMIUM(fence_sync, 826 canvas_gl->GenSyncTokenCHROMIUM(fence_sync,
867 mailbox_holder.sync_token.GetData()); 827 mailbox_holder.sync_token.GetData());
868 828
869 destination_gl->WaitSyncTokenCHROMIUM( 829 destination_gl->WaitSyncTokenCHROMIUM(
870 mailbox_holder.sync_token.GetConstData()); 830 mailbox_holder.sync_token.GetConstData());
871 uint32_t intermediate_texture = 831 uint32_t intermediate_texture =
872 destination_gl->CreateAndConsumeTextureCHROMIUM( 832 destination_gl->CreateAndConsumeTextureCHROMIUM(
873 mailbox_holder.texture_target, mailbox_holder.mailbox.name); 833 mailbox_holder.texture_target, mailbox_holder.mailbox.name);
874 834
875 // See whether the source video texture must be clipped. 835 // The video's texture might be larger than the natural size because
876 if (VideoTextureNeedsClipping(video_frame.get())) { 836 // the encoder might have had to round up to the size of a macroblock.
877 // Reallocate destination texture and copy only valid region. 837 // Make sure to only copy the natural size to avoid putting garbage
878 gfx::Rect dest_rect = video_frame->visible_rect(); 838 // into the bottom of the destination texture.
879 #if DCHECK_IS_ON() 839 const gfx::Size& natural_size = video_frame->natural_size();
880 // The caller should have bound _texture_ to the GL_TEXTURE_2D 840 destination_gl->CopySubTextureCHROMIUM(
881 // binding point already. 841 intermediate_texture, 0, GL_TEXTURE_2D, texture, 0, 0, 0, 0, 0,
882 GLuint current_texture = 0; 842 natural_size.width(), natural_size.height(), flip_y, premultiply_alpha,
883 destination_gl->GetIntegerv(GL_TEXTURE_BINDING_2D, 843 false);
884 reinterpret_cast<GLint*>(&current_texture));
885 DCHECK_EQ(current_texture, texture);
886 // There should always be enough data in the source texture to
887 // cover this copy.
888 DCHECK_LE(dest_rect.width(), video_frame->coded_size().width());
889 DCHECK_LE(dest_rect.height(), video_frame->coded_size().height());
890 #endif
891 destination_gl->TexImage2D(GL_TEXTURE_2D, 0, internal_format,
892 dest_rect.width(), dest_rect.height(), 0,
893 format, type, nullptr);
894 destination_gl->CopySubTextureCHROMIUM(
895 intermediate_texture, 0, GL_TEXTURE_2D, texture, 0, 0, 0,
896 dest_rect.x(), dest_rect.y(), dest_rect.width(), dest_rect.height(),
897 flip_y, premultiply_alpha, false);
898 } else {
899 destination_gl->CopyTextureCHROMIUM(
900 intermediate_texture, 0, GL_TEXTURE_2D, texture, 0, internal_format,
901 type, flip_y, premultiply_alpha, false);
902 }
903
904 destination_gl->DeleteTextures(1, &intermediate_texture); 844 destination_gl->DeleteTextures(1, &intermediate_texture);
905 845
906 // Wait for destination context to consume mailbox before deleting it in 846 // Wait for destination context to consume mailbox before deleting it in
907 // canvas context. 847 // canvas context.
908 const GLuint64 dest_fence_sync = destination_gl->InsertFenceSyncCHROMIUM(); 848 const GLuint64 dest_fence_sync = destination_gl->InsertFenceSyncCHROMIUM();
909 destination_gl->ShallowFlushCHROMIUM(); 849 destination_gl->ShallowFlushCHROMIUM();
910 gpu::SyncToken dest_sync_token; 850 gpu::SyncToken dest_sync_token;
911 destination_gl->GenSyncTokenCHROMIUM(dest_fence_sync, 851 destination_gl->GenSyncTokenCHROMIUM(dest_fence_sync,
912 dest_sync_token.GetData()); 852 dest_sync_token.GetData());
913 canvas_gl->WaitSyncTokenCHROMIUM(dest_sync_token.GetConstData()); 853 canvas_gl->WaitSyncTokenCHROMIUM(dest_sync_token.GetConstData());
914 854
915 SyncTokenClientImpl client(canvas_gl); 855 SyncTokenClientImpl client(canvas_gl);
916 video_frame->UpdateReleaseSyncToken(&client); 856 video_frame->UpdateReleaseSyncToken(&client);
917 } else { 857 } else {
918 CopyVideoFrameSingleTextureToGLTexture( 858 CopyVideoFrameSingleTextureToGLTexture(destination_gl, video_frame.get(),
919 destination_gl, video_frame.get(), SingleFrameForWebGL, texture, 859 texture, premultiply_alpha, flip_y);
920 internal_format, format, type, premultiply_alpha, flip_y);
921 } 860 }
922 861
923 return true; 862 return true;
924 } 863 }
925 864
926 bool SkCanvasVideoRenderer::TexImage2D(unsigned target, 865 bool SkCanvasVideoRenderer::TexImage2D(unsigned target,
927 gpu::gles2::GLES2Interface* gl, 866 gpu::gles2::GLES2Interface* gl,
928 VideoFrame* frame, 867 VideoFrame* frame,
929 int level, 868 int level,
930 int internalformat, 869 int internalformat,
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 last_image_->bounds().contains(visible_rect)) { 957 last_image_->bounds().contains(visible_rect)) {
1019 last_image_ = last_image_->makeSubset(visible_rect); 958 last_image_ = last_image_->makeSubset(visible_rect);
1020 } 959 }
1021 } 960 }
1022 961
1023 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { 962 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() {
1024 return last_image_dimensions_for_testing_; 963 return last_image_dimensions_for_testing_;
1025 } 964 }
1026 965
1027 } // namespace media 966 } // namespace media
OLDNEW
« no previous file with comments | « media/renderers/skcanvas_video_renderer.h ('k') | third_party/WebKit/Source/core/html/HTMLVideoElement.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698