| // 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() |
| ? nullptr |
| : 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() |
| ? nullptr |
| : 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() |
| ? nullptr |
| : 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() |
| ? nullptr |
| : 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() |
| ? nullptr |
| : GLContext::GetCurrent()->GetGLStateRestorer()), |
| buffer_(0), |
| enabled_(GL_FALSE), |
| index_(index), |
| size_(-1), |
| type_(-1), |
| normalized_(GL_FALSE), |
| stride_(0), |
| pointer_(nullptr) { |
| 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() |
| ? nullptr |
| : 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; |
| case GL_PIXEL_UNPACK_BUFFER: |
| target_getter = GL_PIXEL_UNPACK_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 |