Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/gl/GLContext.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* vim: set ts=8 sts=4 et sw=4 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef GLCONTEXT_H_
8
#define GLCONTEXT_H_
9
10
#include <bitset>
11
#include <ctype.h>
12
#include <stdint.h>
13
#include <stdio.h>
14
#include <map>
15
#include <queue>
16
#include <stack>
17
18
#ifdef DEBUG
19
#include <string.h>
20
#endif
21
22
#ifdef GetClassName
23
#undef GetClassName
24
#endif
25
26
// Define MOZ_GL_DEBUG unconditionally to enable GL debugging in opt
27
// builds.
28
#ifdef DEBUG
29
#define MOZ_GL_DEBUG 1
30
#endif
31
32
#include "../../mfbt/RefPtr.h"
33
#include "../../mfbt/UniquePtr.h"
34
#include "../../mfbt/ThreadLocal.h"
35
36
#include "GLDefs.h"
37
#include "GLLibraryLoader.h"
38
#include "nsISupportsImpl.h"
39
#include "plstr.h"
40
#include "GLContextTypes.h"
41
#include "SurfaceTypes.h"
42
#include "GLContextSymbols.h"
43
#include "base/platform_thread.h"       // for PlatformThreadId
44
#include "mozilla/GenericRefCounted.h"
45
#include "mozilla/WeakPtr.h"
46
#include "gfx2DGlue.h"
47
#include "GeckoProfiler.h"
48
49
namespace android {
50
    class GraphicBuffer;
51
} // namespace android
52
53
namespace mozilla {
54
    namespace gfx {
55
        class DataSourceSurface;
56
        class SourceSurface;
57
    } // namespace gfx
58
59
    namespace gl {
60
        class GLBlitHelper;
61
        class GLBlitTextureImageHelper;
62
        class GLContext;
63
        class GLLibraryEGL;
64
        class GLReadTexImageHelper;
65
        class GLScreenBuffer;
66
        class SharedSurface;
67
        struct SurfaceCaps;
68
    } // namespace gl
69
70
    namespace layers {
71
        class ColorTextureLayerProgram;
72
    } // namespace layers
73
74
    namespace widget {
75
        class CompositorWidget;
76
    } // namespace widget
77
} // namespace mozilla
78
79
namespace mozilla {
80
namespace gl {
81
82
enum class GLFeature {
83
    bind_buffer_offset,
84
    blend_minmax,
85
    clear_buffers,
86
    copy_buffer,
87
    depth_texture,
88
    draw_buffers,
89
    draw_instanced,
90
    draw_range_elements,
91
    element_index_uint,
92
    ES2_compatibility,
93
    ES3_compatibility,
94
    EXT_color_buffer_float,
95
    frag_color_float,
96
    frag_depth,
97
    framebuffer_blit,
98
    framebuffer_multisample,
99
    framebuffer_object,
100
    framebuffer_object_EXT_OES,
101
    get_integer_indexed,
102
    get_integer64_indexed,
103
    get_query_object_i64v,
104
    get_query_object_iv,
105
    gpu_shader4,
106
    instanced_arrays,
107
    instanced_non_arrays,
108
    internalformat_query,
109
    invalidate_framebuffer,
110
    map_buffer_range,
111
    occlusion_query,
112
    occlusion_query_boolean,
113
    occlusion_query2,
114
    packed_depth_stencil,
115
    prim_restart,
116
    prim_restart_fixed,
117
    query_counter,
118
    query_objects,
119
    query_time_elapsed,
120
    read_buffer,
121
    renderbuffer_color_float,
122
    renderbuffer_color_half_float,
123
    robust_buffer_access_behavior,
124
    robustness,
125
    sRGB,
126
    sampler_objects,
127
    seamless_cube_map_opt_in,
128
    shader_texture_lod,
129
    split_framebuffer,
130
    standard_derivatives,
131
    sync,
132
    texture_3D,
133
    texture_3D_compressed,
134
    texture_3D_copy,
135
    texture_float,
136
    texture_float_linear,
137
    texture_half_float,
138
    texture_half_float_linear,
139
    texture_non_power_of_two,
140
    texture_rg,
141
    texture_storage,
142
    texture_swizzle,
143
    transform_feedback2,
144
    uniform_buffer_object,
145
    uniform_matrix_nonsquare,
146
    vertex_array_object,
147
    EnumMax
148
};
149
150
enum class ContextProfile : uint8_t {
151
    Unknown = 0,
152
    OpenGLCore,
153
    OpenGLCompatibility,
154
    OpenGLES
155
};
156
157
enum class GLVendor {
158
    Intel,
159
    NVIDIA,
160
    ATI,
161
    Qualcomm,
162
    Imagination,
163
    Nouveau,
164
    Vivante,
165
    VMware,
166
    ARM,
167
    Other
168
};
169
170
enum class GLRenderer {
171
    Adreno200,
172
    Adreno205,
173
    AdrenoTM200,
174
    AdrenoTM205,
175
    AdrenoTM305,
176
    AdrenoTM320,
177
    AdrenoTM330,
178
    AdrenoTM420,
179
    Mali400MP,
180
    Mali450MP,
181
    SGX530,
182
    SGX540,
183
    SGX544MP,
184
    Tegra,
185
    AndroidEmulator,
186
    GalliumLlvmpipe,
187
    IntelHD3000,
188
    MicrosoftBasicRenderDriver,
189
    Other
190
};
191
192
class GLContext
193
    : public GLLibraryLoader
194
    , public GenericAtomicRefCounted
195
    , public SupportsWeakPtr<GLContext>
196
{
197
public:
198
    MOZ_DECLARE_WEAKREFERENCE_TYPENAME(GLContext)
199
    static MOZ_THREAD_LOCAL(uintptr_t) sCurrentContext;
200
201
    bool mImplicitMakeCurrent = false;
202
    bool mUseTLSIsCurrent;
203
204
    class TlsScope final {
205
        const WeakPtr<GLContext> mGL;
206
        const bool mWasTlsOk;
207
    public:
208
        explicit TlsScope(GLContext* const gl)
209
            : mGL(gl)
210
            , mWasTlsOk(gl->mUseTLSIsCurrent)
211
0
        {
212
0
            mGL->mUseTLSIsCurrent = true;
213
0
        }
214
215
0
        ~TlsScope() {
216
0
            if (mGL) {
217
0
                mGL->mUseTLSIsCurrent = mWasTlsOk;
218
0
            }
219
0
        }
220
    };
221
222
// -----------------------------------------------------------------------------
223
// basic getters
224
public:
225
226
    /**
227
     * Returns true if the context is using ANGLE. This should only be overridden
228
     * for an ANGLE implementation.
229
     */
230
0
    virtual bool IsANGLE() const {
231
0
        return false;
232
0
    }
233
234
    /**
235
    * Returns true if the context is using WARP. This should only be overridden
236
    * for an ANGLE implementation.
237
    */
238
0
    virtual bool IsWARP() const {
239
0
        return false;
240
0
    }
241
242
    virtual void GetWSIInfo(nsCString* const out) const = 0;
243
244
    /**
245
     * Return true if we are running on a OpenGL core profile context
246
     */
247
0
    inline bool IsCoreProfile() const {
248
0
        MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
249
0
250
0
        return mProfile == ContextProfile::OpenGLCore;
251
0
    }
252
253
    /**
254
     * Return true if we are running on a OpenGL compatibility profile context
255
     * (legacy profile 2.1 on Max OS X)
256
     */
257
0
    inline bool IsCompatibilityProfile() const {
258
0
        MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
259
0
260
0
        return mProfile == ContextProfile::OpenGLCompatibility;
261
0
    }
262
263
0
    inline bool IsGLES() const {
264
0
        MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
265
0
266
0
        return mProfile == ContextProfile::OpenGLES;
267
0
    }
268
269
    inline bool IsAtLeast(ContextProfile profile, unsigned int version) const
270
    {
271
        MOZ_ASSERT(profile != ContextProfile::Unknown, "IsAtLeast: bad <profile> parameter");
272
        MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
273
        MOZ_ASSERT(mVersion != 0, "unknown context version");
274
275
        if (version > mVersion) {
276
            return false;
277
        }
278
279
        return profile == mProfile;
280
    }
281
282
    /**
283
     * Return the version of the context.
284
     * Example :
285
     *   If this a OpenGL 2.1, that will return 210
286
     */
287
0
    inline uint32_t Version() const {
288
0
        return mVersion;
289
0
    }
290
291
    inline uint32_t ShadingLanguageVersion() const {
292
        return mShadingLanguageVersion;
293
    }
294
295
0
    GLVendor Vendor() const {
296
0
        return mVendor;
297
0
    }
298
299
    GLRenderer Renderer() const {
300
        return mRenderer;
301
    }
302
303
0
    bool IsContextLost() const {
304
0
        return mContextLost;
305
0
    }
306
307
0
    bool HasPBOState() const {
308
0
        return (!IsGLES() || Version() >= 300);
309
0
    }
310
311
    /**
312
     * If this context is double-buffered, returns TRUE.
313
     */
314
    virtual bool IsDoubleBuffered() const {
315
        return false;
316
    }
317
318
    virtual GLContextType GetContextType() const = 0;
319
320
    virtual bool IsCurrentImpl() const = 0;
321
    virtual bool MakeCurrentImpl() const = 0;
322
323
0
    bool IsCurrent() const {
324
0
        if (mImplicitMakeCurrent)
325
0
            return MakeCurrent();
326
0
327
0
        return IsCurrentImpl();
328
0
    }
329
330
    bool MakeCurrent(bool aForce = false) const;
331
332
    /**
333
     * Get the default framebuffer for this context.
334
     */
335
0
    virtual GLuint GetDefaultFramebuffer() {
336
0
        return 0;
337
0
    }
338
339
protected:
340
    bool mIsOffscreen;
341
    mutable bool mContextLost = false;
342
343
    /**
344
     * mVersion store the OpenGL's version, multiplied by 100. For example, if
345
     * the context is an OpenGL 2.1 context, mVersion value will be 210.
346
     */
347
    uint32_t mVersion = 0;
348
    ContextProfile mProfile = ContextProfile::Unknown;
349
350
    uint32_t mShadingLanguageVersion = 0;
351
352
    GLVendor mVendor = GLVendor::Other;
353
    GLRenderer mRenderer = GLRenderer::Other;
354
355
// -----------------------------------------------------------------------------
356
// Extensions management
357
/**
358
 * This mechanism is designed to know if an extension is supported. In the long
359
 * term, we would like to only use the extension group queries XXX_* to have
360
 * full compatibility with context version and profiles (especialy the core that
361
 * officialy don't bring any extensions).
362
 */
363
public:
364
365
    /**
366
     * Known GL extensions that can be queried by
367
     * IsExtensionSupported.  The results of this are cached, and as
368
     * such it's safe to use this even in performance critical code.
369
     * If you add to this array, remember to add to the string names
370
     * in GLContext.cpp.
371
     */
372
    enum GLExtensions {
373
        Extension_None = 0,
374
        AMD_compressed_ATC_texture,
375
        ANGLE_depth_texture,
376
        ANGLE_framebuffer_blit,
377
        ANGLE_framebuffer_multisample,
378
        ANGLE_instanced_arrays,
379
        ANGLE_texture_compression_dxt3,
380
        ANGLE_texture_compression_dxt5,
381
        ANGLE_timer_query,
382
        APPLE_client_storage,
383
        APPLE_fence,
384
        APPLE_framebuffer_multisample,
385
        APPLE_sync,
386
        APPLE_texture_range,
387
        APPLE_vertex_array_object,
388
        ARB_ES2_compatibility,
389
        ARB_ES3_compatibility,
390
        ARB_color_buffer_float,
391
        ARB_compatibility,
392
        ARB_copy_buffer,
393
        ARB_depth_texture,
394
        ARB_draw_buffers,
395
        ARB_draw_instanced,
396
        ARB_framebuffer_object,
397
        ARB_framebuffer_sRGB,
398
        ARB_geometry_shader4,
399
        ARB_half_float_pixel,
400
        ARB_instanced_arrays,
401
        ARB_internalformat_query,
402
        ARB_invalidate_subdata,
403
        ARB_map_buffer_range,
404
        ARB_occlusion_query2,
405
        ARB_pixel_buffer_object,
406
        ARB_robust_buffer_access_behavior,
407
        ARB_robustness,
408
        ARB_sampler_objects,
409
        ARB_seamless_cube_map,
410
        ARB_shader_texture_lod,
411
        ARB_sync,
412
        ARB_texture_compression,
413
        ARB_texture_float,
414
        ARB_texture_non_power_of_two,
415
        ARB_texture_rectangle,
416
        ARB_texture_rg,
417
        ARB_texture_storage,
418
        ARB_texture_swizzle,
419
        ARB_timer_query,
420
        ARB_transform_feedback2,
421
        ARB_uniform_buffer_object,
422
        ARB_vertex_array_object,
423
        EXT_bgra,
424
        EXT_blend_minmax,
425
        EXT_color_buffer_float,
426
        EXT_color_buffer_half_float,
427
        EXT_copy_texture,
428
        EXT_disjoint_timer_query,
429
        EXT_draw_buffers,
430
        EXT_draw_buffers2,
431
        EXT_draw_instanced,
432
        EXT_draw_range_elements,
433
        EXT_frag_depth,
434
        EXT_framebuffer_blit,
435
        EXT_framebuffer_multisample,
436
        EXT_framebuffer_object,
437
        EXT_framebuffer_sRGB,
438
        EXT_gpu_shader4,
439
        EXT_multisampled_render_to_texture,
440
        EXT_occlusion_query_boolean,
441
        EXT_packed_depth_stencil,
442
        EXT_read_format_bgra,
443
        EXT_robustness,
444
        EXT_sRGB,
445
        EXT_sRGB_write_control,
446
        EXT_shader_texture_lod,
447
        EXT_texture3D,
448
        EXT_texture_compression_dxt1,
449
        EXT_texture_compression_s3tc,
450
        EXT_texture_compression_s3tc_srgb,
451
        EXT_texture_filter_anisotropic,
452
        EXT_texture_format_BGRA8888,
453
        EXT_texture_sRGB,
454
        EXT_texture_storage,
455
        EXT_timer_query,
456
        EXT_transform_feedback,
457
        EXT_unpack_subimage,
458
        IMG_read_format,
459
        IMG_texture_compression_pvrtc,
460
        IMG_texture_npot,
461
        KHR_debug,
462
        KHR_robust_buffer_access_behavior,
463
        KHR_robustness,
464
        KHR_texture_compression_astc_hdr,
465
        KHR_texture_compression_astc_ldr,
466
        NV_draw_instanced,
467
        NV_fence,
468
        NV_framebuffer_blit,
469
        NV_geometry_program4,
470
        NV_half_float,
471
        NV_instanced_arrays,
472
        NV_primitive_restart,
473
        NV_texture_barrier,
474
        NV_transform_feedback,
475
        NV_transform_feedback2,
476
        OES_EGL_image,
477
        OES_EGL_image_external,
478
        OES_EGL_sync,
479
        OES_compressed_ETC1_RGB8_texture,
480
        OES_depth24,
481
        OES_depth32,
482
        OES_depth_texture,
483
        OES_element_index_uint,
484
        OES_framebuffer_object,
485
        OES_packed_depth_stencil,
486
        OES_rgb8_rgba8,
487
        OES_standard_derivatives,
488
        OES_stencil8,
489
        OES_texture_3D,
490
        OES_texture_float,
491
        OES_texture_float_linear,
492
        OES_texture_half_float,
493
        OES_texture_half_float_linear,
494
        OES_texture_npot,
495
        OES_vertex_array_object,
496
        Extensions_Max,
497
        Extensions_End
498
    };
499
500
0
    bool IsExtensionSupported(GLExtensions aKnownExtension) const {
501
0
        return mAvailableExtensions[aKnownExtension];
502
0
    }
503
504
protected:
505
    void MarkExtensionUnsupported(GLExtensions aKnownExtension) {
506
        mAvailableExtensions[aKnownExtension] = 0;
507
    }
508
509
    void MarkExtensionSupported(GLExtensions aKnownExtension) {
510
        mAvailableExtensions[aKnownExtension] = 1;
511
    }
512
513
    std::bitset<Extensions_Max> mAvailableExtensions;
514
515
// -----------------------------------------------------------------------------
516
// Feature queries
517
/*
518
 * This mecahnism introduces a new way to check if a OpenGL feature is
519
 * supported, regardless of whether it is supported by an extension or natively
520
 * by the context version/profile
521
 */
522
public:
523
0
    bool IsSupported(GLFeature feature) const {
524
0
        return mAvailableFeatures[size_t(feature)];
525
0
    }
526
527
    static const char* GetFeatureName(GLFeature feature);
528
529
private:
530
    std::bitset<size_t(GLFeature::EnumMax)> mAvailableFeatures;
531
532
    /**
533
     * Init features regarding OpenGL extension and context version and profile
534
     */
535
    void InitFeatures();
536
537
    /**
538
     * Mark the feature and associated extensions as unsupported
539
     */
540
    void MarkUnsupported(GLFeature feature);
541
542
    /**
543
     * Is this feature supported using the core (unsuffixed) symbols?
544
     */
545
    bool IsFeatureProvidedByCoreSymbols(GLFeature feature);
546
547
public:
548
// -----------------------------------------------------------------------------
549
// Error handling
550
    static const char* GLErrorToString(GLenum aError) {
551
        switch (aError) {
552
            case LOCAL_GL_INVALID_ENUM:
553
                return "GL_INVALID_ENUM";
554
            case LOCAL_GL_INVALID_VALUE:
555
                return "GL_INVALID_VALUE";
556
            case LOCAL_GL_INVALID_OPERATION:
557
                return "GL_INVALID_OPERATION";
558
            case LOCAL_GL_STACK_OVERFLOW:
559
                return "GL_STACK_OVERFLOW";
560
            case LOCAL_GL_STACK_UNDERFLOW:
561
                return "GL_STACK_UNDERFLOW";
562
            case LOCAL_GL_OUT_OF_MEMORY:
563
                return "GL_OUT_OF_MEMORY";
564
            case LOCAL_GL_TABLE_TOO_LARGE:
565
                return "GL_TABLE_TOO_LARGE";
566
            case LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION:
567
                return "GL_INVALID_FRAMEBUFFER_OPERATION";
568
            default:
569
                return "";
570
        }
571
    }
572
573
private:
574
    mutable GLenum mTopError = 0;
575
576
0
    GLenum RawGetError() const {
577
0
        return mSymbols.fGetError();
578
0
    }
579
580
0
    GLenum RawGetErrorAndClear() const {
581
0
        GLenum err = RawGetError();
582
0
583
0
        if (err)
584
0
            while (RawGetError()) {}
585
0
586
0
        return err;
587
0
    }
588
589
0
    GLenum FlushErrors() const {
590
0
        GLenum err = RawGetErrorAndClear();
591
0
        if (!mTopError)
592
0
            mTopError = err;
593
0
        return err;
594
0
    }
595
596
    ////////////////////////////////////
597
    // Use this safer option.
598
599
public:
600
    class LocalErrorScope;
601
602
private:
603
    std::stack<const LocalErrorScope*> mLocalErrorScopeStack;
604
605
public:
606
    class LocalErrorScope {
607
        GLContext& mGL;
608
        GLenum mOldTop;
609
        bool mHasBeenChecked;
610
611
    public:
612
        explicit LocalErrorScope(GLContext& gl)
613
            : mGL(gl)
614
            , mHasBeenChecked(false)
615
        {
616
            mGL.mLocalErrorScopeStack.push(this);
617
618
            mGL.FlushErrors();
619
620
            mOldTop = mGL.mTopError;
621
            mGL.mTopError = LOCAL_GL_NO_ERROR;
622
        }
623
624
        GLenum GetError() {
625
            MOZ_ASSERT(!mHasBeenChecked);
626
            mHasBeenChecked = true;
627
628
            const GLenum ret = mGL.fGetError();
629
630
            while (mGL.fGetError()) {}
631
632
            return ret;
633
        }
634
635
        ~LocalErrorScope() {
636
            MOZ_ASSERT(mHasBeenChecked);
637
638
            MOZ_ASSERT(mGL.fGetError() == LOCAL_GL_NO_ERROR);
639
640
            MOZ_ASSERT(mGL.mLocalErrorScopeStack.top() == this);
641
            mGL.mLocalErrorScopeStack.pop();
642
643
            mGL.mTopError = mOldTop;
644
        }
645
    };
646
647
    bool GetPotentialInteger(GLenum pname, GLint* param) {
648
        LocalErrorScope localError(*this);
649
650
        fGetIntegerv(pname, param);
651
652
        GLenum err = localError.GetError();
653
        MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_INVALID_ENUM);
654
        return err == LOCAL_GL_NO_ERROR;
655
    }
656
657
private:
658
    static void GLAPIENTRY StaticDebugCallback(GLenum source,
659
                                               GLenum type,
660
                                               GLuint id,
661
                                               GLenum severity,
662
                                               GLsizei length,
663
                                               const GLchar* message,
664
                                               const GLvoid* userParam);
665
    void DebugCallback(GLenum source,
666
                       GLenum type,
667
                       GLuint id,
668
                       GLenum severity,
669
                       GLsizei length,
670
                       const GLchar* message);
671
672
673
// -----------------------------------------------------------------------------
674
// MOZ_GL_DEBUG implementation
675
private:
676
677
#ifndef MOZ_FUNCTION_NAME
678
# ifdef __GNUC__
679
0
#  define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
680
# elif defined(_MSC_VER)
681
#  define MOZ_FUNCTION_NAME __FUNCTION__
682
# else
683
#  define MOZ_FUNCTION_NAME __func__  // defined in C99, supported in various C++ compilers. Just raw function name.
684
# endif
685
#endif
686
687
#ifdef MOZ_WIDGET_ANDROID
688
// Record the name of the GL call for better hang stacks on Android.
689
#define ANDROID_ONLY_PROFILER_LABEL AUTO_PROFILER_LABEL(__func__, GRAPHICS);
690
#else
691
#define ANDROID_ONLY_PROFILER_LABEL
692
#endif
693
694
#define BEFORE_GL_CALL \
695
0
        ANDROID_ONLY_PROFILER_LABEL \
696
0
        if (MOZ_LIKELY( BeforeGLCall(MOZ_FUNCTION_NAME) )) { \
697
0
            do { } while (0)
698
699
#define AFTER_GL_CALL \
700
0
            AfterGLCall(MOZ_FUNCTION_NAME); \
701
0
        } \
702
0
        do { } while (0)
703
704
    void BeforeGLCall_Debug(const char* funcName) const;
705
    void AfterGLCall_Debug(const char* funcName) const;
706
    static void OnImplicitMakeCurrentFailure(const char* funcName);
707
708
0
    bool BeforeGLCall(const char* const funcName) const {
709
0
        if (mImplicitMakeCurrent) {
710
0
            if (MOZ_UNLIKELY( !MakeCurrent() )) {
711
0
                OnImplicitMakeCurrentFailure(funcName);
712
0
                return false;
713
0
            }
714
0
        }
715
0
        MOZ_ASSERT(IsCurrentImpl());
716
0
717
0
        if (mDebugFlags) {
718
0
            BeforeGLCall_Debug(funcName);
719
0
        }
720
0
        return true;
721
0
    }
722
723
0
    void AfterGLCall(const char* const funcName) const {
724
0
        if (mDebugFlags) {
725
0
            AfterGLCall_Debug(funcName);
726
0
        }
727
0
    }
728
729
    GLContext* TrackingContext()
730
0
    {
731
0
        GLContext* tip = this;
732
0
        while (tip->mSharedContext)
733
0
            tip = tip->mSharedContext;
734
0
        return tip;
735
0
    }
736
737
    static void AssertNotPassingStackBufferToTheGL(const void* ptr);
738
739
#ifdef MOZ_GL_DEBUG
740
741
#define TRACKING_CONTEXT(a)                         \
742
            do {                                    \
743
                TrackingContext()->a;               \
744
            } while (0)
745
746
#define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) AssertNotPassingStackBufferToTheGL(ptr)
747
748
#define ASSERT_SYMBOL_PRESENT(func) \
749
            do {\
750
                MOZ_ASSERT(strstr(MOZ_FUNCTION_NAME, #func) != nullptr, "Mismatched symbol check.");\
751
                if (MOZ_UNLIKELY(!mSymbols.func)) {\
752
                    printf_stderr("RUNTIME ASSERT: Uninitialized GL function: %s\n", #func);\
753
                    MOZ_CRASH("GFX: Uninitialized GL function");\
754
                }\
755
            } while (0)
756
757
#else // ifdef MOZ_GL_DEBUG
758
759
0
#define TRACKING_CONTEXT(a) do {} while (0)
760
0
#define ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(ptr) do {} while (0)
761
0
#define ASSERT_SYMBOL_PRESENT(func) do {} while (0)
762
763
#endif // ifdef MOZ_GL_DEBUG
764
765
766
    // Do whatever setup is necessary to draw to our offscreen FBO, if it's
767
    // bound.
768
0
    void BeforeGLDrawCall() { }
769
770
    // Do whatever tear-down is necessary after drawing to our offscreen FBO,
771
    // if it's bound.
772
    void AfterGLDrawCall();
773
774
    // Do whatever setup is necessary to read from our offscreen FBO, if it's
775
    // bound.
776
    void BeforeGLReadCall();
777
778
    // Do whatever tear-down is necessary after reading from our offscreen FBO,
779
    // if it's bound.
780
0
    void AfterGLReadCall() { }
781
782
public:
783
0
    void OnSyncCall() const {
784
0
        mSyncGLCallCount++;
785
0
    }
786
787
0
    uint64_t GetSyncCallCount() const {
788
0
        return mSyncGLCallCount;
789
0
    }
790
791
    void ResetSyncCallCount(const char* resetReason) const;
792
793
// -----------------------------------------------------------------------------
794
// GL official entry points
795
public:
796
    // We smash all errors together, so you never have to loop on this. We
797
    // guarantee that immediately after this call, there are no errors left.
798
0
    GLenum fGetError() {
799
0
        GLenum err = LOCAL_GL_CONTEXT_LOST;
800
0
        BEFORE_GL_CALL;
801
0
802
0
        FlushErrors();
803
0
        err = mTopError;
804
0
        mTopError = LOCAL_GL_NO_ERROR;
805
0
806
0
        AFTER_GL_CALL;
807
0
        return err;
808
0
    }
809
810
0
    void fActiveTexture(GLenum texture) {
811
0
        BEFORE_GL_CALL;
812
0
        mSymbols.fActiveTexture(texture);
813
0
        AFTER_GL_CALL;
814
0
    }
815
816
0
    void fAttachShader(GLuint program, GLuint shader) {
817
0
        BEFORE_GL_CALL;
818
0
        mSymbols.fAttachShader(program, shader);
819
0
        AFTER_GL_CALL;
820
0
    }
821
822
0
    void fBeginQuery(GLenum target, GLuint id) {
823
0
        BEFORE_GL_CALL;
824
0
        ASSERT_SYMBOL_PRESENT(fBeginQuery);
825
0
        mSymbols.fBeginQuery(target, id);
826
0
        AFTER_GL_CALL;
827
0
    }
828
829
0
    void fBindAttribLocation(GLuint program, GLuint index, const GLchar* name) {
830
0
        BEFORE_GL_CALL;
831
0
        mSymbols.fBindAttribLocation(program, index, name);
832
0
        AFTER_GL_CALL;
833
0
    }
834
835
0
    void fBindBuffer(GLenum target, GLuint buffer) {
836
0
        BEFORE_GL_CALL;
837
0
        mSymbols.fBindBuffer(target, buffer);
838
0
        AFTER_GL_CALL;
839
0
    }
840
841
    void fBindFramebuffer(GLenum target, GLuint framebuffer);
842
843
0
    void fInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) {
844
0
        BeforeGLDrawCall();
845
0
        BEFORE_GL_CALL;
846
0
        ASSERT_SYMBOL_PRESENT(fInvalidateFramebuffer);
847
0
        mSymbols.fInvalidateFramebuffer(target, numAttachments, attachments);
848
0
        AFTER_GL_CALL;
849
0
        AfterGLDrawCall();
850
0
    }
851
852
0
    void fInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) {
853
0
        BeforeGLDrawCall();
854
0
        BEFORE_GL_CALL;
855
0
        ASSERT_SYMBOL_PRESENT(fInvalidateSubFramebuffer);
856
0
        mSymbols.fInvalidateSubFramebuffer(target, numAttachments, attachments, x, y, width, height);
857
0
        AFTER_GL_CALL;
858
0
        AfterGLDrawCall();
859
0
    }
860
861
0
    void fBindTexture(GLenum target, GLuint texture) {
862
0
        BEFORE_GL_CALL;
863
0
        mSymbols.fBindTexture(target, texture);
864
0
        AFTER_GL_CALL;
865
0
    }
866
867
0
    void fBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
868
0
        BEFORE_GL_CALL;
869
0
        mSymbols.fBlendColor(red, green, blue, alpha);
870
0
        AFTER_GL_CALL;
871
0
    }
872
873
0
    void fBlendEquation(GLenum mode) {
874
0
        BEFORE_GL_CALL;
875
0
        mSymbols.fBlendEquation(mode);
876
0
        AFTER_GL_CALL;
877
0
    }
878
879
0
    void fBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
880
0
        BEFORE_GL_CALL;
881
0
        mSymbols.fBlendEquationSeparate(modeRGB, modeAlpha);
882
0
        AFTER_GL_CALL;
883
0
    }
884
885
0
    void fBlendFunc(GLenum sfactor, GLenum dfactor) {
886
0
        BEFORE_GL_CALL;
887
0
        mSymbols.fBlendFunc(sfactor, dfactor);
888
0
        AFTER_GL_CALL;
889
0
    }
890
891
    void fBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {
892
        BEFORE_GL_CALL;
893
        mSymbols.fBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
894
        AFTER_GL_CALL;
895
    }
896
897
private:
898
0
    void raw_fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
899
0
        ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data);
900
0
        BEFORE_GL_CALL;
901
0
        mSymbols.fBufferData(target, size, data, usage);
902
0
        OnSyncCall();
903
0
        AFTER_GL_CALL;
904
0
        mHeavyGLCallsSinceLastFlush = true;
905
0
    }
906
907
public:
908
0
    void fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
909
0
        raw_fBufferData(target, size, data, usage);
910
0
911
0
        // bug 744888
912
0
        if (WorkAroundDriverBugs() &&
913
0
            !data &&
914
0
            Vendor() == GLVendor::NVIDIA)
915
0
        {
916
0
            UniquePtr<char[]> buf = MakeUnique<char[]>(1);
917
0
            buf[0] = 0;
918
0
            fBufferSubData(target, size-1, 1, buf.get());
919
0
        }
920
0
    }
921
922
0
    void fBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) {
923
0
        ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(data);
924
0
        BEFORE_GL_CALL;
925
0
        mSymbols.fBufferSubData(target, offset, size, data);
926
0
        AFTER_GL_CALL;
927
0
        mHeavyGLCallsSinceLastFlush = true;
928
0
    }
929
930
private:
931
0
    void raw_fClear(GLbitfield mask) {
932
0
        BEFORE_GL_CALL;
933
0
        mSymbols.fClear(mask);
934
0
        AFTER_GL_CALL;
935
0
    }
936
937
public:
938
0
    void fClear(GLbitfield mask) {
939
0
        BeforeGLDrawCall();
940
0
        raw_fClear(mask);
941
0
        AfterGLDrawCall();
942
0
    }
943
944
0
    void fClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) {
945
0
        BeforeGLDrawCall();
946
0
        BEFORE_GL_CALL;
947
0
        mSymbols.fClearBufferfi(buffer, drawbuffer, depth, stencil);
948
0
        AFTER_GL_CALL;
949
0
        AfterGLDrawCall();
950
0
    }
951
952
0
    void fClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) {
953
0
        BeforeGLDrawCall();
954
0
        BEFORE_GL_CALL;
955
0
        mSymbols.fClearBufferfv(buffer, drawbuffer, value);
956
0
        AFTER_GL_CALL;
957
0
        AfterGLDrawCall();
958
0
    }
959
960
0
    void fClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) {
961
0
        BeforeGLDrawCall();
962
0
        BEFORE_GL_CALL;
963
0
        mSymbols.fClearBufferiv(buffer, drawbuffer, value);
964
0
        AFTER_GL_CALL;
965
0
        AfterGLDrawCall();
966
0
    }
967
968
0
    void fClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) {
969
0
        BeforeGLDrawCall();
970
0
        BEFORE_GL_CALL;
971
0
        mSymbols.fClearBufferuiv(buffer, drawbuffer, value);
972
0
        AFTER_GL_CALL;
973
0
        AfterGLDrawCall();
974
0
    }
975
976
0
    void fClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
977
0
        BEFORE_GL_CALL;
978
0
        mSymbols.fClearColor(r, g, b, a);
979
0
        AFTER_GL_CALL;
980
0
    }
981
982
0
    void fClearStencil(GLint s) {
983
0
        BEFORE_GL_CALL;
984
0
        mSymbols.fClearStencil(s);
985
0
        AFTER_GL_CALL;
986
0
    }
987
988
0
    void fClientActiveTexture(GLenum texture) {
989
0
        BEFORE_GL_CALL;
990
0
        mSymbols.fClientActiveTexture(texture);
991
0
        AFTER_GL_CALL;
992
0
    }
993
994
0
    void fColorMask(realGLboolean red, realGLboolean green, realGLboolean blue, realGLboolean alpha) {
995
0
        BEFORE_GL_CALL;
996
0
        mSymbols.fColorMask(red, green, blue, alpha);
997
0
        AFTER_GL_CALL;
998
0
    }
999
1000
0
    void fCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* pixels) {
1001
0
        ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
1002
0
        BEFORE_GL_CALL;
1003
0
        mSymbols.fCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, pixels);
1004
0
        AFTER_GL_CALL;
1005
0
        mHeavyGLCallsSinceLastFlush = true;
1006
0
    }
1007
1008
0
    void fCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* pixels) {
1009
0
        ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
1010
0
        BEFORE_GL_CALL;
1011
0
        mSymbols.fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, pixels);
1012
0
        AFTER_GL_CALL;
1013
0
        mHeavyGLCallsSinceLastFlush = true;
1014
0
    }
1015
1016
    void fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
1017
                         GLint y, GLsizei width, GLsizei height, GLint border);
1018
1019
0
    void fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
1020
0
        BeforeGLReadCall();
1021
0
        raw_fCopyTexSubImage2D(target, level, xoffset, yoffset,
1022
0
                               x, y, width, height);
1023
0
        AfterGLReadCall();
1024
0
    }
1025
1026
0
    void fCullFace(GLenum mode) {
1027
0
        BEFORE_GL_CALL;
1028
0
        mSymbols.fCullFace(mode);
1029
0
        AFTER_GL_CALL;
1030
0
    }
1031
1032
    void fDebugMessageCallback(GLDEBUGPROC callback, const GLvoid* userParam) {
1033
        BEFORE_GL_CALL;
1034
        ASSERT_SYMBOL_PRESENT(fDebugMessageCallback);
1035
        mSymbols.fDebugMessageCallback(callback, userParam);
1036
        AFTER_GL_CALL;
1037
    }
1038
1039
    void fDebugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, realGLboolean enabled) {
1040
        BEFORE_GL_CALL;
1041
        ASSERT_SYMBOL_PRESENT(fDebugMessageControl);
1042
        mSymbols.fDebugMessageControl(source, type, severity, count, ids, enabled);
1043
        AFTER_GL_CALL;
1044
    }
1045
1046
0
    void fDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf) {
1047
0
        BEFORE_GL_CALL;
1048
0
        ASSERT_SYMBOL_PRESENT(fDebugMessageInsert);
1049
0
        mSymbols.fDebugMessageInsert(source, type, id, severity, length, buf);
1050
0
        AFTER_GL_CALL;
1051
0
    }
1052
1053
0
    void fDetachShader(GLuint program, GLuint shader) {
1054
0
        BEFORE_GL_CALL;
1055
0
        mSymbols.fDetachShader(program, shader);
1056
0
        AFTER_GL_CALL;
1057
0
    }
1058
1059
0
    void fDepthFunc(GLenum func) {
1060
0
        BEFORE_GL_CALL;
1061
0
        mSymbols.fDepthFunc(func);
1062
0
        AFTER_GL_CALL;
1063
0
    }
1064
1065
0
    void fDepthMask(realGLboolean flag) {
1066
0
        BEFORE_GL_CALL;
1067
0
        mSymbols.fDepthMask(flag);
1068
0
        AFTER_GL_CALL;
1069
0
    }
1070
1071
0
    void fDisable(GLenum capability) {
1072
0
        BEFORE_GL_CALL;
1073
0
        mSymbols.fDisable(capability);
1074
0
        AFTER_GL_CALL;
1075
0
    }
1076
1077
0
    void fDisableClientState(GLenum capability) {
1078
0
        BEFORE_GL_CALL;
1079
0
        mSymbols.fDisableClientState(capability);
1080
0
        AFTER_GL_CALL;
1081
0
    }
1082
1083
0
    void fDisableVertexAttribArray(GLuint index) {
1084
0
        BEFORE_GL_CALL;
1085
0
        mSymbols.fDisableVertexAttribArray(index);
1086
0
        AFTER_GL_CALL;
1087
0
    }
1088
1089
0
    void fDrawBuffer(GLenum mode) {
1090
0
        BEFORE_GL_CALL;
1091
0
        mSymbols.fDrawBuffer(mode);
1092
0
        AFTER_GL_CALL;
1093
0
    }
1094
1095
private:
1096
0
    void raw_fDrawArrays(GLenum mode, GLint first, GLsizei count) {
1097
0
        BEFORE_GL_CALL;
1098
0
        mSymbols.fDrawArrays(mode, first, count);
1099
0
        AFTER_GL_CALL;
1100
0
    }
1101
1102
0
    void raw_fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
1103
0
        BEFORE_GL_CALL;
1104
0
        mSymbols.fDrawElements(mode, count, type, indices);
1105
0
        AFTER_GL_CALL;
1106
0
    }
1107
1108
public:
1109
0
    void fDrawArrays(GLenum mode, GLint first, GLsizei count) {
1110
0
        BeforeGLDrawCall();
1111
0
        raw_fDrawArrays(mode, first, count);
1112
0
        AfterGLDrawCall();
1113
0
    }
1114
1115
0
    void fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
1116
0
        BeforeGLDrawCall();
1117
0
        raw_fDrawElements(mode, count, type, indices);
1118
0
        AfterGLDrawCall();
1119
0
    }
1120
1121
0
    void fEnable(GLenum capability) {
1122
0
        BEFORE_GL_CALL;
1123
0
        mSymbols.fEnable(capability);
1124
0
        AFTER_GL_CALL;
1125
0
    }
1126
1127
0
    void fEnableClientState(GLenum capability) {
1128
0
        BEFORE_GL_CALL;
1129
0
        mSymbols.fEnableClientState(capability);
1130
0
        AFTER_GL_CALL;
1131
0
    }
1132
1133
0
    void fEnableVertexAttribArray(GLuint index) {
1134
0
        BEFORE_GL_CALL;
1135
0
        mSymbols.fEnableVertexAttribArray(index);
1136
0
        AFTER_GL_CALL;
1137
0
    }
1138
1139
0
    void fEndQuery(GLenum target) {
1140
0
        BEFORE_GL_CALL;
1141
0
        ASSERT_SYMBOL_PRESENT(fEndQuery);
1142
0
        mSymbols.fEndQuery(target);
1143
0
        AFTER_GL_CALL;
1144
0
    }
1145
1146
0
    void fFinish() {
1147
0
        BEFORE_GL_CALL;
1148
0
        mSymbols.fFinish();
1149
0
        OnSyncCall();
1150
0
        AFTER_GL_CALL;
1151
0
        mHeavyGLCallsSinceLastFlush = false;
1152
0
    }
1153
1154
0
    void fFlush() {
1155
0
        BEFORE_GL_CALL;
1156
0
        mSymbols.fFlush();
1157
0
        AFTER_GL_CALL;
1158
0
        mHeavyGLCallsSinceLastFlush = false;
1159
0
    }
1160
1161
0
    void fFrontFace(GLenum face) {
1162
0
        BEFORE_GL_CALL;
1163
0
        mSymbols.fFrontFace(face);
1164
0
        AFTER_GL_CALL;
1165
0
    }
1166
1167
0
    void fGetActiveAttrib(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
1168
0
        BEFORE_GL_CALL;
1169
0
        mSymbols.fGetActiveAttrib(program, index, maxLength, length, size, type, name);
1170
0
        OnSyncCall();
1171
0
        AFTER_GL_CALL;
1172
0
    }
1173
1174
    void fGetActiveUniform(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
1175
        BEFORE_GL_CALL;
1176
        mSymbols.fGetActiveUniform(program, index, maxLength, length, size, type, name);
1177
        OnSyncCall();
1178
        AFTER_GL_CALL;
1179
    }
1180
1181
0
    void fGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
1182
0
        BEFORE_GL_CALL;
1183
0
        mSymbols.fGetAttachedShaders(program, maxCount, count, shaders);
1184
0
        OnSyncCall();
1185
0
        AFTER_GL_CALL;
1186
0
    }
1187
1188
0
    GLint fGetAttribLocation(GLuint program, const GLchar* name) {
1189
0
        GLint retval = 0;
1190
0
        BEFORE_GL_CALL;
1191
0
        retval = mSymbols.fGetAttribLocation(program, name);
1192
0
        OnSyncCall();
1193
0
        AFTER_GL_CALL;
1194
0
        return retval;
1195
0
    }
1196
1197
private:
1198
    void raw_fGetIntegerv(GLenum pname, GLint* params) {
1199
        BEFORE_GL_CALL;
1200
        mSymbols.fGetIntegerv(pname, params);
1201
        OnSyncCall();
1202
        AFTER_GL_CALL;
1203
    }
1204
1205
public:
1206
1207
    void fGetIntegerv(GLenum pname, GLint* params);
1208
1209
    void GetUIntegerv(GLenum pname, GLuint* params) {
1210
        fGetIntegerv(pname, reinterpret_cast<GLint*>(params));
1211
    }
1212
1213
    template<typename T>
1214
    T GetIntAs(GLenum pname) {
1215
        static_assert(sizeof(T) == sizeof(GLint), "Invalid T.");
1216
        T ret = 0;
1217
        fGetIntegerv(pname, (GLint*)&ret);
1218
        return ret;
1219
    }
1220
1221
0
    void fGetFloatv(GLenum pname, GLfloat* params) {
1222
0
        BEFORE_GL_CALL;
1223
0
        mSymbols.fGetFloatv(pname, params);
1224
0
        OnSyncCall();
1225
0
        AFTER_GL_CALL;
1226
0
    }
1227
1228
    void fGetBooleanv(GLenum pname, realGLboolean* params) {
1229
        BEFORE_GL_CALL;
1230
        mSymbols.fGetBooleanv(pname, params);
1231
        OnSyncCall();
1232
        AFTER_GL_CALL;
1233
    }
1234
1235
0
    void fGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
1236
0
        BEFORE_GL_CALL;
1237
0
        mSymbols.fGetBufferParameteriv(target, pname, params);
1238
0
        OnSyncCall();
1239
0
        AFTER_GL_CALL;
1240
0
    }
1241
1242
0
    GLuint fGetDebugMessageLog(GLuint count, GLsizei bufsize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog) {
1243
0
        GLuint ret = 0;
1244
0
        BEFORE_GL_CALL;
1245
0
        ASSERT_SYMBOL_PRESENT(fGetDebugMessageLog);
1246
0
        ret = mSymbols.fGetDebugMessageLog(count, bufsize, sources, types, ids, severities, lengths, messageLog);
1247
0
        OnSyncCall();
1248
0
        AFTER_GL_CALL;
1249
0
        return ret;
1250
0
    }
1251
1252
0
    void fGetPointerv(GLenum pname, GLvoid** params) {
1253
0
        BEFORE_GL_CALL;
1254
0
        ASSERT_SYMBOL_PRESENT(fGetPointerv);
1255
0
        mSymbols.fGetPointerv(pname, params);
1256
0
        OnSyncCall();
1257
0
        AFTER_GL_CALL;
1258
0
    }
1259
1260
0
    void fGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label) {
1261
0
        BEFORE_GL_CALL;
1262
0
        ASSERT_SYMBOL_PRESENT(fGetObjectLabel);
1263
0
        mSymbols.fGetObjectLabel(identifier, name, bufSize, length, label);
1264
0
        OnSyncCall();
1265
0
        AFTER_GL_CALL;
1266
0
    }
1267
1268
0
    void fGetObjectPtrLabel(const GLvoid* ptr, GLsizei bufSize, GLsizei* length, GLchar* label) {
1269
0
        BEFORE_GL_CALL;
1270
0
        ASSERT_SYMBOL_PRESENT(fGetObjectPtrLabel);
1271
0
        mSymbols.fGetObjectPtrLabel(ptr, bufSize, length, label);
1272
0
        OnSyncCall();
1273
0
        AFTER_GL_CALL;
1274
0
    }
1275
1276
0
    void fGenerateMipmap(GLenum target) {
1277
0
        BEFORE_GL_CALL;
1278
0
        mSymbols.fGenerateMipmap(target);
1279
0
        AFTER_GL_CALL;
1280
0
    }
1281
1282
0
    void fGetProgramiv(GLuint program, GLenum pname, GLint* param) {
1283
0
        BEFORE_GL_CALL;
1284
0
        mSymbols.fGetProgramiv(program, pname, param);
1285
0
        OnSyncCall();
1286
0
        AFTER_GL_CALL;
1287
0
    }
1288
1289
0
    void fGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
1290
0
        BEFORE_GL_CALL;
1291
0
        mSymbols.fGetProgramInfoLog(program, bufSize, length, infoLog);
1292
0
        OnSyncCall();
1293
0
        AFTER_GL_CALL;
1294
0
    }
1295
1296
0
    void fTexParameteri(GLenum target, GLenum pname, GLint param) {
1297
0
        BEFORE_GL_CALL;
1298
0
        mSymbols.fTexParameteri(target, pname, param);
1299
0
        AFTER_GL_CALL;
1300
0
    }
1301
1302
0
    void fTexParameteriv(GLenum target, GLenum pname, const GLint* params) {
1303
0
        BEFORE_GL_CALL;
1304
0
        mSymbols.fTexParameteriv(target, pname, params);
1305
0
        AFTER_GL_CALL;
1306
0
    }
1307
1308
0
    void fTexParameterf(GLenum target, GLenum pname, GLfloat param) {
1309
0
        BEFORE_GL_CALL;
1310
0
        mSymbols.fTexParameterf(target, pname, param);
1311
0
        AFTER_GL_CALL;
1312
0
    }
1313
1314
0
    const GLubyte* fGetString(GLenum name) {
1315
0
        const GLubyte* result = nullptr;
1316
0
        BEFORE_GL_CALL;
1317
0
        result = mSymbols.fGetString(name);
1318
0
        OnSyncCall();
1319
0
        AFTER_GL_CALL;
1320
0
        return result;
1321
0
    }
1322
1323
    void fGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* img) {
1324
        BEFORE_GL_CALL;
1325
        ASSERT_SYMBOL_PRESENT(fGetTexImage);
1326
        mSymbols.fGetTexImage(target, level, format, type, img);
1327
        OnSyncCall();
1328
        AFTER_GL_CALL;
1329
    }
1330
1331
    void fGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint* params)
1332
0
    {
1333
0
        BEFORE_GL_CALL;
1334
0
        ASSERT_SYMBOL_PRESENT(fGetTexLevelParameteriv);
1335
0
        mSymbols.fGetTexLevelParameteriv(target, level, pname, params);
1336
0
        OnSyncCall();
1337
0
        AFTER_GL_CALL;
1338
0
    }
1339
1340
0
    void fGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) {
1341
0
        BEFORE_GL_CALL;
1342
0
        mSymbols.fGetTexParameterfv(target, pname, params);
1343
0
        OnSyncCall();
1344
0
        AFTER_GL_CALL;
1345
0
    }
1346
1347
0
    void fGetTexParameteriv(GLenum target, GLenum pname, GLint* params) {
1348
0
        BEFORE_GL_CALL;
1349
0
        mSymbols.fGetTexParameteriv(target, pname, params);
1350
0
        OnSyncCall();
1351
0
        AFTER_GL_CALL;
1352
0
    }
1353
1354
0
    void fGetUniformfv(GLuint program, GLint location, GLfloat* params) {
1355
0
        BEFORE_GL_CALL;
1356
0
        mSymbols.fGetUniformfv(program, location, params);
1357
0
        OnSyncCall();
1358
0
        AFTER_GL_CALL;
1359
0
    }
1360
1361
0
    void fGetUniformiv(GLuint program, GLint location, GLint* params) {
1362
0
        BEFORE_GL_CALL;
1363
0
        mSymbols.fGetUniformiv(program, location, params);
1364
0
        OnSyncCall();
1365
0
        AFTER_GL_CALL;
1366
0
    }
1367
1368
0
    void fGetUniformuiv(GLuint program, GLint location, GLuint* params) {
1369
0
        BEFORE_GL_CALL;
1370
0
        ASSERT_SYMBOL_PRESENT(fGetUniformuiv);
1371
0
        mSymbols.fGetUniformuiv(program, location, params);
1372
0
        OnSyncCall();
1373
0
        AFTER_GL_CALL;
1374
0
    }
1375
1376
0
    GLint fGetUniformLocation (GLuint programObj, const GLchar* name) {
1377
0
        GLint retval = 0;
1378
0
        BEFORE_GL_CALL;
1379
0
        retval = mSymbols.fGetUniformLocation(programObj, name);
1380
0
        OnSyncCall();
1381
0
        AFTER_GL_CALL;
1382
0
        return retval;
1383
0
    }
1384
1385
0
    void fGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* retval) {
1386
0
        BEFORE_GL_CALL;
1387
0
        mSymbols.fGetVertexAttribfv(index, pname, retval);
1388
0
        OnSyncCall();
1389
0
        AFTER_GL_CALL;
1390
0
    }
1391
1392
    void fGetVertexAttribiv(GLuint index, GLenum pname, GLint* retval) {
1393
        BEFORE_GL_CALL;
1394
        mSymbols.fGetVertexAttribiv(index, pname, retval);
1395
        OnSyncCall();
1396
        AFTER_GL_CALL;
1397
    }
1398
1399
    void fGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** retval) {
1400
        BEFORE_GL_CALL;
1401
        mSymbols.fGetVertexAttribPointerv(index, pname, retval);
1402
        OnSyncCall();
1403
        AFTER_GL_CALL;
1404
    }
1405
1406
0
    void fHint(GLenum target, GLenum mode) {
1407
0
        BEFORE_GL_CALL;
1408
0
        mSymbols.fHint(target, mode);
1409
0
        AFTER_GL_CALL;
1410
0
    }
1411
1412
0
    realGLboolean fIsBuffer(GLuint buffer) {
1413
0
        realGLboolean retval = false;
1414
0
        BEFORE_GL_CALL;
1415
0
        retval = mSymbols.fIsBuffer(buffer);
1416
0
        OnSyncCall();
1417
0
        AFTER_GL_CALL;
1418
0
        return retval;
1419
0
    }
1420
1421
    realGLboolean fIsEnabled(GLenum capability) {
1422
        realGLboolean retval = false;
1423
        BEFORE_GL_CALL;
1424
        retval = mSymbols.fIsEnabled(capability);
1425
        AFTER_GL_CALL;
1426
        return retval;
1427
    }
1428
1429
    void SetEnabled(const GLenum cap, const bool val) {
1430
        if (val) {
1431
            fEnable(cap);
1432
        } else {
1433
            fDisable(cap);
1434
        }
1435
    }
1436
1437
    bool PushEnabled(const GLenum cap, const bool newVal) {
1438
        const bool oldVal = fIsEnabled(cap);
1439
        if (oldVal != newVal) {
1440
            SetEnabled(cap, newVal);
1441
        }
1442
        return oldVal;
1443
    }
1444
1445
0
    realGLboolean fIsProgram(GLuint program) {
1446
0
        realGLboolean retval = false;
1447
0
        BEFORE_GL_CALL;
1448
0
        retval = mSymbols.fIsProgram(program);
1449
0
        AFTER_GL_CALL;
1450
0
        return retval;
1451
0
    }
1452
1453
0
    realGLboolean fIsShader(GLuint shader) {
1454
0
        realGLboolean retval = false;
1455
0
        BEFORE_GL_CALL;
1456
0
        retval = mSymbols.fIsShader(shader);
1457
0
        AFTER_GL_CALL;
1458
0
        return retval;
1459
0
    }
1460
1461
0
    realGLboolean fIsTexture(GLuint texture) {
1462
0
        realGLboolean retval = false;
1463
0
        BEFORE_GL_CALL;
1464
0
        retval = mSymbols.fIsTexture(texture);
1465
0
        AFTER_GL_CALL;
1466
0
        return retval;
1467
0
    }
1468
1469
0
    void fLineWidth(GLfloat width) {
1470
0
        BEFORE_GL_CALL;
1471
0
        mSymbols.fLineWidth(width);
1472
0
        AFTER_GL_CALL;
1473
0
    }
1474
1475
0
    void fLinkProgram(GLuint program) {
1476
0
        BEFORE_GL_CALL;
1477
0
        mSymbols.fLinkProgram(program);
1478
0
        AFTER_GL_CALL;
1479
0
    }
1480
1481
0
    void fObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar* label) {
1482
0
        BEFORE_GL_CALL;
1483
0
        ASSERT_SYMBOL_PRESENT(fObjectLabel);
1484
0
        mSymbols.fObjectLabel(identifier, name, length, label);
1485
0
        AFTER_GL_CALL;
1486
0
    }
1487
1488
0
    void fObjectPtrLabel(const GLvoid* ptr, GLsizei length, const GLchar* label) {
1489
0
        BEFORE_GL_CALL;
1490
0
        ASSERT_SYMBOL_PRESENT(fObjectPtrLabel);
1491
0
        mSymbols.fObjectPtrLabel(ptr, length, label);
1492
0
        AFTER_GL_CALL;
1493
0
    }
1494
1495
0
    void fLoadIdentity() {
1496
0
        BEFORE_GL_CALL;
1497
0
        mSymbols.fLoadIdentity();
1498
0
        AFTER_GL_CALL;
1499
0
    }
1500
1501
0
    void fLoadMatrixf(const GLfloat* matrix) {
1502
0
        BEFORE_GL_CALL;
1503
0
        mSymbols.fLoadMatrixf(matrix);
1504
0
        AFTER_GL_CALL;
1505
0
    }
1506
1507
0
    void fMatrixMode(GLenum mode) {
1508
0
        BEFORE_GL_CALL;
1509
0
        mSymbols.fMatrixMode(mode);
1510
0
        AFTER_GL_CALL;
1511
0
    }
1512
1513
0
    void fPixelStorei(GLenum pname, GLint param) {
1514
0
        BEFORE_GL_CALL;
1515
0
        mSymbols.fPixelStorei(pname, param);
1516
0
        AFTER_GL_CALL;
1517
0
    }
1518
1519
    void fTextureRangeAPPLE(GLenum target, GLsizei length, GLvoid* pointer) {
1520
        ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pointer);
1521
        BEFORE_GL_CALL;
1522
        mSymbols.fTextureRangeAPPLE(target, length, pointer);
1523
        AFTER_GL_CALL;
1524
    }
1525
1526
0
    void fPointParameterf(GLenum pname, GLfloat param) {
1527
0
        BEFORE_GL_CALL;
1528
0
        mSymbols.fPointParameterf(pname, param);
1529
0
        AFTER_GL_CALL;
1530
0
    }
1531
1532
0
    void fPolygonMode(GLenum face, GLenum mode) {
1533
0
        BEFORE_GL_CALL;
1534
0
        mSymbols.fPolygonMode(face, mode);
1535
0
        AFTER_GL_CALL;
1536
0
    }
1537
1538
0
    void fPolygonOffset(GLfloat factor, GLfloat bias) {
1539
0
        BEFORE_GL_CALL;
1540
0
        mSymbols.fPolygonOffset(factor, bias);
1541
0
        AFTER_GL_CALL;
1542
0
    }
1543
1544
0
    void fPopDebugGroup() {
1545
0
        BEFORE_GL_CALL;
1546
0
        ASSERT_SYMBOL_PRESENT(fPopDebugGroup);
1547
0
        mSymbols.fPopDebugGroup();
1548
0
        AFTER_GL_CALL;
1549
0
    }
1550
1551
0
    void fPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar* message) {
1552
0
        BEFORE_GL_CALL;
1553
0
        ASSERT_SYMBOL_PRESENT(fPushDebugGroup);
1554
0
        mSymbols.fPushDebugGroup(source, id, length, message);
1555
0
        AFTER_GL_CALL;
1556
0
    }
1557
1558
0
    void fReadBuffer(GLenum mode) {
1559
0
        BEFORE_GL_CALL;
1560
0
        mSymbols.fReadBuffer(mode);
1561
0
        AFTER_GL_CALL;
1562
0
    }
1563
1564
    void raw_fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
1565
        BEFORE_GL_CALL;
1566
        mSymbols.fReadPixels(x, y, width, height, format, type, pixels);
1567
        OnSyncCall();
1568
        AFTER_GL_CALL;
1569
        mHeavyGLCallsSinceLastFlush = true;
1570
    }
1571
1572
    void fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
1573
                     GLenum type, GLvoid* pixels);
1574
1575
public:
1576
0
    void fSampleCoverage(GLclampf value, realGLboolean invert) {
1577
0
        BEFORE_GL_CALL;
1578
0
        mSymbols.fSampleCoverage(value, invert);
1579
0
        AFTER_GL_CALL;
1580
0
    }
1581
1582
0
    void fScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
1583
0
        if (mScissorRect[0] == x &&
1584
0
            mScissorRect[1] == y &&
1585
0
            mScissorRect[2] == width &&
1586
0
            mScissorRect[3] == height)
1587
0
        {
1588
0
            return;
1589
0
        }
1590
0
        mScissorRect[0] = x;
1591
0
        mScissorRect[1] = y;
1592
0
        mScissorRect[2] = width;
1593
0
        mScissorRect[3] = height;
1594
0
        BEFORE_GL_CALL;
1595
0
        mSymbols.fScissor(x, y, width, height);
1596
0
        AFTER_GL_CALL;
1597
0
    }
1598
1599
0
    void fStencilFunc(GLenum func, GLint reference, GLuint mask) {
1600
0
        BEFORE_GL_CALL;
1601
0
        mSymbols.fStencilFunc(func, reference, mask);
1602
0
        AFTER_GL_CALL;
1603
0
    }
1604
1605
0
    void fStencilFuncSeparate(GLenum frontfunc, GLenum backfunc, GLint reference, GLuint mask) {
1606
0
        BEFORE_GL_CALL;
1607
0
        mSymbols.fStencilFuncSeparate(frontfunc, backfunc, reference, mask);
1608
0
        AFTER_GL_CALL;
1609
0
    }
1610
1611
0
    void fStencilMask(GLuint mask) {
1612
0
        BEFORE_GL_CALL;
1613
0
        mSymbols.fStencilMask(mask);
1614
0
        AFTER_GL_CALL;
1615
0
    }
1616
1617
0
    void fStencilMaskSeparate(GLenum face, GLuint mask) {
1618
0
        BEFORE_GL_CALL;
1619
0
        mSymbols.fStencilMaskSeparate(face, mask);
1620
0
        AFTER_GL_CALL;
1621
0
    }
1622
1623
0
    void fStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
1624
0
        BEFORE_GL_CALL;
1625
0
        mSymbols.fStencilOp(fail, zfail, zpass);
1626
0
        AFTER_GL_CALL;
1627
0
    }
1628
1629
0
    void fStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {
1630
0
        BEFORE_GL_CALL;
1631
0
        mSymbols.fStencilOpSeparate(face, sfail, dpfail, dppass);
1632
0
        AFTER_GL_CALL;
1633
0
    }
1634
1635
0
    void fTexGeni(GLenum coord, GLenum pname, GLint param) {
1636
0
        BEFORE_GL_CALL;
1637
0
        mSymbols.fTexGeni(coord, pname, param);
1638
0
        AFTER_GL_CALL;
1639
0
    }
1640
1641
0
    void fTexGenf(GLenum coord, GLenum pname, GLfloat param) {
1642
0
        BEFORE_GL_CALL;
1643
0
        mSymbols.fTexGenf(coord, pname, param);
1644
0
        AFTER_GL_CALL;
1645
0
    }
1646
1647
0
    void fTexGenfv(GLenum coord, GLenum pname, const GLfloat* params) {
1648
0
        BEFORE_GL_CALL;
1649
0
        mSymbols.fTexGenfv(coord, pname, params);
1650
0
        AFTER_GL_CALL;
1651
0
    }
1652
1653
private:
1654
    void raw_fTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) {
1655
        ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
1656
        BEFORE_GL_CALL;
1657
        mSymbols.fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
1658
        AFTER_GL_CALL;
1659
        mHeavyGLCallsSinceLastFlush = true;
1660
    }
1661
1662
public:
1663
    void fTexImage2D(GLenum target, GLint level, GLint internalformat,
1664
                     GLsizei width, GLsizei height, GLint border,
1665
                     GLenum format, GLenum type, const GLvoid* pixels);
1666
1667
0
    void fTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) {
1668
0
        ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL(pixels);
1669
0
        BEFORE_GL_CALL;
1670
0
        mSymbols.fTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
1671
0
        AFTER_GL_CALL;
1672
0
        mHeavyGLCallsSinceLastFlush = true;
1673
0
    }
1674
1675
0
    void fUniform1f(GLint location, GLfloat v0) {
1676
0
        BEFORE_GL_CALL;
1677
0
        mSymbols.fUniform1f(location, v0);
1678
0
        AFTER_GL_CALL;
1679
0
    }
1680
1681
0
    void fUniform1fv(GLint location, GLsizei count, const GLfloat* value) {
1682
0
        BEFORE_GL_CALL;
1683
0
        mSymbols.fUniform1fv(location, count, value);
1684
0
        AFTER_GL_CALL;
1685
0
    }
1686
1687
0
    void fUniform1i(GLint location, GLint v0) {
1688
0
        BEFORE_GL_CALL;
1689
0
        mSymbols.fUniform1i(location, v0);
1690
0
        AFTER_GL_CALL;
1691
0
    }
1692
1693
0
    void fUniform1iv(GLint location, GLsizei count, const GLint* value) {
1694
0
        BEFORE_GL_CALL;
1695
0
        mSymbols.fUniform1iv(location, count, value);
1696
0
        AFTER_GL_CALL;
1697
0
    }
1698
1699
0
    void fUniform2f(GLint location, GLfloat v0, GLfloat v1) {
1700
0
        BEFORE_GL_CALL;
1701
0
        mSymbols.fUniform2f(location, v0, v1);
1702
0
        AFTER_GL_CALL;
1703
0
    }
1704
1705
0
    void fUniform2fv(GLint location, GLsizei count, const GLfloat* value) {
1706
0
        BEFORE_GL_CALL;
1707
0
        mSymbols.fUniform2fv(location, count, value);
1708
0
        AFTER_GL_CALL;
1709
0
    }
1710
1711
0
    void fUniform2i(GLint location, GLint v0, GLint v1) {
1712
0
        BEFORE_GL_CALL;
1713
0
        mSymbols.fUniform2i(location, v0, v1);
1714
0
        AFTER_GL_CALL;
1715
0
    }
1716
1717
0
    void fUniform2iv(GLint location, GLsizei count, const GLint* value) {
1718
0
        BEFORE_GL_CALL;
1719
0
        mSymbols.fUniform2iv(location, count, value);
1720
0
        AFTER_GL_CALL;
1721
0
    }
1722
1723
0
    void fUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
1724
0
        BEFORE_GL_CALL;
1725
0
        mSymbols.fUniform3f(location, v0, v1, v2);
1726
0
        AFTER_GL_CALL;
1727
0
    }
1728
1729
0
    void fUniform3fv(GLint location, GLsizei count, const GLfloat* value) {
1730
0
        BEFORE_GL_CALL;
1731
0
        mSymbols.fUniform3fv(location, count, value);
1732
0
        AFTER_GL_CALL;
1733
0
    }
1734
1735
0
    void fUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {
1736
0
        BEFORE_GL_CALL;
1737
0
        mSymbols.fUniform3i(location, v0, v1, v2);
1738
0
        AFTER_GL_CALL;
1739
0
    }
1740
1741
0
    void fUniform3iv(GLint location, GLsizei count, const GLint* value) {
1742
0
        BEFORE_GL_CALL;
1743
0
        mSymbols.fUniform3iv(location, count, value);
1744
0
        AFTER_GL_CALL;
1745
0
    }
1746
1747
0
    void fUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
1748
0
        BEFORE_GL_CALL;
1749
0
        mSymbols.fUniform4f(location, v0, v1, v2, v3);
1750
0
        AFTER_GL_CALL;
1751
0
    }
1752
1753
0
    void fUniform4fv(GLint location, GLsizei count, const GLfloat* value) {
1754
0
        BEFORE_GL_CALL;
1755
0
        mSymbols.fUniform4fv(location, count, value);
1756
0
        AFTER_GL_CALL;
1757
0
    }
1758
1759
0
    void fUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {
1760
0
        BEFORE_GL_CALL;
1761
0
        mSymbols.fUniform4i(location, v0, v1, v2, v3);
1762
0
        AFTER_GL_CALL;
1763
0
    }
1764
1765
0
    void fUniform4iv(GLint location, GLsizei count, const GLint* value) {
1766
0
        BEFORE_GL_CALL;
1767
0
        mSymbols.fUniform4iv(location, count, value);
1768
0
        AFTER_GL_CALL;
1769
0
    }
1770
1771
0
    void fUniformMatrix2fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1772
0
        BEFORE_GL_CALL;
1773
0
        mSymbols.fUniformMatrix2fv(location, count, transpose, value);
1774
0
        AFTER_GL_CALL;
1775
0
    }
1776
1777
0
    void fUniformMatrix2x3fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1778
0
        BEFORE_GL_CALL;
1779
0
        ASSERT_SYMBOL_PRESENT(fUniformMatrix2x3fv);
1780
0
        mSymbols.fUniformMatrix2x3fv(location, count, transpose, value);
1781
0
        AFTER_GL_CALL;
1782
0
    }
1783
1784
0
    void fUniformMatrix2x4fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1785
0
        BEFORE_GL_CALL;
1786
0
        ASSERT_SYMBOL_PRESENT(fUniformMatrix2x4fv);
1787
0
        mSymbols.fUniformMatrix2x4fv(location, count, transpose, value);
1788
0
        AFTER_GL_CALL;
1789
0
    }
1790
1791
0
    void fUniformMatrix3fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1792
0
        BEFORE_GL_CALL;
1793
0
        mSymbols.fUniformMatrix3fv(location, count, transpose, value);
1794
0
        AFTER_GL_CALL;
1795
0
    }
1796
1797
0
    void fUniformMatrix3x2fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1798
0
        BEFORE_GL_CALL;
1799
0
        ASSERT_SYMBOL_PRESENT(fUniformMatrix3x2fv);
1800
0
        mSymbols.fUniformMatrix3x2fv(location, count, transpose, value);
1801
0
        AFTER_GL_CALL;
1802
0
    }
1803
1804
0
    void fUniformMatrix3x4fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1805
0
        BEFORE_GL_CALL;
1806
0
        ASSERT_SYMBOL_PRESENT(fUniformMatrix3x4fv);
1807
0
        mSymbols.fUniformMatrix3x4fv(location, count, transpose, value);
1808
0
        AFTER_GL_CALL;
1809
0
    }
1810
1811
0
    void fUniformMatrix4fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1812
0
        BEFORE_GL_CALL;
1813
0
        mSymbols.fUniformMatrix4fv(location, count, transpose, value);
1814
0
        AFTER_GL_CALL;
1815
0
    }
1816
1817
0
    void fUniformMatrix4x2fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1818
0
        BEFORE_GL_CALL;
1819
0
        ASSERT_SYMBOL_PRESENT(fUniformMatrix4x2fv);
1820
0
        mSymbols.fUniformMatrix4x2fv(location, count, transpose, value);
1821
0
        AFTER_GL_CALL;
1822
0
    }
1823
1824
    void fUniformMatrix4x3fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
1825
        BEFORE_GL_CALL;
1826
        ASSERT_SYMBOL_PRESENT(fUniformMatrix4x3fv);
1827
        mSymbols.fUniformMatrix4x3fv(location, count, transpose, value);
1828
        AFTER_GL_CALL;
1829
    }
1830
1831
0
    void fUseProgram(GLuint program) {
1832
0
        BEFORE_GL_CALL;
1833
0
        mSymbols.fUseProgram(program);
1834
0
        AFTER_GL_CALL;
1835
0
    }
1836
1837
0
    void fValidateProgram(GLuint program) {
1838
0
        BEFORE_GL_CALL;
1839
0
        mSymbols.fValidateProgram(program);
1840
0
        AFTER_GL_CALL;
1841
0
    }
1842
1843
0
    void fVertexAttribPointer(GLuint index, GLint size, GLenum type, realGLboolean normalized, GLsizei stride, const GLvoid* pointer) {
1844
0
        BEFORE_GL_CALL;
1845
0
        mSymbols.fVertexAttribPointer(index, size, type, normalized, stride, pointer);
1846
0
        AFTER_GL_CALL;
1847
0
    }
1848
1849
0
    void fVertexAttrib1f(GLuint index, GLfloat x) {
1850
0
        BEFORE_GL_CALL;
1851
0
        mSymbols.fVertexAttrib1f(index, x);
1852
0
        AFTER_GL_CALL;
1853
0
    }
1854
1855
0
    void fVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {
1856
0
        BEFORE_GL_CALL;
1857
0
        mSymbols.fVertexAttrib2f(index, x, y);
1858
0
        AFTER_GL_CALL;
1859
0
    }
1860
1861
0
    void fVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
1862
0
        BEFORE_GL_CALL;
1863
0
        mSymbols.fVertexAttrib3f(index, x, y, z);
1864
0
        AFTER_GL_CALL;
1865
0
    }
1866
1867
0
    void fVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
1868
0
        BEFORE_GL_CALL;
1869
0
        mSymbols.fVertexAttrib4f(index, x, y, z, w);
1870
0
        AFTER_GL_CALL;
1871
0
    }
1872
1873
0
    void fVertexAttrib1fv(GLuint index, const GLfloat* v) {
1874
0
        BEFORE_GL_CALL;
1875
0
        mSymbols.fVertexAttrib1fv(index, v);
1876
0
        AFTER_GL_CALL;
1877
0
    }
1878
1879
0
    void fVertexAttrib2fv(GLuint index, const GLfloat* v) {
1880
0
        BEFORE_GL_CALL;
1881
0
        mSymbols.fVertexAttrib2fv(index, v);
1882
0
        AFTER_GL_CALL;
1883
0
    }
1884
1885
0
    void fVertexAttrib3fv(GLuint index, const GLfloat* v) {
1886
0
        BEFORE_GL_CALL;
1887
0
        mSymbols.fVertexAttrib3fv(index, v);
1888
0
        AFTER_GL_CALL;
1889
0
    }
1890
1891
0
    void fVertexAttrib4fv(GLuint index, const GLfloat* v) {
1892
0
        BEFORE_GL_CALL;
1893
0
        mSymbols.fVertexAttrib4fv(index, v);
1894
0
        AFTER_GL_CALL;
1895
0
    }
1896
1897
0
    void fVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
1898
0
        BEFORE_GL_CALL;
1899
0
        mSymbols.fVertexPointer(size, type, stride, pointer);
1900
0
        AFTER_GL_CALL;
1901
0
    }
1902
1903
0
    void fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
1904
0
        if (mViewportRect[0] == x &&
1905
0
            mViewportRect[1] == y &&
1906
0
            mViewportRect[2] == width &&
1907
0
            mViewportRect[3] == height)
1908
0
        {
1909
0
            return;
1910
0
        }
1911
0
        mViewportRect[0] = x;
1912
0
        mViewportRect[1] = y;
1913
0
        mViewportRect[2] = width;
1914
0
        mViewportRect[3] = height;
1915
0
        BEFORE_GL_CALL;
1916
0
        mSymbols.fViewport(x, y, width, height);
1917
0
        AFTER_GL_CALL;
1918
0
    }
1919
1920
0
    void fCompileShader(GLuint shader) {
1921
0
        BEFORE_GL_CALL;
1922
0
        mSymbols.fCompileShader(shader);
1923
0
        AFTER_GL_CALL;
1924
0
    }
1925
1926
private:
1927
1928
    friend class SharedSurface_IOSurface;
1929
1930
    void raw_fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
1931
    {
1932
        BEFORE_GL_CALL;
1933
        mSymbols.fCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
1934
        AFTER_GL_CALL;
1935
    }
1936
1937
    void raw_fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1938
0
    {
1939
0
        BEFORE_GL_CALL;
1940
0
        mSymbols.fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
1941
0
        AFTER_GL_CALL;
1942
0
    }
1943
1944
public:
1945
0
    void fGetShaderiv(GLuint shader, GLenum pname, GLint* param) {
1946
0
        BEFORE_GL_CALL;
1947
0
        mSymbols.fGetShaderiv(shader, pname, param);
1948
0
        OnSyncCall();
1949
0
        AFTER_GL_CALL;
1950
0
    }
1951
1952
0
    void fGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
1953
0
        BEFORE_GL_CALL;
1954
0
        mSymbols.fGetShaderInfoLog(shader, bufSize, length, infoLog);
1955
0
        OnSyncCall();
1956
0
        AFTER_GL_CALL;
1957
0
    }
1958
1959
private:
1960
0
    void raw_fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
1961
0
        MOZ_ASSERT(IsGLES());
1962
0
1963
0
        BEFORE_GL_CALL;
1964
0
        ASSERT_SYMBOL_PRESENT(fGetShaderPrecisionFormat);
1965
0
        mSymbols.fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
1966
0
        OnSyncCall();
1967
0
        AFTER_GL_CALL;
1968
0
    }
1969
1970
public:
1971
0
    void fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
1972
0
        if (IsGLES()) {
1973
0
            raw_fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
1974
0
        } else {
1975
0
            // Fall back to automatic values because almost all desktop hardware supports the OpenGL standard precisions.
1976
0
            GetShaderPrecisionFormatNonES2(shadertype, precisiontype, range, precision);
1977
0
        }
1978
0
    }
1979
1980
0
    void fGetShaderSource(GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source) {
1981
0
        BEFORE_GL_CALL;
1982
0
        mSymbols.fGetShaderSource(obj, maxLength, length, source);
1983
0
        OnSyncCall();
1984
0
        AFTER_GL_CALL;
1985
0
    }
1986
1987
0
    void fShaderSource(GLuint shader, GLsizei count, const GLchar* const* strings, const GLint* lengths) {
1988
0
        BEFORE_GL_CALL;
1989
0
        mSymbols.fShaderSource(shader, count, strings, lengths);
1990
0
        AFTER_GL_CALL;
1991
0
    }
1992
1993
private:
1994
    friend class SharedSurface;
1995
1996
    void raw_fBindFramebuffer(GLenum target, GLuint framebuffer) {
1997
        BEFORE_GL_CALL;
1998
        mSymbols.fBindFramebuffer(target, framebuffer);
1999
        AFTER_GL_CALL;
2000
    }
2001
2002
public:
2003
0
    void fBindRenderbuffer(GLenum target, GLuint renderbuffer) {
2004
0
        BEFORE_GL_CALL;
2005
0
        mSymbols.fBindRenderbuffer(target, renderbuffer);
2006
0
        AFTER_GL_CALL;
2007
0
    }
2008
2009
0
    GLenum fCheckFramebufferStatus(GLenum target) {
2010
0
        GLenum retval = 0;
2011
0
        BEFORE_GL_CALL;
2012
0
        retval = mSymbols.fCheckFramebufferStatus(target);
2013
0
        OnSyncCall();
2014
0
        AFTER_GL_CALL;
2015
0
        return retval;
2016
0
    }
2017
2018
0
    void fFramebufferRenderbuffer(GLenum target, GLenum attachmentPoint, GLenum renderbufferTarget, GLuint renderbuffer) {
2019
0
        BEFORE_GL_CALL;
2020
0
        mSymbols.fFramebufferRenderbuffer(target, attachmentPoint, renderbufferTarget, renderbuffer);
2021
0
        AFTER_GL_CALL;
2022
0
    }
2023
2024
0
    void fFramebufferTexture2D(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint texture, GLint level) {
2025
0
        BEFORE_GL_CALL;
2026
0
        mSymbols.fFramebufferTexture2D(target, attachmentPoint, textureTarget, texture, level);
2027
0
        AFTER_GL_CALL;
2028
0
        if (mNeedsCheckAfterAttachTextureToFb) {
2029
0
            fCheckFramebufferStatus(target);
2030
0
        }
2031
0
    }
2032
2033
0
    void fFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) {
2034
0
        BEFORE_GL_CALL;
2035
0
        ASSERT_SYMBOL_PRESENT(fFramebufferTextureLayer);
2036
0
        mSymbols.fFramebufferTextureLayer(target, attachment, texture, level, layer);
2037
0
        AFTER_GL_CALL;
2038
0
    }
2039
2040
0
    void fGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* value) {
2041
0
        BEFORE_GL_CALL;
2042
0
        mSymbols.fGetFramebufferAttachmentParameteriv(target, attachment, pname, value);
2043
0
        OnSyncCall();
2044
0
        AFTER_GL_CALL;
2045
0
    }
2046
2047
0
    void fGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* value) {
2048
0
        BEFORE_GL_CALL;
2049
0
        mSymbols.fGetRenderbufferParameteriv(target, pname, value);
2050
0
        OnSyncCall();
2051
0
        AFTER_GL_CALL;
2052
0
    }
2053
2054
0
    realGLboolean fIsFramebuffer (GLuint framebuffer) {
2055
0
        realGLboolean retval = false;
2056
0
        BEFORE_GL_CALL;
2057
0
        retval = mSymbols.fIsFramebuffer(framebuffer);
2058
0
        OnSyncCall();
2059
0
        AFTER_GL_CALL;
2060
0
        return retval;
2061
0
    }
2062
2063
public:
2064
0
    realGLboolean fIsRenderbuffer (GLuint renderbuffer) {
2065
0
        realGLboolean retval = false;
2066
0
        BEFORE_GL_CALL;
2067
0
        retval = mSymbols.fIsRenderbuffer(renderbuffer);
2068
0
        OnSyncCall();
2069
0
        AFTER_GL_CALL;
2070
0
        return retval;
2071
0
    }
2072
2073
0
    void fRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height) {
2074
0
        BEFORE_GL_CALL;
2075
0
        mSymbols.fRenderbufferStorage(target, internalFormat, width, height);
2076
0
        AFTER_GL_CALL;
2077
0
    }
2078
2079
private:
2080
    void raw_fDepthRange(GLclampf a, GLclampf b) {
2081
        MOZ_ASSERT(!IsGLES());
2082
2083
        BEFORE_GL_CALL;
2084
        ASSERT_SYMBOL_PRESENT(fDepthRange);
2085
        mSymbols.fDepthRange(a, b);
2086
        AFTER_GL_CALL;
2087
    }
2088
2089
    void raw_fDepthRangef(GLclampf a, GLclampf b) {
2090
        MOZ_ASSERT(IsGLES());
2091
2092
        BEFORE_GL_CALL;
2093
        ASSERT_SYMBOL_PRESENT(fDepthRangef);
2094
        mSymbols.fDepthRangef(a, b);
2095
        AFTER_GL_CALL;
2096
    }
2097
2098
    void raw_fClearDepth(GLclampf v) {
2099
        MOZ_ASSERT(!IsGLES());
2100
2101
        BEFORE_GL_CALL;
2102
        ASSERT_SYMBOL_PRESENT(fClearDepth);
2103
        mSymbols.fClearDepth(v);
2104
        AFTER_GL_CALL;
2105
    }
2106
2107
    void raw_fClearDepthf(GLclampf v) {
2108
        MOZ_ASSERT(IsGLES());
2109
2110
        BEFORE_GL_CALL;
2111
        ASSERT_SYMBOL_PRESENT(fClearDepthf);
2112
        mSymbols.fClearDepthf(v);
2113
        AFTER_GL_CALL;
2114
    }
2115
2116
public:
2117
    void fDepthRange(GLclampf a, GLclampf b) {
2118
        if (IsGLES()) {
2119
            raw_fDepthRangef(a, b);
2120
        } else {
2121
            raw_fDepthRange(a, b);
2122
        }
2123
    }
2124
2125
    void fClearDepth(GLclampf v) {
2126
        if (IsGLES()) {
2127
            raw_fClearDepthf(v);
2128
        } else {
2129
            raw_fClearDepth(v);
2130
        }
2131
    }
2132
2133
0
    void* fMapBuffer(GLenum target, GLenum access) {
2134
0
        void* ret = nullptr;
2135
0
        BEFORE_GL_CALL;
2136
0
        ASSERT_SYMBOL_PRESENT(fMapBuffer);
2137
0
        ret = mSymbols.fMapBuffer(target, access);
2138
0
        OnSyncCall();
2139
0
        AFTER_GL_CALL;
2140
0
        return ret;
2141
0
    }
2142
2143
0
    realGLboolean fUnmapBuffer(GLenum target) {
2144
0
        realGLboolean ret = false;
2145
0
        BEFORE_GL_CALL;
2146
0
        ASSERT_SYMBOL_PRESENT(fUnmapBuffer);
2147
0
        ret = mSymbols.fUnmapBuffer(target);
2148
0
        AFTER_GL_CALL;
2149
0
        return ret;
2150
0
    }
2151
2152
2153
private:
2154
0
    GLuint raw_fCreateProgram() {
2155
0
        GLuint ret = 0;
2156
0
        BEFORE_GL_CALL;
2157
0
        ret = mSymbols.fCreateProgram();
2158
0
        AFTER_GL_CALL;
2159
0
        return ret;
2160
0
    }
2161
2162
0
    GLuint raw_fCreateShader(GLenum t) {
2163
0
        GLuint ret = 0;
2164
0
        BEFORE_GL_CALL;
2165
0
        ret = mSymbols.fCreateShader(t);
2166
0
        AFTER_GL_CALL;
2167
0
        return ret;
2168
0
    }
2169
2170
0
    void raw_fGenBuffers(GLsizei n, GLuint* names) {
2171
0
        BEFORE_GL_CALL;
2172
0
        mSymbols.fGenBuffers(n, names);
2173
0
        OnSyncCall();
2174
0
        AFTER_GL_CALL;
2175
0
    }
2176
2177
0
    void raw_fGenFramebuffers(GLsizei n, GLuint* names) {
2178
0
        BEFORE_GL_CALL;
2179
0
        mSymbols.fGenFramebuffers(n, names);
2180
0
        OnSyncCall();
2181
0
        AFTER_GL_CALL;
2182
0
    }
2183
2184
0
    void raw_fGenRenderbuffers(GLsizei n, GLuint* names) {
2185
0
        BEFORE_GL_CALL;
2186
0
        mSymbols.fGenRenderbuffers(n, names);
2187
0
        OnSyncCall();
2188
0
        AFTER_GL_CALL;
2189
0
    }
2190
2191
0
    void raw_fGenTextures(GLsizei n, GLuint* names) {
2192
0
        BEFORE_GL_CALL;
2193
0
        mSymbols.fGenTextures(n, names);
2194
0
        OnSyncCall();
2195
0
        AFTER_GL_CALL;
2196
0
    }
2197
2198
public:
2199
0
    GLuint fCreateProgram() {
2200
0
        GLuint ret = raw_fCreateProgram();
2201
0
        TRACKING_CONTEXT(CreatedProgram(this, ret));
2202
0
        return ret;
2203
0
    }
2204
2205
0
    GLuint fCreateShader(GLenum t) {
2206
0
        GLuint ret = raw_fCreateShader(t);
2207
0
        TRACKING_CONTEXT(CreatedShader(this, ret));
2208
0
        return ret;
2209
0
    }
2210
2211
0
    void fGenBuffers(GLsizei n, GLuint* names) {
2212
0
        raw_fGenBuffers(n, names);
2213
0
        TRACKING_CONTEXT(CreatedBuffers(this, n, names));
2214
0
    }
2215
2216
0
    void fGenFramebuffers(GLsizei n, GLuint* names) {
2217
0
        raw_fGenFramebuffers(n, names);
2218
0
        TRACKING_CONTEXT(CreatedFramebuffers(this, n, names));
2219
0
    }
2220
2221
0
    void fGenRenderbuffers(GLsizei n, GLuint* names) {
2222
0
        raw_fGenRenderbuffers(n, names);
2223
0
        TRACKING_CONTEXT(CreatedRenderbuffers(this, n, names));
2224
0
    }
2225
2226
0
    void fGenTextures(GLsizei n, GLuint* names) {
2227
0
        raw_fGenTextures(n, names);
2228
0
        TRACKING_CONTEXT(CreatedTextures(this, n, names));
2229
0
    }
2230
2231
private:
2232
0
    void raw_fDeleteProgram(GLuint program) {
2233
0
        BEFORE_GL_CALL;
2234
0
        mSymbols.fDeleteProgram(program);
2235
0
        AFTER_GL_CALL;
2236
0
    }
2237
2238
0
    void raw_fDeleteShader(GLuint shader) {
2239
0
        BEFORE_GL_CALL;
2240
0
        mSymbols.fDeleteShader(shader);
2241
0
        AFTER_GL_CALL;
2242
0
    }
2243
2244
0
    void raw_fDeleteBuffers(GLsizei n, const GLuint* names) {
2245
0
        BEFORE_GL_CALL;
2246
0
        mSymbols.fDeleteBuffers(n, names);
2247
0
        AFTER_GL_CALL;
2248
0
    }
2249
2250
    void raw_fDeleteFramebuffers(GLsizei n, const GLuint* names) {
2251
        BEFORE_GL_CALL;
2252
        mSymbols.fDeleteFramebuffers(n, names);
2253
        AFTER_GL_CALL;
2254
    }
2255
2256
0
    void raw_fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
2257
0
        BEFORE_GL_CALL;
2258
0
        mSymbols.fDeleteRenderbuffers(n, names);
2259
0
        AFTER_GL_CALL;
2260
0
    }
2261
2262
0
    void raw_fDeleteTextures(GLsizei n, const GLuint* names) {
2263
0
        BEFORE_GL_CALL;
2264
0
        mSymbols.fDeleteTextures(n, names);
2265
0
        AFTER_GL_CALL;
2266
0
    }
2267
2268
public:
2269
2270
0
    void fDeleteProgram(GLuint program) {
2271
0
        raw_fDeleteProgram(program);
2272
0
        TRACKING_CONTEXT(DeletedProgram(this, program));
2273
0
    }
2274
2275
0
    void fDeleteShader(GLuint shader) {
2276
0
        raw_fDeleteShader(shader);
2277
0
        TRACKING_CONTEXT(DeletedShader(this, shader));
2278
0
    }
2279
2280
0
    void fDeleteBuffers(GLsizei n, const GLuint* names) {
2281
0
        raw_fDeleteBuffers(n, names);
2282
0
        TRACKING_CONTEXT(DeletedBuffers(this, n, names));
2283
0
    }
2284
2285
    void fDeleteFramebuffers(GLsizei n, const GLuint* names);
2286
2287
0
    void fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
2288
0
        raw_fDeleteRenderbuffers(n, names);
2289
0
        TRACKING_CONTEXT(DeletedRenderbuffers(this, n, names));
2290
0
    }
2291
2292
0
    void fDeleteTextures(GLsizei n, const GLuint* names) {
2293
0
        raw_fDeleteTextures(n, names);
2294
0
        TRACKING_CONTEXT(DeletedTextures(this, n, names));
2295
0
    }
2296
2297
    GLenum fGetGraphicsResetStatus() {
2298
        GLenum ret = 0;
2299
        BEFORE_GL_CALL;
2300
        ASSERT_SYMBOL_PRESENT(fGetGraphicsResetStatus);
2301
        ret = mSymbols.fGetGraphicsResetStatus();
2302
        OnSyncCall();
2303
        AFTER_GL_CALL;
2304
        return ret;
2305
    }
2306
2307
2308
// -----------------------------------------------------------------------------
2309
// Extension ARB_sync (GL)
2310
public:
2311
0
    GLsync fFenceSync(GLenum condition, GLbitfield flags) {
2312
0
        GLsync ret = 0;
2313
0
        BEFORE_GL_CALL;
2314
0
        ASSERT_SYMBOL_PRESENT(fFenceSync);
2315
0
        ret = mSymbols.fFenceSync(condition, flags);
2316
0
        OnSyncCall();
2317
0
        AFTER_GL_CALL;
2318
0
        return ret;
2319
0
    }
2320
2321
0
    realGLboolean fIsSync(GLsync sync) {
2322
0
        realGLboolean ret = false;
2323
0
        BEFORE_GL_CALL;
2324
0
        ASSERT_SYMBOL_PRESENT(fIsSync);
2325
0
        ret = mSymbols.fIsSync(sync);
2326
0
        OnSyncCall();
2327
0
        AFTER_GL_CALL;
2328
0
        return ret;
2329
0
    }
2330
2331
0
    void fDeleteSync(GLsync sync) {
2332
0
        BEFORE_GL_CALL;
2333
0
        ASSERT_SYMBOL_PRESENT(fDeleteSync);
2334
0
        mSymbols.fDeleteSync(sync);
2335
0
        AFTER_GL_CALL;
2336
0
    }
2337
2338
0
    GLenum fClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
2339
0
        GLenum ret = 0;
2340
0
        BEFORE_GL_CALL;
2341
0
        ASSERT_SYMBOL_PRESENT(fClientWaitSync);
2342
0
        ret = mSymbols.fClientWaitSync(sync, flags, timeout);
2343
0
        OnSyncCall();
2344
0
        AFTER_GL_CALL;
2345
0
        return ret;
2346
0
    }
2347
2348
    void fWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
2349
        BEFORE_GL_CALL;
2350
        ASSERT_SYMBOL_PRESENT(fWaitSync);
2351
        mSymbols.fWaitSync(sync, flags, timeout);
2352
        AFTER_GL_CALL;
2353
    }
2354
2355
0
    void fGetInteger64v(GLenum pname, GLint64* params) {
2356
0
        BEFORE_GL_CALL;
2357
0
        ASSERT_SYMBOL_PRESENT(fGetInteger64v);
2358
0
        mSymbols.fGetInteger64v(pname, params);
2359
0
        AFTER_GL_CALL;
2360
0
    }
2361
2362
0
    void fGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) {
2363
0
        BEFORE_GL_CALL;
2364
0
        ASSERT_SYMBOL_PRESENT(fGetSynciv);
2365
0
        mSymbols.fGetSynciv(sync, pname, bufSize, length, values);
2366
0
        OnSyncCall();
2367
0
        AFTER_GL_CALL;
2368
0
    }
2369
2370
2371
// -----------------------------------------------------------------------------
2372
// Extension OES_EGL_image (GLES)
2373
public:
2374
    void fEGLImageTargetTexture2D(GLenum target, GLeglImage image) {
2375
        BEFORE_GL_CALL;
2376
        ASSERT_SYMBOL_PRESENT(fEGLImageTargetTexture2D);
2377
        mSymbols.fEGLImageTargetTexture2D(target, image);
2378
        AFTER_GL_CALL;
2379
        mHeavyGLCallsSinceLastFlush = true;
2380
    }
2381
2382
    void fEGLImageTargetRenderbufferStorage(GLenum target, GLeglImage image)
2383
0
    {
2384
0
        BEFORE_GL_CALL;
2385
0
        ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage);
2386
0
        mSymbols.fEGLImageTargetRenderbufferStorage(target, image);
2387
0
        AFTER_GL_CALL;
2388
0
    }
2389
2390
2391
// -----------------------------------------------------------------------------
2392
// Package XXX_bind_buffer_offset
2393
public:
2394
    void fBindBufferOffset(GLenum target, GLuint index, GLuint buffer, GLintptr offset)
2395
0
    {
2396
0
        BEFORE_GL_CALL;
2397
0
        ASSERT_SYMBOL_PRESENT(fBindBufferOffset);
2398
0
        mSymbols.fBindBufferOffset(target, index, buffer, offset);
2399
0
        AFTER_GL_CALL;
2400
0
    }
2401
2402
2403
// -----------------------------------------------------------------------------
2404
// Package XXX_draw_buffers
2405
public:
2406
0
    void fDrawBuffers(GLsizei n, const GLenum* bufs) {
2407
0
        BEFORE_GL_CALL;
2408
0
        ASSERT_SYMBOL_PRESENT(fDrawBuffers);
2409
0
        mSymbols.fDrawBuffers(n, bufs);
2410
0
        AFTER_GL_CALL;
2411
0
    }
2412
2413
2414
// -----------------------------------------------------------------------------
2415
// Package XXX_draw_instanced
2416
public:
2417
    void fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
2418
0
    {
2419
0
        BeforeGLDrawCall();
2420
0
        raw_fDrawArraysInstanced(mode, first, count, primcount);
2421
0
        AfterGLDrawCall();
2422
0
    }
2423
2424
    void fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount)
2425
0
    {
2426
0
        BeforeGLDrawCall();
2427
0
        raw_fDrawElementsInstanced(mode, count, type, indices, primcount);
2428
0
        AfterGLDrawCall();
2429
0
    }
2430
2431
private:
2432
    void raw_fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
2433
0
    {
2434
0
        BEFORE_GL_CALL;
2435
0
        ASSERT_SYMBOL_PRESENT(fDrawArraysInstanced);
2436
0
        mSymbols.fDrawArraysInstanced(mode, first, count, primcount);
2437
0
        AFTER_GL_CALL;
2438
0
    }
2439
2440
    void raw_fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount)
2441
0
    {
2442
0
        BEFORE_GL_CALL;
2443
0
        ASSERT_SYMBOL_PRESENT(fDrawElementsInstanced);
2444
0
        mSymbols.fDrawElementsInstanced(mode, count, type, indices, primcount);
2445
0
        AFTER_GL_CALL;
2446
0
    }
2447
2448
// -----------------------------------------------------------------------------
2449
// Feature draw_range_elements
2450
public:
2451
    void fDrawRangeElements(GLenum mode, GLuint start, GLuint end,
2452
                            GLsizei count, GLenum type, const GLvoid* indices)
2453
0
    {
2454
0
        BeforeGLDrawCall();
2455
0
        raw_fDrawRangeElements(mode, start, end, count, type, indices);
2456
0
        AfterGLDrawCall();
2457
0
    }
2458
2459
private:
2460
    void raw_fDrawRangeElements(GLenum mode, GLuint start, GLuint end,
2461
                                GLsizei count, GLenum type, const GLvoid* indices)
2462
0
    {
2463
0
        BEFORE_GL_CALL;
2464
0
        ASSERT_SYMBOL_PRESENT(fDrawRangeElements);
2465
0
        mSymbols.fDrawRangeElements(mode, start, end, count, type, indices);
2466
0
        AFTER_GL_CALL;
2467
0
    }
2468
2469
// -----------------------------------------------------------------------------
2470
// Package XXX_framebuffer_blit
2471
public:
2472
    // Draw/Read
2473
0
    void fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
2474
0
        BeforeGLDrawCall();
2475
0
        BeforeGLReadCall();
2476
0
        raw_fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
2477
0
        AfterGLReadCall();
2478
0
        AfterGLDrawCall();
2479
0
    }
2480
2481
2482
private:
2483
0
    void raw_fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
2484
0
        BEFORE_GL_CALL;
2485
0
        ASSERT_SYMBOL_PRESENT(fBlitFramebuffer);
2486
0
        mSymbols.fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
2487
0
        AFTER_GL_CALL;
2488
0
    }
2489
2490
2491
// -----------------------------------------------------------------------------
2492
// Package XXX_framebuffer_multisample
2493
public:
2494
0
    void fRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height) {
2495
0
        BEFORE_GL_CALL;
2496
0
        ASSERT_SYMBOL_PRESENT(fRenderbufferStorageMultisample);
2497
0
        mSymbols.fRenderbufferStorageMultisample(target, samples, internalFormat, width, height);
2498
0
        AFTER_GL_CALL;
2499
0
    }
2500
2501
// -----------------------------------------------------------------------------
2502
//  GL 3.0, GL ES 3.0 & EXT_gpu_shader4
2503
public:
2504
    void fGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params)
2505
0
    {
2506
0
        ASSERT_SYMBOL_PRESENT(fGetVertexAttribIiv);
2507
0
        BEFORE_GL_CALL;
2508
0
        mSymbols.fGetVertexAttribIiv(index, pname, params);
2509
0
        OnSyncCall();
2510
0
        AFTER_GL_CALL;
2511
0
    }
2512
2513
    void fGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params)
2514
0
    {
2515
0
        ASSERT_SYMBOL_PRESENT(fGetVertexAttribIuiv);
2516
0
        BEFORE_GL_CALL;
2517
0
        mSymbols.fGetVertexAttribIuiv(index, pname, params);
2518
0
        OnSyncCall();
2519
0
        AFTER_GL_CALL;
2520
0
    }
2521
2522
    void fVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
2523
0
    {
2524
0
        BEFORE_GL_CALL;
2525
0
        ASSERT_SYMBOL_PRESENT(fVertexAttribI4i);
2526
0
        mSymbols.fVertexAttribI4i(index, x, y, z, w);
2527
0
        AFTER_GL_CALL;
2528
0
    }
2529
2530
    void fVertexAttribI4iv(GLuint index, const GLint* v)
2531
0
    {
2532
0
        BEFORE_GL_CALL;
2533
0
        ASSERT_SYMBOL_PRESENT(fVertexAttribI4iv);
2534
0
        mSymbols.fVertexAttribI4iv(index, v);
2535
0
        AFTER_GL_CALL;
2536
0
    }
2537
2538
    void fVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
2539
0
    {
2540
0
        BEFORE_GL_CALL;
2541
0
        ASSERT_SYMBOL_PRESENT(fVertexAttribI4ui);
2542
0
        mSymbols.fVertexAttribI4ui(index, x, y, z, w);
2543
0
        AFTER_GL_CALL;
2544
0
    }
2545
2546
    void fVertexAttribI4uiv(GLuint index, const GLuint* v)
2547
0
    {
2548
0
        BEFORE_GL_CALL;
2549
0
        ASSERT_SYMBOL_PRESENT(fVertexAttribI4uiv);
2550
0
        mSymbols.fVertexAttribI4uiv(index, v);
2551
0
        AFTER_GL_CALL;
2552
0
    }
2553
2554
    void fVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* offset)
2555
0
    {
2556
0
        BEFORE_GL_CALL;
2557
0
        ASSERT_SYMBOL_PRESENT(fVertexAttribIPointer);
2558
0
        mSymbols.fVertexAttribIPointer(index, size, type, stride, offset);
2559
0
        AFTER_GL_CALL;
2560
0
    }
2561
2562
0
    void fUniform1ui(GLint location, GLuint v0) {
2563
0
        BEFORE_GL_CALL;
2564
0
        ASSERT_SYMBOL_PRESENT(fUniform1ui);
2565
0
        mSymbols.fUniform1ui(location, v0);
2566
0
        AFTER_GL_CALL;
2567
0
    }
2568
2569
0
    void fUniform2ui(GLint location, GLuint v0, GLuint v1) {
2570
0
        BEFORE_GL_CALL;
2571
0
        ASSERT_SYMBOL_PRESENT(fUniform2ui);
2572
0
        mSymbols.fUniform2ui(location, v0, v1);
2573
0
        AFTER_GL_CALL;
2574
0
    }
2575
2576
0
    void fUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) {
2577
0
        BEFORE_GL_CALL;
2578
0
        ASSERT_SYMBOL_PRESENT(fUniform3ui);
2579
0
        mSymbols.fUniform3ui(location, v0, v1, v2);
2580
0
        AFTER_GL_CALL;
2581
0
    }
2582
2583
0
    void fUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) {
2584
0
        BEFORE_GL_CALL;
2585
0
        ASSERT_SYMBOL_PRESENT(fUniform4ui);
2586
0
        mSymbols.fUniform4ui(location, v0, v1, v2, v3);
2587
0
        AFTER_GL_CALL;
2588
0
    }
2589
2590
0
    void fUniform1uiv(GLint location, GLsizei count, const GLuint* value) {
2591
0
        BEFORE_GL_CALL;
2592
0
        ASSERT_SYMBOL_PRESENT(fUniform1uiv);
2593
0
        mSymbols.fUniform1uiv(location, count, value);
2594
0
        AFTER_GL_CALL;
2595
0
    }
2596
2597
0
    void fUniform2uiv(GLint location, GLsizei count, const GLuint* value) {
2598
0
        BEFORE_GL_CALL;
2599
0
        ASSERT_SYMBOL_PRESENT(fUniform2uiv);
2600
0
        mSymbols.fUniform2uiv(location, count, value);
2601
0
        AFTER_GL_CALL;
2602
0
    }
2603
2604
0
    void fUniform3uiv(GLint location, GLsizei count, const GLuint* value) {
2605
0
        BEFORE_GL_CALL;
2606
0
        ASSERT_SYMBOL_PRESENT(fUniform3uiv);
2607
0
        mSymbols.fUniform3uiv(location, count, value);
2608
0
        AFTER_GL_CALL;
2609
0
    }
2610
2611
0
    void fUniform4uiv(GLint location, GLsizei count, const GLuint* value) {
2612
0
        BEFORE_GL_CALL;
2613
0
        ASSERT_SYMBOL_PRESENT(fUniform4uiv);
2614
0
        mSymbols.fUniform4uiv(location, count, value);
2615
0
        AFTER_GL_CALL;
2616
0
    }
2617
2618
    GLint fGetFragDataLocation(GLuint program, const GLchar* name)
2619
0
    {
2620
0
        GLint result = 0;
2621
0
        BEFORE_GL_CALL;
2622
0
        ASSERT_SYMBOL_PRESENT(fGetFragDataLocation);
2623
0
        result = mSymbols.fGetFragDataLocation(program, name);
2624
0
        OnSyncCall();
2625
0
        AFTER_GL_CALL;
2626
0
        return result;
2627
0
    }
2628
2629
2630
// -----------------------------------------------------------------------------
2631
// Package XXX_instanced_arrays
2632
public:
2633
    void fVertexAttribDivisor(GLuint index, GLuint divisor)
2634
0
    {
2635
0
        BEFORE_GL_CALL;
2636
0
        ASSERT_SYMBOL_PRESENT(fVertexAttribDivisor);
2637
0
        mSymbols.fVertexAttribDivisor(index, divisor);
2638
0
        AFTER_GL_CALL;
2639
0
    }
2640
2641
// -----------------------------------------------------------------------------
2642
// Feature internalformat_query
2643
public:
2644
0
    void fGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) {
2645
0
        BEFORE_GL_CALL;
2646
0
        ASSERT_SYMBOL_PRESENT(fGetInternalformativ);
2647
0
        mSymbols.fGetInternalformativ(target, internalformat, pname, bufSize, params);
2648
0
        OnSyncCall();
2649
0
        AFTER_GL_CALL;
2650
0
    }
2651
2652
2653
// -----------------------------------------------------------------------------
2654
// Package XXX_query_counter
2655
/**
2656
 * XXX_query_counter:
2657
 *  - depends on XXX_query_objects
2658
 *  - provide all followed entry points
2659
 *  - provide GL_TIMESTAMP
2660
 */
2661
public:
2662
0
    void fQueryCounter(GLuint id, GLenum target) {
2663
0
        BEFORE_GL_CALL;
2664
0
        ASSERT_SYMBOL_PRESENT(fQueryCounter);
2665
0
        mSymbols.fQueryCounter(id, target);
2666
0
        AFTER_GL_CALL;
2667
0
    }
2668
2669
2670
// -----------------------------------------------------------------------------
2671
// Package XXX_query_objects
2672
/**
2673
 * XXX_query_objects:
2674
 *  - provide all followed entry points
2675
 *
2676
 * XXX_occlusion_query2:
2677
 *  - depends on XXX_query_objects
2678
 *  - provide ANY_SAMPLES_PASSED
2679
 *
2680
 * XXX_occlusion_query_boolean:
2681
 *  - depends on XXX_occlusion_query2
2682
 *  - provide ANY_SAMPLES_PASSED_CONSERVATIVE
2683
 */
2684
public:
2685
0
    void fDeleteQueries(GLsizei n, const GLuint* names) {
2686
0
        BEFORE_GL_CALL;
2687
0
        ASSERT_SYMBOL_PRESENT(fDeleteQueries);
2688
0
        mSymbols.fDeleteQueries(n, names);
2689
0
        AFTER_GL_CALL;
2690
0
        TRACKING_CONTEXT(DeletedQueries(this, n, names));
2691
0
    }
2692
2693
0
    void fGenQueries(GLsizei n, GLuint* names) {
2694
0
        BEFORE_GL_CALL;
2695
0
        ASSERT_SYMBOL_PRESENT(fGenQueries);
2696
0
        mSymbols.fGenQueries(n, names);
2697
0
        AFTER_GL_CALL;
2698
0
        TRACKING_CONTEXT(CreatedQueries(this, n, names));
2699
0
    }
2700
2701
0
    void fGetQueryiv(GLenum target, GLenum pname, GLint* params) {
2702
0
        BEFORE_GL_CALL;
2703
0
        ASSERT_SYMBOL_PRESENT(fGetQueryiv);
2704
0
        mSymbols.fGetQueryiv(target, pname, params);
2705
0
        OnSyncCall();
2706
0
        AFTER_GL_CALL;
2707
0
    }
2708
2709
0
    void fGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) {
2710
0
        BEFORE_GL_CALL;
2711
0
        ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv);
2712
0
        mSymbols.fGetQueryObjectuiv(id, pname, params);
2713
0
        OnSyncCall();
2714
0
        AFTER_GL_CALL;
2715
0
    }
2716
2717
0
    realGLboolean fIsQuery(GLuint query) {
2718
0
        realGLboolean retval = false;
2719
0
        BEFORE_GL_CALL;
2720
0
        ASSERT_SYMBOL_PRESENT(fIsQuery);
2721
0
        retval = mSymbols.fIsQuery(query);
2722
0
        OnSyncCall();
2723
0
        AFTER_GL_CALL;
2724
0
        return retval;
2725
0
    }
2726
2727
// -----------------------------------------------------------------------------
2728
// Package XXX_get_query_object_i64v
2729
/**
2730
 * XXX_get_query_object_i64v:
2731
 *  - depends on XXX_query_objects
2732
 *  - provide the followed entry point
2733
 */
2734
public:
2735
0
    void fGetQueryObjecti64v(GLuint id, GLenum pname, GLint64* params) {
2736
0
        BEFORE_GL_CALL;
2737
0
        ASSERT_SYMBOL_PRESENT(fGetQueryObjecti64v);
2738
0
        mSymbols.fGetQueryObjecti64v(id, pname, params);
2739
0
        OnSyncCall();
2740
0
        AFTER_GL_CALL;
2741
0
    }
2742
2743
0
    void fGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64* params) {
2744
0
        BEFORE_GL_CALL;
2745
0
        ASSERT_SYMBOL_PRESENT(fGetQueryObjectui64v);
2746
0
        mSymbols.fGetQueryObjectui64v(id, pname, params);
2747
0
        OnSyncCall();
2748
0
        AFTER_GL_CALL;
2749
0
    }
2750
2751
2752
// -----------------------------------------------------------------------------
2753
// Package XXX_get_query_object_iv
2754
/**
2755
 * XXX_get_query_object_iv:
2756
 *  - depends on XXX_query_objects
2757
 *  - provide the followed entry point
2758
 *
2759
 * XXX_occlusion_query:
2760
 *  - depends on XXX_get_query_object_iv
2761
 *  - provide LOCAL_GL_SAMPLES_PASSED
2762
 */
2763
public:
2764
0
    void fGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) {
2765
0
        BEFORE_GL_CALL;
2766
0
        ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv);
2767
0
        mSymbols.fGetQueryObjectiv(id, pname, params);
2768
0
        OnSyncCall();
2769
0
        AFTER_GL_CALL;
2770
0
    }
2771
2772
2773
// -----------------------------------------------------------------------------
2774
// GL 4.0, GL ES 3.0, ARB_transform_feedback2, NV_transform_feedback2
2775
public:
2776
    void fBindBufferBase(GLenum target, GLuint index, GLuint buffer)
2777
0
    {
2778
0
        BEFORE_GL_CALL;
2779
0
        ASSERT_SYMBOL_PRESENT(fBindBufferBase);
2780
0
        mSymbols.fBindBufferBase(target, index, buffer);
2781
0
        AFTER_GL_CALL;
2782
0
    }
2783
2784
    void fBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
2785
0
    {
2786
0
        BEFORE_GL_CALL;
2787
0
        ASSERT_SYMBOL_PRESENT(fBindBufferRange);
2788
0
        mSymbols.fBindBufferRange(target, index, buffer, offset, size);
2789
0
        AFTER_GL_CALL;
2790
0
    }
2791
2792
    void fGenTransformFeedbacks(GLsizei n, GLuint* ids)
2793
0
    {
2794
0
        BEFORE_GL_CALL;
2795
0
        ASSERT_SYMBOL_PRESENT(fGenTransformFeedbacks);
2796
0
        mSymbols.fGenTransformFeedbacks(n, ids);
2797
0
        OnSyncCall();
2798
0
        AFTER_GL_CALL;
2799
0
    }
2800
2801
    void fDeleteTransformFeedbacks(GLsizei n, const GLuint* ids)
2802
0
    {
2803
0
        BEFORE_GL_CALL;
2804
0
        ASSERT_SYMBOL_PRESENT(fDeleteTransformFeedbacks);
2805
0
        mSymbols.fDeleteTransformFeedbacks(n, ids);
2806
0
        AFTER_GL_CALL;
2807
0
    }
2808
2809
    realGLboolean fIsTransformFeedback(GLuint id)
2810
0
    {
2811
0
        realGLboolean result = false;
2812
0
        BEFORE_GL_CALL;
2813
0
        ASSERT_SYMBOL_PRESENT(fIsTransformFeedback);
2814
0
        result = mSymbols.fIsTransformFeedback(id);
2815
0
        OnSyncCall();
2816
0
        AFTER_GL_CALL;
2817
0
        return result;
2818
0
    }
2819
2820
    void fBindTransformFeedback(GLenum target, GLuint id)
2821
0
    {
2822
0
        BEFORE_GL_CALL;
2823
0
        ASSERT_SYMBOL_PRESENT(fBindTransformFeedback);
2824
0
        mSymbols.fBindTransformFeedback(target, id);
2825
0
        AFTER_GL_CALL;
2826
0
    }
2827
2828
    void fBeginTransformFeedback(GLenum primitiveMode)
2829
0
    {
2830
0
        BEFORE_GL_CALL;
2831
0
        ASSERT_SYMBOL_PRESENT(fBeginTransformFeedback);
2832
0
        mSymbols.fBeginTransformFeedback(primitiveMode);
2833
0
        AFTER_GL_CALL;
2834
0
    }
2835
2836
    void fEndTransformFeedback()
2837
0
    {
2838
0
        BEFORE_GL_CALL;
2839
0
        ASSERT_SYMBOL_PRESENT(fEndTransformFeedback);
2840
0
        mSymbols.fEndTransformFeedback();
2841
0
        AFTER_GL_CALL;
2842
0
    }
2843
2844
    void fTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
2845
0
    {
2846
0
        BEFORE_GL_CALL;
2847
0
        ASSERT_SYMBOL_PRESENT(fTransformFeedbackVaryings);
2848
0
        mSymbols.fTransformFeedbackVaryings(program, count, varyings, bufferMode);
2849
0
        AFTER_GL_CALL;
2850
0
    }
2851
2852
    void fGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
2853
0
    {
2854
0
        BEFORE_GL_CALL;
2855
0
        ASSERT_SYMBOL_PRESENT(fGetTransformFeedbackVarying);
2856
0
        mSymbols.fGetTransformFeedbackVarying(program, index, bufSize, length, size, type, name);
2857
0
        OnSyncCall();
2858
0
        AFTER_GL_CALL;
2859
0
    }
2860
2861
    void fPauseTransformFeedback()
2862
0
    {
2863
0
        BEFORE_GL_CALL;
2864
0
        ASSERT_SYMBOL_PRESENT(fPauseTransformFeedback);
2865
0
        mSymbols.fPauseTransformFeedback();
2866
0
        AFTER_GL_CALL;
2867
0
    }
2868
2869
    void fResumeTransformFeedback()
2870
0
    {
2871
0
        BEFORE_GL_CALL;
2872
0
        ASSERT_SYMBOL_PRESENT(fResumeTransformFeedback);
2873
0
        mSymbols.fResumeTransformFeedback();
2874
0
        AFTER_GL_CALL;
2875
0
    }
2876
2877
    void fGetIntegeri_v(GLenum param, GLuint index, GLint* values)
2878
0
    {
2879
0
        BEFORE_GL_CALL;
2880
0
        ASSERT_SYMBOL_PRESENT(fGetIntegeri_v);
2881
0
        mSymbols.fGetIntegeri_v(param, index, values);
2882
0
        OnSyncCall();
2883
0
        AFTER_GL_CALL;
2884
0
    }
2885
2886
0
    void fGetInteger64i_v(GLenum target, GLuint index, GLint64* data) {
2887
0
        ASSERT_SYMBOL_PRESENT(fGetInteger64i_v);
2888
0
        BEFORE_GL_CALL;
2889
0
        mSymbols.fGetInteger64i_v(target, index, data);
2890
0
        OnSyncCall();
2891
0
        AFTER_GL_CALL;
2892
0
    }
2893
2894
// -----------------------------------------------------------------------------
2895
// Package XXX_vertex_array_object
2896
public:
2897
    void fBindVertexArray(GLuint array)
2898
0
    {
2899
0
        BEFORE_GL_CALL;
2900
0
        ASSERT_SYMBOL_PRESENT(fBindVertexArray);
2901
0
        mSymbols.fBindVertexArray(array);
2902
0
        AFTER_GL_CALL;
2903
0
    }
2904
2905
    void fDeleteVertexArrays(GLsizei n, const GLuint* arrays)
2906
0
    {
2907
0
        BEFORE_GL_CALL;
2908
0
        ASSERT_SYMBOL_PRESENT(fDeleteVertexArrays);
2909
0
        mSymbols.fDeleteVertexArrays(n, arrays);
2910
0
        AFTER_GL_CALL;
2911
0
    }
2912
2913
    void fGenVertexArrays(GLsizei n, GLuint* arrays)
2914
0
    {
2915
0
        BEFORE_GL_CALL;
2916
0
        ASSERT_SYMBOL_PRESENT(fGenVertexArrays);
2917
0
        mSymbols.fGenVertexArrays(n, arrays);
2918
0
        AFTER_GL_CALL;
2919
0
    }
2920
2921
    realGLboolean fIsVertexArray(GLuint array)
2922
0
    {
2923
0
        realGLboolean ret = false;
2924
0
        BEFORE_GL_CALL;
2925
0
        ASSERT_SYMBOL_PRESENT(fIsVertexArray);
2926
0
        ret = mSymbols.fIsVertexArray(array);
2927
0
        OnSyncCall();
2928
0
        AFTER_GL_CALL;
2929
0
        return ret;
2930
0
    }
2931
2932
// -----------------------------------------------------------------------------
2933
// Extension NV_fence
2934
public:
2935
    void fGenFences(GLsizei n, GLuint* fences)
2936
0
    {
2937
0
        ASSERT_SYMBOL_PRESENT(fGenFences);
2938
0
        BEFORE_GL_CALL;
2939
0
        mSymbols.fGenFences(n, fences);
2940
0
        AFTER_GL_CALL;
2941
0
    }
2942
2943
    void fDeleteFences(GLsizei n, const GLuint* fences)
2944
0
    {
2945
0
        ASSERT_SYMBOL_PRESENT(fDeleteFences);
2946
0
        BEFORE_GL_CALL;
2947
0
        mSymbols.fDeleteFences(n, fences);
2948
0
        AFTER_GL_CALL;
2949
0
    }
2950
2951
    void fSetFence(GLuint fence, GLenum condition)
2952
0
    {
2953
0
        ASSERT_SYMBOL_PRESENT(fSetFence);
2954
0
        BEFORE_GL_CALL;
2955
0
        mSymbols.fSetFence(fence, condition);
2956
0
        AFTER_GL_CALL;
2957
0
    }
2958
2959
    realGLboolean fTestFence(GLuint fence)
2960
0
    {
2961
0
        realGLboolean ret = false;
2962
0
        ASSERT_SYMBOL_PRESENT(fTestFence);
2963
0
        BEFORE_GL_CALL;
2964
0
        ret = mSymbols.fTestFence(fence);
2965
0
        OnSyncCall();
2966
0
        AFTER_GL_CALL;
2967
0
        return ret;
2968
0
    }
2969
2970
    void fFinishFence(GLuint fence)
2971
0
    {
2972
0
        ASSERT_SYMBOL_PRESENT(fFinishFence);
2973
0
        BEFORE_GL_CALL;
2974
0
        mSymbols.fFinishFence(fence);
2975
0
        OnSyncCall();
2976
0
        AFTER_GL_CALL;
2977
0
    }
2978
2979
    realGLboolean fIsFence(GLuint fence)
2980
0
    {
2981
0
        realGLboolean ret = false;
2982
0
        ASSERT_SYMBOL_PRESENT(fIsFence);
2983
0
        BEFORE_GL_CALL;
2984
0
        ret = mSymbols.fIsFence(fence);
2985
0
        OnSyncCall();
2986
0
        AFTER_GL_CALL;
2987
0
        return ret;
2988
0
    }
2989
2990
    void fGetFenceiv(GLuint fence, GLenum pname, GLint* params)
2991
0
    {
2992
0
        ASSERT_SYMBOL_PRESENT(fGetFenceiv);
2993
0
        BEFORE_GL_CALL;
2994
0
        mSymbols.fGetFenceiv(fence, pname, params);
2995
0
        OnSyncCall();
2996
0
        AFTER_GL_CALL;
2997
0
    }
2998
2999
// -----------------------------------------------------------------------------
3000
// Extension NV_texture_barrier
3001
public:
3002
    void fTextureBarrier()
3003
    {
3004
        ASSERT_SYMBOL_PRESENT(fTextureBarrier);
3005
        BEFORE_GL_CALL;
3006
        mSymbols.fTextureBarrier();
3007
        AFTER_GL_CALL;
3008
    }
3009
3010
// Core GL & Extension ARB_copy_buffer
3011
public:
3012
    void fCopyBufferSubData(GLenum readtarget, GLenum writetarget,
3013
                            GLintptr readoffset, GLintptr writeoffset,
3014
                            GLsizeiptr size)
3015
0
    {
3016
0
        BEFORE_GL_CALL;
3017
0
        ASSERT_SYMBOL_PRESENT(fCopyBufferSubData);
3018
0
        mSymbols.fCopyBufferSubData(readtarget, writetarget, readoffset, writeoffset, size);
3019
0
        AFTER_GL_CALL;
3020
0
    }
3021
3022
3023
// -----------------------------------------------------------------------------
3024
// Core GL & Extension ARB_map_buffer_range
3025
public:
3026
    void* fMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
3027
                          GLbitfield access)
3028
0
    {
3029
0
        void* data = nullptr;
3030
0
        ASSERT_SYMBOL_PRESENT(fMapBufferRange);
3031
0
        BEFORE_GL_CALL;
3032
0
        data = mSymbols.fMapBufferRange(target, offset, length, access);
3033
0
        OnSyncCall();
3034
0
        AFTER_GL_CALL;
3035
0
        return data;
3036
0
    }
3037
3038
0
    void fFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) {
3039
0
        ASSERT_SYMBOL_PRESENT(fFlushMappedBufferRange);
3040
0
        BEFORE_GL_CALL;
3041
0
        mSymbols.fFlushMappedBufferRange(target, offset, length);
3042
0
        AFTER_GL_CALL;
3043
0
    }
3044
3045
3046
// -----------------------------------------------------------------------------
3047
// Core GL & Extension ARB_sampler_objects
3048
public:
3049
    void fGenSamplers(GLsizei count, GLuint* samplers)
3050
0
    {
3051
0
        BEFORE_GL_CALL;
3052
0
        ASSERT_SYMBOL_PRESENT(fGenSamplers);
3053
0
        mSymbols.fGenSamplers(count, samplers);
3054
0
        AFTER_GL_CALL;
3055
0
    }
3056
3057
    void fDeleteSamplers(GLsizei count, const GLuint* samplers)
3058
0
    {
3059
0
        BEFORE_GL_CALL;
3060
0
        ASSERT_SYMBOL_PRESENT(fDeleteSamplers);
3061
0
        mSymbols.fDeleteSamplers(count, samplers);
3062
0
        AFTER_GL_CALL;
3063
0
    }
3064
3065
    realGLboolean fIsSampler(GLuint sampler)
3066
0
    {
3067
0
        realGLboolean result = false;
3068
0
        BEFORE_GL_CALL;
3069
0
        ASSERT_SYMBOL_PRESENT(fIsSampler);
3070
0
        result = mSymbols.fIsSampler(sampler);
3071
0
        OnSyncCall();
3072
0
        AFTER_GL_CALL;
3073
0
        return result;
3074
0
    }
3075
3076
    void fBindSampler(GLuint unit, GLuint sampler)
3077
    {
3078
        BEFORE_GL_CALL;
3079
        ASSERT_SYMBOL_PRESENT(fBindSampler);
3080
        mSymbols.fBindSampler(unit, sampler);
3081
        AFTER_GL_CALL;
3082
    }
3083
3084
    void fSamplerParameteri(GLuint sampler, GLenum pname, GLint param)
3085
0
    {
3086
0
        BEFORE_GL_CALL;
3087
0
        ASSERT_SYMBOL_PRESENT(fSamplerParameteri);
3088
0
        mSymbols.fSamplerParameteri(sampler, pname, param);
3089
0
        AFTER_GL_CALL;
3090
0
    }
3091
3092
    void fSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param)
3093
0
    {
3094
0
        BEFORE_GL_CALL;
3095
0
        ASSERT_SYMBOL_PRESENT(fSamplerParameteriv);
3096
0
        mSymbols.fSamplerParameteriv(sampler, pname, param);
3097
0
        AFTER_GL_CALL;
3098
0
    }
3099
3100
    void fSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
3101
0
    {
3102
0
        BEFORE_GL_CALL;
3103
0
        ASSERT_SYMBOL_PRESENT(fSamplerParameterf);
3104
0
        mSymbols.fSamplerParameterf(sampler, pname, param);
3105
0
        AFTER_GL_CALL;
3106
0
    }
3107
3108
    void fSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param)
3109
0
    {
3110
0
        BEFORE_GL_CALL;
3111
0
        ASSERT_SYMBOL_PRESENT(fSamplerParameterfv);
3112
0
        mSymbols.fSamplerParameterfv(sampler, pname, param);
3113
0
        AFTER_GL_CALL;
3114
0
    }
3115
3116
    void fGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params)
3117
0
    {
3118
0
        BEFORE_GL_CALL;
3119
0
        ASSERT_SYMBOL_PRESENT(fGetSamplerParameteriv);
3120
0
        mSymbols.fGetSamplerParameteriv(sampler, pname, params);
3121
0
        AFTER_GL_CALL;
3122
0
    }
3123
3124
    void fGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params)
3125
0
    {
3126
0
        BEFORE_GL_CALL;
3127
0
        ASSERT_SYMBOL_PRESENT(fGetSamplerParameterfv);
3128
0
        mSymbols.fGetSamplerParameterfv(sampler, pname, params);
3129
0
        AFTER_GL_CALL;
3130
0
    }
3131
3132
3133
// -----------------------------------------------------------------------------
3134
// Core GL & Extension ARB_uniform_buffer_object
3135
public:
3136
    void fGetUniformIndices(GLuint program, GLsizei uniformCount,
3137
                            const GLchar* const* uniformNames, GLuint* uniformIndices)
3138
0
    {
3139
0
        ASSERT_SYMBOL_PRESENT(fGetUniformIndices);
3140
0
        BEFORE_GL_CALL;
3141
0
        mSymbols.fGetUniformIndices(program, uniformCount, uniformNames, uniformIndices);
3142
0
        OnSyncCall();
3143
0
        AFTER_GL_CALL;
3144
0
    }
3145
3146
    void fGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices,
3147
                              GLenum pname, GLint* params)
3148
0
    {
3149
0
        ASSERT_SYMBOL_PRESENT(fGetActiveUniformsiv);
3150
0
        BEFORE_GL_CALL;
3151
0
        mSymbols.fGetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params);
3152
0
        OnSyncCall();
3153
0
        AFTER_GL_CALL;
3154
0
    }
3155
3156
0
    GLuint fGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) {
3157
0
        GLuint result = 0;
3158
0
        ASSERT_SYMBOL_PRESENT(fGetUniformBlockIndex);
3159
0
        BEFORE_GL_CALL;
3160
0
        result = mSymbols.fGetUniformBlockIndex(program, uniformBlockName);
3161
0
        OnSyncCall();
3162
0
        AFTER_GL_CALL;
3163
0
        return result;
3164
0
    }
3165
3166
    void fGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex,
3167
                                  GLenum pname, GLint* params)
3168
0
    {
3169
0
        ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockiv);
3170
0
        BEFORE_GL_CALL;
3171
0
        mSymbols.fGetActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
3172
0
        OnSyncCall();
3173
0
        AFTER_GL_CALL;
3174
0
    }
3175
3176
    void fGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize,
3177
                                    GLsizei* length, GLchar* uniformBlockName)
3178
0
    {
3179
0
        ASSERT_SYMBOL_PRESENT(fGetActiveUniformBlockName);
3180
0
        BEFORE_GL_CALL;
3181
0
        mSymbols.fGetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName);
3182
0
        OnSyncCall();
3183
0
        AFTER_GL_CALL;
3184
0
    }
3185
3186
0
    void fUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) {
3187
0
        ASSERT_SYMBOL_PRESENT(fUniformBlockBinding);
3188
0
        BEFORE_GL_CALL;
3189
0
        mSymbols.fUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
3190
0
        AFTER_GL_CALL;
3191
0
    }
3192
3193
// -----------------------------------------------------------------------------
3194
// Core GL 4.2, GL ES 3.0 & Extension ARB_texture_storage/EXT_texture_storage
3195
    void fTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
3196
0
    {
3197
0
        BEFORE_GL_CALL;
3198
0
        ASSERT_SYMBOL_PRESENT(fTexStorage2D);
3199
0
        mSymbols.fTexStorage2D(target, levels, internalformat, width, height);
3200
0
        OnSyncCall();
3201
0
        AFTER_GL_CALL;
3202
0
    }
3203
3204
    void fTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
3205
0
    {
3206
0
        BEFORE_GL_CALL;
3207
0
        ASSERT_SYMBOL_PRESENT(fTexStorage3D);
3208
0
        mSymbols.fTexStorage3D(target, levels, internalformat, width, height, depth);
3209
0
        OnSyncCall();
3210
0
        AFTER_GL_CALL;
3211
0
    }
3212
3213
// -----------------------------------------------------------------------------
3214
// 3D Textures
3215
    void fTexImage3D(GLenum target, GLint level,
3216
                     GLint internalFormat,
3217
                     GLsizei width, GLsizei height, GLsizei depth,
3218
                     GLint border, GLenum format, GLenum type,
3219
                     const GLvoid * data)
3220
0
    {
3221
0
        BEFORE_GL_CALL;
3222
0
        ASSERT_SYMBOL_PRESENT(fTexImage3D);
3223
0
        mSymbols.fTexImage3D(target, level, internalFormat,
3224
0
                             width, height, depth,
3225
0
                             border, format, type,
3226
0
                             data);
3227
0
        OnSyncCall();
3228
0
        AFTER_GL_CALL;
3229
0
    }
3230
3231
    void fTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
3232
                        GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
3233
                        GLenum format, GLenum type, const GLvoid* pixels)
3234
0
    {
3235
0
        BEFORE_GL_CALL;
3236
0
        ASSERT_SYMBOL_PRESENT(fTexSubImage3D);
3237
0
        mSymbols.fTexSubImage3D(target, level, xoffset, yoffset, zoffset,
3238
0
                                width, height, depth, format, type,
3239
0
                                pixels);
3240
0
        OnSyncCall();
3241
0
        AFTER_GL_CALL;
3242
0
    }
3243
3244
    void fCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset,
3245
                            GLint yoffset, GLint zoffset, GLint x,
3246
                            GLint y, GLsizei width, GLsizei height)
3247
0
    {
3248
0
        BeforeGLReadCall();
3249
0
        BEFORE_GL_CALL;
3250
0
        ASSERT_SYMBOL_PRESENT(fCopyTexSubImage3D);
3251
0
        mSymbols.fCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset,
3252
0
                                    x, y, width, height);
3253
0
        AFTER_GL_CALL;
3254
0
        AfterGLReadCall();
3255
0
    }
3256
3257
    void fCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat,
3258
                               GLsizei width, GLsizei height, GLsizei depth,
3259
                               GLint border, GLsizei imageSize, const GLvoid* data)
3260
0
    {
3261
0
        BEFORE_GL_CALL;
3262
0
        ASSERT_SYMBOL_PRESENT(fCompressedTexImage3D);
3263
0
        mSymbols.fCompressedTexImage3D(target, level, internalformat,
3264
0
                                       width, height, depth,
3265
0
                                       border, imageSize, data);
3266
0
        AFTER_GL_CALL;
3267
0
    }
3268
3269
    void fCompressedTexSubImage3D(GLenum target, GLint level,
3270
                                  GLint xoffset, GLint yoffset, GLint zoffset,
3271
                                  GLsizei width, GLsizei height, GLsizei depth,
3272
                                  GLenum format, GLsizei imageSize, const GLvoid* data)
3273
0
    {
3274
0
        BEFORE_GL_CALL;
3275
0
        ASSERT_SYMBOL_PRESENT(fCompressedTexSubImage3D);
3276
0
        mSymbols.fCompressedTexSubImage3D(target, level,
3277
0
                                          xoffset, yoffset, zoffset,
3278
0
                                          width, height, depth,
3279
0
                                          format, imageSize, data);
3280
0
        AFTER_GL_CALL;
3281
0
    }
3282
3283
// -----------------------------------------------------------------------------
3284
// GL3+, ES3+
3285
3286
    const GLubyte* fGetStringi(GLenum name, GLuint index) {
3287
        const GLubyte* ret = nullptr;
3288
        BEFORE_GL_CALL;
3289
        ASSERT_SYMBOL_PRESENT(fGetStringi);
3290
        ret = mSymbols.fGetStringi(name, index);
3291
        OnSyncCall();
3292
        AFTER_GL_CALL;
3293
        return ret;
3294
    }
3295
3296
// -----------------------------------------------------------------------------
3297
// APPLE_framebuffer_multisample
3298
3299
    void fResolveMultisampleFramebufferAPPLE() {
3300
        BEFORE_GL_CALL;
3301
        ASSERT_SYMBOL_PRESENT(fResolveMultisampleFramebufferAPPLE);
3302
        mSymbols.fResolveMultisampleFramebufferAPPLE();
3303
        AFTER_GL_CALL;
3304
    }
3305
3306
// -----------------------------------------------------------------------------
3307
// APPLE_fence
3308
3309
    void fFinishObjectAPPLE(GLenum object, GLint name) {
3310
        BEFORE_GL_CALL;
3311
        ASSERT_SYMBOL_PRESENT(fFinishObjectAPPLE);
3312
        mSymbols.fFinishObjectAPPLE(object, name);
3313
        AFTER_GL_CALL;
3314
    }
3315
3316
    realGLboolean fTestObjectAPPLE(GLenum object, GLint name) {
3317
        realGLboolean ret = false;
3318
        BEFORE_GL_CALL;
3319
        ASSERT_SYMBOL_PRESENT(fTestObjectAPPLE);
3320
        ret = mSymbols.fTestObjectAPPLE(object, name);
3321
        AFTER_GL_CALL;
3322
        return ret;
3323
    }
3324
3325
// -----------------------------------------------------------------------------
3326
// prim_restart
3327
3328
0
    void fPrimitiveRestartIndex(GLuint index) {
3329
0
        BEFORE_GL_CALL;
3330
0
        ASSERT_SYMBOL_PRESENT(fPrimitiveRestartIndex);
3331
0
        mSymbols.fPrimitiveRestartIndex(index);
3332
0
        AFTER_GL_CALL;
3333
0
    }
3334
3335
#undef BEFORE_GL_CALL
3336
#undef AFTER_GL_CALL
3337
#undef ASSERT_SYMBOL_PRESENT
3338
// #undef TRACKING_CONTEXT // Needed in GLContext.cpp
3339
#undef ASSERT_NOT_PASSING_STACK_BUFFER_TO_GL
3340
3341
// -----------------------------------------------------------------------------
3342
// Constructor
3343
protected:
3344
    explicit GLContext(CreateContextFlags flags, const SurfaceCaps& caps,
3345
                       GLContext* sharedContext = nullptr,
3346
                       bool isOffscreen = false, bool canUseTLSIsCurrent = false);
3347
3348
3349
// -----------------------------------------------------------------------------
3350
// Destructor
3351
public:
3352
    virtual ~GLContext();
3353
3354
    // Mark this context as destroyed.  This will nullptr out all
3355
    // the GL function pointers!
3356
    void MarkDestroyed();
3357
3358
// -----------------------------------------------------------------------------
3359
// Everything that isn't standard GL APIs
3360
protected:
3361
    typedef gfx::SurfaceFormat SurfaceFormat;
3362
3363
public:
3364
    virtual bool Init() = 0;
3365
3366
    virtual bool SetupLookupFunction() = 0;
3367
3368
0
    virtual void ReleaseSurface() {}
3369
3370
    bool IsDestroyed() const {
3371
        // MarkDestroyed will mark all these as null.
3372
        return mSymbols.fUseProgram == nullptr;
3373
    }
3374
3375
    GLContext* GetSharedContext() { return mSharedContext; }
3376
3377
    /**
3378
     * Returns true if the thread on which this context was created is the currently
3379
     * executing thread.
3380
     */
3381
    bool IsOwningThreadCurrent();
3382
3383
    static void PlatformStartup();
3384
3385
public:
3386
    /**
3387
     * If this context wraps a double-buffered target, swap the back
3388
     * and front buffers.  It should be assumed that after a swap, the
3389
     * contents of the new back buffer are undefined.
3390
     */
3391
    virtual bool SwapBuffers() { return false; }
3392
3393
    /**
3394
     * Defines a two-dimensional texture image for context target surface
3395
     */
3396
0
    virtual bool BindTexImage() { return false; }
3397
    /*
3398
     * Releases a color buffer that is being used as a texture
3399
     */
3400
0
    virtual bool ReleaseTexImage() { return false; }
3401
3402
    // Before reads from offscreen texture
3403
    void GuaranteeResolve();
3404
3405
    /*
3406
     * Resize the current offscreen buffer.  Returns true on success.
3407
     * If it returns false, the context should be treated as unusable
3408
     * and should be recreated.  After the resize, the viewport is not
3409
     * changed; glViewport should be called as appropriate.
3410
     *
3411
     * Only valid if IsOffscreen() returns true.
3412
     */
3413
0
    bool ResizeOffscreen(const gfx::IntSize& size) {
3414
0
        return ResizeScreenBuffer(size);
3415
0
    }
3416
3417
    /*
3418
     * Return size of this offscreen context.
3419
     *
3420
     * Only valid if IsOffscreen() returns true.
3421
     */
3422
    const gfx::IntSize& OffscreenSize() const;
3423
3424
    void BindFB(GLuint fb) {
3425
        fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
3426
        MOZ_ASSERT(!fb || fIsFramebuffer(fb));
3427
    }
3428
3429
0
    void BindDrawFB(GLuint fb) {
3430
0
        fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb);
3431
0
    }
3432
3433
0
    void BindReadFB(GLuint fb) {
3434
0
        fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb);
3435
0
    }
3436
3437
    GLuint GetDrawFB();
3438
3439
    GLuint GetReadFB();
3440
3441
    GLuint GetFB();
3442
3443
private:
3444
0
    void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
3445
0
        switch (precisiontype) {
3446
0
            case LOCAL_GL_LOW_FLOAT:
3447
0
            case LOCAL_GL_MEDIUM_FLOAT:
3448
0
            case LOCAL_GL_HIGH_FLOAT:
3449
0
                // Assume IEEE 754 precision
3450
0
                range[0] = 127;
3451
0
                range[1] = 127;
3452
0
                *precision = 23;
3453
0
                break;
3454
0
            case LOCAL_GL_LOW_INT:
3455
0
            case LOCAL_GL_MEDIUM_INT:
3456
0
            case LOCAL_GL_HIGH_INT:
3457
0
                // Some (most) hardware only supports single-precision floating-point numbers,
3458
0
                // which can accurately represent integers up to +/-16777216
3459
0
                range[0] = 24;
3460
0
                range[1] = 24;
3461
0
                *precision = 0;
3462
0
                break;
3463
0
        }
3464
0
    }
3465
3466
public:
3467
3468
    void ForceDirtyScreen();
3469
    void CleanDirtyScreen();
3470
3471
0
    virtual GLenum GetPreferredARGB32Format() const { return LOCAL_GL_RGBA; }
3472
3473
0
    virtual GLenum GetPreferredEGLImageTextureTarget() const {
3474
0
        return IsExtensionSupported(OES_EGL_image_external) ?
3475
0
            LOCAL_GL_TEXTURE_EXTERNAL : LOCAL_GL_TEXTURE_2D;
3476
0
    }
3477
3478
0
    virtual bool RenewSurface(widget::CompositorWidget* aWidget) { return false; }
3479
3480
    // Shared code for GL extensions and GLX extensions.
3481
    static bool ListHasExtension(const GLubyte* extensions,
3482
                                 const char* extension);
3483
3484
0
    GLint GetMaxTextureImageSize() { return mMaxTextureImageSize; }
3485
3486
public:
3487
    std::map<GLuint, SharedSurface*> mFBOMapping;
3488
3489
    enum {
3490
        DebugFlagEnabled = 1 << 0,
3491
        DebugFlagTrace = 1 << 1,
3492
        DebugFlagAbortOnError = 1 << 2
3493
    };
3494
3495
    const uint8_t mDebugFlags;
3496
    static uint8_t ChooseDebugFlags(CreateContextFlags createFlags);
3497
3498
protected:
3499
    RefPtr<GLContext> mSharedContext;
3500
3501
    // The thread id which this context was created.
3502
    PlatformThreadId mOwningThreadId;
3503
3504
    GLContextSymbols mSymbols = {};
3505
3506
    UniquePtr<GLBlitHelper> mBlitHelper;
3507
    UniquePtr<GLReadTexImageHelper> mReadTexImageHelper;
3508
3509
public:
3510
    GLBlitHelper* BlitHelper();
3511
    GLBlitTextureImageHelper* BlitTextureImageHelper();
3512
    GLReadTexImageHelper* ReadTexImageHelper();
3513
3514
    // Assumes shares are created by all sharing with the same global context.
3515
0
    bool SharesWith(const GLContext* other) const {
3516
0
        MOZ_ASSERT(!this->mSharedContext || !this->mSharedContext->mSharedContext);
3517
0
        MOZ_ASSERT(!other->mSharedContext || !other->mSharedContext->mSharedContext);
3518
0
        MOZ_ASSERT(!this->mSharedContext ||
3519
0
                   !other->mSharedContext ||
3520
0
                   this->mSharedContext == other->mSharedContext);
3521
0
3522
0
        const GLContext* thisShared = this->mSharedContext ? this->mSharedContext
3523
0
                                                           : this;
3524
0
        const GLContext* otherShared = other->mSharedContext ? other->mSharedContext
3525
0
                                                             : other;
3526
0
3527
0
        return thisShared == otherShared;
3528
0
    }
3529
3530
    bool InitOffscreen(const gfx::IntSize& size, const SurfaceCaps& caps);
3531
3532
protected:
3533
    // Note that it does -not- clear the resized buffers.
3534
    bool CreateScreenBuffer(const gfx::IntSize& size, const SurfaceCaps& caps) {
3535
        if (!IsOffscreenSizeAllowed(size))
3536
            return false;
3537
3538
       return CreateScreenBufferImpl(size, caps);
3539
    }
3540
3541
    bool CreateScreenBufferImpl(const gfx::IntSize& size,
3542
                                const SurfaceCaps& caps);
3543
3544
public:
3545
    bool ResizeScreenBuffer(const gfx::IntSize& size);
3546
3547
protected:
3548
    SurfaceCaps mCaps;
3549
3550
public:
3551
    const SurfaceCaps& Caps() const {
3552
        return mCaps;
3553
    }
3554
3555
    // Only varies based on bpp16 and alpha.
3556
    GLFormats ChooseGLFormats(const SurfaceCaps& caps) const;
3557
3558
    bool IsFramebufferComplete(GLuint fb, GLenum* status = nullptr);
3559
3560
    // Does not check completeness.
3561
    void AttachBuffersToFB(GLuint colorTex, GLuint colorRB,
3562
                           GLuint depthRB, GLuint stencilRB,
3563
                           GLuint fb, GLenum target = LOCAL_GL_TEXTURE_2D);
3564
3565
    // Passing null is fine if the value you'd get is 0.
3566
    bool AssembleOffscreenFBs(const GLuint colorMSRB,
3567
                              const GLuint depthRB,
3568
                              const GLuint stencilRB,
3569
                              const GLuint texture,
3570
                              GLuint* drawFB,
3571
                              GLuint* readFB);
3572
3573
protected:
3574
    friend class GLScreenBuffer;
3575
    UniquePtr<GLScreenBuffer> mScreen;
3576
3577
    SharedSurface* mLockedSurface = nullptr;
3578
3579
public:
3580
0
    void LockSurface(SharedSurface* surf) {
3581
0
        MOZ_ASSERT(!mLockedSurface);
3582
0
        mLockedSurface = surf;
3583
0
    }
3584
3585
0
    void UnlockSurface(SharedSurface* surf) {
3586
0
        MOZ_ASSERT(mLockedSurface == surf);
3587
0
        mLockedSurface = nullptr;
3588
0
    }
3589
3590
    SharedSurface* GetLockedSurface() const {
3591
        return mLockedSurface;
3592
    }
3593
3594
0
    bool IsOffscreen() const {
3595
0
        return mIsOffscreen;
3596
0
    }
3597
3598
0
    GLScreenBuffer* Screen() const {
3599
0
        return mScreen.get();
3600
0
    }
3601
3602
0
    bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
3603
3604
    bool IsDrawingToDefaultFramebuffer();
3605
3606
    bool IsOffscreenSizeAllowed(const gfx::IntSize& aSize) const;
3607
3608
protected:
3609
    bool InitWithPrefix(const char* prefix, bool trygl);
3610
3611
private:
3612
    bool InitWithPrefixImpl(const char* prefix, bool trygl);
3613
    void LoadMoreSymbols(const char* prefix, bool trygl);
3614
    bool LoadExtSymbols(const char* prefix, bool trygl, const SymLoadStruct* list,
3615
                        GLExtensions ext);
3616
    bool LoadFeatureSymbols(const char* prefix, bool trygl, const SymLoadStruct* list,
3617
                            GLFeature feature);
3618
3619
protected:
3620
    void InitExtensions();
3621
3622
    GLint mViewportRect[4] = {};
3623
    GLint mScissorRect[4] = {};
3624
3625
    uint32_t mMaxTexOrRbSize = 0;
3626
    GLint mMaxTextureSize = 0;
3627
    GLint mMaxCubeMapTextureSize = 0;
3628
    GLint mMaxTextureImageSize = 0;
3629
    GLint mMaxRenderbufferSize = 0;
3630
    GLint mMaxViewportDims[2] = {};
3631
    GLsizei mMaxSamples = 0;
3632
    bool mNeedsTextureSizeChecks = false;
3633
    bool mNeedsFlushBeforeDeleteFB = false;
3634
    bool mTextureAllocCrashesOnMapFailure = false;
3635
    bool mNeedsCheckAfterAttachTextureToFb = false;
3636
    bool mWorkAroundDriverBugs = true;
3637
    mutable uint64_t mSyncGLCallCount = 0;
3638
3639
    bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const {
3640
        if (mNeedsTextureSizeChecks) {
3641
            // some drivers incorrectly handle some large texture sizes that are below the
3642
            // max texture size that they report. So we check ourselves against our own values
3643
            // (mMax[CubeMap]TextureSize).
3644
            // see bug 737182 for Mac Intel 2D textures
3645
            // see bug 684882 for Mac Intel cube map textures
3646
            // see bug 814716 for Mesa Nouveau
3647
            GLsizei maxSize = target == LOCAL_GL_TEXTURE_CUBE_MAP ||
3648
                                (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
3649
                                target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
3650
                              ? mMaxCubeMapTextureSize
3651
                              : mMaxTextureSize;
3652
            return width <= maxSize && height <= maxSize;
3653
        }
3654
        return true;
3655
    }
3656
3657
public:
3658
0
    auto MaxSamples() const { return uint32_t(mMaxSamples); }
3659
0
    auto MaxTextureSize() const { return uint32_t(mMaxTextureSize); }
3660
0
    auto MaxRenderbufferSize() const { return uint32_t(mMaxRenderbufferSize); }
3661
0
    auto MaxTexOrRbSize() const { return mMaxTexOrRbSize; }
3662
3663
#ifdef MOZ_GL_DEBUG
3664
    void CreatedProgram(GLContext* aOrigin, GLuint aName);
3665
    void CreatedShader(GLContext* aOrigin, GLuint aName);
3666
    void CreatedBuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3667
    void CreatedQueries(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3668
    void CreatedTextures(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3669
    void CreatedFramebuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3670
    void CreatedRenderbuffers(GLContext* aOrigin, GLsizei aCount, GLuint* aNames);
3671
    void DeletedProgram(GLContext* aOrigin, GLuint aName);
3672
    void DeletedShader(GLContext* aOrigin, GLuint aName);
3673
    void DeletedBuffers(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
3674
    void DeletedQueries(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
3675
    void DeletedTextures(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
3676
    void DeletedFramebuffers(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
3677
    void DeletedRenderbuffers(GLContext* aOrigin, GLsizei aCount, const GLuint* aNames);
3678
3679
    void SharedContextDestroyed(GLContext* aChild);
3680
    void ReportOutstandingNames();
3681
3682
    struct NamedResource {
3683
        NamedResource()
3684
            : origin(nullptr), name(0), originDeleted(false)
3685
        { }
3686
3687
        NamedResource(GLContext* aOrigin, GLuint aName)
3688
            : origin(aOrigin), name(aName), originDeleted(false)
3689
        { }
3690
3691
        GLContext* origin;
3692
        GLuint name;
3693
        bool originDeleted;
3694
3695
        // for sorting
3696
        bool operator<(const NamedResource& aOther) const {
3697
            if (intptr_t(origin) < intptr_t(aOther.origin))
3698
                return true;
3699
            if (name < aOther.name)
3700
                return true;
3701
            return false;
3702
        }
3703
        bool operator==(const NamedResource& aOther) const {
3704
            return origin == aOther.origin &&
3705
                name == aOther.name &&
3706
                originDeleted == aOther.originDeleted;
3707
        }
3708
    };
3709
3710
    nsTArray<NamedResource> mTrackedPrograms;
3711
    nsTArray<NamedResource> mTrackedShaders;
3712
    nsTArray<NamedResource> mTrackedTextures;
3713
    nsTArray<NamedResource> mTrackedFramebuffers;
3714
    nsTArray<NamedResource> mTrackedRenderbuffers;
3715
    nsTArray<NamedResource> mTrackedBuffers;
3716
    nsTArray<NamedResource> mTrackedQueries;
3717
#endif
3718
3719
3720
protected:
3721
    bool mHeavyGLCallsSinceLastFlush = false;
3722
3723
public:
3724
    void FlushIfHeavyGLCallsSinceLastFlush();
3725
    static bool ShouldSpew();
3726
    static bool ShouldDumpExts();
3727
    bool Readback(SharedSurface* src, gfx::DataSourceSurface* dest);
3728
3729
    // --
3730
3731
    void TexParams_SetClampNoMips(GLenum target = LOCAL_GL_TEXTURE_2D) {
3732
        fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
3733
        fTexParameteri(target, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
3734
        fTexParameteri(target, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
3735
        fTexParameteri(target, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
3736
    }
3737
3738
    // --
3739
3740
0
    GLuint CreateFramebuffer() {
3741
0
        GLuint x = 0;
3742
0
        fGenFramebuffers(1, &x);
3743
0
        return x;
3744
0
    }
3745
0
    GLuint CreateRenderbuffer() {
3746
0
        GLuint x = 0;
3747
0
        fGenRenderbuffers(1, &x);
3748
0
        return x;
3749
0
    }
3750
0
    GLuint CreateTexture() {
3751
0
        GLuint x = 0;
3752
0
        fGenTextures(1, &x);
3753
0
        return x;
3754
0
    }
3755
3756
0
    void DeleteFramebuffer(const GLuint x) {
3757
0
        fDeleteFramebuffers(1, &x);
3758
0
    }
3759
0
    void DeleteRenderbuffer(const GLuint x) {
3760
0
        fDeleteRenderbuffers(1, &x);
3761
0
    }
3762
0
    void DeleteTexture(const GLuint x) {
3763
0
        fDeleteTextures(1, &x);
3764
0
    }
3765
};
3766
3767
bool DoesStringMatch(const char* aString, const char* aWantedString);
3768
3769
void SplitByChar(const nsACString& str, const char delim,
3770
                 std::vector<nsCString>* const out);
3771
3772
template<size_t N>
3773
bool
3774
MarkBitfieldByString(const nsACString& str, const char* const (&markStrList)[N],
3775
                     std::bitset<N>* const out_markList)
3776
{
3777
    for (size_t i = 0; i < N; i++) {
3778
        if (str.Equals(markStrList[i])) {
3779
            (*out_markList)[i] = 1;
3780
            return true;
3781
        }
3782
    }
3783
    return false;
3784
}
3785
3786
template<size_t N>
3787
void
3788
MarkBitfieldByStrings(const std::vector<nsCString>& strList,
3789
                      bool dumpStrings, const char* const (&markStrList)[N],
3790
                      std::bitset<N>* const out_markList)
3791
{
3792
    for (auto itr = strList.begin(); itr != strList.end(); ++itr) {
3793
        const nsACString& str = *itr;
3794
        const bool wasMarked = MarkBitfieldByString(str, markStrList,
3795
                                                    out_markList);
3796
        if (dumpStrings)
3797
            printf_stderr("  %s%s\n", str.BeginReading(), wasMarked ? "(*)" : "");
3798
    }
3799
}
3800
3801
/**
3802
 * Helper function that creates a 2D texture aSize.width x aSize.height with
3803
 * storage type specified by aFormats. Returns GL texture object id.
3804
 *
3805
 * See mozilla::gl::CreateTexture.
3806
 */
3807
GLuint CreateTextureForOffscreen(GLContext* aGL, const GLFormats& aFormats,
3808
                                 const gfx::IntSize& aSize);
3809
3810
/**
3811
 * Helper function that creates a 2D texture aSize.width x aSize.height with
3812
 * storage type aInternalFormat. Returns GL texture object id.
3813
 *
3814
 * Initialize textyre parameters to:
3815
 *    GL_TEXTURE_MIN_FILTER = GL_LINEAR
3816
 *    GL_TEXTURE_MAG_FILTER = GL_LINEAR
3817
 *    GL_TEXTURE_WRAP_S = GL_CLAMP_TO_EDGE
3818
 *    GL_TEXTURE_WRAP_T = GL_CLAMP_TO_EDGE
3819
 */
3820
GLuint CreateTexture(GLContext* aGL, GLenum aInternalFormat, GLenum aFormat,
3821
                     GLenum aType, const gfx::IntSize& aSize, bool linear = true);
3822
3823
/**
3824
 * Helper function that calculates the number of bytes required per
3825
 * texel for a texture from its format and type.
3826
 */
3827
uint32_t GetBytesPerTexel(GLenum format, GLenum type);
3828
3829
} /* namespace gl */
3830
} /* namespace mozilla */
3831
3832
#endif /* GLCONTEXT_H_ */