diff -r 000000000000 -r 6474c204b198 gfx/gl/ScopedGLHelpers.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/gl/ScopedGLHelpers.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,296 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "GLContext.h" +#include "ScopedGLHelpers.h" + +namespace mozilla { +namespace gl { + +/* ScopedGLState - Wraps glEnable/glDisable. **********************************/ + +// Use |newState = true| to enable, |false| to disable. +ScopedGLState::ScopedGLState(GLContext* aGL, GLenum aCapability, bool aNewState) + : ScopedGLWrapper(aGL) + , mCapability(aCapability) +{ + mOldState = mGL->fIsEnabled(mCapability); + + // Early out if we're already in the right state. + if (aNewState == mOldState) + return; + + if (aNewState) { + mGL->fEnable(mCapability); + } else { + mGL->fDisable(mCapability); + } +} + +ScopedGLState::ScopedGLState(GLContext* aGL, GLenum aCapability) + : ScopedGLWrapper(aGL) + , mCapability(aCapability) +{ + mOldState = mGL->fIsEnabled(mCapability); +} + +void +ScopedGLState::UnwrapImpl() +{ + if (mOldState) { + mGL->fEnable(mCapability); + } else { + mGL->fDisable(mCapability); + } +} + + +/* ScopedBindFramebuffer - Saves and restores with GetUserBoundFB and BindUserFB. */ + +void +ScopedBindFramebuffer::Init() +{ + mOldFB = mGL->GetFB(); +} + +ScopedBindFramebuffer::ScopedBindFramebuffer(GLContext* aGL) + : ScopedGLWrapper(aGL) +{ + Init(); +} + +ScopedBindFramebuffer::ScopedBindFramebuffer(GLContext* aGL, GLuint aNewFB) + : ScopedGLWrapper(aGL) +{ + Init(); + mGL->BindFB(aNewFB); +} + +void +ScopedBindFramebuffer::UnwrapImpl() +{ + // Check that we're not falling out of scope after the current context changed. + MOZ_ASSERT(mGL->IsCurrent()); + + mGL->BindFB(mOldFB); +} + + +/* ScopedBindTextureUnit ******************************************************/ + +ScopedBindTextureUnit::ScopedBindTextureUnit(GLContext* aGL, GLenum aTexUnit) + : ScopedGLWrapper(aGL) +{ + MOZ_ASSERT(aTexUnit >= LOCAL_GL_TEXTURE0); + mGL->GetUIntegerv(LOCAL_GL_ACTIVE_TEXTURE, &mOldTexUnit); + mGL->fActiveTexture(aTexUnit); +} + +void +ScopedBindTextureUnit::UnwrapImpl() { + // Check that we're not falling out of scope after the current context changed. + MOZ_ASSERT(mGL->IsCurrent()); + + mGL->fActiveTexture(mOldTexUnit); +} + + +/* ScopedTexture **************************************************************/ + +ScopedTexture::ScopedTexture(GLContext* aGL) + : ScopedGLWrapper(aGL) +{ + mGL->fGenTextures(1, &mTexture); +} + +void +ScopedTexture::UnwrapImpl() +{ + // Check that we're not falling out of scope after + // the current context changed. + MOZ_ASSERT(mGL->IsCurrent()); + + mGL->fDeleteTextures(1, &mTexture); +} + +/* ScopedBindTexture **********************************************************/ +void +ScopedBindTexture::Init(GLenum aTarget) +{ + mTarget = aTarget; + mOldTex = 0; + GLenum bindingTarget = (aTarget == LOCAL_GL_TEXTURE_2D) ? LOCAL_GL_TEXTURE_BINDING_2D + : (aTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) ? LOCAL_GL_TEXTURE_BINDING_RECTANGLE_ARB + : (aTarget == LOCAL_GL_TEXTURE_CUBE_MAP) ? LOCAL_GL_TEXTURE_BINDING_CUBE_MAP + : (aTarget == LOCAL_GL_TEXTURE_EXTERNAL) ? LOCAL_GL_TEXTURE_BINDING_EXTERNAL + : LOCAL_GL_NONE; + MOZ_ASSERT(bindingTarget != LOCAL_GL_NONE); + mGL->GetUIntegerv(bindingTarget, &mOldTex); +} + +ScopedBindTexture::ScopedBindTexture(GLContext* aGL, GLuint aNewTex, GLenum aTarget) + : ScopedGLWrapper(aGL) + { + Init(aTarget); + mGL->fBindTexture(aTarget, aNewTex); + } + +void +ScopedBindTexture::UnwrapImpl() +{ + // Check that we're not falling out of scope after the current context changed. + MOZ_ASSERT(mGL->IsCurrent()); + + mGL->fBindTexture(mTarget, mOldTex); +} + + +/* ScopedBindRenderbuffer *****************************************************/ + +void +ScopedBindRenderbuffer::Init() +{ + mOldRB = 0; + mGL->GetUIntegerv(LOCAL_GL_RENDERBUFFER_BINDING, &mOldRB); +} + +ScopedBindRenderbuffer::ScopedBindRenderbuffer(GLContext* aGL) + : ScopedGLWrapper(aGL) +{ + Init(); +} + +ScopedBindRenderbuffer::ScopedBindRenderbuffer(GLContext* aGL, GLuint aNewRB) + : ScopedGLWrapper(aGL) +{ + Init(); + mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, aNewRB); +} + +void +ScopedBindRenderbuffer::UnwrapImpl() { + // Check that we're not falling out of scope after the current context changed. + MOZ_ASSERT(mGL->IsCurrent()); + + mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mOldRB); +} + + +/* ScopedFramebufferForTexture ************************************************/ +ScopedFramebufferForTexture::ScopedFramebufferForTexture(GLContext* aGL, + GLuint aTexture, + GLenum aTarget) + : ScopedGLWrapper(aGL) + , mComplete(false) + , mFB(0) +{ + mGL->fGenFramebuffers(1, &mFB); + ScopedBindFramebuffer autoFB(aGL, mFB); + mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, + LOCAL_GL_COLOR_ATTACHMENT0, + aTarget, + aTexture, + 0); + + GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); + if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE) { + mComplete = true; + } else { + mGL->fDeleteFramebuffers(1, &mFB); + mFB = 0; + } +} + +void ScopedFramebufferForTexture::UnwrapImpl() +{ + if (!mFB) + return; + + mGL->fDeleteFramebuffers(1, &mFB); + mFB = 0; +} + + +/* ScopedFramebufferForRenderbuffer *******************************************/ + + +ScopedFramebufferForRenderbuffer::ScopedFramebufferForRenderbuffer(GLContext* aGL, + GLuint aRB) + : ScopedGLWrapper(aGL) + , mComplete(false) + , mFB(0) +{ + mGL->fGenFramebuffers(1, &mFB); + ScopedBindFramebuffer autoFB(aGL, mFB); + mGL->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, + LOCAL_GL_COLOR_ATTACHMENT0, + LOCAL_GL_RENDERBUFFER, + aRB); + + GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); + if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE) { + mComplete = true; + } else { + mGL->fDeleteFramebuffers(1, &mFB); + mFB = 0; + } +} + +void +ScopedFramebufferForRenderbuffer::UnwrapImpl() +{ + if (!mFB) + return; + + mGL->fDeleteFramebuffers(1, &mFB); + mFB = 0; +} + +/* ScopedViewportRect *********************************************************/ + +ScopedViewportRect::ScopedViewportRect(GLContext* aGL, + GLint x, GLint y, + GLsizei width, GLsizei height) + : ScopedGLWrapper(aGL) +{ + mGL->fGetIntegerv(LOCAL_GL_VIEWPORT, mSavedViewportRect); + mGL->fViewport(x, y, width, height); +} + +void ScopedViewportRect::UnwrapImpl() +{ + mGL->fViewport(mSavedViewportRect[0], + mSavedViewportRect[1], + mSavedViewportRect[2], + mSavedViewportRect[3]); +} + +/* ScopedScissorRect **********************************************************/ + +ScopedScissorRect::ScopedScissorRect(GLContext* aGL, + GLint x, GLint y, + GLsizei width, GLsizei height) + : ScopedGLWrapper(aGL) +{ + mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mSavedScissorRect); + mGL->fScissor(x, y, width, height); +} + +ScopedScissorRect::ScopedScissorRect(GLContext* aGL) + : ScopedGLWrapper(aGL) +{ + mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mSavedScissorRect); +} + +void ScopedScissorRect::UnwrapImpl() +{ + mGL->fScissor(mSavedScissorRect[0], + mSavedScissorRect[1], + mSavedScissorRect[2], + mSavedScissorRect[3]); +} + +} /* namespace gl */ +} /* namespace mozilla */