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 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 sk_sp<SkImage> WebGLRenderingContextBase::makeImageSnapshot( | 807 sk_sp<SkImage> WebGLRenderingContextBase::makeImageSnapshot( |
808 SkImageInfo& imageInfo) { | 808 SkImageInfo& imageInfo) { |
809 drawingBuffer()->resolveAndBindForReadAndDraw(); | 809 drawingBuffer()->resolveAndBindForReadAndDraw(); |
810 gpu::gles2::GLES2Interface* gl = SharedGpuContext::gl(); | 810 gpu::gles2::GLES2Interface* gl = SharedGpuContext::gl(); |
811 | 811 |
812 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry); | 812 SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry); |
813 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget( | 813 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget( |
814 SharedGpuContext::gr(), SkBudgeted::kYes, imageInfo, 0, | 814 SharedGpuContext::gr(), SkBudgeted::kYes, imageInfo, 0, |
815 imageInfo.alphaType() == kOpaque_SkAlphaType ? nullptr | 815 imageInfo.alphaType() == kOpaque_SkAlphaType ? nullptr |
816 : &disableLCDProps); | 816 : &disableLCDProps); |
817 GLuint textureId = skia::GrBackendObjectToGrGLTextureInfo( | 817 const GrGLTextureInfo* textureInfo = skia::GrBackendObjectToGrGLTextureInfo( |
818 surface->getTextureHandle( | 818 surface->getTextureHandle(SkSurface::kDiscardWrite_TextureHandleAccess)); |
819 SkSurface::kDiscardWrite_TextureHandleAccess)) | 819 GLuint textureId = textureInfo->fID; |
820 ->fID; | 820 GLenum textureTarget = textureInfo->fTarget; |
821 | 821 |
822 drawingBuffer()->copyToPlatformTexture( | 822 drawingBuffer()->copyToPlatformTexture( |
823 gl, textureId, GL_RGBA, GL_UNSIGNED_BYTE, 0, true, false, IntPoint(0, 0), | 823 gl, textureTarget, textureId, true, false, IntPoint(0, 0), |
824 IntRect(IntPoint(0, 0), drawingBuffer()->size()), BackBuffer); | 824 IntRect(IntPoint(0, 0), drawingBuffer()->size()), BackBuffer); |
825 return surface->makeImageSnapshot(); | 825 return surface->makeImageSnapshot(); |
826 } | 826 } |
827 | 827 |
828 ImageData* WebGLRenderingContextBase::toImageData(SnapshotReason reason) { | 828 ImageData* WebGLRenderingContextBase::toImageData(SnapshotReason reason) { |
829 ImageData* imageData = nullptr; | 829 ImageData* imageData = nullptr; |
830 // TODO(ccameron): WebGL should produce sRGB images. | 830 // TODO(ccameron): WebGL should produce sRGB images. |
831 // https://crbug.com/672299 | 831 // https://crbug.com/672299 |
832 if (drawingBuffer()) { | 832 if (drawingBuffer()) { |
833 // For un-premultiplied data | 833 // For un-premultiplied data |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 GL_UNSIGNED_INT_5_9_9_9_REV, | 977 GL_UNSIGNED_INT_5_9_9_9_REV, |
978 GL_UNSIGNED_INT_24_8, | 978 GL_UNSIGNED_INT_24_8, |
979 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, | 979 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, |
980 }; | 980 }; |
981 | 981 |
982 // ES3 enums supported by TexImageSource | 982 // ES3 enums supported by TexImageSource |
983 static const GLenum kSupportedTypesTexImageSourceES3[] = { | 983 static const GLenum kSupportedTypesTexImageSourceES3[] = { |
984 GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_INT_10F_11F_11F_REV, | 984 GL_HALF_FLOAT, GL_FLOAT, GL_UNSIGNED_INT_10F_11F_11F_REV, |
985 }; | 985 }; |
986 | 986 |
987 bool isUnsignedIntegerFormat(GLenum internalformat) { | |
988 switch (internalformat) { | |
989 case GL_R8UI: | |
990 case GL_R16UI: | |
991 case GL_R32UI: | |
992 case GL_RG8UI: | |
993 case GL_RG16UI: | |
994 case GL_RG32UI: | |
995 case GL_RGB8UI: | |
996 case GL_RGB16UI: | |
997 case GL_RGB32UI: | |
998 case GL_RGBA8UI: | |
999 case GL_RGB10_A2UI: | |
1000 case GL_RGBA16UI: | |
1001 case GL_RGBA32UI: | |
1002 return true; | |
1003 default: | |
1004 return false; | |
1005 } | |
1006 } | |
1007 | |
1008 bool isSignedIntegerFormat(GLenum internalformat) { | |
1009 switch (internalformat) { | |
1010 case GL_R8I: | |
1011 case GL_R16I: | |
1012 case GL_R32I: | |
1013 case GL_RG8I: | |
1014 case GL_RG16I: | |
1015 case GL_RG32I: | |
1016 case GL_RGB8I: | |
1017 case GL_RGB16I: | |
1018 case GL_RGB32I: | |
1019 case GL_RGBA8I: | |
1020 case GL_RGBA16I: | |
1021 case GL_RGBA32I: | |
1022 return true; | |
1023 default: | |
1024 return false; | |
1025 } | |
1026 } | |
1027 | |
1028 bool isIntegerFormat(GLenum internalformat) { | |
1029 return (isUnsignedIntegerFormat(internalformat) || | |
1030 isSignedIntegerFormat(internalformat)); | |
1031 } | |
1032 | |
1033 bool isFloatType(GLenum type) { | |
1034 switch (type) { | |
1035 case GL_FLOAT: | |
1036 case GL_HALF_FLOAT: | |
1037 case GL_HALF_FLOAT_OES: | |
1038 case GL_UNSIGNED_INT_10F_11F_11F_REV: | |
1039 return true; | |
1040 default: | |
1041 return false; | |
1042 } | |
1043 } | |
1044 | |
1045 bool isSRGBFormat(GLenum internalformat) { | 987 bool isSRGBFormat(GLenum internalformat) { |
1046 switch (internalformat) { | 988 switch (internalformat) { |
1047 case GL_SRGB_EXT: | 989 case GL_SRGB_EXT: |
1048 case GL_SRGB_ALPHA_EXT: | 990 case GL_SRGB_ALPHA_EXT: |
1049 case GL_SRGB8: | 991 case GL_SRGB8: |
1050 case GL_SRGB8_ALPHA8: | 992 case GL_SRGB8_ALPHA8: |
1051 return true; | 993 return true; |
1052 default: | 994 default: |
1053 return false; | 995 return false; |
1054 } | 996 } |
(...skipping 3891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4946 ExceptionState& exceptionState) { | 4888 ExceptionState& exceptionState) { |
4947 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, | 4889 texImageHelperHTMLImageElement(TexImage2D, target, level, internalformat, |
4948 format, type, 0, 0, 0, image, | 4890 format, type, 0, 0, 0, image, |
4949 sentinelEmptyRect(), 1, 0, exceptionState); | 4891 sentinelEmptyRect(), 1, 0, exceptionState); |
4950 } | 4892 } |
4951 | 4893 |
4952 bool WebGLRenderingContextBase::canUseTexImageByGPU( | 4894 bool WebGLRenderingContextBase::canUseTexImageByGPU( |
4953 TexImageFunctionID functionID, | 4895 TexImageFunctionID functionID, |
4954 GLint internalformat, | 4896 GLint internalformat, |
4955 GLenum type) { | 4897 GLenum type) { |
4956 if (functionID == TexImage2D && | 4898 // SRGB format has color-space conversion issue, see |
4957 (isFloatType(type) || isIntegerFormat(internalformat) || | 4899 // https://github.com/KhronosGroup/WebGL/issues/2165. |
4958 isSRGBFormat(internalformat))) | 4900 if (isSRGBFormat(internalformat)) |
4959 return false; | 4901 return false; |
4960 // TODO(crbug.com/622958): Implement GPU-to-GPU path for WebGL 2 and more | 4902 // TODO(qiankun.miao@intel.com): revisit this after |
4961 // internal formats. | 4903 // https://github.com/KhronosGroup/WebGL/issues/2165 is resolved. Before that, |
4962 if (functionID == TexSubImage2D && | 4904 // if we can not detect internalformat in TexSubImage2D, we disable GPU path |
4963 (isWebGL2OrHigher() || extensionEnabled(OESTextureFloatName) || | 4905 // when EXT_sRGB extension is enabled. |
4964 extensionEnabled(OESTextureHalfFloatName) || | 4906 if (functionID == TexSubImage2D && extensionEnabled(EXTsRGBName)) |
4965 extensionEnabled(EXTsRGBName))) | |
4966 return false; | 4907 return false; |
| 4908 #if OS(MACOSX) |
| 4909 // RGB5_A1 is not color-renderable on NVIDIA Mac, see crbug.com/676209. |
| 4910 if (type == GL_UNSIGNED_SHORT_5_5_5_1) |
| 4911 return false; |
| 4912 #endif |
| 4913 // OES_texture_half_float doesn't support HALF_FLOAT_OES type for |
| 4914 // CopyTexImage/CopyTexSubImage. And OES_texture_half_float doesn't require |
| 4915 // HALF_FLOAT_OES type texture to be renderable. So, HALF_FLOAT_OES type |
| 4916 // texture cannot be copied to or drawn to by glCopyTextureCHROMIUM. |
| 4917 if (type == GL_HALF_FLOAT_OES) |
| 4918 return false; |
| 4919 |
4967 return true; | 4920 return true; |
4968 } | 4921 } |
4969 | 4922 |
4970 SnapshotReason WebGLRenderingContextBase::functionIDToSnapshotReason( | 4923 SnapshotReason WebGLRenderingContextBase::functionIDToSnapshotReason( |
4971 TexImageFunctionID id) { | 4924 TexImageFunctionID id) { |
4972 switch (id) { | 4925 switch (id) { |
4973 case TexImage2D: | 4926 case TexImage2D: |
4974 return SnapshotReasonWebGLTexImage2D; | 4927 return SnapshotReasonWebGLTexImage2D; |
4975 case TexSubImage2D: | 4928 case TexSubImage2D: |
4976 return SnapshotReasonWebGLTexSubImage2D; | 4929 return SnapshotReasonWebGLTexSubImage2D; |
4977 case TexImage3D: | 4930 case TexImage3D: |
4978 return SnapshotReasonWebGLTexImage3D; | 4931 return SnapshotReasonWebGLTexImage3D; |
4979 case TexSubImage3D: | 4932 case TexSubImage3D: |
4980 return SnapshotReasonWebGLTexSubImage3D; | 4933 return SnapshotReasonWebGLTexSubImage3D; |
4981 } | 4934 } |
4982 NOTREACHED(); | 4935 NOTREACHED(); |
4983 return SnapshotReasonUnknown; | 4936 return SnapshotReasonUnknown; |
4984 } | 4937 } |
4985 | 4938 |
4986 void WebGLRenderingContextBase::texImageCanvasByGPU( | 4939 void WebGLRenderingContextBase::texImageCanvasByGPU( |
4987 TexImageFunctionID functionID, | 4940 TexImageFunctionID functionID, |
4988 HTMLCanvasElement* canvas, | 4941 HTMLCanvasElement* canvas, |
| 4942 GLenum target, |
4989 GLuint targetTexture, | 4943 GLuint targetTexture, |
4990 GLenum targetInternalformat, | |
4991 GLenum targetType, | |
4992 GLint targetLevel, | |
4993 GLint xoffset, | 4944 GLint xoffset, |
4994 GLint yoffset, | 4945 GLint yoffset, |
4995 const IntRect& sourceSubRectangle) { | 4946 const IntRect& sourceSubRectangle) { |
4996 if (!canvas->is3D()) { | 4947 if (!canvas->is3D()) { |
4997 ImageBuffer* buffer = canvas->buffer(); | 4948 ImageBuffer* buffer = canvas->buffer(); |
4998 if (buffer && | 4949 if (buffer && |
4999 !buffer->copyToPlatformTexture( | 4950 !buffer->copyToPlatformTexture( |
5000 functionIDToSnapshotReason(functionID), contextGL(), targetTexture, | 4951 functionIDToSnapshotReason(functionID), contextGL(), target, |
5001 targetInternalformat, targetType, targetLevel, | 4952 targetTexture, m_unpackPremultiplyAlpha, m_unpackFlipY, |
5002 m_unpackPremultiplyAlpha, m_unpackFlipY, IntPoint(xoffset, yoffset), | 4953 IntPoint(xoffset, yoffset), sourceSubRectangle)) { |
5003 sourceSubRectangle)) { | |
5004 NOTREACHED(); | 4954 NOTREACHED(); |
5005 } | 4955 } |
5006 } else { | 4956 } else { |
5007 WebGLRenderingContextBase* gl = | 4957 WebGLRenderingContextBase* gl = |
5008 toWebGLRenderingContextBase(canvas->renderingContext()); | 4958 toWebGLRenderingContextBase(canvas->renderingContext()); |
5009 ScopedTexture2DRestorer restorer(gl); | 4959 ScopedTexture2DRestorer restorer(gl); |
5010 if (!gl->drawingBuffer()->copyToPlatformTexture( | 4960 if (!gl->drawingBuffer()->copyToPlatformTexture( |
5011 contextGL(), targetTexture, targetInternalformat, targetType, | 4961 contextGL(), target, targetTexture, m_unpackPremultiplyAlpha, |
5012 targetLevel, m_unpackPremultiplyAlpha, !m_unpackFlipY, | 4962 !m_unpackFlipY, IntPoint(xoffset, yoffset), sourceSubRectangle, |
5013 IntPoint(xoffset, yoffset), sourceSubRectangle, BackBuffer)) { | 4963 BackBuffer)) { |
5014 NOTREACHED(); | 4964 NOTREACHED(); |
5015 } | 4965 } |
5016 } | 4966 } |
5017 } | 4967 } |
5018 | 4968 |
5019 void WebGLRenderingContextBase::texImageByGPU( | 4969 void WebGLRenderingContextBase::texImageByGPU( |
5020 TexImageFunctionID functionID, | 4970 TexImageFunctionID functionID, |
5021 WebGLTexture* texture, | 4971 WebGLTexture* texture, |
5022 GLenum target, | 4972 GLenum target, |
5023 GLint level, | 4973 GLint level, |
5024 GLint internalformat, | |
5025 GLenum type, | |
5026 GLint xoffset, | 4974 GLint xoffset, |
5027 GLint yoffset, | 4975 GLint yoffset, |
5028 GLint zoffset, | 4976 GLint zoffset, |
5029 CanvasImageSource* image, | 4977 CanvasImageSource* image, |
5030 const IntRect& sourceSubRectangle) { | 4978 const IntRect& sourceSubRectangle) { |
5031 DCHECK(image->isCanvasElement() || image->isImageBitmap()); | 4979 DCHECK(image->isCanvasElement() || image->isImageBitmap()); |
5032 int width = sourceSubRectangle.width(); | 4980 int width = sourceSubRectangle.width(); |
5033 int height = sourceSubRectangle.height(); | 4981 int height = sourceSubRectangle.height(); |
5034 | 4982 |
5035 ScopedTexture2DRestorer restorer(this); | 4983 ScopedTexture2DRestorer restorer(this); |
5036 | 4984 |
5037 GLuint targetTexture = texture->object(); | 4985 GLuint targetTexture = texture->object(); |
5038 GLenum targetType = type; | |
5039 GLenum targetInternalformat = internalformat; | |
5040 GLint targetLevel = level; | |
5041 bool possibleDirectCopy = false; | 4986 bool possibleDirectCopy = false; |
5042 if (functionID == TexImage2D) { | 4987 if (functionID == TexImage2D || functionID == TexSubImage2D) { |
5043 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM( | 4988 possibleDirectCopy = Extensions3DUtil::canUseCopyTextureCHROMIUM(target); |
5044 target, internalformat, type, level); | |
5045 } | 4989 } |
5046 | 4990 |
5047 GLint copyXOffset = xoffset; | 4991 GLint copyXOffset = xoffset; |
5048 GLint copyYOffset = yoffset; | 4992 GLint copyYOffset = yoffset; |
| 4993 GLenum copyTarget = target; |
5049 | 4994 |
5050 // if direct copy is not possible, create a temporary texture and then copy | 4995 // if direct copy is not possible, create a temporary texture and then copy |
5051 // from canvas to temporary texture to target texture. | 4996 // from canvas to temporary texture to target texture. |
5052 if (!possibleDirectCopy) { | 4997 if (!possibleDirectCopy) { |
5053 targetLevel = 0; | |
5054 targetInternalformat = GL_RGBA; | |
5055 targetType = GL_UNSIGNED_BYTE; | |
5056 contextGL()->GenTextures(1, &targetTexture); | 4998 contextGL()->GenTextures(1, &targetTexture); |
5057 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); | 4999 contextGL()->BindTexture(GL_TEXTURE_2D, targetTexture); |
5058 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, | 5000 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, |
5059 GL_NEAREST); | 5001 GL_NEAREST); |
5060 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, | 5002 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, |
5061 GL_NEAREST); | 5003 GL_NEAREST); |
5062 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, | 5004 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, |
5063 GL_CLAMP_TO_EDGE); | 5005 GL_CLAMP_TO_EDGE); |
5064 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, | 5006 contextGL()->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, |
5065 GL_CLAMP_TO_EDGE); | 5007 GL_CLAMP_TO_EDGE); |
5066 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, targetInternalformat, width, | 5008 contextGL()->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, |
5067 height, 0, GL_RGBA, targetType, 0); | 5009 GL_RGBA, GL_UNSIGNED_BYTE, 0); |
5068 copyXOffset = 0; | 5010 copyXOffset = 0; |
5069 copyYOffset = 0; | 5011 copyYOffset = 0; |
| 5012 copyTarget = GL_TEXTURE_2D; |
5070 } | 5013 } |
5071 | 5014 |
5072 if (image->isCanvasElement()) { | 5015 if (image->isCanvasElement()) { |
5073 texImageCanvasByGPU(functionID, static_cast<HTMLCanvasElement*>(image), | 5016 texImageCanvasByGPU(functionID, static_cast<HTMLCanvasElement*>(image), |
5074 targetTexture, targetInternalformat, targetType, | 5017 copyTarget, targetTexture, copyXOffset, copyYOffset, |
5075 targetLevel, copyXOffset, copyYOffset, | |
5076 sourceSubRectangle); | 5018 sourceSubRectangle); |
5077 } else { | 5019 } else { |
5078 texImageBitmapByGPU(static_cast<ImageBitmap*>(image), targetTexture, | 5020 texImageBitmapByGPU(static_cast<ImageBitmap*>(image), copyTarget, |
5079 targetInternalformat, targetType, targetLevel, | 5021 targetTexture, !m_unpackFlipY, copyXOffset, copyYOffset, |
5080 !m_unpackFlipY); | 5022 sourceSubRectangle); |
5081 } | 5023 } |
5082 | 5024 |
5083 if (!possibleDirectCopy) { | 5025 if (!possibleDirectCopy) { |
5084 GLuint tmpFBO; | 5026 GLuint tmpFBO; |
5085 contextGL()->GenFramebuffers(1, &tmpFBO); | 5027 contextGL()->GenFramebuffers(1, &tmpFBO); |
5086 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO); | 5028 contextGL()->BindFramebuffer(GL_FRAMEBUFFER, tmpFBO); |
5087 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 5029 contextGL()->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
5088 GL_TEXTURE_2D, targetTexture, 0); | 5030 GL_TEXTURE_2D, targetTexture, 0); |
5089 contextGL()->BindTexture(texture->getTarget(), texture->object()); | 5031 contextGL()->BindTexture(texture->getTarget(), texture->object()); |
5090 if (functionID == TexImage2D) { | 5032 if (functionID == TexImage2D) { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5170 // The GPU-GPU copy path uses the Y-up coordinate system. | 5112 // The GPU-GPU copy path uses the Y-up coordinate system. |
5171 IntRect adjustedSourceSubRectangle = sourceSubRectangle; | 5113 IntRect adjustedSourceSubRectangle = sourceSubRectangle; |
5172 if (!m_unpackFlipY) { | 5114 if (!m_unpackFlipY) { |
5173 adjustedSourceSubRectangle.setY(canvas->height() - | 5115 adjustedSourceSubRectangle.setY(canvas->height() - |
5174 adjustedSourceSubRectangle.maxY()); | 5116 adjustedSourceSubRectangle.maxY()); |
5175 } | 5117 } |
5176 | 5118 |
5177 if (functionID == TexImage2D) { | 5119 if (functionID == TexImage2D) { |
5178 texImage2DBase(target, level, internalformat, sourceSubRectangle.width(), | 5120 texImage2DBase(target, level, internalformat, sourceSubRectangle.width(), |
5179 sourceSubRectangle.height(), 0, format, type, 0); | 5121 sourceSubRectangle.height(), 0, format, type, 0); |
5180 texImageByGPU(functionID, texture, target, level, internalformat, type, 0, | 5122 texImageByGPU(functionID, texture, target, level, 0, 0, 0, canvas, |
5181 0, 0, canvas, adjustedSourceSubRectangle); | 5123 adjustedSourceSubRectangle); |
5182 } else { | 5124 } else { |
5183 texImageByGPU(functionID, texture, target, level, GL_RGBA, type, xoffset, | 5125 texImageByGPU(functionID, texture, target, level, xoffset, yoffset, 0, |
5184 yoffset, 0, canvas, adjustedSourceSubRectangle); | 5126 canvas, adjustedSourceSubRectangle); |
5185 } | 5127 } |
5186 } else { | 5128 } else { |
5187 // 3D functions. | 5129 // 3D functions. |
5188 | 5130 |
5189 // TODO(zmo): Implement GPU-to-GPU copy path (crbug.com/612542). | 5131 // TODO(zmo): Implement GPU-to-GPU copy path (crbug.com/612542). |
5190 // Note that code will also be needed to copy to layers of 3D | 5132 // Note that code will also be needed to copy to layers of 3D |
5191 // textures, and elements of 2D texture arrays. | 5133 // textures, and elements of 2D texture arrays. |
5192 texImageImpl( | 5134 texImageImpl( |
5193 functionID, target, level, internalformat, xoffset, yoffset, zoffset, | 5135 functionID, target, level, internalformat, xoffset, yoffset, zoffset, |
5194 format, type, canvas | 5136 format, type, canvas |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5256 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, | 5198 if (!validateTexFunc(funcName, functionType, SourceHTMLVideoElement, target, |
5257 level, internalformat, video->videoWidth(), | 5199 level, internalformat, video->videoWidth(), |
5258 video->videoHeight(), 1, 0, format, type, xoffset, | 5200 video->videoHeight(), 1, 0, format, type, xoffset, |
5259 yoffset, zoffset)) | 5201 yoffset, zoffset)) |
5260 return; | 5202 return; |
5261 | 5203 |
5262 bool sourceImageRectIsDefault = | 5204 bool sourceImageRectIsDefault = |
5263 sourceImageRect == sentinelEmptyRect() || | 5205 sourceImageRect == sentinelEmptyRect() || |
5264 sourceImageRect == | 5206 sourceImageRect == |
5265 IntRect(0, 0, video->videoWidth(), video->videoHeight()); | 5207 IntRect(0, 0, video->videoWidth(), video->videoHeight()); |
| 5208 // Format of source video may be 16-bit format, e.g. Y16 format. |
| 5209 // glCopyTextureCHROMIUM will cause precision lost when uploading such video |
| 5210 // texture to half float or float texture. |
5266 if (functionID == TexImage2D && sourceImageRectIsDefault && depth == 1 && | 5211 if (functionID == TexImage2D && sourceImageRectIsDefault && depth == 1 && |
5267 GL_TEXTURE_2D == target && Extensions3DUtil::canUseCopyTextureCHROMIUM( | 5212 GL_TEXTURE_2D == target && |
5268 target, internalformat, type, level)) { | 5213 canUseTexImageByGPU(functionID, internalformat, type) && |
| 5214 (type != GL_FLOAT && type != GL_HALF_FLOAT && |
| 5215 type != GL_UNSIGNED_INT_10F_11F_11F_REV)) { |
5269 DCHECK_EQ(xoffset, 0); | 5216 DCHECK_EQ(xoffset, 0); |
5270 DCHECK_EQ(yoffset, 0); | 5217 DCHECK_EQ(yoffset, 0); |
5271 DCHECK_EQ(zoffset, 0); | 5218 DCHECK_EQ(zoffset, 0); |
5272 // Go through the fast path doing a GPU-GPU textures copy without a readback | 5219 // Go through the fast path doing a GPU-GPU textures copy without a readback |
5273 // to system memory if possible. Otherwise, it will fall back to the normal | 5220 // to system memory if possible. Otherwise, it will fall back to the normal |
5274 // SW path. | 5221 // SW path. |
5275 | 5222 |
5276 // Note that neither | 5223 // Note that neither |
5277 // HTMLVideoElement::copyVideoTextureToPlatformTexture nor | 5224 // HTMLVideoElement::copyVideoTextureToPlatformTexture nor |
5278 // ImageBuffer::copyToPlatformTexture allocate the destination texture | 5225 // ImageBuffer::copyToPlatformTexture allocate the destination texture |
(...skipping 21 matching lines...) Expand all Loading... |
5300 // implementation to do any necessary color space conversion on the GPU | 5247 // implementation to do any necessary color space conversion on the GPU |
5301 // (though it may still do a CPU conversion and upload the results). | 5248 // (though it may still do a CPU conversion and upload the results). |
5302 video->paintCurrentFrame( | 5249 video->paintCurrentFrame( |
5303 imageBuffer->canvas(), | 5250 imageBuffer->canvas(), |
5304 IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr); | 5251 IntRect(0, 0, video->videoWidth(), video->videoHeight()), nullptr); |
5305 | 5252 |
5306 // This is a straight GPU-GPU copy, any necessary color space conversion | 5253 // This is a straight GPU-GPU copy, any necessary color space conversion |
5307 // was handled in the paintCurrentFrameInContext() call. | 5254 // was handled in the paintCurrentFrameInContext() call. |
5308 | 5255 |
5309 if (imageBuffer->copyToPlatformTexture( | 5256 if (imageBuffer->copyToPlatformTexture( |
5310 functionIDToSnapshotReason(functionID), contextGL(), | 5257 functionIDToSnapshotReason(functionID), contextGL(), target, |
5311 texture->object(), internalformat, type, level, | 5258 texture->object(), m_unpackPremultiplyAlpha, m_unpackFlipY, |
5312 m_unpackPremultiplyAlpha, m_unpackFlipY, IntPoint(0, 0), | 5259 IntPoint(0, 0), |
5313 IntRect(0, 0, video->videoWidth(), video->videoHeight()))) { | 5260 IntRect(0, 0, video->videoWidth(), video->videoHeight()))) { |
5314 return; | 5261 return; |
5315 } | 5262 } |
5316 } | 5263 } |
5317 } | 5264 } |
5318 } | 5265 } |
5319 | 5266 |
5320 if (sourceImageRectIsDefault) { | 5267 if (sourceImageRectIsDefault) { |
5321 // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It | 5268 // Try using optimized CPU-GPU path for some formats: e.g. Y16 and Y8. It |
5322 // leaves early for other formats or if frame is stored on GPU. | 5269 // leaves early for other formats or if frame is stored on GPU. |
(...skipping 11 matching lines...) Expand all Loading... |
5334 RefPtr<Image> image = videoFrameToImage(video); | 5281 RefPtr<Image> image = videoFrameToImage(video); |
5335 if (!image) | 5282 if (!image) |
5336 return; | 5283 return; |
5337 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, | 5284 texImageImpl(functionID, target, level, internalformat, xoffset, yoffset, |
5338 zoffset, format, type, image.get(), | 5285 zoffset, format, type, image.get(), |
5339 WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, | 5286 WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, |
5340 m_unpackPremultiplyAlpha, sourceImageRect, depth, | 5287 m_unpackPremultiplyAlpha, sourceImageRect, depth, |
5341 unpackImageHeight); | 5288 unpackImageHeight); |
5342 } | 5289 } |
5343 | 5290 |
5344 void WebGLRenderingContextBase::texImageBitmapByGPU(ImageBitmap* bitmap, | 5291 void WebGLRenderingContextBase::texImageBitmapByGPU( |
5345 GLuint targetTexture, | 5292 ImageBitmap* bitmap, |
5346 GLenum targetInternalformat, | 5293 GLenum target, |
5347 GLenum targetType, | 5294 GLuint targetTexture, |
5348 GLint targetLevel, | 5295 bool flipY, |
5349 bool flipY) { | 5296 GLint xoffset, |
5350 bitmap->bitmapImage()->copyToTexture(drawingBuffer()->contextProvider(), | 5297 GLint yoffset, |
5351 targetTexture, targetInternalformat, | 5298 const IntRect& sourceSubRectangle) { |
5352 targetType, flipY); | 5299 bitmap->bitmapImage()->copyToTexture( |
| 5300 drawingBuffer()->contextProvider(), target, targetTexture, flipY, |
| 5301 IntPoint(xoffset, yoffset), sourceSubRectangle); |
5353 } | 5302 } |
5354 | 5303 |
5355 void WebGLRenderingContextBase::texImage2D(GLenum target, | 5304 void WebGLRenderingContextBase::texImage2D(GLenum target, |
5356 GLint level, | 5305 GLint level, |
5357 GLint internalformat, | 5306 GLint internalformat, |
5358 GLenum format, | 5307 GLenum format, |
5359 GLenum type, | 5308 GLenum type, |
5360 HTMLVideoElement* video, | 5309 HTMLVideoElement* video, |
5361 ExceptionState& exceptionState) { | 5310 ExceptionState& exceptionState) { |
5362 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, | 5311 texImageHelperHTMLVideoElement(TexImage2D, target, level, internalformat, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5410 ASSERT(bitmap->bitmapImage()); | 5359 ASSERT(bitmap->bitmapImage()); |
5411 | 5360 |
5412 // TODO(kbr): make this work for sub-rectangles of ImageBitmaps. | 5361 // TODO(kbr): make this work for sub-rectangles of ImageBitmaps. |
5413 if (functionID != TexSubImage3D && functionID != TexImage3D && | 5362 if (functionID != TexSubImage3D && functionID != TexImage3D && |
5414 bitmap->isAccelerated() && | 5363 bitmap->isAccelerated() && |
5415 canUseTexImageByGPU(functionID, internalformat, type) && | 5364 canUseTexImageByGPU(functionID, internalformat, type) && |
5416 !selectingSubRectangle) { | 5365 !selectingSubRectangle) { |
5417 if (functionID == TexImage2D) { | 5366 if (functionID == TexImage2D) { |
5418 texImage2DBase(target, level, internalformat, width, height, 0, format, | 5367 texImage2DBase(target, level, internalformat, width, height, 0, format, |
5419 type, 0); | 5368 type, 0); |
5420 texImageByGPU(functionID, texture, target, level, internalformat, type, 0, | 5369 texImageByGPU(functionID, texture, target, level, 0, 0, 0, bitmap, |
5421 0, 0, bitmap, sourceSubRect); | 5370 sourceSubRect); |
5422 } else if (functionID == TexSubImage2D) { | 5371 } else if (functionID == TexSubImage2D) { |
5423 texImageByGPU(functionID, texture, target, level, GL_RGBA, type, xoffset, | 5372 texImageByGPU(functionID, texture, target, level, xoffset, yoffset, 0, |
5424 yoffset, 0, bitmap, sourceSubRect); | 5373 bitmap, sourceSubRect); |
5425 } | 5374 } |
5426 return; | 5375 return; |
5427 } | 5376 } |
5428 sk_sp<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); | 5377 sk_sp<SkImage> skImage = bitmap->bitmapImage()->imageForCurrentFrame(); |
5429 SkPixmap pixmap; | 5378 SkPixmap pixmap; |
5430 uint8_t* pixelDataPtr = nullptr; | 5379 uint8_t* pixelDataPtr = nullptr; |
5431 RefPtr<Uint8Array> pixelData; | 5380 RefPtr<Uint8Array> pixelData; |
5432 // In the case where an ImageBitmap is not texture backed, peekPixels() always | 5381 // In the case where an ImageBitmap is not texture backed, peekPixels() always |
5433 // succeed. However, when it is texture backed and !canUseTexImageByGPU, we | 5382 // succeed. However, when it is texture backed and !canUseTexImageByGPU, we |
5434 // do a GPU read back. | 5383 // do a GPU read back. |
(...skipping 2400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7835 | 7784 |
7836 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( | 7785 void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas( |
7837 HTMLCanvasElementOrOffscreenCanvas& result) const { | 7786 HTMLCanvasElementOrOffscreenCanvas& result) const { |
7838 if (canvas()) | 7787 if (canvas()) |
7839 result.setHTMLCanvasElement(canvas()); | 7788 result.setHTMLCanvasElement(canvas()); |
7840 else | 7789 else |
7841 result.setOffscreenCanvas(offscreenCanvas()); | 7790 result.setOffscreenCanvas(offscreenCanvas()); |
7842 } | 7791 } |
7843 | 7792 |
7844 } // namespace blink | 7793 } // namespace blink |
OLD | NEW |