1 /**************************************************************************
3 * Copyright 2011 Jose Fonseca
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 **************************************************************************/
29 #include "retrace.hpp"
31 #include "glstate.hpp"
32 #include "glretrace.hpp"
37 bool insideGlBeginEnd = false;
38 glws::Profile defaultProfile = glws::PROFILE_COMPAT;
39 glws::Visual *visual[glws::PROFILE_MAX];
40 glws::Drawable *drawable = NULL;
41 glws::Context *context = NULL;
44 checkGlError(trace::Call &call) {
45 GLenum error = glGetError();
46 if (error == GL_NO_ERROR) {
50 std::ostream & os = retrace::warning(call);
58 os << "GL_INVALID_ENUM";
60 case GL_INVALID_VALUE:
61 os << "GL_INVALID_VALUE";
63 case GL_INVALID_OPERATION:
64 os << "GL_INVALID_OPERATION";
66 case GL_STACK_OVERFLOW:
67 os << "GL_STACK_OVERFLOW";
69 case GL_STACK_UNDERFLOW:
70 os << "GL_STACK_UNDERFLOW";
72 case GL_OUT_OF_MEMORY:
73 os << "GL_OUT_OF_MEMORY";
75 case GL_INVALID_FRAMEBUFFER_OPERATION:
76 os << "GL_INVALID_FRAMEBUFFER_OPERATION";
78 case GL_TABLE_TOO_LARGE:
79 os << "GL_TABLE_TOO_LARGE";
89 * Grow the current drawble.
91 * We need to infer the drawable size from GL calls because the drawable sizes
92 * are specified by OS specific calls which we do not trace.
95 updateDrawable(int width, int height) {
100 if (drawable->visible &&
101 width <= drawable->width &&
102 height <= drawable->height) {
106 // Ignore zero area viewports
107 if (width == 0 || height == 0) {
111 // Check for bound framebuffer last, as this may have a performance impact.
112 GLint draw_framebuffer = 0;
113 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
114 if (draw_framebuffer != 0) {
118 drawable->resize(width, height);
121 glScissor(0, 0, width, height);
125 void frame_complete(trace::Call &call) {
126 retrace::frameComplete(call);
132 if (!drawable->visible) {
133 retrace::warning(call) << "could not infer drawable size (glViewport never called)\n";
138 } /* namespace glretrace */
142 retrace::setUp(void) {
143 if (retrace::coreProfile) {
144 glretrace::defaultProfile = glws::PROFILE_CORE;
149 glretrace::visual[glws::PROFILE_COMPAT] = glws::createVisual(retrace::doubleBuffer, glws::PROFILE_COMPAT);
150 glretrace::visual[glws::PROFILE_CORE] = glws::createVisual(retrace::doubleBuffer, glws::PROFILE_CORE);
151 glretrace::visual[glws::PROFILE_ES1] = glws::createVisual(retrace::doubleBuffer, glws::PROFILE_ES1);
152 glretrace::visual[glws::PROFILE_ES2] = glws::createVisual(retrace::doubleBuffer, glws::PROFILE_ES2);
157 retrace::addCallbacks(retrace::Retracer &retracer)
159 retracer.addCallbacks(glretrace::gl_callbacks);
160 retracer.addCallbacks(glretrace::glx_callbacks);
161 retracer.addCallbacks(glretrace::wgl_callbacks);
162 retracer.addCallbacks(glretrace::cgl_callbacks);
163 retracer.addCallbacks(glretrace::egl_callbacks);
168 retrace::getSnapshot(void) {
169 if (!glretrace::drawable) {
173 return glstate::getDrawBufferImage();
178 retrace::dumpState(std::ostream &os)
180 if (glretrace::insideGlBeginEnd ||
181 !glretrace::drawable ||
182 !glretrace::context) {
186 glstate::dumpCurrentContext(os);
192 retrace::flushRendering(void) {
197 retrace::waitForInput(void) {
198 while (glws::processEvents()) {
203 retrace::cleanUp(void) {
204 for (int n = 0; n < glws::PROFILE_MAX; n++) {
205 delete glretrace::visual[n];