gfx/gl/GLContext.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* vim: set ts=8 sts=4 et sw=4 tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef GLCONTEXT_H_
     8 #define GLCONTEXT_H_
    10 #include <stdio.h>
    11 #include <stdint.h>
    12 #include <ctype.h>
    13 #include <map>
    14 #include <bitset>
    16 #ifdef DEBUG
    17 #include <string.h>
    18 #endif
    20 #ifdef WIN32
    21 #include <windows.h>
    22 #endif
    24 #ifdef GetClassName
    25 #undef GetClassName
    26 #endif
    28 #include "GLDefs.h"
    29 #include "GLLibraryLoader.h"
    30 #include "gfx3DMatrix.h"
    31 #include "nsISupportsImpl.h"
    32 #include "plstr.h"
    33 #include "nsDataHashtable.h"
    34 #include "nsHashKeys.h"
    35 #include "nsAutoPtr.h"
    36 #include "GLContextTypes.h"
    37 #include "GLTextureImage.h"
    38 #include "SurfaceTypes.h"
    39 #include "GLScreenBuffer.h"
    40 #include "GLContextSymbols.h"
    41 #include "mozilla/GenericRefCounted.h"
    42 #include "mozilla/Scoped.h"
    43 #include "gfx2DGlue.h"
    45 #ifdef DEBUG
    46 #define MOZ_ENABLE_GL_TRACKING 1
    47 #endif
    49 class nsIntRegion;
    50 class nsIRunnable;
    51 class nsIThread;
    53 namespace android {
    54     class GraphicBuffer;
    55 }
    57 namespace mozilla {
    58     namespace gfx {
    59         class SourceSurface;
    60         class DataSourceSurface;
    61         struct SurfaceCaps;
    62     }
    64     namespace gl {
    65         class GLContext;
    66         class GLLibraryEGL;
    67         class GLScreenBuffer;
    68         class TextureGarbageBin;
    69         class GLBlitHelper;
    70         class GLBlitTextureImageHelper;
    71         class GLReadTexImageHelper;
    72         class SharedSurface_GL;
    73     }
    75     namespace layers {
    76         class ColorTextureLayerProgram;
    77     }
    78 }
    80 namespace mozilla {
    81 namespace gl {
    83 MOZ_BEGIN_ENUM_CLASS(GLFeature)
    84     bind_buffer_offset,
    85     blend_minmax,
    86     depth_texture,
    87     draw_buffers,
    88     draw_instanced,
    89     draw_range_elements,
    90     element_index_uint,
    91     ES2_compatibility,
    92     ES3_compatibility,
    93     frag_color_float,
    94     frag_depth,
    95     framebuffer_blit,
    96     framebuffer_multisample,
    97     framebuffer_object,
    98     get_query_object_iv,
    99     instanced_arrays,
   100     instanced_non_arrays,
   101     occlusion_query,
   102     occlusion_query_boolean,
   103     occlusion_query2,
   104     packed_depth_stencil,
   105     query_objects,
   106     renderbuffer_color_float,
   107     renderbuffer_color_half_float,
   108     robustness,
   109     sRGB,
   110     standard_derivatives,
   111     texture_float,
   112     texture_float_linear,
   113     texture_half_float,
   114     texture_half_float_linear,
   115     texture_non_power_of_two,
   116     transform_feedback,
   117     vertex_array_object,
   118     EnumMax
   119 MOZ_END_ENUM_CLASS(GLFeature)
   121 MOZ_BEGIN_ENUM_CLASS(ContextProfile, uint8_t)
   122     Unknown = 0,
   123     OpenGL, // only for IsAtLeast's <profile> parameter
   124     OpenGLCore,
   125     OpenGLCompatibility,
   126     OpenGLES
   127 MOZ_END_ENUM_CLASS(ContextProfile)
   129 MOZ_BEGIN_ENUM_CLASS(GLVendor)
   130     Intel,
   131     NVIDIA,
   132     ATI,
   133     Qualcomm,
   134     Imagination,
   135     Nouveau,
   136     Vivante,
   137     VMware,
   138     Other
   139 MOZ_END_ENUM_CLASS(GLVendor)
   141 MOZ_BEGIN_ENUM_CLASS(GLRenderer)
   142     Adreno200,
   143     Adreno205,
   144     AdrenoTM205,
   145     AdrenoTM320,
   146     SGX530,
   147     SGX540,
   148     Tegra,
   149     AndroidEmulator,
   150     GalliumLlvmpipe,
   151     Other
   152 MOZ_END_ENUM_CLASS(GLRenderer)
   154 class GLContext
   155     : public GLLibraryLoader
   156     , public GenericAtomicRefCounted
   157 {
   158 // -----------------------------------------------------------------------------
   159 // basic enums
   160 public:
   162 // -----------------------------------------------------------------------------
   163 // basic getters
   164 public:
   166     /**
   167      * Returns true if the context is using ANGLE. This should only be overridden
   168      * for an ANGLE implementation.
   169      */
   170     virtual bool IsANGLE() const {
   171         return false;
   172     }
   174     /**
   175      * Return true if we are running on a OpenGL core profile context
   176      */
   177     inline bool IsCoreProfile() const {
   178         MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
   180         return mProfile == ContextProfile::OpenGLCore;
   181     }
   183     /**
   184      * Return true if we are running on a OpenGL compatibility profile context
   185      * (legacy profile 2.1 on Max OS X)
   186      */
   187     inline bool IsCompatibilityProfile() const {
   188         MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
   190         return mProfile == ContextProfile::OpenGLCompatibility;
   191     }
   193     /**
   194      * Return true if the context is a true OpenGL ES context or an ANGLE context
   195      */
   196     inline bool IsGLES() const {
   197         MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
   199         return mProfile == ContextProfile::OpenGLES;
   200     }
   202     static const char* GetProfileName(ContextProfile profile)
   203     {
   204         switch (profile)
   205         {
   206             case ContextProfile::OpenGL:
   207                 return "OpenGL";
   208             case ContextProfile::OpenGLCore:
   209                 return "OpenGL Core";
   210             case ContextProfile::OpenGLCompatibility:
   211                 return "OpenGL Compatibility";
   212             case ContextProfile::OpenGLES:
   213                 return "OpenGL ES";
   214             default:
   215                 break;
   216         }
   218         MOZ_ASSERT(profile != ContextProfile::Unknown, "unknown context profile");
   219         return "OpenGL unknown profile";
   220     }
   222     /**
   223      * Return true if we are running on a OpenGL core profile context
   224      */
   225     const char* ProfileString() const {
   226         return GetProfileName(mProfile);
   227     }
   229     /**
   230      * Return true if the context is compatible with given parameters
   231      *
   232      * IsAtLeast(ContextProfile::OpenGL, N) is exactly same as
   233      * IsAtLeast(ContextProfile::OpenGLCore, N) || IsAtLeast(ContextProfile::OpenGLCompatibility, N)
   234      */
   235     inline bool IsAtLeast(ContextProfile profile, unsigned int version) const
   236     {
   237         MOZ_ASSERT(profile != ContextProfile::Unknown, "IsAtLeast: bad <profile> parameter");
   238         MOZ_ASSERT(mProfile != ContextProfile::Unknown, "unknown context profile");
   239         MOZ_ASSERT(mVersion != 0, "unknown context version");
   241         if (version > mVersion) {
   242             return false;
   243         }
   245         if (profile == ContextProfile::OpenGL) {
   246             return profile == ContextProfile::OpenGLCore ||
   247                    profile == ContextProfile::OpenGLCompatibility;
   248         }
   250         return profile == mProfile;
   251     }
   253     /**
   254      * Return the version of the context.
   255      * Example :
   256      *   If this a OpenGL 2.1, that will return 210
   257      */
   258     inline unsigned int Version() const {
   259         return mVersion;
   260     }
   262     const char* VersionString() const {
   263         return mVersionString.get();
   264     }
   266     GLVendor Vendor() const {
   267         return mVendor;
   268     }
   270     GLRenderer Renderer() const {
   271         return mRenderer;
   272     }
   274     bool IsContextLost() const {
   275         return mContextLost;
   276     }
   278     /**
   279      * If this context is double-buffered, returns TRUE.
   280      */
   281     virtual bool IsDoubleBuffered() const {
   282         return false;
   283     }
   285     virtual GLContextType GetContextType() const = 0;
   287     virtual bool IsCurrent() = 0;
   289 protected:
   291     bool mInitialized;
   292     bool mIsOffscreen;
   293     bool mIsGlobalSharedContext;
   294     bool mContextLost;
   296     /**
   297      * mVersion store the OpenGL's version, multiplied by 100. For example, if
   298      * the context is an OpenGL 2.1 context, mVersion value will be 210.
   299      */
   300     unsigned int mVersion;
   301     nsCString mVersionString;
   302     ContextProfile mProfile;
   304     GLVendor mVendor;
   305     GLRenderer mRenderer;
   307     inline void SetProfileVersion(ContextProfile profile, unsigned int version) {
   308         MOZ_ASSERT(!mInitialized, "SetProfileVersion can only be called before initialization!");
   309         MOZ_ASSERT(profile != ContextProfile::Unknown && profile != ContextProfile::OpenGL, "Invalid `profile` for SetProfileVersion");
   310         MOZ_ASSERT(version >= 100, "Invalid `version` for SetProfileVersion");
   312         mVersion = version;
   313         mProfile = profile;
   314     }
   317 // -----------------------------------------------------------------------------
   318 // Extensions management
   319 /**
   320  * This mechanism is designed to know if an extension is supported. In the long
   321  * term, we would like to only use the extension group queries XXX_* to have
   322  * full compatibility with context version and profiles (especialy the core that
   323  * officialy don't bring any extensions).
   324  */
   325 public:
   327     /**
   328      * Known GL extensions that can be queried by
   329      * IsExtensionSupported.  The results of this are cached, and as
   330      * such it's safe to use this even in performance critical code.
   331      * If you add to this array, remember to add to the string names
   332      * in GLContext.cpp.
   333      */
   334     enum GLExtensions {
   335         EXT_framebuffer_object,
   336         ARB_framebuffer_object,
   337         ARB_texture_rectangle,
   338         EXT_bgra,
   339         EXT_texture_format_BGRA8888,
   340         OES_depth24,
   341         OES_depth32,
   342         OES_stencil8,
   343         OES_texture_npot,
   344         ARB_depth_texture,
   345         OES_depth_texture,
   346         OES_packed_depth_stencil,
   347         IMG_read_format,
   348         EXT_read_format_bgra,
   349         APPLE_client_storage,
   350         APPLE_texture_range,
   351         ARB_texture_non_power_of_two,
   352         ARB_pixel_buffer_object,
   353         ARB_ES2_compatibility,
   354         ARB_ES3_compatibility,
   355         OES_texture_float,
   356         OES_texture_float_linear,
   357         ARB_texture_float,
   358         OES_texture_half_float,
   359         OES_texture_half_float_linear,
   360         NV_half_float,
   361         EXT_color_buffer_float,
   362         EXT_color_buffer_half_float,
   363         ARB_color_buffer_float,
   364         EXT_unpack_subimage,
   365         OES_standard_derivatives,
   366         EXT_texture_filter_anisotropic,
   367         EXT_texture_compression_s3tc,
   368         EXT_texture_compression_dxt1,
   369         ANGLE_texture_compression_dxt3,
   370         ANGLE_texture_compression_dxt5,
   371         AMD_compressed_ATC_texture,
   372         IMG_texture_compression_pvrtc,
   373         EXT_framebuffer_blit,
   374         ANGLE_framebuffer_blit,
   375         EXT_framebuffer_multisample,
   376         ANGLE_framebuffer_multisample,
   377         OES_rgb8_rgba8,
   378         ARB_robustness,
   379         EXT_robustness,
   380         ARB_sync,
   381         OES_EGL_image,
   382         OES_EGL_sync,
   383         OES_EGL_image_external,
   384         EXT_packed_depth_stencil,
   385         OES_element_index_uint,
   386         OES_vertex_array_object,
   387         ARB_vertex_array_object,
   388         APPLE_vertex_array_object,
   389         ARB_draw_buffers,
   390         EXT_draw_buffers,
   391         EXT_gpu_shader4,
   392         EXT_blend_minmax,
   393         ARB_draw_instanced,
   394         EXT_draw_instanced,
   395         NV_draw_instanced,
   396         ARB_instanced_arrays,
   397         NV_instanced_arrays,
   398         ANGLE_instanced_arrays,
   399         EXT_occlusion_query_boolean,
   400         ARB_occlusion_query2,
   401         EXT_transform_feedback,
   402         NV_transform_feedback,
   403         ANGLE_depth_texture,
   404         EXT_sRGB,
   405         EXT_texture_sRGB,
   406         ARB_framebuffer_sRGB,
   407         EXT_framebuffer_sRGB,
   408         KHR_debug,
   409         ARB_half_float_pixel,
   410         EXT_frag_depth,
   411         OES_compressed_ETC1_RGB8_texture,
   412         EXT_draw_range_elements,
   413         Extensions_Max,
   414         Extensions_End
   415     };
   417     bool IsExtensionSupported(GLExtensions aKnownExtension) const {
   418         return mAvailableExtensions[aKnownExtension];
   419     }
   421     void MarkExtensionUnsupported(GLExtensions aKnownExtension) {
   422         mAvailableExtensions[aKnownExtension] = 0;
   423     }
   425     void MarkExtensionSupported(GLExtensions aKnownExtension) {
   426         mAvailableExtensions[aKnownExtension] = 1;
   427     }
   430 public:
   432     template<size_t N>
   433     static void InitializeExtensionsBitSet(std::bitset<N>& extensionsBitset, const char* extStr, const char** extList, bool verbose = false)
   434     {
   435         char* exts = ::strdup(extStr);
   437         if (verbose)
   438             printf_stderr("Extensions: %s\n", exts);
   440         char* cur = exts;
   441         bool done = false;
   442         while (!done) {
   443             char* space = strchr(cur, ' ');
   444             if (space) {
   445                 *space = '\0';
   446             } else {
   447                 done = true;
   448             }
   450             for (int i = 0; extList[i]; ++i) {
   451                 if (PL_strcasecmp(cur, extList[i]) == 0) {
   452                     if (verbose)
   453                         printf_stderr("Found extension %s\n", cur);
   454                     extensionsBitset[i] = true;
   455                 }
   456             }
   458             cur = space + 1;
   459         }
   461         free(exts);
   462     }
   465 protected:
   466     std::bitset<Extensions_Max> mAvailableExtensions;
   469 // -----------------------------------------------------------------------------
   470 // Feature queries
   471 /*
   472  * This mecahnism introduces a new way to check if a OpenGL feature is
   473  * supported, regardless of whether it is supported by an extension or natively
   474  * by the context version/profile
   475  */
   476 public:
   477     bool IsSupported(GLFeature feature) const {
   478         return mAvailableFeatures[size_t(feature)];
   479     }
   481     static const char* GetFeatureName(GLFeature feature);
   484 private:
   485     std::bitset<size_t(GLFeature::EnumMax)> mAvailableFeatures;
   487     /**
   488      * Init features regarding OpenGL extension and context version and profile
   489      */
   490     void InitFeatures();
   492     /**
   493      * Mark the feature and associated extensions as unsupported
   494      */
   495     void MarkUnsupported(GLFeature feature);
   497 // -----------------------------------------------------------------------------
   498 // Robustness handling
   499 public:
   501     bool HasRobustness() const {
   502         return mHasRobustness;
   503     }
   505     /**
   506      * The derived class is expected to provide information on whether or not it
   507      * supports robustness.
   508      */
   509     virtual bool SupportsRobustness() const = 0;
   512 private:
   513     bool mHasRobustness;
   516 // -----------------------------------------------------------------------------
   517 // Error handling
   518 public:
   520     static const char* GLErrorToString(GLenum aError)
   521     {
   522         switch (aError) {
   523             case LOCAL_GL_INVALID_ENUM:
   524                 return "GL_INVALID_ENUM";
   525             case LOCAL_GL_INVALID_VALUE:
   526                 return "GL_INVALID_VALUE";
   527             case LOCAL_GL_INVALID_OPERATION:
   528                 return "GL_INVALID_OPERATION";
   529             case LOCAL_GL_STACK_OVERFLOW:
   530                 return "GL_STACK_OVERFLOW";
   531             case LOCAL_GL_STACK_UNDERFLOW:
   532                 return "GL_STACK_UNDERFLOW";
   533             case LOCAL_GL_OUT_OF_MEMORY:
   534                 return "GL_OUT_OF_MEMORY";
   535             case LOCAL_GL_TABLE_TOO_LARGE:
   536                 return "GL_TABLE_TOO_LARGE";
   537             case LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION:
   538                 return "GL_INVALID_FRAMEBUFFER_OPERATION";
   539             default:
   540                 return "";
   541         }
   542     }
   545     /** \returns the first GL error, and guarantees that all GL error flags are cleared,
   546      * i.e. that a subsequent GetError call will return NO_ERROR
   547      */
   548     GLenum GetAndClearError()
   549     {
   550         // the first error is what we want to return
   551         GLenum error = fGetError();
   553         if (error) {
   554             // clear all pending errors
   555             while(fGetError()) {}
   556         }
   558         return error;
   559     }
   562     /*** In GL debug mode, we completely override glGetError ***/
   564     GLenum fGetError()
   565     {
   566 #ifdef DEBUG
   567         // debug mode ends up eating the error in AFTER_GL_CALL
   568         if (DebugMode()) {
   569             GLenum err = mGLError;
   570             mGLError = LOCAL_GL_NO_ERROR;
   571             return err;
   572         }
   573 #endif // DEBUG
   575         return mSymbols.fGetError();
   576     }
   579 #ifdef DEBUG
   580 private:
   582     GLenum mGLError;
   583 #endif // DEBUG
   586 // -----------------------------------------------------------------------------
   587 // MOZ_GL_DEBUG implementation
   588 private:
   590 #undef BEFORE_GL_CALL
   591 #undef AFTER_GL_CALL
   593 #ifdef MOZ_ENABLE_GL_TRACKING
   595 #ifndef MOZ_FUNCTION_NAME
   596 # ifdef __GNUC__
   597 #  define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
   598 # elif defined(_MSC_VER)
   599 #  define MOZ_FUNCTION_NAME __FUNCTION__
   600 # else
   601 #  define MOZ_FUNCTION_NAME __func__  // defined in C99, supported in various C++ compilers. Just raw function name.
   602 # endif
   603 #endif
   605     void BeforeGLCall(const char* glFunction)
   606     {
   607         MOZ_ASSERT(IsCurrent());
   608         if (DebugMode()) {
   609             GLContext *currentGLContext = nullptr;
   611             currentGLContext = (GLContext*)PR_GetThreadPrivate(sCurrentGLContextTLS);
   613             if (DebugMode() & DebugTrace)
   614                 printf_stderr("[gl:%p] > %s\n", this, glFunction);
   615             if (this != currentGLContext) {
   616                 printf_stderr("Fatal: %s called on non-current context %p. "
   617                               "The current context for this thread is %p.\n",
   618                               glFunction, this, currentGLContext);
   619                 NS_ABORT();
   620             }
   621         }
   622     }
   624     void AfterGLCall(const char* glFunction)
   625     {
   626         if (DebugMode()) {
   627             // calling fFinish() immediately after every GL call makes sure that if this GL command crashes,
   628             // the stack trace will actually point to it. Otherwise, OpenGL being an asynchronous API, stack traces
   629             // tend to be meaningless
   630             mSymbols.fFinish();
   631             mGLError = mSymbols.fGetError();
   632             if (DebugMode() & DebugTrace)
   633                 printf_stderr("[gl:%p] < %s [0x%04x]\n", this, glFunction, mGLError);
   634             if (mGLError != LOCAL_GL_NO_ERROR) {
   635                 printf_stderr("GL ERROR: %s generated GL error %s(0x%04x)\n",
   636                               glFunction,
   637                               GLErrorToString(mGLError),
   638                               mGLError);
   639                 if (DebugMode() & DebugAbortOnError)
   640                     NS_ABORT();
   641             }
   642         }
   643     }
   645     GLContext *TrackingContext()
   646     {
   647         GLContext *tip = this;
   648         while (tip->mSharedContext)
   649             tip = tip->mSharedContext;
   650         return tip;
   651     }
   653 #define BEFORE_GL_CALL                              \
   654             do {                                    \
   655                 BeforeGLCall(MOZ_FUNCTION_NAME);    \
   656             } while (0)
   658 #define AFTER_GL_CALL                               \
   659             do {                                    \
   660                 AfterGLCall(MOZ_FUNCTION_NAME);     \
   661             } while (0)
   663 #define TRACKING_CONTEXT(a)                         \
   664             do {                                    \
   665                 TrackingContext()->a;               \
   666             } while (0)
   668 #else // ifdef DEBUG
   670 #define BEFORE_GL_CALL do { } while (0)
   671 #define AFTER_GL_CALL do { } while (0)
   672 #define TRACKING_CONTEXT(a) do {} while (0)
   674 #endif // ifdef DEBUG
   676 #define ASSERT_SYMBOL_PRESENT(func) \
   677             do {\
   678                 MOZ_ASSERT(strstr(MOZ_FUNCTION_NAME, #func) != nullptr, "Mismatched symbol check.");\
   679                 if (MOZ_UNLIKELY(!mSymbols.func)) {\
   680                     printf_stderr("RUNTIME ASSERT: Uninitialized GL function: %s\n", #func);\
   681                     MOZ_CRASH();\
   682                 }\
   683             } while (0)
   685     // Do whatever setup is necessary to draw to our offscreen FBO, if it's
   686     // bound.
   687     void BeforeGLDrawCall() {
   688     }
   690     // Do whatever tear-down is necessary after drawing to our offscreen FBO,
   691     // if it's bound.
   692     void AfterGLDrawCall()
   693     {
   694         if (mScreen)
   695             mScreen->AfterDrawCall();
   696     }
   698     // Do whatever setup is necessary to read from our offscreen FBO, if it's
   699     // bound.
   700     void BeforeGLReadCall()
   701     {
   702         if (mScreen)
   703             mScreen->BeforeReadCall();
   704     }
   706     // Do whatever tear-down is necessary after reading from our offscreen FBO,
   707     // if it's bound.
   708     void AfterGLReadCall() {
   709     }
   712 // -----------------------------------------------------------------------------
   713 // GL official entry points
   714 public:
   716     void fActiveTexture(GLenum texture) {
   717         BEFORE_GL_CALL;
   718         mSymbols.fActiveTexture(texture);
   719         AFTER_GL_CALL;
   720     }
   722     void fAttachShader(GLuint program, GLuint shader) {
   723         BEFORE_GL_CALL;
   724         mSymbols.fAttachShader(program, shader);
   725         AFTER_GL_CALL;
   726     }
   728     void fBeginQuery(GLenum target, GLuint id) {
   729         BEFORE_GL_CALL;
   730         ASSERT_SYMBOL_PRESENT(fBeginQuery);
   731         mSymbols.fBeginQuery(target, id);
   732         AFTER_GL_CALL;
   733     }
   735     void fBindAttribLocation(GLuint program, GLuint index, const GLchar* name) {
   736         BEFORE_GL_CALL;
   737         mSymbols.fBindAttribLocation(program, index, name);
   738         AFTER_GL_CALL;
   739     }
   741     void fBindBuffer(GLenum target, GLuint buffer) {
   742         BEFORE_GL_CALL;
   743         mSymbols.fBindBuffer(target, buffer);
   744         AFTER_GL_CALL;
   745     }
   747     void fBindFramebuffer(GLenum target, GLuint framebuffer) {
   748         if (!mScreen) {
   749             raw_fBindFramebuffer(target, framebuffer);
   750             return;
   751         }
   753         switch (target) {
   754             case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
   755                 mScreen->BindDrawFB(framebuffer);
   756                 return;
   758             case LOCAL_GL_READ_FRAMEBUFFER_EXT:
   759                 mScreen->BindReadFB(framebuffer);
   760                 return;
   762             case LOCAL_GL_FRAMEBUFFER:
   763                 mScreen->BindFB(framebuffer);
   764                 return;
   766             default:
   767                 // Nothing we care about, likely an error.
   768                 break;
   769         }
   771         raw_fBindFramebuffer(target, framebuffer);
   772     }
   774     void fBindTexture(GLenum target, GLuint texture) {
   775         BEFORE_GL_CALL;
   776         mSymbols.fBindTexture(target, texture);
   777         AFTER_GL_CALL;
   778     }
   780     void fBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
   781         BEFORE_GL_CALL;
   782         mSymbols.fBlendColor(red, green, blue, alpha);
   783         AFTER_GL_CALL;
   784     }
   786     void fBlendEquation(GLenum mode) {
   787         BEFORE_GL_CALL;
   788         mSymbols.fBlendEquation(mode);
   789         AFTER_GL_CALL;
   790     }
   792     void fBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
   793         BEFORE_GL_CALL;
   794         mSymbols.fBlendEquationSeparate(modeRGB, modeAlpha);
   795         AFTER_GL_CALL;
   796     }
   798     void fBlendFunc(GLenum sfactor, GLenum dfactor) {
   799         BEFORE_GL_CALL;
   800         mSymbols.fBlendFunc(sfactor, dfactor);
   801         AFTER_GL_CALL;
   802     }
   804     void fBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {
   805         BEFORE_GL_CALL;
   806         mSymbols.fBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
   807         AFTER_GL_CALL;
   808     }
   810 private:
   811     void raw_fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
   812         BEFORE_GL_CALL;
   813         mSymbols.fBufferData(target, size, data, usage);
   814         AFTER_GL_CALL;
   815     }
   817 public:
   818     void fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
   819         raw_fBufferData(target, size, data, usage);
   821         // bug 744888
   822         if (WorkAroundDriverBugs() &&
   823             !data &&
   824             Vendor() == GLVendor::NVIDIA)
   825         {
   826             char c = 0;
   827             fBufferSubData(target, size-1, 1, &c);
   828         }
   829     }
   831     void fBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) {
   832         BEFORE_GL_CALL;
   833         mSymbols.fBufferSubData(target, offset, size, data);
   834         AFTER_GL_CALL;
   835     }
   837 private:
   838     void raw_fClear(GLbitfield mask) {
   839         BEFORE_GL_CALL;
   840         mSymbols.fClear(mask);
   841         AFTER_GL_CALL;
   842     }
   844 public:
   845     void fClear(GLbitfield mask) {
   846         BeforeGLDrawCall();
   847         raw_fClear(mask);
   848         AfterGLDrawCall();
   849     }
   851     void fClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) {
   852         BEFORE_GL_CALL;
   853         mSymbols.fClearColor(r, g, b, a);
   854         AFTER_GL_CALL;
   855     }
   857     void fClearStencil(GLint s) {
   858         BEFORE_GL_CALL;
   859         mSymbols.fClearStencil(s);
   860         AFTER_GL_CALL;
   861     }
   863     void fClientActiveTexture(GLenum texture) {
   864         BEFORE_GL_CALL;
   865         mSymbols.fClientActiveTexture(texture);
   866         AFTER_GL_CALL;
   867     }
   869     void fColorMask(realGLboolean red, realGLboolean green, realGLboolean blue, realGLboolean alpha) {
   870         BEFORE_GL_CALL;
   871         mSymbols.fColorMask(red, green, blue, alpha);
   872         AFTER_GL_CALL;
   873     }
   875     void fCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *pixels) {
   876         BEFORE_GL_CALL;
   877         mSymbols.fCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, pixels);
   878         AFTER_GL_CALL;
   879     }
   881     void fCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *pixels) {
   882         BEFORE_GL_CALL;
   883         mSymbols.fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, pixels);
   884         AFTER_GL_CALL;
   885     }
   887     void fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
   888         if (!IsTextureSizeSafeToPassToDriver(target, width, height)) {
   889             // pass wrong values to cause the GL to generate GL_INVALID_VALUE.
   890             // See bug 737182 and the comment in IsTextureSizeSafeToPassToDriver.
   891             level = -1;
   892             width = -1;
   893             height = -1;
   894             border = -1;
   895         }
   897         BeforeGLReadCall();
   898         raw_fCopyTexImage2D(target, level, internalformat,
   899                             x, y, width, height, border);
   900         AfterGLReadCall();
   901     }
   903     void fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
   904         BeforeGLReadCall();
   905         raw_fCopyTexSubImage2D(target, level, xoffset, yoffset,
   906                                x, y, width, height);
   907         AfterGLReadCall();
   908     }
   910     void fCullFace(GLenum mode) {
   911         BEFORE_GL_CALL;
   912         mSymbols.fCullFace(mode);
   913         AFTER_GL_CALL;
   914     }
   916     void fDebugMessageCallback(GLDEBUGPROC callback, const GLvoid* userParam) {
   917         BEFORE_GL_CALL;
   918         ASSERT_SYMBOL_PRESENT(fDebugMessageCallback);
   919         mSymbols.fDebugMessageCallback(callback, userParam);
   920         AFTER_GL_CALL;
   921     }
   923     void fDebugMessageControl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, realGLboolean enabled) {
   924         BEFORE_GL_CALL;
   925         ASSERT_SYMBOL_PRESENT(fDebugMessageControl);
   926         mSymbols.fDebugMessageControl(source, type, severity, count, ids, enabled);
   927         AFTER_GL_CALL;
   928     }
   930     void fDebugMessageInsert(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf) {
   931         BEFORE_GL_CALL;
   932         ASSERT_SYMBOL_PRESENT(fDebugMessageInsert);
   933         mSymbols.fDebugMessageInsert(source, type, id, severity, length, buf);
   934         AFTER_GL_CALL;
   935     }
   937     void fDetachShader(GLuint program, GLuint shader) {
   938         BEFORE_GL_CALL;
   939         mSymbols.fDetachShader(program, shader);
   940         AFTER_GL_CALL;
   941     }
   943     void fDepthFunc(GLenum func) {
   944         BEFORE_GL_CALL;
   945         mSymbols.fDepthFunc(func);
   946         AFTER_GL_CALL;
   947     }
   949     void fDepthMask(realGLboolean flag) {
   950         BEFORE_GL_CALL;
   951         mSymbols.fDepthMask(flag);
   952         AFTER_GL_CALL;
   953     }
   955     void fDisable(GLenum capability) {
   956         BEFORE_GL_CALL;
   957         mSymbols.fDisable(capability);
   958         AFTER_GL_CALL;
   959     }
   961     void fDisableClientState(GLenum capability) {
   962         BEFORE_GL_CALL;
   963         mSymbols.fDisableClientState(capability);
   964         AFTER_GL_CALL;
   965     }
   967     void fDisableVertexAttribArray(GLuint index) {
   968         BEFORE_GL_CALL;
   969         mSymbols.fDisableVertexAttribArray(index);
   970         AFTER_GL_CALL;
   971     }
   973     void fDrawBuffer(GLenum mode) {
   974         BEFORE_GL_CALL;
   975         mSymbols.fDrawBuffer(mode);
   976         AFTER_GL_CALL;
   977     }
   979 private:
   980     void raw_fDrawArrays(GLenum mode, GLint first, GLsizei count) {
   981         BEFORE_GL_CALL;
   982         mSymbols.fDrawArrays(mode, first, count);
   983         AFTER_GL_CALL;
   984     }
   986     void raw_fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {
   987         BEFORE_GL_CALL;
   988         mSymbols.fDrawElements(mode, count, type, indices);
   989         AFTER_GL_CALL;
   990     }
   992 public:
   993     void fDrawArrays(GLenum mode, GLint first, GLsizei count) {
   994         BeforeGLDrawCall();
   995         raw_fDrawArrays(mode, first, count);
   996         AfterGLDrawCall();
   997     }
   999     void fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {
  1000         BeforeGLDrawCall();
  1001         raw_fDrawElements(mode, count, type, indices);
  1002         AfterGLDrawCall();
  1005     void fEnable(GLenum capability) {
  1006         BEFORE_GL_CALL;
  1007         mSymbols.fEnable(capability);
  1008         AFTER_GL_CALL;
  1011     void fEnableClientState(GLenum capability) {
  1012         BEFORE_GL_CALL;
  1013         mSymbols.fEnableClientState(capability);
  1014         AFTER_GL_CALL;
  1017     void fEnableVertexAttribArray(GLuint index) {
  1018         BEFORE_GL_CALL;
  1019         mSymbols.fEnableVertexAttribArray(index);
  1020         AFTER_GL_CALL;
  1023     void fEndQuery(GLenum target) {
  1024         BEFORE_GL_CALL;
  1025         ASSERT_SYMBOL_PRESENT(fEndQuery);
  1026         mSymbols.fEndQuery(target);
  1027         AFTER_GL_CALL;
  1030     void fFinish() {
  1031         BEFORE_GL_CALL;
  1032         mSymbols.fFinish();
  1033         AFTER_GL_CALL;
  1036     void fFlush() {
  1037         BEFORE_GL_CALL;
  1038         mSymbols.fFlush();
  1039         AFTER_GL_CALL;
  1042     void fFrontFace(GLenum face) {
  1043         BEFORE_GL_CALL;
  1044         mSymbols.fFrontFace(face);
  1045         AFTER_GL_CALL;
  1048     void fGetActiveAttrib(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
  1049         BEFORE_GL_CALL;
  1050         mSymbols.fGetActiveAttrib(program, index, maxLength, length, size, type, name);
  1051         AFTER_GL_CALL;
  1054     void fGetActiveUniform(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
  1055         BEFORE_GL_CALL;
  1056         mSymbols.fGetActiveUniform(program, index, maxLength, length, size, type, name);
  1057         AFTER_GL_CALL;
  1060     void fGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
  1061         BEFORE_GL_CALL;
  1062         mSymbols.fGetAttachedShaders(program, maxCount, count, shaders);
  1063         AFTER_GL_CALL;
  1066     GLint fGetAttribLocation(GLuint program, const GLchar* name) {
  1067         BEFORE_GL_CALL;
  1068         GLint retval = mSymbols.fGetAttribLocation(program, name);
  1069         AFTER_GL_CALL;
  1070         return retval;
  1073 private:
  1074     void raw_fGetIntegerv(GLenum pname, GLint *params) {
  1075         BEFORE_GL_CALL;
  1076         mSymbols.fGetIntegerv(pname, params);
  1077         AFTER_GL_CALL;
  1080 public:
  1082     void fGetIntegerv(GLenum pname, GLint *params) {
  1083         switch (pname)
  1085             // LOCAL_GL_FRAMEBUFFER_BINDING is equal to
  1086             // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT,
  1087             // so we don't need two cases.
  1088             case LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT:
  1089                 if (mScreen) {
  1090                     *params = mScreen->GetDrawFB();
  1091                 } else {
  1092                     raw_fGetIntegerv(pname, params);
  1094                 break;
  1096             case LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT:
  1097                 if (mScreen) {
  1098                     *params = mScreen->GetReadFB();
  1099                 } else {
  1100                     raw_fGetIntegerv(pname, params);
  1102                 break;
  1104             case LOCAL_GL_MAX_TEXTURE_SIZE:
  1105                 MOZ_ASSERT(mMaxTextureSize>0);
  1106                 *params = mMaxTextureSize;
  1107                 break;
  1109             case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
  1110                 MOZ_ASSERT(mMaxCubeMapTextureSize>0);
  1111                 *params = mMaxCubeMapTextureSize;
  1112                 break;
  1114             case LOCAL_GL_MAX_RENDERBUFFER_SIZE:
  1115                 MOZ_ASSERT(mMaxRenderbufferSize>0);
  1116                 *params = mMaxRenderbufferSize;
  1117                 break;
  1119             case LOCAL_GL_VIEWPORT:
  1120                 for (size_t i = 0; i < 4; i++) {
  1121                     params[i] = mViewportRect[i];
  1123                 break;
  1125             case LOCAL_GL_SCISSOR_BOX:
  1126                 for (size_t i = 0; i < 4; i++) {
  1127                     params[i] = mScissorRect[i];
  1129                 break;
  1131             default:
  1132                 raw_fGetIntegerv(pname, params);
  1133                 break;
  1137     void GetUIntegerv(GLenum pname, GLuint *params) {
  1138         fGetIntegerv(pname, reinterpret_cast<GLint*>(params));
  1141     void fGetFloatv(GLenum pname, GLfloat *params) {
  1142         BEFORE_GL_CALL;
  1143         mSymbols.fGetFloatv(pname, params);
  1144         AFTER_GL_CALL;
  1147     void fGetBooleanv(GLenum pname, realGLboolean *params) {
  1148         BEFORE_GL_CALL;
  1149         mSymbols.fGetBooleanv(pname, params);
  1150         AFTER_GL_CALL;
  1153     void fGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
  1154         BEFORE_GL_CALL;
  1155         mSymbols.fGetBufferParameteriv(target, pname, params);
  1156         AFTER_GL_CALL;
  1159     GLuint fGetDebugMessageLog(GLuint count, GLsizei bufsize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog) {
  1160         BEFORE_GL_CALL;
  1161         ASSERT_SYMBOL_PRESENT(fGetDebugMessageLog);
  1162         GLuint ret = mSymbols.fGetDebugMessageLog(count, bufsize, sources, types, ids, severities, lengths, messageLog);
  1163         AFTER_GL_CALL;
  1164         return ret;
  1167     void fGetPointerv(GLenum pname, GLvoid** params) {
  1168         BEFORE_GL_CALL;
  1169         ASSERT_SYMBOL_PRESENT(fGetPointerv);
  1170         mSymbols.fGetPointerv(pname, params);
  1171         AFTER_GL_CALL;
  1174     void fGetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label) {
  1175         BEFORE_GL_CALL;
  1176         ASSERT_SYMBOL_PRESENT(fGetObjectLabel);
  1177         mSymbols.fGetObjectLabel(identifier, name, bufSize, length, label);
  1178         AFTER_GL_CALL;
  1181     void fGetObjectPtrLabel(const GLvoid* ptr, GLsizei bufSize, GLsizei* length, GLchar* label) {
  1182         BEFORE_GL_CALL;
  1183         ASSERT_SYMBOL_PRESENT(fGetObjectPtrLabel);
  1184         mSymbols.fGetObjectPtrLabel(ptr, bufSize, length, label);
  1185         AFTER_GL_CALL;
  1188     void fGenerateMipmap(GLenum target) {
  1189         BEFORE_GL_CALL;
  1190         mSymbols.fGenerateMipmap(target);
  1191         AFTER_GL_CALL;
  1194     void fGetProgramiv(GLuint program, GLenum pname, GLint* param) {
  1195         BEFORE_GL_CALL;
  1196         mSymbols.fGetProgramiv(program, pname, param);
  1197         AFTER_GL_CALL;
  1200     void fGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
  1201         BEFORE_GL_CALL;
  1202         mSymbols.fGetProgramInfoLog(program, bufSize, length, infoLog);
  1203         AFTER_GL_CALL;
  1206     void fTexParameteri(GLenum target, GLenum pname, GLint param) {
  1207         BEFORE_GL_CALL;
  1208         mSymbols.fTexParameteri(target, pname, param);
  1209         AFTER_GL_CALL;
  1212     void fTexParameteriv(GLenum target, GLenum pname, const GLint* params) {
  1213         BEFORE_GL_CALL;
  1214         mSymbols.fTexParameteriv(target, pname, params);
  1215         AFTER_GL_CALL;
  1218     void fTexParameterf(GLenum target, GLenum pname, GLfloat param) {
  1219         BEFORE_GL_CALL;
  1220         mSymbols.fTexParameterf(target, pname, param);
  1221         AFTER_GL_CALL;
  1224     const GLubyte* fGetString(GLenum name) {
  1225         BEFORE_GL_CALL;
  1226         const GLubyte *result = mSymbols.fGetString(name);
  1227         AFTER_GL_CALL;
  1228         return result;
  1231     void fGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *img) {
  1232         BEFORE_GL_CALL;
  1233         ASSERT_SYMBOL_PRESENT(fGetTexImage);
  1234         mSymbols.fGetTexImage(target, level, format, type, img);
  1235         AFTER_GL_CALL;
  1238     void fGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
  1240         BEFORE_GL_CALL;
  1241         ASSERT_SYMBOL_PRESENT(fGetTexLevelParameteriv);
  1242         mSymbols.fGetTexLevelParameteriv(target, level, pname, params);
  1243         AFTER_GL_CALL;
  1246     void fGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) {
  1247         BEFORE_GL_CALL;
  1248         mSymbols.fGetTexParameterfv(target, pname, params);
  1249         AFTER_GL_CALL;
  1252     void fGetTexParameteriv(GLenum target, GLenum pname, GLint* params) {
  1253         BEFORE_GL_CALL;
  1254         mSymbols.fGetTexParameteriv(target, pname, params);
  1255         AFTER_GL_CALL;
  1258     void fGetUniformfv(GLuint program, GLint location, GLfloat* params) {
  1259         BEFORE_GL_CALL;
  1260         mSymbols.fGetUniformfv(program, location, params);
  1261         AFTER_GL_CALL;
  1264     void fGetUniformiv(GLuint program, GLint location, GLint* params) {
  1265         BEFORE_GL_CALL;
  1266         mSymbols.fGetUniformiv(program, location, params);
  1267         AFTER_GL_CALL;
  1270     GLint fGetUniformLocation (GLint programObj, const GLchar* name) {
  1271         BEFORE_GL_CALL;
  1272         GLint retval = mSymbols.fGetUniformLocation(programObj, name);
  1273         AFTER_GL_CALL;
  1274         return retval;
  1277     void fGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* retval) {
  1278         BEFORE_GL_CALL;
  1279         mSymbols.fGetVertexAttribfv(index, pname, retval);
  1280         AFTER_GL_CALL;
  1283     void fGetVertexAttribiv(GLuint index, GLenum pname, GLint* retval) {
  1284         BEFORE_GL_CALL;
  1285         mSymbols.fGetVertexAttribiv(index, pname, retval);
  1286         AFTER_GL_CALL;
  1289     void fGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** retval) {
  1290         BEFORE_GL_CALL;
  1291         mSymbols.fGetVertexAttribPointerv(index, pname, retval);
  1292         AFTER_GL_CALL;
  1295     void fHint(GLenum target, GLenum mode) {
  1296         BEFORE_GL_CALL;
  1297         mSymbols.fHint(target, mode);
  1298         AFTER_GL_CALL;
  1301     realGLboolean fIsBuffer(GLuint buffer) {
  1302         BEFORE_GL_CALL;
  1303         realGLboolean retval = mSymbols.fIsBuffer(buffer);
  1304         AFTER_GL_CALL;
  1305         return retval;
  1308     realGLboolean fIsEnabled(GLenum capability) {
  1309         BEFORE_GL_CALL;
  1310         realGLboolean retval = mSymbols.fIsEnabled(capability);
  1311         AFTER_GL_CALL;
  1312         return retval;
  1315     realGLboolean fIsProgram(GLuint program) {
  1316         BEFORE_GL_CALL;
  1317         realGLboolean retval = mSymbols.fIsProgram(program);
  1318         AFTER_GL_CALL;
  1319         return retval;
  1322     realGLboolean fIsShader(GLuint shader) {
  1323         BEFORE_GL_CALL;
  1324         realGLboolean retval = mSymbols.fIsShader(shader);
  1325         AFTER_GL_CALL;
  1326         return retval;
  1329     realGLboolean fIsTexture(GLuint texture) {
  1330         BEFORE_GL_CALL;
  1331         realGLboolean retval = mSymbols.fIsTexture(texture);
  1332         AFTER_GL_CALL;
  1333         return retval;
  1336     void fLineWidth(GLfloat width) {
  1337         BEFORE_GL_CALL;
  1338         mSymbols.fLineWidth(width);
  1339         AFTER_GL_CALL;
  1342     void fLinkProgram(GLuint program) {
  1343         BEFORE_GL_CALL;
  1344         mSymbols.fLinkProgram(program);
  1345         AFTER_GL_CALL;
  1348     void fObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar* label) {
  1349         BEFORE_GL_CALL;
  1350         ASSERT_SYMBOL_PRESENT(fObjectLabel);
  1351         mSymbols.fObjectLabel(identifier, name, length, label);
  1352         AFTER_GL_CALL;
  1355     void fObjectPtrLabel(const GLvoid* ptr, GLsizei length, const GLchar* label) {
  1356         BEFORE_GL_CALL;
  1357         ASSERT_SYMBOL_PRESENT(fObjectPtrLabel);
  1358         mSymbols.fObjectPtrLabel(ptr, length, label);
  1359         AFTER_GL_CALL;
  1362     void fLoadIdentity() {
  1363         BEFORE_GL_CALL;
  1364         mSymbols.fLoadIdentity();
  1365         AFTER_GL_CALL;
  1368     void fLoadMatrixf(const GLfloat *matrix) {
  1369         BEFORE_GL_CALL;
  1370         mSymbols.fLoadMatrixf(matrix);
  1371         AFTER_GL_CALL;
  1374     void fMatrixMode(GLenum mode) {
  1375         BEFORE_GL_CALL;
  1376         mSymbols.fMatrixMode(mode);
  1377         AFTER_GL_CALL;
  1380     void fPixelStorei(GLenum pname, GLint param) {
  1381         BEFORE_GL_CALL;
  1382         mSymbols.fPixelStorei(pname, param);
  1383         AFTER_GL_CALL;
  1386     void fTextureRangeAPPLE(GLenum target, GLsizei length, GLvoid *pointer) {
  1387         BEFORE_GL_CALL;
  1388         mSymbols.fTextureRangeAPPLE(target, length, pointer);
  1389         AFTER_GL_CALL;
  1392     void fPointParameterf(GLenum pname, GLfloat param) {
  1393         BEFORE_GL_CALL;
  1394         mSymbols.fPointParameterf(pname, param);
  1395         AFTER_GL_CALL;
  1398     void fPolygonOffset(GLfloat factor, GLfloat bias) {
  1399         BEFORE_GL_CALL;
  1400         mSymbols.fPolygonOffset(factor, bias);
  1401         AFTER_GL_CALL;
  1404     void fPopDebugGroup() {
  1405         BEFORE_GL_CALL;
  1406         ASSERT_SYMBOL_PRESENT(fPopDebugGroup);
  1407         mSymbols.fPopDebugGroup();
  1408         AFTER_GL_CALL;
  1411     void fPushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar* message) {
  1412         BEFORE_GL_CALL;
  1413         ASSERT_SYMBOL_PRESENT(fPushDebugGroup);
  1414         mSymbols.fPushDebugGroup(source, id, length, message);
  1415         AFTER_GL_CALL;
  1418     void fReadBuffer(GLenum mode) {
  1419         BEFORE_GL_CALL;
  1420         mSymbols.fReadBuffer(mode);
  1421         AFTER_GL_CALL;
  1424 private:
  1425     void raw_fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
  1426         BEFORE_GL_CALL;
  1427         mSymbols.fReadPixels(x, y, width, height, format, type, pixels);
  1428         AFTER_GL_CALL;
  1431 public:
  1432     void fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
  1433         BeforeGLReadCall();
  1435         bool didReadPixels = false;
  1436         if (mScreen) {
  1437             didReadPixels = mScreen->ReadPixels(x, y, width, height, format, type, pixels);
  1440         if (!didReadPixels) {
  1441             raw_fReadPixels(x, y, width, height, format, type, pixels);
  1444         AfterGLReadCall();
  1447 public:
  1448     void fSampleCoverage(GLclampf value, realGLboolean invert) {
  1449         BEFORE_GL_CALL;
  1450         mSymbols.fSampleCoverage(value, invert);
  1451         AFTER_GL_CALL;
  1454     void fScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
  1455         if (mScissorRect[0] == x &&
  1456             mScissorRect[1] == y &&
  1457             mScissorRect[2] == width &&
  1458             mScissorRect[3] == height)
  1460             return;
  1462         mScissorRect[0] = x;
  1463         mScissorRect[1] = y;
  1464         mScissorRect[2] = width;
  1465         mScissorRect[3] = height;
  1466         BEFORE_GL_CALL;
  1467         mSymbols.fScissor(x, y, width, height);
  1468         AFTER_GL_CALL;
  1471     void fStencilFunc(GLenum func, GLint ref, GLuint mask) {
  1472         BEFORE_GL_CALL;
  1473         mSymbols.fStencilFunc(func, ref, mask);
  1474         AFTER_GL_CALL;
  1477     void fStencilFuncSeparate(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask) {
  1478         BEFORE_GL_CALL;
  1479         mSymbols.fStencilFuncSeparate(frontfunc, backfunc, ref, mask);
  1480         AFTER_GL_CALL;
  1483     void fStencilMask(GLuint mask) {
  1484         BEFORE_GL_CALL;
  1485         mSymbols.fStencilMask(mask);
  1486         AFTER_GL_CALL;
  1489     void fStencilMaskSeparate(GLenum face, GLuint mask) {
  1490         BEFORE_GL_CALL;
  1491         mSymbols.fStencilMaskSeparate(face, mask);
  1492         AFTER_GL_CALL;
  1495     void fStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
  1496         BEFORE_GL_CALL;
  1497         mSymbols.fStencilOp(fail, zfail, zpass);
  1498         AFTER_GL_CALL;
  1501     void fStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {
  1502         BEFORE_GL_CALL;
  1503         mSymbols.fStencilOpSeparate(face, sfail, dpfail, dppass);
  1504         AFTER_GL_CALL;
  1507     void fTexGeni(GLenum coord, GLenum pname, GLint param) {
  1508         BEFORE_GL_CALL;
  1509         mSymbols.fTexGeni(coord, pname, param);
  1510         AFTER_GL_CALL;
  1513     void fTexGenf(GLenum coord, GLenum pname, GLfloat param) {
  1514         BEFORE_GL_CALL;
  1515         mSymbols.fTexGenf(coord, pname, param);
  1516         AFTER_GL_CALL;
  1519     void fTexGenfv(GLenum coord, GLenum pname, const GLfloat *params) {
  1520         BEFORE_GL_CALL;
  1521         mSymbols.fTexGenfv(coord, pname, params);
  1522         AFTER_GL_CALL;
  1525 private:
  1526     void raw_fTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
  1527         BEFORE_GL_CALL;
  1528         mSymbols.fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
  1529         AFTER_GL_CALL;
  1532 public:
  1533     void fTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
  1534         if (!IsTextureSizeSafeToPassToDriver(target, width, height)) {
  1535             // pass wrong values to cause the GL to generate GL_INVALID_VALUE.
  1536             // See bug 737182 and the comment in IsTextureSizeSafeToPassToDriver.
  1537             level = -1;
  1538             width = -1;
  1539             height = -1;
  1540             border = -1;
  1542         raw_fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
  1545     void fTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) {
  1546         BEFORE_GL_CALL;
  1547         mSymbols.fTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
  1548         AFTER_GL_CALL;
  1551     void fUniform1f(GLint location, GLfloat v0) {
  1552         BEFORE_GL_CALL;
  1553         mSymbols.fUniform1f(location, v0);
  1554         AFTER_GL_CALL;
  1557     void fUniform1fv(GLint location, GLsizei count, const GLfloat* value) {
  1558         BEFORE_GL_CALL;
  1559         mSymbols.fUniform1fv(location, count, value);
  1560         AFTER_GL_CALL;
  1563     void fUniform1i(GLint location, GLint v0) {
  1564         BEFORE_GL_CALL;
  1565         mSymbols.fUniform1i(location, v0);
  1566         AFTER_GL_CALL;
  1569     void fUniform1iv(GLint location, GLsizei count, const GLint* value) {
  1570         BEFORE_GL_CALL;
  1571         mSymbols.fUniform1iv(location, count, value);
  1572         AFTER_GL_CALL;
  1575     void fUniform2f(GLint location, GLfloat v0, GLfloat v1) {
  1576         BEFORE_GL_CALL;
  1577         mSymbols.fUniform2f(location, v0, v1);
  1578         AFTER_GL_CALL;
  1581     void fUniform2fv(GLint location, GLsizei count, const GLfloat* value) {
  1582         BEFORE_GL_CALL;
  1583         mSymbols.fUniform2fv(location, count, value);
  1584         AFTER_GL_CALL;
  1587     void fUniform2i(GLint location, GLint v0, GLint v1) {
  1588         BEFORE_GL_CALL;
  1589         mSymbols.fUniform2i(location, v0, v1);
  1590         AFTER_GL_CALL;
  1593     void fUniform2iv(GLint location, GLsizei count, const GLint* value) {
  1594         BEFORE_GL_CALL;
  1595         mSymbols.fUniform2iv(location, count, value);
  1596         AFTER_GL_CALL;
  1599     void fUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
  1600         BEFORE_GL_CALL;
  1601         mSymbols.fUniform3f(location, v0, v1, v2);
  1602         AFTER_GL_CALL;
  1605     void fUniform3fv(GLint location, GLsizei count, const GLfloat* value) {
  1606         BEFORE_GL_CALL;
  1607         mSymbols.fUniform3fv(location, count, value);
  1608         AFTER_GL_CALL;
  1611     void fUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {
  1612         BEFORE_GL_CALL;
  1613         mSymbols.fUniform3i(location, v0, v1, v2);
  1614         AFTER_GL_CALL;
  1617     void fUniform3iv(GLint location, GLsizei count, const GLint* value) {
  1618         BEFORE_GL_CALL;
  1619         mSymbols.fUniform3iv(location, count, value);
  1620         AFTER_GL_CALL;
  1623     void fUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
  1624         BEFORE_GL_CALL;
  1625         mSymbols.fUniform4f(location, v0, v1, v2, v3);
  1626         AFTER_GL_CALL;
  1629     void fUniform4fv(GLint location, GLsizei count, const GLfloat* value) {
  1630         BEFORE_GL_CALL;
  1631         mSymbols.fUniform4fv(location, count, value);
  1632         AFTER_GL_CALL;
  1635     void fUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {
  1636         BEFORE_GL_CALL;
  1637         mSymbols.fUniform4i(location, v0, v1, v2, v3);
  1638         AFTER_GL_CALL;
  1641     void fUniform4iv(GLint location, GLsizei count, const GLint* value) {
  1642         BEFORE_GL_CALL;
  1643         mSymbols.fUniform4iv(location, count, value);
  1644         AFTER_GL_CALL;
  1647     void fUniformMatrix2fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
  1648         BEFORE_GL_CALL;
  1649         mSymbols.fUniformMatrix2fv(location, count, transpose, value);
  1650         AFTER_GL_CALL;
  1653     void fUniformMatrix3fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
  1654         BEFORE_GL_CALL;
  1655         mSymbols.fUniformMatrix3fv(location, count, transpose, value);
  1656         AFTER_GL_CALL;
  1659     void fUniformMatrix4fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
  1660         BEFORE_GL_CALL;
  1661         mSymbols.fUniformMatrix4fv(location, count, transpose, value);
  1662         AFTER_GL_CALL;
  1665     void fUseProgram(GLuint program) {
  1666         BEFORE_GL_CALL;
  1667         mSymbols.fUseProgram(program);
  1668         AFTER_GL_CALL;
  1671     void fValidateProgram(GLuint program) {
  1672         BEFORE_GL_CALL;
  1673         mSymbols.fValidateProgram(program);
  1674         AFTER_GL_CALL;
  1677     void fVertexAttribPointer(GLuint index, GLint size, GLenum type, realGLboolean normalized, GLsizei stride, const GLvoid* pointer) {
  1678         BEFORE_GL_CALL;
  1679         mSymbols.fVertexAttribPointer(index, size, type, normalized, stride, pointer);
  1680         AFTER_GL_CALL;
  1683     void fVertexAttrib1f(GLuint index, GLfloat x) {
  1684         BEFORE_GL_CALL;
  1685         mSymbols.fVertexAttrib1f(index, x);
  1686         AFTER_GL_CALL;
  1689     void fVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {
  1690         BEFORE_GL_CALL;
  1691         mSymbols.fVertexAttrib2f(index, x, y);
  1692         AFTER_GL_CALL;
  1695     void fVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
  1696         BEFORE_GL_CALL;
  1697         mSymbols.fVertexAttrib3f(index, x, y, z);
  1698         AFTER_GL_CALL;
  1701     void fVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
  1702         BEFORE_GL_CALL;
  1703         mSymbols.fVertexAttrib4f(index, x, y, z, w);
  1704         AFTER_GL_CALL;
  1707     void fVertexAttrib1fv(GLuint index, const GLfloat* v) {
  1708         BEFORE_GL_CALL;
  1709         mSymbols.fVertexAttrib1fv(index, v);
  1710         AFTER_GL_CALL;
  1713     void fVertexAttrib2fv(GLuint index, const GLfloat* v) {
  1714         BEFORE_GL_CALL;
  1715         mSymbols.fVertexAttrib2fv(index, v);
  1716         AFTER_GL_CALL;
  1719     void fVertexAttrib3fv(GLuint index, const GLfloat* v) {
  1720         BEFORE_GL_CALL;
  1721         mSymbols.fVertexAttrib3fv(index, v);
  1722         AFTER_GL_CALL;
  1725     void fVertexAttrib4fv(GLuint index, const GLfloat* v) {
  1726         BEFORE_GL_CALL;
  1727         mSymbols.fVertexAttrib4fv(index, v);
  1728         AFTER_GL_CALL;
  1731     void fVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) {
  1732         BEFORE_GL_CALL;
  1733         mSymbols.fVertexPointer(size, type, stride, pointer);
  1734         AFTER_GL_CALL;
  1737     void fCompileShader(GLuint shader) {
  1738         BEFORE_GL_CALL;
  1739         mSymbols.fCompileShader(shader);
  1740         AFTER_GL_CALL;
  1743 private:
  1744     void raw_fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
  1745         BEFORE_GL_CALL;
  1746         mSymbols.fCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
  1747         AFTER_GL_CALL;
  1750     void raw_fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
  1751         BEFORE_GL_CALL;
  1752         mSymbols.fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
  1753         AFTER_GL_CALL;
  1756 public:
  1757     void fGetShaderiv(GLuint shader, GLenum pname, GLint* param) {
  1758         BEFORE_GL_CALL;
  1759         mSymbols.fGetShaderiv(shader, pname, param);
  1760         AFTER_GL_CALL;
  1763     void fGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
  1764         BEFORE_GL_CALL;
  1765         mSymbols.fGetShaderInfoLog(shader, bufSize, length, infoLog);
  1766         AFTER_GL_CALL;
  1769 private:
  1770     void raw_fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
  1771         MOZ_ASSERT(IsGLES());
  1773         BEFORE_GL_CALL;
  1774         ASSERT_SYMBOL_PRESENT(fGetShaderPrecisionFormat);
  1775         mSymbols.fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
  1776         AFTER_GL_CALL;
  1779 public:
  1780     void fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
  1781         if (IsGLES()) {
  1782             raw_fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
  1783         } else {
  1784             // Fall back to automatic values because almost all desktop hardware supports the OpenGL standard precisions.
  1785             GetShaderPrecisionFormatNonES2(shadertype, precisiontype, range, precision);
  1789     void fGetShaderSource(GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source) {
  1790         BEFORE_GL_CALL;
  1791         mSymbols.fGetShaderSource(obj, maxLength, length, source);
  1792         AFTER_GL_CALL;
  1795     void fShaderSource(GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths) {
  1796         BEFORE_GL_CALL;
  1797         mSymbols.fShaderSource(shader, count, strings, lengths);
  1798         AFTER_GL_CALL;
  1801 private:
  1802     void raw_fBindFramebuffer(GLenum target, GLuint framebuffer) {
  1803         BEFORE_GL_CALL;
  1804         mSymbols.fBindFramebuffer(target, framebuffer);
  1805         AFTER_GL_CALL;
  1808 public:
  1809     void fBindRenderbuffer(GLenum target, GLuint renderbuffer) {
  1810         BEFORE_GL_CALL;
  1811         mSymbols.fBindRenderbuffer(target, renderbuffer);
  1812         AFTER_GL_CALL;
  1815     GLenum fCheckFramebufferStatus(GLenum target) {
  1816         BEFORE_GL_CALL;
  1817         GLenum retval = mSymbols.fCheckFramebufferStatus(target);
  1818         AFTER_GL_CALL;
  1819         return retval;
  1822     void fFramebufferRenderbuffer(GLenum target, GLenum attachmentPoint, GLenum renderbufferTarget, GLuint renderbuffer) {
  1823         BEFORE_GL_CALL;
  1824         mSymbols.fFramebufferRenderbuffer(target, attachmentPoint, renderbufferTarget, renderbuffer);
  1825         AFTER_GL_CALL;
  1828     void fFramebufferTexture2D(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint texture, GLint level) {
  1829         BEFORE_GL_CALL;
  1830         mSymbols.fFramebufferTexture2D(target, attachmentPoint, textureTarget, texture, level);
  1831         AFTER_GL_CALL;
  1834     void fGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* value) {
  1835         BEFORE_GL_CALL;
  1836         mSymbols.fGetFramebufferAttachmentParameteriv(target, attachment, pname, value);
  1837         AFTER_GL_CALL;
  1840     void fGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* value) {
  1841         BEFORE_GL_CALL;
  1842         mSymbols.fGetRenderbufferParameteriv(target, pname, value);
  1843         AFTER_GL_CALL;
  1846     realGLboolean fIsFramebuffer (GLuint framebuffer) {
  1847         BEFORE_GL_CALL;
  1848         realGLboolean retval = mSymbols.fIsFramebuffer(framebuffer);
  1849         AFTER_GL_CALL;
  1850         return retval;
  1853 public:
  1854     realGLboolean fIsRenderbuffer (GLuint renderbuffer) {
  1855         BEFORE_GL_CALL;
  1856         realGLboolean retval = mSymbols.fIsRenderbuffer(renderbuffer);
  1857         AFTER_GL_CALL;
  1858         return retval;
  1861     void fRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height) {
  1862         BEFORE_GL_CALL;
  1863         mSymbols.fRenderbufferStorage(target, internalFormat, width, height);
  1864         AFTER_GL_CALL;
  1867 private:
  1868     void raw_fDepthRange(GLclampf a, GLclampf b) {
  1869         MOZ_ASSERT(!IsGLES());
  1871         BEFORE_GL_CALL;
  1872         ASSERT_SYMBOL_PRESENT(fDepthRange);
  1873         mSymbols.fDepthRange(a, b);
  1874         AFTER_GL_CALL;
  1877     void raw_fDepthRangef(GLclampf a, GLclampf b) {
  1878         MOZ_ASSERT(IsGLES());
  1880         BEFORE_GL_CALL;
  1881         ASSERT_SYMBOL_PRESENT(fDepthRangef);
  1882         mSymbols.fDepthRangef(a, b);
  1883         AFTER_GL_CALL;
  1886     void raw_fClearDepth(GLclampf v) {
  1887         MOZ_ASSERT(!IsGLES());
  1889         BEFORE_GL_CALL;
  1890         ASSERT_SYMBOL_PRESENT(fClearDepth);
  1891         mSymbols.fClearDepth(v);
  1892         AFTER_GL_CALL;
  1895     void raw_fClearDepthf(GLclampf v) {
  1896         MOZ_ASSERT(IsGLES());
  1898         BEFORE_GL_CALL;
  1899         ASSERT_SYMBOL_PRESENT(fClearDepthf);
  1900         mSymbols.fClearDepthf(v);
  1901         AFTER_GL_CALL;
  1904 public:
  1905     void fDepthRange(GLclampf a, GLclampf b) {
  1906         if (IsGLES()) {
  1907             raw_fDepthRangef(a, b);
  1908         } else {
  1909             raw_fDepthRange(a, b);
  1913     void fClearDepth(GLclampf v) {
  1914         if (IsGLES()) {
  1915             raw_fClearDepthf(v);
  1916         } else {
  1917             raw_fClearDepth(v);
  1921     void* fMapBuffer(GLenum target, GLenum access) {
  1922         BEFORE_GL_CALL;
  1923         ASSERT_SYMBOL_PRESENT(fMapBuffer);
  1924         void *ret = mSymbols.fMapBuffer(target, access);
  1925         AFTER_GL_CALL;
  1926         return ret;
  1929     realGLboolean fUnmapBuffer(GLenum target) {
  1930         BEFORE_GL_CALL;
  1931         ASSERT_SYMBOL_PRESENT(fUnmapBuffer);
  1932         realGLboolean ret = mSymbols.fUnmapBuffer(target);
  1933         AFTER_GL_CALL;
  1934         return ret;
  1938 private:
  1939     GLuint raw_fCreateProgram() {
  1940         BEFORE_GL_CALL;
  1941         GLuint ret = mSymbols.fCreateProgram();
  1942         AFTER_GL_CALL;
  1943         return ret;
  1946     GLuint raw_fCreateShader(GLenum t) {
  1947         BEFORE_GL_CALL;
  1948         GLuint ret = mSymbols.fCreateShader(t);
  1949         AFTER_GL_CALL;
  1950         return ret;
  1953     void raw_fGenBuffers(GLsizei n, GLuint* names) {
  1954         BEFORE_GL_CALL;
  1955         mSymbols.fGenBuffers(n, names);
  1956         AFTER_GL_CALL;
  1959     void raw_fGenFramebuffers(GLsizei n, GLuint* names) {
  1960         BEFORE_GL_CALL;
  1961         mSymbols.fGenFramebuffers(n, names);
  1962         AFTER_GL_CALL;
  1965     void raw_fGenRenderbuffers(GLsizei n, GLuint* names) {
  1966         BEFORE_GL_CALL;
  1967         mSymbols.fGenRenderbuffers(n, names);
  1968         AFTER_GL_CALL;
  1971     void raw_fGenTextures(GLsizei n, GLuint* names) {
  1972         BEFORE_GL_CALL;
  1973         mSymbols.fGenTextures(n, names);
  1974         AFTER_GL_CALL;
  1977 public:
  1978     GLuint fCreateProgram() {
  1979         GLuint ret = raw_fCreateProgram();
  1980         TRACKING_CONTEXT(CreatedProgram(this, ret));
  1981         return ret;
  1984     GLuint fCreateShader(GLenum t) {
  1985         GLuint ret = raw_fCreateShader(t);
  1986         TRACKING_CONTEXT(CreatedShader(this, ret));
  1987         return ret;
  1990     void fGenBuffers(GLsizei n, GLuint* names) {
  1991         raw_fGenBuffers(n, names);
  1992         TRACKING_CONTEXT(CreatedBuffers(this, n, names));
  1995     void fGenFramebuffers(GLsizei n, GLuint* names) {
  1996         raw_fGenFramebuffers(n, names);
  1997         TRACKING_CONTEXT(CreatedFramebuffers(this, n, names));
  2000     void fGenRenderbuffers(GLsizei n, GLuint* names) {
  2001         raw_fGenRenderbuffers(n, names);
  2002         TRACKING_CONTEXT(CreatedRenderbuffers(this, n, names));
  2005     void fGenTextures(GLsizei n, GLuint* names) {
  2006         raw_fGenTextures(n, names);
  2007         TRACKING_CONTEXT(CreatedTextures(this, n, names));
  2010 private:
  2011     void raw_fDeleteProgram(GLuint program) {
  2012         BEFORE_GL_CALL;
  2013         mSymbols.fDeleteProgram(program);
  2014         AFTER_GL_CALL;
  2017     void raw_fDeleteShader(GLuint shader) {
  2018         BEFORE_GL_CALL;
  2019         mSymbols.fDeleteShader(shader);
  2020         AFTER_GL_CALL;
  2023     void raw_fDeleteBuffers(GLsizei n, const GLuint* names) {
  2024         BEFORE_GL_CALL;
  2025         mSymbols.fDeleteBuffers(n, names);
  2026         AFTER_GL_CALL;
  2029     void raw_fDeleteFramebuffers(GLsizei n, const GLuint* names) {
  2030         BEFORE_GL_CALL;
  2031         mSymbols.fDeleteFramebuffers(n, names);
  2032         AFTER_GL_CALL;
  2035     void raw_fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
  2036         BEFORE_GL_CALL;
  2037         mSymbols.fDeleteRenderbuffers(n, names);
  2038         AFTER_GL_CALL;
  2041     void raw_fDeleteTextures(GLsizei n, const GLuint* names) {
  2042         BEFORE_GL_CALL;
  2043         mSymbols.fDeleteTextures(n, names);
  2044         AFTER_GL_CALL;
  2047 public:
  2049     void fDeleteProgram(GLuint program) {
  2050         raw_fDeleteProgram(program);
  2051         TRACKING_CONTEXT(DeletedProgram(this, program));
  2054     void fDeleteShader(GLuint shader) {
  2055         raw_fDeleteShader(shader);
  2056         TRACKING_CONTEXT(DeletedShader(this, shader));
  2059     void fDeleteBuffers(GLsizei n, const GLuint* names) {
  2060         raw_fDeleteBuffers(n, names);
  2061         TRACKING_CONTEXT(DeletedBuffers(this, n, names));
  2064     void fDeleteFramebuffers(GLsizei n, const GLuint* names) {
  2065         if (mScreen) {
  2066             // Notify mScreen which framebuffers we're deleting.
  2067             // Otherwise, we will get framebuffer binding mispredictions.
  2068             for (int i = 0; i < n; i++) {
  2069                 mScreen->DeletingFB(names[i]);
  2073         if (n == 1 && *names == 0) {
  2074             // Deleting framebuffer 0 causes hangs on the DROID. See bug 623228.
  2075         } else {
  2076             raw_fDeleteFramebuffers(n, names);
  2078         TRACKING_CONTEXT(DeletedFramebuffers(this, n, names));
  2081     void fDeleteRenderbuffers(GLsizei n, const GLuint* names) {
  2082         raw_fDeleteRenderbuffers(n, names);
  2083         TRACKING_CONTEXT(DeletedRenderbuffers(this, n, names));
  2086     void fDeleteTextures(GLsizei n, const GLuint* names) {
  2087         raw_fDeleteTextures(n, names);
  2088         TRACKING_CONTEXT(DeletedTextures(this, n, names));
  2091     GLenum fGetGraphicsResetStatus() {
  2092         MOZ_ASSERT(mHasRobustness);
  2094         BEFORE_GL_CALL;
  2095         ASSERT_SYMBOL_PRESENT(fGetGraphicsResetStatus);
  2096         GLenum ret = mSymbols.fGetGraphicsResetStatus();
  2097         AFTER_GL_CALL;
  2098         return ret;
  2102 // -----------------------------------------------------------------------------
  2103 // Extension ARB_sync (GL)
  2104 public:
  2105     GLsync fFenceSync(GLenum condition, GLbitfield flags) {
  2106         BEFORE_GL_CALL;
  2107         ASSERT_SYMBOL_PRESENT(fFenceSync);
  2108         GLsync ret = mSymbols.fFenceSync(condition, flags);
  2109         AFTER_GL_CALL;
  2110         return ret;
  2113     realGLboolean fIsSync(GLsync sync) {
  2114         BEFORE_GL_CALL;
  2115         ASSERT_SYMBOL_PRESENT(fIsSync);
  2116         realGLboolean ret = mSymbols.fIsSync(sync);
  2117         AFTER_GL_CALL;
  2118         return ret;
  2121     void fDeleteSync(GLsync sync) {
  2122         BEFORE_GL_CALL;
  2123         ASSERT_SYMBOL_PRESENT(fDeleteSync);
  2124         mSymbols.fDeleteSync(sync);
  2125         AFTER_GL_CALL;
  2128     GLenum fClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
  2129         BEFORE_GL_CALL;
  2130         ASSERT_SYMBOL_PRESENT(fClientWaitSync);
  2131         GLenum ret = mSymbols.fClientWaitSync(sync, flags, timeout);
  2132         AFTER_GL_CALL;
  2133         return ret;
  2136     void fWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
  2137         BEFORE_GL_CALL;
  2138         ASSERT_SYMBOL_PRESENT(fWaitSync);
  2139         mSymbols.fWaitSync(sync, flags, timeout);
  2140         AFTER_GL_CALL;
  2143     void fGetInteger64v(GLenum pname, GLint64 *params) {
  2144         BEFORE_GL_CALL;
  2145         ASSERT_SYMBOL_PRESENT(fGetInteger64v);
  2146         mSymbols.fGetInteger64v(pname, params);
  2147         AFTER_GL_CALL;
  2150     void fGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
  2151         BEFORE_GL_CALL;
  2152         ASSERT_SYMBOL_PRESENT(fGetSynciv);
  2153         mSymbols.fGetSynciv(sync, pname, bufSize, length, values);
  2154         AFTER_GL_CALL;
  2158 // -----------------------------------------------------------------------------
  2159 // Extension OES_EGL_image (GLES)
  2160 public:
  2161     void fEGLImageTargetTexture2D(GLenum target, GLeglImage image) {
  2162         BEFORE_GL_CALL;
  2163         ASSERT_SYMBOL_PRESENT(fEGLImageTargetTexture2D);
  2164         mSymbols.fEGLImageTargetTexture2D(target, image);
  2165         AFTER_GL_CALL;
  2168     void fEGLImageTargetRenderbufferStorage(GLenum target, GLeglImage image)
  2170         BEFORE_GL_CALL;
  2171         ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage);
  2172         mSymbols.fEGLImageTargetRenderbufferStorage(target, image);
  2173         AFTER_GL_CALL;
  2177 // -----------------------------------------------------------------------------
  2178 // Package XXX_bind_buffer_offset
  2179 public:
  2180     void fBindBufferOffset(GLenum target, GLuint index, GLuint buffer, GLintptr offset)
  2182         BEFORE_GL_CALL;
  2183         ASSERT_SYMBOL_PRESENT(fBindBufferOffset);
  2184         mSymbols.fBindBufferOffset(target, index, buffer, offset);
  2185         AFTER_GL_CALL;
  2189 // -----------------------------------------------------------------------------
  2190 // Package XXX_draw_buffers
  2191 public:
  2192     void fDrawBuffers(GLsizei n, const GLenum* bufs) {
  2193         BEFORE_GL_CALL;
  2194         mSymbols.fDrawBuffers(n, bufs);
  2195         AFTER_GL_CALL;
  2199 // -----------------------------------------------------------------------------
  2200 // Package XXX_draw_instanced
  2201 public:
  2202     void fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
  2204         BeforeGLDrawCall();
  2205         raw_fDrawArraysInstanced(mode, first, count, primcount);
  2206         AfterGLDrawCall();
  2209     void fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount)
  2211         BeforeGLDrawCall();
  2212         raw_fDrawElementsInstanced(mode, count, type, indices, primcount);
  2213         AfterGLDrawCall();
  2216 private:
  2217     void raw_fDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
  2219         BEFORE_GL_CALL;
  2220         ASSERT_SYMBOL_PRESENT(fDrawArraysInstanced);
  2221         mSymbols.fDrawArraysInstanced(mode, first, count, primcount);
  2222         AFTER_GL_CALL;
  2225     void raw_fDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount)
  2227         BEFORE_GL_CALL;
  2228         ASSERT_SYMBOL_PRESENT(fDrawElementsInstanced);
  2229         mSymbols.fDrawElementsInstanced(mode, count, type, indices, primcount);
  2230         AFTER_GL_CALL;
  2233 // -----------------------------------------------------------------------------
  2234 // Feature draw_range_elements
  2235 public:
  2236     void fDrawRangeElements(GLenum mode, GLuint start, GLuint end,
  2237                             GLsizei count, GLenum type, const GLvoid* indices)
  2239         BeforeGLDrawCall();
  2240         raw_fDrawRangeElements(mode, start, end, count, type, indices);
  2241         AfterGLDrawCall();
  2244 private:
  2245     void raw_fDrawRangeElements(GLenum mode, GLuint start, GLuint end,
  2246                                 GLsizei count, GLenum type, const GLvoid* indices)
  2248         BEFORE_GL_CALL;
  2249         ASSERT_SYMBOL_PRESENT(fDrawRangeElements);
  2250         mSymbols.fDrawRangeElements(mode, start, end, count, type, indices);
  2251         AFTER_GL_CALL;
  2254 // -----------------------------------------------------------------------------
  2255 // Package XXX_framebuffer_blit
  2256 public:
  2257     // Draw/Read
  2258     void fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
  2259         BeforeGLDrawCall();
  2260         BeforeGLReadCall();
  2261         raw_fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
  2262         AfterGLReadCall();
  2263         AfterGLDrawCall();
  2267 private:
  2268     void raw_fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
  2269         BEFORE_GL_CALL;
  2270         ASSERT_SYMBOL_PRESENT(fBlitFramebuffer);
  2271         mSymbols.fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
  2272         AFTER_GL_CALL;
  2276 // -----------------------------------------------------------------------------
  2277 // Package XXX_framebuffer_multisample
  2278 public:
  2279     void fRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height) {
  2280         BEFORE_GL_CALL;
  2281         ASSERT_SYMBOL_PRESENT(fRenderbufferStorageMultisample);
  2282         mSymbols.fRenderbufferStorageMultisample(target, samples, internalFormat, width, height);
  2283         AFTER_GL_CALL;
  2287 // -----------------------------------------------------------------------------
  2288 // Package XXX_instanced_arrays
  2289 public:
  2290     void fVertexAttribDivisor(GLuint index, GLuint divisor)
  2292         BEFORE_GL_CALL;
  2293         ASSERT_SYMBOL_PRESENT(fVertexAttribDivisor);
  2294         mSymbols.fVertexAttribDivisor(index, divisor);
  2295         AFTER_GL_CALL;
  2299 // -----------------------------------------------------------------------------
  2300 // Package XXX_query_objects
  2301 /**
  2302  * XXX_query_objects:
  2303  *  - provide all followed entry points
  2305  * XXX_occlusion_query2:
  2306  *  - depends on XXX_query_objects
  2307  *  - provide ANY_SAMPLES_PASSED
  2309  * XXX_occlusion_query_boolean:
  2310  *  - depends on XXX_occlusion_query2
  2311  *  - provide ANY_SAMPLES_PASSED_CONSERVATIVE
  2312  */
  2313 public:
  2314     void fDeleteQueries(GLsizei n, const GLuint* names) {
  2315         BEFORE_GL_CALL;
  2316         ASSERT_SYMBOL_PRESENT(fDeleteQueries);
  2317         mSymbols.fDeleteQueries(n, names);
  2318         AFTER_GL_CALL;
  2319         TRACKING_CONTEXT(DeletedQueries(this, n, names));
  2322     void fGenQueries(GLsizei n, GLuint* names) {
  2323         BEFORE_GL_CALL;
  2324         ASSERT_SYMBOL_PRESENT(fGenQueries);
  2325         mSymbols.fGenQueries(n, names);
  2326         AFTER_GL_CALL;
  2327         TRACKING_CONTEXT(CreatedQueries(this, n, names));
  2330     void fGetQueryiv(GLenum target, GLenum pname, GLint* params) {
  2331         BEFORE_GL_CALL;
  2332         ASSERT_SYMBOL_PRESENT(fGetQueryiv);
  2333         mSymbols.fGetQueryiv(target, pname, params);
  2334         AFTER_GL_CALL;
  2337     void fGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) {
  2338         BEFORE_GL_CALL;
  2339         ASSERT_SYMBOL_PRESENT(fGetQueryObjectuiv);
  2340         mSymbols.fGetQueryObjectuiv(id, pname, params);
  2341         AFTER_GL_CALL;
  2344     realGLboolean fIsQuery(GLuint query) {
  2345         BEFORE_GL_CALL;
  2346         ASSERT_SYMBOL_PRESENT(fIsQuery);
  2347         realGLboolean retval = mSymbols.fIsQuery(query);
  2348         AFTER_GL_CALL;
  2349         return retval;
  2353 // -----------------------------------------------------------------------------
  2354 // Package XXX_get_query_object_iv
  2355 /**
  2356  * XXX_get_query_object_iv:
  2357  *  - depends on XXX_query_objects
  2358  *  - provide the followed entry point
  2360  * XXX_occlusion_query:
  2361  *  - depends on XXX_get_query_object_iv
  2362  *  - provide LOCAL_GL_SAMPLES_PASSED
  2363  */
  2364 public:
  2365     void fGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) {
  2366         BEFORE_GL_CALL;
  2367         ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv);
  2368         mSymbols.fGetQueryObjectiv(id, pname, params);
  2369         AFTER_GL_CALL;
  2373 // -----------------------------------------------------------------------------
  2374 // Package XXX_transform_feedback
  2375 public:
  2376     void fBindBufferBase(GLenum target, GLuint index, GLuint buffer)
  2378         BEFORE_GL_CALL;
  2379         ASSERT_SYMBOL_PRESENT(fBindBufferBase);
  2380         mSymbols.fBindBufferBase(target, index, buffer);
  2381         AFTER_GL_CALL;
  2384     void fBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
  2386         BEFORE_GL_CALL;
  2387         ASSERT_SYMBOL_PRESENT(fBindBufferRange);
  2388         mSymbols.fBindBufferRange(target, index, buffer, offset, size);
  2389         AFTER_GL_CALL;
  2392     void fBeginTransformFeedback(GLenum primitiveMode)
  2394         BEFORE_GL_CALL;
  2395         ASSERT_SYMBOL_PRESENT(fBeginTransformFeedback);
  2396         mSymbols.fBeginTransformFeedback(primitiveMode);
  2397         AFTER_GL_CALL;
  2400     void fEndTransformFeedback()
  2402         BEFORE_GL_CALL;
  2403         ASSERT_SYMBOL_PRESENT(fEndTransformFeedback);
  2404         mSymbols.fEndTransformFeedback();
  2405         AFTER_GL_CALL;
  2408     void fTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode)
  2410         BEFORE_GL_CALL;
  2411         ASSERT_SYMBOL_PRESENT(fTransformFeedbackVaryings);
  2412         mSymbols.fTransformFeedbackVaryings(program, count, varyings, bufferMode);
  2413         AFTER_GL_CALL;
  2416     void fGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name)
  2418         BEFORE_GL_CALL;
  2419         ASSERT_SYMBOL_PRESENT(fGetTransformFeedbackVarying);
  2420         mSymbols.fGetTransformFeedbackVarying(program, index, bufSize, length, size, type, name);
  2421         AFTER_GL_CALL;
  2424     void fGetIntegeri_v(GLenum param, GLuint index, GLint* values)
  2426         BEFORE_GL_CALL;
  2427         ASSERT_SYMBOL_PRESENT(fGetIntegeri_v);
  2428         mSymbols.fGetIntegeri_v(param, index, values);
  2429         AFTER_GL_CALL;
  2433 // -----------------------------------------------------------------------------
  2434 // Package XXX_vertex_array_object
  2435 public:
  2436     void fBindVertexArray(GLuint array)
  2438         BEFORE_GL_CALL;
  2439         ASSERT_SYMBOL_PRESENT(fBindVertexArray);
  2440         mSymbols.fBindVertexArray(array);
  2441         AFTER_GL_CALL;
  2444     void fDeleteVertexArrays(GLsizei n, const GLuint *arrays)
  2446         BEFORE_GL_CALL;
  2447         ASSERT_SYMBOL_PRESENT(fDeleteVertexArrays);
  2448         mSymbols.fDeleteVertexArrays(n, arrays);
  2449         AFTER_GL_CALL;
  2452     void fGenVertexArrays(GLsizei n, GLuint *arrays)
  2454         BEFORE_GL_CALL;
  2455         ASSERT_SYMBOL_PRESENT(fGenVertexArrays);
  2456         mSymbols.fGenVertexArrays(n, arrays);
  2457         AFTER_GL_CALL;
  2460     realGLboolean fIsVertexArray(GLuint array)
  2462         BEFORE_GL_CALL;
  2463         ASSERT_SYMBOL_PRESENT(fIsVertexArray);
  2464         realGLboolean ret = mSymbols.fIsVertexArray(array);
  2465         AFTER_GL_CALL;
  2466         return ret;
  2470 // -----------------------------------------------------------------------------
  2471 // Constructor
  2472 public:
  2474     typedef struct gfx::SurfaceCaps SurfaceCaps;
  2477 protected:
  2478     GLContext(const SurfaceCaps& caps,
  2479               GLContext* sharedContext = nullptr,
  2480               bool isOffscreen = false);
  2483 // -----------------------------------------------------------------------------
  2484 // Destructor
  2485 public:
  2486     virtual ~GLContext();
  2489 // -----------------------------------------------------------------------------
  2490 // Everything that isn't standard GL APIs
  2491 protected:
  2492     typedef class gfx::SharedSurface SharedSurface;
  2493     typedef gfx::SharedSurfaceType SharedSurfaceType;
  2494     typedef gfx::SurfaceFormat SurfaceFormat;
  2496     virtual bool MakeCurrentImpl(bool aForce) = 0;
  2498 public:
  2499 #ifdef MOZ_ENABLE_GL_TRACKING
  2500     static void StaticInit() {
  2501         PR_NewThreadPrivateIndex(&sCurrentGLContextTLS, nullptr);
  2503 #endif
  2505     bool MakeCurrent(bool aForce = false) {
  2506         if (IsDestroyed()) {
  2507             return false;
  2509 #ifdef MOZ_ENABLE_GL_TRACKING
  2510     PR_SetThreadPrivate(sCurrentGLContextTLS, this);
  2512     // XXX this assertion is disabled because it's triggering on Mac;
  2513     // we need to figure out why and reenable it.
  2514 #if 0
  2515         // IsOwningThreadCurrent is a bit of a misnomer;
  2516         // the "owning thread" is the creation thread,
  2517         // and the only thread that can own this.  We don't
  2518         // support contexts used on multiple threads.
  2519         NS_ASSERTION(IsOwningThreadCurrent(),
  2520                      "MakeCurrent() called on different thread than this context was created on!");
  2521 #endif
  2522 #endif
  2523         return MakeCurrentImpl(aForce);
  2526     virtual bool Init() = 0;
  2528     virtual bool SetupLookupFunction() = 0;
  2530     virtual void ReleaseSurface() {}
  2532     // Mark this context as destroyed.  This will nullptr out all
  2533     // the GL function pointers!
  2534     void MarkDestroyed();
  2536     bool IsDestroyed() {
  2537         // MarkDestroyed will mark all these as null.
  2538         return mSymbols.fUseProgram == nullptr;
  2541     GLContext *GetSharedContext() { return mSharedContext; }
  2543     /**
  2544      * Returns true if the thread on which this context was created is the currently
  2545      * executing thread.
  2546      */
  2547     bool IsOwningThreadCurrent();
  2548     void DispatchToOwningThread(nsIRunnable *event);
  2550     static void PlatformStartup();
  2552 public:
  2553     /**
  2554      * If this context wraps a double-buffered target, swap the back
  2555      * and front buffers.  It should be assumed that after a swap, the
  2556      * contents of the new back buffer are undefined.
  2557      */
  2558     virtual bool SwapBuffers() { return false; }
  2560     /**
  2561      * Defines a two-dimensional texture image for context target surface
  2562      */
  2563     virtual bool BindTexImage() { return false; }
  2564     /*
  2565      * Releases a color buffer that is being used as a texture
  2566      */
  2567     virtual bool ReleaseTexImage() { return false; }
  2569     // Before reads from offscreen texture
  2570     void GuaranteeResolve();
  2572     /*
  2573      * Resize the current offscreen buffer.  Returns true on success.
  2574      * If it returns false, the context should be treated as unusable
  2575      * and should be recreated.  After the resize, the viewport is not
  2576      * changed; glViewport should be called as appropriate.
  2578      * Only valid if IsOffscreen() returns true.
  2579      */
  2580     bool ResizeOffscreen(const gfx::IntSize& size) {
  2581         return ResizeScreenBuffer(size);
  2584     /*
  2585      * Return size of this offscreen context.
  2587      * Only valid if IsOffscreen() returns true.
  2588      */
  2589     const gfx::IntSize& OffscreenSize() const;
  2591     void BindFB(GLuint fb) {
  2592         fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
  2593         MOZ_ASSERT(!fb || fIsFramebuffer(fb));
  2596     void BindDrawFB(GLuint fb) {
  2597         fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb);
  2600     void BindReadFB(GLuint fb) {
  2601         fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb);
  2604     GLuint GetDrawFB() {
  2605         if (mScreen)
  2606             return mScreen->GetDrawFB();
  2608         GLuint ret = 0;
  2609         GetUIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, &ret);
  2610         return ret;
  2613     GLuint GetReadFB() {
  2614         if (mScreen)
  2615             return mScreen->GetReadFB();
  2617         GLenum bindEnum = IsSupported(GLFeature::framebuffer_blit)
  2618                             ? LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT
  2619                             : LOCAL_GL_FRAMEBUFFER_BINDING;
  2621         GLuint ret = 0;
  2622         GetUIntegerv(bindEnum, &ret);
  2623         return ret;
  2626     GLuint GetFB() {
  2627         if (mScreen) {
  2628             // This has a very important extra assert that checks that we're
  2629             // not accidentally ignoring a situation where the draw and read
  2630             // FBs differ.
  2631             return mScreen->GetFB();
  2634         GLuint ret = 0;
  2635         GetUIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &ret);
  2636         return ret;
  2639 private:
  2640     void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
  2641         switch (precisiontype) {
  2642             case LOCAL_GL_LOW_FLOAT:
  2643             case LOCAL_GL_MEDIUM_FLOAT:
  2644             case LOCAL_GL_HIGH_FLOAT:
  2645                 // Assume IEEE 754 precision
  2646                 range[0] = 127;
  2647                 range[1] = 127;
  2648                 *precision = 23;
  2649                 break;
  2650             case LOCAL_GL_LOW_INT:
  2651             case LOCAL_GL_MEDIUM_INT:
  2652             case LOCAL_GL_HIGH_INT:
  2653                 // Some (most) hardware only supports single-precision floating-point numbers,
  2654                 // which can accurately represent integers up to +/-16777216
  2655                 range[0] = 24;
  2656                 range[1] = 24;
  2657                 *precision = 0;
  2658                 break;
  2662 public:
  2664     void ForceDirtyScreen();
  2665     void CleanDirtyScreen();
  2667     virtual GLenum GetPreferredARGB32Format() const { return LOCAL_GL_RGBA; }
  2669     virtual bool RenewSurface() { return false; }
  2671     // Shared code for GL extensions and GLX extensions.
  2672     static bool ListHasExtension(const GLubyte *extensions,
  2673                                  const char *extension);
  2675     GLint GetMaxTextureImageSize() { return mMaxTextureImageSize; }
  2677 public:
  2678     /**
  2679      * Context reset constants.
  2680      * These are used to determine who is guilty when a context reset
  2681      * happens.
  2682      */
  2683     enum ContextResetARB {
  2684         CONTEXT_NO_ERROR = 0,
  2685         CONTEXT_GUILTY_CONTEXT_RESET_ARB = 0x8253,
  2686         CONTEXT_INNOCENT_CONTEXT_RESET_ARB = 0x8254,
  2687         CONTEXT_UNKNOWN_CONTEXT_RESET_ARB = 0x8255
  2688     };
  2690 public:
  2691     std::map<GLuint, SharedSurface_GL*> mFBOMapping;
  2693     enum {
  2694         DebugEnabled = 1 << 0,
  2695         DebugTrace = 1 << 1,
  2696         DebugAbortOnError = 1 << 2
  2697     };
  2699     static uint32_t sDebugMode;
  2701     static uint32_t DebugMode() {
  2702 #ifdef DEBUG
  2703         return sDebugMode;
  2704 #else
  2705         return 0;
  2706 #endif
  2709 protected:
  2710     nsRefPtr<GLContext> mSharedContext;
  2712     // The thread on which this context was created.
  2713     nsCOMPtr<nsIThread> mOwningThread;
  2715     GLContextSymbols mSymbols;
  2717 #ifdef DEBUG
  2718     // GLDebugMode will check that we don't send call
  2719     // to a GLContext that isn't current on the current
  2720     // thread.
  2721     // Store the current context when binding to thread local
  2722     // storage to support DebugMode on an arbitrary thread.
  2723     static unsigned sCurrentGLContextTLS;
  2724 #endif
  2726     ScopedDeletePtr<GLBlitHelper> mBlitHelper;
  2727     ScopedDeletePtr<GLBlitTextureImageHelper> mBlitTextureImageHelper;
  2728     ScopedDeletePtr<GLReadTexImageHelper> mReadTexImageHelper;
  2730 public:
  2731     GLBlitHelper* BlitHelper();
  2732     GLBlitTextureImageHelper* BlitTextureImageHelper();
  2733     GLReadTexImageHelper* ReadTexImageHelper();
  2735     // Assumes shares are created by all sharing with the same global context.
  2736     bool SharesWith(const GLContext* other) const {
  2737         MOZ_ASSERT(!this->mSharedContext || !this->mSharedContext->mSharedContext);
  2738         MOZ_ASSERT(!other->mSharedContext || !other->mSharedContext->mSharedContext);
  2739         MOZ_ASSERT(!this->mSharedContext ||
  2740                    !other->mSharedContext ||
  2741                    this->mSharedContext == other->mSharedContext);
  2743         const GLContext* thisShared = this->mSharedContext ? this->mSharedContext
  2744                                                            : this;
  2745         const GLContext* otherShared = other->mSharedContext ? other->mSharedContext
  2746                                                              : other;
  2748         return thisShared == otherShared;
  2751     bool InitOffscreen(const gfx::IntSize& size, const SurfaceCaps& caps) {
  2752         if (!CreateScreenBuffer(size, caps))
  2753             return false;
  2755         MakeCurrent();
  2756         fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
  2757         fScissor(0, 0, size.width, size.height);
  2758         fViewport(0, 0, size.width, size.height);
  2760         mCaps = mScreen->Caps();
  2761         if (mCaps.any)
  2762             DetermineCaps();
  2764         UpdateGLFormats(mCaps);
  2765         UpdatePixelFormat();
  2767         return true;
  2770 protected:
  2771     // Note that it does -not- clear the resized buffers.
  2772     bool CreateScreenBuffer(const gfx::IntSize& size, const SurfaceCaps& caps) {
  2773         if (!IsOffscreenSizeAllowed(size))
  2774             return false;
  2776         SurfaceCaps tryCaps = caps;
  2777         if (tryCaps.antialias) {
  2778             // AA path
  2779             if (CreateScreenBufferImpl(size, tryCaps))
  2780                 return true;
  2782             NS_WARNING("CreateScreenBuffer failed to initialize an AA context! Falling back to no AA...");
  2783             tryCaps.antialias = false;
  2785         MOZ_ASSERT(!tryCaps.antialias);
  2787         if (CreateScreenBufferImpl(size, tryCaps))
  2788             return true;
  2790         NS_WARNING("CreateScreenBuffer failed to initialize non-AA context!");
  2791         return false;
  2794     bool CreateScreenBufferImpl(const gfx::IntSize& size,
  2795                                 const SurfaceCaps& caps);
  2797 public:
  2798     bool ResizeScreenBuffer(const gfx::IntSize& size);
  2800 protected:
  2801     SurfaceCaps mCaps;
  2802     nsAutoPtr<GLFormats> mGLFormats;
  2803     nsAutoPtr<PixelBufferFormat> mPixelFormat;
  2805 public:
  2806     void DetermineCaps();
  2807     const SurfaceCaps& Caps() const {
  2808         return mCaps;
  2811     // Only varies based on bpp16 and alpha.
  2812     GLFormats ChooseGLFormats(const SurfaceCaps& caps) const;
  2813     void UpdateGLFormats(const SurfaceCaps& caps) {
  2814         mGLFormats = new GLFormats(ChooseGLFormats(caps));
  2817     const GLFormats& GetGLFormats() const {
  2818         MOZ_ASSERT(mGLFormats);
  2819         return *mGLFormats;
  2822     PixelBufferFormat QueryPixelFormat();
  2823     void UpdatePixelFormat();
  2825     const PixelBufferFormat& GetPixelFormat() const {
  2826         MOZ_ASSERT(mPixelFormat);
  2827         return *mPixelFormat;
  2830     bool IsFramebufferComplete(GLuint fb, GLenum* status = nullptr);
  2832     // Does not check completeness.
  2833     void AttachBuffersToFB(GLuint colorTex, GLuint colorRB,
  2834                            GLuint depthRB, GLuint stencilRB,
  2835                            GLuint fb, GLenum target = LOCAL_GL_TEXTURE_2D);
  2837     // Passing null is fine if the value you'd get is 0.
  2838     bool AssembleOffscreenFBs(const GLuint colorMSRB,
  2839                               const GLuint depthRB,
  2840                               const GLuint stencilRB,
  2841                               const GLuint texture,
  2842                               GLuint* drawFB,
  2843                               GLuint* readFB);
  2845 protected:
  2846     friend class GLScreenBuffer;
  2847     GLScreenBuffer* mScreen;
  2849     void DestroyScreenBuffer();
  2851     SharedSurface_GL* mLockedSurface;
  2853 public:
  2854     void LockSurface(SharedSurface_GL* surf) {
  2855         MOZ_ASSERT(!mLockedSurface);
  2856         mLockedSurface = surf;
  2859     void UnlockSurface(SharedSurface_GL* surf) {
  2860         MOZ_ASSERT(mLockedSurface == surf);
  2861         mLockedSurface = nullptr;
  2864     SharedSurface_GL* GetLockedSurface() const {
  2865         return mLockedSurface;
  2868     bool IsOffscreen() const {
  2869         return mScreen;
  2872     GLScreenBuffer* Screen() const {
  2873         return mScreen;
  2876     bool PublishFrame();
  2877     SharedSurface_GL* RequestFrame();
  2879     /* Clear to transparent black, with 0 depth and stencil,
  2880      * while preserving current ClearColor etc. values.
  2881      * Useful for resizing offscreen buffers.
  2882      */
  2883     void ClearSafely();
  2885     bool WorkAroundDriverBugs() const { return mWorkAroundDriverBugs; }
  2887 protected:
  2888     nsRefPtr<TextureGarbageBin> mTexGarbageBin;
  2890 public:
  2891     TextureGarbageBin* TexGarbageBin() {
  2892         MOZ_ASSERT(mTexGarbageBin);
  2893         return mTexGarbageBin;
  2896     void EmptyTexGarbageBin();
  2898     bool IsOffscreenSizeAllowed(const gfx::IntSize& aSize) const;
  2900 protected:
  2901     bool InitWithPrefix(const char *prefix, bool trygl);
  2903     void InitExtensions();
  2905     GLint mViewportRect[4];
  2906     GLint mScissorRect[4];
  2908     GLint mMaxTextureSize;
  2909     GLint mMaxCubeMapTextureSize;
  2910     GLint mMaxTextureImageSize;
  2911     GLint mMaxRenderbufferSize;
  2912     GLsizei mMaxSamples;
  2913     bool mNeedsTextureSizeChecks;
  2914     bool mWorkAroundDriverBugs;
  2916     bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const {
  2917         if (mNeedsTextureSizeChecks) {
  2918             // some drivers incorrectly handle some large texture sizes that are below the
  2919             // max texture size that they report. So we check ourselves against our own values
  2920             // (mMax[CubeMap]TextureSize).
  2921             // see bug 737182 for Mac Intel 2D textures
  2922             // see bug 684882 for Mac Intel cube map textures
  2923             // see bug 814716 for Mesa Nouveau
  2924             GLsizei maxSize = target == LOCAL_GL_TEXTURE_CUBE_MAP ||
  2925                                 (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
  2926                                 target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
  2927                               ? mMaxCubeMapTextureSize
  2928                               : mMaxTextureSize;
  2929             return width <= maxSize && height <= maxSize;
  2931         return true;
  2935 public:
  2937     void fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
  2938         if (mViewportRect[0] == x &&
  2939             mViewportRect[1] == y &&
  2940             mViewportRect[2] == width &&
  2941             mViewportRect[3] == height)
  2943             return;
  2945         mViewportRect[0] = x;
  2946         mViewportRect[1] = y;
  2947         mViewportRect[2] = width;
  2948         mViewportRect[3] = height;
  2949         BEFORE_GL_CALL;
  2950         mSymbols.fViewport(x, y, width, height);
  2951         AFTER_GL_CALL;
  2954 #undef ASSERT_SYMBOL_PRESENT
  2956 #ifdef MOZ_ENABLE_GL_TRACKING
  2957     void CreatedProgram(GLContext *aOrigin, GLuint aName);
  2958     void CreatedShader(GLContext *aOrigin, GLuint aName);
  2959     void CreatedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
  2960     void CreatedQueries(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
  2961     void CreatedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
  2962     void CreatedFramebuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
  2963     void CreatedRenderbuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
  2964     void DeletedProgram(GLContext *aOrigin, GLuint aName);
  2965     void DeletedShader(GLContext *aOrigin, GLuint aName);
  2966     void DeletedBuffers(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
  2967     void DeletedQueries(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
  2968     void DeletedTextures(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
  2969     void DeletedFramebuffers(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
  2970     void DeletedRenderbuffers(GLContext *aOrigin, GLsizei aCount, const GLuint *aNames);
  2972     void SharedContextDestroyed(GLContext *aChild);
  2973     void ReportOutstandingNames();
  2975     struct NamedResource {
  2976         NamedResource()
  2977             : origin(nullptr), name(0), originDeleted(false)
  2978         { }
  2980         NamedResource(GLContext *aOrigin, GLuint aName)
  2981             : origin(aOrigin), name(aName), originDeleted(false)
  2982         { }
  2984         GLContext *origin;
  2985         GLuint name;
  2986         bool originDeleted;
  2988         // for sorting
  2989         bool operator<(const NamedResource& aOther) const {
  2990             if (intptr_t(origin) < intptr_t(aOther.origin))
  2991                 return true;
  2992             if (name < aOther.name)
  2993                 return true;
  2994             return false;
  2996         bool operator==(const NamedResource& aOther) const {
  2997             return origin == aOther.origin &&
  2998                 name == aOther.name &&
  2999                 originDeleted == aOther.originDeleted;
  3001     };
  3003     nsTArray<NamedResource> mTrackedPrograms;
  3004     nsTArray<NamedResource> mTrackedShaders;
  3005     nsTArray<NamedResource> mTrackedTextures;
  3006     nsTArray<NamedResource> mTrackedFramebuffers;
  3007     nsTArray<NamedResource> mTrackedRenderbuffers;
  3008     nsTArray<NamedResource> mTrackedBuffers;
  3009     nsTArray<NamedResource> mTrackedQueries;
  3010 #endif
  3011 };
  3013 bool DoesStringMatch(const char* aString, const char *aWantedString);
  3016 } /* namespace gl */
  3017 } /* namespace mozilla */
  3019 #endif /* GLCONTEXT_H_ */

mercurial