Coverage Report

Created: 2018-09-25 14:53

/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 */