| |
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/. */ |
| |
5 |
| |
6 #include "GLContext.h" |
| |
7 #include "ScopedGLHelpers.h" |
| |
8 |
| |
9 namespace mozilla { |
| |
10 namespace gl { |
| |
11 |
| |
12 /* ScopedGLState - Wraps glEnable/glDisable. **********************************/ |
| |
13 |
| |
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); |
| |
20 |
| |
21 // Early out if we're already in the right state. |
| |
22 if (aNewState == mOldState) |
| |
23 return; |
| |
24 |
| |
25 if (aNewState) { |
| |
26 mGL->fEnable(mCapability); |
| |
27 } else { |
| |
28 mGL->fDisable(mCapability); |
| |
29 } |
| |
30 } |
| |
31 |
| |
32 ScopedGLState::ScopedGLState(GLContext* aGL, GLenum aCapability) |
| |
33 : ScopedGLWrapper<ScopedGLState>(aGL) |
| |
34 , mCapability(aCapability) |
| |
35 { |
| |
36 mOldState = mGL->fIsEnabled(mCapability); |
| |
37 } |
| |
38 |
| |
39 void |
| |
40 ScopedGLState::UnwrapImpl() |
| |
41 { |
| |
42 if (mOldState) { |
| |
43 mGL->fEnable(mCapability); |
| |
44 } else { |
| |
45 mGL->fDisable(mCapability); |
| |
46 } |
| |
47 } |
| |
48 |
| |
49 |
| |
50 /* ScopedBindFramebuffer - Saves and restores with GetUserBoundFB and BindUserFB. */ |
| |
51 |
| |
52 void |
| |
53 ScopedBindFramebuffer::Init() |
| |
54 { |
| |
55 mOldFB = mGL->GetFB(); |
| |
56 } |
| |
57 |
| |
58 ScopedBindFramebuffer::ScopedBindFramebuffer(GLContext* aGL) |
| |
59 : ScopedGLWrapper<ScopedBindFramebuffer>(aGL) |
| |
60 { |
| |
61 Init(); |
| |
62 } |
| |
63 |
| |
64 ScopedBindFramebuffer::ScopedBindFramebuffer(GLContext* aGL, GLuint aNewFB) |
| |
65 : ScopedGLWrapper<ScopedBindFramebuffer>(aGL) |
| |
66 { |
| |
67 Init(); |
| |
68 mGL->BindFB(aNewFB); |
| |
69 } |
| |
70 |
| |
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()); |
| |
76 |
| |
77 mGL->BindFB(mOldFB); |
| |
78 } |
| |
79 |
| |
80 |
| |
81 /* ScopedBindTextureUnit ******************************************************/ |
| |
82 |
| |
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 } |
| |
90 |
| |
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()); |
| |
95 |
| |
96 mGL->fActiveTexture(mOldTexUnit); |
| |
97 } |
| |
98 |
| |
99 |
| |
100 /* ScopedTexture **************************************************************/ |
| |
101 |
| |
102 ScopedTexture::ScopedTexture(GLContext* aGL) |
| |
103 : ScopedGLWrapper<ScopedTexture>(aGL) |
| |
104 { |
| |
105 mGL->fGenTextures(1, &mTexture); |
| |
106 } |
| |
107 |
| |
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()); |
| |
114 |
| |
115 mGL->fDeleteTextures(1, &mTexture); |
| |
116 } |
| |
117 |
| |
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 } |
| |
132 |
| |
133 ScopedBindTexture::ScopedBindTexture(GLContext* aGL, GLuint aNewTex, GLenum aTarget) |
| |
134 : ScopedGLWrapper<ScopedBindTexture>(aGL) |
| |
135 { |
| |
136 Init(aTarget); |
| |
137 mGL->fBindTexture(aTarget, aNewTex); |
| |
138 } |
| |
139 |
| |
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()); |
| |
145 |
| |
146 mGL->fBindTexture(mTarget, mOldTex); |
| |
147 } |
| |
148 |
| |
149 |
| |
150 /* ScopedBindRenderbuffer *****************************************************/ |
| |
151 |
| |
152 void |
| |
153 ScopedBindRenderbuffer::Init() |
| |
154 { |
| |
155 mOldRB = 0; |
| |
156 mGL->GetUIntegerv(LOCAL_GL_RENDERBUFFER_BINDING, &mOldRB); |
| |
157 } |
| |
158 |
| |
159 ScopedBindRenderbuffer::ScopedBindRenderbuffer(GLContext* aGL) |
| |
160 : ScopedGLWrapper<ScopedBindRenderbuffer>(aGL) |
| |
161 { |
| |
162 Init(); |
| |
163 } |
| |
164 |
| |
165 ScopedBindRenderbuffer::ScopedBindRenderbuffer(GLContext* aGL, GLuint aNewRB) |
| |
166 : ScopedGLWrapper<ScopedBindRenderbuffer>(aGL) |
| |
167 { |
| |
168 Init(); |
| |
169 mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, aNewRB); |
| |
170 } |
| |
171 |
| |
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()); |
| |
176 |
| |
177 mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mOldRB); |
| |
178 } |
| |
179 |
| |
180 |
| |
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); |
| |
196 |
| |
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 } |
| |
205 |
| |
206 void ScopedFramebufferForTexture::UnwrapImpl() |
| |
207 { |
| |
208 if (!mFB) |
| |
209 return; |
| |
210 |
| |
211 mGL->fDeleteFramebuffers(1, &mFB); |
| |
212 mFB = 0; |
| |
213 } |
| |
214 |
| |
215 |
| |
216 /* ScopedFramebufferForRenderbuffer *******************************************/ |
| |
217 |
| |
218 |
| |
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); |
| |
231 |
| |
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 } |
| |
240 |
| |
241 void |
| |
242 ScopedFramebufferForRenderbuffer::UnwrapImpl() |
| |
243 { |
| |
244 if (!mFB) |
| |
245 return; |
| |
246 |
| |
247 mGL->fDeleteFramebuffers(1, &mFB); |
| |
248 mFB = 0; |
| |
249 } |
| |
250 |
| |
251 /* ScopedViewportRect *********************************************************/ |
| |
252 |
| |
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 } |
| |
261 |
| |
262 void ScopedViewportRect::UnwrapImpl() |
| |
263 { |
| |
264 mGL->fViewport(mSavedViewportRect[0], |
| |
265 mSavedViewportRect[1], |
| |
266 mSavedViewportRect[2], |
| |
267 mSavedViewportRect[3]); |
| |
268 } |
| |
269 |
| |
270 /* ScopedScissorRect **********************************************************/ |
| |
271 |
| |
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 } |
| |
280 |
| |
281 ScopedScissorRect::ScopedScissorRect(GLContext* aGL) |
| |
282 : ScopedGLWrapper<ScopedScissorRect>(aGL) |
| |
283 { |
| |
284 mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mSavedScissorRect); |
| |
285 } |
| |
286 |
| |
287 void ScopedScissorRect::UnwrapImpl() |
| |
288 { |
| |
289 mGL->fScissor(mSavedScissorRect[0], |
| |
290 mSavedScissorRect[1], |
| |
291 mSavedScissorRect[2], |
| |
292 mSavedScissorRect[3]); |
| |
293 } |
| |
294 |
| |
295 } /* namespace gl */ |
| |
296 } /* namespace mozilla */ |