Index: Source/modules/webgl/WebGLRenderingContextBase.cpp |
diff --git a/Source/modules/webgl/WebGLRenderingContextBase.cpp b/Source/modules/webgl/WebGLRenderingContextBase.cpp |
index 53aaea0151620316a369e2c80916623f0b6df6ab..c04cf510b7030195219e387d5673d41dff9deb29 100644 |
--- a/Source/modules/webgl/WebGLRenderingContextBase.cpp |
+++ b/Source/modules/webgl/WebGLRenderingContextBase.cpp |
@@ -222,33 +222,6 @@ void WebGLRenderingContextBase::willDestroyContext(WebGLRenderingContextBase* co |
namespace { |
-// ScopedDrawingBufferBinder is used for ReadPixels/CopyTexImage2D/CopySubImage2D to read from |
-// a multisampled DrawingBuffer. In this situation, we need to blit to a single sampled buffer |
-// for reading, during which the bindings could be changed and need to be recovered. |
-class ScopedDrawingBufferBinder { |
- STACK_ALLOCATED(); |
-public: |
- ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding) |
- : m_drawingBuffer(drawingBuffer) |
- , m_readFramebufferBinding(framebufferBinding) |
- { |
- // Commit DrawingBuffer if needed (e.g., for multisampling) |
- if (!m_readFramebufferBinding && m_drawingBuffer) |
- m_drawingBuffer->commit(); |
- } |
- |
- ~ScopedDrawingBufferBinder() |
- { |
- // Restore DrawingBuffer if needed |
- if (!m_readFramebufferBinding && m_drawingBuffer) |
- m_drawingBuffer->restoreFramebufferBindings(); |
- } |
- |
-private: |
- DrawingBuffer* m_drawingBuffer; |
- Member<WebGLFramebuffer> m_readFramebufferBinding; |
-}; |
- |
GLint clamp(GLint value, GLint min, GLint max) |
{ |
if (value < min) |
@@ -1608,6 +1581,8 @@ void WebGLRenderingContextBase::bufferDataImpl(GLenum target, long long size, co |
if (!validateValueFitNonNegInt32("bufferData", "size", size)) |
return; |
+ buffer->setSize(size); |
+ |
webContext()->bufferData(target, static_cast<GLsizeiptr>(size), data, usage); |
} |
@@ -3729,33 +3704,16 @@ DOMArrayBufferView::ViewType WebGLRenderingContextBase::readPixelsExpectedArrayB |
} |
} |
-void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, DOMArrayBufferView* pixels) |
+bool WebGLRenderingContextBase::validateReadPixelsFuncParameters(GLsizei width, GLsizei height, GLenum format, GLenum type, long long bufferSize) |
{ |
- if (isContextLost()) |
- return; |
- // Due to WebGL's same-origin restrictions, it is not possible to |
- // taint the origin using the WebGL API. |
- ASSERT(canvas()->originClean()); |
- // Validate input parameters. |
- if (!pixels) { |
- synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayBufferView"); |
- return; |
- } |
if (!validateReadPixelsFormatAndType(format, type)) |
- return; |
- GLenum readBufferInternalFormat = 0, readBufferType = 0; |
+ return false; |
WebGLFramebuffer* readFramebufferBinding = nullptr; |
+ GLenum readBufferInternalFormat = 0, readBufferType = 0; |
if (!validateReadBufferAndGetInfo("readPixels", readFramebufferBinding, &readBufferInternalFormat, &readBufferType)) |
- return; |
+ return false; |
if (!validateReadPixelsFormatTypeCombination(format, type, readBufferInternalFormat, readBufferType)) |
- return; |
- |
- DOMArrayBufferView::ViewType expectedViewType = readPixelsExpectedArrayBufferViewType(type); |
- // Validate array type against pixel type. |
- if (pixels->type() != expectedViewType) { |
- synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView was the wrong type for the pixel format"); |
- return; |
- } |
+ return false; |
// Calculate array size, taking into consideration of PACK_ALIGNMENT. |
unsigned totalBytesRequired = 0; |
@@ -3763,22 +3721,54 @@ void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsi |
GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding); |
if (error != GL_NO_ERROR) { |
synthesizeGLError(error, "readPixels", "invalid dimensions"); |
- return; |
+ return false; |
} |
- if (pixels->byteLength() < totalBytesRequired) { |
- synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions"); |
- return; |
+ if (bufferSize < static_cast<long long>(totalBytesRequired)) { |
+ synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "buffer is not large enough for dimensions"); |
+ return false; |
} |
+ return true; |
+} |
+ |
+void WebGLRenderingContextBase::readPixelsImpl(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* data, long long bufferSize) |
+{ |
+ // Due to WebGL's same-origin restrictions, it is not possible to |
+ // taint the origin using the WebGL API. |
+ ASSERT(canvas()->originClean()); |
+ |
+ if (!validateReadPixelsFuncParameters(width, height, format, type, bufferSize)) |
+ return; |
clearIfComposited(); |
- void* data = pixels->baseAddress(); |
+ GLenum target = isWebGL2OrHigher() ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER; |
+ WebGLFramebuffer* readFramebufferBinding = getFramebufferBinding(target); |
Zhenyao Mo
2015/08/19 17:20:23
nit: ASSERT(readFramebufferBinding) here?
yunchao
2015/08/20 08:16:39
Seems that we can't add this assertion. In my opin
Zhenyao Mo
2015/08/20 17:27:34
You are right.
|
{ |
ScopedDrawingBufferBinder binder(drawingBuffer(), readFramebufferBinding); |
webContext()->readPixels(x, y, width, height, format, type, data); |
} |
} |
+void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, DOMArrayBufferView* pixels) |
+{ |
+ if (isContextLost()) |
+ return; |
+ // Validate input parameters. |
+ if (!pixels) { |
+ synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayBufferView"); |
+ return; |
+ } |
+ |
+ DOMArrayBufferView::ViewType expectedViewType = readPixelsExpectedArrayBufferViewType(type); |
+ // Validate array type against pixel type. |
+ if (pixels->type() != expectedViewType) { |
+ synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView was the wrong type for the pixel format"); |
+ return; |
+ } |
+ |
+ readPixelsImpl(x, y, width, height, format, type, pixels->baseAddress(), static_cast<long long>(pixels->byteLength())); |
+} |
+ |
void WebGLRenderingContextBase::renderbufferStorageImpl( |
GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, |
const char* functionName) |