/src/mozilla-central/gfx/gl/ScopedGLHelpers.cpp
Line | Count | Source (jump to first uncovered line) |
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 "mozilla/UniquePtr.h" |
7 | | |
8 | | #include "GLContext.h" |
9 | | #include "ScopedGLHelpers.h" |
10 | | |
11 | | namespace mozilla { |
12 | | namespace gl { |
13 | | |
14 | | #ifdef DEBUG |
15 | | bool |
16 | | IsContextCurrent(GLContext* gl) |
17 | | { |
18 | | return gl->IsCurrent(); |
19 | | } |
20 | | #endif |
21 | | |
22 | | /* ScopedGLState - Wraps glEnable/glDisable. **********************************/ |
23 | | |
24 | | // Use |newState = true| to enable, |false| to disable. |
25 | | ScopedGLState::ScopedGLState(GLContext* aGL, GLenum aCapability, bool aNewState) |
26 | | : ScopedGLWrapper<ScopedGLState>(aGL) |
27 | | , mCapability(aCapability) |
28 | 0 | { |
29 | 0 | mOldState = mGL->fIsEnabled(mCapability); |
30 | 0 |
|
31 | 0 | // Early out if we're already in the right state. |
32 | 0 | if (aNewState == mOldState) |
33 | 0 | return; |
34 | 0 | |
35 | 0 | if (aNewState) { |
36 | 0 | mGL->fEnable(mCapability); |
37 | 0 | } else { |
38 | 0 | mGL->fDisable(mCapability); |
39 | 0 | } |
40 | 0 | } |
41 | | |
42 | | ScopedGLState::ScopedGLState(GLContext* aGL, GLenum aCapability) |
43 | | : ScopedGLWrapper<ScopedGLState>(aGL) |
44 | | , mCapability(aCapability) |
45 | 0 | { |
46 | 0 | mOldState = mGL->fIsEnabled(mCapability); |
47 | 0 | } |
48 | | |
49 | | void |
50 | | ScopedGLState::UnwrapImpl() |
51 | 0 | { |
52 | 0 | if (mOldState) { |
53 | 0 | mGL->fEnable(mCapability); |
54 | 0 | } else { |
55 | 0 | mGL->fDisable(mCapability); |
56 | 0 | } |
57 | 0 | } |
58 | | |
59 | | |
60 | | /* ScopedBindFramebuffer - Saves and restores with GetUserBoundFB and BindUserFB. */ |
61 | | |
62 | | void |
63 | | ScopedBindFramebuffer::Init() |
64 | 0 | { |
65 | 0 | if (mGL->IsSupported(GLFeature::split_framebuffer)) { |
66 | 0 | mOldReadFB = mGL->GetReadFB(); |
67 | 0 | mOldDrawFB = mGL->GetDrawFB(); |
68 | 0 | } else { |
69 | 0 | mOldReadFB = mOldDrawFB = mGL->GetFB(); |
70 | 0 | } |
71 | 0 | } |
72 | | |
73 | | ScopedBindFramebuffer::ScopedBindFramebuffer(GLContext* aGL) |
74 | | : ScopedGLWrapper<ScopedBindFramebuffer>(aGL) |
75 | 0 | { |
76 | 0 | Init(); |
77 | 0 | } |
78 | | |
79 | | ScopedBindFramebuffer::ScopedBindFramebuffer(GLContext* aGL, GLuint aNewFB) |
80 | | : ScopedGLWrapper<ScopedBindFramebuffer>(aGL) |
81 | 0 | { |
82 | 0 | Init(); |
83 | 0 | mGL->BindFB(aNewFB); |
84 | 0 | } |
85 | | |
86 | | void |
87 | | ScopedBindFramebuffer::UnwrapImpl() |
88 | 0 | { |
89 | 0 | if (mOldReadFB == mOldDrawFB) { |
90 | 0 | mGL->BindFB(mOldDrawFB); |
91 | 0 | } else { |
92 | 0 | mGL->BindDrawFB(mOldDrawFB); |
93 | 0 | mGL->BindReadFB(mOldReadFB); |
94 | 0 | } |
95 | 0 | } |
96 | | |
97 | | |
98 | | /* ScopedBindTextureUnit ******************************************************/ |
99 | | |
100 | | ScopedBindTextureUnit::ScopedBindTextureUnit(GLContext* aGL, GLenum aTexUnit) |
101 | | : ScopedGLWrapper<ScopedBindTextureUnit>(aGL) |
102 | | , mOldTexUnit(0) |
103 | 0 | { |
104 | 0 | MOZ_ASSERT(aTexUnit >= LOCAL_GL_TEXTURE0); |
105 | 0 | mGL->GetUIntegerv(LOCAL_GL_ACTIVE_TEXTURE, &mOldTexUnit); |
106 | 0 | mGL->fActiveTexture(aTexUnit); |
107 | 0 | } |
108 | | |
109 | | void |
110 | 0 | ScopedBindTextureUnit::UnwrapImpl() { |
111 | 0 | mGL->fActiveTexture(mOldTexUnit); |
112 | 0 | } |
113 | | |
114 | | |
115 | | /* ScopedTexture **************************************************************/ |
116 | | |
117 | | ScopedTexture::ScopedTexture(GLContext* aGL) |
118 | | : ScopedGLWrapper<ScopedTexture>(aGL) |
119 | | , mTexture(0) |
120 | 0 | { |
121 | 0 | mGL->fGenTextures(1, &mTexture); |
122 | 0 | } |
123 | | |
124 | | void |
125 | | ScopedTexture::UnwrapImpl() |
126 | 0 | { |
127 | 0 | mGL->fDeleteTextures(1, &mTexture); |
128 | 0 | } |
129 | | |
130 | | /* ScopedFramebuffer **************************************************************/ |
131 | | |
132 | | ScopedFramebuffer::ScopedFramebuffer(GLContext* aGL) |
133 | | : ScopedGLWrapper<ScopedFramebuffer>(aGL) |
134 | | , mFB(0) |
135 | 0 | { |
136 | 0 | mGL->fGenFramebuffers(1, &mFB); |
137 | 0 | } |
138 | | |
139 | | void |
140 | | ScopedFramebuffer::UnwrapImpl() |
141 | 0 | { |
142 | 0 | mGL->fDeleteFramebuffers(1, &mFB); |
143 | 0 | } |
144 | | |
145 | | |
146 | | /* ScopedRenderbuffer **************************************************************/ |
147 | | |
148 | | ScopedRenderbuffer::ScopedRenderbuffer(GLContext* aGL) |
149 | | : ScopedGLWrapper<ScopedRenderbuffer>(aGL) |
150 | | , mRB(0) |
151 | 0 | { |
152 | 0 | mGL->fGenRenderbuffers(1, &mRB); |
153 | 0 | } |
154 | | |
155 | | void |
156 | | ScopedRenderbuffer::UnwrapImpl() |
157 | 0 | { |
158 | 0 | mGL->fDeleteRenderbuffers(1, &mRB); |
159 | 0 | } |
160 | | |
161 | | /* ScopedBindTexture **********************************************************/ |
162 | | |
163 | | static GLuint |
164 | | GetBoundTexture(GLContext* gl, GLenum texTarget) |
165 | 0 | { |
166 | 0 | GLenum bindingTarget; |
167 | 0 | switch (texTarget) { |
168 | 0 | case LOCAL_GL_TEXTURE_2D: |
169 | 0 | bindingTarget = LOCAL_GL_TEXTURE_BINDING_2D; |
170 | 0 | break; |
171 | 0 |
|
172 | 0 | case LOCAL_GL_TEXTURE_CUBE_MAP: |
173 | 0 | bindingTarget = LOCAL_GL_TEXTURE_BINDING_CUBE_MAP; |
174 | 0 | break; |
175 | 0 |
|
176 | 0 | case LOCAL_GL_TEXTURE_3D: |
177 | 0 | bindingTarget = LOCAL_GL_TEXTURE_BINDING_3D; |
178 | 0 | break; |
179 | 0 |
|
180 | 0 | case LOCAL_GL_TEXTURE_2D_ARRAY: |
181 | 0 | bindingTarget = LOCAL_GL_TEXTURE_BINDING_2D_ARRAY; |
182 | 0 | break; |
183 | 0 |
|
184 | 0 | case LOCAL_GL_TEXTURE_RECTANGLE_ARB: |
185 | 0 | bindingTarget = LOCAL_GL_TEXTURE_BINDING_RECTANGLE_ARB; |
186 | 0 | break; |
187 | 0 |
|
188 | 0 | case LOCAL_GL_TEXTURE_EXTERNAL: |
189 | 0 | bindingTarget = LOCAL_GL_TEXTURE_BINDING_EXTERNAL; |
190 | 0 | break; |
191 | 0 |
|
192 | 0 | default: |
193 | 0 | MOZ_CRASH("bad texTarget"); |
194 | 0 | } |
195 | 0 |
|
196 | 0 | GLuint ret = 0; |
197 | 0 | gl->GetUIntegerv(bindingTarget, &ret); |
198 | 0 | return ret; |
199 | 0 | } |
200 | | |
201 | | ScopedBindTexture::ScopedBindTexture(GLContext* aGL, GLuint aNewTex, GLenum aTarget) |
202 | | : ScopedGLWrapper<ScopedBindTexture>(aGL) |
203 | | , mTarget(aTarget) |
204 | | , mOldTex(GetBoundTexture(aGL, aTarget)) |
205 | 0 | { |
206 | 0 | mGL->fBindTexture(mTarget, aNewTex); |
207 | 0 | } |
208 | | |
209 | | void |
210 | | ScopedBindTexture::UnwrapImpl() |
211 | 0 | { |
212 | 0 | mGL->fBindTexture(mTarget, mOldTex); |
213 | 0 | } |
214 | | |
215 | | |
216 | | /* ScopedBindRenderbuffer *****************************************************/ |
217 | | |
218 | | void |
219 | | ScopedBindRenderbuffer::Init() |
220 | 0 | { |
221 | 0 | mOldRB = 0; |
222 | 0 | mGL->GetUIntegerv(LOCAL_GL_RENDERBUFFER_BINDING, &mOldRB); |
223 | 0 | } |
224 | | |
225 | | ScopedBindRenderbuffer::ScopedBindRenderbuffer(GLContext* aGL) |
226 | | : ScopedGLWrapper<ScopedBindRenderbuffer>(aGL) |
227 | 0 | { |
228 | 0 | Init(); |
229 | 0 | } |
230 | | |
231 | | ScopedBindRenderbuffer::ScopedBindRenderbuffer(GLContext* aGL, GLuint aNewRB) |
232 | | : ScopedGLWrapper<ScopedBindRenderbuffer>(aGL) |
233 | 0 | { |
234 | 0 | Init(); |
235 | 0 | mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, aNewRB); |
236 | 0 | } |
237 | | |
238 | | void |
239 | | ScopedBindRenderbuffer::UnwrapImpl() |
240 | 0 | { |
241 | 0 | mGL->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mOldRB); |
242 | 0 | } |
243 | | |
244 | | |
245 | | /* ScopedFramebufferForTexture ************************************************/ |
246 | | ScopedFramebufferForTexture::ScopedFramebufferForTexture(GLContext* aGL, |
247 | | GLuint aTexture, |
248 | | GLenum aTarget) |
249 | | : ScopedGLWrapper<ScopedFramebufferForTexture>(aGL) |
250 | | , mComplete(false) |
251 | | , mFB(0) |
252 | 0 | { |
253 | 0 | mGL->fGenFramebuffers(1, &mFB); |
254 | 0 | ScopedBindFramebuffer autoFB(aGL, mFB); |
255 | 0 | mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, |
256 | 0 | LOCAL_GL_COLOR_ATTACHMENT0, |
257 | 0 | aTarget, |
258 | 0 | aTexture, |
259 | 0 | 0); |
260 | 0 |
|
261 | 0 | GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); |
262 | 0 | if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE) { |
263 | 0 | mComplete = true; |
264 | 0 | } else { |
265 | 0 | mGL->fDeleteFramebuffers(1, &mFB); |
266 | 0 | mFB = 0; |
267 | 0 | } |
268 | 0 | } |
269 | | |
270 | | void ScopedFramebufferForTexture::UnwrapImpl() |
271 | 0 | { |
272 | 0 | if (!mFB) |
273 | 0 | return; |
274 | 0 | |
275 | 0 | mGL->fDeleteFramebuffers(1, &mFB); |
276 | 0 | mFB = 0; |
277 | 0 | } |
278 | | |
279 | | |
280 | | /* ScopedFramebufferForRenderbuffer *******************************************/ |
281 | | |
282 | | |
283 | | ScopedFramebufferForRenderbuffer::ScopedFramebufferForRenderbuffer(GLContext* aGL, |
284 | | GLuint aRB) |
285 | | : ScopedGLWrapper<ScopedFramebufferForRenderbuffer>(aGL) |
286 | | , mComplete(false) |
287 | | , mFB(0) |
288 | 0 | { |
289 | 0 | mGL->fGenFramebuffers(1, &mFB); |
290 | 0 | ScopedBindFramebuffer autoFB(aGL, mFB); |
291 | 0 | mGL->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, |
292 | 0 | LOCAL_GL_COLOR_ATTACHMENT0, |
293 | 0 | LOCAL_GL_RENDERBUFFER, |
294 | 0 | aRB); |
295 | 0 |
|
296 | 0 | GLenum status = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); |
297 | 0 | if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE) { |
298 | 0 | mComplete = true; |
299 | 0 | } else { |
300 | 0 | mGL->fDeleteFramebuffers(1, &mFB); |
301 | 0 | mFB = 0; |
302 | 0 | } |
303 | 0 | } |
304 | | |
305 | | void |
306 | | ScopedFramebufferForRenderbuffer::UnwrapImpl() |
307 | 0 | { |
308 | 0 | if (!mFB) |
309 | 0 | return; |
310 | 0 | |
311 | 0 | mGL->fDeleteFramebuffers(1, &mFB); |
312 | 0 | mFB = 0; |
313 | 0 | } |
314 | | |
315 | | /* ScopedViewportRect *********************************************************/ |
316 | | |
317 | | ScopedViewportRect::ScopedViewportRect(GLContext* aGL, |
318 | | GLint x, GLint y, |
319 | | GLsizei width, GLsizei height) |
320 | | : ScopedGLWrapper<ScopedViewportRect>(aGL) |
321 | 0 | { |
322 | 0 | mGL->fGetIntegerv(LOCAL_GL_VIEWPORT, mSavedViewportRect); |
323 | 0 | mGL->fViewport(x, y, width, height); |
324 | 0 | } |
325 | | |
326 | | void ScopedViewportRect::UnwrapImpl() |
327 | 0 | { |
328 | 0 | mGL->fViewport(mSavedViewportRect[0], |
329 | 0 | mSavedViewportRect[1], |
330 | 0 | mSavedViewportRect[2], |
331 | 0 | mSavedViewportRect[3]); |
332 | 0 | } |
333 | | |
334 | | /* ScopedScissorRect **********************************************************/ |
335 | | |
336 | | ScopedScissorRect::ScopedScissorRect(GLContext* aGL, |
337 | | GLint x, GLint y, |
338 | | GLsizei width, GLsizei height) |
339 | | : ScopedGLWrapper<ScopedScissorRect>(aGL) |
340 | 0 | { |
341 | 0 | mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mSavedScissorRect); |
342 | 0 | mGL->fScissor(x, y, width, height); |
343 | 0 | } |
344 | | |
345 | | ScopedScissorRect::ScopedScissorRect(GLContext* aGL) |
346 | | : ScopedGLWrapper<ScopedScissorRect>(aGL) |
347 | 0 | { |
348 | 0 | mGL->fGetIntegerv(LOCAL_GL_SCISSOR_BOX, mSavedScissorRect); |
349 | 0 | } |
350 | | |
351 | | void ScopedScissorRect::UnwrapImpl() |
352 | 0 | { |
353 | 0 | mGL->fScissor(mSavedScissorRect[0], |
354 | 0 | mSavedScissorRect[1], |
355 | 0 | mSavedScissorRect[2], |
356 | 0 | mSavedScissorRect[3]); |
357 | 0 | } |
358 | | |
359 | | /* ScopedVertexAttribPointer **************************************************/ |
360 | | |
361 | | ScopedVertexAttribPointer::ScopedVertexAttribPointer(GLContext* aGL, |
362 | | GLuint index, |
363 | | GLint size, |
364 | | GLenum type, |
365 | | realGLboolean normalized, |
366 | | GLsizei stride, |
367 | | GLuint buffer, |
368 | | const GLvoid* pointer) |
369 | | : ScopedGLWrapper<ScopedVertexAttribPointer>(aGL) |
370 | | , mAttribEnabled(0) |
371 | | , mAttribSize(0) |
372 | | , mAttribStride(0) |
373 | | , mAttribType(0) |
374 | | , mAttribNormalized(0) |
375 | | , mAttribBufferBinding(0) |
376 | | , mAttribPointer(nullptr) |
377 | | , mBoundBuffer(0) |
378 | 0 | { |
379 | 0 | WrapImpl(index); |
380 | 0 | mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, buffer); |
381 | 0 | mGL->fVertexAttribPointer(index, size, type, normalized, stride, pointer); |
382 | 0 | mGL->fEnableVertexAttribArray(index); |
383 | 0 | } |
384 | | |
385 | | ScopedVertexAttribPointer::ScopedVertexAttribPointer(GLContext* aGL, |
386 | | GLuint index) |
387 | | : ScopedGLWrapper<ScopedVertexAttribPointer>(aGL) |
388 | | , mAttribEnabled(0) |
389 | | , mAttribSize(0) |
390 | | , mAttribStride(0) |
391 | | , mAttribType(0) |
392 | | , mAttribNormalized(0) |
393 | | , mAttribBufferBinding(0) |
394 | | , mAttribPointer(nullptr) |
395 | | , mBoundBuffer(0) |
396 | 0 | { |
397 | 0 | WrapImpl(index); |
398 | 0 | } |
399 | | |
400 | | void |
401 | | ScopedVertexAttribPointer::WrapImpl(GLuint index) |
402 | 0 | { |
403 | 0 | mAttribIndex = index; |
404 | 0 |
|
405 | 0 | /* |
406 | 0 | * mGL->fGetVertexAttribiv takes: |
407 | 0 | * VERTEX_ATTRIB_ARRAY_ENABLED |
408 | 0 | * VERTEX_ATTRIB_ARRAY_SIZE, |
409 | 0 | * VERTEX_ATTRIB_ARRAY_STRIDE, |
410 | 0 | * VERTEX_ATTRIB_ARRAY_TYPE, |
411 | 0 | * VERTEX_ATTRIB_ARRAY_NORMALIZED, |
412 | 0 | * VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, |
413 | 0 | * CURRENT_VERTEX_ATTRIB |
414 | 0 | * |
415 | 0 | * CURRENT_VERTEX_ATTRIB is vertex shader state. \o/ |
416 | 0 | * Others appear to be vertex array state, |
417 | 0 | * or alternatively in the internal vertex array state |
418 | 0 | * for a buffer object. |
419 | 0 | */ |
420 | 0 |
|
421 | 0 | mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED, &mAttribEnabled); |
422 | 0 | mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE, &mAttribSize); |
423 | 0 | mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE, &mAttribStride); |
424 | 0 | mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE, &mAttribType); |
425 | 0 | mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &mAttribNormalized); |
426 | 0 | mGL->fGetVertexAttribiv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &mAttribBufferBinding); |
427 | 0 | mGL->fGetVertexAttribPointerv(mAttribIndex, LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER, &mAttribPointer); |
428 | 0 |
|
429 | 0 | // Note that uniform values are program state, so we don't need to rebind those. |
430 | 0 |
|
431 | 0 | mGL->GetUIntegerv(LOCAL_GL_ARRAY_BUFFER_BINDING, &mBoundBuffer); |
432 | 0 | } |
433 | | |
434 | | void |
435 | | ScopedVertexAttribPointer::UnwrapImpl() |
436 | 0 | { |
437 | 0 | mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mAttribBufferBinding); |
438 | 0 | mGL->fVertexAttribPointer(mAttribIndex, mAttribSize, mAttribType, mAttribNormalized, mAttribStride, mAttribPointer); |
439 | 0 | if (mAttribEnabled) |
440 | 0 | mGL->fEnableVertexAttribArray(mAttribIndex); |
441 | 0 | else |
442 | 0 | mGL->fDisableVertexAttribArray(mAttribIndex); |
443 | 0 | mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mBoundBuffer); |
444 | 0 | } |
445 | | |
446 | | //////////////////////////////////////////////////////////////////////// |
447 | | // ScopedPackState |
448 | | |
449 | | ScopedPackState::ScopedPackState(GLContext* gl) |
450 | | : ScopedGLWrapper<ScopedPackState>(gl) |
451 | | , mAlignment(0) |
452 | | , mPixelBuffer(0) |
453 | | , mRowLength(0) |
454 | | , mSkipPixels(0) |
455 | | , mSkipRows(0) |
456 | 0 | { |
457 | 0 | mGL->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, &mAlignment); |
458 | 0 |
|
459 | 0 | if (mAlignment != 4) mGL->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, 4); |
460 | 0 |
|
461 | 0 | if (!mGL->HasPBOState()) |
462 | 0 | return; |
463 | 0 | |
464 | 0 | mGL->fGetIntegerv(LOCAL_GL_PIXEL_PACK_BUFFER_BINDING, (GLint*)&mPixelBuffer); |
465 | 0 | mGL->fGetIntegerv(LOCAL_GL_PACK_ROW_LENGTH, &mRowLength); |
466 | 0 | mGL->fGetIntegerv(LOCAL_GL_PACK_SKIP_PIXELS, &mSkipPixels); |
467 | 0 | mGL->fGetIntegerv(LOCAL_GL_PACK_SKIP_ROWS, &mSkipRows); |
468 | 0 |
|
469 | 0 | if (mPixelBuffer != 0) mGL->fBindBuffer(LOCAL_GL_PIXEL_PACK_BUFFER, 0); |
470 | 0 | if (mRowLength != 0) mGL->fPixelStorei(LOCAL_GL_PACK_ROW_LENGTH, 0); |
471 | 0 | if (mSkipPixels != 0) mGL->fPixelStorei(LOCAL_GL_PACK_SKIP_PIXELS, 0); |
472 | 0 | if (mSkipRows != 0) mGL->fPixelStorei(LOCAL_GL_PACK_SKIP_ROWS, 0); |
473 | 0 | } |
474 | | |
475 | | void |
476 | | ScopedPackState::UnwrapImpl() |
477 | 0 | { |
478 | 0 | mGL->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, mAlignment); |
479 | 0 |
|
480 | 0 | if (!mGL->HasPBOState()) |
481 | 0 | return; |
482 | 0 | |
483 | 0 | mGL->fBindBuffer(LOCAL_GL_PIXEL_PACK_BUFFER, mPixelBuffer); |
484 | 0 | mGL->fPixelStorei(LOCAL_GL_PACK_ROW_LENGTH, mRowLength); |
485 | 0 | mGL->fPixelStorei(LOCAL_GL_PACK_SKIP_PIXELS, mSkipPixels); |
486 | 0 | mGL->fPixelStorei(LOCAL_GL_PACK_SKIP_ROWS, mSkipRows); |
487 | 0 | } |
488 | | |
489 | | //////////////////////////////////////////////////////////////////////// |
490 | | // ResetUnpackState |
491 | | |
492 | | ResetUnpackState::ResetUnpackState(GLContext* gl) |
493 | | : ScopedGLWrapper<ResetUnpackState>(gl) |
494 | | , mAlignment(0) |
495 | | , mPBO(0) |
496 | | , mRowLength(0) |
497 | | , mImageHeight(0) |
498 | | , mSkipPixels(0) |
499 | | , mSkipRows(0) |
500 | | , mSkipImages(0) |
501 | 0 | { |
502 | 0 | const auto fnReset = [&](GLenum pname, GLuint val, GLuint* const out_old) { |
503 | 0 | mGL->GetUIntegerv(pname, out_old); |
504 | 0 | if (*out_old != val) { |
505 | 0 | mGL->fPixelStorei(pname, val); |
506 | 0 | } |
507 | 0 | }; |
508 | 0 |
|
509 | 0 | // Default is 4, but 1 is more useful. |
510 | 0 | fnReset(LOCAL_GL_UNPACK_ALIGNMENT, 1, &mAlignment); |
511 | 0 |
|
512 | 0 | if (!mGL->HasPBOState()) |
513 | 0 | return; |
514 | 0 | |
515 | 0 | mGL->GetUIntegerv(LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING, &mPBO); |
516 | 0 | if (mPBO != 0) mGL->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0); |
517 | 0 |
|
518 | 0 | fnReset(LOCAL_GL_UNPACK_ROW_LENGTH , 0, &mRowLength); |
519 | 0 | fnReset(LOCAL_GL_UNPACK_IMAGE_HEIGHT, 0, &mImageHeight); |
520 | 0 | fnReset(LOCAL_GL_UNPACK_SKIP_PIXELS , 0, &mSkipPixels); |
521 | 0 | fnReset(LOCAL_GL_UNPACK_SKIP_ROWS , 0, &mSkipRows); |
522 | 0 | fnReset(LOCAL_GL_UNPACK_SKIP_IMAGES , 0, &mSkipImages); |
523 | 0 | } |
524 | | |
525 | | void |
526 | | ResetUnpackState::UnwrapImpl() |
527 | 0 | { |
528 | 0 | mGL->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, mAlignment); |
529 | 0 |
|
530 | 0 | if (!mGL->HasPBOState()) |
531 | 0 | return; |
532 | 0 | |
533 | 0 | mGL->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPBO); |
534 | 0 |
|
535 | 0 | mGL->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, mRowLength); |
536 | 0 | mGL->fPixelStorei(LOCAL_GL_UNPACK_IMAGE_HEIGHT, mImageHeight); |
537 | 0 | mGL->fPixelStorei(LOCAL_GL_UNPACK_SKIP_PIXELS, mSkipPixels); |
538 | 0 | mGL->fPixelStorei(LOCAL_GL_UNPACK_SKIP_ROWS, mSkipRows); |
539 | 0 | mGL->fPixelStorei(LOCAL_GL_UNPACK_SKIP_IMAGES, mSkipImages); |
540 | 0 | } |
541 | | |
542 | | //////////////////////////////////////////////////////////////////////// |
543 | | // ScopedBindPBO |
544 | | |
545 | | static GLuint |
546 | | GetPBOBinding(GLContext* gl, GLenum target) |
547 | 0 | { |
548 | 0 | if (!gl->HasPBOState()) |
549 | 0 | return 0; |
550 | 0 | |
551 | 0 | GLenum targetBinding; |
552 | 0 | switch (target) { |
553 | 0 | case LOCAL_GL_PIXEL_PACK_BUFFER: |
554 | 0 | targetBinding = LOCAL_GL_PIXEL_PACK_BUFFER_BINDING; |
555 | 0 | break; |
556 | 0 |
|
557 | 0 | case LOCAL_GL_PIXEL_UNPACK_BUFFER: |
558 | 0 | targetBinding = LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING; |
559 | 0 | break; |
560 | 0 |
|
561 | 0 | default: |
562 | 0 | MOZ_CRASH(); |
563 | 0 | } |
564 | 0 |
|
565 | 0 | return gl->GetIntAs<GLuint>(targetBinding); |
566 | 0 | } |
567 | | |
568 | | ScopedBindPBO::ScopedBindPBO(GLContext* gl, GLenum target) |
569 | | : ScopedGLWrapper<ScopedBindPBO>(gl) |
570 | | , mTarget(target) |
571 | | , mPBO(GetPBOBinding(mGL, mTarget)) |
572 | 0 | { } |
573 | | |
574 | | void |
575 | | ScopedBindPBO::UnwrapImpl() |
576 | 0 | { |
577 | 0 | if (!mGL->HasPBOState()) |
578 | 0 | return; |
579 | 0 | |
580 | 0 | mGL->fBindBuffer(mTarget, mPBO); |
581 | 0 | } |
582 | | |
583 | | } /* namespace gl */ |
584 | | } /* namespace mozilla */ |