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

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

Issue 2896553003: Re-enable GPU-GPU copies of video textures to GL_RED (Closed)
Patch Set: rebased and clean up Created 3 years, 5 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 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 gl->TexParameteri(source_textures[i].fTarget, GL_TEXTURE_MIN_FILTER, 169 gl->TexParameteri(source_textures[i].fTarget, GL_TEXTURE_MIN_FILTER,
170 min_mag_filter[i][0]); 170 min_mag_filter[i][0]);
171 gl->TexParameteri(source_textures[i].fTarget, GL_TEXTURE_MAG_FILTER, 171 gl->TexParameteri(source_textures[i].fTarget, GL_TEXTURE_MAG_FILTER,
172 min_mag_filter[i][1]); 172 min_mag_filter[i][1]);
173 173
174 gl->DeleteTextures(1, &source_textures[i].fID); 174 gl->DeleteTextures(1, &source_textures[i].fID);
175 } 175 }
176 return img; 176 return img;
177 } 177 }
178 178
179 bool VideoTextureNeedsClipping(const VideoFrame* video_frame) {
180 // There are multiple reasons that the size of the video frame's
181 // visible rectangle may differ from the coded size, including the
182 // encoder rounding up to the size of a macroblock, or use of
183 // non-square pixels.
184 //
185 // Some callers of these APIs (HTMLVideoElement and the 2D canvas
186 // context) already clip to the video frame's visible rectangle.
187 // WebGL on the other hand assumes that only the valid pixels are
188 // contained in the destination texture. This helper function
189 // determines whether this slower path is needed.
190 return video_frame->visible_rect().size() != video_frame->coded_size();
191 }
192
193 // Creates a SkImage from a |video_frame| backed by native resources. 179 // Creates a SkImage from a |video_frame| backed by native resources.
194 // The SkImage will take ownership of the underlying resource. 180 // The SkImage will take ownership of the underlying resource.
195 sk_sp<SkImage> NewSkImageFromVideoFrameNative(VideoFrame* video_frame, 181 sk_sp<SkImage> NewSkImageFromVideoFrameNative(VideoFrame* video_frame,
196 const Context3D& context_3d) { 182 const Context3D& context_3d) {
197 DCHECK(PIXEL_FORMAT_ARGB == video_frame->format() || 183 DCHECK(PIXEL_FORMAT_ARGB == video_frame->format() ||
198 PIXEL_FORMAT_XRGB == video_frame->format() || 184 PIXEL_FORMAT_XRGB == video_frame->format() ||
199 PIXEL_FORMAT_NV12 == video_frame->format() || 185 PIXEL_FORMAT_NV12 == video_frame->format() ||
200 PIXEL_FORMAT_UYVY == video_frame->format()); 186 PIXEL_FORMAT_UYVY == video_frame->format());
201 187
202 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); 188 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0);
203 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || 189 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D ||
204 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || 190 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB ||
205 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) 191 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES)
206 << mailbox_holder.texture_target; 192 << mailbox_holder.texture_target;
207 193
208 gpu::gles2::GLES2Interface* gl = context_3d.gl; 194 gpu::gles2::GLES2Interface* gl = context_3d.gl;
209 unsigned source_texture = 0; 195 unsigned source_texture = 0;
210 if (mailbox_holder.texture_target != GL_TEXTURE_2D) { 196 if (mailbox_holder.texture_target != GL_TEXTURE_2D) {
211 // TODO(dcastagna): At the moment Skia doesn't support targets different 197 // TODO(dcastagna): At the moment Skia doesn't support targets different
212 // than GL_TEXTURE_2D. Avoid this copy once 198 // than GL_TEXTURE_2D. Avoid this copy once
213 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed. 199 // https://code.google.com/p/skia/issues/detail?id=3868 is addressed.
214 gl->GenTextures(1, &source_texture); 200 gl->GenTextures(1, &source_texture);
215 DCHECK(source_texture); 201 DCHECK(source_texture);
216 gl->BindTexture(GL_TEXTURE_2D, source_texture); 202 gl->BindTexture(GL_TEXTURE_2D, source_texture);
217 SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( 203 SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture(
218 gl, video_frame, 204 gl, video_frame,
219 SkCanvasVideoRenderer::SingleFrameForVideoElementOrCanvas,
220 GL_TEXTURE_2D, source_texture, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 0, 205 GL_TEXTURE_2D, source_texture, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 0,
221 true, false); 206 true, false);
222 context_3d.gr_context->resetContext(kTextureBinding_GrGLBackendState); 207 context_3d.gr_context->resetContext(kTextureBinding_GrGLBackendState);
223 } else { 208 } else {
224 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); 209 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData());
225 source_texture = gl->CreateAndConsumeTextureCHROMIUM( 210 source_texture = gl->CreateAndConsumeTextureCHROMIUM(
226 mailbox_holder.texture_target, mailbox_holder.mailbox.name); 211 mailbox_holder.texture_target, mailbox_holder.mailbox.name);
227 } 212 }
228 GrGLTextureInfo source_texture_info; 213 GrGLTextureInfo source_texture_info;
229 source_texture_info.fID = source_texture; 214 source_texture_info.fID = source_texture;
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
807 case PIXEL_FORMAT_Y8: 792 case PIXEL_FORMAT_Y8:
808 case PIXEL_FORMAT_UNKNOWN: 793 case PIXEL_FORMAT_UNKNOWN:
809 NOTREACHED() << "Only YUV formats and Y16 are supported."; 794 NOTREACHED() << "Only YUV formats and Y16 are supported.";
810 } 795 }
811 } 796 }
812 797
813 // static 798 // static
814 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture( 799 void SkCanvasVideoRenderer::CopyVideoFrameSingleTextureToGLTexture(
815 gpu::gles2::GLES2Interface* gl, 800 gpu::gles2::GLES2Interface* gl,
816 VideoFrame* video_frame, 801 VideoFrame* video_frame,
817 SingleFrameCopyMode copy_mode,
818 unsigned int target, 802 unsigned int target,
819 unsigned int texture, 803 unsigned int texture,
820 unsigned int internal_format, 804 unsigned int internal_format,
821 unsigned int format, 805 unsigned int format,
822 unsigned int type, 806 unsigned int type,
823 int level, 807 int level,
824 bool premultiply_alpha, 808 bool premultiply_alpha,
825 bool flip_y) { 809 bool flip_y) {
826 DCHECK(video_frame); 810 DCHECK(video_frame);
827 DCHECK(video_frame->HasTextures()); 811 DCHECK(video_frame->HasTextures());
828 812
829 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0); 813 const gpu::MailboxHolder& mailbox_holder = video_frame->mailbox_holder(0);
830 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D || 814 DCHECK(mailbox_holder.texture_target == GL_TEXTURE_2D ||
831 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB || 815 mailbox_holder.texture_target == GL_TEXTURE_RECTANGLE_ARB ||
832 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES) 816 mailbox_holder.texture_target == GL_TEXTURE_EXTERNAL_OES)
833 << mailbox_holder.texture_target; 817 << mailbox_holder.texture_target;
834 818
835 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); 819 gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData());
836 uint32_t source_texture = gl->CreateAndConsumeTextureCHROMIUM( 820 uint32_t source_texture = gl->CreateAndConsumeTextureCHROMIUM(
837 mailbox_holder.texture_target, mailbox_holder.mailbox.name); 821 mailbox_holder.texture_target, mailbox_holder.mailbox.name);
838 822
839 // The video is stored in a unmultiplied format, so premultiply 823 // The video is stored in a unmultiplied format, so premultiply
840 // if necessary. 824 // if necessary.
841 // Application itself needs to take care of setting the right |flip_y| 825 // Application itself needs to take care of setting the right |flip_y|
842 // value down to get the expected result. 826 // value down to get the expected result.
843 // "flip_y == true" means to reverse the video orientation while 827 // "flip_y == true" means to reverse the video orientation while
844 // "flip_y == false" means to keep the intrinsic orientation. 828 // "flip_y == false" means to keep the intrinsic orientation.
845 829
846 if (copy_mode == SingleFrameForVideoElementOrCanvas || 830 // Must reallocate the destination texture and copy only a sub-portion.
847 !VideoTextureNeedsClipping(video_frame)) { 831 gfx::Rect dest_rect = video_frame->visible_rect();
848 // No need to clip the source video texture.
849 gl->CopyTextureCHROMIUM(source_texture, 0, target, texture, level,
850 internal_format, type, flip_y, premultiply_alpha,
851 false);
852 } else {
853 // Must reallocate the destination texture and copy only a sub-portion.
854 gfx::Rect dest_rect = video_frame->visible_rect();
855 #if DCHECK_IS_ON() 832 #if DCHECK_IS_ON()
856 // The caller should have bound _texture_ to the GL_TEXTURE_2D 833 // There should always be enough data in the source texture to
857 // binding point already. 834 // cover this copy.
858 GLuint current_texture = 0; 835 DCHECK_LE(dest_rect.width(), video_frame->coded_size().width());
859 gl->GetIntegerv(GL_TEXTURE_BINDING_2D, 836 DCHECK_LE(dest_rect.height(), video_frame->coded_size().height());
860 reinterpret_cast<GLint*>(&current_texture));
861 DCHECK_EQ(current_texture, texture);
862 // There should always be enough data in the source texture to
863 // cover this copy.
864 DCHECK_LE(dest_rect.width(), video_frame->coded_size().width());
865 DCHECK_LE(dest_rect.height(), video_frame->coded_size().height());
866 #endif 837 #endif
867 gl->TexImage2D(target, level, internal_format, dest_rect.width(), 838 gl->TexImage2D(target, level, internal_format, dest_rect.width(),
868 dest_rect.height(), 0, format, type, nullptr); 839 dest_rect.height(), 0, format, type, nullptr);
869 gl->CopySubTextureCHROMIUM(source_texture, 0, target, texture, level, 0, 0, 840 gl->CopySubTextureCHROMIUM(source_texture, 0, target, texture, level, 0, 0,
870 dest_rect.x(), dest_rect.y(), dest_rect.width(), 841 dest_rect.x(), dest_rect.y(), dest_rect.width(),
871 dest_rect.height(), flip_y, premultiply_alpha, 842 dest_rect.height(), flip_y, premultiply_alpha,
872 false); 843 false);
873 }
874 844
875 gl->DeleteTextures(1, &source_texture); 845 gl->DeleteTextures(1, &source_texture);
876 gl->Flush(); 846 gl->Flush();
877 847
878 SyncTokenClientImpl client(gl); 848 SyncTokenClientImpl client(gl);
879 video_frame->UpdateReleaseSyncToken(&client); 849 video_frame->UpdateReleaseSyncToken(&client);
880 } 850 }
881 851
882 bool SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture( 852 bool SkCanvasVideoRenderer::CopyVideoFrameTexturesToGLTexture(
883 const Context3D& context_3d, 853 const Context3D& context_3d,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 canvas_gl->ShallowFlushCHROMIUM(); 888 canvas_gl->ShallowFlushCHROMIUM();
919 canvas_gl->GenSyncTokenCHROMIUM(fence_sync, 889 canvas_gl->GenSyncTokenCHROMIUM(fence_sync,
920 mailbox_holder.sync_token.GetData()); 890 mailbox_holder.sync_token.GetData());
921 891
922 destination_gl->WaitSyncTokenCHROMIUM( 892 destination_gl->WaitSyncTokenCHROMIUM(
923 mailbox_holder.sync_token.GetConstData()); 893 mailbox_holder.sync_token.GetConstData());
924 uint32_t intermediate_texture = 894 uint32_t intermediate_texture =
925 destination_gl->CreateAndConsumeTextureCHROMIUM( 895 destination_gl->CreateAndConsumeTextureCHROMIUM(
926 mailbox_holder.texture_target, mailbox_holder.mailbox.name); 896 mailbox_holder.texture_target, mailbox_holder.mailbox.name);
927 897
928 // See whether the source video texture must be clipped. 898 // Reallocate destination texture and copy only valid region.
929 if (VideoTextureNeedsClipping(video_frame.get())) { 899 gfx::Rect dest_rect = video_frame->visible_rect();
930 // Reallocate destination texture and copy only valid region.
931 gfx::Rect dest_rect = video_frame->visible_rect();
932 #if DCHECK_IS_ON() 900 #if DCHECK_IS_ON()
933 // The caller should have bound _texture_ to the GL_TEXTURE_2D 901 // There should always be enough data in the source texture to
934 // binding point already. 902 // cover this copy.
935 GLuint current_texture = 0; 903 DCHECK_LE(dest_rect.width(), video_frame->coded_size().width());
936 destination_gl->GetIntegerv(GL_TEXTURE_BINDING_2D, 904 DCHECK_LE(dest_rect.height(), video_frame->coded_size().height());
937 reinterpret_cast<GLint*>(&current_texture));
938 DCHECK_EQ(current_texture, texture);
939 // There should always be enough data in the source texture to
940 // cover this copy.
941 DCHECK_LE(dest_rect.width(), video_frame->coded_size().width());
942 DCHECK_LE(dest_rect.height(), video_frame->coded_size().height());
943 #endif 905 #endif
944 destination_gl->TexImage2D(target, level, internal_format, 906 destination_gl->TexImage2D(target, level, internal_format,
945 dest_rect.width(), dest_rect.height(), 0, 907 dest_rect.width(), dest_rect.height(), 0, format,
946 format, type, nullptr); 908 type, nullptr);
947 destination_gl->CopySubTextureCHROMIUM( 909 destination_gl->CopySubTextureCHROMIUM(
948 intermediate_texture, 0, target, texture, level, 0, 0, dest_rect.x(), 910 intermediate_texture, 0, target, texture, level, 0, 0, dest_rect.x(),
949 dest_rect.y(), dest_rect.width(), dest_rect.height(), flip_y, 911 dest_rect.y(), dest_rect.width(), dest_rect.height(), flip_y,
950 premultiply_alpha, false); 912 premultiply_alpha, false);
951 } else {
952 destination_gl->CopyTextureCHROMIUM(intermediate_texture, 0, target,
953 texture, level, internal_format, type,
954 flip_y, premultiply_alpha, false);
955 }
956 913
957 destination_gl->DeleteTextures(1, &intermediate_texture); 914 destination_gl->DeleteTextures(1, &intermediate_texture);
958 915
959 // Wait for destination context to consume mailbox before deleting it in 916 // Wait for destination context to consume mailbox before deleting it in
960 // canvas context. 917 // canvas context.
961 const GLuint64 dest_fence_sync = destination_gl->InsertFenceSyncCHROMIUM(); 918 const GLuint64 dest_fence_sync = destination_gl->InsertFenceSyncCHROMIUM();
962 destination_gl->ShallowFlushCHROMIUM(); 919 destination_gl->ShallowFlushCHROMIUM();
963 gpu::SyncToken dest_sync_token; 920 gpu::SyncToken dest_sync_token;
964 destination_gl->GenSyncTokenCHROMIUM(dest_fence_sync, 921 destination_gl->GenSyncTokenCHROMIUM(dest_fence_sync,
965 dest_sync_token.GetData()); 922 dest_sync_token.GetData());
966 canvas_gl->WaitSyncTokenCHROMIUM(dest_sync_token.GetConstData()); 923 canvas_gl->WaitSyncTokenCHROMIUM(dest_sync_token.GetConstData());
967 924
968 SyncTokenClientImpl client(canvas_gl); 925 SyncTokenClientImpl client(canvas_gl);
969 video_frame->UpdateReleaseSyncToken(&client); 926 video_frame->UpdateReleaseSyncToken(&client);
970 } else { 927 } else {
971 CopyVideoFrameSingleTextureToGLTexture( 928 CopyVideoFrameSingleTextureToGLTexture(
972 destination_gl, video_frame.get(), SingleFrameForWebGL, target, texture, 929 destination_gl, video_frame.get(), target, texture, internal_format,
973 internal_format, format, type, level, premultiply_alpha, flip_y); 930 format, type, level, premultiply_alpha, flip_y);
974 } 931 }
975 932
976 return true; 933 return true;
977 } 934 }
978 935
979 bool SkCanvasVideoRenderer::TexImage2D( 936 bool SkCanvasVideoRenderer::TexImage2D(
980 unsigned target, 937 unsigned target,
981 unsigned texture, 938 unsigned texture,
982 gpu::gles2::GLES2Interface* gl, 939 gpu::gles2::GLES2Interface* gl,
983 const gpu::Capabilities& gpu_capabilities, 940 const gpu::Capabilities& gpu_capabilities,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 last_image_->bounds().contains(visible_rect)) { 1055 last_image_->bounds().contains(visible_rect)) {
1099 last_image_ = last_image_->makeSubset(visible_rect); 1056 last_image_ = last_image_->makeSubset(visible_rect);
1100 } 1057 }
1101 } 1058 }
1102 1059
1103 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { 1060 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() {
1104 return last_image_dimensions_for_testing_; 1061 return last_image_dimensions_for_testing_;
1105 } 1062 }
1106 1063
1107 } // namespace media 1064 } // namespace media
OLDNEW
« no previous file with comments | « media/renderers/skcanvas_video_renderer.h ('k') | third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698