| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License") |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #include "GLcommon/ScopedGLState.h" |
| |
| #include "GLcommon/GLEScontext.h" |
| |
| #include <GLES/gl.h> |
| #include <GLES2/gl2.h> |
| #include <GLES2/gl2ext.h> |
| #include <GLES3/gl31.h> |
| |
| #include <unordered_map> |
| |
| void ScopedGLState::push(GLenum name) { |
| auto& gl = GLEScontext::dispatcher(); |
| |
| StateVector v; |
| |
| switch (name) { |
| case GL_DRAW_FRAMEBUFFER_BINDING: |
| case GL_READ_FRAMEBUFFER_BINDING: |
| case GL_CURRENT_PROGRAM: |
| case GL_VERTEX_ARRAY_BINDING: |
| case GL_ARRAY_BUFFER_BINDING: |
| case GL_TEXTURE_BINDING_2D: |
| case GL_TEXTURE_BINDING_CUBE_MAP: |
| case GL_VIEWPORT: |
| case GL_COLOR_WRITEMASK: |
| gl.glGetIntegerv(name, v.intData); |
| break; |
| case GL_DEPTH_RANGE: |
| gl.glGetFloatv(name, v.floatData); |
| break; |
| // glIsEnabled queries |
| case GL_BLEND: |
| case GL_SCISSOR_TEST: |
| case GL_DEPTH_TEST: |
| case GL_STENCIL_TEST: |
| case GL_CULL_FACE: |
| case GL_RASTERIZER_DISCARD: |
| case GL_SAMPLE_ALPHA_TO_COVERAGE: |
| case GL_SAMPLE_COVERAGE: |
| case GL_POLYGON_OFFSET_FILL: |
| v.intData[0] = gl.glIsEnabled(name); |
| break; |
| default: |
| fprintf(stderr, |
| "%s: ScopedGLState doesn't support 0x%x yet, it's mainly for " |
| "texture emulation by drawing fullscreen quads.\n", __func__, |
| name); |
| break; |
| } |
| |
| mStateMap[name] = v; |
| } |
| |
| void ScopedGLState::push(std::initializer_list<GLenum> names) { |
| for (const auto name : names) { |
| push(name); |
| } |
| } |
| |
| void ScopedGLState::pushForCoreProfileTextureEmulation() { |
| push({ GL_DRAW_FRAMEBUFFER_BINDING, |
| GL_READ_FRAMEBUFFER_BINDING, |
| GL_VERTEX_ARRAY_BINDING, |
| GL_CURRENT_PROGRAM, |
| GL_VIEWPORT, |
| GL_SCISSOR_TEST, |
| GL_DEPTH_TEST, |
| GL_BLEND, |
| GL_DEPTH_RANGE, |
| GL_COLOR_WRITEMASK, |
| GL_SAMPLE_ALPHA_TO_COVERAGE, |
| GL_SAMPLE_COVERAGE, |
| GL_CULL_FACE, |
| GL_POLYGON_OFFSET_FILL, |
| GL_RASTERIZER_DISCARD, |
| GL_TEXTURE_BINDING_2D }); |
| } |
| |
| ScopedGLState::~ScopedGLState() { |
| auto& gl = GLEScontext::dispatcher(); |
| |
| for (const auto& it : mStateMap) { |
| GLenum name = it.first; |
| const StateVector& v = it.second; |
| switch (name) { |
| case GL_DRAW_FRAMEBUFFER_BINDING: |
| gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, v.intData[0]); |
| case GL_READ_FRAMEBUFFER_BINDING: |
| gl.glBindFramebuffer(GL_READ_FRAMEBUFFER, v.intData[0]); |
| break; |
| case GL_CURRENT_PROGRAM: |
| gl.glUseProgram(v.intData[0]); |
| break; |
| case GL_VERTEX_ARRAY_BINDING: |
| gl.glBindVertexArray(v.intData[0]); |
| break; |
| case GL_ARRAY_BUFFER_BINDING: |
| gl.glBindBuffer(GL_ARRAY_BUFFER, v.intData[0]); |
| break; |
| case GL_TEXTURE_BINDING_2D: |
| gl.glBindTexture(GL_TEXTURE_2D, v.intData[0]); |
| break; |
| case GL_TEXTURE_BINDING_CUBE_MAP: |
| gl.glBindTexture(GL_TEXTURE_CUBE_MAP, v.intData[0]); |
| break; |
| case GL_VIEWPORT: |
| gl.glViewport(v.intData[0], v.intData[1], v.intData[2], v.intData[3]); |
| break; |
| case GL_COLOR_WRITEMASK: |
| gl.glColorMask(v.intData[0], v.intData[1], v.intData[2], v.intData[3]); |
| break; |
| case GL_DEPTH_RANGE: |
| gl.glDepthRange(v.floatData[0], v.floatData[1]); |
| break; |
| // glIsEnabled queries |
| case GL_BLEND: |
| case GL_SCISSOR_TEST: |
| case GL_DEPTH_TEST: |
| case GL_STENCIL_TEST: |
| case GL_CULL_FACE: |
| case GL_RASTERIZER_DISCARD: |
| case GL_SAMPLE_ALPHA_TO_COVERAGE: |
| case GL_SAMPLE_COVERAGE: |
| case GL_POLYGON_OFFSET_FILL: |
| if (v.intData[0]) { |
| gl.glEnable(name); |
| } else { |
| gl.glDisable(name); |
| } |
| break; |
| default: |
| fprintf(stderr, |
| "%s: ScopedGLState doesn't support 0x%x yet, it's mainly for " |
| "texture emulation by drawing fullscreen quads.\n", __func__, |
| name); |
| break; |
| } |
| } |
| } |