OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 1864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1875 return; | 1875 return; |
1876 if (border) { | 1876 if (border) { |
1877 synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "border not 0"); | 1877 synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "border not 0"); |
1878 return; | 1878 return; |
1879 } | 1879 } |
1880 if (!validateCompressedTexDimensions("compressedTexImage2D", CompressedTexIm age, target, level, width, height, 1, internalformat)) | 1880 if (!validateCompressedTexDimensions("compressedTexImage2D", CompressedTexIm age, target, level, width, height, 1, internalformat)) |
1881 return; | 1881 return; |
1882 if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, 1, internalformat, data)) | 1882 if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, 1, internalformat, data)) |
1883 return; | 1883 return; |
1884 | 1884 |
1885 if (tex->isImmutable()) { | |
1886 synthesizeGLError(GL_INVALID_OPERATION, "compressedTexImage2D", "attempt ed to modify immutable texture"); | |
1887 return; | |
1888 } | |
1889 if (isNPOTStrict() && level && WebGLTexture::isNPOT(width, height)) { | 1885 if (isNPOTStrict() && level && WebGLTexture::isNPOT(width, height)) { |
1890 synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "level > 0 n ot power of 2"); | 1886 synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "level > 0 n ot power of 2"); |
1891 return; | 1887 return; |
1892 } | 1888 } |
1893 webContext()->compressedTexImage2D(target, level, internalformat, width, hei ght, | 1889 webContext()->compressedTexImage2D(target, level, internalformat, width, hei ght, |
1894 border, data->byteLength(), data->baseAddress()); | 1890 border, data->byteLength(), data->baseAddress()); |
1895 tex->setLevelInfo(target, level, internalformat, width, height, 1, GL_UNSIGN ED_BYTE); | |
1896 } | 1891 } |
1897 | 1892 |
1898 void WebGLRenderingContextBase::compressedTexSubImage2D(GLenum target, GLint lev el, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, DOMArrayBufferView* data) | 1893 void WebGLRenderingContextBase::compressedTexSubImage2D(GLenum target, GLint lev el, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, DOMArrayBufferView* data) |
1899 { | 1894 { |
1900 if (isContextLost()) | 1895 if (isContextLost()) |
1901 return; | 1896 return; |
1902 WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target , true); | 1897 WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target , true); |
1903 if (!tex) | 1898 if (!tex) |
1904 return; | 1899 return; |
1905 if (!validateTexFuncLevel("compressedTexSubImage2D", target, level)) | 1900 if (!validateTexFuncLevel("compressedTexSubImage2D", target, level)) |
1906 return; | 1901 return; |
1907 if (!validateCompressedTexFormat("compressedTexSubImage2D", format)) | 1902 if (!validateCompressedTexFormat("compressedTexSubImage2D", format)) |
1908 return; | 1903 return; |
1909 if (format != tex->getInternalFormat(target, level)) { | |
1910 synthesizeGLError(GL_INVALID_OPERATION, "compressedTexSubImage2D", "form at does not match texture format"); | |
1911 return; | |
1912 } | |
1913 if (!validateCompressedTexSubDimensions("compressedTexSubImage2D", target, l evel, xoffset, yoffset, 0, width, height, 1, format, tex)) | 1904 if (!validateCompressedTexSubDimensions("compressedTexSubImage2D", target, l evel, xoffset, yoffset, 0, width, height, 1, format, tex)) |
1914 return; | 1905 return; |
1915 if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, 1, format, data)) | 1906 if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, 1, format, data)) |
1916 return; | 1907 return; |
1917 webContext()->compressedTexSubImage2D(target, level, xoffset, yoffset, | 1908 webContext()->compressedTexSubImage2D(target, level, xoffset, yoffset, |
1918 width, height, format, data->byteLength(), data->baseAddress()); | 1909 width, height, format, data->byteLength(), data->baseAddress()); |
1919 } | 1910 } |
1920 | 1911 |
1912 | |
1921 bool WebGLRenderingContextBase::validateSettableTexFormat(const char* functionNa me, GLenum format) | 1913 bool WebGLRenderingContextBase::validateSettableTexFormat(const char* functionNa me, GLenum format) |
1922 { | 1914 { |
1923 if (isWebGL2OrHigher()) | 1915 if (isWebGL2OrHigher()) |
1924 return true; | 1916 return true; |
1925 | 1917 |
1926 if (WebGLImageConversion::getChannelBitsByFormat(format) & WebGLImageConvers ion::ChannelDepthStencil) { | 1918 if (WebGLImageConversion::getChannelBitsByFormat(format) & WebGLImageConvers ion::ChannelDepthStencil) { |
1927 synthesizeGLError(GL_INVALID_OPERATION, functionName, "format can not be set, only rendered to"); | 1919 synthesizeGLError(GL_INVALID_OPERATION, functionName, "format can not be set, only rendered to"); |
1928 return false; | 1920 return false; |
1929 } | 1921 } |
1930 return true; | 1922 return true; |
(...skipping 26 matching lines...) Expand all Loading... | |
1957 if (!validateCopyTexFormat("copyTexImage2D", internalformat)) | 1949 if (!validateCopyTexFormat("copyTexImage2D", internalformat)) |
1958 return; | 1950 return; |
1959 if (!validateTexFuncDimensions("copyTexImage2D", CopyTexImage, target, level , width, height, 1)) | 1951 if (!validateTexFuncDimensions("copyTexImage2D", CopyTexImage, target, level , width, height, 1)) |
1960 return; | 1952 return; |
1961 if (border) { | 1953 if (border) { |
1962 synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "border != 0"); | 1954 synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "border != 0"); |
1963 return; | 1955 return; |
1964 } | 1956 } |
1965 if (!validateSettableTexFormat("copyTexImage2D", internalformat)) | 1957 if (!validateSettableTexFormat("copyTexImage2D", internalformat)) |
1966 return; | 1958 return; |
1967 if (tex->isImmutable()) { | |
1968 synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "attempted to modify immutable texture"); | |
1969 return; | |
1970 } | |
1971 WebGLFramebuffer* readFramebufferBinding = nullptr; | 1959 WebGLFramebuffer* readFramebufferBinding = nullptr; |
1972 if (!validateReadBufferAndGetInfo("copyTexImage2D", readFramebufferBinding)) | 1960 if (!validateReadBufferAndGetInfo("copyTexImage2D", readFramebufferBinding)) |
1973 return; | 1961 return; |
1974 if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFra mebufferColorFormat())) { | |
1975 synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "framebuffer i s incompatible format"); | |
1976 return; | |
1977 } | |
1978 if (isNPOTStrict() && level && WebGLTexture::isNPOT(width, height)) { | 1962 if (isNPOTStrict() && level && WebGLTexture::isNPOT(width, height)) { |
1979 synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not pow er of 2"); | 1963 synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not pow er of 2"); |
1980 return; | 1964 return; |
1981 } | 1965 } |
1982 clearIfComposited(); | 1966 clearIfComposited(); |
1983 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding); | 1967 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding); |
1984 webContext()->copyTexImage2D(target, level, internalformat, x, y, width, hei ght, border); | 1968 webContext()->copyTexImage2D(target, level, internalformat, x, y, width, hei ght, border); |
1985 tex->setLevelInfo(target, level, internalformat, width, height, 1, WebGLText ure::getValidTypeForInternalFormat(internalformat)); | |
1986 } | 1969 } |
1987 | 1970 |
1988 void WebGLRenderingContextBase::copyTexSubImage2D(GLenum target, GLint level, GL int xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) | 1971 void WebGLRenderingContextBase::copyTexSubImage2D(GLenum target, GLint level, GL int xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) |
1989 { | 1972 { |
1990 if (isContextLost()) | 1973 if (isContextLost()) |
1991 return; | 1974 return; |
1992 WebGLFramebuffer* readFramebufferBinding = nullptr; | 1975 WebGLFramebuffer* readFramebufferBinding = nullptr; |
1993 if (!validateCopyTexSubImage("copyTexSubImage2D", target, level, xoffset, yo ffset, 0, x, y, width, height)) | 1976 if (!validateCopyTexSubImage("copyTexSubImage2D", target, level, xoffset, yo ffset, 0, x, y, width, height)) |
1994 return; | 1977 return; |
1995 if (!validateReadBufferAndGetInfo("copyTexSubImage2D", readFramebufferBindin g)) | 1978 if (!validateReadBufferAndGetInfo("copyTexSubImage2D", readFramebufferBindin g)) |
1996 return; | 1979 return; |
1997 WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true ); | |
1998 ASSERT(tex); | |
1999 if (!isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(t arget, level), boundFramebufferColorFormat())) { | |
2000 synthesizeGLError(GL_INVALID_OPERATION, "copyTexSubImage2D", "framebuffe r is incompatible format"); | |
2001 return; | |
2002 } | |
2003 clearIfComposited(); | 1980 clearIfComposited(); |
2004 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding); | 1981 ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding); |
2005 webContext()->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width , height); | 1982 webContext()->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width , height); |
2006 } | 1983 } |
2007 | 1984 |
2008 WebGLBuffer* WebGLRenderingContextBase::createBuffer() | 1985 WebGLBuffer* WebGLRenderingContextBase::createBuffer() |
2009 { | 1986 { |
2010 if (isContextLost()) | 1987 if (isContextLost()) |
2011 return nullptr; | 1988 return nullptr; |
2012 WebGLBuffer* o = WebGLBuffer::create(this); | 1989 WebGLBuffer* o = WebGLBuffer::create(this); |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2471 webContext()->frontFace(mode); | 2448 webContext()->frontFace(mode); |
2472 } | 2449 } |
2473 | 2450 |
2474 void WebGLRenderingContextBase::generateMipmap(GLenum target) | 2451 void WebGLRenderingContextBase::generateMipmap(GLenum target) |
2475 { | 2452 { |
2476 if (isContextLost()) | 2453 if (isContextLost()) |
2477 return; | 2454 return; |
2478 WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false); | 2455 WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false); |
2479 if (!tex) | 2456 if (!tex) |
2480 return; | 2457 return; |
2481 if (!tex->canGenerateMipmaps()) { | |
2482 synthesizeGLError(GL_INVALID_OPERATION, "generateMipmap", "cannot genera te mipmaps"); | |
2483 return; | |
2484 } | |
2485 if (tex->getInternalFormat(target, 0) == GL_SRGB_EXT || tex->getInternalForm at(target, 0) == GL_SRGB_ALPHA_EXT) { | |
2486 synthesizeGLError(GL_INVALID_OPERATION, "generateMipmap", "cannot genera te mipmaps for sRGB textures"); | |
2487 return; | |
2488 } | |
2489 if (!validateSettableTexFormat("generateMipmap", tex->getInternalFormat(targ et, 0))) | |
2490 return; | |
2491 webContext()->generateMipmap(target); | 2458 webContext()->generateMipmap(target); |
2492 tex->generateMipmapLevelInfo(); | |
2493 } | 2459 } |
2494 | 2460 |
2495 WebGLActiveInfo* WebGLRenderingContextBase::getActiveAttrib(WebGLProgram* progra m, GLuint index) | 2461 WebGLActiveInfo* WebGLRenderingContextBase::getActiveAttrib(WebGLProgram* progra m, GLuint index) |
2496 { | 2462 { |
2497 if (isContextLost() || !validateWebGLObject("getActiveAttrib", program)) | 2463 if (isContextLost() || !validateWebGLObject("getActiveAttrib", program)) |
2498 return nullptr; | 2464 return nullptr; |
2499 WebGraphicsContext3D::ActiveInfo info; | 2465 WebGraphicsContext3D::ActiveInfo info; |
2500 if (!webContext()->getActiveAttrib(objectOrZero(program), index, info)) | 2466 if (!webContext()->getActiveAttrib(objectOrZero(program), index, info)) |
2501 return nullptr; | 2467 return nullptr; |
2502 return WebGLActiveInfo::create(info.name, info.type, info.size); | 2468 return WebGLActiveInfo::create(info.name, info.type, info.size); |
(...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3666 if (isContextLost()) | 3632 if (isContextLost()) |
3667 return; | 3633 return; |
3668 webContext()->polygonOffset(factor, units); | 3634 webContext()->polygonOffset(factor, units); |
3669 } | 3635 } |
3670 | 3636 |
3671 bool WebGLRenderingContextBase::validateReadBufferAndGetInfo(const char* functio nName, WebGLFramebuffer*& readFramebufferBinding) | 3637 bool WebGLRenderingContextBase::validateReadBufferAndGetInfo(const char* functio nName, WebGLFramebuffer*& readFramebufferBinding) |
3672 { | 3638 { |
3673 readFramebufferBinding = getReadFramebufferBinding(); | 3639 readFramebufferBinding = getReadFramebufferBinding(); |
3674 if (readFramebufferBinding) { | 3640 if (readFramebufferBinding) { |
3675 const char* reason = "framebuffer incomplete"; | 3641 const char* reason = "framebuffer incomplete"; |
3676 if (readFramebufferBinding->checkStatus(&reason) != GL_FRAMEBUFFER_COMPL ETE) { | 3642 if (readFramebufferBinding->checkDepthStencilStatus(&reason) != GL_FRAME BUFFER_COMPLETE) { |
3677 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, re ason); | 3643 synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, re ason); |
3678 return false; | 3644 return false; |
3679 } | 3645 } |
3680 if (!readFramebufferBinding->getReadBufferFormatAndType(nullptr, nullptr )) { | |
3681 synthesizeGLError(GL_INVALID_OPERATION, functionName, "no image to r ead from"); | |
3682 return false; | |
3683 } | |
3684 } else { | 3646 } else { |
3685 if (m_readBufferOfDefaultFramebuffer == GL_NONE) { | 3647 if (m_readBufferOfDefaultFramebuffer == GL_NONE) { |
3686 ASSERT(isWebGL2OrHigher()); | 3648 ASSERT(isWebGL2OrHigher()); |
3687 synthesizeGLError(GL_INVALID_OPERATION, functionName, "no image to r ead from"); | 3649 synthesizeGLError(GL_INVALID_OPERATION, functionName, "no image to r ead from"); |
3688 return false; | 3650 return false; |
3689 } | 3651 } |
3690 } | 3652 } |
3691 return true; | 3653 return true; |
3692 } | 3654 } |
3693 | 3655 |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4043 return GL_RGBA32F_EXT; | 4005 return GL_RGBA32F_EXT; |
4044 if (type == GL_FLOAT && internalformat == GL_RGB | 4006 if (type == GL_FLOAT && internalformat == GL_RGB |
4045 && extensionsUtil()->isExtensionEnabled("GL_CHROMIUM_color_buffer_float_ rgb")) | 4007 && extensionsUtil()->isExtensionEnabled("GL_CHROMIUM_color_buffer_float_ rgb")) |
4046 return GL_RGB32F_EXT; | 4008 return GL_RGB32F_EXT; |
4047 return internalformat; | 4009 return internalformat; |
4048 } | 4010 } |
4049 | 4011 |
4050 void WebGLRenderingContextBase::texImage2DBase(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLe num type, const void* pixels) | 4012 void WebGLRenderingContextBase::texImage2DBase(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLe num type, const void* pixels) |
4051 { | 4013 { |
4052 // All calling functions check isContextLost, so a duplicate check is not ne eded here. | 4014 // All calling functions check isContextLost, so a duplicate check is not ne eded here. |
4053 WebGLTexture* tex = validateTextureBinding("texImage2D", target, true); | |
4054 ASSERT(tex); | |
4055 webContext()->texImage2D(target, level, convertTexInternalFormat(internalfor mat, type), width, height, border, format, type, pixels); | 4015 webContext()->texImage2D(target, level, convertTexInternalFormat(internalfor mat, type), width, height, border, format, type, pixels); |
4056 tex->setLevelInfo(target, level, internalformat, width, height, 1, type); | |
4057 } | 4016 } |
4058 | 4017 |
4059 void WebGLRenderingContextBase::texImage2DImpl(GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type, Image* image, WebGLImageConversion: :ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha) | 4018 void WebGLRenderingContextBase::texImage2DImpl(GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type, Image* image, WebGLImageConversion: :ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha) |
4060 { | 4019 { |
4061 // All calling functions check isContextLost, so a duplicate check is not ne eded here. | 4020 // All calling functions check isContextLost, so a duplicate check is not ne eded here. |
4062 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { | 4021 if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) { |
4063 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. | 4022 // The UNSIGNED_INT_10F_11F_11F_REV type pack/unpack isn't implemented. |
4064 type = GL_FLOAT; | 4023 type = GL_FLOAT; |
4065 } | 4024 } |
4066 Vector<uint8_t> data; | 4025 Vector<uint8_t> data; |
(...skipping 22 matching lines...) Expand all Loading... | |
4089 } | 4048 } |
4090 | 4049 |
4091 bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexIma geFunctionType functionType, TexFuncValidationSourceType sourceType, GLenum targ et, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei d epth, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset, GL int zoffset) | 4050 bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexIma geFunctionType functionType, TexFuncValidationSourceType sourceType, GLenum targ et, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei d epth, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset, GL int zoffset) |
4092 { | 4051 { |
4093 if (!validateTexFuncLevel(functionName, target, level)) | 4052 if (!validateTexFuncLevel(functionName, target, level)) |
4094 return false; | 4053 return false; |
4095 WebGLTexture* texture = validateTextureBinding(functionName, target, true); | 4054 WebGLTexture* texture = validateTextureBinding(functionName, target, true); |
4096 if (!texture) | 4055 if (!texture) |
4097 return false; | 4056 return false; |
4098 | 4057 |
4099 if (functionType == TexSubImage) { | |
4100 if (!texture->isValid(target, level)) { | |
4101 synthesizeGLError(GL_INVALID_OPERATION, functionName, "no previously defined texture image"); | |
4102 return false; | |
4103 } | |
4104 } | |
4105 | |
4106 if (internalformat == 0) | |
4107 internalformat = texture->getInternalFormat(target, level); | |
4108 if (!validateTexFuncParameters(functionName, functionType, target, level, in ternalformat, width, height, depth, border, format, type)) | 4058 if (!validateTexFuncParameters(functionName, functionType, target, level, in ternalformat, width, height, depth, border, format, type)) |
4109 return false; | 4059 return false; |
4110 | 4060 |
4111 if (functionType == TexSubImage) { | 4061 if (functionType == TexSubImage) { |
4112 if (!validateSettableTexFormat(functionName, format)) | 4062 if (!validateSettableTexFormat(functionName, format)) |
4113 return false; | 4063 return false; |
4114 if (!validateSize(functionName, xoffset, yoffset, zoffset)) | 4064 if (!validateSize(functionName, xoffset, yoffset, zoffset)) |
4115 return false; | 4065 return false; |
4116 // Before checking if it is in the range, check if overflow happens firs t. | |
4117 CheckedInt<GLint> maxX = xoffset, maxY = yoffset, maxZ = zoffset; | |
4118 maxX += width; | |
4119 maxY += height; | |
4120 maxZ += depth; | |
4121 if (!maxX.isValid() || !maxY.isValid() || !maxZ.isValid() | |
4122 || maxX.value() > texture->getWidth(target, level) | |
4123 || maxY.value() > texture->getHeight(target, level) | |
4124 || maxZ.value() > texture->getDepth(target, level)) { | |
4125 synthesizeGLError(GL_INVALID_VALUE, functionName, "dimensions out of range"); | |
4126 return false; | |
4127 } | |
4128 if (!isWebGL2OrHigher() && texture->getType(target, level) != type) { | |
4129 synthesizeGLError(GL_INVALID_OPERATION, functionName, "type of incom ing data does not match that used to define the texture"); | |
4130 return false; | |
4131 } | |
4132 } else { | 4066 } else { |
4133 if (texture->isImmutable()) { | |
4134 synthesizeGLError(GL_INVALID_OPERATION, functionName, "attempted to modify immutable texture"); | |
4135 return false; | |
4136 } | |
4137 | |
4138 // Depth is for WebGL 2.0 only where iSNPOTStrict() is always false. | 4067 // Depth is for WebGL 2.0 only where iSNPOTStrict() is always false. |
4139 if (isNPOTStrict() && level && WebGLTexture::isNPOT(width, height)) { | 4068 if (isNPOTStrict() && level && WebGLTexture::isNPOT(width, height)) { |
4140 synthesizeGLError(GL_INVALID_VALUE, functionName, "level > 0 not pow er of 2"); | 4069 synthesizeGLError(GL_INVALID_VALUE, functionName, "level > 0 not pow er of 2"); |
4141 return false; | 4070 return false; |
4142 } | 4071 } |
4143 // For SourceArrayBufferView, function validateTexFuncData() would handl e whether to validate the SettableTexFormat | 4072 // For SourceArrayBufferView, function validateTexFuncData() would handl e whether to validate the SettableTexFormat |
4144 // by checking if the ArrayBufferView is null or not. | 4073 // by checking if the ArrayBufferView is null or not. |
4145 if (sourceType != SourceArrayBufferView) { | 4074 if (sourceType != SourceArrayBufferView) { |
4146 if (!validateSettableTexFormat(functionName, format)) | 4075 if (!validateSettableTexFormat(functionName, format)) |
4147 return false; | 4076 return false; |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4337 webContext()->deleteTexture(targetTexture); | 4266 webContext()->deleteTexture(targetTexture); |
4338 } | 4267 } |
4339 } | 4268 } |
4340 | 4269 |
4341 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, | 4270 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, |
4342 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) | 4271 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) |
4343 { | 4272 { |
4344 if (isContextLost() || !validateHTMLCanvasElement("texImage2D", canvas, exce ptionState) || !validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, 0, 0, 0)) | 4273 if (isContextLost() || !validateHTMLCanvasElement("texImage2D", canvas, exce ptionState) || !validateTexFunc("texImage2D", TexImage, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 1, 0, format, type, 0, 0, 0)) |
4345 return; | 4274 return; |
4346 | 4275 |
4347 WebGLTexture* texture = validateTextureBinding("texImage2D", target, true); | |
4348 ASSERT(texture); | |
4349 | |
4350 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support f loat/integer/sRGB internal format. | 4276 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support f loat/integer/sRGB internal format. |
4351 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats. | 4277 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats. |
4352 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || !canUseTexImageCanvasByGPU(internalformat, type)) { | 4278 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || !canUseTexImageCanvasByGPU(internalformat, type)) { |
4353 // 2D canvas has only FrontBuffer. | 4279 // 2D canvas has only FrontBuffer. |
4354 texImage2DImpl(target, level, internalformat, format, type, canvas->copi edImage(FrontBuffer, PreferAcceleration).get(), | 4280 texImage2DImpl(target, level, internalformat, format, type, canvas->copi edImage(FrontBuffer, PreferAcceleration).get(), |
4355 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); | 4281 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); |
4356 return; | 4282 return; |
4357 } | 4283 } |
4358 | 4284 |
4359 texImage2DBase(target, level, internalformat, canvas->width(), canvas->heigh t(), 0, format, type, 0); | 4285 texImage2DBase(target, level, internalformat, canvas->width(), canvas->heigh t(), 0, format, type, 0); |
4286 WebGLTexture* texture = validateTextureBinding("texImage2D", target, true); | |
4287 ASSERT(texture); | |
4360 texImageCanvasByGPU(TexImage2DByGPU, texture, target, level, internalformat, type, 0, 0, 0, canvas); | 4288 texImageCanvasByGPU(TexImage2DByGPU, texture, target, level, internalformat, type, 0, 0, 0, canvas); |
4361 texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas ->height(), 1, type); | |
4362 } | 4289 } |
4363 | 4290 |
4364 PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video) | 4291 PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video) |
4365 { | 4292 { |
4366 IntSize size(video->videoWidth(), video->videoHeight()); | 4293 IntSize size(video->videoWidth(), video->videoHeight()); |
4367 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size); | 4294 ImageBuffer* buf = m_generatedImageCache.imageBuffer(size); |
4368 if (!buf) { | 4295 if (!buf) { |
4369 synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory"); | 4296 synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory"); |
4370 return nullptr; | 4297 return nullptr; |
4371 } | 4298 } |
4372 IntRect destRect(0, 0, size.width(), size.height()); | 4299 IntRect destRect(0, 0, size.width(), size.height()); |
4373 video->paintCurrentFrame(buf->canvas(), destRect, nullptr); | 4300 video->paintCurrentFrame(buf->canvas(), destRect, nullptr); |
4374 return buf->newImageSnapshot(); | 4301 return buf->newImageSnapshot(); |
4375 } | 4302 } |
4376 | 4303 |
4377 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, | 4304 void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLint int ernalformat, |
4378 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) | 4305 GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& excepti onState) |
4379 { | 4306 { |
4380 if (isContextLost() || !validateHTMLVideoElement("texImage2D", video, except ionState) | 4307 if (isContextLost() || !validateHTMLVideoElement("texImage2D", video, except ionState) |
4381 || !validateTexFunc("texImage2D", TexImage, SourceHTMLVideoElement, targ et, level, internalformat, video->videoWidth(), video->videoHeight(), 1, 0, form at, type, 0, 0, 0)) | 4308 || !validateTexFunc("texImage2D", TexImage, SourceHTMLVideoElement, targ et, level, internalformat, video->videoWidth(), video->videoHeight(), 1, 0, form at, type, 0, 0, 0)) |
4382 return; | 4309 return; |
4383 | 4310 |
4384 // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible. | 4311 // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible. |
4385 // Otherwise, it will fall back to the normal SW path. | 4312 // Otherwise, it will fall back to the normal SW path. |
4386 WebGLTexture* texture = validateTextureBinding("texImage2D", target, true); | 4313 WebGLTexture* texture = validateTextureBinding("texImage2D", target, true); |
4387 ASSERT(texture); | 4314 ASSERT(texture); |
4388 if (GL_TEXTURE_2D == target) { | 4315 if (GL_TEXTURE_2D == target) { |
4389 if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level) | 4316 if (Extensions3DUtil::canUseCopyTextureCHROMIUM(target, internalformat, type, level) |
4390 && video->copyVideoTextureToPlatformTexture(webContext(), texture->o bject(), internalformat, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) { | 4317 && video->copyVideoTextureToPlatformTexture(webContext(), texture->o bject(), internalformat, type, m_unpackPremultiplyAlpha, m_unpackFlipY)) { |
4391 texture->setLevelInfo(target, level, internalformat, video->videoWid th(), video->videoHeight(), 1, type); | |
4392 return; | 4318 return; |
4393 } | 4319 } |
4394 | 4320 |
4395 // Try using an accelerated image buffer, this allows YUV conversion to be done on the GPU. | 4321 // Try using an accelerated image buffer, this allows YUV conversion to be done on the GPU. |
4396 OwnPtr<ImageBufferSurface> surface = adoptPtr(new AcceleratedImageBuffer Surface(IntSize(video->videoWidth(), video->videoHeight()))); | 4322 OwnPtr<ImageBufferSurface> surface = adoptPtr(new AcceleratedImageBuffer Surface(IntSize(video->videoWidth(), video->videoHeight()))); |
4397 if (surface->isValid()) { | 4323 if (surface->isValid()) { |
4398 OwnPtr<ImageBuffer> imageBuffer(ImageBuffer::create(surface.release( ))); | 4324 OwnPtr<ImageBuffer> imageBuffer(ImageBuffer::create(surface.release( ))); |
4399 if (imageBuffer) { | 4325 if (imageBuffer) { |
4400 // The video element paints an RGBA frame into our surface here. By using an AcceleratedImageBufferSurface, | 4326 // The video element paints an RGBA frame into our surface here. By using an AcceleratedImageBufferSurface, |
4401 // we enable the WebMediaPlayer implementation to do any necessa ry color space conversion on the GPU (though it | 4327 // we enable the WebMediaPlayer implementation to do any necessa ry color space conversion on the GPU (though it |
4402 // may still do a CPU conversion and upload the results). | 4328 // may still do a CPU conversion and upload the results). |
4403 video->paintCurrentFrame(imageBuffer->canvas(), IntRect(0, 0, vi deo->videoWidth(), video->videoHeight()), nullptr); | 4329 video->paintCurrentFrame(imageBuffer->canvas(), IntRect(0, 0, vi deo->videoWidth(), video->videoHeight()), nullptr); |
4404 | 4330 |
4405 // This is a straight GPU-GPU copy, any necessary color space co nversion was handled in the paintCurrentFrameInContext() call. | 4331 // This is a straight GPU-GPU copy, any necessary color space co nversion was handled in the paintCurrentFrameInContext() call. |
4406 if (imageBuffer->copyToPlatformTexture(webContext(), texture->ob ject(), internalformat, type, | 4332 if (imageBuffer->copyToPlatformTexture(webContext(), texture->ob ject(), internalformat, type, |
4407 level, m_unpackPremultiplyAlpha, m_unpackFlipY)) { | 4333 level, m_unpackPremultiplyAlpha, m_unpackFlipY)) { |
4408 texture->setLevelInfo(target, level, internalformat, video-> videoWidth(), video->videoHeight(), 1, type); | |
4409 return; | 4334 return; |
4410 } | 4335 } |
4411 } | 4336 } |
4412 } | 4337 } |
4413 } | 4338 } |
4414 | 4339 |
4415 // Normal pure SW path. | 4340 // Normal pure SW path. |
4416 RefPtr<Image> image = videoFrameToImage(video); | 4341 RefPtr<Image> image = videoFrameToImage(video); |
4417 if (!image) | 4342 if (!image) |
4418 return; | 4343 return; |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4608 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, | 4533 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, |
4609 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) | 4534 GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& excep tionState) |
4610 { | 4535 { |
4611 if (isContextLost() || !validateHTMLCanvasElement("texSubImage2D", canvas, e xceptionState) | 4536 if (isContextLost() || !validateHTMLCanvasElement("texSubImage2D", canvas, e xceptionState) |
4612 || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElemen t, target, level, 0, canvas->width(), canvas->height(), 1, 0, format, type, xoff set, yoffset, 0)) | 4537 || !validateTexFunc("texSubImage2D", TexSubImage, SourceHTMLCanvasElemen t, target, level, 0, canvas->width(), canvas->height(), 1, 0, format, type, xoff set, yoffset, 0)) |
4613 return; | 4538 return; |
4614 | 4539 |
4615 WebGLTexture* texture = validateTextureBinding("texSubImage2D", target, true ); | 4540 WebGLTexture* texture = validateTextureBinding("texSubImage2D", target, true ); |
4616 ASSERT(texture); | 4541 ASSERT(texture); |
4617 | 4542 |
4618 GLint internalformat = texture->getInternalFormat(target, level); | 4543 // FIXME: Implement GPU-to-GPU path for WebGL 2 and more internal formats. |
4544 bool useReadBackPath = isWebGL2OrHigher() | |
4545 || extensionEnabled(OESTextureFloatName) | |
4546 || extensionEnabled(OESTextureHalfFloatName) | |
4547 || extensionEnabled(EXTsRGBName); | |
4619 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support f loat/integer/sRGB internal format. | 4548 // texImageCanvasByGPU relies on copyTextureCHROMIUM which doesn't support f loat/integer/sRGB internal format. |
4620 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats. | 4549 // FIXME: relax the constrains if copyTextureCHROMIUM is upgraded to handle more formats. |
4621 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || !canUseTexImageCanvasByGPU(internalformat, type)) { | 4550 if (!canvas->renderingContext() || !canvas->renderingContext()->isAccelerate d() || useReadBackPath) { |
4622 // 2D canvas has only FrontBuffer. | 4551 // 2D canvas has only FrontBuffer. |
4623 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas- >copiedImage(FrontBuffer, PreferAcceleration).get(), | 4552 texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas- >copiedImage(FrontBuffer, PreferAcceleration).get(), |
4624 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); | 4553 WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremulti plyAlpha); |
4625 return; | 4554 return; |
4626 } | 4555 } |
4627 | 4556 |
4628 texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, typ e, xoffset, yoffset, 0, canvas); | 4557 texImageCanvasByGPU(TexSubImage2DByGPU, texture, target, level, GL_RGBA, typ e, xoffset, yoffset, 0, canvas); |
4629 } | 4558 } |
4630 | 4559 |
4631 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, | 4560 void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, |
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5371 case GL_SCISSOR_BOX: | 5300 case GL_SCISSOR_BOX: |
5372 case GL_VIEWPORT: | 5301 case GL_VIEWPORT: |
5373 length = 4; | 5302 length = 4; |
5374 break; | 5303 break; |
5375 default: | 5304 default: |
5376 notImplemented(); | 5305 notImplemented(); |
5377 } | 5306 } |
5378 return WebGLAny(scriptState, DOMInt32Array::create(value, length)); | 5307 return WebGLAny(scriptState, DOMInt32Array::create(value, length)); |
5379 } | 5308 } |
5380 | 5309 |
5381 bool WebGLRenderingContextBase::isTexInternalFormatColorBufferCombinationValid(G Lenum texInternalFormat, GLenum colorBufferFormat) | |
5382 { | |
5383 unsigned need = WebGLImageConversion::getChannelBitsByFormat(texInternalForm at); | |
5384 unsigned have = WebGLImageConversion::getChannelBitsByFormat(colorBufferForm at); | |
5385 return (need & have) == need; | |
5386 } | |
5387 | |
5388 GLenum WebGLRenderingContextBase::boundFramebufferColorFormat() | |
5389 { | |
5390 if (m_framebufferBinding && m_framebufferBinding->object()) | |
5391 return m_framebufferBinding->colorBufferFormat(); | |
5392 if (m_requestedAttributes.alpha()) | |
5393 return GL_RGBA; | |
5394 return GL_RGB; | |
5395 } | |
5396 | |
5397 WebGLTexture* WebGLRenderingContextBase::validateTextureBinding(const char* func tionName, GLenum target, bool useSixEnumsForCubeMap) | 5310 WebGLTexture* WebGLRenderingContextBase::validateTextureBinding(const char* func tionName, GLenum target, bool useSixEnumsForCubeMap) |
5398 { | 5311 { |
5399 WebGLTexture* tex = nullptr; | 5312 WebGLTexture* tex = nullptr; |
5400 switch (target) { | 5313 switch (target) { |
5401 case GL_TEXTURE_2D: | 5314 case GL_TEXTURE_2D: |
5402 tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get(); | 5315 tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get(); |
5403 if (!tex) | 5316 if (!tex) |
5404 synthesizeGLError(GL_INVALID_OPERATION, functionName, "no texture bo und to GL_TEXTURE_2D"); | 5317 synthesizeGLError(GL_INVALID_OPERATION, functionName, "no texture bo und to GL_TEXTURE_2D"); |
5405 break; | 5318 break; |
5406 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: | 5319 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5496 } | 5409 } |
5497 | 5410 |
5498 if (!m_isEXTsRGBFormatsTypesAdded && extensionEnabled(EXTsRGBName)) { | 5411 if (!m_isEXTsRGBFormatsTypesAdded && extensionEnabled(EXTsRGBName)) { |
5499 ADD_VALUES_TO_SET(m_supportedInternalFormats, kSupportedInternalForm atsEXTsRGB); | 5412 ADD_VALUES_TO_SET(m_supportedInternalFormats, kSupportedInternalForm atsEXTsRGB); |
5500 ADD_VALUES_TO_SET(m_supportedFormats, kSupportedFormatsEXTsRGB); | 5413 ADD_VALUES_TO_SET(m_supportedFormats, kSupportedFormatsEXTsRGB); |
5501 ADD_VALUES_TO_SET(m_supportedFormatTypeCombinations, kSupportedForma tTypesEXTsRGB); | 5414 ADD_VALUES_TO_SET(m_supportedFormatTypeCombinations, kSupportedForma tTypesEXTsRGB); |
5502 m_isEXTsRGBFormatsTypesAdded = true; | 5415 m_isEXTsRGBFormatsTypesAdded = true; |
5503 } | 5416 } |
5504 } | 5417 } |
5505 | 5418 |
5506 if (m_supportedInternalFormats.find(internalformat) == m_supportedInternalFo rmats.end()) { | 5419 if (internalformat != 0 && m_supportedInternalFormats.find(internalformat) = = m_supportedInternalFormats.end()) { |
5507 if (functionType == TexImage) { | 5420 if (functionType == TexImage) { |
5508 synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid internalf ormat"); | 5421 synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid internalf ormat"); |
5509 } else { | 5422 } else { |
5510 synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid internalfo rmat"); | 5423 synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid internalfo rmat"); |
5511 } | 5424 } |
5512 return false; | 5425 return false; |
5513 } | 5426 } |
5514 if (m_supportedFormats.find(format) == m_supportedFormats.end()) { | 5427 if (m_supportedFormats.find(format) == m_supportedFormats.end()) { |
5515 synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format"); | 5428 synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format"); |
5516 return false; | 5429 return false; |
5517 } | 5430 } |
5518 if (m_supportedTypes.find(type) == m_supportedTypes.end()) { | 5431 if (m_supportedTypes.find(type) == m_supportedTypes.end()) { |
5519 synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type"); | 5432 synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type"); |
5520 return false; | 5433 return false; |
5521 } | 5434 } |
5522 FormatType combinationQuery = { internalformat, format, type }; | 5435 FormatType combinationQuery = { internalformat, format, type }; |
5523 if (m_supportedFormatTypeCombinations.find(combinationQuery) == m_supportedF ormatTypeCombinations.end()) { | 5436 if (internalformat != 0 && m_supportedFormatTypeCombinations.find(combinatio nQuery) == m_supportedFormatTypeCombinations.end()) { |
5524 synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid internalf ormat/format/type combination"); | 5437 synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid internalf ormat/format/type combination"); |
5525 return false; | 5438 return false; |
5526 } | 5439 } |
5527 | 5440 |
5528 if (format == GL_DEPTH_COMPONENT && level > 0 && !isWebGL2OrHigher()) { | 5441 if (format == GL_DEPTH_COMPONENT && level > 0 && !isWebGL2OrHigher()) { |
5529 synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 f or DEPTH_COMPONENT format"); | 5442 synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 f or DEPTH_COMPONENT format"); |
5530 return false; | 5443 return false; |
5531 } | 5444 } |
5532 if (format == GL_DEPTH_STENCIL_OES && level > 0 && !isWebGL2OrHigher()) { | 5445 if (format == GL_DEPTH_STENCIL_OES && level > 0 && !isWebGL2OrHigher()) { |
5533 synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 f or DEPTH_STENCIL format"); | 5446 synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 f or DEPTH_STENCIL format"); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5748 return false; | 5661 return false; |
5749 // Before checking if it is in the range, check if overflow happens first. | 5662 // Before checking if it is in the range, check if overflow happens first. |
5750 CheckedInt<GLint> maxX = xoffset; | 5663 CheckedInt<GLint> maxX = xoffset; |
5751 maxX += width; | 5664 maxX += width; |
5752 CheckedInt<GLint> maxY = yoffset; | 5665 CheckedInt<GLint> maxY = yoffset; |
5753 maxY += height; | 5666 maxY += height; |
5754 if (!maxX.isValid() || !maxY.isValid()) { | 5667 if (!maxX.isValid() || !maxY.isValid()) { |
5755 synthesizeGLError(GL_INVALID_VALUE, functionName, "bad dimensions"); | 5668 synthesizeGLError(GL_INVALID_VALUE, functionName, "bad dimensions"); |
5756 return false; | 5669 return false; |
5757 } | 5670 } |
5758 if (maxX.value() > tex->getWidth(target, level) || maxY.value() > tex->getHe ight(target, level) || zoffset >= tex->getDepth(target, level)) { | |
5759 synthesizeGLError(GL_INVALID_VALUE, functionName, "rectangle out of rang e"); | |
5760 return false; | |
5761 } | |
5762 GLenum internalformat = tex->getInternalFormat(target, level); | |
5763 if (!validateSettableTexFormat(functionName, internalformat)) | |
5764 return false; | |
5765 | |
5766 return true; | 5671 return true; |
5767 } | 5672 } |
5768 | 5673 |
5769 bool WebGLRenderingContextBase::validateCompressedTexFormat(const char* function Name, GLenum format) | 5674 bool WebGLRenderingContextBase::validateCompressedTexFormat(const char* function Name, GLenum format) |
5770 { | 5675 { |
5771 if (!m_compressedTextureFormats.contains(format)) { | 5676 if (!m_compressedTextureFormats.contains(format)) { |
5772 synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format"); | 5677 synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format"); |
5773 return false; | 5678 return false; |
5774 } | 5679 } |
5775 return true; | 5680 return true; |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6018 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: | 5923 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: |
6019 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: | 5924 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: |
6020 case GL_COMPRESSED_RGBA8_ETC2_EAC: | 5925 case GL_COMPRESSED_RGBA8_ETC2_EAC: |
6021 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: { | 5926 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: { |
6022 const int kBlockWidth = 4; | 5927 const int kBlockWidth = 4; |
6023 const int kBlockHeight = 4; | 5928 const int kBlockHeight = 4; |
6024 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) { | 5929 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) { |
6025 synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset or yo ffset not multiple of 4"); | 5930 synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset or yo ffset not multiple of 4"); |
6026 return false; | 5931 return false; |
6027 } | 5932 } |
6028 CheckedInt<GLint> maxX = xoffset, maxY = yoffset; | |
6029 maxX += width; | |
6030 maxY += height; | |
6031 if (!maxX.isValid() || ((width % kBlockWidth) && maxX.value() != tex->ge tWidth(target, level))) { | |
Ken Russell (switch to Gerrit)
2016/02/11 01:25:01
Are all of these compressed texture formats' valid
Zhenyao Mo
2016/02/11 02:16:46
It is my next step to consolidate compressed textu
| |
6032 synthesizeGLError(GL_INVALID_OPERATION, functionName, "width not mul tiple of 4 and width + xoffset not equal to width of the texture level for ETC2/ EAC format texture"); | |
6033 return false; | |
6034 } | |
6035 if (!maxY.isValid() || ((height % kBlockHeight) && maxY.value() != tex-> getHeight(target, level))) { | |
6036 synthesizeGLError(GL_INVALID_OPERATION, functionName, "height not mu ltiple of 4 and height + yoffset not equal to height of the texture level for ET C2/EAC format texture"); | |
6037 return false; | |
6038 } | |
6039 return validateCompressedTexDimensions(functionName, TexSubImage, target , level, width, height, depth, format); | 5933 return validateCompressedTexDimensions(functionName, TexSubImage, target , level, width, height, depth, format); |
6040 } | 5934 } |
6041 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: | 5935 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: |
6042 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: | 5936 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: |
6043 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: | 5937 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: |
6044 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { | 5938 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { |
6045 const int kBlockWidth = 4; | 5939 const int kBlockWidth = 4; |
6046 const int kBlockHeight = 4; | 5940 const int kBlockHeight = 4; |
6047 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) { | 5941 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) { |
6048 synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset or yo ffset not multiple of 4"); | 5942 synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset or yo ffset not multiple of 4"); |
6049 return false; | 5943 return false; |
6050 } | 5944 } |
6051 // Before checking if it is in the range, check if overflow happens firs t. | |
6052 CheckedInt<GLint> maxX = xoffset, maxY = yoffset; | |
6053 maxX += width; | |
6054 maxY += height; | |
6055 if (!maxX.isValid() || !maxY.isValid() || maxX.value() > tex->getWidth(t arget, level) | |
6056 || maxY.value() > tex->getHeight(target, level)) { | |
6057 synthesizeGLError(GL_INVALID_VALUE, functionName, "dimensions out of range"); | |
6058 return false; | |
6059 } | |
6060 return validateCompressedTexDimensions(functionName, TexSubImage, target , level, width, height, depth, format); | 5945 return validateCompressedTexDimensions(functionName, TexSubImage, target , level, width, height, depth, format); |
6061 } | 5946 } |
6062 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: | 5947 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: |
6063 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: | 5948 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: |
6064 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: | 5949 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: |
6065 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { | 5950 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: { |
6066 if ((xoffset != 0) || (yoffset != 0)) { | 5951 if ((xoffset != 0) || (yoffset != 0)) { |
6067 synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset and y offset must be zero"); | 5952 synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset and y offset must be zero"); |
6068 return false; | 5953 return false; |
6069 } | 5954 } |
6070 if (width != tex->getWidth(target, level) | |
6071 || height != tex->getHeight(target, level)) { | |
6072 synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions mu st match existing level"); | |
6073 return false; | |
6074 } | |
6075 return validateCompressedTexDimensions(functionName, TexSubImage, target , level, width, height, depth, format); | 5955 return validateCompressedTexDimensions(functionName, TexSubImage, target , level, width, height, depth, format); |
6076 } | 5956 } |
6077 case GC3D_COMPRESSED_ATC_RGB_AMD: | 5957 case GC3D_COMPRESSED_ATC_RGB_AMD: |
6078 case GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD: | 5958 case GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD: |
6079 case GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD: | 5959 case GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD: |
6080 case GL_ETC1_RGB8_OES: { | 5960 case GL_ETC1_RGB8_OES: { |
6081 synthesizeGLError(GL_INVALID_OPERATION, functionName, "unable to update sub-images with this format"); | 5961 synthesizeGLError(GL_INVALID_OPERATION, functionName, "unable to update sub-images with this format"); |
6082 return false; | 5962 return false; |
6083 } | 5963 } |
6084 default: | 5964 default: |
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6795 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1); | 6675 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1); |
6796 } | 6676 } |
6797 | 6677 |
6798 void WebGLRenderingContextBase::restoreUnpackParameters() | 6678 void WebGLRenderingContextBase::restoreUnpackParameters() |
6799 { | 6679 { |
6800 if (m_unpackAlignment != 1) | 6680 if (m_unpackAlignment != 1) |
6801 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); | 6681 webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); |
6802 } | 6682 } |
6803 | 6683 |
6804 } // namespace blink | 6684 } // namespace blink |
OLD | NEW |