X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=glstate.cpp;h=614b069eb59e7c244e19439b65a5ad91263adfc0;hb=788a7cb792894d40c7cf37a3d2b9eaa6edaaa3dd;hp=ccbc9102277126710b709c5b2b8964fe2eb7782e;hpb=0582a6dfacf0f4be1b266390e6b43910d13f5bf4;p=apitrace diff --git a/glstate.cpp b/glstate.cpp index ccbc910..614b069 100644 --- a/glstate.cpp +++ b/glstate.cpp @@ -28,14 +28,13 @@ #include #include -#include -#include #include "image.hpp" #include "json.hpp" #include "glproc.hpp" #include "glsize.hpp" #include "glstate.hpp" +#include "glstate_internal.hpp" #ifdef __APPLE__ @@ -55,517 +54,69 @@ OSStatus CGSGetSurfaceBounds(CGSConnectionID, CGWindowID, CGSSurfaceID, CGRect * #endif /* __APPLE__ */ -namespace glstate { - +/* Change thi to one to force interpreting depth buffers as RGBA, which enables + * visualizing full dynamic range, until we can transmit HDR images to the GUI */ +#define DEPTH_AS_RGBA 0 -static inline void -resetPixelPackState(void) { - 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); - glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); -} - - -static inline void -restorePixelPackState(void) { - glPopClientAttrib(); -} - - -// Mapping from shader type to shader source, used to accumulated the sources -// of different shaders with same type. -typedef std::map ShaderMap; - - -static void -getShaderSource(ShaderMap &shaderMap, GLuint shader) -{ - if (!shader) { - return; - } - - GLint shader_type = 0; - glGetShaderiv(shader, GL_SHADER_TYPE, &shader_type); - if (!shader_type) { - return; - } - - GLint source_length = 0; - glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &source_length); - if (!source_length) { - return; - } - - GLchar *source = new GLchar[source_length]; - GLsizei length = 0; - source[0] = 0; - glGetShaderSource(shader, source_length, &length, source); - - shaderMap[enumToString(shader_type)] += source; - - delete [] source; -} - - -static void -getShaderObjSource(ShaderMap &shaderMap, GLhandleARB shaderObj) -{ - if (!shaderObj) { - return; - } - - GLint object_type = 0; - glGetObjectParameterivARB(shaderObj, GL_OBJECT_TYPE_ARB, &object_type); - if (object_type != GL_SHADER_OBJECT_ARB) { - return; - } - - GLint shader_type = 0; - glGetObjectParameterivARB(shaderObj, GL_OBJECT_SUBTYPE_ARB, &shader_type); - if (!shader_type) { - return; - } - - GLint source_length = 0; - glGetObjectParameterivARB(shaderObj, GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &source_length); - if (!source_length) { - return; - } - - GLcharARB *source = new GLcharARB[source_length]; - GLsizei length = 0; - source[0] = 0; - glGetShaderSource(shaderObj, source_length, &length, source); - - shaderMap[enumToString(shader_type)] += source; - - delete [] source; -} - - -static inline void -dumpProgram(JSONWriter &json, GLint program) -{ - GLint attached_shaders = 0; - glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders); - if (!attached_shaders) { - return; - } - - ShaderMap shaderMap; - - GLuint *shaders = new GLuint[attached_shaders]; - GLsizei count = 0; - glGetAttachedShaders(program, attached_shaders, &count, shaders); - std::sort(shaders, shaders + count); - for (GLsizei i = 0; i < count; ++ i) { - getShaderSource(shaderMap, shaders[i]); - } - delete [] shaders; - - for (ShaderMap::const_iterator it = shaderMap.begin(); it != shaderMap.end(); ++it) { - json.beginMember(it->first); - json.writeString(it->second); - json.endMember(); - } -} - - -static inline void -dumpProgramObj(JSONWriter &json, GLhandleARB programObj) -{ - GLint attached_shaders = 0; - glGetObjectParameterivARB(programObj, GL_OBJECT_ATTACHED_OBJECTS_ARB, &attached_shaders); - if (!attached_shaders) { - return; - } - - ShaderMap shaderMap; - - GLhandleARB *shaderObjs = new GLhandleARB[attached_shaders]; - GLsizei count = 0; - glGetAttachedObjectsARB(programObj, attached_shaders, &count, shaderObjs); - std::sort(shaderObjs, shaderObjs + count); - for (GLsizei i = 0; i < count; ++ i) { - getShaderObjSource(shaderMap, shaderObjs[i]); - } - delete [] shaderObjs; - - for (ShaderMap::const_iterator it = shaderMap.begin(); it != shaderMap.end(); ++it) { - json.beginMember(it->first); - json.writeString(it->second); - json.endMember(); - } -} - -/* - * When fetching the uniform name of an array we usually get name[0] - * so we need to cut the trailing "[0]" in order to properly construct - * array names later. Otherwise we endup with stuff like - * uniformArray[0][0], - * uniformArray[0][1], - * instead of - * uniformArray[0], - * uniformArray[1]. - */ -static std::string -resolveUniformName(const GLchar *name, GLint size) -{ - std::string qualifiedName(name); - if (size > 1) { - std::string::size_type nameLength = qualifiedName.length(); - static const char * const arrayStart = "[0]"; - static const int arrayStartLen = 3; - if (qualifiedName.rfind(arrayStart) == (nameLength - arrayStartLen)) { - qualifiedName = qualifiedName.substr(0, nameLength - 3); - } - } - return qualifiedName; -} - -static void -dumpUniform(JSONWriter &json, GLint program, GLint size, GLenum type, const GLchar *name) { - GLenum elemType; - GLint numElems; - __gl_uniform_size(type, elemType, numElems); - if (elemType == GL_NONE) { - return; - } - - GLfloat fvalues[4*4]; - GLdouble dvalues[4*4]; - GLint ivalues[4*4]; - GLuint uivalues[4*4]; - - GLint i, j; - - std::string qualifiedName = resolveUniformName(name, size); - - for (i = 0; i < size; ++i) { - std::stringstream ss; - ss << qualifiedName; - - if (size > 1) { - ss << '[' << i << ']'; - } - - std::string elemName = ss.str(); - - json.beginMember(elemName); - - GLint location = glGetUniformLocation(program, elemName.c_str()); - - if (numElems > 1) { - json.beginArray(); - } - - switch (elemType) { - case GL_FLOAT: - glGetUniformfv(program, location, fvalues); - for (j = 0; j < numElems; ++j) { - json.writeNumber(fvalues[j]); - } - break; - case GL_DOUBLE: - glGetUniformdv(program, location, dvalues); - for (j = 0; j < numElems; ++j) { - json.writeNumber(dvalues[j]); - } - break; - case GL_INT: - glGetUniformiv(program, location, ivalues); - for (j = 0; j < numElems; ++j) { - json.writeNumber(ivalues[j]); - } - break; - case GL_UNSIGNED_INT: - glGetUniformuiv(program, location, uivalues); - for (j = 0; j < numElems; ++j) { - json.writeNumber(uivalues[j]); - } - break; - case GL_BOOL: - glGetUniformiv(program, location, ivalues); - for (j = 0; j < numElems; ++j) { - json.writeBool(ivalues[j]); - } - break; - default: - assert(0); - break; - } - - if (numElems > 1) { - json.endArray(); - } - - json.endMember(); - } -} - - -static void -dumpUniformARB(JSONWriter &json, GLhandleARB programObj, GLint size, GLenum type, const GLchar *name) { - - GLenum elemType; - GLint numElems; - __gl_uniform_size(type, elemType, numElems); - if (elemType == GL_NONE) { - return; - } - - GLfloat fvalues[4*4]; - GLint ivalues[4*4]; - - GLint i, j; - - std::string qualifiedName = resolveUniformName(name, size); - - for (i = 0; i < size; ++i) { - std::stringstream ss; - ss << qualifiedName; - - if (size > 1) { - ss << '[' << i << ']'; - } - - std::string elemName = ss.str(); - - json.beginMember(elemName); - - GLint location = glGetUniformLocationARB(programObj, elemName.c_str()); - - if (numElems > 1) { - json.beginArray(); - } - switch (elemType) { - case GL_DOUBLE: - // glGetUniformdvARB does not exists - case GL_FLOAT: - glGetUniformfvARB(programObj, location, fvalues); - for (j = 0; j < numElems; ++j) { - json.writeNumber(fvalues[j]); - } - break; - case GL_UNSIGNED_INT: - // glGetUniformuivARB does not exists - case GL_INT: - glGetUniformivARB(programObj, location, ivalues); - for (j = 0; j < numElems; ++j) { - json.writeNumber(ivalues[j]); - } - break; - case GL_BOOL: - glGetUniformivARB(programObj, location, ivalues); - for (j = 0; j < numElems; ++j) { - json.writeBool(ivalues[j]); - } - break; - default: - assert(0); - break; - } - - if (numElems > 1) { - json.endArray(); - } - - json.endMember(); - } -} - - -static inline void -dumpProgramUniforms(JSONWriter &json, GLint program) -{ - GLint active_uniforms = 0; - glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &active_uniforms); - if (!active_uniforms) { - return; - } - - GLint active_uniform_max_length = 0; - glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &active_uniform_max_length); - GLchar *name = new GLchar[active_uniform_max_length]; - if (!name) { - return; - } - - for (GLint index = 0; index < active_uniforms; ++index) { - GLsizei length = 0; - GLint size = 0; - GLenum type = GL_NONE; - glGetActiveUniform(program, index, active_uniform_max_length, &length, &size, &type, name); - - dumpUniform(json, program, size, type, name); - } - - delete [] name; -} - - -static inline void -dumpProgramObjUniforms(JSONWriter &json, GLhandleARB programObj) -{ - GLint active_uniforms = 0; - glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &active_uniforms); - if (!active_uniforms) { - return; - } - - GLint active_uniform_max_length = 0; - glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB, &active_uniform_max_length); - GLchar *name = new GLchar[active_uniform_max_length]; - if (!name) { - return; - } - - for (GLint index = 0; index < active_uniforms; ++index) { - GLsizei length = 0; - GLint size = 0; - GLenum type = GL_NONE; - glGetActiveUniformARB(programObj, index, active_uniform_max_length, &length, &size, &type, name); - - dumpUniformARB(json, programObj, size, type, name); - } - - delete [] name; -} - - -static inline void -dumpArbProgram(JSONWriter &json, GLenum target) -{ - if (!glIsEnabled(target)) { - return; - } - - GLint program_length = 0; - glGetProgramivARB(target, GL_PROGRAM_LENGTH_ARB, &program_length); - if (!program_length) { - return; - } - - GLchar *source = new GLchar[program_length + 1]; - source[0] = 0; - glGetProgramStringARB(target, GL_PROGRAM_STRING_ARB, source); - source[program_length] = 0; - - json.beginMember(enumToString(target)); - json.writeString(source); - json.endMember(); - - delete [] source; -} - - -static inline void -dumpArbProgramUniforms(JSONWriter &json, GLenum target, const char *prefix) -{ - if (!glIsEnabled(target)) { - return; - } - - GLint program_parameters = 0; - glGetProgramivARB(target, GL_PROGRAM_PARAMETERS_ARB, &program_parameters); - if (!program_parameters) { - return; - } +namespace glstate { - GLint max_program_local_parameters = 0; - glGetProgramivARB(target, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &max_program_local_parameters); - for (GLint index = 0; index < max_program_local_parameters; ++index) { - GLdouble params[4] = {0, 0, 0, 0}; - glGetProgramLocalParameterdvARB(target, index, params); - if (!params[0] && !params[1] && !params[2] && !params[3]) { - continue; +Context::Context(void) { + memset(this, 0, sizeof *this); + + const char *version = (const char *)glGetString(GL_VERSION); + if (version) { + if (version[0] == 'O' && + version[1] == 'p' && + version[2] == 'e' && + version[3] == 'n' && + version[4] == 'G' && + version[5] == 'L' && + version[6] == ' ' && + version[7] == 'E' && + version[8] == 'S' && + version[9] == ' ') { + ES = true; } - - char name[256]; - snprintf(name, sizeof name, "%sprogram.local[%i]", prefix, index); - - json.beginMember(name); - json.beginArray(); - json.writeNumber(params[0]); - json.writeNumber(params[1]); - json.writeNumber(params[2]); - json.writeNumber(params[3]); - json.endArray(); - json.endMember(); } - GLint max_program_env_parameters = 0; - glGetProgramivARB(target, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &max_program_env_parameters); - for (GLint index = 0; index < max_program_env_parameters; ++index) { - GLdouble params[4] = {0, 0, 0, 0}; - glGetProgramEnvParameterdvARB(target, index, params); - - if (!params[0] && !params[1] && !params[2] && !params[3]) { - continue; - } - - char name[256]; - snprintf(name, sizeof name, "%sprogram.env[%i]", prefix, index); + ARB_draw_buffers = !ES; - json.beginMember(name); - json.beginArray(); - json.writeNumber(params[0]); - json.writeNumber(params[1]); - json.writeNumber(params[2]); - json.writeNumber(params[3]); - json.endArray(); - json.endMember(); - } + // TODO: Check extensions we use below } - -static inline void -dumpShadersUniforms(JSONWriter &json) -{ - GLint program = 0; - glGetIntegerv(GL_CURRENT_PROGRAM, &program); - - GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB); - - json.beginMember("shaders"); - json.beginObject(); - if (program) { - dumpProgram(json, program); - } else if (programObj) { - dumpProgramObj(json, programObj); +void +Context::resetPixelPackState(void) { + if (!ES) { + glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + 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); } else { - dumpArbProgram(json, GL_FRAGMENT_PROGRAM_ARB); - dumpArbProgram(json, GL_VERTEX_PROGRAM_ARB); + packAlignment = 4; + glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment); } - json.endObject(); - json.endMember(); // shaders + glPixelStorei(GL_PACK_ALIGNMENT, 1); +} - json.beginMember("uniforms"); - json.beginObject(); - if (program) { - dumpProgramUniforms(json, program); - } else if (programObj) { - dumpProgramObjUniforms(json, programObj); +void +Context::restorePixelPackState(void) { + if (!ES) { + glPopClientAttrib(); } else { - dumpArbProgramUniforms(json, GL_FRAGMENT_PROGRAM_ARB, "fp."); - dumpArbProgramUniforms(json, GL_VERTEX_PROGRAM_ARB, "vp."); + glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); } - json.endObject(); - json.endMember(); // uniforms } static inline void -dumpTextureImage(JSONWriter &json, GLenum target, GLint level) +dumpTextureImage(JSONWriter &json, Context &context, GLenum target, GLint level) { GLint width, height = 1, depth = 1; GLint format; @@ -615,11 +166,11 @@ dumpTextureImage(JSONWriter &json, GLenum target, GLint level) GLubyte *pixels = new GLubyte[depth*width*height*4]; - resetPixelPackState(); + context.resetPixelPackState(); glGetTexImage(target, level, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - restorePixelPackState(); + context.restorePixelPackState(); json.beginMember("__data__"); char *pngBuffer; @@ -636,7 +187,7 @@ dumpTextureImage(JSONWriter &json, GLenum target, GLint level) static inline void -dumpTexture(JSONWriter &json, GLenum target, GLenum binding) +dumpTexture(JSONWriter &json, Context &context, GLenum target, GLenum binding) { GLint texture_binding = 0; glGetIntegerv(binding, &texture_binding); @@ -655,10 +206,10 @@ dumpTexture(JSONWriter &json, GLenum target, GLenum binding) if (target == GL_TEXTURE_CUBE_MAP) { for (int face = 0; face < 6; ++face) { - dumpTextureImage(json, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level); + dumpTextureImage(json, context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level); } } else { - dumpTextureImage(json, target, level); + dumpTextureImage(json, context, target, level); } ++level; @@ -667,7 +218,7 @@ dumpTexture(JSONWriter &json, GLenum target, GLenum binding) static inline void -dumpTextures(JSONWriter &json) +dumpTextures(JSONWriter &json, Context &context) { json.beginMember("textures"); json.beginObject(); @@ -681,11 +232,11 @@ dumpTextures(JSONWriter &json) for (GLint unit = 0; unit < max_units; ++unit) { GLenum texture = GL_TEXTURE0 + unit; glActiveTexture(texture); - dumpTexture(json, GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D); - dumpTexture(json, GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D); - dumpTexture(json, GL_TEXTURE_3D, GL_TEXTURE_BINDING_3D); - dumpTexture(json, GL_TEXTURE_RECTANGLE, GL_TEXTURE_BINDING_RECTANGLE); - dumpTexture(json, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BINDING_CUBE_MAP); + dumpTexture(json, context, GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D); + dumpTexture(json, context, GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D); + dumpTexture(json, context, GL_TEXTURE_3D, GL_TEXTURE_BINDING_3D); + dumpTexture(json, context, GL_TEXTURE_RECTANGLE, GL_TEXTURE_BINDING_RECTANGLE); + dumpTexture(json, context, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BINDING_CUBE_MAP); } glActiveTexture(active_texture); json.endObject(); @@ -735,6 +286,7 @@ getDrawableBounds(GLint *width, GLint *height) { *width = rect.right - rect.left; *height = rect.bottom - rect.top; + return true; #elif defined(__APPLE__) @@ -984,24 +536,40 @@ getDrawBufferImage() { return NULL; } + Context context; + + GLenum framebuffer_binding; + GLenum framebuffer_target; + if (context.ES) { + framebuffer_binding = GL_FRAMEBUFFER_BINDING; + framebuffer_target = GL_FRAMEBUFFER; + } else { + framebuffer_binding = GL_DRAW_FRAMEBUFFER_BINDING; + framebuffer_target = GL_DRAW_FRAMEBUFFER; + } + GLint draw_framebuffer = 0; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer); + glGetIntegerv(framebuffer_binding, &draw_framebuffer); GLint draw_buffer = GL_NONE; GLint width, height; if (draw_framebuffer) { - glGetIntegerv(GL_DRAW_BUFFER0, &draw_buffer); - if (draw_buffer == GL_NONE) { - return NULL; + if (context.ARB_draw_buffers) { + glGetIntegerv(GL_DRAW_BUFFER0, &draw_buffer); + if (draw_buffer == GL_NONE) { + return NULL; + } } - if (!getFramebufferAttachmentSize(GL_DRAW_FRAMEBUFFER, draw_buffer, &width, &height)) { + if (!getFramebufferAttachmentSize(framebuffer_target, draw_buffer, &width, &height)) { return NULL; } } else { - glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer); - if (draw_buffer == GL_NONE) { - return NULL; + if (!context.ES) { + glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer); + if (draw_buffer == GL_NONE) { + return NULL; + } } if (!getDrawableBounds(&width, &height)) { @@ -1009,6 +577,15 @@ getDrawBufferImage() { } } + GLenum type = GL_UNSIGNED_BYTE; + +#if DEPTH_AS_RGBA + if (format == GL_DEPTH_COMPONENT) { + type = GL_UNSIGNED_INT; + channels = 4; + } +#endif + image::Image *image = new image::Image(width, height, channels, true); if (!image) { return NULL; @@ -1017,21 +594,26 @@ getDrawBufferImage() { while (glGetError() != GL_NO_ERROR) {} GLint read_framebuffer = 0; - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer); - glBindFramebuffer(GL_READ_FRAMEBUFFER, draw_framebuffer); + GLint read_buffer = GL_NONE; + if (!context.ES) { + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer); + glBindFramebuffer(GL_READ_FRAMEBUFFER, draw_framebuffer); - GLint read_buffer = 0; - glGetIntegerv(GL_READ_BUFFER, &read_buffer); - glReadBuffer(draw_buffer); + glGetIntegerv(GL_READ_BUFFER, &read_buffer); + glReadBuffer(draw_buffer); + } // TODO: reset imaging state too - resetPixelPackState(); + context.resetPixelPackState(); - glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, image->pixels); + glReadPixels(0, 0, width, height, format, type, image->pixels); - restorePixelPackState(); - glReadBuffer(read_buffer); - glBindFramebuffer(GL_READ_FRAMEBUFFER, read_framebuffer); + context.restorePixelPackState(); + + if (!context.ES) { + glReadBuffer(read_buffer); + glBindFramebuffer(GL_READ_FRAMEBUFFER, read_framebuffer); + } GLenum error = glGetError(); if (error != GL_NO_ERROR) { @@ -1056,6 +638,8 @@ dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format, { GLint channels = __gl_format_channels(format); + Context context; + json.beginObject(); // Tell the GUI this is no ordinary object, but an image @@ -1073,14 +657,23 @@ dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format, json.writeBoolMember("__normalized__", true); json.writeNumberMember("__channels__", channels); + GLenum type = GL_UNSIGNED_BYTE; + +#if DEPTH_AS_RGBA + if (format == GL_DEPTH_COMPONENT) { + type = GL_UNSIGNED_INT; + channels = 4; + } +#endif + GLubyte *pixels = new GLubyte[width*height*channels]; // TODO: reset imaging state too - resetPixelPackState(); + context.resetPixelPackState(); - glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels); + glReadPixels(0, 0, width, height, format, type, pixels); - restorePixelPackState(); + context.restorePixelPackState(); json.beginMember("__data__"); char *pngBuffer; @@ -1212,7 +805,7 @@ downsampledFramebuffer(GLuint oldFbo, GLint drawbuffer, * Dump images of current draw drawable/window. */ static void -dumpDrawableImages(JSONWriter &json) +dumpDrawableImages(JSONWriter &json, Context &context) { GLint width, height; @@ -1221,12 +814,18 @@ dumpDrawableImages(JSONWriter &json) } GLint draw_buffer = GL_NONE; - glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer); - glReadBuffer(draw_buffer); + if (context.ES) { + draw_buffer = GL_BACK; + } else { + glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer); + glReadBuffer(draw_buffer); + } if (draw_buffer != GL_NONE) { GLint read_buffer = GL_NONE; - glGetIntegerv(GL_READ_BUFFER, &read_buffer); + if (!context.ES) { + glGetIntegerv(GL_READ_BUFFER, &read_buffer); + } GLint alpha_bits = 0; #if 0 @@ -1238,23 +837,27 @@ dumpDrawableImages(JSONWriter &json) dumpReadBufferImage(json, width, height, format); json.endMember(); - glReadBuffer(read_buffer); + if (!context.ES) { + glReadBuffer(read_buffer); + } } - GLint depth_bits = 0; - glGetIntegerv(GL_DEPTH_BITS, &depth_bits); - if (depth_bits) { - json.beginMember("GL_DEPTH_COMPONENT"); - dumpReadBufferImage(json, width, height, GL_DEPTH_COMPONENT); - json.endMember(); - } + if (!context.ES) { + GLint depth_bits = 0; + glGetIntegerv(GL_DEPTH_BITS, &depth_bits); + if (depth_bits) { + json.beginMember("GL_DEPTH_COMPONENT"); + dumpReadBufferImage(json, width, height, GL_DEPTH_COMPONENT); + json.endMember(); + } - GLint stencil_bits = 0; - glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); - if (stencil_bits) { - json.beginMember("GL_STENCIL_INDEX"); - dumpReadBufferImage(json, width, height, GL_STENCIL_INDEX); - json.endMember(); + GLint stencil_bits = 0; + glGetIntegerv(GL_STENCIL_BITS, &stencil_bits); + if (stencil_bits) { + json.beginMember("GL_STENCIL_INDEX"); + dumpReadBufferImage(json, width, height, GL_STENCIL_INDEX); + json.endMember(); + } } } @@ -1281,7 +884,7 @@ dumpFramebufferAttachment(JSONWriter &json, GLenum target, GLenum attachment, GL static void -dumpFramebufferAttachments(JSONWriter &json, GLenum target) +dumpFramebufferAttachments(JSONWriter &json, Context &context, GLenum target) { GLint read_framebuffer = 0; glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer); @@ -1317,15 +920,17 @@ dumpFramebufferAttachments(JSONWriter &json, GLenum target) glReadBuffer(read_buffer); - dumpFramebufferAttachment(json, target, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT); - dumpFramebufferAttachment(json, target, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX); + if (!context.ES) { + dumpFramebufferAttachment(json, target, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT); + dumpFramebufferAttachment(json, target, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX); + } glBindFramebuffer(GL_READ_FRAMEBUFFER, read_framebuffer); } static void -dumpFramebuffer(JSONWriter &json) +dumpFramebuffer(JSONWriter &json, Context &context) { json.beginMember("framebuffer"); json.beginObject(); @@ -1334,7 +939,9 @@ dumpFramebuffer(JSONWriter &json) glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &boundDrawFbo); glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &boundReadFbo); if (!boundDrawFbo) { - dumpDrawableImages(json); + dumpDrawableImages(json, context); + } else if (context.ES) { + dumpFramebufferAttachments(json, context, GL_FRAMEBUFFER); } else { GLint colorRb = 0, stencilRb = 0, depthRb = 0; GLint draw_buffer0 = GL_NONE; @@ -1392,7 +999,7 @@ dumpFramebuffer(JSONWriter &json) rbs, &numRbs); } - dumpFramebufferAttachments(json, GL_DRAW_FRAMEBUFFER); + dumpFramebufferAttachments(json, context, GL_DRAW_FRAMEBUFFER); if (multisample) { glBindRenderbuffer(GL_RENDERBUFFER_BINDING, boundRb); @@ -1448,10 +1055,12 @@ void dumpCurrentContext(std::ostream &os) } #endif - dumpParameters(json); + Context context; + + dumpParameters(json, context); dumpShadersUniforms(json); - dumpTextures(json); - dumpFramebuffer(json); + dumpTextures(json, context); + dumpFramebuffer(json, context); #ifndef NDEBUG for (unsigned i = 0; i < NUM_BINDINGS; ++i) {