| 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 |