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 // Though, glCopyTextureCHROMIUM can handle RGB5_A1 internalformat by doing a |
4966 if (functionID == TexImage2D && | 4896 // fallback path, but it doesn't know the type info. So, we still cannot do |
Zhenyao Mo
2017/03/31 21:12:59
Maybe I miss something, but in command buffer side
qiankun
2017/04/05 08:43:16
We can detect the type info as you said. The fallb
| |
4967 (isFloatType(type) || isIntegerFormat(internalformat) || | 4897 // the fallback path in glCopyTextureCHROMIUM for |
4968 isSRGBFormat(internalformat))) | 4898 // RGBA/RGBA/UNSIGNED_SHORT_5_5_5_1 format and type combination. |
4899 if (type == GL_UNSIGNED_SHORT_5_5_5_1) | |
4969 return false; | 4900 return false; |
4970 // TODO(crbug.com/622958): Implement GPU-to-GPU path for WebGL 2 and more | 4901 #endif |
4971 // internal formats. | 4902 // OES_texture_half_float doesn't support HALF_FLOAT_OES type for |
4972 if (functionID == TexSubImage2D && | 4903 // CopyTexImage/CopyTexSubImage. And OES_texture_half_float doesn't require |
4973 (isWebGL2OrHigher() || extensionEnabled(OESTextureFloatName) || | 4904 // HALF_FLOAT_OES type texture to be renderable. So, HALF_FLOAT_OES type |
4974 extensionEnabled(OESTextureHalfFloatName) || | 4905 // texture cannot be copied to or drawn to by glCopyTextureCHROMIUM. |
4975 extensionEnabled(EXTsRGBName))) | 4906 if (type == GL_HALF_FLOAT_OES) |
Zhenyao Mo
2017/03/31 21:12:59
Is this the right place for this? Because in most
qiankun
2017/04/05 08:43:15
This is used to skip gpu path for RGBA/RGBA/HALF_F
| |
4976 return false; | 4907 return false; |
4908 | |
4977 return true; | 4909 return true; |
4978 } | 4910 } |
4979 | 4911 |
4980 SnapshotReason WebGLRenderingContextBase::functionIDToSnapshotReason( | 4912 SnapshotReason WebGLRenderingContextBase::functionIDToSnapshotReason( |
4981 TexImageFunctionID id) { | 4913 TexImageFunctionID id) { |
4982 switch (id) { | 4914 switch (id) { |
4983 case TexImage2D: | 4915 case TexImage2D: |
4984 return SnapshotReasonWebGLTexImage2D; | 4916 return SnapshotReasonWebGLTexImage2D; |
4985 case TexSubImage2D: | 4917 case TexSubImage2D: |
4986 return SnapshotReasonWebGLTexSubImage2D; | 4918 return SnapshotReasonWebGLTexSubImage2D; |
4987 case TexImage3D: | 4919 case TexImage3D: |
4988 return SnapshotReasonWebGLTexImage3D; | 4920 return SnapshotReasonWebGLTexImage3D; |
4989 case TexSubImage3D: | 4921 case TexSubImage3D: |
4990 return SnapshotReasonWebGLTexSubImage3D; | 4922 return SnapshotReasonWebGLTexSubImage3D; |
4991 } | 4923 } |
4992 NOTREACHED(); | 4924 NOTREACHED(); |
4993 return SnapshotReasonUnknown; | 4925 return SnapshotReasonUnknown; |
4994 } | 4926 } |
4995 | 4927 |
4996 void WebGLRenderingContextBase::texImageCanvasByGPU( | 4928 void WebGLRenderingContextBase::texImageCanvasByGPU( |
4997 TexImageFunctionID functionID, | 4929 TexImageFunctionID functionID, |
4998 HTMLCanvasElement* canvas, | 4930 HTMLCanvasElement* canvas, |
4931 GLenum target, | |
4999 GLuint targetTexture, | 4932 GLuint targetTexture, |
5000 GLenum targetInternalformat, | |
5001 GLenum targetType, | |
5002 GLint targetLevel, | |
5003 GLint xoffset, | 4933 GLint xoffset, |
5004 GLint yoffset, | 4934 GLint yoffset, |
5005 const IntRect& sourceSubRectangle) { | 4935 const IntRect& sourceSubRectangle) { |
5006 if (!canvas->is3D()) { | 4936 if (!canvas->is3D()) { |
5007 ImageBuffer* buffer = canvas->buffer(); | 4937 ImageBuffer* buffer = canvas->buffer(); |
5008 if (buffer && | 4938 if (buffer && |
5009 !buffer->copyToPlatformTexture( | 4939 !buffer->copyToPlatformTexture( |
5010 functionIDToSnapshotReason(functionID), contextGL(), targetTexture, | 4940 functionIDToSnapshotReason(functionID), contextGL(), target, |
5011 targetInternalformat, targetType, targetLevel, | 4941 targetTexture, m_unpackPremultiplyAlpha, m_unpackFlipY, |
5012 m_unpackPremultiplyAlpha, m_unpackFlipY, IntPoint(xoffset, yoffset), | 4942 IntPoint(xoffset, yoffset), sourceSubRectangle)) { |
5013 sourceSubRectangle)) { | |
5014 NOTREACHED(); | 4943 NOTREACHED(); |
5015 } | 4944 } |
5016 } else { | 4945 } else { |
5017 WebGLRenderingContextBase* gl = | 4946 WebGLRenderingContextBase* gl = |
5018 toWebGLRenderingContextBase(canvas->renderingContext()); | 4947 toWebGLRenderingContextBase(canvas->renderingContext()); |
5019 ScopedTexture2DRestorer restorer(gl); | 4948 ScopedTexture2DRestorer restorer(gl); |
5020 if (!gl->drawingBuffer()->copyToPlatformTexture( | 4949 if (!gl->drawingBuffer()->copyToPlatformTexture( |
5021 contextGL(), targetTexture, targetInternalformat, targetType, | 4950 contextGL(), target, targetTexture, m_unpackPremultiplyAlpha, |
5022 targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, | 4951 !m_unpackFlipY, IntPoint(xoffset, yoffset), sourceSubRectangle, |
5023 IntPoint(xoffset, yoffset), sourceSubRectangle, BackBuffer)) { | 4952 BackBuffer)) { |
5024 NOTREACHED(); | 4953 NOTREACHED(); |
5025 } | 4954 } |
5026 } | 4955 } |
5027 } | 4956 } |
5028 | 4957 |
5029 void WebGLRenderingContextBase::texImageByGPU( | 4958 void WebGLRenderingContextBase::texImageByGPU( |
5030 TexImageFunctionID functionID, | 4959 TexImageFunctionID functionID, |
5031 WebGLTexture* texture, | 4960 WebGLTexture* texture, |
5032 GLenum target, | 4961 GLenum target, |
5033 GLint level, | 4962 GLint level, |
5034 GLint internalformat, | |
5035 GLenum type, | |
5036 GLint xoffset, | 4963 GLint xoffset, |
5037 GLint yoffset, | 4964 GLint yoffset, |
5038 GLint zoffset, | 4965 GLint zoffset, |
5039 CanvasImageSource* image, | 4966 CanvasImageSource* image, |
5040 const IntRect& sourceSubRectangle) { | 4967 const IntRect& sourceSubRectangle) { |
5041 DCHECK(image->isCanvasElement() || image->isImageBitmap()); | 4968 DCHECK(image->isCanvasElement() || image->isImageBitmap()); |
5042 int width = sourceSubRectangle.width(); | 4969 int width = sourceSubRectangle.width(); |
5043 int height = sourceSubRectangle.height(); | 4970 int height = sourceSubRectangle.height(); |
5044 | 4971 |
5045 ScopedTexture2DRestorer restorer(this); | 4972 ScopedTexture2DRestorer restorer(this); |
5046 | 4973 |
5047 GLuint targetTexture = texture->object(); | 4974 GLuint targetTexture = texture->object(); |
5048 GLenum targetType = type; | |
5049 GLenum targetInternalformat = internalformat; | |
5050 GLint targetLevel = level; | |
5051 bool possibleDirectCopy = false; | 4975 bool possibleDirectCopy = false; |
5052 if (functionID == TexImage2D) { | 4976 if (functionID == TexImage2D || functionID == TexSubImage2D) { |
5053 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM( | 4977 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target); |
5054 target, internalformat, type, level); | |
5055 } | 4978 } |
5056 | 4979 |
5057 GLint copyXOffset = xoffset; | 4980 GLint copyXOffset = xoffset; |
5058 GLint copyYOffset = yoffset; | 4981 GLint copyYOffset = yoffset; |
4982 GLenum copyTarget = target; | |
5059 | 4983 |
5060 // if direct copy is not possible, create a temporary texture and then copy | 4984 // if direct copy is not possible, create a temporary texture and then copy |
5061 // from canvas to temporary texture to target texture. | 4985 // from canvas to temporary texture to target texture. |
5062 if (!possibleDirectCopy) { | 4986 if (!possibleDirectCopy) { |
5063 targetLevel = 0; | |
5064 targetInternalformat = GL_RGBA; | |
5065 targetType = GL_UNSIGNED_BYTE; | |
5066 contextGL()->GenTextures(1, &targetTexture); | 4987 contextGL()->GenTextures(1, &targetTexture); |
5067 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); | 4988 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); |
5068 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, | 4989 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, |
5069 GL_NEAREST); | 4990 GL_NEAREST); |
5070 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, | 4991 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, |
5071 GL_NEAREST); | 4992 GL_NEAREST); |
5072 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, | 4993 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, |
5073 GL_CLAMP_TO_EDGE); | 4994 GL_CLAMP_TO_EDGE); |
5074 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, | 4995 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, |
5075 GL_CLAMP_TO_EDGE); | 4996 GL_CLAMP_TO_EDGE); |
5076 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, width, | 4997 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, |
5077 height, 0, GL_RGBA, targetType, 0); | 4998 GL_RGBA, GL_UNSIGNED_BYTE, 0); |
5078 copyXOffset = 0; | 4999 copyXOffset = 0; |
5079 copyYOffset = 0; | 5000 copyYOffset = 0; |
5001 copyTarget = GL_TEXTURE_2D; | |
5080 } | 5002 } |
5081 | 5003 |
5082 if (image->isCanvasElement()) { | 5004 { |
5083 texImageCanvasByGPU(functionID, static_cast<HTMLCanvasElement*>(image), | 5005 // glCopyTextureCHROMIUM has a DRAW_AND_READBACK path which will call |
5084 targetTexture, targetInternalformat, targetType, | 5006 // texImage2D. So, reset unpack buffer parameters before that. |
5085 targetLevel, copyXOffset, copyYOffset, | 5007 ScopedUnpackParametersResetRestore temporaryResetUnpack(this); |
5086 sourceSubRectangle); | 5008 if (image->isCanvasElement()) { |
5087 } else { | 5009 texImageCanvasByGPU(functionID, static_cast<HTMLCanvasElement*>(image), |
5088 texImageBitmapByGPU(static_cast<ImageBitmap*>(image), targetTexture, | 5010 copyTarget, targetTexture, copyXOffset, copyYOffset, |
5089 targetInternalformat, targetType, targetLevel, | 5011 sourceSubRectangle); |
5090 !m_unpackFlipY); | 5012 } else { |
5013 texImageBitmapByGPU(static_cast<ImageBitmap*>(image), copyTarget, | |
5014 targetTexture, !m_unpackFlipY, copyXOffset, | |
5015 copyYOffset, sourceSubRectangle); | |
5016 } | |
5091 } | 5017 } |
5092 | 5018 |
5093 if (!possibleDirectCopy) { | 5019 if (!possibleDirectCopy) { |
5094 GLuint tmpFBO; | 5020 GLuint tmpFBO; |
5095 contextGL()->GenFramebuffers(1, &tmpFBO); | 5021 contextGL()->GenFramebuffers(1, &tmpFBO); |
5096 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO); | 5022 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO); |
5097 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 5023 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
5098 GL_TEXTURE_2D, targetTexture, 0); | 5024 GL_TEXTURE_2D, targetTexture, 0); |
5099 contextGL()->BindTexture(texture->getTarget(), texture->object()); | 5025 contextGL()->BindTexture(texture->getTarget(), texture->object()); |
5100 if (functionID == TexImage2D) { | 5026 if (functionID == TexImage2D) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5157 return; | 5083 return; |
5158 } | 5084 } |
5159 | 5085 |
5160 if (functionID == TexImage2D || functionID == TexSubImage2D) { | 5086 if (functionID == TexImage2D || functionID == TexSubImage2D) { |
5161 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support | 5087 // texImageByGPU relies on copyTextureCHROMIUM which doesn't support |
5162 // float/integer/sRGB internal format. | 5088 // float/integer/sRGB internal format. |
5163 // TODO(crbug.com/622958): relax the constrains if copyTextureCHROMIUM is | 5089 // TODO(crbug.com/622958): relax the constrains if copyTextureCHROMIUM is |
5164 // upgraded to handle more formats. | 5090 // upgraded to handle more formats. |
5165 if (!canvas->renderingContext() || | 5091 if (!canvas->renderingContext() || |
5166 !canvas->renderingContext()->isAccelerated() || | 5092 !canvas->renderingContext()->isAccelerated() || |
5167 !canUseTexImageByGPU(functionID, internalformat, type)) { | 5093 !canUseTexImageByGPU(type)) { |
5168 // 2D canvas has only FrontBuffer. | 5094 // 2D canvas has only FrontBuffer. |
5169 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, | 5095 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, |
5170 zoffset, format, type, | 5096 zoffset, format, type, |
5171 canvas | 5097 canvas |
5172 ->copiedImage(FrontBuffer, PreferAcceleration, | 5098 ->copiedImage(FrontBuffer, PreferAcceleration, |
5173 functionIDToSnapshotReason(functionID)) | 5099 functionIDToSnapshotReason(functionID)) |
5174 .get(), | 5100 .get(), |
5175 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, | 5101 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, |
5176 m_unpackPremultiplyAlpha, sourceSubRectangle, 1, 0); | 5102 m_unpackPremultiplyAlpha, sourceSubRectangle, 1, 0); |
5177 return; | 5103 return; |
5178 } | 5104 } |
5179 | 5105 |
5180 // The GPU-GPU copy path uses the Y-up coordinate system. | 5106 // The GPU-GPU copy path uses the Y-up coordinate system. |
5181 IntRect adjustedSourceSubRectangle = sourceSubRectangle; | 5107 IntRect adjustedSourceSubRectangle = sourceSubRectangle; |
5182 if (!m_unpackFlipY) { | 5108 if (!m_unpackFlipY) { |
5183 adjustedSourceSubRectangle.setY(canvas->height() - | 5109 adjustedSourceSubRectangle.setY(canvas->height() - |
5184 adjustedSourceSubRectangle.maxY()); | 5110 adjustedSourceSubRectangle.maxY()); |
5185 } | 5111 } |
5186 | 5112 |
5187 if (functionID == TexImage2D) { | 5113 if (functionID == TexImage2D) { |
5188 texImage2DBase(target, level, internalformat, sourceSubRectangle.width(), | 5114 texImage2DBase(target, level, internalformat, sourceSubRectangle.width(), |
5189 sourceSubRectangle.height(), 0, format, type, 0); | 5115 sourceSubRectangle.height(), 0, format, type, 0); |
5190 texImageByGPU(functionID, texture, target, level, internalformat, type, 0, | 5116 texImageByGPU(functionID, texture, target, level, 0, 0, 0, canvas, |
5191 0, 0, canvas, adjustedSourceSubRectangle); | 5117 adjustedSourceSubRectangle); |
5192 } else { | 5118 } else { |
5193 texImageByGPU(functionID, texture, target, level, GL_RGBA, type, xoffset, | 5119 texImageByGPU(functionID, texture, target, level, xoffset, yoffset, 0, |
5194 yoffset, 0, canvas, adjustedSourceSubRectangle); | 5120 canvas, adjustedSourceSubRectangle); |
5195 } | 5121 } |
5196 } else { | 5122 } else { |
5197 // 3D functions. | 5123 // 3D functions. |
5198 | 5124 |
5199 // TODO(zmo): Implement GPU-to-GPU copy path (crbug.com/612542). | 5125 // 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 | 5126 // Note that code will also be needed to copy to layers of 3D |
5201 // textures, and elements of 2D texture arrays. | 5127 // textures, and elements of 2D texture arrays. |
5202 texImageImpl( | 5128 texImageImpl( |
5203 functionID, target, level, internalformat, xoffset, yoffset, zoffset, | 5129 functionID, target, level, internalformat, xoffset, yoffset, zoffset, |
5204 format, type, canvas | 5130 format, type, canvas |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5266 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, | 5192 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, |
5267 level, internalformat, video->videoWidth(), | 5193 level, internalformat, video->videoWidth(), |
5268 video->videoHeight(), 1, 0, format, type, xoffset, | 5194 video->videoHeight(), 1, 0, format, type, xoffset, |
5269 yoffset, zoffset)) | 5195 yoffset, zoffset)) |
5270 return; | 5196 return; |
5271 | 5197 |
5272 bool sourceImageRectIsDefault = | 5198 bool sourceImageRectIsDefault = |
5273 sourceImageRect == sentinelEmptyRect() || | 5199 sourceImageRect == sentinelEmptyRect() || |
5274 sourceImageRect == | 5200 sourceImageRect == |
5275 IntRect(0, 0, video->videoWidth(), video->videoHeight()); | 5201 IntRect(0, 0, video->videoWidth(), video->videoHeight()); |
5276 if (functionID == TexImage2D && sourceImageRectIsDefault && depth == 1 && | 5202 const bool useCopyTextureCHROMIUM = |
5277 GL_TEXTURE_2D == target && Extensions3DUtil::canUseCopyTextureCHROMIUM( | 5203 functionID == TexImage2D && sourceImageRectIsDefault && depth == 1 && |
5278 target, internalformat, type, level)) { | 5204 GL_TEXTURE_2D == target && canUseTexImageByGPU(type); |
5205 // Format of source video may be 16-bit format, e.g. Y16 format. | |
5206 // glCopyTextureCHROMIUM requires the source texture to be in 8-bit format. | |
5207 // Converting 16-bits formated source texture to 8-bits formated texture will | |
5208 // cause precision lost. So, uploading such video texture to half float or | |
5209 // float texture can not use GPU-GPU path. | |
5210 if (useCopyTextureCHROMIUM) { | |
5279 DCHECK_EQ(xoffset, 0); | 5211 DCHECK_EQ(xoffset, 0); |
5280 DCHECK_EQ(yoffset, 0); | 5212 DCHECK_EQ(yoffset, 0); |
5281 DCHECK_EQ(zoffset, 0); | 5213 DCHECK_EQ(zoffset, 0); |
5282 // Go through the fast path doing a GPU-GPU textures copy without a readback | 5214 // 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 | 5215 // to system memory if possible. Otherwise, it will fall back to the normal |
5284 // SW path. | 5216 // SW path. |
5285 | 5217 |
5286 // Note that neither | 5218 // Note that neither |
5287 // HTMLVideoElement::copyVideoTextureToPlatformTexture nor | 5219 // HTMLVideoElement::copyVideoTextureToPlatformTexture nor |
5288 // ImageBuffer::copyToPlatformTexture allocate the destination texture | 5220 // ImageBuffer::copyToPlatformTexture allocate the destination texture |
5289 // any more. | 5221 // any more. |
5290 texImage2DBase(target, level, internalformat, video->videoWidth(), | 5222 texImage2DBase(target, level, internalformat, video->videoWidth(), |
5291 video->videoHeight(), 0, format, type, nullptr); | 5223 video->videoHeight(), 0, format, type, nullptr); |
5292 | 5224 |
5293 if (video->copyVideoTextureToPlatformTexture(contextGL(), texture->object(), | 5225 if (video->copyVideoTextureToPlatformTexture(contextGL(), texture->object(), |
5294 m_unpackPremultiplyAlpha, | 5226 m_unpackPremultiplyAlpha, |
5295 m_unpackFlipY)) { | 5227 m_unpackFlipY)) { |
5296 texture->updateLastUploadedVideo(video->webMediaPlayer()); | 5228 texture->updateLastUploadedVideo(video->webMediaPlayer()); |
5297 return; | 5229 return; |
5298 } | 5230 } |
5231 } | |
5299 | 5232 |
5233 if (sourceImageRectIsDefault) { | |
5234 // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It | |
5235 // leaves early for other formats or if frame is stored on GPU. | |
5236 ScopedUnpackParametersResetRestore( | |
5237 this, m_unpackFlipY || m_unpackPremultiplyAlpha); | |
5238 if (video->texImageImpl( | |
5239 static_cast<WebMediaPlayer::TexImageFunctionID>(functionID), target, | |
5240 contextGL(), level, convertTexInternalFormat(internalformat, type), | |
5241 format, type, xoffset, yoffset, zoffset, m_unpackFlipY, | |
5242 m_unpackPremultiplyAlpha && | |
5243 m_unpackColorspaceConversion == GL_NONE)) { | |
5244 texture->updateLastUploadedVideo(video->webMediaPlayer()); | |
5245 return; | |
5246 } | |
5247 } | |
5248 | |
5249 if (useCopyTextureCHROMIUM) { | |
5300 // Try using an accelerated image buffer, this allows YUV conversion to be | 5250 // Try using an accelerated image buffer, this allows YUV conversion to be |
5301 // done on the GPU. | 5251 // done on the GPU. |
5302 std::unique_ptr<ImageBufferSurface> surface = | 5252 std::unique_ptr<ImageBufferSurface> surface = |
5303 WTF::wrapUnique(new AcceleratedImageBufferSurface( | 5253 WTF::wrapUnique(new AcceleratedImageBufferSurface( |
5304 IntSize(video->videoWidth(), video->videoHeight()))); | 5254 IntSize(video->videoWidth(), video->videoHeight()))); |
5305 if (surface->isValid()) { | 5255 if (surface->isValid()) { |
5306 std::unique_ptr<ImageBuffer> imageBuffer( | 5256 std::unique_ptr<ImageBuffer> imageBuffer( |
5307 ImageBuffer::create(std::move(surface))); | 5257 ImageBuffer::create(std::move(surface))); |
5308 if (imageBuffer) { | 5258 if (imageBuffer) { |
5309 // The video element paints an RGBA frame into our surface here. By | 5259 // The video element paints an RGBA frame into our surface here. By |
5310 // using an AcceleratedImageBufferSurface, we enable the WebMediaPlayer | 5260 // using an AcceleratedImageBufferSurface, we enable the WebMediaPlayer |
5311 // implementation to do any necessary color space conversion on the GPU | 5261 // implementation to do any necessary color space conversion on the GPU |
5312 // (though it may still do a CPU conversion and upload the results). | 5262 // (though it may still do a CPU conversion and upload the results). |
5313 video->paintCurrentFrame( | 5263 video->paintCurrentFrame( |
5314 imageBuffer->canvas(), | 5264 imageBuffer->canvas(), |
5315 IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr); | 5265 IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr); |
5316 | 5266 |
5317 // This is a straight GPU-GPU copy, any necessary color space conversion | 5267 // This is a straight GPU-GPU copy, any necessary color space conversion |
5318 // was handled in the paintCurrentFrameInContext() call. | 5268 // was handled in the paintCurrentFrameInContext() call. |
5319 | 5269 |
5320 if (imageBuffer->copyToPlatformTexture( | 5270 if (imageBuffer->copyToPlatformTexture( |
5321 functionIDToSnapshotReason(functionID), contextGL(), | 5271 functionIDToSnapshotReason(functionID), contextGL(), target, |
5322 texture->object(), internalformat, type, level, | 5272 texture->object(), m_unpackPremultiplyAlpha, m_unpackFlipY, |
5323 m_unpackPremultiplyAlpha, m_unpackFlipY, IntPoint(0, 0), | 5273 IntPoint(0, 0), |
5324 IntRect(0, 0, video->videoWidth(), video->videoHeight()))) { | 5274 IntRect(0, 0, video->videoWidth(), video->videoHeight()))) { |
5325 texture->updateLastUploadedVideo(video->webMediaPlayer()); | 5275 texture->updateLastUploadedVideo(video->webMediaPlayer()); |
5326 return; | 5276 return; |
5327 } | 5277 } |
5328 } | 5278 } |
5329 } | 5279 } |
5330 } | 5280 } |
5331 | 5281 |
5332 if (sourceImageRectIsDefault) { | |
5333 // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It | |
5334 // leaves early for other formats or if frame is stored on GPU. | |
5335 ScopedUnpackParametersResetRestore( | |
5336 this, m_unpackFlipY || m_unpackPremultiplyAlpha); | |
5337 if (video->texImageImpl( | |
5338 static_cast<WebMediaPlayer::TexImageFunctionID>(functionID), target, | |
5339 contextGL(), level, convertTexInternalFormat(internalformat, type), | |
5340 format, type, xoffset, yoffset, zoffset, m_unpackFlipY, | |
5341 m_unpackPremultiplyAlpha && | |
5342 m_unpackColorspaceConversion == GL_NONE)) { | |
5343 texture->updateLastUploadedVideo(video->webMediaPlayer()); | |
5344 return; | |
5345 } | |
5346 } | |
5347 | |
5348 RefPtr<Image> image = videoFrameToImage(video); | 5282 RefPtr<Image> image = videoFrameToImage(video); |
5349 if (!image) | 5283 if (!image) |
5350 return; | 5284 return; |
5351 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, | 5285 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, |
5352 zoffset, format, type, image.get(), | 5286 zoffset, format, type, image.get(), |
5353 WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, | 5287 WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, |
5354 m_unpackPremultiplyAlpha, sourceImageRect, depth, | 5288 m_unpackPremultiplyAlpha, sourceImageRect, depth, |
5355 unpackImageHeight); | 5289 unpackImageHeight); |
5356 texture->updateLastUploadedVideo(video->webMediaPlayer()); | 5290 texture->updateLastUploadedVideo(video->webMediaPlayer()); |
5357 } | 5291 } |
5358 | 5292 |
5359 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, | 5293 void WebGLRenderingContextBase::texImageBitmapByGPU( |
5360 GLuint targetTexture, | 5294 ImageBitmap* bitmap, |
5361 GLenum targetInternalformat, | 5295 GLenum target, |
5362 GLenum targetType, | 5296 GLuint targetTexture, |
5363 GLint targetLevel, | 5297 bool flipY, |
5364 bool flipY) { | 5298 GLint xoffset, |
5365 bitmap->bitmapImage()->copyToTexture(drawingBuffer()->contextProvider(), | 5299 GLint yoffset, |
5366 targetTexture, targetInternalformat, | 5300 const IntRect& sourceSubRectangle) { |
5367 targetType, flipY); | 5301 bitmap->bitmapImage()->copyToTexture( |
5302 drawingBuffer()->contextProvider(), target, targetTexture, flipY, | |
5303 IntPoint(xoffset, yoffset), sourceSubRectangle); | |
5368 } | 5304 } |
5369 | 5305 |
5370 void WebGLRenderingContextBase::texImage2D(GLenum target, | 5306 void WebGLRenderingContextBase::texImage2D(GLenum target, |
5371 GLint level, | 5307 GLint level, |
5372 GLint internalformat, | 5308 GLint internalformat, |
5373 GLenum format, | 5309 GLenum format, |
5374 GLenum type, | 5310 GLenum type, |
5375 HTMLVideoElement* video, | 5311 HTMLVideoElement* video, |
5376 ExceptionState& exceptionState) { | 5312 ExceptionState& exceptionState) { |
5377 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, | 5313 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5419 GLsizei width = sourceSubRect.width(); | 5355 GLsizei width = sourceSubRect.width(); |
5420 GLsizei height = sourceSubRect.height(); | 5356 GLsizei height = sourceSubRect.height(); |
5421 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, level, | 5357 if (!validateTexFunc(funcName, functionType, SourceImageBitmap, target, level, |
5422 internalformat, width, height, depth, 0, format, type, | 5358 internalformat, width, height, depth, 0, format, type, |
5423 xoffset, yoffset, zoffset)) | 5359 xoffset, yoffset, zoffset)) |
5424 return; | 5360 return; |
5425 ASSERT(bitmap->bitmapImage()); | 5361 ASSERT(bitmap->bitmapImage()); |
5426 | 5362 |
5427 // TODO(kbr): make this work for sub-rectangles of ImageBitmaps. | 5363 // TODO(kbr): make this work for sub-rectangles of ImageBitmaps. |
5428 if (functionID != TexSubImage3D && functionID != TexImage3D && | 5364 if (functionID != TexSubImage3D && functionID != TexImage3D && |
5429 bitmap->isAccelerated() && | 5365 bitmap->isAccelerated() && canUseTexImageByGPU(type) && |
5430 canUseTexImageByGPU(functionID, internalformat, type) && | |
5431 !selectingSubRectangle) { | 5366 !selectingSubRectangle) { |
5432 if (functionID == TexImage2D) { | 5367 if (functionID == TexImage2D) { |
5433 texImage2DBase(target, level, internalformat, width, height, 0, format, | 5368 texImage2DBase(target, level, internalformat, width, height, 0, format, |
5434 type, 0); | 5369 type, 0); |
5435 texImageByGPU(functionID, texture, target, level, internalformat, type, 0, | 5370 texImageByGPU(functionID, texture, target, level, 0, 0, 0, bitmap, |
5436 0, 0, bitmap, sourceSubRect); | 5371 sourceSubRect); |
5437 } else if (functionID == TexSubImage2D) { | 5372 } else if (functionID == TexSubImage2D) { |
5438 texImageByGPU(functionID, texture, target, level, GL_RGBA, type, xoffset, | 5373 texImageByGPU(functionID, texture, target, level, xoffset, yoffset, 0, |
5439 yoffset, 0, bitmap, sourceSubRect); | 5374 bitmap, sourceSubRect); |
5440 } | 5375 } |
5441 return; | 5376 return; |
5442 } | 5377 } |
5443 sk_sp<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); | 5378 sk_sp<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); |
5444 SkPixmap pixmap; | 5379 SkPixmap pixmap; |
5445 uint8_t* pixelDataPtr = nullptr; | 5380 uint8_t* pixelDataPtr = nullptr; |
5446 RefPtr<Uint8Array> pixelData; | 5381 RefPtr<Uint8Array> pixelData; |
5447 // In the case where an ImageBitmap is not texture backed, peekPixels() always | 5382 // In the case where an ImageBitmap is not texture backed, peekPixels() always |
5448 // succeed. However, when it is texture backed and !canUseTexImageByGPU, we | 5383 // succeed. However, when it is texture backed and !canUseTexImageByGPU, we |
5449 // do a GPU read back. | 5384 // do a GPU read back. |
(...skipping 2400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7850 | 7785 |
7851 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( | 7786 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( |
7852 HTMLCanvasElementOrOffscreenCanvas& result) const { | 7787 HTMLCanvasElementOrOffscreenCanvas& result) const { |
7853 if (canvas()) | 7788 if (canvas()) |
7854 result.setHTMLCanvasElement(canvas()); | 7789 result.setHTMLCanvasElement(canvas()); |
7855 else | 7790 else |
7856 result.setOffscreenCanvas(offscreenCanvas()); | 7791 result.setOffscreenCanvas(offscreenCanvas()); |
7857 } | 7792 } |
7858 | 7793 |
7859 } // namespace blink | 7794 } // namespace blink |
OLD | NEW |