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