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: #ifndef SCOPEDGLHELPERS_H_ michael@0: #define SCOPEDGLHELPERS_H_ michael@0: michael@0: #include "GLContext.h" michael@0: michael@0: namespace mozilla { michael@0: namespace gl { michael@0: michael@0: //RAII via CRTP! michael@0: template michael@0: struct ScopedGLWrapper michael@0: { michael@0: private: michael@0: bool mIsUnwrapped; michael@0: michael@0: protected: michael@0: GLContext* const mGL; michael@0: michael@0: ScopedGLWrapper(GLContext* gl) michael@0: : mIsUnwrapped(false) michael@0: , mGL(gl) michael@0: { michael@0: MOZ_ASSERT(&ScopedGLWrapper::Unwrap == &Derived::Unwrap); michael@0: MOZ_ASSERT(&Derived::UnwrapImpl); michael@0: MOZ_ASSERT(mGL->IsCurrent()); michael@0: } michael@0: michael@0: virtual ~ScopedGLWrapper() { michael@0: if (!mIsUnwrapped) michael@0: Unwrap(); michael@0: } michael@0: michael@0: public: michael@0: void Unwrap() { michael@0: MOZ_ASSERT(!mIsUnwrapped); michael@0: michael@0: Derived* derived = static_cast(this); michael@0: derived->UnwrapImpl(); michael@0: michael@0: mIsUnwrapped = true; michael@0: } michael@0: }; michael@0: michael@0: // Wraps glEnable/Disable. michael@0: struct ScopedGLState michael@0: : public ScopedGLWrapper michael@0: { michael@0: friend struct ScopedGLWrapper; michael@0: michael@0: protected: michael@0: const GLenum mCapability; michael@0: bool mOldState; michael@0: michael@0: public: michael@0: // Use |newState = true| to enable, |false| to disable. michael@0: ScopedGLState(GLContext* aGL, GLenum aCapability, bool aNewState); michael@0: // variant that doesn't change state; simply records existing state to be michael@0: // restored by the destructor michael@0: ScopedGLState(GLContext* aGL, GLenum aCapability); michael@0: michael@0: protected: michael@0: void UnwrapImpl(); michael@0: }; michael@0: michael@0: // Saves and restores with GetUserBoundFB and BindUserFB. michael@0: struct ScopedBindFramebuffer michael@0: : public ScopedGLWrapper michael@0: { michael@0: friend struct ScopedGLWrapper; michael@0: michael@0: protected: michael@0: GLuint mOldFB; michael@0: michael@0: private: michael@0: void Init(); michael@0: michael@0: public: michael@0: explicit ScopedBindFramebuffer(GLContext* aGL); michael@0: ScopedBindFramebuffer(GLContext* aGL, GLuint aNewFB); michael@0: michael@0: protected: michael@0: void UnwrapImpl(); michael@0: }; michael@0: michael@0: struct ScopedBindTextureUnit michael@0: : public ScopedGLWrapper michael@0: { michael@0: friend struct ScopedGLWrapper; michael@0: michael@0: protected: michael@0: GLenum mOldTexUnit; michael@0: michael@0: public: michael@0: ScopedBindTextureUnit(GLContext* aGL, GLenum aTexUnit); michael@0: michael@0: protected: michael@0: void UnwrapImpl(); michael@0: }; michael@0: michael@0: michael@0: struct ScopedTexture michael@0: : public ScopedGLWrapper michael@0: { michael@0: friend struct ScopedGLWrapper; michael@0: michael@0: protected: michael@0: GLuint mTexture; michael@0: michael@0: public: michael@0: ScopedTexture(GLContext* aGL); michael@0: GLuint Texture() { return mTexture; } michael@0: michael@0: protected: michael@0: void UnwrapImpl(); michael@0: }; michael@0: michael@0: michael@0: struct ScopedBindTexture michael@0: : public ScopedGLWrapper michael@0: { michael@0: friend struct ScopedGLWrapper; michael@0: michael@0: protected: michael@0: GLuint mOldTex; michael@0: GLenum mTarget; michael@0: michael@0: private: michael@0: void Init(GLenum aTarget); michael@0: michael@0: public: michael@0: ScopedBindTexture(GLContext* aGL, GLuint aNewTex, michael@0: GLenum aTarget = LOCAL_GL_TEXTURE_2D); michael@0: michael@0: protected: michael@0: void UnwrapImpl(); michael@0: }; michael@0: michael@0: michael@0: struct ScopedBindRenderbuffer michael@0: : public ScopedGLWrapper michael@0: { michael@0: friend struct ScopedGLWrapper; michael@0: michael@0: protected: michael@0: GLuint mOldRB; michael@0: michael@0: private: michael@0: void Init(); michael@0: michael@0: public: michael@0: explicit ScopedBindRenderbuffer(GLContext* aGL); michael@0: michael@0: ScopedBindRenderbuffer(GLContext* aGL, GLuint aNewRB); michael@0: michael@0: protected: michael@0: void UnwrapImpl(); michael@0: }; michael@0: michael@0: michael@0: struct ScopedFramebufferForTexture michael@0: : public ScopedGLWrapper michael@0: { michael@0: friend struct ScopedGLWrapper; michael@0: michael@0: protected: michael@0: bool mComplete; // True if the framebuffer we create is complete. michael@0: GLuint mFB; michael@0: michael@0: public: michael@0: ScopedFramebufferForTexture(GLContext* aGL, GLuint aTexture, michael@0: GLenum aTarget = LOCAL_GL_TEXTURE_2D); michael@0: michael@0: bool IsComplete() const { michael@0: return mComplete; michael@0: } michael@0: michael@0: GLuint FB() const { michael@0: MOZ_ASSERT(IsComplete()); michael@0: return mFB; michael@0: } michael@0: michael@0: protected: michael@0: void UnwrapImpl(); michael@0: }; michael@0: michael@0: struct ScopedFramebufferForRenderbuffer michael@0: : public ScopedGLWrapper michael@0: { michael@0: friend struct ScopedGLWrapper; michael@0: michael@0: protected: michael@0: bool mComplete; // True if the framebuffer we create is complete. michael@0: GLuint mFB; michael@0: michael@0: public: michael@0: ScopedFramebufferForRenderbuffer(GLContext* aGL, GLuint aRB); michael@0: michael@0: bool IsComplete() const { michael@0: return mComplete; michael@0: } michael@0: michael@0: GLuint FB() const { michael@0: return mFB; michael@0: } michael@0: michael@0: protected: michael@0: void UnwrapImpl(); michael@0: }; michael@0: michael@0: struct ScopedViewportRect michael@0: : public ScopedGLWrapper michael@0: { michael@0: friend struct ScopedGLWrapper; michael@0: michael@0: protected: michael@0: GLint mSavedViewportRect[4]; michael@0: michael@0: public: michael@0: ScopedViewportRect(GLContext* aGL, GLint x, GLint y, GLsizei width, GLsizei height); michael@0: michael@0: protected: michael@0: void UnwrapImpl(); michael@0: }; michael@0: michael@0: struct ScopedScissorRect michael@0: : public ScopedGLWrapper michael@0: { michael@0: friend struct ScopedGLWrapper; michael@0: michael@0: protected: michael@0: GLint mSavedScissorRect[4]; michael@0: michael@0: public: michael@0: ScopedScissorRect(GLContext* aGL, GLint x, GLint y, GLsizei width, GLsizei height); michael@0: explicit ScopedScissorRect(GLContext* aGL); michael@0: michael@0: protected: michael@0: void UnwrapImpl(); michael@0: }; michael@0: michael@0: } /* namespace gl */ michael@0: } /* namespace mozilla */ michael@0: michael@0: #endif /* SCOPEDGLHELPERS_H_ */