Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1547)

Unified Diff: Source/modules/webgl/WebGLRenderingContextBase.cpp

Issue 1300573002: WebGL 2: add readPixels API to read pixels into pixel pack buffer (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);

Powered by Google App Engine
This is Rietveld 408576698