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 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 sk_sp<SkImage> WebGLRenderingContextBase::makeImageSnapshot( | 812 sk_sp<SkImage> WebGLRenderingContextBase::makeImageSnapshot( |
813 SkImageInfo& imageInfo) { | 813 SkImageInfo& imageInfo) { |
814 drawingBuffer()->resolveAndBindForReadAndDraw(); | 814 drawingBuffer()->resolveAndBindForReadAndDraw(); |
815 gpu::gles2::GLES2Interface* gl = SharedGpuContext::gl(); | 815 gpu::gles2::GLES2Interface* gl = SharedGpuContext::gl(); |
816 | 816 |
817 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry); | 817 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry); |
818 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget( | 818 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget( |
819 SharedGpuContext::gr(), SkBudgeted::kYes, imageInfo, 0, | 819 SharedGpuContext::gr(), SkBudgeted::kYes, imageInfo, 0, |
820 imageInfo.alphaType() == kOpaque_SkAlphaType ? nullptr | 820 imageInfo.alphaType() == kOpaque_SkAlphaType ? nullptr |
821 : &disableLCDProps); | 821 : &disableLCDProps); |
822 GLuint textureId = skia::GrBackendObjectToGrGLTextureInfo( | 822 const GrGLTextureInfo* textureInfo = skia::GrBackendObjectToGrGLTextureInfo( |
823 surface->getTextureHandle( | 823 surface->getTextureHandle(SkSurface::kDiscardWrite_TextureHandleAccess)); |
824 SkSurface::kDiscardWrite_TextureHandleAccess)) | 824 GLuint textureId = textureInfo->fID; |
825 ->fID; | 825 GLenum textureTarget = textureInfo->fTarget; |
826 | 826 |
827 drawingBuffer()->copyToPlatformTexture( | 827 drawingBuffer()->copyToPlatformTexture( |
828 gl, textureId, GL_RGBA, GL_UNSIGNED_BYTE, 0, true, false, IntPoint(0, 0), | 828 gl, textureTarget, textureId, true, false, IntPoint(0, 0), |
829 IntRect(IntPoint(0, 0), drawingBuffer()->size()), BackBuffer); | 829 IntRect(IntPoint(0, 0), drawingBuffer()->size()), BackBuffer); |
830 return surface->makeImageSnapshot(); | 830 return surface->makeImageSnapshot(); |
831 } | 831 } |
832 | 832 |
833 ImageData* WebGLRenderingContextBase::toImageData(SnapshotReason reason) { | 833 ImageData* WebGLRenderingContextBase::toImageData(SnapshotReason reason) { |
834 ImageData* imageData = nullptr; | 834 ImageData* imageData = nullptr; |
835 // TODO(ccameron): WebGL should produce sRGB images. | 835 // TODO(ccameron): WebGL should produce sRGB images. |
836 // https://crbug.com/672299 | 836 // https://crbug.com/672299 |
837 if (drawingBuffer()) { | 837 if (drawingBuffer()) { |
838 // For un-premultiplied data | 838 // For un-premultiplied data |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
982 GL_UNSIGNED_INT_5_9_9_9_REV, | 982 GL_UNSIGNED_INT_5_9_9_9_REV, |
983 GL_UNSIGNED_INT_24_8, | 983 GL_UNSIGNED_INT_24_8, |
984 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, | 984 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, |
985 }; | 985 }; |
986 | 986 |
987 // ES3 enums supported by TexImageSource | 987 // ES3 enums supported by TexImageSource |
988 static const GLenum kSupportedTypesTexImageSourceES3[] = { | 988 static const GLenum kSupportedTypesTexImageSourceES3[] = { |
989 GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_INT_10F_11F_11F_REV, | 989 GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_INT_10F_11F_11F_REV, |
990 }; | 990 }; |
991 | 991 |
992 bool isUnsignedIntegerFormat(GLenum internalformat) { | |
993 switch (internalformat) { | |
994 case GL_R8UI: | |
995 case GL_R16UI: | |
996 case GL_R32UI: | |
997 case GL_RG8UI: | |
998 case GL_RG16UI: | |
999 case GL_RG32UI: | |
1000 case GL_RGB8UI: | |
1001 case GL_RGB16UI: | |
1002 case GL_RGB32UI: | |
1003 case GL_RGBA8UI: | |
1004 case GL_RGB10_A2UI: | |
1005 case GL_RGBA16UI: | |
1006 case GL_RGBA32UI: | |
1007 return true; | |
1008 default: | |
1009 return false; | |
1010 } | |
1011 } | |
1012 | |
1013 bool isSignedIntegerFormat(GLenum internalformat) { | |
1014 switch (internalformat) { | |
1015 case GL_R8I: | |
1016 case GL_R16I: | |
1017 case GL_R32I: | |
1018 case GL_RG8I: | |
1019 case GL_RG16I: | |
1020 case GL_RG32I: | |
1021 case GL_RGB8I: | |
1022 case GL_RGB16I: | |
1023 case GL_RGB32I: | |
1024 case GL_RGBA8I: | |
1025 case GL_RGBA16I: | |
1026 case GL_RGBA32I: | |
1027 return true; | |
1028 default: | |
1029 return false; | |
1030 } | |
1031 } | |
1032 | |
1033 bool isIntegerFormat(GLenum internalformat) { | |
1034 return (isUnsignedIntegerFormat(internalformat) || | |
1035 isSignedIntegerFormat(internalformat)); | |
1036 } | |
1037 | |
1038 bool isFloatType(GLenum type) { | |
1039 switch (type) { | |
1040 case GL_FLOAT: | |
1041 case GL_HALF_FLOAT: | |
1042 case GL_HALF_FLOAT_OES: | |
1043 case GL_UNSIGNED_INT_10F_11F_11F_REV: | |
1044 return true; | |
1045 default: | |
1046 return false; | |
1047 } | |
1048 } | |
1049 | |
1050 bool isSRGBFormat(GLenum internalformat) { | |
1051 switch (internalformat) { | |
1052 case GL_SRGB_EXT: | |
1053 case GL_SRGB_ALPHA_EXT: | |
1054 case GL_SRGB8: | |
1055 case GL_SRGB8_ALPHA8: | |
1056 return true; | |
1057 default: | |
1058 return false; | |
1059 } | |
1060 } | |
1061 | |
1062 } // namespace | 992 } // namespace |
1063 | 993 |
1064 WebGLRenderingContextBase::WebGLRenderingContextBase( | 994 WebGLRenderingContextBase::WebGLRenderingContextBase( |
1065 OffscreenCanvas* passedOffscreenCanvas, | 995 OffscreenCanvas* passedOffscreenCanvas, |
1066 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 996 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, |
1067 const CanvasContextCreationAttributes& requestedAttributes, | 997 const CanvasContextCreationAttributes& requestedAttributes, |
1068 unsigned version) | 998 unsigned version) |
1069 : WebGLRenderingContextBase( | 999 : WebGLRenderingContextBase( |
1070 nullptr, | 1000 nullptr, |
1071 passedOffscreenCanvas, | 1001 passedOffscreenCanvas, |
(...skipping 3880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4952 GLint internalformat, | 4882 GLint internalformat, |
4953 GLenum format, | 4883 GLenum format, |
4954 GLenum type, | 4884 GLenum type, |
4955 HTMLImageElement* image, | 4885 HTMLImageElement* image, |
4956 ExceptionState& exceptionState) { | 4886 ExceptionState& exceptionState) { |
4957 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, | 4887 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, |
4958 format, type, 0, 0, 0, image, | 4888 format, type, 0, 0, 0, image, |
4959 sentinelEmptyRect(), 1, 0, exceptionState); | 4889 sentinelEmptyRect(), 1, 0, exceptionState); |
4960 } | 4890 } |
4961 | 4891 |
4962 bool WebGLRenderingContextBase::canUseTexImageByGPU( | 4892 bool WebGLRenderingContextBase::canUseTexImageByGPU(GLenum type) { |
4963 TexImageFunctionID functionID, | 4893 #if OS(MACOSX) |
4964 GLint internalformat, | 4894 // RGB5_A1 is not color-renderable on NVIDIA Mac, see crbug.com/676209. |
4965 GLenum type) { | 4895 if (type == GL_UNSIGNED_SHORT_5_5_5_1) |
4966 if (functionID == TexImage2D && | |
4967 (isFloatType(type) || isIntegerFormat(internalformat) || | |
4968 isSRGBFormat(internalformat))) | |
4969 return false; | 4896 return false; |
4970 // TODO(crbug.com/622958): Implement GPU-to-GPU path for WebGL 2 and more | 4897 #endif |
4971 // internal formats. | 4898 // OES_texture_half_float doesn't support HALF_FLOAT_OES type for |
4972 if (functionID == TexSubImage2D && | 4899 // CopyTexImage/CopyTexSubImage. And OES_texture_half_float doesn't require |
4973 (isWebGL2OrHigher() || extensionEnabled(OESTextureFloatName) || | 4900 // HALF_FLOAT_OES type texture to be renderable. So, HALF_FLOAT_OES type |
4974 extensionEnabled(OESTextureHalfFloatName) || | 4901 // texture cannot be copied to or drawn to by glCopyTextureCHROMIUM. |
4975 extensionEnabled(EXTsRGBName))) | 4902 if (type == GL_HALF_FLOAT_OES) |
4976 return false; | 4903 return false; |
| 4904 |
4977 return true; | 4905 return true; |
4978 } | 4906 } |
4979 | 4907 |
4980 SnapshotReason WebGLRenderingContextBase::functionIDToSnapshotReason( | 4908 SnapshotReason WebGLRenderingContextBase::functionIDToSnapshotReason( |
4981 TexImageFunctionID id) { | 4909 TexImageFunctionID id) { |
4982 switch (id) { | 4910 switch (id) { |
4983 case TexImage2D: | 4911 case TexImage2D: |
4984 return SnapshotReasonWebGLTexImage2D; | 4912 return SnapshotReasonWebGLTexImage2D; |
4985 case TexSubImage2D: | 4913 case TexSubImage2D: |
4986 return SnapshotReasonWebGLTexSubImage2D; | 4914 return SnapshotReasonWebGLTexSubImage2D; |
4987 case TexImage3D: | 4915 case TexImage3D: |
4988 return SnapshotReasonWebGLTexImage3D; | 4916 return SnapshotReasonWebGLTexImage3D; |
4989 case TexSubImage3D: | 4917 case TexSubImage3D: |
4990 return SnapshotReasonWebGLTexSubImage3D; | 4918 return SnapshotReasonWebGLTexSubImage3D; |
4991 } | 4919 } |
4992 NOTREACHED(); | 4920 NOTREACHED(); |
4993 return SnapshotReasonUnknown; | 4921 return SnapshotReasonUnknown; |
4994 } | 4922 } |
4995 | 4923 |
4996 void WebGLRenderingContextBase::texImageCanvasByGPU( | 4924 void WebGLRenderingContextBase::texImageCanvasByGPU( |
4997 TexImageFunctionID functionID, | 4925 TexImageFunctionID functionID, |
4998 HTMLCanvasElement* canvas, | 4926 HTMLCanvasElement* canvas, |
| 4927 GLenum target, |
4999 GLuint targetTexture, | 4928 GLuint targetTexture, |
5000 GLenum targetInternalformat, | |
5001 GLenum targetType, | |
5002 GLint targetLevel, | |
5003 GLint xoffset, | 4929 GLint xoffset, |
5004 GLint yoffset, | 4930 GLint yoffset, |
5005 const IntRect& sourceSubRectangle) { | 4931 const IntRect& sourceSubRectangle) { |
5006 if (!canvas->is3D()) { | 4932 if (!canvas->is3D()) { |
5007 ImageBuffer* buffer = canvas->buffer(); | 4933 ImageBuffer* buffer = canvas->buffer(); |
5008 if (buffer && | 4934 if (buffer && |
5009 !buffer->copyToPlatformTexture( | 4935 !buffer->copyToPlatformTexture( |
5010 functionIDToSnapshotReason(functionID), contextGL(), targetTexture, | 4936 functionIDToSnapshotReason(functionID), contextGL(), target, |
5011 targetInternalformat, targetType, targetLevel, | 4937 targetTexture, m_unpackPremultiplyAlpha, m_unpackFlipY, |
5012 m_unpackPremultiplyAlpha, m_unpackFlipY, IntPoint(xoffset, yoffset), | 4938 IntPoint(xoffset, yoffset), sourceSubRectangle)) { |
5013 sourceSubRectangle)) { | |
5014 NOTREACHED(); | 4939 NOTREACHED(); |
5015 } | 4940 } |
5016 } else { | 4941 } else { |
5017 WebGLRenderingContextBase* gl = | 4942 WebGLRenderingContextBase* gl = |
5018 toWebGLRenderingContextBase(canvas->renderingContext()); | 4943 toWebGLRenderingContextBase(canvas->renderingContext()); |
5019 ScopedTexture2DRestorer restorer(gl); | 4944 ScopedTexture2DRestorer restorer(gl); |
5020 if (!gl->drawingBuffer()->copyToPlatformTexture( | 4945 if (!gl->drawingBuffer()->copyToPlatformTexture( |
5021 contextGL(), targetTexture, targetInternalformat, targetType, | 4946 contextGL(), target, targetTexture, m_unpackPremultiplyAlpha, |
5022 targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, | 4947 !m_unpackFlipY, IntPoint(xoffset, yoffset), sourceSubRectangle, |
5023 IntPoint(xoffset, yoffset), sourceSubRectangle, BackBuffer)) { | 4948 BackBuffer)) { |
5024 NOTREACHED(); | 4949 NOTREACHED(); |
5025 } | 4950 } |
5026 } | 4951 } |
5027 } | 4952 } |
5028 | 4953 |
5029 void WebGLRenderingContextBase::texImageByGPU( | 4954 void WebGLRenderingContextBase::texImageByGPU( |
5030 TexImageFunctionID functionID, | 4955 TexImageFunctionID functionID, |
5031 WebGLTexture* texture, | 4956 WebGLTexture* texture, |
5032 GLenum target, | 4957 GLenum target, |
5033 GLint level, | 4958 GLint level, |
5034 GLint internalformat, | |
5035 GLenum type, | |
5036 GLint xoffset, | 4959 GLint xoffset, |
5037 GLint yoffset, | 4960 GLint yoffset, |
5038 GLint zoffset, | 4961 GLint zoffset, |
5039 CanvasImageSource* image, | 4962 CanvasImageSource* image, |
5040 const IntRect& sourceSubRectangle) { | 4963 const IntRect& sourceSubRectangle) { |
5041 DCHECK(image->isCanvasElement() || image->isImageBitmap()); | 4964 DCHECK(image->isCanvasElement() || image->isImageBitmap()); |
5042 int width = sourceSubRectangle.width(); | 4965 int width = sourceSubRectangle.width(); |
5043 int height = sourceSubRectangle.height(); | 4966 int height = sourceSubRectangle.height(); |
5044 | 4967 |
5045 ScopedTexture2DRestorer restorer(this); | 4968 ScopedTexture2DRestorer restorer(this); |
5046 | 4969 |
5047 GLuint targetTexture = texture->object(); | 4970 GLuint targetTexture = texture->object(); |
5048 GLenum targetType = type; | |
5049 GLenum targetInternalformat = internalformat; | |
5050 GLint targetLevel = level; | |
5051 bool possibleDirectCopy = false; | 4971 bool possibleDirectCopy = false; |
5052 if (functionID == TexImage2D) { | 4972 if (functionID == TexImage2D || functionID == TexSubImage2D) { |
5053 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM( | 4973 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target); |
5054 target, internalformat, type, level); | |
5055 } | 4974 } |
5056 | 4975 |
5057 GLint copyXOffset = xoffset; | 4976 GLint copyXOffset = xoffset; |
5058 GLint copyYOffset = yoffset; | 4977 GLint copyYOffset = yoffset; |
| 4978 GLenum copyTarget = target; |
5059 | 4979 |
5060 // if direct copy is not possible, create a temporary texture and then copy | 4980 // if direct copy is not possible, create a temporary texture and then copy |
5061 // from canvas to temporary texture to target texture. | 4981 // from canvas to temporary texture to target texture. |
5062 if (!possibleDirectCopy) { | 4982 if (!possibleDirectCopy) { |
5063 targetLevel = 0; | |
5064 targetInternalformat = GL_RGBA; | |
5065 targetType = GL_UNSIGNED_BYTE; | |
5066 contextGL()->GenTextures(1, &targetTexture); | 4983 contextGL()->GenTextures(1, &targetTexture); |
5067 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); | 4984 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); |
5068 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, | 4985 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, |
5069 GL_NEAREST); | 4986 GL_NEAREST); |
5070 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, | 4987 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, |
5071 GL_NEAREST); | 4988 GL_NEAREST); |
5072 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, | 4989 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, |
5073 GL_CLAMP_TO_EDGE); | 4990 GL_CLAMP_TO_EDGE); |
5074 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, | 4991 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, |
5075 GL_CLAMP_TO_EDGE); | 4992 GL_CLAMP_TO_EDGE); |
5076 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, width, | 4993 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, |
5077 height, 0, GL_RGBA, targetType, 0); | 4994 GL_RGBA, GL_UNSIGNED_BYTE, 0); |
5078 copyXOffset = 0; | 4995 copyXOffset = 0; |
5079 copyYOffset = 0; | 4996 copyYOffset = 0; |
| 4997 copyTarget = GL_TEXTURE_2D; |
5080 } | 4998 } |
5081 | 4999 |
| 5000 ScopedUnpackParametersResetRestore temporaryResetUnpack(this); |
5082 if (image->isCanvasElement()) { | 5001 if (image->isCanvasElement()) { |
5083 texImageCanvasByGPU(functionID, static_cast<HTMLCanvasElement*>(image), | 5002 texImageCanvasByGPU(functionID, static_cast<HTMLCanvasElement*>(image), |
5084 targetTexture, targetInternalformat, targetType, | 5003 copyTarget, targetTexture, copyXOffset, copyYOffset, |
5085 targetLevel, copyXOffset, copyYOffset, | |
5086 sourceSubRectangle); | 5004 sourceSubRectangle); |
5087 } else { | 5005 } else { |
5088 texImageBitmapByGPU(static_cast<ImageBitmap*>(image), targetTexture, | 5006 texImageBitmapByGPU(static_cast<ImageBitmap*>(image), copyTarget, |
5089 targetInternalformat, targetType, targetLevel, | 5007 targetTexture, !m_unpackFlipY, copyXOffset, copyYOffset, |
5090 !m_unpackFlipY); | 5008 sourceSubRectangle); |
5091 } | 5009 } |
5092 | 5010 |
5093 if (!possibleDirectCopy) { | 5011 if (!possibleDirectCopy) { |
5094 GLuint tmpFBO; | 5012 GLuint tmpFBO; |
5095 contextGL()->GenFramebuffers(1, &tmpFBO); | 5013 contextGL()->GenFramebuffers(1, &tmpFBO); |
5096 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO); | 5014 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO); |
5097 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 5015 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
5098 GL_TEXTURE_2D, targetTexture, 0); | 5016 GL_TEXTURE_2D, targetTexture, 0); |
5099 contextGL()->BindTexture(texture->getTarget(), texture->object()); | 5017 contextGL()->BindTexture(texture->getTarget(), texture->object()); |
5100 if (functionID == TexImage2D) { | 5018 if (functionID == TexImage2D) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5157 return; | 5075 return; |
5158 } | 5076 } |
5159 | 5077 |
5160 if (functionID == TexImage2D || functionID == TexSubImage2D) { | 5078 if (functionID == TexImage2D || functionID == TexSubImage2D) { |
5161 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support | 5079 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support |
5162 // float/integer/sRGB internal format. | 5080 // float/integer/sRGB internal format. |
5163 // TODO(crbug.com/622958): relax the constrains if copyTextureCHROMIUM is | 5081 // TODO(crbug.com/622958): relax the constrains if copyTextureCHROMIUM is |
5164 // upgraded to handle more formats. | 5082 // upgraded to handle more formats. |
5165 if (!canvas->renderingContext() || | 5083 if (!canvas->renderingContext() || |
5166 !canvas->renderingContext()->isAccelerated() || | 5084 !canvas->renderingContext()->isAccelerated() || |
5167 !canUseTexImageByGPU(functionID, internalformat, type)) { | 5085 !canUseTexImageByGPU(type)) { |
5168 // 2D canvas has only FrontBuffer. | 5086 // 2D canvas has only FrontBuffer. |
5169 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, | 5087 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, |
5170 zoffset, format, type, | 5088 zoffset, format, type, |
5171 canvas | 5089 canvas |
5172 ->copiedImage(FrontBuffer, PreferAcceleration, | 5090 ->copiedImage(FrontBuffer, PreferAcceleration, |
5173 functionIDToSnapshotReason(functionID)) | 5091 functionIDToSnapshotReason(functionID)) |
5174 .get(), | 5092 .get(), |
5175 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, | 5093 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, |
5176 m_unpackPremultiplyAlpha, sourceSubRectangle, 1, 0); | 5094 m_unpackPremultiplyAlpha, sourceSubRectangle, 1, 0); |
5177 return; | 5095 return; |
5178 } | 5096 } |
5179 | 5097 |
5180 // The GPU-GPU copy path uses the Y-up coordinate system. | 5098 // The GPU-GPU copy path uses the Y-up coordinate system. |
5181 IntRect adjustedSourceSubRectangle = sourceSubRectangle; | 5099 IntRect adjustedSourceSubRectangle = sourceSubRectangle; |
5182 if (!m_unpackFlipY) { | 5100 if (!m_unpackFlipY) { |
5183 adjustedSourceSubRectangle.setY(canvas->height() - | 5101 adjustedSourceSubRectangle.setY(canvas->height() - |
5184 adjustedSourceSubRectangle.maxY()); | 5102 adjustedSourceSubRectangle.maxY()); |
5185 } | 5103 } |
5186 | 5104 |
5187 if (functionID == TexImage2D) { | 5105 if (functionID == TexImage2D) { |
5188 texImage2DBase(target, level, internalformat, sourceSubRectangle.width(), | 5106 texImage2DBase(target, level, internalformat, sourceSubRectangle.width(), |
5189 sourceSubRectangle.height(), 0, format, type, 0); | 5107 sourceSubRectangle.height(), 0, format, type, 0); |
5190 texImageByGPU(functionID, texture, target, level, internalformat, type, 0, | 5108 texImageByGPU(functionID, texture, target, level, 0, 0, 0, canvas, |
5191 0, 0, canvas, adjustedSourceSubRectangle); | 5109 adjustedSourceSubRectangle); |
5192 } else { | 5110 } else { |
5193 texImageByGPU(functionID, texture, target, level, GL_RGBA, type, xoffset, | 5111 texImageByGPU(functionID, texture, target, level, xoffset, yoffset, 0, |
5194 yoffset, 0, canvas, adjustedSourceSubRectangle); | 5112 canvas, adjustedSourceSubRectangle); |
5195 } | 5113 } |
5196 } else { | 5114 } else { |
5197 // 3D functions. | 5115 // 3D functions. |
5198 | 5116 |
5199 // TODO(zmo): Implement GPU-to-GPU copy path (crbug.com/612542). | 5117 // TODO(zmo): Implement GPU-to-GPU copy path (crbug.com/612542). |
5200 // Note that code will also be needed to copy to layers of 3D | 5118 // Note that code will also be needed to copy to layers of 3D |
5201 // textures, and elements of 2D texture arrays. | 5119 // textures, and elements of 2D texture arrays. |
5202 texImageImpl( | 5120 texImageImpl( |
5203 functionID, target, level, internalformat, xoffset, yoffset, zoffset, | 5121 functionID, target, level, internalformat, xoffset, yoffset, zoffset, |
5204 format, type, canvas | 5122 format, type, canvas |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5266 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, | 5184 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, |
5267 level, internalformat, video->videoWidth(), | 5185 level, internalformat, video->videoWidth(), |
5268 video->videoHeight(), 1, 0, format, type, xoffset, | 5186 video->videoHeight(), 1, 0, format, type, xoffset, |
5269 yoffset, zoffset)) | 5187 yoffset, zoffset)) |
5270 return; | 5188 return; |
5271 | 5189 |
5272 bool sourceImageRectIsDefault = | 5190 bool sourceImageRectIsDefault = |
5273 sourceImageRect == sentinelEmptyRect() || | 5191 sourceImageRect == sentinelEmptyRect() || |
5274 sourceImageRect == | 5192 sourceImageRect == |
5275 IntRect(0, 0, video->videoWidth(), video->videoHeight()); | 5193 IntRect(0, 0, video->videoWidth(), video->videoHeight()); |
5276 if (functionID == TexImage2D && sourceImageRectIsDefault && depth == 1 && | 5194 const bool useCopyTextureCHROMIUM = |
5277 GL_TEXTURE_2D == target && Extensions3DUtil::canUseCopyTextureCHROMIUM( | 5195 functionID == TexImage2D && sourceImageRectIsDefault && depth == 1 && |
5278 target, internalformat, type, level)) { | 5196 GL_TEXTURE_2D == target && canUseTexImageByGPU(type); |
| 5197 // Format of source video may be 16-bit format, e.g. Y16 format. |
| 5198 // glCopyTextureCHROMIUM will cause precision lost when uploading such video |
| 5199 // texture to half float or float texture. |
| 5200 if (useCopyTextureCHROMIUM) { |
5279 DCHECK_EQ(xoffset, 0); | 5201 DCHECK_EQ(xoffset, 0); |
5280 DCHECK_EQ(yoffset, 0); | 5202 DCHECK_EQ(yoffset, 0); |
5281 DCHECK_EQ(zoffset, 0); | 5203 DCHECK_EQ(zoffset, 0); |
5282 // Go through the fast path doing a GPU-GPU textures copy without a readback | 5204 // Go through the fast path doing a GPU-GPU textures copy without a readback |
5283 // to system memory if possible. Otherwise, it will fall back to the normal | 5205 // to system memory if possible. Otherwise, it will fall back to the normal |
5284 // SW path. | 5206 // SW path. |
5285 | 5207 |
5286 // Note that neither | 5208 // Note that neither |
5287 // HTMLVideoElement::copyVideoTextureToPlatformTexture nor | 5209 // HTMLVideoElement::copyVideoTextureToPlatformTexture nor |
5288 // ImageBuffer::copyToPlatformTexture allocate the destination texture | 5210 // ImageBuffer::copyToPlatformTexture allocate the destination texture |
5289 // any more. | 5211 // any more. |
5290 texImage2DBase(target, level, internalformat, video->videoWidth(), | 5212 texImage2DBase(target, level, internalformat, video->videoWidth(), |
5291 video->videoHeight(), 0, format, type, nullptr); | 5213 video->videoHeight(), 0, format, type, nullptr); |
5292 | 5214 |
5293 if (video->copyVideoTextureToPlatformTexture(contextGL(), texture->object(), | 5215 if (video->copyVideoTextureToPlatformTexture(contextGL(), texture->object(), |
5294 m_unpackPremultiplyAlpha, | 5216 m_unpackPremultiplyAlpha, |
5295 m_unpackFlipY)) { | 5217 m_unpackFlipY)) { |
5296 return; | 5218 return; |
5297 } | 5219 } |
| 5220 } |
5298 | 5221 |
| 5222 if (sourceImageRectIsDefault) { |
| 5223 // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It |
| 5224 // leaves early for other formats or if frame is stored on GPU. |
| 5225 ScopedUnpackParametersResetRestore( |
| 5226 this, m_unpackFlipY || m_unpackPremultiplyAlpha); |
| 5227 if (video->texImageImpl( |
| 5228 static_cast<WebMediaPlayer::TexImageFunctionID>(functionID), target, |
| 5229 contextGL(), level, convertTexInternalFormat(internalformat, type), |
| 5230 format, type, xoffset, yoffset, zoffset, m_unpackFlipY, |
| 5231 m_unpackPremultiplyAlpha && |
| 5232 m_unpackColorspaceConversion == GL_NONE)) |
| 5233 return; |
| 5234 } |
| 5235 |
| 5236 if (useCopyTextureCHROMIUM) { |
5299 // Try using an accelerated image buffer, this allows YUV conversion to be | 5237 // Try using an accelerated image buffer, this allows YUV conversion to be |
5300 // done on the GPU. | 5238 // done on the GPU. |
5301 std::unique_ptr<ImageBufferSurface> surface = | 5239 std::unique_ptr<ImageBufferSurface> surface = |
5302 WTF::wrapUnique(new AcceleratedImageBufferSurface( | 5240 WTF::wrapUnique(new AcceleratedImageBufferSurface( |
5303 IntSize(video->videoWidth(), video->videoHeight()))); | 5241 IntSize(video->videoWidth(), video->videoHeight()))); |
5304 if (surface->isValid()) { | 5242 if (surface->isValid()) { |
5305 std::unique_ptr<ImageBuffer> imageBuffer( | 5243 std::unique_ptr<ImageBuffer> imageBuffer( |
5306 ImageBuffer::create(std::move(surface))); | 5244 ImageBuffer::create(std::move(surface))); |
5307 if (imageBuffer) { | 5245 if (imageBuffer) { |
5308 // The video element paints an RGBA frame into our surface here. By | 5246 // The video element paints an RGBA frame into our surface here. By |
5309 // using an AcceleratedImageBufferSurface, we enable the WebMediaPlayer | 5247 // using an AcceleratedImageBufferSurface, we enable the WebMediaPlayer |
5310 // implementation to do any necessary color space conversion on the GPU | 5248 // implementation to do any necessary color space conversion on the GPU |
5311 // (though it may still do a CPU conversion and upload the results). | 5249 // (though it may still do a CPU conversion and upload the results). |
5312 video->paintCurrentFrame( | 5250 video->paintCurrentFrame( |
5313 imageBuffer->canvas(), | 5251 imageBuffer->canvas(), |
5314 IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr); | 5252 IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr); |
5315 | 5253 |
5316 // This is a straight GPU-GPU copy, any necessary color space conversion | 5254 // This is a straight GPU-GPU copy, any necessary color space conversion |
5317 // was handled in the paintCurrentFrameInContext() call. | 5255 // was handled in the paintCurrentFrameInContext() call. |
5318 | 5256 |
5319 if (imageBuffer->copyToPlatformTexture( | 5257 if (imageBuffer->copyToPlatformTexture( |
5320 functionIDToSnapshotReason(functionID), contextGL(), | 5258 functionIDToSnapshotReason(functionID), contextGL(), target, |
5321 texture->object(), internalformat, type, level, | 5259 texture->object(), m_unpackPremultiplyAlpha, m_unpackFlipY, |
5322 m_unpackPremultiplyAlpha, m_unpackFlipY, IntPoint(0, 0), | 5260 IntPoint(0, 0), |
5323 IntRect(0, 0, video->videoWidth(), video->videoHeight()))) { | 5261 IntRect(0, 0, video->videoWidth(), video->videoHeight()))) { |
5324 return; | 5262 return; |
5325 } | 5263 } |
5326 } | 5264 } |
5327 } | 5265 } |
5328 } | 5266 } |
5329 | 5267 |
5330 if (sourceImageRectIsDefault) { | |
5331 // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It | |
5332 // leaves early for other formats or if frame is stored on GPU. | |
5333 ScopedUnpackParametersResetRestore( | |
5334 this, m_unpackFlipY || m_unpackPremultiplyAlpha); | |
5335 if (video->texImageImpl( | |
5336 static_cast<WebMediaPlayer::TexImageFunctionID>(functionID), target, | |
5337 contextGL(), level, convertTexInternalFormat(internalformat, type), | |
5338 format, type, xoffset, yoffset, zoffset, m_unpackFlipY, | |
5339 m_unpackPremultiplyAlpha && | |
5340 m_unpackColorspaceConversion == GL_NONE)) | |
5341 return; | |
5342 } | |
5343 | |
5344 RefPtr<Image> image = videoFrameToImage(video); | 5268 RefPtr<Image> image = videoFrameToImage(video); |
5345 if (!image) | 5269 if (!image) |
5346 return; | 5270 return; |
5347 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, | 5271 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, |
5348 zoffset, format, type, image.get(), | 5272 zoffset, format, type, image.get(), |
5349 WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, | 5273 WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, |
5350 m_unpackPremultiplyAlpha, sourceImageRect, depth, | 5274 m_unpackPremultiplyAlpha, sourceImageRect, depth, |
5351 unpackImageHeight); | 5275 unpackImageHeight); |
5352 } | 5276 } |
5353 | 5277 |
5354 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, | 5278 void WebGLRenderingContextBase::texImageBitmapByGPU( |
5355 GLuint targetTexture, | 5279 ImageBitmap* bitmap, |
5356 GLenum targetInternalformat, | 5280 GLenum target, |
5357 GLenum targetType, | 5281 GLuint targetTexture, |
5358 GLint targetLevel, | 5282 bool flipY, |
5359 bool flipY) { | 5283 GLint xoffset, |
5360 bitmap->bitmapImage()->copyToTexture(drawingBuffer()->contextProvider(), | 5284 GLint yoffset, |
5361 targetTexture, targetInternalformat, | 5285 const IntRect& sourceSubRectangle) { |
5362 targetType, flipY); | 5286 bitmap->bitmapImage()->copyToTexture( |
| 5287 drawingBuffer()->contextProvider(), target, targetTexture, flipY, |
| 5288 IntPoint(xoffset, yoffset), sourceSubRectangle); |
5363 } | 5289 } |
5364 | 5290 |
5365 void WebGLRenderingContextBase::texImage2D(GLenum target, | 5291 void WebGLRenderingContextBase::texImage2D(GLenum target, |
5366 GLint level, | 5292 GLint level, |
5367 GLint internalformat, | 5293 GLint internalformat, |
5368 GLenum format, | 5294 GLenum format, |
5369 GLenum type, | 5295 GLenum type, |
5370 HTMLVideoElement* video, | 5296 HTMLVideoElement* video, |
5371 ExceptionState& exceptionState) { | 5297 ExceptionState& exceptionState) { |
5372 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, | 5298 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5414 GLsizei width = sourceSubRect.width(); | 5340 GLsizei width = sourceSubRect.width(); |
5415 GLsizei height = sourceSubRect.height(); | 5341 GLsizei height = sourceSubRect.height(); |
5416 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, level, | 5342 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, level, |
5417 internalformat, width, height, depth, 0, format, type, | 5343 internalformat, width, height, depth, 0, format, type, |
5418 xoffset, yoffset, zoffset)) | 5344 xoffset, yoffset, zoffset)) |
5419 return; | 5345 return; |
5420 ASSERT(bitmap->bitmapImage()); | 5346 ASSERT(bitmap->bitmapImage()); |
5421 | 5347 |
5422 // TODO(kbr): make this work for sub-rectangles of ImageBitmaps. | 5348 // TODO(kbr): make this work for sub-rectangles of ImageBitmaps. |
5423 if (functionID != TexSubImage3D && functionID != TexImage3D && | 5349 if (functionID != TexSubImage3D && functionID != TexImage3D && |
5424 bitmap->isAccelerated() && | 5350 bitmap->isAccelerated() && canUseTexImageByGPU(type) && |
5425 canUseTexImageByGPU(functionID, internalformat, type) && | |
5426 !selectingSubRectangle) { | 5351 !selectingSubRectangle) { |
5427 if (functionID == TexImage2D) { | 5352 if (functionID == TexImage2D) { |
5428 texImage2DBase(target, level, internalformat, width, height, 0, format, | 5353 texImage2DBase(target, level, internalformat, width, height, 0, format, |
5429 type, 0); | 5354 type, 0); |
5430 texImageByGPU(functionID, texture, target, level, internalformat, type, 0, | 5355 texImageByGPU(functionID, texture, target, level, 0, 0, 0, bitmap, |
5431 0, 0, bitmap, sourceSubRect); | 5356 sourceSubRect); |
5432 } else if (functionID == TexSubImage2D) { | 5357 } else if (functionID == TexSubImage2D) { |
5433 texImageByGPU(functionID, texture, target, level, GL_RGBA, type, xoffset, | 5358 texImageByGPU(functionID, texture, target, level, xoffset, yoffset, 0, |
5434 yoffset, 0, bitmap, sourceSubRect); | 5359 bitmap, sourceSubRect); |
5435 } | 5360 } |
5436 return; | 5361 return; |
5437 } | 5362 } |
5438 sk_sp<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); | 5363 sk_sp<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); |
5439 SkPixmap pixmap; | 5364 SkPixmap pixmap; |
5440 uint8_t* pixelDataPtr = nullptr; | 5365 uint8_t* pixelDataPtr = nullptr; |
5441 RefPtr<Uint8Array> pixelData; | 5366 RefPtr<Uint8Array> pixelData; |
5442 // In the case where an ImageBitmap is not texture backed, peekPixels() always | 5367 // In the case where an ImageBitmap is not texture backed, peekPixels() always |
5443 // succeed. However, when it is texture backed and !canUseTexImageByGPU, we | 5368 // succeed. However, when it is texture backed and !canUseTexImageByGPU, we |
5444 // do a GPU read back. | 5369 // do a GPU read back. |
(...skipping 2400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7845 | 7770 |
7846 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( | 7771 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( |
7847 HTMLCanvasElementOrOffscreenCanvas& result) const { | 7772 HTMLCanvasElementOrOffscreenCanvas& result) const { |
7848 if (canvas()) | 7773 if (canvas()) |
7849 result.setHTMLCanvasElement(canvas()); | 7774 result.setHTMLCanvasElement(canvas()); |
7850 else | 7775 else |
7851 result.setOffscreenCanvas(offscreenCanvas()); | 7776 result.setOffscreenCanvas(offscreenCanvas()); |
7852 } | 7777 } |
7853 | 7778 |
7854 } // namespace blink | 7779 } // namespace blink |
OLD | NEW |