tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

GLContext.h (123615B)


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