Changeset 179842 in webkit
- Timestamp:
- Feb 9, 2015, 12:50:15 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 8 edited
-
ChangeLog (modified) (1 diff)
-
html/canvas/WebGL2RenderingContext.cpp (modified) (3 diffs)
-
html/canvas/WebGL2RenderingContext.h (modified) (2 diffs)
-
html/canvas/WebGLRenderingContext.cpp (modified) (4 diffs)
-
html/canvas/WebGLRenderingContext.h (modified) (1 diff)
-
html/canvas/WebGLRenderingContextBase.cpp (modified) (12 diffs)
-
html/canvas/WebGLRenderingContextBase.h (modified) (9 diffs)
-
platform/graphics/GraphicsContext3D.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r179839 r179842 1 2015-02-07 Roger Fong <roger_fong@apple.com> 2 3 WebGL 2: Texture call format, internal format, and type validation. 4 https://bugs.webkit.org/show_bug.cgi?id=141318. 5 <rdar://problem/19733828> 6 7 Reviewed by Brent Fulgham. 8 9 Tests will be covered by WebGL2 conformance tests. 10 11 * html/canvas/WebGL2RenderingContext.cpp: 12 (WebCore::WebGL2RenderingContext::getFramebufferAttachmentParameter): Add missing ExceptionCode argument. 13 (WebCore::WebGL2RenderingContext::copyTexImage2D): Validate texture formats based on GLES3 spec. 14 (WebCore::WebGL2RenderingContext::texSubImage2DBase): Validate using internal format from texture target. 15 (WebCore::WebGL2RenderingContext::texSubImage2DImpl): Validate using internal format from texture target. 16 (WebCore::WebGL2RenderingContext::texSubImage2D): Validate using internal format from texture target. 17 (WebCore::WebGL2RenderingContext::validateTexFuncParameters): Do extra validation for copyTexImage2D. 18 (WebCore::WebGL2RenderingContext::validateTexFuncFormatAndType): Validate internal format, format and type combination. 19 (WebCore::WebGL2RenderingContext::validateTexFuncData): Validate new data types. 20 This method now accepts an internal format argument. 21 (WebCore::WebGL2RenderingContext::baseInternalFormatFromInternalFormat): 22 Helper method to convert internal format to base internal format. 23 * html/canvas/WebGL2RenderingContext.h: 24 25 * html/canvas/WebGLRenderingContext.cpp: 26 (WebCore::WebGLRenderingContext::copyTexImage2D): Moved from WebGLRenderingContextBase. 27 (WebCore::WebGLRenderingContext::texSubImage2DBase): Ditto. 28 (WebCore::WebGLRenderingContext::texSubImage2DImpl): Ditto. 29 (WebCore::WebGLRenderingContext::texSubImage2D): Ditto. 30 (WebCore::WebGLRenderingContext::validateTexFuncParameters): Ditto. 31 (WebCore::WebGLRenderingContext::validateTexFuncFormatAndType): Ditto. 32 (WebCore::WebGLRenderingContext::validateTexFuncData): Ditto. 33 * html/canvas/WebGLRenderingContext.h: 34 35 * html/canvas/WebGLRenderingContextBase.cpp: 36 (WebCore::WebGLRenderingContextBase::texImage2DBase): 37 (WebCore::WebGLRenderingContextBase::validateTexFunc): 38 (WebCore::WebGLRenderingContextBase::texImage2D): 39 (WebCore::WebGLRenderingContextBase::copyTexImage2D): Deleted. 40 (WebCore::WebGLRenderingContextBase::texSubImage2DBase): Deleted. 41 (WebCore::WebGLRenderingContextBase::texSubImage2DImpl): Deleted. 42 (WebCore::WebGLRenderingContextBase::texSubImage2D): Deleted. 43 (WebCore::WebGLRenderingContextBase::validateTexFuncFormatAndType): Deleted. 44 (WebCore::WebGLRenderingContextBase::validateTexFuncParameters): Deleted. 45 (WebCore::WebGLRenderingContextBase::validateTexFuncData): Deleted. 46 * html/canvas/WebGLRenderingContextBase.h: Modify validation type enums to differentiate between CopyImage, TexImage and TexSubImage calls. 47 (WebCore::ScopedDrawingBufferBinder::ScopedDrawingBufferBinder): Moved from WebGLRenderingContextBase. 48 (WebCore::ScopedDrawingBufferBinder::~ScopedDrawingBufferBinder): Ditto. 49 (WebCore::clip1D): Ditto. 50 (WebCore::clip2D): Ditto. 51 * platform/graphics/GraphicsContext3D.h: Rename a typo'ed enum. 52 1 53 2015-02-09 Commit Queue <commit-queue@webkit.org> 2 54 -
trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp
r179530 r179842 29 29 #include "WebGL2RenderingContext.h" 30 30 31 #include "CachedImage.h" 31 32 #include "EXTTextureFilterAnisotropic.h" 32 33 #include "Extensions3D.h" 34 #include "HTMLCanvasElement.h" 35 #include "HTMLImageElement.h" 36 #include "HTMLVideoElement.h" 37 #include "ImageData.h" 33 38 #include "OESTextureFloat.h" 34 39 #include "OESTextureFloatLinear.h" 35 40 #include "OESTextureHalfFloat.h" 36 41 #include "OESTextureHalfFloatLinear.h" 42 #include "RenderBox.h" 37 43 #include "WebGLActiveInfo.h" 38 44 #include "WebGLCompressedTextureATC.h" 39 45 #include "WebGLCompressedTexturePVRTC.h" 40 46 #include "WebGLCompressedTextureS3TC.h" 47 #include "WebGLContextAttributes.h" 41 48 #include "WebGLDebugRendererInfo.h" 42 49 #include "WebGLDebugShaders.h" … … 83 90 } 84 91 85 WebGLGetInfo WebGL2RenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname )92 WebGLGetInfo WebGL2RenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode& ec) 86 93 { 87 94 UNUSED_PARAM(target); 88 95 UNUSED_PARAM(attachment); 89 96 UNUSED_PARAM(pname); 97 UNUSED_PARAM(ec); 90 98 return WebGLGetInfo(); 91 99 } … … 899 907 900 908 return result; 909 } 910 911 void WebGL2RenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) 912 { 913 if (isContextLostOrPending()) 914 return; 915 RefPtr<WebGLContextAttributes> attributes = getContextAttributes(); 916 GC3Denum bufferFormat = attributes->alpha() ? GraphicsContext3D::RGBA : GraphicsContext3D::RGB; 917 if (!validateTexFuncParameters("copyTexImage2D", CopyTexImage, target, level, internalformat, width, height, border, bufferFormat, GraphicsContext3D::UNSIGNED_BYTE)) 918 return; 919 if (!validateSettableTexFormat("copyTexImage2D", internalformat)) 920 return; 921 WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true); 922 if (!tex) 923 return; 924 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) { 925 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format"); 926 return; 927 } 928 if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) { 929 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2"); 930 return; 931 } 932 const char* reason = "framebuffer incomplete"; 933 if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) { 934 synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason); 935 return; 936 } 937 clearIfComposited(); 938 if (isResourceSafe()) { 939 ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get()); 940 m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border); 941 } else { 942 ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get()); 943 GC3Dint clippedX, clippedY; 944 GC3Dsizei clippedWidth, clippedHeight; 945 if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) { 946 m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border, 947 internalformat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment); 948 if (clippedWidth > 0 && clippedHeight > 0) { 949 m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y, 950 clippedX, clippedY, clippedWidth, clippedHeight); 951 } 952 } else 953 m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border); 954 } 955 // FIXME: if the framebuffer is not complete, none of the below should be executed. 956 tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE); 957 } 958 959 void WebGL2RenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode& ec) 960 { 961 ec = 0; 962 ASSERT(!isContextLost()); 963 if (!validateTexFuncParameters("texSubImage2D", TexSubImage, target, level, internalformat, width, height, 0, format, type)) 964 return; 965 ASSERT(validateSize("texSubImage2D", xoffset, yoffset)); 966 ASSERT(validateSettableTexFormat("texSubImage2D", format)); 967 WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true); 968 if (!tex) { 969 ASSERT_NOT_REACHED(); 970 return; 971 } 972 ASSERT((xoffset + width) >= 0); 973 ASSERT((yoffset + height) >= 0); 974 ASSERT(tex->getWidth(target, level) >= (xoffset + width)); 975 ASSERT(tex->getHeight(target, level) >= (yoffset + height)); 976 ASSERT(tex->getInternalFormat(target, level) == format); 977 ASSERT(tex->getType(target, level) == type); 978 m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); 979 } 980 981 void WebGL2RenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) 982 { 983 ec = 0; 984 Vector<uint8_t> data; 985 GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE); 986 if (!imageExtractor.extractSucceeded()) { 987 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image"); 988 return; 989 } 990 GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat(); 991 GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp(); 992 const void* imagePixelData = imageExtractor.imagePixelData(); 993 994 bool needConversion = true; 995 if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY) 996 needConversion = false; 997 else { 998 if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) { 999 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data"); 1000 return; 1001 } 1002 } 1003 1004 if (m_unpackAlignment != 1) 1005 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1); 1006 1007 WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true); 1008 GC3Denum internalformat = tex->getInternalFormat(target, level); 1009 texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), internalformat, format, type, needConversion ? data.data() : imagePixelData, ec); 1010 if (m_unpackAlignment != 1) 1011 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment); 1012 } 1013 1014 void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec) 1015 { 1016 if (isContextLostOrPending() || !validateTexFuncData("texSubImage2D", level, width, height, GraphicsContext3D::NONE, format, type, pixels, NullNotAllowed) || !validateTexFunc("texSubImage2D", TexSubImage, SourceArrayBufferView, target, level, GraphicsContext3D::NONE, width, height, 0, format, type, xoffset, yoffset)) 1017 return; 1018 1019 void* data = pixels->baseAddress(); 1020 Vector<uint8_t> tempData; 1021 bool changeUnpackAlignment = false; 1022 if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) { 1023 if (!m_context->extractTextureData(width, height, format, type, 1024 m_unpackAlignment, 1025 m_unpackFlipY, m_unpackPremultiplyAlpha, 1026 data, 1027 tempData)) 1028 return; 1029 data = tempData.data(); 1030 changeUnpackAlignment = true; 1031 } 1032 if (changeUnpackAlignment) 1033 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1); 1034 WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true); 1035 GC3Denum internalformat = tex->getInternalFormat(target, level); 1036 texSubImage2DBase(target, level, xoffset, yoffset, width, height, internalformat, format, type, data, ec); 1037 if (changeUnpackAlignment) 1038 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment); 1039 } 1040 1041 void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec) 1042 { 1043 ec = 0; 1044 if (isContextLostOrPending() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage, SourceImageData, target, level, GraphicsContext3D::NONE, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset)) 1045 return; 1046 1047 Vector<uint8_t> data; 1048 bool needConversion = true; 1049 // The data from ImageData is always of format RGBA8. 1050 // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required. 1051 if (format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha) 1052 needConversion = false; 1053 else { 1054 if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) { 1055 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image data"); 1056 return; 1057 } 1058 } 1059 if (m_unpackAlignment != 1) 1060 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1); 1061 1062 WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true); 1063 GC3Denum internalformat = tex->getInternalFormat(target, level); 1064 texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), internalformat, format, type, needConversion ? data.data() : pixels->data()->data(), ec); 1065 if (m_unpackAlignment != 1) 1066 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment); 1067 } 1068 1069 void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec) 1070 { 1071 ec = 0; 1072 if (isContextLostOrPending() || !validateHTMLImageElement("texSubImage2D", image, ec)) 1073 return; 1074 1075 RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer()); 1076 if (imageForRender->isSVGImage()) 1077 imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), 1); 1078 1079 if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLImageElement, target, level, GraphicsContext3D::NONE, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset)) 1080 return; 1081 1082 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec); 1083 } 1084 1085 void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 1086 GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec) 1087 { 1088 ec = 0; 1089 if (isContextLostOrPending() || !validateHTMLCanvasElement("texSubImage2D", canvas, ec) 1090 || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, GraphicsContext3D::NONE, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset)) 1091 return; 1092 1093 RefPtr<ImageData> imageData = canvas->getImageData(); 1094 if (imageData) 1095 texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec); 1096 else 1097 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec); 1098 } 1099 1100 #if ENABLE(VIDEO) 1101 void WebGL2RenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec) 1102 { 1103 ec = 0; 1104 if (isContextLostOrPending() || !validateHTMLVideoElement("texSubImage2D", video, ec) 1105 || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, target, level, GraphicsContext3D::NONE, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset)) 1106 return; 1107 1108 RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec); 1109 if (!image) 1110 return; 1111 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec); 1112 } 1113 #endif 1114 1115 bool WebGL2RenderingContext::validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType functionType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type) 1116 { 1117 if (functionType == CopyTexImage) { 1118 GC3Denum framebufferInternalFormat = 0; 1119 WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(GraphicsContext3D::COLOR_ATTACHMENT0); 1120 if (object->isTexture()) { 1121 WebGLTexture* texture = reinterpret_cast<WebGLTexture*>(object); 1122 framebufferInternalFormat = baseInternalFormatFromInternalFormat(texture->getInternalFormat(GraphicsContext3D::TEXTURE_2D, 0)); 1123 } else if (object->isRenderbuffer()) { 1124 WebGLRenderbuffer* renderBuffer = reinterpret_cast<WebGLRenderbuffer*>(object); 1125 framebufferInternalFormat = baseInternalFormatFromInternalFormat(renderBuffer->getInternalFormat()); 1126 } 1127 1128 GC3Denum baseTextureInternalFormat = baseInternalFormatFromInternalFormat(internalformat); 1129 bool validFormatCombination = true; 1130 switch (framebufferInternalFormat) { 1131 case GraphicsContext3D::RED: 1132 if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::RED) 1133 validFormatCombination = false; 1134 break; 1135 case GraphicsContext3D::RG: 1136 if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::RED && baseTextureInternalFormat != GraphicsContext3D::RG) 1137 validFormatCombination = false; 1138 break; 1139 case GraphicsContext3D::RGB: 1140 if (baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::RED && baseTextureInternalFormat != GraphicsContext3D::RG && baseTextureInternalFormat != GraphicsContext3D::RGB) 1141 validFormatCombination = false; 1142 break; 1143 case GraphicsContext3D::RGBA: 1144 if (baseTextureInternalFormat != GraphicsContext3D::ALPHA && baseTextureInternalFormat != GraphicsContext3D::LUMINANCE && baseTextureInternalFormat != GraphicsContext3D::LUMINANCE_ALPHA && baseTextureInternalFormat != GraphicsContext3D::RED && baseTextureInternalFormat != GraphicsContext3D::RG && baseTextureInternalFormat != GraphicsContext3D::RGB && baseTextureInternalFormat != GraphicsContext3D::RGBA) 1145 validFormatCombination = false; 1146 break; 1147 case GraphicsContext3D::DEPTH_COMPONENT: 1148 validFormatCombination = false; 1149 break; 1150 case GraphicsContext3D::DEPTH_STENCIL: 1151 validFormatCombination = false; 1152 break; 1153 } 1154 1155 if (!validFormatCombination) { 1156 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "copyTexImage: invalid combination of framebuffer and texture formats"); 1157 return false; 1158 } 1159 1160 ExceptionCode ec; 1161 bool isSRGB = (getFramebufferAttachmentParameter(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, ec).getInt() == GraphicsContext3D::SRGB); 1162 if (isSRGB != (framebufferInternalFormat == GraphicsContext3D::SRGB8 || framebufferInternalFormat == GraphicsContext3D::SRGB8_ALPHA8)) { 1163 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "framebuffer attachment color encoding and internal format do not match"); 1164 return false; 1165 } 1166 } 1167 1168 // We absolutely have to validate the format and type combination. 1169 // The texImage2D entry points taking HTMLImage, etc. will produce 1170 // temporary data based on this combination, so it must be legal. 1171 if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level) || !validateTexFuncLevel(functionName, target, level)) 1172 return false; 1173 1174 if (width < 0 || height < 0) { 1175 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0"); 1176 return false; 1177 } 1178 1179 GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level); 1180 switch (target) { 1181 case GraphicsContext3D::TEXTURE_2D: 1182 if (width > maxTextureSizeForLevel || height > maxTextureSizeForLevel) { 1183 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range"); 1184 return false; 1185 } 1186 break; 1187 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X: 1188 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X: 1189 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y: 1190 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y: 1191 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z: 1192 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z: 1193 if (functionType != TexSubImage && width != height) { 1194 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map"); 1195 return false; 1196 } 1197 // No need to check height here. For texImage width == height. 1198 // For texSubImage that will be checked when checking yoffset + height is in range. 1199 if (width > maxTextureSizeForLevel) { 1200 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range for cube map"); 1201 return false; 1202 } 1203 break; 1204 default: 1205 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target"); 1206 return false; 1207 } 1208 1209 if (border) { 1210 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0"); 1211 return false; 1212 } 1213 1214 return true; 1215 } 1216 1217 bool WebGL2RenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) 1218 { 1219 // Verify that a valid format has been provided. 1220 switch (format) { 1221 case GraphicsContext3D::ALPHA: 1222 case GraphicsContext3D::LUMINANCE: 1223 case GraphicsContext3D::LUMINANCE_ALPHA: 1224 case GraphicsContext3D::RGB: 1225 case GraphicsContext3D::RGBA: 1226 case GraphicsContext3D::RGBA_INTEGER: 1227 case GraphicsContext3D::RG: 1228 case GraphicsContext3D::RG_INTEGER: 1229 case GraphicsContext3D::RED_INTEGER: 1230 break; 1231 case GraphicsContext3D::DEPTH_STENCIL: 1232 case GraphicsContext3D::DEPTH_COMPONENT: 1233 if (m_webglDepthTexture) 1234 break; 1235 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled"); 1236 return false; 1237 default: 1238 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format"); 1239 return false; 1240 } 1241 1242 // Verify that a valid type has been provided. 1243 switch (type) { 1244 case GraphicsContext3D::UNSIGNED_BYTE: 1245 case GraphicsContext3D::BYTE: 1246 case GraphicsContext3D::UNSIGNED_SHORT: 1247 case GraphicsContext3D::SHORT: 1248 case GraphicsContext3D::UNSIGNED_INT: 1249 case GraphicsContext3D::INT: 1250 case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV: 1251 case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV: 1252 case GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV: 1253 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: 1254 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: 1255 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: 1256 break; 1257 case GraphicsContext3D::FLOAT: 1258 if (m_oesTextureFloat) 1259 break; 1260 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type"); 1261 return false; 1262 case GraphicsContext3D::HALF_FLOAT: 1263 case GraphicsContext3D::HALF_FLOAT_OES: 1264 if (m_oesTextureHalfFloat) 1265 break; 1266 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type"); 1267 return false; 1268 case GraphicsContext3D::UNSIGNED_INT_24_8: 1269 case GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV: 1270 if (isDepthStencilSupported()) 1271 break; 1272 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type"); 1273 return false; 1274 default: 1275 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type"); 1276 return false; 1277 } 1278 1279 // Veryify that a valid internal format has been provided. 1280 switch (internalformat) { 1281 case GraphicsContext3D::RGBA: 1282 case GraphicsContext3D::RGB: 1283 case GraphicsContext3D::LUMINANCE_ALPHA: 1284 case GraphicsContext3D::LUMINANCE: 1285 case GraphicsContext3D::ALPHA: 1286 case GraphicsContext3D::RGBA32I: 1287 case GraphicsContext3D::RGBA32UI: 1288 case GraphicsContext3D::RGBA16I: 1289 case GraphicsContext3D::RGBA16UI: 1290 case GraphicsContext3D::RGBA8: 1291 case GraphicsContext3D::RGBA8I: 1292 case GraphicsContext3D::RGBA8UI: 1293 case GraphicsContext3D::RGB10_A2: 1294 case GraphicsContext3D::RGB10_A2UI: 1295 case GraphicsContext3D::RGBA4: 1296 case GraphicsContext3D::RG32I: 1297 case GraphicsContext3D::RG32UI: 1298 case GraphicsContext3D::RG16I: 1299 case GraphicsContext3D::RG16UI: 1300 case GraphicsContext3D::RG8: 1301 case GraphicsContext3D::RG8I: 1302 case GraphicsContext3D::RG8UI: 1303 case GraphicsContext3D::R32I: 1304 case GraphicsContext3D::R32UI: 1305 case GraphicsContext3D::R16I: 1306 case GraphicsContext3D::R16UI: 1307 case GraphicsContext3D::R8: 1308 case GraphicsContext3D::R8I: 1309 case GraphicsContext3D::R8UI: 1310 case GraphicsContext3D::RGB5_A1: 1311 case GraphicsContext3D::RGB8: 1312 case GraphicsContext3D::RGB565: 1313 case GraphicsContext3D::RGBA32F: 1314 case GraphicsContext3D::RGBA16F: 1315 case GraphicsContext3D::RGBA8_SNORM: 1316 case GraphicsContext3D::RGB32F: 1317 case GraphicsContext3D::RGB32I: 1318 case GraphicsContext3D::RGB32UI: 1319 case GraphicsContext3D::RGB16F: 1320 case GraphicsContext3D::RGB16I: 1321 case GraphicsContext3D::RGB16UI: 1322 case GraphicsContext3D::RGB8_SNORM: 1323 case GraphicsContext3D::RGB8I: 1324 case GraphicsContext3D::RGB8UI: 1325 case GraphicsContext3D::SRGB8: 1326 case GraphicsContext3D::R11F_G11F_B10F: 1327 case GraphicsContext3D::RGB9_E5: 1328 case GraphicsContext3D::RG32F: 1329 case GraphicsContext3D::RG16F: 1330 case GraphicsContext3D::RG8_SNORM: 1331 case GraphicsContext3D::R32F: 1332 case GraphicsContext3D::R16F: 1333 case GraphicsContext3D::R8_SNORM: 1334 case GraphicsContext3D::STENCIL_INDEX8: 1335 break; 1336 case GraphicsContext3D::DEPTH_COMPONENT16: 1337 case GraphicsContext3D::DEPTH_COMPONENT32F: 1338 case GraphicsContext3D::DEPTH_COMPONENT24: 1339 if (m_webglDepthTexture) 1340 break; 1341 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled"); 1342 return false; 1343 case GraphicsContext3D::DEPTH32F_STENCIL8: 1344 case GraphicsContext3D::DEPTH24_STENCIL8: 1345 if (isDepthStencilSupported()) 1346 break; 1347 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture internal format"); 1348 return false; 1349 case GraphicsContext3D::NONE: 1350 // When calling validateTexFuncFormatAndType with internalformat == GraphicsContext3D::NONE, the intent is 1351 // only to check for whether or not the format and type are valid types, which we have already done at this point. 1352 return true; 1353 break; 1354 default: 1355 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture internal format"); 1356 return false; 1357 } 1358 1359 // Verify that the combination of format, internalformat and type is supported. 1360 switch (format) { 1361 case GraphicsContext3D::RGBA: 1362 if (type == GraphicsContext3D::UNSIGNED_BYTE 1363 && (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGBA8 || internalformat == GraphicsContext3D::RGB5_A1 || internalformat == GraphicsContext3D::RGBA4 || internalformat == GraphicsContext3D::SRGB8_ALPHA8)) 1364 break; 1365 if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGBA8_SNORM) 1366 break; 1367 if (type == GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4 1368 && (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGBA4)) 1369 break; 1370 if (type == GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1 1371 && (internalformat == GraphicsContext3D::RGBA || internalformat == GraphicsContext3D::RGB5_A1)) 1372 break; 1373 if (type == GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV 1374 && (internalformat == GraphicsContext3D::RGB10_A2 || internalformat == GraphicsContext3D::RGB5_A1)) 1375 break; 1376 if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) && internalformat == GraphicsContext3D::RGBA16F) 1377 break; 1378 if (type == GraphicsContext3D::FLOAT 1379 && (internalformat == GraphicsContext3D::RGBA32F || internalformat == GraphicsContext3D::RGBA16F)) 1380 break; 1381 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination"); 1382 return false; 1383 case GraphicsContext3D::RGBA_INTEGER: 1384 if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RGBA8UI) 1385 break; 1386 if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGBA8I) 1387 break; 1388 if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::RGBA16UI) 1389 break; 1390 if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::RGBA16I) 1391 break; 1392 if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::RGBA32UI) 1393 break; 1394 if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::RGBA32I) 1395 break; 1396 if (type == GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV && internalformat == GraphicsContext3D::RGB10_A2UI) 1397 break; 1398 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination"); 1399 return false; 1400 case GraphicsContext3D::RGB: 1401 if (type == GraphicsContext3D::UNSIGNED_BYTE 1402 && (internalformat == GraphicsContext3D::RGB || internalformat == GraphicsContext3D::RGB8 || internalformat == GraphicsContext3D::RGB565 1403 || internalformat == GraphicsContext3D::SRGB8)) 1404 break; 1405 if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGB8_SNORM) 1406 break; 1407 if (type == GraphicsContext3D::UNSIGNED_SHORT_5_6_5 1408 && (internalformat == GraphicsContext3D::RGB || internalformat == GraphicsContext3D::RGB565)) 1409 break; 1410 if (type == GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV && internalformat == GraphicsContext3D::R11F_G11F_B10F) 1411 break; 1412 if (type == GraphicsContext3D::UNSIGNED_INT_5_9_9_9_REV && internalformat == GraphicsContext3D::RGB9_E5) 1413 break; 1414 if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) 1415 && (internalformat == GraphicsContext3D::RGB16F || internalformat == GraphicsContext3D::R11F_G11F_B10F || internalformat == GraphicsContext3D::RGB9_E5)) 1416 break; 1417 if (type == GraphicsContext3D::FLOAT 1418 && (internalformat == GraphicsContext3D::RGB32F || internalformat == GraphicsContext3D::RGB16F || internalformat == GraphicsContext3D::R11F_G11F_B10F || internalformat == GraphicsContext3D::RGB9_E5)) 1419 break; 1420 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination"); 1421 return false; 1422 case GraphicsContext3D::RGB_INTEGER: 1423 if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RGB8UI) 1424 break; 1425 if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RGB8I) 1426 break; 1427 if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::RGB16UI) 1428 break; 1429 if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::RGB16I) 1430 break; 1431 if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::RGB32UI) 1432 break; 1433 if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::RGB32I) 1434 break; 1435 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination"); 1436 return false; 1437 case GraphicsContext3D::RG: 1438 if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RG8) 1439 break; 1440 if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RG8_SNORM) 1441 break; 1442 if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) && internalformat == GraphicsContext3D::RG16F) 1443 break; 1444 if (type == GraphicsContext3D::FLOAT 1445 && (internalformat == GraphicsContext3D::RG32F || internalformat == GraphicsContext3D::RG16F)) 1446 break; 1447 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination"); 1448 return false; 1449 case GraphicsContext3D::RG_INTEGER: 1450 if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::RG8UI) 1451 break; 1452 if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::RG8I) 1453 break; 1454 if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::RG16UI) 1455 break; 1456 if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::RG16I) 1457 break; 1458 if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::RG32UI) 1459 break; 1460 if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::RG32I) 1461 break; 1462 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination"); 1463 return false; 1464 case GraphicsContext3D::RED: 1465 if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::R8) 1466 break; 1467 if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::R8_SNORM) 1468 break; 1469 if ((type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::HALF_FLOAT_OES) && internalformat == GraphicsContext3D::R16F) 1470 break; 1471 if (type == GraphicsContext3D::FLOAT 1472 && (internalformat == GraphicsContext3D::R32F || internalformat == GraphicsContext3D::R16F)) 1473 break; 1474 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination"); 1475 return false; 1476 case GraphicsContext3D::RED_INTEGER: 1477 if (type == GraphicsContext3D::UNSIGNED_BYTE && internalformat == GraphicsContext3D::R8UI) 1478 break; 1479 if (type == GraphicsContext3D::BYTE && internalformat == GraphicsContext3D::R8I) 1480 break; 1481 if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::R16UI) 1482 break; 1483 if (type == GraphicsContext3D::SHORT && internalformat == GraphicsContext3D::R16I) 1484 break; 1485 if (type == GraphicsContext3D::UNSIGNED_INT && internalformat == GraphicsContext3D::R32UI) 1486 break; 1487 if (type == GraphicsContext3D::INT && internalformat == GraphicsContext3D::R32I) 1488 break; 1489 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination"); 1490 return false; 1491 case GraphicsContext3D::DEPTH_COMPONENT: 1492 if (!m_webglDepthTexture) { 1493 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled"); 1494 return false; 1495 } 1496 if (type == GraphicsContext3D::UNSIGNED_SHORT && internalformat == GraphicsContext3D::DEPTH_COMPONENT16) 1497 break; 1498 if (type == GraphicsContext3D::UNSIGNED_INT 1499 && (internalformat == GraphicsContext3D::DEPTH_COMPONENT24 || internalformat == GraphicsContext3D::DEPTH_COMPONENT16)) 1500 break; 1501 if (type == GraphicsContext3D::FLOAT && internalformat == GraphicsContext3D::DEPTH_COMPONENT32F) 1502 break; 1503 if (level > 0) { 1504 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format"); 1505 return false; 1506 } 1507 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination"); 1508 return false; 1509 case GraphicsContext3D::DEPTH_STENCIL: 1510 if (!m_webglDepthTexture || !isDepthStencilSupported()) { 1511 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled"); 1512 return false; 1513 } 1514 if (type == GraphicsContext3D::UNSIGNED_INT_24_8 && internalformat == GraphicsContext3D::DEPTH24_STENCIL8) 1515 break; 1516 if (type == GraphicsContext3D::FLOAT_32_UNSIGNED_INT_24_8_REV && internalformat == GraphicsContext3D::DEPTH32F_STENCIL8) 1517 break; 1518 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination"); 1519 return false; 1520 case GraphicsContext3D::ALPHA: 1521 case GraphicsContext3D::LUMINANCE: 1522 case GraphicsContext3D::LUMINANCE_ALPHA: 1523 if ((type == GraphicsContext3D::UNSIGNED_BYTE || type == GraphicsContext3D::HALF_FLOAT_OES || type == GraphicsContext3D::HALF_FLOAT || type == GraphicsContext3D::FLOAT) && internalformat == format) 1524 break; 1525 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid format, internalformat, and type combination"); 1526 return false; 1527 default: 1528 ASSERT_NOT_REACHED(); 1529 } 1530 1531 return true; 1532 } 1533 1534 bool WebGL2RenderingContext::validateTexFuncData(const char* functionName, GC3Dint level, 1535 GC3Dsizei width, GC3Dsizei height, 1536 GC3Denum internalformat, GC3Denum format, GC3Denum type, 1537 ArrayBufferView* pixels, 1538 NullDisposition disposition) 1539 { 1540 if (!pixels) { 1541 if (disposition == NullAllowed) 1542 return true; 1543 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels"); 1544 return false; 1545 } 1546 1547 if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level)) 1548 return false; 1549 if (!validateSettableTexFormat(functionName, format)) 1550 return false; 1551 1552 switch (type) { 1553 case GraphicsContext3D::BYTE: 1554 if (pixels->getType() != JSC::TypeInt8) { 1555 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type BYTE but ArrayBufferView not Int8Array"); 1556 return false; 1557 } 1558 break; 1559 case GraphicsContext3D::UNSIGNED_BYTE: 1560 if (pixels->getType() != JSC::TypeUint8) { 1561 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array"); 1562 return false; 1563 } 1564 break; 1565 case GraphicsContext3D::SHORT: 1566 if (pixels->getType() != JSC::TypeInt16) { 1567 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type SHORT but ArrayBufferView not Int16Array"); 1568 return false; 1569 } 1570 break; 1571 case GraphicsContext3D::UNSIGNED_SHORT: 1572 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: 1573 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: 1574 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: 1575 if (pixels->getType() != JSC::TypeUint16) { 1576 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array"); 1577 return false; 1578 } 1579 break; 1580 case GraphicsContext3D::INT: 1581 if (pixels->getType() != JSC::TypeInt32) { 1582 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type INT but ArrayBufferView not Int32Array"); 1583 return false; 1584 } 1585 break; 1586 case GraphicsContext3D::UNSIGNED_INT: 1587 case GraphicsContext3D::UNSIGNED_INT_2_10_10_10_REV: 1588 case GraphicsContext3D::UNSIGNED_INT_10F_11F_11F_REV: 1589 if (pixels->getType() != JSC::TypeUint32) { 1590 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_INT but ArrayBufferView not Uint32Array"); 1591 return false; 1592 } 1593 break; 1594 case GraphicsContext3D::HALF_FLOAT: 1595 case GraphicsContext3D::FLOAT: 1596 if (pixels->getType() != JSC::TypeFloat32) { 1597 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array"); 1598 return false; 1599 } 1600 break; 1601 case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float 1602 // As per the specification, ArrayBufferView should be null when 1603 // OES_texture_half_float is enabled. 1604 if (pixels) { 1605 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL"); 1606 return false; 1607 } 1608 break; 1609 default: 1610 ASSERT_NOT_REACHED(); 1611 } 1612 1613 unsigned totalBytesRequired; 1614 GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0); 1615 if (error != GraphicsContext3D::NO_ERROR) { 1616 synthesizeGLError(error, functionName, "invalid texture dimensions"); 1617 return false; 1618 } 1619 if (pixels->byteLength() < totalBytesRequired) { 1620 if (m_unpackAlignment != 1) { 1621 error = m_context->computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0); 1622 if (pixels->byteLength() == totalBytesRequired) { 1623 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1"); 1624 return false; 1625 } 1626 } 1627 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request"); 1628 return false; 1629 } 1630 return true; 1631 } 1632 1633 GC3Denum WebGL2RenderingContext::baseInternalFormatFromInternalFormat(GC3Denum internalformat) 1634 { 1635 // Handles sized, unsized, and compressed internal formats. 1636 switch (internalformat) { 1637 case GraphicsContext3D::R8: 1638 case GraphicsContext3D::R8_SNORM: 1639 case GraphicsContext3D::R16F: 1640 case GraphicsContext3D::R32F: 1641 case GraphicsContext3D::R8I: 1642 case GraphicsContext3D::R8UI: 1643 case GraphicsContext3D::R16I: 1644 case GraphicsContext3D::R16UI: 1645 case GraphicsContext3D::R32I: 1646 case GraphicsContext3D::R32UI: 1647 case GraphicsContext3D::COMPRESSED_R11_EAC: 1648 case GraphicsContext3D::COMPRESSED_SIGNED_R11_EAC: 1649 return GraphicsContext3D::RED; 1650 case GraphicsContext3D::RG8: 1651 case GraphicsContext3D::RG8_SNORM: 1652 case GraphicsContext3D::RG16F: 1653 case GraphicsContext3D::RG32F: 1654 case GraphicsContext3D::RG8I: 1655 case GraphicsContext3D::RG8UI: 1656 case GraphicsContext3D::RG16I: 1657 case GraphicsContext3D::RG16UI: 1658 case GraphicsContext3D::RG32I: 1659 case GraphicsContext3D::RG32UI: 1660 case GraphicsContext3D::COMPRESSED_RG11_EAC: 1661 case GraphicsContext3D::COMPRESSED_SIGNED_RG11_EAC: 1662 return GraphicsContext3D::RG; 1663 case GraphicsContext3D::RGB8: 1664 case GraphicsContext3D::RGB8_SNORM: 1665 case GraphicsContext3D::RGB565: 1666 case GraphicsContext3D::SRGB8: 1667 case GraphicsContext3D::RGB16F: 1668 case GraphicsContext3D::RGB32F: 1669 case GraphicsContext3D::RGB8I: 1670 case GraphicsContext3D::RGB8UI: 1671 case GraphicsContext3D::RGB16I: 1672 case GraphicsContext3D::RGB16UI: 1673 case GraphicsContext3D::RGB32I: 1674 case GraphicsContext3D::RGB32UI: 1675 case GraphicsContext3D::RGB: 1676 case GraphicsContext3D::COMPRESSED_RGB8_ETC2: 1677 case GraphicsContext3D::COMPRESSED_SRGB8_ETC2: 1678 return GraphicsContext3D::RGB; 1679 case GraphicsContext3D::RGBA4: 1680 case GraphicsContext3D::RGB5_A1: 1681 case GraphicsContext3D::RGBA8: 1682 case GraphicsContext3D::RGBA8_SNORM: 1683 case GraphicsContext3D::RGB10_A2: 1684 case GraphicsContext3D::RGB10_A2UI: 1685 case GraphicsContext3D::SRGB8_ALPHA8: 1686 case GraphicsContext3D::RGBA16F: 1687 case GraphicsContext3D::RGBA32F: 1688 case GraphicsContext3D::RGBA8I: 1689 case GraphicsContext3D::RGBA8UI: 1690 case GraphicsContext3D::RGBA16I: 1691 case GraphicsContext3D::RGBA16UI: 1692 case GraphicsContext3D::RGBA32I: 1693 case GraphicsContext3D::RGBA32UI: 1694 case GraphicsContext3D::RGBA: 1695 case GraphicsContext3D::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: 1696 case GraphicsContext3D::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: 1697 case GraphicsContext3D::COMPRESSED_RGBA8_ETC2_EAC: 1698 case GraphicsContext3D::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: 1699 return GraphicsContext3D::RGBA; 1700 case GraphicsContext3D::DEPTH_COMPONENT16: 1701 case GraphicsContext3D::DEPTH_COMPONENT24: 1702 case GraphicsContext3D::DEPTH_COMPONENT32F: 1703 return GraphicsContext3D::DEPTH_COMPONENT; 1704 case GraphicsContext3D::DEPTH24_STENCIL8: 1705 case GraphicsContext3D::DEPTH32F_STENCIL8: 1706 return GraphicsContext3D::DEPTH_STENCIL; 1707 case GraphicsContext3D::LUMINANCE: 1708 case GraphicsContext3D::LUMINANCE_ALPHA: 1709 case GraphicsContext3D::ALPHA: 1710 return internalformat; 1711 default: 1712 ASSERT_NOT_REACHED(); 1713 return GraphicsContext3D::NONE; 1714 } 901 1715 } 902 1716 -
trunk/Source/WebCore/html/canvas/WebGL2RenderingContext.h
r179482 r179842 49 49 50 50 /* Framebuffer objects */ 51 WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname );51 WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode&); 52 52 void blitFramebuffer(GC3Dint srcX0, GC3Dint srcY0, GC3Dint srcX1, GC3Dint srcY1, GC3Dint dstX0, GC3Dint dstY0, GC3Dint dstX1, GC3Dint dstY1, GC3Dbitfield mask, GC3Denum filter); 53 53 void framebufferTextureLayer(GC3Denum target, GC3Denum attachment, GC3Duint texture, GC3Dint level, GC3Dint layer); … … 170 170 171 171 virtual WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&) override; 172 bool validateCapability(const char* functionName, GC3Denum cap) override; 172 173 virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) override; 174 virtual void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&) override; 175 virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&) override; 176 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 177 GC3Dsizei width, GC3Dsizei height, 178 GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&) override; 179 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 180 GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&) override; 181 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 182 GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&) override; 183 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 184 GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&) override; 185 #if ENABLE(VIDEO) 186 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 187 GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&) override; 188 #endif 189 190 protected: 191 virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) override; 192 virtual bool validateTexFuncParameters(const char* functionName, 193 TexFuncValidationFunctionType, 194 GC3Denum target, GC3Dint level, 195 GC3Denum internalformat, 196 GC3Dsizei width, GC3Dsizei height, GC3Dint border, 197 GC3Denum format, GC3Denum type) override; 198 virtual bool validateTexFuncData(const char* functionName, GC3Dint level, 199 GC3Dsizei width, GC3Dsizei height, 200 GC3Denum internalformat, GC3Denum format, GC3Denum type, 201 ArrayBufferView* pixels, 202 NullDisposition) override; 203 virtual bool validateCapability(const char* functionName, GC3Denum cap) override; 204 205 private: 206 GC3Denum baseInternalFormatFromInternalFormat(GC3Denum internalformat); 173 207 }; 174 208 -
trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
r179482 r179842 30 30 31 31 #include "ANGLEInstancedArrays.h" 32 #include "CachedImage.h" 32 33 #include "EXTBlendMinMax.h" 33 34 #include "EXTFragDepth.h" … … 36 37 #include "EXTsRGB.h" 37 38 #include "Extensions3D.h" 39 #include "HTMLCanvasElement.h" 40 #include "HTMLImageElement.h" 41 #include "HTMLVideoElement.h" 42 #include "ImageData.h" 38 43 #include "OESElementIndexUint.h" 39 44 #include "OESStandardDerivatives.h" … … 43 48 #include "OESTextureHalfFloatLinear.h" 44 49 #include "OESVertexArrayObject.h" 50 #include "RenderBox.h" 45 51 #include "WebGLCompressedTextureATC.h" 46 52 #include "WebGLCompressedTexturePVRTC.h" … … 282 288 } 283 289 290 void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) 291 { 292 if (isContextLostOrPending()) 293 return; 294 if (!validateTexFuncParameters("copyTexImage2D", CopyTexImage, target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE)) 295 return; 296 if (!validateSettableTexFormat("copyTexImage2D", internalformat)) 297 return; 298 WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true); 299 if (!tex) 300 return; 301 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) { 302 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format"); 303 return; 304 } 305 if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) { 306 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2"); 307 return; 308 } 309 const char* reason = "framebuffer incomplete"; 310 if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) { 311 synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason); 312 return; 313 } 314 clearIfComposited(); 315 if (isResourceSafe()) { 316 ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get()); 317 m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border); 318 } else { 319 ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get()); 320 GC3Dint clippedX, clippedY; 321 GC3Dsizei clippedWidth, clippedHeight; 322 if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) { 323 m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border, 324 internalformat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment); 325 if (clippedWidth > 0 && clippedHeight > 0) { 326 m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y, 327 clippedX, clippedY, clippedWidth, clippedHeight); 328 } 329 } else 330 m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border); 331 } 332 // FIXME: if the framebuffer is not complete, none of the below should be executed. 333 tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE); 334 } 335 336 void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode& ec) 337 { 338 UNUSED_PARAM(internalformat); 339 // FIXME: For now we ignore any errors returned 340 ec = 0; 341 ASSERT(!isContextLost()); 342 ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage, target, level, format, width, height, 0, format, type)); 343 ASSERT(validateSize("texSubImage2D", xoffset, yoffset)); 344 ASSERT(validateSettableTexFormat("texSubImage2D", format)); 345 WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true); 346 if (!tex) { 347 ASSERT_NOT_REACHED(); 348 return; 349 } 350 ASSERT((xoffset + width) >= 0); 351 ASSERT((yoffset + height) >= 0); 352 ASSERT(tex->getWidth(target, level) >= (xoffset + width)); 353 ASSERT(tex->getHeight(target, level) >= (yoffset + height)); 354 ASSERT(tex->getInternalFormat(target, level) == format); 355 ASSERT(tex->getType(target, level) == type); 356 m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); 357 } 358 359 void WebGLRenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec) 360 { 361 ec = 0; 362 Vector<uint8_t> data; 363 GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE); 364 if (!imageExtractor.extractSucceeded()) { 365 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image"); 366 return; 367 } 368 GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat(); 369 GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp(); 370 const void* imagePixelData = imageExtractor.imagePixelData(); 371 372 bool needConversion = true; 373 if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY) 374 needConversion = false; 375 else { 376 if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) { 377 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data"); 378 return; 379 } 380 } 381 382 if (m_unpackAlignment != 1) 383 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1); 384 385 texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), format, format, type, needConversion ? data.data() : imagePixelData, ec); 386 if (m_unpackAlignment != 1) 387 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment); 388 } 389 390 void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec) 391 { 392 if (isContextLostOrPending() || !validateTexFuncData("texSubImage2D", level, width, height, format, format, type, pixels, NullNotAllowed) || !validateTexFunc("texSubImage2D", TexSubImage, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset)) 393 return; 394 395 void* data = pixels->baseAddress(); 396 Vector<uint8_t> tempData; 397 bool changeUnpackAlignment = false; 398 if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) { 399 if (!m_context->extractTextureData(width, height, format, type, 400 m_unpackAlignment, 401 m_unpackFlipY, m_unpackPremultiplyAlpha, 402 data, 403 tempData)) 404 return; 405 data = tempData.data(); 406 changeUnpackAlignment = true; 407 } 408 if (changeUnpackAlignment) 409 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1); 410 411 texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, format, type, data, ec); 412 if (changeUnpackAlignment) 413 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment); 414 } 415 416 void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec) 417 { 418 ec = 0; 419 if (isContextLostOrPending() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage, SourceImageData, target, level, format, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset)) 420 return; 421 422 Vector<uint8_t> data; 423 bool needConversion = true; 424 // The data from ImageData is always of format RGBA8. 425 // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required. 426 if (format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha) 427 needConversion = false; 428 else { 429 if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) { 430 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image data"); 431 return; 432 } 433 } 434 if (m_unpackAlignment != 1) 435 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1); 436 437 texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, format, type, needConversion ? data.data() : pixels->data()->data(), ec); 438 if (m_unpackAlignment != 1) 439 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment); 440 } 441 442 void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec) 443 { 444 ec = 0; 445 if (isContextLostOrPending() || !validateHTMLImageElement("texSubImage2D", image, ec)) 446 return; 447 448 RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer()); 449 if (imageForRender->isSVGImage()) 450 imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), 1); 451 452 if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset)) 453 return; 454 455 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec); 456 } 457 458 void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec) 459 { 460 ec = 0; 461 if (isContextLostOrPending() || !validateHTMLCanvasElement("texSubImage2D", canvas, ec) 462 || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset)) 463 return; 464 465 RefPtr<ImageData> imageData = canvas->getImageData(); 466 if (imageData) 467 texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec); 468 else 469 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec); 470 } 471 472 #if ENABLE(VIDEO) 473 void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec) 474 { 475 ec = 0; 476 if (isContextLostOrPending() || !validateHTMLVideoElement("texSubImage2D", video, ec) 477 || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLVideoElement, target, level, format, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset)) 478 return; 479 480 RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec); 481 if (!image) 482 return; 483 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec); 484 } 485 #endif 486 487 bool WebGLRenderingContext::validateTexFuncParameters(const char* functionName, 488 TexFuncValidationFunctionType functionType, 489 GC3Denum target, GC3Dint level, 490 GC3Denum internalformat, 491 GC3Dsizei width, GC3Dsizei height, GC3Dint border, 492 GC3Denum format, GC3Denum type) 493 { 494 // We absolutely have to validate the format and type combination. 495 // The texImage2D entry points taking HTMLImage, etc. will produce 496 // temporary data based on this combination, so it must be legal. 497 if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level) || !validateTexFuncLevel(functionName, target, level)) 498 return false; 499 500 if (width < 0 || height < 0) { 501 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0"); 502 return false; 503 } 504 505 GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level); 506 switch (target) { 507 case GraphicsContext3D::TEXTURE_2D: 508 if (width > maxTextureSizeForLevel || height > maxTextureSizeForLevel) { 509 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range"); 510 return false; 511 } 512 break; 513 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X: 514 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X: 515 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y: 516 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y: 517 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z: 518 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z: 519 if (functionType != TexSubImage && width != height) { 520 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map"); 521 return false; 522 } 523 // No need to check height here. For texImage width == height. 524 // For texSubImage that will be checked when checking yoffset + height is in range. 525 if (width > maxTextureSizeForLevel) { 526 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range for cube map"); 527 return false; 528 } 529 break; 530 default: 531 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target"); 532 return false; 533 } 534 535 if (format != internalformat) { 536 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format != internalformat"); 537 return false; 538 } 539 540 if (border) { 541 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0"); 542 return false; 543 } 544 545 return true; 546 } 547 548 bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) 549 { 550 UNUSED_PARAM(internalformat); 551 switch (format) { 552 case GraphicsContext3D::ALPHA: 553 case GraphicsContext3D::LUMINANCE: 554 case GraphicsContext3D::LUMINANCE_ALPHA: 555 case GraphicsContext3D::RGB: 556 case GraphicsContext3D::RGBA: 557 break; 558 case GraphicsContext3D::DEPTH_STENCIL: 559 case GraphicsContext3D::DEPTH_COMPONENT: 560 if (m_webglDepthTexture) 561 break; 562 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled"); 563 return false; 564 case Extensions3D::SRGB_EXT: 565 case Extensions3D::SRGB_ALPHA_EXT: 566 default: 567 if ((format == Extensions3D::SRGB_EXT || format == Extensions3D::SRGB_ALPHA_EXT) 568 && m_extsRGB) 569 break; 570 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format"); 571 return false; 572 } 573 574 switch (type) { 575 case GraphicsContext3D::UNSIGNED_BYTE: 576 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: 577 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: 578 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: 579 break; 580 case GraphicsContext3D::FLOAT: 581 if (m_oesTextureFloat) 582 break; 583 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type"); 584 return false; 585 case GraphicsContext3D::HALF_FLOAT_OES: 586 if (m_oesTextureHalfFloat) 587 break; 588 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type"); 589 return false; 590 case GraphicsContext3D::UNSIGNED_INT: 591 case GraphicsContext3D::UNSIGNED_INT_24_8: 592 case GraphicsContext3D::UNSIGNED_SHORT: 593 if (m_webglDepthTexture) 594 break; 595 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type"); 596 return false; 597 default: 598 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type"); 599 return false; 600 } 601 602 // Verify that the combination of format and type is supported. 603 switch (format) { 604 case GraphicsContext3D::ALPHA: 605 case GraphicsContext3D::LUMINANCE: 606 case GraphicsContext3D::LUMINANCE_ALPHA: 607 if (type != GraphicsContext3D::UNSIGNED_BYTE 608 && type != GraphicsContext3D::FLOAT 609 && type != GraphicsContext3D::HALF_FLOAT_OES) { 610 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for format"); 611 return false; 612 } 613 break; 614 case GraphicsContext3D::RGB: 615 case Extensions3D::SRGB_EXT: 616 if (type != GraphicsContext3D::UNSIGNED_BYTE 617 && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5 618 && type != GraphicsContext3D::FLOAT 619 && type != GraphicsContext3D::HALF_FLOAT_OES) { 620 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGB format"); 621 return false; 622 } 623 break; 624 case GraphicsContext3D::RGBA: 625 case Extensions3D::SRGB_ALPHA_EXT: 626 if (type != GraphicsContext3D::UNSIGNED_BYTE 627 && type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4 628 && type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1 629 && type != GraphicsContext3D::FLOAT 630 && type != GraphicsContext3D::HALF_FLOAT_OES) { 631 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGBA format"); 632 return false; 633 } 634 break; 635 case GraphicsContext3D::DEPTH_COMPONENT: 636 if (!m_webglDepthTexture) { 637 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled"); 638 return false; 639 } 640 if (type != GraphicsContext3D::UNSIGNED_SHORT 641 && type != GraphicsContext3D::UNSIGNED_INT) { 642 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for DEPTH_COMPONENT format"); 643 return false; 644 } 645 if (level > 0) { 646 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format"); 647 return false; 648 } 649 break; 650 case GraphicsContext3D::DEPTH_STENCIL: 651 if (!m_webglDepthTexture) { 652 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled"); 653 return false; 654 } 655 if (type != GraphicsContext3D::UNSIGNED_INT_24_8) { 656 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for DEPTH_STENCIL format"); 657 return false; 658 } 659 if (level > 0) { 660 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_STENCIL format"); 661 return false; 662 } 663 break; 664 default: 665 ASSERT_NOT_REACHED(); 666 } 667 668 return true; 669 } 670 671 bool WebGLRenderingContext::validateTexFuncData(const char* functionName, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, NullDisposition disposition) 672 { 673 if (!pixels) { 674 if (disposition == NullAllowed) 675 return true; 676 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels"); 677 return false; 678 } 679 680 if (!validateTexFuncFormatAndType(functionName, internalformat, format, type, level)) 681 return false; 682 if (!validateSettableTexFormat(functionName, format)) 683 return false; 684 685 switch (type) { 686 case GraphicsContext3D::UNSIGNED_BYTE: 687 if (pixels->getType() != JSC::TypeUint8) { 688 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array"); 689 return false; 690 } 691 break; 692 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: 693 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: 694 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: 695 if (pixels->getType() != JSC::TypeUint16) { 696 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array"); 697 return false; 698 } 699 break; 700 case GraphicsContext3D::FLOAT: // OES_texture_float 701 if (pixels->getType() != JSC::TypeFloat32) { 702 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array"); 703 return false; 704 } 705 break; 706 case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float 707 // As per the specification, ArrayBufferView should be null when 708 // OES_texture_half_float is enabled. 709 if (pixels) { 710 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL"); 711 return false; 712 } 713 break; 714 default: 715 ASSERT_NOT_REACHED(); 716 } 717 718 unsigned totalBytesRequired; 719 GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0); 720 if (error != GraphicsContext3D::NO_ERROR) { 721 synthesizeGLError(error, functionName, "invalid texture dimensions"); 722 return false; 723 } 724 if (pixels->byteLength() < totalBytesRequired) { 725 if (m_unpackAlignment != 1) { 726 error = m_context->computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0); 727 if (pixels->byteLength() == totalBytesRequired) { 728 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1"); 729 return false; 730 } 731 } 732 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request"); 733 return false; 734 } 735 return true; 736 } 737 284 738 WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode& ec) 285 739 { -
trunk/Source/WebCore/html/canvas/WebGLRenderingContext.h
r179482 r179842 40 40 virtual WebGLGetInfo getParameter(GC3Denum pname, ExceptionCode&) override; 41 41 virtual Vector<String> getSupportedExtensions() override; 42 bool validateCapability(const char* functionName, GC3Denum cap) override; 42 43 virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) override; 44 virtual void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&) override; 45 virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&) override; 46 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 47 GC3Dsizei width, GC3Dsizei height, 48 GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&) override; 49 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 50 GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&) override; 51 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 52 GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&) override; 53 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 54 GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&) override; 55 #if ENABLE(VIDEO) 56 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 57 GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&) override; 58 #endif 59 60 protected: 61 virtual bool validateTexFuncParameters(const char* functionName, 62 TexFuncValidationFunctionType, 63 GC3Denum target, GC3Dint level, 64 GC3Denum internalformat, 65 GC3Dsizei width, GC3Dsizei height, GC3Dint border, 66 GC3Denum format, GC3Denum type) override; 67 virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) override; 68 virtual bool validateTexFuncData(const char* functionName, GC3Dint level, 69 GC3Dsizei width, GC3Dsizei height, 70 GC3Denum internalformat, GC3Denum format, GC3Denum type, 71 ArrayBufferView* pixels, 72 NullDisposition) override; 73 virtual bool validateCapability(const char* functionName, GC3Denum cap) override; 43 74 }; 44 75 -
trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
r179530 r179842 100 100 101 101 namespace { 102 103 class ScopedDrawingBufferBinder { 104 public: 105 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding) 106 : m_drawingBuffer(drawingBuffer) 107 , m_framebufferBinding(framebufferBinding) 108 { 109 // Commit DrawingBuffer if needed (e.g., for multisampling) 110 if (!m_framebufferBinding && m_drawingBuffer) 111 m_drawingBuffer->commit(); 112 } 113 114 ~ScopedDrawingBufferBinder() 115 { 116 // Restore DrawingBuffer if needed 117 if (!m_framebufferBinding && m_drawingBuffer) 118 m_drawingBuffer->bind(); 119 } 120 121 private: 122 DrawingBuffer* m_drawingBuffer; 123 WebGLFramebuffer* m_framebufferBinding; 124 }; 125 102 126 103 Platform3DObject objectOrZero(WebGLObject* object) 127 104 { 128 105 return object ? object->object() : 0; 129 }130 131 void clip1D(GC3Dint start, GC3Dsizei range, GC3Dsizei sourceRange, GC3Dint* clippedStart, GC3Dsizei* clippedRange)132 {133 ASSERT(clippedStart && clippedRange);134 if (start < 0) {135 range += start;136 start = 0;137 }138 GC3Dint end = start + range;139 if (end > sourceRange)140 range -= end - sourceRange;141 *clippedStart = start;142 *clippedRange = range;143 }144 145 // Returns false if no clipping is necessary, i.e., x, y, width, height stay the same.146 bool clip2D(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height,147 GC3Dsizei sourceWidth, GC3Dsizei sourceHeight,148 GC3Dint* clippedX, GC3Dint* clippedY, GC3Dsizei* clippedWidth, GC3Dsizei*clippedHeight)149 {150 ASSERT(clippedX && clippedY && clippedWidth && clippedHeight);151 clip1D(x, width, sourceWidth, clippedX, clippedWidth);152 clip1D(y, height, sourceHeight, clippedY, clippedHeight);153 return (*clippedX != x || *clippedY != y || *clippedWidth != width || *clippedHeight != height);154 106 } 155 107 … … 1441 1393 } 1442 1394 return true; 1443 }1444 1445 void WebGLRenderingContextBase::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)1446 {1447 if (isContextLostOrPending())1448 return;1449 if (!validateTexFuncParameters("copyTexImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))1450 return;1451 if (!validateSettableTexFormat("copyTexImage2D", internalformat))1452 return;1453 WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);1454 if (!tex)1455 return;1456 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {1457 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");1458 return;1459 }1460 if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {1461 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");1462 return;1463 }1464 const char* reason = "framebuffer incomplete";1465 if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe(), &reason)) {1466 synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);1467 return;1468 }1469 clearIfComposited();1470 if (isResourceSafe()) {1471 ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());1472 m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);1473 } else {1474 ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());1475 GC3Dint clippedX, clippedY;1476 GC3Dsizei clippedWidth, clippedHeight;1477 if (clip2D(x, y, width, height, getBoundFramebufferWidth(), getBoundFramebufferHeight(), &clippedX, &clippedY, &clippedWidth, &clippedHeight)) {1478 m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border,1479 internalformat, GraphicsContext3D::UNSIGNED_BYTE, m_unpackAlignment);1480 if (clippedWidth > 0 && clippedHeight > 0) {1481 m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y,1482 clippedX, clippedY, clippedWidth, clippedHeight);1483 }1484 } else1485 m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);1486 }1487 // FIXME: if the framebuffer is not complete, none of the below should be executed.1488 tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);1489 1395 } 1490 1396 … … 3548 3454 ec = 0; 3549 3455 WebGLTexture* tex = validateTextureBinding("texImage2D", target, true); 3550 ASSERT(validateTexFuncParameters("texImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, format, type));3456 ASSERT(validateTexFuncParameters("texImage2D", TexImage, target, level, internalformat, width, height, border, format, type)); 3551 3457 ASSERT(tex); 3552 3458 ASSERT(!level || !WebGLTexture::isNPOT(width, height)); … … 3617 3523 return false; 3618 3524 3619 if (functionType == NotTexSubImage2D) {3525 if (functionType != TexSubImage) { 3620 3526 if (level && WebGLTexture::isNPOT(width, height)) { 3621 3527 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level > 0 not power of 2"); … … 3655 3561 GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec) 3656 3562 { 3657 if (isContextLostOrPending() || !validateTexFuncData("texImage2D", level, width, height, format, type, pixels, NullAllowed)3658 || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0))3563 if (isContextLostOrPending() || !validateTexFuncData("texImage2D", level, width, height, internalformat, format, type, pixels, NullAllowed) 3564 || !validateTexFunc("texImage2D", TexImage, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0)) 3659 3565 return; 3660 3566 void* data = pixels ? pixels->baseAddress() : 0; … … 3683 3589 { 3684 3590 ec = 0; 3685 if (isContextLostOrPending() || !pixels || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))3591 if (isContextLostOrPending() || !pixels || !validateTexFunc("texImage2D", TexImage, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0)) 3686 3592 return; 3687 3593 Vector<uint8_t> data; … … 3731 3637 imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), 1); 3732 3638 3733 if (!imageForRender || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))3639 if (!imageForRender || !validateTexFunc("texImage2D", TexImage, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0)) 3734 3640 return; 3735 3641 … … 3741 3647 { 3742 3648 ec = 0; 3743 if (isContextLostOrPending() || !validateHTMLCanvasElement("texImage2D", canvas, ec) || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))3649 if (isContextLostOrPending() || !validateHTMLCanvasElement("texImage2D", canvas, ec) || !validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0)) 3744 3650 return; 3745 3651 … … 3786 3692 ec = 0; 3787 3693 if (isContextLostOrPending() || !validateHTMLVideoElement("texImage2D", video, ec) 3788 || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))3694 || !validateTexFunc("texImage2D", TexImage, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0)) 3789 3695 return; 3790 3696 … … 3860 3766 texParameter(target, pname, 0, param, false); 3861 3767 } 3862 3863 void WebGLRenderingContextBase::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode& ec)3864 {3865 // FIXME: For now we ignore any errors returned3866 ec = 0;3867 ASSERT(!isContextLost());3868 ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage2D, target, level, format, width, height, 0, format, type));3869 ASSERT(validateSize("texSubImage2D", xoffset, yoffset));3870 ASSERT(validateSettableTexFormat("texSubImage2D", format));3871 WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);3872 if (!tex) {3873 ASSERT_NOT_REACHED();3874 return;3875 }3876 ASSERT((xoffset + width) >= 0);3877 ASSERT((yoffset + height) >= 0);3878 ASSERT(tex->getWidth(target, level) >= (xoffset + width));3879 ASSERT(tex->getHeight(target, level) >= (yoffset + height));3880 ASSERT(tex->getInternalFormat(target, level) == format);3881 ASSERT(tex->getType(target, level) == type);3882 m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);3883 }3884 3885 void WebGLRenderingContextBase::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionCode& ec)3886 {3887 ec = 0;3888 Vector<uint8_t> data;3889 GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE);3890 if (!imageExtractor.extractSucceeded()) {3891 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image");3892 return;3893 }3894 GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();3895 GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();3896 const void* imagePixelData = imageExtractor.imagePixelData();3897 3898 bool needConversion = true;3899 if (type == GraphicsContext3D::UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GraphicsContext3D::RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)3900 needConversion = false;3901 else {3902 if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {3903 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");3904 return;3905 }3906 }3907 3908 if (m_unpackAlignment != 1)3909 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);3910 texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), format, type, needConversion ? data.data() : imagePixelData, ec);3911 if (m_unpackAlignment != 1)3912 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);3913 }3914 3915 void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,3916 GC3Dsizei width, GC3Dsizei height,3917 GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)3918 {3919 if (isContextLostOrPending() || !validateTexFuncData("texSubImage2D", level, width, height, format, type, pixels, NullNotAllowed)3920 || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset))3921 return;3922 void* data = pixels->baseAddress();3923 Vector<uint8_t> tempData;3924 bool changeUnpackAlignment = false;3925 if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {3926 if (!m_context->extractTextureData(width, height, format, type,3927 m_unpackAlignment,3928 m_unpackFlipY, m_unpackPremultiplyAlpha,3929 data,3930 tempData))3931 return;3932 data = tempData.data();3933 changeUnpackAlignment = true;3934 }3935 if (changeUnpackAlignment)3936 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);3937 texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, ec);3938 if (changeUnpackAlignment)3939 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);3940 }3941 3942 void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,3943 GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionCode& ec)3944 {3945 ec = 0;3946 if (isContextLostOrPending() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceImageData, target, level, format, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))3947 return;3948 3949 Vector<uint8_t> data;3950 bool needConversion = true;3951 // The data from ImageData is always of format RGBA8.3952 // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.3953 if (format == GraphicsContext3D::RGBA && type == GraphicsContext3D::UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)3954 needConversion = false;3955 else {3956 if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {3957 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image data");3958 return;3959 }3960 }3961 if (m_unpackAlignment != 1)3962 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);3963 texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data(), ec);3964 if (m_unpackAlignment != 1)3965 m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);3966 }3967 3968 void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,3969 GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionCode& ec)3970 {3971 ec = 0;3972 if (isContextLostOrPending() || !validateHTMLImageElement("texSubImage2D", image, ec))3973 return;3974 3975 RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());3976 if (imageForRender->isSVGImage())3977 imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), 1);3978 3979 if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))3980 return;3981 3982 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);3983 }3984 3985 void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,3986 GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionCode& ec)3987 {3988 ec = 0;3989 if (isContextLostOrPending() || !validateHTMLCanvasElement("texSubImage2D", canvas, ec)3990 || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))3991 return;3992 3993 RefPtr<ImageData> imageData = canvas->getImageData();3994 if (imageData)3995 texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec);3996 else3997 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);3998 }3999 4000 #if ENABLE(VIDEO)4001 void WebGLRenderingContextBase::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,4002 GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionCode& ec)4003 {4004 ec = 0;4005 if (isContextLostOrPending() || !validateHTMLVideoElement("texSubImage2D", video, ec)4006 || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLVideoElement, target, level, format, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))4007 return;4008 4009 RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode(), ec);4010 if (!image)4011 return;4012 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, ec);4013 }4014 #endif4015 3768 4016 3769 void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GC3Dfloat x, ExceptionCode& ec) … … 4864 4617 } 4865 4618 4866 bool WebGLRenderingContextBase::validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level)4867 {4868 switch (format) {4869 case GraphicsContext3D::ALPHA:4870 case GraphicsContext3D::LUMINANCE:4871 case GraphicsContext3D::LUMINANCE_ALPHA:4872 case GraphicsContext3D::RGB:4873 case GraphicsContext3D::RGBA:4874 break;4875 case GraphicsContext3D::DEPTH_STENCIL:4876 case GraphicsContext3D::DEPTH_COMPONENT:4877 if (m_webglDepthTexture)4878 break;4879 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "depth texture formats not enabled");4880 return false;4881 case Extensions3D::SRGB_EXT:4882 case Extensions3D::SRGB_ALPHA_EXT:4883 default:4884 if ((format == Extensions3D::SRGB_EXT || format == Extensions3D::SRGB_ALPHA_EXT)4885 && m_extsRGB)4886 break;4887 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format");4888 return false;4889 }4890 4891 switch (type) {4892 case GraphicsContext3D::UNSIGNED_BYTE:4893 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:4894 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:4895 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:4896 break;4897 case GraphicsContext3D::FLOAT:4898 if (m_oesTextureFloat)4899 break;4900 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");4901 return false;4902 case GraphicsContext3D::HALF_FLOAT_OES:4903 if (m_oesTextureHalfFloat)4904 break;4905 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");4906 return false;4907 case GraphicsContext3D::UNSIGNED_INT:4908 case GraphicsContext3D::UNSIGNED_INT_24_8:4909 case GraphicsContext3D::UNSIGNED_SHORT:4910 if (m_webglDepthTexture)4911 break;4912 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");4913 return false;4914 default:4915 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");4916 return false;4917 }4918 4919 // Verify that the combination of format and type is supported.4920 switch (format) {4921 case GraphicsContext3D::ALPHA:4922 case GraphicsContext3D::LUMINANCE:4923 case GraphicsContext3D::LUMINANCE_ALPHA:4924 if (type != GraphicsContext3D::UNSIGNED_BYTE4925 && type != GraphicsContext3D::FLOAT4926 && type != GraphicsContext3D::HALF_FLOAT_OES) {4927 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for format");4928 return false;4929 }4930 break;4931 case GraphicsContext3D::RGB:4932 case Extensions3D::SRGB_EXT:4933 if (type != GraphicsContext3D::UNSIGNED_BYTE4934 && type != GraphicsContext3D::UNSIGNED_SHORT_5_6_54935 && type != GraphicsContext3D::FLOAT4936 && type != GraphicsContext3D::HALF_FLOAT_OES) {4937 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGB format");4938 return false;4939 }4940 break;4941 case GraphicsContext3D::RGBA:4942 case Extensions3D::SRGB_ALPHA_EXT:4943 if (type != GraphicsContext3D::UNSIGNED_BYTE4944 && type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_44945 && type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_14946 && type != GraphicsContext3D::FLOAT4947 && type != GraphicsContext3D::HALF_FLOAT_OES) {4948 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGBA format");4949 return false;4950 }4951 break;4952 case GraphicsContext3D::DEPTH_COMPONENT:4953 if (!m_webglDepthTexture) {4954 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled");4955 return false;4956 }4957 if (type != GraphicsContext3D::UNSIGNED_SHORT4958 && type != GraphicsContext3D::UNSIGNED_INT) {4959 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for DEPTH_COMPONENT format");4960 return false;4961 }4962 if (level > 0) {4963 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");4964 return false;4965 }4966 break;4967 case GraphicsContext3D::DEPTH_STENCIL:4968 if (!m_webglDepthTexture) {4969 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled");4970 return false;4971 }4972 if (type != GraphicsContext3D::UNSIGNED_INT_24_8) {4973 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for DEPTH_STENCIL format");4974 return false;4975 }4976 if (level > 0) {4977 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "level must be 0 for DEPTH_STENCIL format");4978 return false;4979 }4980 break;4981 default:4982 ASSERT_NOT_REACHED();4983 }4984 4985 return true;4986 }4987 4988 4619 bool WebGLRenderingContextBase::validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level) 4989 4620 { … … 5013 4644 // This function only checks if level is legal, so we return true and don't 5014 4645 // generate INVALID_ENUM if target is illegal. 5015 return true;5016 }5017 5018 bool WebGLRenderingContextBase::validateTexFuncParameters(const char* functionName,5019 TexFuncValidationFunctionType functionType,5020 GC3Denum target, GC3Dint level,5021 GC3Denum internalformat,5022 GC3Dsizei width, GC3Dsizei height, GC3Dint border,5023 GC3Denum format, GC3Denum type)5024 {5025 // We absolutely have to validate the format and type combination.5026 // The texImage2D entry points taking HTMLImage, etc. will produce5027 // temporary data based on this combination, so it must be legal.5028 if (!validateTexFuncFormatAndType(functionName, format, type, level) || !validateTexFuncLevel(functionName, target, level))5029 return false;5030 5031 if (width < 0 || height < 0) {5032 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");5033 return false;5034 }5035 5036 GC3Dint maxTextureSizeForLevel = pow(2.0, m_maxTextureLevel - 1 - level);5037 switch (target) {5038 case GraphicsContext3D::TEXTURE_2D:5039 if (width > maxTextureSizeForLevel || height > maxTextureSizeForLevel) {5040 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range");5041 return false;5042 }5043 break;5044 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_X:5045 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_X:5046 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Y:5047 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Y:5048 case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:5049 case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:5050 if (functionType != TexSubImage2D && width != height) {5051 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height for cube map");5052 return false;5053 }5054 // No need to check height here. For texImage width == height.5055 // For texSubImage that will be checked when checking yoffset + height is in range.5056 if (width > maxTextureSizeForLevel) {5057 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range for cube map");5058 return false;5059 }5060 break;5061 default:5062 synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");5063 return false;5064 }5065 5066 if (format != internalformat) {5067 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format != internalformat");5068 return false;5069 }5070 5071 if (border) {5072 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0");5073 return false;5074 }5075 5076 return true;5077 }5078 5079 bool WebGLRenderingContextBase::validateTexFuncData(const char* functionName, GC3Dint level,5080 GC3Dsizei width, GC3Dsizei height,5081 GC3Denum format, GC3Denum type,5082 ArrayBufferView* pixels,5083 NullDisposition disposition)5084 {5085 if (!pixels) {5086 if (disposition == NullAllowed)5087 return true;5088 synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels");5089 return false;5090 }5091 5092 if (!validateTexFuncFormatAndType(functionName, format, type, level))5093 return false;5094 if (!validateSettableTexFormat(functionName, format))5095 return false;5096 5097 switch (type) {5098 case GraphicsContext3D::UNSIGNED_BYTE:5099 if (pixels->getType() != JSC::TypeUint8) {5100 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");5101 return false;5102 }5103 break;5104 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:5105 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:5106 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:5107 if (pixels->getType() != JSC::TypeUint16) {5108 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");5109 return false;5110 }5111 break;5112 case GraphicsContext3D::FLOAT: // OES_texture_float5113 if (pixels->getType() != JSC::TypeFloat32) {5114 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");5115 return false;5116 }5117 break;5118 case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float5119 // As per the specification, ArrayBufferView should be null when5120 // OES_texture_half_float is enabled.5121 if (pixels) {5122 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL");5123 return false;5124 }5125 break;5126 default:5127 ASSERT_NOT_REACHED();5128 }5129 5130 unsigned int totalBytesRequired;5131 GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);5132 if (error != GraphicsContext3D::NO_ERROR) {5133 synthesizeGLError(error, functionName, "invalid texture dimensions");5134 return false;5135 }5136 if (pixels->byteLength() < totalBytesRequired) {5137 if (m_unpackAlignment != 1) {5138 error = m_context->computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);5139 if (pixels->byteLength() == totalBytesRequired) {5140 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");5141 return false;5142 }5143 }5144 synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");5145 return false;5146 }5147 4646 return true; 5148 4647 } -
trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.h
r179530 r179842 34 34 #include "Timer.h" 35 35 #include "WebGLGetInfo.h" 36 #include "WebGLObject.h" 36 37 #include <memory> 37 38 #include <runtime/Float32Array.h> … … 86 87 typedef int ExceptionCode; 87 88 89 class ScopedDrawingBufferBinder { 90 public: 91 ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding) 92 : m_drawingBuffer(drawingBuffer) 93 , m_framebufferBinding(framebufferBinding) 94 { 95 // Commit DrawingBuffer if needed (e.g., for multisampling) 96 if (!m_framebufferBinding && m_drawingBuffer) 97 m_drawingBuffer->commit(); 98 } 99 100 ~ScopedDrawingBufferBinder() 101 { 102 // Restore DrawingBuffer if needed 103 if (!m_framebufferBinding && m_drawingBuffer) 104 m_drawingBuffer->bind(); 105 } 106 107 private: 108 DrawingBuffer* m_drawingBuffer; 109 WebGLFramebuffer* m_framebufferBinding; 110 }; 111 112 inline void clip1D(GC3Dint start, GC3Dsizei range, GC3Dsizei sourceRange, GC3Dint* clippedStart, GC3Dsizei* clippedRange) 113 { 114 ASSERT(clippedStart && clippedRange); 115 if (start < 0) { 116 range += start; 117 start = 0; 118 } 119 GC3Dint end = start + range; 120 if (end > sourceRange) 121 range -= end - sourceRange; 122 *clippedStart = start; 123 *clippedRange = range; 124 } 125 126 // Returns false if no clipping is necessary, i.e., x, y, width, height stay the same. 127 inline bool clip2D(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, 128 GC3Dsizei sourceWidth, GC3Dsizei sourceHeight, 129 GC3Dint* clippedX, GC3Dint* clippedY, GC3Dsizei* clippedWidth, GC3Dsizei*clippedHeight) 130 { 131 ASSERT(clippedX && clippedY && clippedWidth && clippedHeight); 132 clip1D(x, width, sourceWidth, clippedX, clippedWidth); 133 clip1D(y, height, sourceHeight, clippedY, clippedHeight); 134 return (*clippedX != x || *clippedY != y || *clippedWidth != width || *clippedHeight != height); 135 } 136 88 137 class WebGLRenderingContextBase : public CanvasRenderingContext, public ActiveDOMObject { 89 138 public: … … 133 182 GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data); 134 183 135 v oid copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);184 virtual void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border) = 0; 136 185 void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height); 137 186 … … 238 287 void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param); 239 288 240 v oid texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,241 GC3Dsizei width, GC3Dsizei height,242 GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&);243 v oid texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,244 GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&);245 v oid texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,246 GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&);247 v oid texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,248 GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&);289 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 290 GC3Dsizei width, GC3Dsizei height, 291 GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionCode&) = 0; 292 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 293 GC3Denum format, GC3Denum type, ImageData*, ExceptionCode&) = 0; 294 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 295 GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionCode&) = 0; 296 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 297 GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionCode&) = 0; 249 298 #if ENABLE(VIDEO) 250 v oid texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,251 GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&);299 virtual void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, 300 GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionCode&) = 0; 252 301 #endif 253 302 … … 585 634 void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&); 586 635 void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&); 587 v oid texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&);588 v oid texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&);636 virtual void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum internalformat, GC3Denum format, GC3Denum type, const void* pixels, ExceptionCode&) = 0; 637 virtual void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionCode&) = 0; 589 638 590 639 void checkTextureCompleteness(const char*, bool); … … 625 674 // Helper function to check input format/type for functions {copy}Tex{Sub}Image. 626 675 // Generates GL error and returns false if parameters are invalid. 627 bool validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level);676 virtual bool validateTexFuncFormatAndType(const char* functionName, GC3Denum internalformat, GC3Denum format, GC3Denum type, GC3Dint level) = 0; 628 677 629 678 // Helper function to check input level for functions {copy}Tex{Sub}Image. … … 632 681 633 682 enum TexFuncValidationFunctionType { 634 NotTexSubImage2D, 635 TexSubImage2D, 683 TexImage, 684 TexSubImage, 685 CopyTexImage 636 686 }; 637 687 … … 651 701 // Helper function to check input parameters for functions {copy}Tex{Sub}Image. 652 702 // Generates GL error and returns false if parameters are invalid. 653 bool validateTexFuncParameters(const char* functionName,654 TexFuncValidationFunctionType,655 GC3Denum target, GC3Dint level,656 GC3Denum internalformat,657 GC3Dsizei width, GC3Dsizei height, GC3Dint border,658 GC3Denum format, GC3Denum type);703 virtual bool validateTexFuncParameters(const char* functionName, 704 TexFuncValidationFunctionType, 705 GC3Denum target, GC3Dint level, 706 GC3Denum internalformat, 707 GC3Dsizei width, GC3Dsizei height, GC3Dint border, 708 GC3Denum format, GC3Denum type) = 0; 659 709 660 710 enum NullDisposition { … … 666 716 // is of the correct type and contains enough data for the texImage call. 667 717 // Generates GL error and returns false if parameters are invalid. 668 bool validateTexFuncData(const char* functionName, GC3Dint level,669 GC3Dsizei width, GC3Dsizei height,670 GC3Denum format, GC3Denum type,671 ArrayBufferView* pixels,672 NullDisposition);718 virtual bool validateTexFuncData(const char* functionName, GC3Dint level, 719 GC3Dsizei width, GC3Dsizei height, 720 GC3Denum internalformat, GC3Denum format, GC3Denum type, 721 ArrayBufferView* pixels, 722 NullDisposition) = 0; 673 723 674 724 // Helper function to validate a given texture format is settable as in -
trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h
r179530 r179842 509 509 RGBA32F = 0x8814, 510 510 RGB32F = 0x8815, 511 RGBA16 = 0x881A,511 RGBA16F = 0x881A, 512 512 RGB16F = 0x881B, 513 513 VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD,
Note:
See TracChangeset
for help on using the changeset viewer.