]> git.cworth.org Git - apitrace/blob - retrace/glstate.cpp
glretrace: Fix snapshots on GL 3.2 core contexts (issue #106).
[apitrace] / retrace / glstate.cpp
1 /**************************************************************************
2  *
3  * Copyright 2011 Jose Fonseca
4  * All Rights Reserved.
5  *
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:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
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
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26
27 #include <string.h>
28
29 #include <algorithm>
30 #include <iostream>
31
32 #include "image.hpp"
33 #include "json.hpp"
34 #include "glproc.hpp"
35 #include "glsize.hpp"
36 #include "glstate.hpp"
37 #include "glstate_internal.hpp"
38
39
40 namespace glstate {
41
42
43 Context::Context(void) {
44     memset(this, 0, sizeof *this);
45
46     const char *version = (const char *)glGetString(GL_VERSION);
47     if (version) {
48         if (version[0] == 'O' &&
49             version[1] == 'p' &&
50             version[2] == 'e' &&
51             version[3] == 'n' &&
52             version[4] == 'G' &&
53             version[5] == 'L' &&
54             version[6] == ' ' &&
55             version[7] == 'E' &&
56             version[8] == 'S' &&
57             (version[9] == ' ' || version[9] == '-')) {
58             ES = true;
59         }
60     }
61
62     ARB_draw_buffers = !ES;
63
64     // TODO: Check extensions we use below
65 }
66
67 void
68 Context::resetPixelPackState(void) {
69     // Start with default state
70     pack_alignment = 4;
71     pack_image_height = 0;
72     pack_lsb_first = GL_FALSE;
73     pack_row_length = 0;
74     pack_skip_images = 0;
75     pack_skip_pixels = 0;
76     pack_skip_rows = 0;
77     pack_swap_bytes = GL_FALSE;
78     pixel_pack_buffer_binding = 0;
79
80     // Get current state
81     glGetIntegerv(GL_PACK_ALIGNMENT, &pack_alignment);
82     if (!ES) {
83         glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &pack_image_height);
84         glGetIntegerv(GL_PACK_LSB_FIRST, &pack_lsb_first);
85         glGetIntegerv(GL_PACK_ROW_LENGTH, &pack_row_length);
86         glGetIntegerv(GL_PACK_SKIP_IMAGES, &pack_skip_images);
87         glGetIntegerv(GL_PACK_SKIP_PIXELS, &pack_skip_pixels);
88         glGetIntegerv(GL_PACK_SKIP_ROWS, &pack_skip_rows);
89         glGetIntegerv(GL_PACK_SWAP_BYTES, &pack_swap_bytes);
90         glGetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &pixel_pack_buffer_binding);
91     }
92
93     // Reset state for compact images
94     glPixelStorei(GL_PACK_ALIGNMENT, 1);
95     if (!ES) {
96         glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
97         glPixelStorei(GL_PACK_LSB_FIRST, GL_FALSE);
98         glPixelStorei(GL_PACK_ROW_LENGTH, 0);
99         glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
100         glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
101         glPixelStorei(GL_PACK_SKIP_ROWS, 0);
102         glPixelStorei(GL_PACK_SWAP_BYTES, GL_FALSE);
103         glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
104     }
105 }
106
107 void
108 Context::restorePixelPackState(void) {
109     glPixelStorei(GL_PACK_ALIGNMENT, pack_alignment);
110     if (!ES) {
111         glPixelStorei(GL_PACK_IMAGE_HEIGHT, pack_image_height);
112         glPixelStorei(GL_PACK_LSB_FIRST, pack_lsb_first);
113         glPixelStorei(GL_PACK_ROW_LENGTH, pack_row_length);
114         glPixelStorei(GL_PACK_SKIP_IMAGES, pack_skip_images);
115         glPixelStorei(GL_PACK_SKIP_PIXELS, pack_skip_pixels);
116         glPixelStorei(GL_PACK_SKIP_ROWS, pack_skip_rows);
117         glPixelStorei(GL_PACK_SWAP_BYTES, pack_swap_bytes);
118         glBindBuffer(GL_PIXEL_PACK_BUFFER, pixel_pack_buffer_binding);
119     }
120 }
121
122
123 static const GLenum bindings[] = {
124     GL_DRAW_BUFFER,
125     GL_READ_BUFFER,
126     GL_PIXEL_PACK_BUFFER_BINDING,
127     GL_PIXEL_UNPACK_BUFFER_BINDING,
128     GL_TEXTURE_BINDING_1D,
129     GL_TEXTURE_BINDING_2D,
130     GL_TEXTURE_BINDING_3D,
131     GL_TEXTURE_BINDING_RECTANGLE,
132     GL_TEXTURE_BINDING_CUBE_MAP,
133     GL_DRAW_FRAMEBUFFER_BINDING,
134     GL_READ_FRAMEBUFFER_BINDING,
135     GL_RENDERBUFFER_BINDING,
136     GL_DRAW_BUFFER0,
137     GL_DRAW_BUFFER1,
138     GL_DRAW_BUFFER2,
139     GL_DRAW_BUFFER3,
140     GL_DRAW_BUFFER4,
141     GL_DRAW_BUFFER5,
142     GL_DRAW_BUFFER6,
143     GL_DRAW_BUFFER7,
144 };
145
146
147 #define NUM_BINDINGS sizeof(bindings)/sizeof(bindings[0])
148
149
150 void dumpCurrentContext(std::ostream &os)
151 {
152     JSONWriter json(os);
153
154 #ifndef NDEBUG
155     GLint old_bindings[NUM_BINDINGS];
156     for (unsigned i = 0; i < NUM_BINDINGS; ++i) {
157         old_bindings[i] = 0;
158         glGetIntegerv(bindings[i], &old_bindings[i]);
159     }
160 #endif
161
162     Context context;
163
164     dumpParameters(json, context);
165     dumpShadersUniforms(json, context);
166     dumpTextures(json, context);
167     dumpFramebuffer(json, context);
168
169 #ifndef NDEBUG
170     for (unsigned i = 0; i < NUM_BINDINGS; ++i) {
171         GLint new_binding = 0;
172         glGetIntegerv(bindings[i], &new_binding);
173         if (new_binding != old_bindings[i]) {
174             std::cerr << "warning: " << enumToString(bindings[i]) << " was clobbered\n";
175         }
176     }
177 #endif
178
179 }
180
181
182 } /* namespace glstate */