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

Side by Side Diff: third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp

Issue 2738163002: Enable CopyTextureCHROMIUM in Blink for Tex{Sub}Image2D with more cases (Closed)
Patch Set: rebase only--blink renaming and formatting 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 /* 1 /*
2 * Copyright (C) 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2009 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 sk_sp<SkImage> WebGLRenderingContextBase::MakeImageSnapshot( 815 sk_sp<SkImage> WebGLRenderingContextBase::MakeImageSnapshot(
816 SkImageInfo& image_info) { 816 SkImageInfo& image_info) {
817 GetDrawingBuffer()->ResolveAndBindForReadAndDraw(); 817 GetDrawingBuffer()->ResolveAndBindForReadAndDraw();
818 gpu::gles2::GLES2Interface* gl = SharedGpuContext::Gl(); 818 gpu::gles2::GLES2Interface* gl = SharedGpuContext::Gl();
819 819
820 SkSurfaceProps disable_lcd_props(0, kUnknown_SkPixelGeometry); 820 SkSurfaceProps disable_lcd_props(0, kUnknown_SkPixelGeometry);
821 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget( 821 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
822 SharedGpuContext::Gr(), SkBudgeted::kYes, image_info, 0, 822 SharedGpuContext::Gr(), SkBudgeted::kYes, image_info, 0,
823 image_info.alphaType() == kOpaque_SkAlphaType ? nullptr 823 image_info.alphaType() == kOpaque_SkAlphaType ? nullptr
824 : &disable_lcd_props); 824 : &disable_lcd_props);
825 GLuint texture_id = skia::GrBackendObjectToGrGLTextureInfo( 825 const GrGLTextureInfo* texture_info = skia::GrBackendObjectToGrGLTextureInfo(
826 surface->getTextureHandle( 826 surface->getTextureHandle(SkSurface::kDiscardWrite_TextureHandleAccess));
827 SkSurface::kDiscardWrite_TextureHandleAccess)) 827 GLuint texture_id = texture_info->fID;
828 ->fID; 828 GLenum texture_target = texture_info->fTarget;
829 829
830 GetDrawingBuffer()->CopyToPlatformTexture( 830 GetDrawingBuffer()->CopyToPlatformTexture(
831 gl, texture_id, GL_RGBA, GL_UNSIGNED_BYTE, 0, true, false, IntPoint(0, 0), 831 gl, texture_target, texture_id, true, false, IntPoint(0, 0),
832 IntRect(IntPoint(0, 0), GetDrawingBuffer()->size()), kBackBuffer); 832 IntRect(IntPoint(0, 0), GetDrawingBuffer()->size()), kBackBuffer);
833 return surface->makeImageSnapshot(); 833 return surface->makeImageSnapshot();
834 } 834 }
835 835
836 ImageData* WebGLRenderingContextBase::ToImageData(SnapshotReason reason) { 836 ImageData* WebGLRenderingContextBase::ToImageData(SnapshotReason reason) {
837 ImageData* image_data = nullptr; 837 ImageData* image_data = nullptr;
838 // TODO(ccameron): WebGL should produce sRGB images. 838 // TODO(ccameron): WebGL should produce sRGB images.
839 // https://crbug.com/672299 839 // https://crbug.com/672299
840 if (GetDrawingBuffer()) { 840 if (GetDrawingBuffer()) {
841 // For un-premultiplied data 841 // For un-premultiplied data
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 GL_UNSIGNED_INT_5_9_9_9_REV, 985 GL_UNSIGNED_INT_5_9_9_9_REV,
986 GL_UNSIGNED_INT_24_8, 986 GL_UNSIGNED_INT_24_8,
987 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 987 GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
988 }; 988 };
989 989
990 // ES3 enums supported by TexImageSource 990 // ES3 enums supported by TexImageSource
991 static const GLenum kSupportedTypesTexImageSourceES3[] = { 991 static const GLenum kSupportedTypesTexImageSourceES3[] = {
992 GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_INT_10F_11F_11F_REV, 992 GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_INT_10F_11F_11F_REV,
993 }; 993 };
994 994
995 bool IsUnsignedIntegerFormat(GLenum internalformat) {
996 switch (internalformat) {
997 case GL_R8UI:
998 case GL_R16UI:
999 case GL_R32UI:
1000 case GL_RG8UI:
1001 case GL_RG16UI:
1002 case GL_RG32UI:
1003 case GL_RGB8UI:
1004 case GL_RGB16UI:
1005 case GL_RGB32UI:
1006 case GL_RGBA8UI:
1007 case GL_RGB10_A2UI:
1008 case GL_RGBA16UI:
1009 case GL_RGBA32UI:
1010 return true;
1011 default:
1012 return false;
1013 }
1014 }
1015
1016 bool IsSignedIntegerFormat(GLenum internalformat) {
1017 switch (internalformat) {
1018 case GL_R8I:
1019 case GL_R16I:
1020 case GL_R32I:
1021 case GL_RG8I:
1022 case GL_RG16I:
1023 case GL_RG32I:
1024 case GL_RGB8I:
1025 case GL_RGB16I:
1026 case GL_RGB32I:
1027 case GL_RGBA8I:
1028 case GL_RGBA16I:
1029 case GL_RGBA32I:
1030 return true;
1031 default:
1032 return false;
1033 }
1034 }
1035
1036 bool IsIntegerFormat(GLenum internalformat) {
1037 return (IsUnsignedIntegerFormat(internalformat) ||
1038 IsSignedIntegerFormat(internalformat));
1039 }
1040
1041 bool IsFloatType(GLenum type) {
1042 switch (type) {
1043 case GL_FLOAT:
1044 case GL_HALF_FLOAT:
1045 case GL_HALF_FLOAT_OES:
1046 case GL_UNSIGNED_INT_10F_11F_11F_REV:
1047 return true;
1048 default:
1049 return false;
1050 }
1051 }
1052
1053 bool IsSRGBFormat(GLenum internalformat) {
1054 switch (internalformat) {
1055 case GL_SRGB_EXT:
1056 case GL_SRGB_ALPHA_EXT:
1057 case GL_SRGB8:
1058 case GL_SRGB8_ALPHA8:
1059 return true;
1060 default:
1061 return false;
1062 }
1063 }
1064
1065 } // namespace 995 } // namespace
1066 996
1067 WebGLRenderingContextBase::WebGLRenderingContextBase( 997 WebGLRenderingContextBase::WebGLRenderingContextBase(
1068 OffscreenCanvas* passed_offscreen_canvas, 998 OffscreenCanvas* passed_offscreen_canvas,
1069 std::unique_ptr<WebGraphicsContext3DProvider> context_provider, 999 std::unique_ptr<WebGraphicsContext3DProvider> context_provider,
1070 const CanvasContextCreationAttributes& requested_attributes, 1000 const CanvasContextCreationAttributes& requested_attributes,
1071 unsigned version) 1001 unsigned version)
1072 : WebGLRenderingContextBase( 1002 : WebGLRenderingContextBase(
1073 nullptr, 1003 nullptr,
1074 passed_offscreen_canvas, 1004 passed_offscreen_canvas,
(...skipping 3898 matching lines...) Expand 10 before | Expand all | Expand 10 after
4973 GLint internalformat, 4903 GLint internalformat,
4974 GLenum format, 4904 GLenum format,
4975 GLenum type, 4905 GLenum type,
4976 HTMLImageElement* image, 4906 HTMLImageElement* image,
4977 ExceptionState& exception_state) { 4907 ExceptionState& exception_state) {
4978 TexImageHelperHTMLImageElement(kTexImage2D, target, level, internalformat, 4908 TexImageHelperHTMLImageElement(kTexImage2D, target, level, internalformat,
4979 format, type, 0, 0, 0, image, 4909 format, type, 0, 0, 0, image,
4980 SentinelEmptyRect(), 1, 0, exception_state); 4910 SentinelEmptyRect(), 1, 0, exception_state);
4981 } 4911 }
4982 4912
4983 bool WebGLRenderingContextBase::CanUseTexImageByGPU( 4913 bool WebGLRenderingContextBase::CanUseTexImageByGPU(GLenum type) {
4984 TexImageFunctionID function_id, 4914 #if OS(MACOSX)
4985 GLint internalformat, 4915 // RGB5_A1 is not color-renderable on NVIDIA Mac, see crbug.com/676209.
4986 GLenum type) { 4916 // Though, glCopyTextureCHROMIUM can handle RGB5_A1 internalformat by doing a
4987 if (function_id == kTexImage2D && 4917 // fallback path, but it doesn't know the type info. So, we still cannot do
4988 (IsFloatType(type) || IsIntegerFormat(internalformat) || 4918 // the fallback path in glCopyTextureCHROMIUM for
4989 IsSRGBFormat(internalformat))) 4919 // RGBA/RGBA/UNSIGNED_SHORT_5_5_5_1 format and type combination.
4920 if (type == GL_UNSIGNED_SHORT_5_5_5_1)
4990 return false; 4921 return false;
4991 // TODO(crbug.com/622958): Implement GPU-to-GPU path for WebGL 2 and more 4922 #endif
4992 // internal formats. 4923 // OES_texture_half_float doesn't support HALF_FLOAT_OES type for
4993 if (function_id == kTexSubImage2D && 4924 // CopyTexImage/CopyTexSubImage. And OES_texture_half_float doesn't require
4994 (IsWebGL2OrHigher() || ExtensionEnabled(kOESTextureFloatName) || 4925 // HALF_FLOAT_OES type texture to be renderable. So, HALF_FLOAT_OES type
4995 ExtensionEnabled(kOESTextureHalfFloatName) || 4926 // texture cannot be copied to or drawn to by glCopyTextureCHROMIUM.
4996 ExtensionEnabled(kEXTsRGBName))) 4927 if (type == GL_HALF_FLOAT_OES)
4997 return false; 4928 return false;
4929
4998 return true; 4930 return true;
4999 } 4931 }
5000 4932
5001 SnapshotReason WebGLRenderingContextBase::FunctionIDToSnapshotReason( 4933 SnapshotReason WebGLRenderingContextBase::FunctionIDToSnapshotReason(
5002 TexImageFunctionID id) { 4934 TexImageFunctionID id) {
5003 switch (id) { 4935 switch (id) {
5004 case kTexImage2D: 4936 case kTexImage2D:
5005 return kSnapshotReasonWebGLTexImage2D; 4937 return kSnapshotReasonWebGLTexImage2D;
5006 case kTexSubImage2D: 4938 case kTexSubImage2D:
5007 return kSnapshotReasonWebGLTexSubImage2D; 4939 return kSnapshotReasonWebGLTexSubImage2D;
5008 case kTexImage3D: 4940 case kTexImage3D:
5009 return kSnapshotReasonWebGLTexImage3D; 4941 return kSnapshotReasonWebGLTexImage3D;
5010 case kTexSubImage3D: 4942 case kTexSubImage3D:
5011 return kSnapshotReasonWebGLTexSubImage3D; 4943 return kSnapshotReasonWebGLTexSubImage3D;
5012 } 4944 }
5013 NOTREACHED(); 4945 NOTREACHED();
5014 return kSnapshotReasonUnknown; 4946 return kSnapshotReasonUnknown;
5015 } 4947 }
5016 4948
5017 void WebGLRenderingContextBase::TexImageCanvasByGPU( 4949 void WebGLRenderingContextBase::TexImageCanvasByGPU(
5018 TexImageFunctionID function_id, 4950 TexImageFunctionID function_id,
5019 HTMLCanvasElement* canvas, 4951 HTMLCanvasElement* canvas,
4952 GLenum target,
5020 GLuint target_texture, 4953 GLuint target_texture,
5021 GLenum target_internalformat,
5022 GLenum target_type,
5023 GLint target_level,
5024 GLint xoffset, 4954 GLint xoffset,
5025 GLint yoffset, 4955 GLint yoffset,
5026 const IntRect& source_sub_rectangle) { 4956 const IntRect& source_sub_rectangle) {
5027 if (!canvas->Is3D()) { 4957 if (!canvas->Is3D()) {
5028 ImageBuffer* buffer = canvas->Buffer(); 4958 ImageBuffer* buffer = canvas->Buffer();
5029 if (buffer && !buffer->CopyToPlatformTexture( 4959 if (buffer &&
5030 FunctionIDToSnapshotReason(function_id), ContextGL(), 4960 !buffer->CopyToPlatformTexture(
5031 target_texture, target_internalformat, target_type, 4961 FunctionIDToSnapshotReason(function_id), ContextGL(), target,
5032 target_level, unpack_premultiply_alpha_, unpack_flip_y_, 4962 target_texture, unpack_premultiply_alpha_, unpack_flip_y_,
5033 IntPoint(xoffset, yoffset), source_sub_rectangle)) { 4963 IntPoint(xoffset, yoffset), source_sub_rectangle)) {
5034 NOTREACHED(); 4964 NOTREACHED();
5035 } 4965 }
5036 } else { 4966 } else {
5037 WebGLRenderingContextBase* gl = 4967 WebGLRenderingContextBase* gl =
5038 ToWebGLRenderingContextBase(canvas->RenderingContext()); 4968 ToWebGLRenderingContextBase(canvas->RenderingContext());
5039 ScopedTexture2DRestorer restorer(gl); 4969 ScopedTexture2DRestorer restorer(gl);
5040 if (!gl->GetDrawingBuffer()->CopyToPlatformTexture( 4970 if (!gl->GetDrawingBuffer()->CopyToPlatformTexture(
5041 ContextGL(), target_texture, target_internalformat, target_type, 4971 ContextGL(), target, target_texture, unpack_premultiply_alpha_,
5042 target_level, unpack_premultiply_alpha_, !unpack_flip_y_, 4972 !unpack_flip_y_, IntPoint(xoffset, yoffset), source_sub_rectangle,
5043 IntPoint(xoffset, yoffset), source_sub_rectangle, kBackBuffer)) { 4973 kBackBuffer)) {
5044 NOTREACHED(); 4974 NOTREACHED();
5045 } 4975 }
5046 } 4976 }
5047 } 4977 }
5048 4978
5049 void WebGLRenderingContextBase::TexImageByGPU( 4979 void WebGLRenderingContextBase::TexImageByGPU(
5050 TexImageFunctionID function_id, 4980 TexImageFunctionID function_id,
5051 WebGLTexture* texture, 4981 WebGLTexture* texture,
5052 GLenum target, 4982 GLenum target,
5053 GLint level, 4983 GLint level,
5054 GLint internalformat,
5055 GLenum type,
5056 GLint xoffset, 4984 GLint xoffset,
5057 GLint yoffset, 4985 GLint yoffset,
5058 GLint zoffset, 4986 GLint zoffset,
5059 CanvasImageSource* image, 4987 CanvasImageSource* image,
5060 const IntRect& source_sub_rectangle) { 4988 const IntRect& source_sub_rectangle) {
5061 DCHECK(image->IsCanvasElement() || image->IsImageBitmap()); 4989 DCHECK(image->IsCanvasElement() || image->IsImageBitmap());
5062 int width = source_sub_rectangle.Width(); 4990 int width = source_sub_rectangle.Width();
5063 int height = source_sub_rectangle.Height(); 4991 int height = source_sub_rectangle.Height();
5064 4992
5065 ScopedTexture2DRestorer restorer(this); 4993 ScopedTexture2DRestorer restorer(this);
5066 4994
5067 GLuint target_texture = texture->Object(); 4995 GLuint target_texture = texture->Object();
5068 GLenum target_type = type;
5069 GLenum target_internalformat = internalformat;
5070 GLint target_level = level;
5071 bool possible_direct_copy = false; 4996 bool possible_direct_copy = false;
5072 if (function_id == kTexImage2D) { 4997 if (function_id == kTexImage2D || function_id == kTexSubImage2D) {
5073 possible_direct_copy = Extensions3DUtil::CanUseCopyTextureCHROMIUM( 4998 possible_direct_copy = Extensions3DUtil::CanUseCopyTextureCHROMIUM(target);
5074 target, internalformat, type, level);
5075 } 4999 }
5076 5000
5077 GLint copy_x_offset = xoffset; 5001 GLint copy_x_offset = xoffset;
5078 GLint copy_y_offset = yoffset; 5002 GLint copy_y_offset = yoffset;
5003 GLenum copy_target = target;
5079 5004
5080 // if direct copy is not possible, create a temporary texture and then copy 5005 // if direct copy is not possible, create a temporary texture and then copy
5081 // from canvas to temporary texture to target texture. 5006 // from canvas to temporary texture to target texture.
5082 if (!possible_direct_copy) { 5007 if (!possible_direct_copy) {
5083 target_level = 0;
5084 target_internalformat = GL_RGBA;
5085 target_type = GL_UNSIGNED_BYTE;
5086 ContextGL()->GenTextures(1, &target_texture); 5008 ContextGL()->GenTextures(1, &target_texture);
5087 ContextGL()->BindTexture(GL_TEXTURE_2D, target_texture); 5009 ContextGL()->BindTexture(GL_TEXTURE_2D, target_texture);
5088 ContextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 5010 ContextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
5089 GL_NEAREST); 5011 GL_NEAREST);
5090 ContextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 5012 ContextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
5091 GL_NEAREST); 5013 GL_NEAREST);
5092 ContextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 5014 ContextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
5093 GL_CLAMP_TO_EDGE); 5015 GL_CLAMP_TO_EDGE);
5094 ContextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 5016 ContextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
5095 GL_CLAMP_TO_EDGE); 5017 GL_CLAMP_TO_EDGE);
5096 ContextGL()->TexImage2D(GL_TEXTURE_2D, 0, target_internalformat, width, 5018 ContextGL()->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
5097 height, 0, GL_RGBA, target_type, 0); 5019 GL_RGBA, GL_UNSIGNED_BYTE, 0);
5098 copy_x_offset = 0; 5020 copy_x_offset = 0;
5099 copy_y_offset = 0; 5021 copy_y_offset = 0;
5022 copy_target = GL_TEXTURE_2D;
5100 } 5023 }
5101 5024
5102 if (image->IsCanvasElement()) { 5025 {
5103 TexImageCanvasByGPU(function_id, static_cast<HTMLCanvasElement*>(image), 5026 // glCopyTextureCHROMIUM has a DRAW_AND_READBACK path which will call
5104 target_texture, target_internalformat, target_type, 5027 // texImage2D. So, reset unpack buffer parameters before that.
5105 target_level, copy_x_offset, copy_y_offset, 5028 ScopedUnpackParametersResetRestore temporaryResetUnpack(this);
5106 source_sub_rectangle); 5029 if (image->IsCanvasElement()) {
5107 } else { 5030 TexImageCanvasByGPU(function_id, static_cast<HTMLCanvasElement*>(image),
5108 TexImageBitmapByGPU(static_cast<ImageBitmap*>(image), target_texture, 5031 copy_target, target_texture, copy_x_offset,
5109 target_internalformat, target_type, target_level, 5032 copy_y_offset, source_sub_rectangle);
5110 !unpack_flip_y_); 5033 } else {
5034 TexImageBitmapByGPU(static_cast<ImageBitmap*>(image), copy_target,
5035 target_texture, !unpack_flip_y_, copy_x_offset,
5036 copy_y_offset, source_sub_rectangle);
5037 }
5111 } 5038 }
5112 5039
5113 if (!possible_direct_copy) { 5040 if (!possible_direct_copy) {
5114 GLuint tmp_fbo; 5041 GLuint tmp_fbo;
5115 ContextGL()->GenFramebuffers(1, &tmp_fbo); 5042 ContextGL()->GenFramebuffers(1, &tmp_fbo);
5116 ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmp_fbo); 5043 ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmp_fbo);
5117 ContextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 5044 ContextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5118 GL_TEXTURE_2D, target_texture, 0); 5045 GL_TEXTURE_2D, target_texture, 0);
5119 ContextGL()->BindTexture(texture->GetTarget(), texture->Object()); 5046 ContextGL()->BindTexture(texture->GetTarget(), texture->Object());
5120 if (function_id == kTexImage2D) { 5047 if (function_id == kTexImage2D) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
5177 func_name, function_id, canvas, source_sub_rectangle, depth, 5104 func_name, function_id, canvas, source_sub_rectangle, depth,
5178 unpack_image_height, &selecting_sub_rectangle)) { 5105 unpack_image_height, &selecting_sub_rectangle)) {
5179 return; 5106 return;
5180 } 5107 }
5181 5108
5182 if (function_id == kTexImage2D || function_id == kTexSubImage2D) { 5109 if (function_id == kTexImage2D || function_id == kTexSubImage2D) {
5183 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support 5110 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support
5184 // float/integer/sRGB internal format. 5111 // float/integer/sRGB internal format.
5185 // TODO(crbug.com/622958): relax the constrains if copyTextureCHROMIUM is 5112 // TODO(crbug.com/622958): relax the constrains if copyTextureCHROMIUM is
5186 // upgraded to handle more formats. 5113 // upgraded to handle more formats.
5187 if (!canvas->IsAccelerated() || 5114 if (!canvas->IsAccelerated() || !CanUseTexImageByGPU(type)) {
5188 !CanUseTexImageByGPU(function_id, internalformat, type)) {
5189 // 2D canvas has only FrontBuffer. 5115 // 2D canvas has only FrontBuffer.
5190 TexImageImpl(function_id, target, level, internalformat, xoffset, yoffset, 5116 TexImageImpl(function_id, target, level, internalformat, xoffset, yoffset,
5191 zoffset, format, type, 5117 zoffset, format, type,
5192 canvas 5118 canvas
5193 ->CopiedImage(kFrontBuffer, kPreferAcceleration, 5119 ->CopiedImage(kFrontBuffer, kPreferAcceleration,
5194 FunctionIDToSnapshotReason(function_id)) 5120 FunctionIDToSnapshotReason(function_id))
5195 .Get(), 5121 .Get(),
5196 WebGLImageConversion::kHtmlDomCanvas, unpack_flip_y_, 5122 WebGLImageConversion::kHtmlDomCanvas, unpack_flip_y_,
5197 unpack_premultiply_alpha_, source_sub_rectangle, 1, 0); 5123 unpack_premultiply_alpha_, source_sub_rectangle, 1, 0);
5198 return; 5124 return;
5199 } 5125 }
5200 5126
5201 // The GPU-GPU copy path uses the Y-up coordinate system. 5127 // The GPU-GPU copy path uses the Y-up coordinate system.
5202 IntRect adjusted_source_sub_rectangle = source_sub_rectangle; 5128 IntRect adjusted_source_sub_rectangle = source_sub_rectangle;
5203 if (!unpack_flip_y_) { 5129 if (!unpack_flip_y_) {
5204 adjusted_source_sub_rectangle.SetY(canvas->height() - 5130 adjusted_source_sub_rectangle.SetY(canvas->height() -
5205 adjusted_source_sub_rectangle.MaxY()); 5131 adjusted_source_sub_rectangle.MaxY());
5206 } 5132 }
5207 5133
5208 if (function_id == kTexImage2D) { 5134 if (function_id == kTexImage2D) {
5209 TexImage2DBase(target, level, internalformat, 5135 TexImage2DBase(target, level, internalformat,
5210 source_sub_rectangle.Width(), 5136 source_sub_rectangle.Width(),
5211 source_sub_rectangle.Height(), 0, format, type, 0); 5137 source_sub_rectangle.Height(), 0, format, type, 0);
5212 TexImageByGPU(function_id, texture, target, level, internalformat, type, 5138 TexImageByGPU(function_id, texture, target, level, 0, 0, 0, canvas,
5213 0, 0, 0, canvas, adjusted_source_sub_rectangle); 5139 adjusted_source_sub_rectangle);
5214 } else { 5140 } else {
5215 TexImageByGPU(function_id, texture, target, level, GL_RGBA, type, xoffset, 5141 TexImageByGPU(function_id, texture, target, level, xoffset, yoffset, 0,
5216 yoffset, 0, canvas, adjusted_source_sub_rectangle); 5142 canvas, adjusted_source_sub_rectangle);
5217 } 5143 }
5218 } else { 5144 } else {
5219 // 3D functions. 5145 // 3D functions.
5220 5146
5221 // TODO(zmo): Implement GPU-to-GPU copy path (crbug.com/612542). 5147 // TODO(zmo): Implement GPU-to-GPU copy path (crbug.com/612542).
5222 // Note that code will also be needed to copy to layers of 3D 5148 // Note that code will also be needed to copy to layers of 3D
5223 // textures, and elements of 2D texture arrays. 5149 // textures, and elements of 2D texture arrays.
5224 TexImageImpl(function_id, target, level, internalformat, xoffset, yoffset, 5150 TexImageImpl(function_id, target, level, internalformat, xoffset, yoffset,
5225 zoffset, format, type, 5151 zoffset, format, type,
5226 canvas 5152 canvas
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
5290 if (!ValidateTexFunc(func_name, function_type, kSourceHTMLVideoElement, 5216 if (!ValidateTexFunc(func_name, function_type, kSourceHTMLVideoElement,
5291 target, level, internalformat, video->videoWidth(), 5217 target, level, internalformat, video->videoWidth(),
5292 video->videoHeight(), 1, 0, format, type, xoffset, 5218 video->videoHeight(), 1, 0, format, type, xoffset,
5293 yoffset, zoffset)) 5219 yoffset, zoffset))
5294 return; 5220 return;
5295 5221
5296 bool source_image_rect_is_default = 5222 bool source_image_rect_is_default =
5297 source_image_rect == SentinelEmptyRect() || 5223 source_image_rect == SentinelEmptyRect() ||
5298 source_image_rect == 5224 source_image_rect ==
5299 IntRect(0, 0, video->videoWidth(), video->videoHeight()); 5225 IntRect(0, 0, video->videoWidth(), video->videoHeight());
5300 if (function_id == kTexImage2D && source_image_rect_is_default && 5226 const bool use_copyTextureCHROMIUM =
5301 depth == 1 && GL_TEXTURE_2D == target && 5227 function_id == kTexImage2D && source_image_rect_is_default &&
5302 Extensions3DUtil::CanUseCopyTextureCHROMIUM(target, internalformat, type, 5228 depth == 1 && GL_TEXTURE_2D == target && CanUseTexImageByGPU(type);
5303 level)) { 5229 // Format of source video may be 16-bit format, e.g. Y16 format.
5230 // glCopyTextureCHROMIUM requires the source texture to be in 8-bit format.
5231 // Converting 16-bits formated source texture to 8-bits formated texture will
5232 // cause precision lost. So, uploading such video texture to half float or
5233 // float texture can not use GPU-GPU path.
5234 if (use_copyTextureCHROMIUM) {
5304 DCHECK_EQ(xoffset, 0); 5235 DCHECK_EQ(xoffset, 0);
5305 DCHECK_EQ(yoffset, 0); 5236 DCHECK_EQ(yoffset, 0);
5306 DCHECK_EQ(zoffset, 0); 5237 DCHECK_EQ(zoffset, 0);
5307 // Go through the fast path doing a GPU-GPU textures copy without a readback 5238 // Go through the fast path doing a GPU-GPU textures copy without a readback
5308 // to system memory if possible. Otherwise, it will fall back to the normal 5239 // to system memory if possible. Otherwise, it will fall back to the normal
5309 // SW path. 5240 // SW path.
5310 5241
5311 // Note that neither 5242 // Note that neither
5312 // HTMLVideoElement::copyVideoTextureToPlatformTexture nor 5243 // HTMLVideoElement::copyVideoTextureToPlatformTexture nor
5313 // ImageBuffer::copyToPlatformTexture allocate the destination texture 5244 // ImageBuffer::copyToPlatformTexture allocate the destination texture
5314 // any more. 5245 // any more.
5315 TexImage2DBase(target, level, internalformat, video->videoWidth(), 5246 TexImage2DBase(target, level, internalformat, video->videoWidth(),
5316 video->videoHeight(), 0, format, type, nullptr); 5247 video->videoHeight(), 0, format, type, nullptr);
5317 5248
5318 if (video->CopyVideoTextureToPlatformTexture(ContextGL(), texture->Object(), 5249 if (video->CopyVideoTextureToPlatformTexture(ContextGL(), texture->Object(),
5319 unpack_premultiply_alpha_, 5250 unpack_premultiply_alpha_,
5320 unpack_flip_y_)) { 5251 unpack_flip_y_)) {
5321 texture->UpdateLastUploadedVideo(video->GetWebMediaPlayer()); 5252 texture->UpdateLastUploadedVideo(video->GetWebMediaPlayer());
5322 return; 5253 return;
5323 } 5254 }
5255 }
5324 5256
5257 if (source_image_rect_is_default) {
5258 // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It
5259 // leaves early for other formats or if frame is stored on GPU.
5260 ScopedUnpackParametersResetRestore(
5261 this, unpack_flip_y_ || unpack_premultiply_alpha_);
5262 if (video->TexImageImpl(
5263 static_cast<WebMediaPlayer::TexImageFunctionID>(function_id),
5264 target, ContextGL(), level,
5265 ConvertTexInternalFormat(internalformat, type), format, type,
5266 xoffset, yoffset, zoffset, unpack_flip_y_,
5267 unpack_premultiply_alpha_ &&
5268 unpack_colorspace_conversion_ == GL_NONE)) {
5269 texture->UpdateLastUploadedVideo(video->GetWebMediaPlayer());
5270 return;
5271 }
5272 }
5273
5274 if (use_copyTextureCHROMIUM) {
5325 // Try using an accelerated image buffer, this allows YUV conversion to be 5275 // Try using an accelerated image buffer, this allows YUV conversion to be
5326 // done on the GPU. 5276 // done on the GPU.
5327 std::unique_ptr<ImageBufferSurface> surface = 5277 std::unique_ptr<ImageBufferSurface> surface =
5328 WTF::WrapUnique(new AcceleratedImageBufferSurface( 5278 WTF::WrapUnique(new AcceleratedImageBufferSurface(
5329 IntSize(video->videoWidth(), video->videoHeight()))); 5279 IntSize(video->videoWidth(), video->videoHeight())));
5330 if (surface->IsValid()) { 5280 if (surface->IsValid()) {
5331 std::unique_ptr<ImageBuffer> image_buffer( 5281 std::unique_ptr<ImageBuffer> image_buffer(
5332 ImageBuffer::Create(std::move(surface))); 5282 ImageBuffer::Create(std::move(surface)));
5333 if (image_buffer) { 5283 if (image_buffer) {
5334 // The video element paints an RGBA frame into our surface here. By 5284 // The video element paints an RGBA frame into our surface here. By
5335 // using an AcceleratedImageBufferSurface, we enable the WebMediaPlayer 5285 // using an AcceleratedImageBufferSurface, we enable the WebMediaPlayer
5336 // implementation to do any necessary color space conversion on the GPU 5286 // implementation to do any necessary color space conversion on the GPU
5337 // (though it may still do a CPU conversion and upload the results). 5287 // (though it may still do a CPU conversion and upload the results).
5338 video->PaintCurrentFrame( 5288 video->PaintCurrentFrame(
5339 image_buffer->Canvas(), 5289 image_buffer->Canvas(),
5340 IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr); 5290 IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr);
5341 5291
5342 // This is a straight GPU-GPU copy, any necessary color space conversion 5292 // This is a straight GPU-GPU copy, any necessary color space conversion
5343 // was handled in the paintCurrentFrameInContext() call. 5293 // was handled in the paintCurrentFrameInContext() call.
5344 5294
5345 if (image_buffer->CopyToPlatformTexture( 5295 if (image_buffer->CopyToPlatformTexture(
5346 FunctionIDToSnapshotReason(function_id), ContextGL(), 5296 FunctionIDToSnapshotReason(function_id), ContextGL(), target,
5347 texture->Object(), internalformat, type, level, 5297 texture->Object(), unpack_premultiply_alpha_, unpack_flip_y_,
5348 unpack_premultiply_alpha_, unpack_flip_y_, IntPoint(0, 0), 5298 IntPoint(0, 0),
5349 IntRect(0, 0, video->videoWidth(), video->videoHeight()))) { 5299 IntRect(0, 0, video->videoWidth(), video->videoHeight()))) {
5350 texture->UpdateLastUploadedVideo(video->GetWebMediaPlayer()); 5300 texture->UpdateLastUploadedVideo(video->GetWebMediaPlayer());
5351 return; 5301 return;
5352 } 5302 }
5353 } 5303 }
5354 } 5304 }
5355 } 5305 }
5356 5306
5357 if (source_image_rect_is_default) {
5358 // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It
5359 // leaves early for other formats or if frame is stored on GPU.
5360 ScopedUnpackParametersResetRestore(
5361 this, unpack_flip_y_ || unpack_premultiply_alpha_);
5362 if (video->TexImageImpl(
5363 static_cast<WebMediaPlayer::TexImageFunctionID>(function_id),
5364 target, ContextGL(), level,
5365 ConvertTexInternalFormat(internalformat, type), format, type,
5366 xoffset, yoffset, zoffset, unpack_flip_y_,
5367 unpack_premultiply_alpha_ &&
5368 unpack_colorspace_conversion_ == GL_NONE)) {
5369 texture->UpdateLastUploadedVideo(video->GetWebMediaPlayer());
5370 return;
5371 }
5372 }
5373
5374 RefPtr<Image> image = VideoFrameToImage(video); 5307 RefPtr<Image> image = VideoFrameToImage(video);
5375 if (!image) 5308 if (!image)
5376 return; 5309 return;
5377 TexImageImpl(function_id, target, level, internalformat, xoffset, yoffset, 5310 TexImageImpl(function_id, target, level, internalformat, xoffset, yoffset,
5378 zoffset, format, type, image.Get(), 5311 zoffset, format, type, image.Get(),
5379 WebGLImageConversion::kHtmlDomVideo, unpack_flip_y_, 5312 WebGLImageConversion::kHtmlDomVideo, unpack_flip_y_,
5380 unpack_premultiply_alpha_, source_image_rect, depth, 5313 unpack_premultiply_alpha_, source_image_rect, depth,
5381 unpack_image_height); 5314 unpack_image_height);
5382 texture->UpdateLastUploadedVideo(video->GetWebMediaPlayer()); 5315 texture->UpdateLastUploadedVideo(video->GetWebMediaPlayer());
5383 } 5316 }
5384 5317
5385 void WebGLRenderingContextBase::TexImageBitmapByGPU( 5318 void WebGLRenderingContextBase::TexImageBitmapByGPU(
5386 ImageBitmap* bitmap, 5319 ImageBitmap* bitmap,
5320 GLenum target,
5387 GLuint target_texture, 5321 GLuint target_texture,
5388 GLenum target_internalformat, 5322 bool flip_y,
5389 GLenum target_type, 5323 GLint xoffset,
5390 GLint target_level, 5324 GLint yoffset,
5391 bool flip_y) { 5325 const IntRect& source_sub_rect) {
5392 bitmap->BitmapImage()->CopyToTexture(GetDrawingBuffer()->ContextProvider(), 5326 bitmap->BitmapImage()->CopyToTexture(
5393 target_texture, target_internalformat, 5327 GetDrawingBuffer()->ContextProvider(), target, target_texture, flip_y,
5394 target_type, flip_y); 5328 IntPoint(xoffset, yoffset), source_sub_rect);
5395 } 5329 }
5396 5330
5397 void WebGLRenderingContextBase::texImage2D(GLenum target, 5331 void WebGLRenderingContextBase::texImage2D(GLenum target,
5398 GLint level, 5332 GLint level,
5399 GLint internalformat, 5333 GLint internalformat,
5400 GLenum format, 5334 GLenum format,
5401 GLenum type, 5335 GLenum type,
5402 HTMLVideoElement* video, 5336 HTMLVideoElement* video,
5403 ExceptionState& exception_state) { 5337 ExceptionState& exception_state) {
5404 TexImageHelperHTMLVideoElement(kTexImage2D, target, level, internalformat, 5338 TexImageHelperHTMLVideoElement(kTexImage2D, target, level, internalformat,
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
5447 GLsizei width = source_sub_rect.Width(); 5381 GLsizei width = source_sub_rect.Width();
5448 GLsizei height = source_sub_rect.Height(); 5382 GLsizei height = source_sub_rect.Height();
5449 if (!ValidateTexFunc(func_name, function_type, kSourceImageBitmap, target, 5383 if (!ValidateTexFunc(func_name, function_type, kSourceImageBitmap, target,
5450 level, internalformat, width, height, depth, 0, format, 5384 level, internalformat, width, height, depth, 0, format,
5451 type, xoffset, yoffset, zoffset)) 5385 type, xoffset, yoffset, zoffset))
5452 return; 5386 return;
5453 ASSERT(bitmap->BitmapImage()); 5387 ASSERT(bitmap->BitmapImage());
5454 5388
5455 // TODO(kbr): make this work for sub-rectangles of ImageBitmaps. 5389 // TODO(kbr): make this work for sub-rectangles of ImageBitmaps.
5456 if (function_id != kTexSubImage3D && function_id != kTexImage3D && 5390 if (function_id != kTexSubImage3D && function_id != kTexImage3D &&
5457 bitmap->IsAccelerated() && 5391 bitmap->IsAccelerated() && CanUseTexImageByGPU(type) &&
5458 CanUseTexImageByGPU(function_id, internalformat, type) &&
5459 !selecting_sub_rectangle) { 5392 !selecting_sub_rectangle) {
5460 if (function_id == kTexImage2D) { 5393 if (function_id == kTexImage2D) {
5461 TexImage2DBase(target, level, internalformat, width, height, 0, format, 5394 TexImage2DBase(target, level, internalformat, width, height, 0, format,
5462 type, 0); 5395 type, 0);
5463 TexImageByGPU(function_id, texture, target, level, internalformat, type, 5396 TexImageByGPU(function_id, texture, target, level, 0, 0, 0, bitmap,
5464 0, 0, 0, bitmap, source_sub_rect); 5397 source_sub_rect);
5465 } else if (function_id == kTexSubImage2D) { 5398 } else if (function_id == kTexSubImage2D) {
5466 TexImageByGPU(function_id, texture, target, level, GL_RGBA, type, xoffset, 5399 TexImageByGPU(function_id, texture, target, level, xoffset, yoffset, 0,
5467 yoffset, 0, bitmap, source_sub_rect); 5400 bitmap, source_sub_rect);
5468 } 5401 }
5469 return; 5402 return;
5470 } 5403 }
5471 sk_sp<SkImage> sk_image = bitmap->BitmapImage()->ImageForCurrentFrame(); 5404 sk_sp<SkImage> sk_image = bitmap->BitmapImage()->ImageForCurrentFrame();
5472 SkPixmap pixmap; 5405 SkPixmap pixmap;
5473 uint8_t* pixel_data_ptr = nullptr; 5406 uint8_t* pixel_data_ptr = nullptr;
5474 RefPtr<Uint8Array> pixel_data; 5407 RefPtr<Uint8Array> pixel_data;
5475 // In the case where an ImageBitmap is not texture backed, peekPixels() always 5408 // In the case where an ImageBitmap is not texture backed, peekPixels() always
5476 // succeed. However, when it is texture backed and !canUseTexImageByGPU, we 5409 // succeed. However, when it is texture backed and !canUseTexImageByGPU, we
5477 // do a GPU read back. 5410 // do a GPU read back.
(...skipping 2396 matching lines...) Expand 10 before | Expand all | Expand 10 after
7874 7807
7875 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( 7808 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas(
7876 HTMLCanvasElementOrOffscreenCanvas& result) const { 7809 HTMLCanvasElementOrOffscreenCanvas& result) const {
7877 if (canvas()) 7810 if (canvas())
7878 result.setHTMLCanvasElement(canvas()); 7811 result.setHTMLCanvasElement(canvas());
7879 else 7812 else
7880 result.setOffscreenCanvas(offscreenCanvas()); 7813 result.setOffscreenCanvas(offscreenCanvas());
7881 } 7814 }
7882 7815
7883 } // namespace blink 7816 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698