1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License")
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "GLcommon/ScopedGLState.h"
17
18 #include "GLcommon/GLEScontext.h"
19
20 #include <GLES/gl.h>
21 #include <GLES2/gl2.h>
22 #include <GLES2/gl2ext.h>
23 #include <GLES3/gl31.h>
24
25 #include <unordered_map>
26
push(GLenum name)27 void ScopedGLState::push(GLenum name) {
28 auto& gl = GLEScontext::dispatcher();
29
30 StateVector v;
31
32 switch (name) {
33 case GL_DRAW_FRAMEBUFFER_BINDING:
34 case GL_READ_FRAMEBUFFER_BINDING:
35 case GL_CURRENT_PROGRAM:
36 case GL_VERTEX_ARRAY_BINDING:
37 case GL_ARRAY_BUFFER_BINDING:
38 case GL_TEXTURE_BINDING_2D:
39 case GL_TEXTURE_BINDING_CUBE_MAP:
40 case GL_VIEWPORT:
41 case GL_COLOR_WRITEMASK:
42 gl.glGetIntegerv(name, v.intData);
43 break;
44 case GL_DEPTH_RANGE:
45 gl.glGetFloatv(name, v.floatData);
46 break;
47 // glIsEnabled queries
48 case GL_BLEND:
49 case GL_SCISSOR_TEST:
50 case GL_DEPTH_TEST:
51 case GL_STENCIL_TEST:
52 case GL_CULL_FACE:
53 case GL_RASTERIZER_DISCARD:
54 case GL_SAMPLE_ALPHA_TO_COVERAGE:
55 case GL_SAMPLE_COVERAGE:
56 case GL_POLYGON_OFFSET_FILL:
57 v.intData[0] = gl.glIsEnabled(name);
58 break;
59 default:
60 fprintf(stderr,
61 "%s: ScopedGLState doesn't support 0x%x yet, it's mainly for "
62 "texture emulation by drawing fullscreen quads.\n", __func__,
63 name);
64 break;
65 }
66
67 mStateMap[name] = v;
68 }
69
push(std::initializer_list<GLenum> names)70 void ScopedGLState::push(std::initializer_list<GLenum> names) {
71 for (const auto name : names) {
72 push(name);
73 }
74 }
75
pushForCoreProfileTextureEmulation()76 void ScopedGLState::pushForCoreProfileTextureEmulation() {
77 push({ GL_DRAW_FRAMEBUFFER_BINDING,
78 GL_READ_FRAMEBUFFER_BINDING,
79 GL_VERTEX_ARRAY_BINDING,
80 GL_CURRENT_PROGRAM,
81 GL_VIEWPORT,
82 GL_SCISSOR_TEST,
83 GL_DEPTH_TEST,
84 GL_BLEND,
85 GL_DEPTH_RANGE,
86 GL_COLOR_WRITEMASK,
87 GL_SAMPLE_ALPHA_TO_COVERAGE,
88 GL_SAMPLE_COVERAGE,
89 GL_CULL_FACE,
90 GL_POLYGON_OFFSET_FILL,
91 GL_RASTERIZER_DISCARD,
92 GL_TEXTURE_BINDING_2D });
93 }
94
~ScopedGLState()95 ScopedGLState::~ScopedGLState() {
96 auto& gl = GLEScontext::dispatcher();
97
98 for (const auto& it : mStateMap) {
99 GLenum name = it.first;
100 const StateVector& v = it.second;
101 switch (name) {
102 case GL_DRAW_FRAMEBUFFER_BINDING:
103 gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, v.intData[0]);
104 case GL_READ_FRAMEBUFFER_BINDING:
105 gl.glBindFramebuffer(GL_READ_FRAMEBUFFER, v.intData[0]);
106 break;
107 case GL_CURRENT_PROGRAM:
108 gl.glUseProgram(v.intData[0]);
109 break;
110 case GL_VERTEX_ARRAY_BINDING:
111 gl.glBindVertexArray(v.intData[0]);
112 break;
113 case GL_ARRAY_BUFFER_BINDING:
114 gl.glBindBuffer(GL_ARRAY_BUFFER, v.intData[0]);
115 break;
116 case GL_TEXTURE_BINDING_2D:
117 gl.glBindTexture(GL_TEXTURE_2D, v.intData[0]);
118 break;
119 case GL_TEXTURE_BINDING_CUBE_MAP:
120 gl.glBindTexture(GL_TEXTURE_CUBE_MAP, v.intData[0]);
121 break;
122 case GL_VIEWPORT:
123 gl.glViewport(v.intData[0], v.intData[1], v.intData[2], v.intData[3]);
124 break;
125 case GL_COLOR_WRITEMASK:
126 gl.glColorMask(v.intData[0], v.intData[1], v.intData[2], v.intData[3]);
127 break;
128 case GL_DEPTH_RANGE:
129 gl.glDepthRange(v.floatData[0], v.floatData[1]);
130 break;
131 // glIsEnabled queries
132 case GL_BLEND:
133 case GL_SCISSOR_TEST:
134 case GL_DEPTH_TEST:
135 case GL_STENCIL_TEST:
136 case GL_CULL_FACE:
137 case GL_RASTERIZER_DISCARD:
138 case GL_SAMPLE_ALPHA_TO_COVERAGE:
139 case GL_SAMPLE_COVERAGE:
140 case GL_POLYGON_OFFSET_FILL:
141 if (v.intData[0]) {
142 gl.glEnable(name);
143 } else {
144 gl.glDisable(name);
145 }
146 break;
147 default:
148 fprintf(stderr,
149 "%s: ScopedGLState doesn't support 0x%x yet, it's mainly for "
150 "texture emulation by drawing fullscreen quads.\n", __func__,
151 name);
152 break;
153 }
154 }
155 }
156