| Index: Source/modules/webgl/WebGLRenderingContextBase.cpp
|
| diff --git a/Source/modules/webgl/WebGLRenderingContextBase.cpp b/Source/modules/webgl/WebGLRenderingContextBase.cpp
|
| index 53aaea0151620316a369e2c80916623f0b6df6ab..e7ae2706065aa6304a0e718e6597a6d1cdcdab62 100644
|
| --- a/Source/modules/webgl/WebGLRenderingContextBase.cpp
|
| +++ b/Source/modules/webgl/WebGLRenderingContextBase.cpp
|
| @@ -967,6 +967,7 @@ void WebGLRenderingContextBase::initializeNewContext()
|
| m_unpackPremultiplyAlpha = false;
|
| m_unpackColorspaceConversion = GC3D_BROWSER_DEFAULT_WEBGL;
|
| m_boundArrayBuffer = nullptr;
|
| + m_boundPixelPackBuffer = nullptr;
|
| m_currentProgram = nullptr;
|
| m_framebufferBinding = nullptr;
|
| m_renderbufferBinding = nullptr;
|
| @@ -1098,6 +1099,7 @@ WebGLRenderingContextBase::~WebGLRenderingContextBase()
|
| // Remove all references to WebGLObjects so if they are the last reference
|
| // they will be freed before the last context is removed from the context group.
|
| m_boundArrayBuffer = nullptr;
|
| + m_boundPixelPackBuffer = nullptr;
|
| m_defaultVertexArrayObject = nullptr;
|
| m_boundVertexArrayObject = nullptr;
|
| m_vertexAttrib0Buffer = nullptr;
|
| @@ -3729,6 +3731,31 @@ DOMArrayBufferView::ViewType WebGLRenderingContextBase::readPixelsExpectedArrayB
|
| }
|
| }
|
|
|
| +bool WebGLRenderingContextBase::validateReadPixelsFuncParameters(GLsizei width, GLsizei height, GLenum format, GLenum type, unsigned domArrayBufferLength, WebGLFramebuffer*& readFramebufferBinding)
|
| +{
|
| + if (!validateReadPixelsFormatAndType(format, type))
|
| + return false;
|
| + GLenum readBufferInternalFormat = 0, readBufferType = 0;
|
| + if (!validateReadBufferAndGetInfo("readPixels", readFramebufferBinding, &readBufferInternalFormat, &readBufferType))
|
| + return false;
|
| + if (!validateReadPixelsFormatTypeCombination(format, type, readBufferInternalFormat, readBufferType))
|
| + return false;
|
| +
|
| + // Calculate array size, taking into consideration of PACK_ALIGNMENT.
|
| + unsigned totalBytesRequired = 0;
|
| + unsigned padding = 0;
|
| + GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
|
| + if (error != GL_NO_ERROR) {
|
| + synthesizeGLError(error, "readPixels", "invalid dimensions");
|
| + return false;
|
| + }
|
| + if (domArrayBufferLength && domArrayBufferLength < totalBytesRequired) {
|
| + synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions");
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, DOMArrayBufferView* pixels)
|
| {
|
| if (isContextLost())
|
| @@ -3736,19 +3763,15 @@ void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsi
|
| // Due to WebGL's same-origin restrictions, it is not possible to
|
| // taint the origin using the WebGL API.
|
| ASSERT(canvas()->originClean());
|
| + if (isWebGL2OrHigher() && m_boundPixelPackBuffer.get()) {
|
| + synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "PIXEL_PACK buffer should not bound");
|
| + return;
|
| + }
|
| // Validate input parameters.
|
| if (!pixels) {
|
| synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayBufferView");
|
| return;
|
| }
|
| - if (!validateReadPixelsFormatAndType(format, type))
|
| - return;
|
| - GLenum readBufferInternalFormat = 0, readBufferType = 0;
|
| - WebGLFramebuffer* readFramebufferBinding = nullptr;
|
| - if (!validateReadBufferAndGetInfo("readPixels", readFramebufferBinding, &readBufferInternalFormat, &readBufferType))
|
| - return;
|
| - if (!validateReadPixelsFormatTypeCombination(format, type, readBufferInternalFormat, readBufferType))
|
| - return;
|
|
|
| DOMArrayBufferView::ViewType expectedViewType = readPixelsExpectedArrayBufferViewType(type);
|
| // Validate array type against pixel type.
|
| @@ -3757,18 +3780,9 @@ void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsi
|
| return;
|
| }
|
|
|
| - // Calculate array size, taking into consideration of PACK_ALIGNMENT.
|
| - unsigned totalBytesRequired = 0;
|
| - unsigned padding = 0;
|
| - GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
|
| - if (error != GL_NO_ERROR) {
|
| - synthesizeGLError(error, "readPixels", "invalid dimensions");
|
| - return;
|
| - }
|
| - if (pixels->byteLength() < totalBytesRequired) {
|
| - synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions");
|
| + WebGLFramebuffer* readFramebufferBinding = nullptr;
|
| + if (!validateReadPixelsFuncParameters(format, type, width, height, pixels->byteLength(), readFramebufferBinding))
|
| return;
|
| - }
|
|
|
| clearIfComposited();
|
| void* data = pixels->baseAddress();
|
| @@ -3779,6 +3793,29 @@ void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsi
|
| }
|
| }
|
|
|
| +void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, long long offset)
|
| +{
|
| + if (isContextLost() || !isWebGL2OrHigher())
|
| + return;
|
| + // Due to WebGL's same-origin restrictions, it is not possible to
|
| + // taint the origin using the WebGL API.
|
| + ASSERT(canvas()->originClean());
|
| + if (!m_boundPixelPackBuffer.get()) {
|
| + synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "no PIXEL_PACK buffer bound");
|
| + return;
|
| + }
|
| +
|
| + WebGLFramebuffer* readFramebufferBinding = nullptr;
|
| + if (!validateReadPixelsFuncParameters(format, type, width, height, 0, readFramebufferBinding))
|
| + return;
|
| +
|
| + clearIfComposited();
|
| + {
|
| + ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding);
|
| + webContext()->readPixels(x, y, width, height, format, type, (void*)offset);
|
| + }
|
| +}
|
| +
|
| void WebGLRenderingContextBase::renderbufferStorageImpl(
|
| GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height,
|
| const char* functionName)
|
| @@ -6588,6 +6625,7 @@ DEFINE_TRACE(WebGLRenderingContextBase)
|
| visitor->trace(m_contextLostCallbackAdapter);
|
| visitor->trace(m_errorMessageCallbackAdapter);
|
| visitor->trace(m_boundArrayBuffer);
|
| + visitor->trace(m_boundPixelPackBuffer);
|
| visitor->trace(m_defaultVertexArrayObject);
|
| visitor->trace(m_boundVertexArrayObject);
|
| visitor->trace(m_vertexAttrib0Buffer);
|
|
|