blob: 8c968fef7ab161ec4ef250ffd1c1dd9c5ca33278 [file] [log] [blame]
/*
* 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;
}
}
}