OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |