X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=glstate.cpp;h=cac9f4e44a0d96cc9f7909f9b5f4379516133f00;hb=4644dc65e83c56ba0bb577f57cd20e7419f3ade4;hp=6dc6f8063a2bf37c5c0b6896ac7f777214fa76bd;hpb=3dabe543b983aaa89ff3a85f790d6e1d60d93732;p=apitrace diff --git a/glstate.cpp b/glstate.cpp index 6dc6f80..cac9f4e 100644 --- a/glstate.cpp +++ b/glstate.cpp @@ -25,659 +25,130 @@ #include -#include + #include +#include #include "image.hpp" #include "json.hpp" #include "glproc.hpp" #include "glsize.hpp" #include "glstate.hpp" - - -#ifdef __APPLE__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int CGSConnectionID; -typedef int CGSWindowID; -typedef int CGSSurfaceID; - -CGLError CGLGetSurface(CGLContextObj, CGSConnectionID*, CGSWindowID*, CGSSurfaceID*); -OSStatus CGSGetSurfaceBounds(CGSConnectionID, CGWindowID, CGSSurfaceID, CGRect *); - -#ifdef __cplusplus -} -#endif - -#endif /* __APPLE__ */ +#include "glstate_internal.hpp" namespace glstate { -static void -dumpShader(JSONWriter &json, 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); - - json.beginMember(enumToString(shader_type)); - json.writeString(source); - json.endMember(); - - delete [] source; -} - - -static void -dumpShaderObj(JSONWriter &json, GLhandleARB shaderObj) -{ - if (!shaderObj) { - return; - } - - GLint shader_type = 0; - glGetObjectParameterivARB(shaderObj, GL_OBJECT_TYPE_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); - - json.beginMember(enumToString(shader_type)); - json.writeString(source); - json.endMember(); - - delete [] source; -} - - -static inline void -dumpCurrentProgram(JSONWriter &json) -{ - GLint program = 0; - glGetIntegerv(GL_CURRENT_PROGRAM, &program); - if (!program) { - return; - } - - GLint attached_shaders = 0; - glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders); - if (!attached_shaders) { - return; - } - - GLuint *shaders = new GLuint[attached_shaders]; - GLsizei count = 0; - glGetAttachedShaders(program, attached_shaders, &count, shaders); - for (GLsizei i = 0; i < count; ++ i) { - dumpShader(json, shaders[i]); - } - delete [] shaders; -} - - -static inline void -dumpCurrentProgramObj(JSONWriter &json) -{ - GLhandleARB programObj = glGetHandleARB(GL_PROGRAM_OBJECT_ARB); - if (!programObj) { - return; - } - - GLint attached_shaders = 0; - glGetProgramivARB(programObj, GL_OBJECT_ATTACHED_OBJECTS_ARB, &attached_shaders); - if (!attached_shaders) { - return; - } - - GLhandleARB *shaderObjs = new GLhandleARB[attached_shaders]; - GLsizei count = 0; - glGetAttachedObjectsARB(programObj, attached_shaders, &count, shaderObjs); - for (GLsizei i = 0; i < count; ++ i) { - dumpShaderObj(json, shaderObjs[i]); - } - delete [] shaderObjs; -} - - -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 -dumpShaders(JSONWriter &json) -{ - json.beginMember("shaders"); - json.beginObject(); - dumpCurrentProgram(json); - dumpArbProgram(json, GL_FRAGMENT_PROGRAM_ARB); - dumpArbProgram(json, GL_VERTEX_PROGRAM_ARB); - json.endObject(); - json.endMember(); //shaders -} - - -static inline void -dumpTextureImage(JSONWriter &json, GLenum target, GLint level) -{ - GLint width, height = 1, depth = 1; - - width = 0; - glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width); - - if (target != GL_TEXTURE_1D) { - height = 0; - glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height); - if (target == GL_TEXTURE_3D) { - depth = 0; - glGetTexLevelParameteriv(target, level, GL_TEXTURE_DEPTH, &depth); +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; } } - if (width <= 0 || height <= 0 || depth <= 0) { - return; - } else { - char label[512]; - - GLint active_texture = GL_TEXTURE0; - glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); - snprintf(label, sizeof label, "%s, %s, level = %i", enumToString(active_texture), enumToString(target), level); - - json.beginMember(label); - - json.beginObject(); - - // Tell the GUI this is no ordinary object, but an image - json.writeStringMember("__class__", "image"); - - json.writeNumberMember("__width__", width); - json.writeNumberMember("__height__", height); - json.writeNumberMember("__depth__", depth); - - // Hardcoded for now, but we could chose types more adequate to the - // texture internal format - json.writeStringMember("__type__", "uint8"); - json.writeBoolMember("__normalized__", true); - json.writeNumberMember("__channels__", 4); + ARB_draw_buffers = !ES; - GLubyte *pixels = new GLubyte[depth*width*height*4]; - - glGetTexImage(target, level, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - - json.beginMember("__data__"); - char *pngBuffer; - int pngBufferSize; - Image::writePixelsToBuffer(pixels, width, height, 4, false, &pngBuffer, &pngBufferSize); - json.writeBase64(pngBuffer, pngBufferSize); - free(pngBuffer); - json.endMember(); // __data__ - - delete [] pixels; - json.endObject(); - } + // TODO: Check extensions we use below } - -static inline void -dumpTexture(JSONWriter &json, GLenum target, GLenum binding) -{ - GLint texture_binding = 0; - glGetIntegerv(binding, &texture_binding); - if (!glIsEnabled(target) && !texture_binding) { - return; - } - - GLint level = 0; - do { - GLint width = 0, height = 0; - glGetTexLevelParameteriv(target, level, GL_TEXTURE_WIDTH, &width); - glGetTexLevelParameteriv(target, level, GL_TEXTURE_HEIGHT, &height); - if (!width || !height) { - break; - } - - if (target == GL_TEXTURE_CUBE_MAP) { - for (int face = 0; face < 6; ++face) { - dumpTextureImage(json, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level); - } - } else { - dumpTextureImage(json, target, level); - } - - ++level; - } while(true); -} - - -static inline void -dumpTextures(JSONWriter &json) -{ - json.beginMember("textures"); - json.beginObject(); - GLint active_texture = GL_TEXTURE0; - glGetIntegerv(GL_ACTIVE_TEXTURE, &active_texture); - GLint max_texture_coords = 0; - glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords); - GLint max_combined_texture_image_units = 0; - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_combined_texture_image_units); - GLint max_units = std::max(max_combined_texture_image_units, max_texture_coords); - 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); - } - glActiveTexture(active_texture); - json.endObject(); - json.endMember(); // textures -} - - -static bool -getDrawableBounds(GLint *width, GLint *height) { -#if defined(_WIN32) - - HDC hDC = wglGetCurrentDC(); - if (!hDC) { - return false; - } - - HWND hWnd = WindowFromDC(hDC); - RECT rect; - - if (!GetClientRect(hWnd, &rect)) { - return false; - } - - *width = rect.right - rect.left; - *height = rect.bottom - rect.top; - -#elif defined(__APPLE__) - - CGLContextObj ctx = CGLGetCurrentContext(); - if (ctx == NULL) { - return false; - } - - CGSConnectionID cid; - CGSWindowID wid; - CGSSurfaceID sid; - - if (CGLGetSurface(ctx, &cid, &wid, &sid) != kCGLNoError) { - return false; - } - - CGRect rect; - - if (CGSGetSurfaceBounds(cid, wid, sid, &rect) != 0) { - return false; - } - - *width = rect.size.width; - *height = rect.size.height; - -#else - - Display *display; - Drawable drawable; - Window root; - int x, y; - unsigned int w, h, bw, depth; - - display = glXGetCurrentDisplay(); - if (!display) { - return false; - } - - drawable = glXGetCurrentDrawable(); - if (drawable == None) { - return false; - } - - if (!XGetGeometry(display, drawable, &root, &x, &y, &w, &h, &bw, &depth)) { - return false; - } - - *width = w; - *height = h; - -#endif - - return true; -} - - -static inline void -dumpDrawBufferImage(JSONWriter &json, GLenum format) -{ - GLint channels = __gl_format_channels(format); - - GLint width, height; - - if (!getDrawableBounds(&width, &height)) { - json.writeNull(); - } else { - json.beginObject(); - - // Tell the GUI this is no ordinary object, but an image - json.writeStringMember("__class__", "image"); - - json.writeNumberMember("__width__", width); - json.writeNumberMember("__height__", height); - json.writeNumberMember("__depth__", 1); - - // Hardcoded for now, but we could chose types more adequate to the - // texture internal format - json.writeStringMember("__type__", "uint8"); - json.writeBoolMember("__normalized__", true); - json.writeNumberMember("__channels__", channels); - - GLubyte *pixels = new GLubyte[width*height*channels]; - - GLint drawbuffer = GL_NONE; - GLint readbuffer = GL_NONE; - glGetIntegerv(GL_DRAW_BUFFER, &drawbuffer); - glGetIntegerv(GL_READ_BUFFER, &readbuffer); - glReadBuffer(drawbuffer); - +void +Context::resetPixelPackState(void) { + if (!ES) { glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - - glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels); - - glPopClientAttrib(); - glReadBuffer(readbuffer); - - json.beginMember("__data__"); - char *pngBuffer; - int pngBufferSize; - Image::writePixelsToBuffer(pixels, width, height, channels, false, &pngBuffer, &pngBufferSize); - //std::cerr <<" Before = "<<(width * height * channels * sizeof *pixels) - // <<", after = "<