• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                 break;
105             case GL_READ_FRAMEBUFFER_BINDING:
106                 gl.glBindFramebuffer(GL_READ_FRAMEBUFFER, v.intData[0]);
107                 break;
108             case GL_CURRENT_PROGRAM:
109                 gl.glUseProgram(v.intData[0]);
110                 break;
111             case GL_VERTEX_ARRAY_BINDING:
112                 gl.glBindVertexArray(v.intData[0]);
113                 break;
114             case GL_ARRAY_BUFFER_BINDING:
115                 gl.glBindBuffer(GL_ARRAY_BUFFER, v.intData[0]);
116                 break;
117             case GL_TEXTURE_BINDING_2D:
118                 gl.glBindTexture(GL_TEXTURE_2D, v.intData[0]);
119                 break;
120             case GL_TEXTURE_BINDING_CUBE_MAP:
121                 gl.glBindTexture(GL_TEXTURE_CUBE_MAP, v.intData[0]);
122                 break;
123             case GL_VIEWPORT:
124                 gl.glViewport(v.intData[0], v.intData[1], v.intData[2], v.intData[3]);
125                 break;
126             case GL_COLOR_WRITEMASK:
127                 gl.glColorMask(v.intData[0], v.intData[1], v.intData[2], v.intData[3]);
128                 break;
129             case GL_DEPTH_RANGE:
130                 gl.glDepthRange(v.floatData[0], v.floatData[1]);
131                 break;
132                 // glIsEnabled queries
133             case GL_BLEND:
134             case GL_SCISSOR_TEST:
135             case GL_DEPTH_TEST:
136             case GL_STENCIL_TEST:
137             case GL_CULL_FACE:
138             case GL_RASTERIZER_DISCARD:
139             case GL_SAMPLE_ALPHA_TO_COVERAGE:
140             case GL_SAMPLE_COVERAGE:
141             case GL_POLYGON_OFFSET_FILL:
142                 if (v.intData[0]) {
143                     gl.glEnable(name);
144                 } else {
145                     gl.glDisable(name);
146                 }
147                 break;
148             default:
149                 fprintf(stderr,
150                         "%s: ScopedGLState doesn't support 0x%x yet, it's mainly for "
151                         "texture emulation by drawing fullscreen quads.\n", __func__,
152                         name);
153                 break;
154         }
155     }
156 }
157