blob: 0ac1bd6ab455b83e9175352853776dbdf4063e15 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/gl/scoped_binders.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_state_restorer.h"
namespace gl {
ScopedFramebufferBinder::ScopedFramebufferBinder(unsigned int fbo)
: state_restorer_(!GLContext::GetCurrent()
? NULL
: GLContext::GetCurrent()->GetGLStateRestorer()),
old_fbo_(-1) {
if (!state_restorer_)
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_fbo_);
glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
}
ScopedFramebufferBinder::~ScopedFramebufferBinder() {
if (state_restorer_) {
DCHECK(!!GLContext::GetCurrent());
DCHECK_EQ(state_restorer_, GLContext::GetCurrent()->GetGLStateRestorer());
state_restorer_->RestoreFramebufferBindings();
} else {
glBindFramebufferEXT(GL_FRAMEBUFFER, old_fbo_);
}
}
ScopedActiveTexture::ScopedActiveTexture(unsigned int texture)
: state_restorer_(!GLContext::GetCurrent()
? NULL
: GLContext::GetCurrent()->GetGLStateRestorer()),
old_texture_(-1) {
if (!state_restorer_)
glGetIntegerv(GL_ACTIVE_TEXTURE, &old_texture_);
glActiveTexture(texture);
}
ScopedActiveTexture::~ScopedActiveTexture() {
if (state_restorer_) {
DCHECK(!!GLContext::GetCurrent());
DCHECK_EQ(state_restorer_, GLContext::GetCurrent()->GetGLStateRestorer());
state_restorer_->RestoreActiveTexture();
} else {
glActiveTexture(old_texture_);
}
}
ScopedTextureBinder::ScopedTextureBinder(unsigned int target, unsigned int id)
: state_restorer_(!GLContext::GetCurrent()
? NULL
: GLContext::GetCurrent()->GetGLStateRestorer()),
target_(target),
old_id_(-1) {
if (!state_restorer_) {
GLenum target_getter = 0;
switch (target) {
case GL_TEXTURE_2D:
target_getter = GL_TEXTURE_BINDING_2D;
break;
case GL_TEXTURE_CUBE_MAP:
target_getter = GL_TEXTURE_BINDING_CUBE_MAP;
break;
case GL_TEXTURE_EXTERNAL_OES:
target_getter = GL_TEXTURE_BINDING_EXTERNAL_OES;
break;
case GL_TEXTURE_RECTANGLE_ARB:
target_getter = GL_TEXTURE_BINDING_RECTANGLE_ARB;
break;
default:
NOTIMPLEMENTED() << " Target not supported.";
}
glGetIntegerv(target_getter, &old_id_);
}
glBindTexture(target_, id);
}
ScopedTextureBinder::~ScopedTextureBinder() {
if (state_restorer_) {
DCHECK(!!GLContext::GetCurrent());
DCHECK_EQ(state_restorer_, GLContext::GetCurrent()->GetGLStateRestorer());
state_restorer_->RestoreActiveTextureUnitBinding(target_);
} else {
glBindTexture(target_, old_id_);
}
}
ScopedUseProgram::ScopedUseProgram(unsigned int program)
: state_restorer_(!GLContext::GetCurrent()
? NULL
: GLContext::GetCurrent()->GetGLStateRestorer()),
old_program_(-1) {
if (!state_restorer_)
glGetIntegerv(GL_CURRENT_PROGRAM, &old_program_);
glUseProgram(program);
}
ScopedUseProgram::~ScopedUseProgram() {
if (state_restorer_) {
DCHECK(!!GLContext::GetCurrent());
DCHECK_EQ(state_restorer_, GLContext::GetCurrent()->GetGLStateRestorer());
state_restorer_->RestoreProgramBindings();
} else {
glUseProgram(old_program_);
}
}
ScopedVertexAttribArray::ScopedVertexAttribArray(unsigned int index,
int size,
unsigned int type,
char normalized,
int stride,
const void* pointer)
: state_restorer_(!GLContext::GetCurrent()
? NULL
: GLContext::GetCurrent()->GetGLStateRestorer()),
buffer_(0),
enabled_(GL_FALSE),
index_(index),
size_(-1),
type_(-1),
normalized_(GL_FALSE),
stride_(0),
pointer_(0) {
if (!state_restorer_) {
glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_);
glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled_);
glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size_);
glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type_);
glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized_);
glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride_);
glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &pointer_);
}
glEnableVertexAttribArray(index);
glVertexAttribPointer(index, size, type, normalized, stride, pointer);
}
ScopedVertexAttribArray::~ScopedVertexAttribArray() {
if (state_restorer_) {
DCHECK(!!GLContext::GetCurrent());
DCHECK_EQ(state_restorer_, GLContext::GetCurrent()->GetGLStateRestorer());
state_restorer_->RestoreVertexAttribArray(index_);
} else {
ScopedBufferBinder buffer_binder(GL_ARRAY_BUFFER, buffer_);
glVertexAttribPointer(index_, size_, type_, normalized_, stride_, pointer_);
if (enabled_ == GL_FALSE)
glDisableVertexAttribArray(index_);
}
}
ScopedBufferBinder::ScopedBufferBinder(unsigned int target, unsigned int id)
: state_restorer_(!GLContext::GetCurrent()
? NULL
: GLContext::GetCurrent()->GetGLStateRestorer()),
target_(target),
old_id_(-1) {
if (!state_restorer_) {
GLenum target_getter = 0;
switch (target) {
case GL_ARRAY_BUFFER:
target_getter = GL_ARRAY_BUFFER_BINDING;
break;
default:
NOTIMPLEMENTED() << " Target not supported.";
}
glGetIntegerv(target_getter, &old_id_);
}
glBindBuffer(target_, id);
}
ScopedBufferBinder::~ScopedBufferBinder() {
if (state_restorer_) {
DCHECK(!!GLContext::GetCurrent());
DCHECK_EQ(state_restorer_, GLContext::GetCurrent()->GetGLStateRestorer());
state_restorer_->RestoreBufferBinding(target_);
} else {
glBindBuffer(target_, old_id_);
}
}
ScopedViewport::ScopedViewport(int x, int y, int width, int height) {
glGetIntegerv(GL_VIEWPORT, data_);
glViewport(x, y, width, height);
}
ScopedViewport::~ScopedViewport() {
glViewport(data_[0], data_[1], data_[2], data_[3]);
}
ScopedColorMask::ScopedColorMask(char red, char green, char blue, char alpha) {
glGetBooleanv(GL_COLOR_WRITEMASK, colors_);
glColorMask(red, green, blue, alpha);
}
ScopedColorMask::~ScopedColorMask() {
glColorMask(colors_[0], colors_[1], colors_[2], colors_[3]);
}
ScopedCapability::ScopedCapability(unsigned capability, unsigned char enabled)
: capability_(capability) {
enabled_ = glIsEnabled(capability_);
if (enabled == GL_TRUE) {
glEnable(capability);
} else {
glDisable(capability);
}
}
ScopedCapability::~ScopedCapability() {
if (enabled_ == GL_TRUE) {
glEnable(capability_);
} else {
glDisable(capability_);
}
}
} // namespace gl