Commit c0c0046b authored by jbauman@chromium.org's avatar jbauman@chromium.org

Add WebGraphicsContext support for readbacks from any framebuffer.

This is needed for https://bugs.webkit.org/show_bug.cgi?id=65658 .

BUG=55927
TEST=


Review URL: http://codereview.chromium.org/7566046

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95898 0039d316-1c4b-4281-b951-d872f2087c98
parent 632983f7
...@@ -274,8 +274,11 @@ void WebGraphicsContext3DCommandBufferImpl::FlipVertically( ...@@ -274,8 +274,11 @@ void WebGraphicsContext3DCommandBufferImpl::FlipVertically(
bool WebGraphicsContext3DCommandBufferImpl::readBackFramebuffer( bool WebGraphicsContext3DCommandBufferImpl::readBackFramebuffer(
unsigned char* pixels, unsigned char* pixels,
size_t buffer_size) { size_t buffer_size,
if (buffer_size != static_cast<size_t>(4 * width() * height())) { WebGLId buffer,
int width,
int height) {
if (buffer_size != static_cast<size_t>(4 * width * height)) {
return false; return false;
} }
...@@ -286,11 +289,11 @@ bool WebGraphicsContext3DCommandBufferImpl::readBackFramebuffer( ...@@ -286,11 +289,11 @@ bool WebGraphicsContext3DCommandBufferImpl::readBackFramebuffer(
// vertical flip is only a temporary solution anyway until Chrome // vertical flip is only a temporary solution anyway until Chrome
// is fully GPU composited, it wasn't worth the complexity. // is fully GPU composited, it wasn't worth the complexity.
bool mustRestoreFBO = (bound_fbo_ != 0); bool mustRestoreFBO = (bound_fbo_ != buffer);
if (mustRestoreFBO) { if (mustRestoreFBO) {
gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); gl_->BindFramebuffer(GL_FRAMEBUFFER, buffer);
} }
gl_->ReadPixels(0, 0, cached_width_, cached_height_, gl_->ReadPixels(0, 0, width, height,
GL_RGBA, GL_UNSIGNED_BYTE, pixels); GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// Swizzle red and blue channels // Swizzle red and blue channels
...@@ -305,13 +308,19 @@ bool WebGraphicsContext3DCommandBufferImpl::readBackFramebuffer( ...@@ -305,13 +308,19 @@ bool WebGraphicsContext3DCommandBufferImpl::readBackFramebuffer(
#ifdef FLIP_FRAMEBUFFER_VERTICALLY #ifdef FLIP_FRAMEBUFFER_VERTICALLY
if (pixels) { if (pixels) {
FlipVertically(pixels, cached_width_, cached_height_); FlipVertically(pixels, width, height);
} }
#endif #endif
return true; return true;
} }
bool WebGraphicsContext3DCommandBufferImpl::readBackFramebuffer(
unsigned char* pixels,
size_t buffer_size) {
return readBackFramebuffer(pixels, buffer_size, 0, width(), height());
}
void WebGraphicsContext3DCommandBufferImpl::synthesizeGLError( void WebGraphicsContext3DCommandBufferImpl::synthesizeGLError(
WGC3Denum error) { WGC3Denum error) {
if (find(synthetic_errors_.begin(), synthetic_errors_.end(), error) == if (find(synthetic_errors_.begin(), synthetic_errors_.end(), error) ==
......
...@@ -69,6 +69,8 @@ class WebGraphicsContext3DCommandBufferImpl ...@@ -69,6 +69,8 @@ class WebGraphicsContext3DCommandBufferImpl
virtual void reshape(int width, int height); virtual void reshape(int width, int height);
virtual bool readBackFramebuffer(unsigned char* pixels, size_t buffer_size); virtual bool readBackFramebuffer(unsigned char* pixels, size_t buffer_size);
virtual bool readBackFramebuffer(unsigned char* pixels, size_t buffer_size,
WebGLId framebuffer, int width, int height);
virtual WebGLId getPlatformTextureId(); virtual WebGLId getPlatformTextureId();
virtual void prepareTexture(); virtual void prepareTexture();
......
...@@ -822,10 +822,13 @@ void WebGraphicsContext3DInProcessCommandBufferImpl::FlipVertically( ...@@ -822,10 +822,13 @@ void WebGraphicsContext3DInProcessCommandBufferImpl::FlipVertically(
bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer( bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer(
unsigned char* pixels, unsigned char* pixels,
size_t buffer_size) { size_t buffer_size,
WebGLId framebuffer,
int width,
int height) {
// TODO(gmam): See if we can comment this in. // TODO(gmam): See if we can comment this in.
// ClearContext(); // ClearContext();
if (buffer_size != static_cast<size_t>(4 * width() * height())) { if (buffer_size != static_cast<size_t>(4 * width * height)) {
return false; return false;
} }
...@@ -836,11 +839,11 @@ bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer( ...@@ -836,11 +839,11 @@ bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer(
// vertical flip is only a temporary solution anyway until Chrome // vertical flip is only a temporary solution anyway until Chrome
// is fully GPU composited, it wasn't worth the complexity. // is fully GPU composited, it wasn't worth the complexity.
bool mustRestoreFBO = (bound_fbo_ != 0); bool mustRestoreFBO = (bound_fbo_ != framebuffer);
if (mustRestoreFBO) { if (mustRestoreFBO) {
gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); gl_->BindFramebuffer(GL_FRAMEBUFFER, framebuffer);
} }
gl_->ReadPixels(0, 0, cached_width_, cached_height_, gl_->ReadPixels(0, 0, width, height,
GL_RGBA, GL_UNSIGNED_BYTE, pixels); GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// Swizzle red and blue channels // Swizzle red and blue channels
...@@ -855,13 +858,19 @@ bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer( ...@@ -855,13 +858,19 @@ bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer(
#ifdef FLIP_FRAMEBUFFER_VERTICALLY #ifdef FLIP_FRAMEBUFFER_VERTICALLY
if (pixels) { if (pixels) {
FlipVertically(pixels, cached_width_, cached_height_); FlipVertically(pixels, width, height);
} }
#endif #endif
return true; return true;
} }
bool WebGraphicsContext3DInProcessCommandBufferImpl::readBackFramebuffer(
unsigned char* pixels,
size_t buffer_size) {
return readBackFramebuffer(pixels, buffer_size, 0, width(), height());
}
void WebGraphicsContext3DInProcessCommandBufferImpl::synthesizeGLError( void WebGraphicsContext3DInProcessCommandBufferImpl::synthesizeGLError(
WGC3Denum error) { WGC3Denum error) {
if (find(synthetic_errors_.begin(), synthetic_errors_.end(), error) == if (find(synthetic_errors_.begin(), synthetic_errors_.end(), error) ==
......
...@@ -70,6 +70,8 @@ class WebGraphicsContext3DInProcessCommandBufferImpl ...@@ -70,6 +70,8 @@ class WebGraphicsContext3DInProcessCommandBufferImpl
virtual void reshape(int width, int height); virtual void reshape(int width, int height);
virtual bool readBackFramebuffer(unsigned char* pixels, size_t buffer_size); virtual bool readBackFramebuffer(unsigned char* pixels, size_t buffer_size);
virtual bool readBackFramebuffer(unsigned char* pixels, size_t buffer_size,
WebGLId framebuffer, int width, int height);
virtual WebGLId getPlatformTextureId(); virtual WebGLId getPlatformTextureId();
virtual void prepareTexture(); virtual void prepareTexture();
......
...@@ -588,8 +588,9 @@ void WebGraphicsContext3DInProcessImpl::FlipVertically( ...@@ -588,8 +588,9 @@ void WebGraphicsContext3DInProcessImpl::FlipVertically(
#endif #endif
bool WebGraphicsContext3DInProcessImpl::readBackFramebuffer( bool WebGraphicsContext3DInProcessImpl::readBackFramebuffer(
unsigned char* pixels, size_t bufferSize) { unsigned char* pixels, size_t bufferSize, WebGLId framebuffer,
if (bufferSize != static_cast<size_t>(4 * width() * height())) int width, int height) {
if (bufferSize != static_cast<size_t>(4 * width * height))
return false; return false;
makeContextCurrent(); makeContextCurrent();
...@@ -601,8 +602,14 @@ bool WebGraphicsContext3DInProcessImpl::readBackFramebuffer( ...@@ -601,8 +602,14 @@ bool WebGraphicsContext3DInProcessImpl::readBackFramebuffer(
// vertical flip is only a temporary solution anyway until Chrome // vertical flip is only a temporary solution anyway until Chrome
// is fully GPU composited, it wasn't worth the complexity. // is fully GPU composited, it wasn't worth the complexity.
ResolveMultisampledFramebuffer(0, 0, cached_width_, cached_height_); // In this implementation fbo_, not 0, is the drawing buffer, so
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_); // special-case that.
if (framebuffer == 0)
framebuffer = fbo_;
if (framebuffer == fbo_)
ResolveMultisampledFramebuffer(0, 0, width, height);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
GLint pack_alignment = 4; GLint pack_alignment = 4;
bool must_restore_pack_alignment = false; bool must_restore_pack_alignment = false;
...@@ -616,13 +623,13 @@ bool WebGraphicsContext3DInProcessImpl::readBackFramebuffer( ...@@ -616,13 +623,13 @@ bool WebGraphicsContext3DInProcessImpl::readBackFramebuffer(
// FIXME: consider testing for presence of GL_OES_read_format // FIXME: consider testing for presence of GL_OES_read_format
// and GL_EXT_read_format_bgra, and using GL_BGRA_EXT here // and GL_EXT_read_format_bgra, and using GL_BGRA_EXT here
// directly. // directly.
glReadPixels(0, 0, cached_width_, cached_height_, glReadPixels(0, 0, width, height,
GL_RGBA, GL_UNSIGNED_BYTE, pixels); GL_RGBA, GL_UNSIGNED_BYTE, pixels);
for (size_t i = 0; i < bufferSize; i += 4) { for (size_t i = 0; i < bufferSize; i += 4) {
std::swap(pixels[i], pixels[i + 2]); std::swap(pixels[i], pixels[i + 2]);
} }
} else { } else {
glReadPixels(0, 0, cached_width_, cached_height_, glReadPixels(0, 0, width, height,
GL_BGRA, GL_UNSIGNED_BYTE, pixels); GL_BGRA, GL_UNSIGNED_BYTE, pixels);
} }
...@@ -633,12 +640,17 @@ bool WebGraphicsContext3DInProcessImpl::readBackFramebuffer( ...@@ -633,12 +640,17 @@ bool WebGraphicsContext3DInProcessImpl::readBackFramebuffer(
#ifdef FLIP_FRAMEBUFFER_VERTICALLY #ifdef FLIP_FRAMEBUFFER_VERTICALLY
if (pixels) if (pixels)
FlipVertically(pixels, cached_width_, cached_height_); FlipVertically(pixels, width, height);
#endif #endif
return true; return true;
} }
bool WebGraphicsContext3DInProcessImpl::readBackFramebuffer(
unsigned char* pixels, size_t bufferSize) {
return readBackFramebuffer(pixels, bufferSize, fbo_, width(), height());
}
void WebGraphicsContext3DInProcessImpl::synthesizeGLError(WGC3Denum error) { void WebGraphicsContext3DInProcessImpl::synthesizeGLError(WGC3Denum error) {
if (synthetic_errors_set_.find(error) == synthetic_errors_set_.end()) { if (synthetic_errors_set_.find(error) == synthetic_errors_set_.end()) {
synthetic_errors_set_.insert(error); synthetic_errors_set_.insert(error);
......
...@@ -70,6 +70,8 @@ class WebGraphicsContext3DInProcessImpl : public WebGraphicsContext3D { ...@@ -70,6 +70,8 @@ class WebGraphicsContext3DInProcessImpl : public WebGraphicsContext3D {
virtual void reshape(int width, int height); virtual void reshape(int width, int height);
virtual bool readBackFramebuffer(unsigned char* pixels, size_t bufferSize); virtual bool readBackFramebuffer(unsigned char* pixels, size_t bufferSize);
virtual bool readBackFramebuffer(unsigned char* pixels, size_t buffer_size,
WebGLId framebuffer, int width, int height);
virtual WebGLId getPlatformTextureId(); virtual WebGLId getPlatformTextureId();
virtual void prepareTexture(); virtual void prepareTexture();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment