Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "GLContext.h"
7 #include "ScopedGLHelpers.h"
9 namespace mozilla {
10 namespace gl {
12 /* ScopedGLState - Wraps glEnable/glDisable. **********************************/
14 // Use |newState = true| to enable, |false| to disable.
15 ScopedGLState::ScopedGLState(GLContext* aGL, GLenum aCapability, bool aNewState)
16 : ScopedGLWrapper<ScopedGLState>(aGL)
17 , mCapability(aCapability)
18 {
19 mOldState = mGL->fIsEnabled(mCapability);
21 // Early out if we're already in the right state.
22 if (aNewState == mOldState)
23 return;
25 if (aNewState) {
26 mGL->fEnable(mCapability);
27 } else {
28 mGL->fDisable(mCapability);
29 }
30 }
32 ScopedGLState::ScopedGLState(GLContext* aGL, GLenum aCapability)
33 : ScopedGLWrapper<ScopedGLState>(aGL)
34 , mCapability(aCapability)
35 {
36 mOldState = mGL->fIsEnabled(mCapability);
37 }
39 void
40 ScopedGLState::UnwrapImpl()
41 {
42 if (mOldState) {
43 mGL->fEnable(mCapability);
44 } else {
45 mGL->fDisable(mCapability);
46 }
47 }
50 /* ScopedBindFramebuffer - Saves and restores with GetUserBoundFB and BindUserFB. */
52 void
53 ScopedBindFramebuffer::Init()
54 {
55 mOldFB = mGL->GetFB();
56 }
58 ScopedBindFramebuffer::ScopedBindFramebuffer(GLContext* aGL)
59 : ScopedGLWrapper<ScopedBindFramebuffer>(aGL)
60 {
61 Init();
62 }
64 ScopedBindFramebuffer::ScopedBindFramebuffer(GLContext* aGL, GLuint aNewFB)
65 : ScopedGLWrapper<ScopedBindFramebuffer>(aGL)
66 {
67 Init();
68 mGL->BindFB(aNewFB);
69 }
71 void
72 ScopedBindFramebuffer::UnwrapImpl()
73 {
74 // Check that we're not falling out of scope after the current context changed.
75 MOZ_ASSERT(mGL->IsCurrent());
77 mGL->BindFB(mOldFB);
78 }
81 /* ScopedBindTextureUnit ******************************************************/
83 ScopedBindTextureUnit::ScopedBindTextureUnit(GLContext* aGL, GLenum aTexUnit)
84 : ScopedGLWrapper<ScopedBindTextureUnit>(aGL)
85 {
86 MOZ_ASSERT(aTexUnit >= LOCAL_GL_TEXTURE0);
87 mGL->GetUIntegerv(LOCAL_GL_ACTIVE_TEXTURE, &mOldTexUnit);
88 mGL->fActiveTexture(aTexUnit);
89 }
91 void
92 ScopedBindTextureUnit::UnwrapImpl() {
93 // Check that we're not falling out of scope after the current context changed.
94 MOZ_ASSERT(mGL->IsCurrent());
96 mGL->fActiveTexture(mOldTexUnit);
97 }
100 /* ScopedTexture **************************************************************/
102 ScopedTexture::ScopedTexture(GLContext* aGL)
103 : ScopedGLWrapper<ScopedTexture>(aGL)
104 {
105 mGL->fGenTextures(1, &mTexture);
106 }
108 void
109 ScopedTexture::UnwrapImpl()
110 {
111 // Check that we're not falling out of scope after
112 // the current context changed.
113 MOZ_ASSERT(mGL->IsCurrent());
115 mGL->fDeleteTextures(1, &mTexture);
116 }
118 /* ScopedBindTexture **********************************************************/
119 void
120 ScopedBindTexture::Init(GLenum aTarget)
121 {
122 mTarget = aTarget;
123 mOldTex = 0;
124 GLenum bindingTarget = (aTarget == LOCAL_GL_TEXTURE_2D) ? LOCAL_GL_TEXTURE_BINDING_2D
125 : (aTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) ? LOCAL_GL_TEXTURE_BINDING_RECTANGLE_ARB
126 : (aTarget == LOCAL_GL_TEXTURE_CUBE_MAP) ? LOCAL_GL_TEXTURE_BINDING_CUBE_MAP
127 : (aTarget == LOCAL_GL_TEXTURE_EXTERNAL) ? LOCAL_GL_TEXTURE_BINDING_EXTERNAL
128 : LOCAL_GL_NONE;
129 MOZ_ASSERT(bindingTarget != LOCAL_GL_NONE);
130 mGL->GetUIntegerv(bindingTarget, &mOldTex);
131 }
133 ScopedBindTexture::ScopedBindTexture(GLContext* aGL, GLuint aNewTex, GLenum aTarget)
134 : ScopedGLWrapper<ScopedBindTexture>(aGL)
135 {
136 Init(aTarget);
137 mGL->fBindTexture(aTarget, aNewTex);
138 }
140 void
141 ScopedBindTexture::UnwrapImpl()
142 {
143 // Check that we're not falling out of scope after the current context changed.
144 MOZ_ASSERT(mGL->IsCurrent());
146 mGL->fBindTexture(mTarget, mOldTex);
147 }
150 /* ScopedBindRenderbuffer *****************************************************/
152 void
153 ScopedBindRenderbuffer::Init()
154 {
155 mOldRB = 0;
156 mGL->GetUIntegerv(LOCAL_GL_RENDERBUFFER_BINDING, &mOldRB);
157 }
159 ScopedBindRenderbuffer::ScopedBindRenderbuffer(GLContext* aGL)
160 : ScopedGLWrapper<ScopedBindRenderbuffer>(aGL)
161 {
162 Init();
163 }
165 ScopedBindRenderbuffer::ScopedBindRenderbuffer(GLContext* aGL, GLuint aNewRB)
166 : ScopedGLWrapper<ScopedBindRenderbuffer>(aGL)
167 {
168 Init();
169 mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, aNewRB);
170 }
172 void
173 ScopedBindRenderbuffer::UnwrapImpl() {
174 // Check that we're not falling out of scope after the current context changed.
175 MOZ_ASSERT(mGL->IsCurrent());
177 mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mOldRB);
178 }
181 /* ScopedFramebufferForTexture ************************************************/
182 ScopedFramebufferForTexture::ScopedFramebufferForTexture(GLContext* aGL,
183 GLuint aTexture,
184 GLenum aTarget)
185 : ScopedGLWrapper<ScopedFramebufferForTexture>(aGL)
186 , mComplete(false)
187 , mFB(0)
188 {
189 mGL->fGenFramebuffers(1, &mFB);
190 ScopedBindFramebuffer autoFB(aGL, mFB);
191 mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
192 LOCAL_GL_COLOR_ATTACHMENT0,
193 aTarget,
194 aTexture,
195 0);
197 GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
198 if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE) {
199 mComplete = true;
200 } else {
201 mGL->fDeleteFramebuffers(1, &mFB);
202 mFB = 0;
203 }
204 }
206 void ScopedFramebufferForTexture::UnwrapImpl()
207 {
208 if (!mFB)
209 return;
211 mGL->fDeleteFramebuffers(1, &mFB);
212 mFB = 0;
213 }
216 /* ScopedFramebufferForRenderbuffer *******************************************/
219 ScopedFramebufferForRenderbuffer::ScopedFramebufferForRenderbuffer(GLContext* aGL,
220 GLuint aRB)
221 : ScopedGLWrapper<ScopedFramebufferForRenderbuffer>(aGL)
222 , mComplete(false)
223 , mFB(0)
224 {
225 mGL->fGenFramebuffers(1, &mFB);
226 ScopedBindFramebuffer autoFB(aGL, mFB);
227 mGL->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
228 LOCAL_GL_COLOR_ATTACHMENT0,
229 LOCAL_GL_RENDERBUFFER,
230 aRB);
232 GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
233 if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE) {
234 mComplete = true;
235 } else {
236 mGL->fDeleteFramebuffers(1, &mFB);
237 mFB = 0;
238 }
239 }
241 void
242 ScopedFramebufferForRenderbuffer::UnwrapImpl()
243 {
244 if (!mFB)
245 return;
247 mGL->fDeleteFramebuffers(1, &mFB);
248 mFB = 0;
249 }
251 /* ScopedViewportRect *********************************************************/
253 ScopedViewportRect::ScopedViewportRect(GLContext* aGL,
254 GLint x, GLint y,
255 GLsizei width, GLsizei height)
256 : ScopedGLWrapper<ScopedViewportRect>(aGL)
257 {
258 mGL->fGetIntegerv(LOCAL_GL_VIEWPORT, mSavedViewportRect);
259 mGL->fViewport(x, y, width, height);
260 }
262 void ScopedViewportRect::UnwrapImpl()
263 {
264 mGL->fViewport(mSavedViewportRect[0],
265 mSavedViewportRect[1],
266 mSavedViewportRect[2],
267 mSavedViewportRect[3]);
268 }
270 /* ScopedScissorRect **********************************************************/
272 ScopedScissorRect::ScopedScissorRect(GLContext* aGL,
273 GLint x, GLint y,
274 GLsizei width, GLsizei height)
275 : ScopedGLWrapper<ScopedScissorRect>(aGL)
276 {
277 mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mSavedScissorRect);
278 mGL->fScissor(x, y, width, height);
279 }
281 ScopedScissorRect::ScopedScissorRect(GLContext* aGL)
282 : ScopedGLWrapper<ScopedScissorRect>(aGL)
283 {
284 mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mSavedScissorRect);
285 }
287 void ScopedScissorRect::UnwrapImpl()
288 {
289 mGL->fScissor(mSavedScissorRect[0],
290 mSavedScissorRect[1],
291 mSavedScissorRect[2],
292 mSavedScissorRect[3]);
293 }
295 } /* namespace gl */
296 } /* namespace mozilla */