From: José Fonseca Date: Tue, 24 May 2011 08:13:56 +0000 (+0100) Subject: Move snapshooting to glstate. X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=96404a790de7891a30bd4e3e668b436a735efde0;p=apitrace Move snapshooting to glstate. --- diff --git a/glretrace_main.cpp b/glretrace_main.cpp index 1c128d7..6a740d3 100644 --- a/glretrace_main.cpp +++ b/glretrace_main.cpp @@ -103,31 +103,6 @@ checkGlError(Trace::Call &call) { } -static void color_snapshot(Image::Image &image) { - GLint drawbuffer = double_buffer ? GL_BACK : GL_FRONT; - GLint readbuffer = double_buffer ? GL_BACK : GL_FRONT; - glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer); - glGetIntegerv(GL_READ_BUFFER, &readbuffer); - glReadBuffer(drawbuffer); - - glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); - glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE); - glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE); - glPixelStorei(GL_PACK_ROW_LENGTH, 0); - glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0); - glPixelStorei(GL_PACK_SKIP_ROWS, 0); - glPixelStorei(GL_PACK_SKIP_PIXELS, 0); - glPixelStorei(GL_PACK_SKIP_IMAGES, 0); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - - glReadPixels(0, 0, image.width, image.height, GL_RGBA, GL_UNSIGNED_BYTE, image.pixels); - - glPopClientAttrib(); - - glReadBuffer(readbuffer); -} - - void snapshot(unsigned call_no) { if (!drawable || (!snapshot_prefix && !compare_prefix)) { @@ -148,21 +123,25 @@ void snapshot(unsigned call_no) { } } - Image::Image src(drawable->width, drawable->height, true); - color_snapshot(src); + Image::Image *src = glstate::getDrawBufferImage(GL_RGBA); + if (!src) { + return; + } if (snapshot_prefix) { char filename[PATH_MAX]; snprintf(filename, sizeof filename, "%s%010u.png", snapshot_prefix, call_no); - if (src.writePNG(filename) && retrace::verbosity >= 0) { + if (src->writePNG(filename) && retrace::verbosity >= 0) { std::cout << "Wrote " << filename << "\n"; } } if (ref) { - std::cout << "Snapshot " << call_no << " average precision of " << src.compare(*ref) << " bits\n"; + std::cout << "Snapshot " << call_no << " average precision of " << src->compare(*ref) << " bits\n"; delete ref; } + + delete src; } diff --git a/glstate.cpp b/glstate.cpp index 8fdc75d..2fa4cb5 100644 --- a/glstate.cpp +++ b/glstate.cpp @@ -405,6 +405,50 @@ getDrawableBounds(GLint *width, GLint *height) { } +Image::Image * +getDrawBufferImage(GLenum format) { + GLint width, height; + + if (format != GL_RGBA) { + // FIXME: this function can only handle 4-channel images + return NULL; + } + + if (!getDrawableBounds(&width, &height)) { + return NULL; + } + + Image::Image *image = new Image::Image(width, height, true); + if (!image) { + return NULL; + } + + GLint drawbuffer = GL_NONE; + GLint readbuffer = GL_NONE; + glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer); + glGetIntegerv(GL_READ_BUFFER, &readbuffer); + glReadBuffer(drawbuffer); + + glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); + glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE); + glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE); + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0); + glPixelStorei(GL_PACK_SKIP_ROWS, 0); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + glPixelStorei(GL_PACK_SKIP_IMAGES, 0); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); + + glPopClientAttrib(); + + glReadBuffer(readbuffer); + + return image; +} + + static inline void dumpDrawBufferImage(JSONWriter &json, GLenum format) { diff --git a/glstate.hpp b/glstate.hpp index abbfad0..2cc929a 100644 --- a/glstate.hpp +++ b/glstate.hpp @@ -35,6 +35,11 @@ class JSONWriter; +namespace Image { + class Image; +} + + namespace glstate { @@ -46,6 +51,9 @@ void dumpParameters(JSONWriter &json); void dumpCurrentContext(std::ostream &os); +Image::Image * +getDrawBufferImage(GLenum format); + } /* namespace glstate */