LCOV - code coverage report
Current view: directory - objdir/dist/include - GLContext.h (source / functions) Found Hit Coverage
Test: app.info Lines: 1044 10 1.0 %
Date: 2012-06-02 Functions: 210 2 1.0 %

       1                 : /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  *   Mozilla Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2010
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Vladimir Vukicevic <vladimir@pobox.com>
      24                 :  *   Mark Steele <mwsteele@gmail.com>
      25                 :  *   Bas Schouten <bschouten@mozilla.com>
      26                 :  *   Jeff Gilbert <jgilbert@mozilla.com>
      27                 :  *
      28                 :  * Alternatively, the contents of this file may be used under the terms of
      29                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      30                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      31                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      32                 :  * of those above. If you wish to allow use of your version of this file only
      33                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      34                 :  * use your version of this file under the terms of the MPL, indicate your
      35                 :  * decision by deleting the provisions above and replace them with the notice
      36                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      37                 :  * the provisions above, a recipient may use your version of this file under
      38                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      39                 :  *
      40                 :  * ***** END LICENSE BLOCK ***** */
      41                 : 
      42                 : #ifndef GLCONTEXT_H_
      43                 : #define GLCONTEXT_H_
      44                 : 
      45                 : #include <stdio.h>
      46                 : #if defined(XP_UNIX)
      47                 : #include <stdint.h>
      48                 : #endif
      49                 : #include <string.h>
      50                 : #include <ctype.h>
      51                 : 
      52                 : #ifdef WIN32
      53                 : #include <windows.h>
      54                 : #endif
      55                 : 
      56                 : #include "GLDefs.h"
      57                 : #include "gfxASurface.h"
      58                 : #include "gfxImageSurface.h"
      59                 : #include "gfxContext.h"
      60                 : #include "gfxRect.h"
      61                 : #include "nsISupportsImpl.h"
      62                 : #include "prlink.h"
      63                 : 
      64                 : #include "nsDataHashtable.h"
      65                 : #include "nsHashKeys.h"
      66                 : #include "nsRegion.h"
      67                 : #include "nsAutoPtr.h"
      68                 : #include "nsThreadUtils.h"
      69                 : 
      70                 : #if defined(MOZ_PLATFORM_MAEMO) || defined(ANDROID) || defined(MOZ_EGL_XRENDER_COMPOSITE)
      71                 : #define USE_GLES2 1
      72                 : #endif
      73                 : 
      74                 : typedef char realGLboolean;
      75                 : 
      76                 : #include "GLContextSymbols.h"
      77                 : 
      78                 : namespace mozilla {
      79                 :   namespace layers {
      80                 :     class LayerManagerOGL;
      81                 :     class ColorTextureLayerProgram;
      82                 :   }
      83                 : 
      84                 : namespace gl {
      85                 : class GLContext;
      86                 : 
      87                 : class LibrarySymbolLoader
      88                 : {
      89                 : public:
      90                 :     bool OpenLibrary(const char *library);
      91                 : 
      92                 :     typedef PRFuncPtr (GLAPIENTRY * PlatformLookupFunction) (const char *);
      93                 : 
      94                 :     enum {
      95                 :         MAX_SYMBOL_NAMES = 5,
      96                 :         MAX_SYMBOL_LENGTH = 128
      97                 :     };
      98                 : 
      99                 :     typedef struct {
     100                 :         PRFuncPtr *symPointer;
     101                 :         const char *symNames[MAX_SYMBOL_NAMES];
     102                 :     } SymLoadStruct;
     103                 : 
     104                 :     bool LoadSymbols(SymLoadStruct *firstStruct,
     105                 :                        bool tryplatform = false,
     106                 :                        const char *prefix = nsnull);
     107                 : 
     108                 :     /*
     109                 :      * Static version of the functions in this class
     110                 :      */
     111                 :     static PRFuncPtr LookupSymbol(PRLibrary *lib,
     112                 :                                   const char *symname,
     113                 :                                   PlatformLookupFunction lookupFunction = nsnull);
     114                 :     static bool LoadSymbols(PRLibrary *lib,
     115                 :                               SymLoadStruct *firstStruct,
     116                 :                               PlatformLookupFunction lookupFunction = nsnull,
     117                 :                               const char *prefix = nsnull);
     118                 : protected:
     119                 :     LibrarySymbolLoader() {
     120                 :         mLibrary = nsnull;
     121                 :         mLookupFunc = nsnull;
     122                 :     }
     123                 : 
     124                 :     PRLibrary *mLibrary;
     125                 :     PlatformLookupFunction mLookupFunc;
     126                 : };
     127                 : 
     128                 : enum ShaderProgramType {
     129                 :     RGBALayerProgramType,
     130                 :     BGRALayerProgramType,
     131                 :     RGBXLayerProgramType,
     132                 :     BGRXLayerProgramType,
     133                 :     RGBARectLayerProgramType,
     134                 :     ColorLayerProgramType,
     135                 :     YCbCrLayerProgramType,
     136                 :     ComponentAlphaPass1ProgramType,
     137                 :     ComponentAlphaPass2ProgramType,
     138                 :     Copy2DProgramType,
     139                 :     Copy2DRectProgramType,
     140                 :     NumProgramTypes
     141                 : };
     142                 : 
     143                 : 
     144                 : /**
     145                 :  * A TextureImage encapsulates a surface that can be drawn to by a
     146                 :  * Thebes gfxContext and (hopefully efficiently!) synchronized to a
     147                 :  * texture in the server.  TextureImages are associated with one and
     148                 :  * only one GLContext.
     149                 :  *
     150                 :  * Implementation note: TextureImages attempt to unify two categories
     151                 :  * of backends
     152                 :  *
     153                 :  *  (1) proxy to server-side object that can be bound to a texture;
     154                 :  *      e.g. Pixmap on X11.
     155                 :  *
     156                 :  *  (2) efficient manager of texture memory; e.g. by having clients draw
     157                 :  *      into a scratch buffer which is then uploaded with
     158                 :  *      glTexSubImage2D().
     159                 :  */
     160                 : class TextureImage
     161                 : {
     162               0 :     NS_INLINE_DECL_REFCOUNTING(TextureImage)
     163                 : public:
     164                 :     enum TextureState
     165                 :     {
     166                 :       Created, // Texture created, but has not had glTexImage called to initialize it.
     167                 :       Allocated,  // Texture memory exists, but contents are invalid.
     168                 :       Valid  // Texture fully ready to use.
     169                 :     };
     170                 : 
     171                 :     typedef gfxASurface::gfxContentType ContentType;
     172                 : 
     173                 :     virtual ~TextureImage() {}
     174                 : 
     175                 :     /**
     176                 :      * Returns a gfxASurface for updating |aRegion| of the client's
     177                 :      * image if successul, NULL if not.  |aRegion|'s bounds must fit
     178                 :      * within Size(); its coordinate space (if any) is ignored.  If
     179                 :      * the update begins successfully, the returned gfxASurface is
     180                 :      * owned by this.  Otherwise, NULL is returned.
     181                 :      *
     182                 :      * |aRegion| is an inout param: the returned region is what the
     183                 :      * client must repaint.  Category (1) regions above can
     184                 :      * efficiently handle repaints to "scattered" regions, while (2)
     185                 :      * can only efficiently handle repaints to rects.
     186                 :      *
     187                 :      * Painting the returned surface outside of |aRegion| results 
     188                 :      * in undefined behavior.
     189                 :      *
     190                 :      * BeginUpdate() calls cannot be "nested", and each successful
     191                 :      * BeginUpdate() must be followed by exactly one EndUpdate() (see
     192                 :      * below).  Failure to do so can leave this in a possibly
     193                 :      * inconsistent state.  Unsuccessful BeginUpdate()s must not be
     194                 :      * followed by EndUpdate().
     195                 :      */
     196                 :     virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion) = 0;
     197                 :     /**
     198                 :      * Retrieves the region that will require updating, given a
     199                 :      * region that needs to be updated. This can be used for
     200                 :      * making decisions about updating before calling BeginUpdate().
     201                 :      *
     202                 :      * |aRegion| is an inout param.
     203                 :      */
     204                 :     virtual void GetUpdateRegion(nsIntRegion& aForRegion) {
     205                 :     };
     206                 :     /**
     207                 :      * Finish the active update and synchronize with the server, if
     208                 :      * necessary.
     209                 :      *
     210                 :      * BeginUpdate() must have been called exactly once before
     211                 :      * EndUpdate().
     212                 :      */
     213                 :     virtual void EndUpdate() = 0;
     214                 : 
     215                 :     /**
     216                 :      * The Image may contain several textures for different regions (tiles).
     217                 :      * These functions iterate over each sub texture image tile.
     218                 :      */
     219                 :     virtual void BeginTileIteration() {
     220                 :     };
     221                 : 
     222                 :     virtual bool NextTile() {
     223                 :         return false;
     224                 :     };
     225                 : 
     226                 :     virtual nsIntRect GetTileRect() {
     227                 :         return nsIntRect(nsIntPoint(0,0), mSize);
     228                 :     };
     229                 : 
     230                 :     virtual GLuint GetTextureID() = 0;
     231                 : 
     232                 :     virtual PRUint32 GetTileCount() {
     233                 :         return 1;
     234                 :     };
     235                 : 
     236                 :     /**
     237                 :      * Set this TextureImage's size, and ensure a texture has been
     238                 :      * allocated.  Must not be called between BeginUpdate and EndUpdate.
     239                 :      * After a resize, the contents are undefined.
     240                 :      *
     241                 :      * If this isn't implemented by a subclass, it will just perform
     242                 :      * a dummy BeginUpdate/EndUpdate pair.
     243                 :      */
     244                 :     virtual void Resize(const nsIntSize& aSize) {
     245                 :         mSize = aSize;
     246                 :         nsIntRegion r(nsIntRect(0, 0, aSize.width, aSize.height));
     247                 :         BeginUpdate(r);
     248                 :         EndUpdate();
     249                 :     }
     250                 : 
     251                 :     /**
     252                 :      * Mark this texture as having valid contents. Call this after modifying
     253                 :      * the texture contents externally.
     254                 :      */
     255                 :     virtual void MarkValid() {}
     256                 : 
     257                 :     /**
     258                 :      * aSurf - the source surface to update from
     259                 :      * aRegion - the region in this image to update
     260                 :      * aFrom - offset in the source to update from
     261                 :      */
     262                 :     virtual bool DirectUpdate(gfxASurface *aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0)) = 0;
     263                 : 
     264                 :     virtual void BindTexture(GLenum aTextureUnit) = 0;
     265                 :     virtual void ReleaseTexture() {};
     266                 : 
     267                 :     void BindTextureAndApplyFilter(GLenum aTextureUnit) {
     268                 :         BindTexture(aTextureUnit);
     269                 :         ApplyFilter();
     270                 :     }
     271                 : 
     272                 :     class ScopedBindTexture
     273                 :     {
     274                 :     public:
     275               0 :         ScopedBindTexture(TextureImage *aTexture, GLenum aTextureUnit) :
     276               0 :           mTexture(aTexture)
     277                 :         {
     278               0 :             if (mTexture) {
     279               0 :                 mTexture->BindTexture(aTextureUnit);
     280                 :             }
     281               0 :         }
     282                 : 
     283               0 :         ~ScopedBindTexture()
     284                 :         {
     285               0 :             if (mTexture) {
     286               0 :                 mTexture->ReleaseTexture();
     287                 :             }       
     288               0 :         }
     289                 : 
     290                 :     protected:
     291                 :         TextureImage *mTexture;
     292                 :     };
     293                 : 
     294                 :     class ScopedBindTextureAndApplyFilter
     295                 :         : public ScopedBindTexture
     296               0 :     {
     297                 :     public:
     298               0 :         ScopedBindTextureAndApplyFilter(TextureImage *aTexture, GLenum aTextureUnit) :
     299               0 :           ScopedBindTexture(aTexture, aTextureUnit)
     300                 :         {
     301               0 :             if (mTexture) {
     302               0 :                 mTexture->ApplyFilter();
     303                 :             }
     304               0 :         }
     305                 :     };
     306                 : 
     307                 :     /**
     308                 :      * Returns the shader program type that should be used to render
     309                 :      * this texture. Only valid after a matching BeginUpdate/EndUpdate
     310                 :      * pair have been called.
     311                 :      */
     312                 :     virtual ShaderProgramType GetShaderProgramType()
     313                 :     {
     314                 :          return mShaderType;
     315                 :     }
     316                 : 
     317                 :     /** Can be called safely at any time. */
     318                 : 
     319                 :     /**
     320                 :      * If this TextureImage has a permanent gfxASurface backing,
     321                 :      * return it.  Otherwise return NULL.
     322                 :      */
     323                 :     virtual already_AddRefed<gfxASurface> GetBackingSurface()
     324                 :     { return NULL; }
     325                 : 
     326               0 :     const nsIntSize& GetSize() const { return mSize; }
     327               0 :     ContentType GetContentType() const { return mContentType; }
     328                 :     virtual bool InUpdate() const = 0;
     329               0 :     GLenum GetWrapMode() const { return mWrapMode; }
     330                 : 
     331               0 :     void SetFilter(gfxPattern::GraphicsFilter aFilter) { mFilter = aFilter; }
     332                 : 
     333                 :     /**
     334                 :      * Applies this TextureImage's filter, assuming that its texture is
     335                 :      * the currently bound texture.
     336                 :      */
     337                 :     virtual void ApplyFilter() = 0;
     338                 : 
     339                 : protected:
     340                 :     friend class GLContext;
     341                 : 
     342                 :     /**
     343                 :      * After the ctor, the TextureImage is invalid.  Implementations
     344                 :      * must allocate resources successfully before returning the new
     345                 :      * TextureImage from GLContext::CreateTextureImage().  That is,
     346                 :      * clients must not be given partially-constructed TextureImages.
     347                 :      */
     348                 :     TextureImage(const nsIntSize& aSize,
     349                 :                  GLenum aWrapMode, ContentType aContentType,
     350                 :                  bool aIsRGB = false)
     351                 :         : mSize(aSize)
     352                 :         , mWrapMode(aWrapMode)
     353                 :         , mContentType(aContentType)
     354                 :     {}
     355                 : 
     356                 :     nsIntSize mSize;
     357                 :     GLenum mWrapMode;
     358                 :     ContentType mContentType;
     359                 :     ShaderProgramType mShaderType;
     360                 :     gfxPattern::GraphicsFilter mFilter;
     361                 : };
     362                 : 
     363                 : /**
     364                 :  * BasicTextureImage is the baseline TextureImage implementation ---
     365                 :  * it updates its texture by allocating a scratch buffer for the
     366                 :  * client to draw into, then using glTexSubImage2D() to upload the new
     367                 :  * pixels.  Platforms must provide the code to create a new surface
     368                 :  * into which the updated pixels will be drawn, and the code to
     369                 :  * convert the update surface's pixels into an image on which we can
     370                 :  * glTexSubImage2D().
     371                 :  */
     372                 : class BasicTextureImage
     373                 :     : public TextureImage
     374                 : {
     375                 : public:
     376                 :     typedef gfxASurface::gfxImageFormat ImageFormat;
     377                 :     virtual ~BasicTextureImage();
     378                 : 
     379                 :     BasicTextureImage(GLuint aTexture,
     380                 :                       const nsIntSize& aSize,
     381                 :                       GLenum aWrapMode,
     382                 :                       ContentType aContentType,
     383                 :                       GLContext* aContext)
     384                 :         : TextureImage(aSize, aWrapMode, aContentType)
     385                 :         , mTexture(aTexture)
     386                 :         , mTextureState(Created)
     387                 :         , mGLContext(aContext)
     388                 :         , mUpdateOffset(0, 0)
     389                 :     {}
     390                 : 
     391                 :     virtual void BindTexture(GLenum aTextureUnit);
     392                 : 
     393                 :     virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
     394                 :     virtual void GetUpdateRegion(nsIntRegion& aForRegion);
     395                 :     virtual void EndUpdate();
     396                 :     virtual bool DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0));
     397                 :     virtual GLuint GetTextureID() { return mTexture; };
     398                 :     // Returns a surface to draw into
     399                 :     virtual already_AddRefed<gfxASurface>
     400                 :       GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt);
     401                 : 
     402                 :     virtual void MarkValid() { mTextureState = Valid; }
     403                 : 
     404                 :     // Call when drawing into the update surface is complete.
     405                 :     // Returns true if textures should be upload with a relative 
     406                 :     // offset - See UploadSurfaceToTexture.
     407                 :     virtual bool FinishedSurfaceUpdate();
     408                 : 
     409                 :     // Call after surface data has been uploaded to a texture.
     410                 :     virtual void FinishedSurfaceUpload();
     411                 : 
     412                 :     virtual bool InUpdate() const { return !!mUpdateSurface; }
     413                 : 
     414                 :     virtual void Resize(const nsIntSize& aSize);
     415                 : 
     416                 :     virtual void ApplyFilter();
     417                 : protected:
     418                 : 
     419                 :     GLuint mTexture;
     420                 :     TextureState mTextureState;
     421                 :     GLContext* mGLContext;
     422                 :     nsRefPtr<gfxASurface> mUpdateSurface;
     423                 :     nsIntRegion mUpdateRegion;
     424                 : 
     425                 :     // The offset into the update surface at which the update rect is located.
     426                 :     nsIntPoint mUpdateOffset;
     427                 : };
     428                 : 
     429                 : /**
     430                 :  * A container class that complements many sub TextureImages into a big TextureImage.
     431                 :  * Aims to behave just like the real thing.
     432                 :  */
     433                 : 
     434                 : class TiledTextureImage
     435                 :     : public TextureImage
     436                 : {
     437                 : public:
     438                 :     TiledTextureImage(GLContext* aGL, nsIntSize aSize,
     439                 :         TextureImage::ContentType, bool aUseNearestFilter = false);
     440                 :     ~TiledTextureImage();
     441                 :     void DumpDiv();
     442                 :     virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
     443                 :     virtual void GetUpdateRegion(nsIntRegion& aForRegion);
     444                 :     virtual void EndUpdate();
     445                 :     virtual void Resize(const nsIntSize& aSize);
     446                 :     virtual PRUint32 GetTileCount();
     447                 :     virtual void BeginTileIteration();
     448                 :     virtual bool NextTile();
     449                 :     virtual nsIntRect GetTileRect();
     450                 :     virtual GLuint GetTextureID() {
     451                 :         return mImages[mCurrentImage]->GetTextureID();
     452                 :     };
     453                 :     virtual bool DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0));
     454                 :     virtual bool InUpdate() const { return mInUpdate; };
     455                 :     virtual void BindTexture(GLenum);
     456                 :     virtual void ApplyFilter();
     457                 : protected:
     458                 :     unsigned int mCurrentImage;
     459                 :     nsTArray< nsRefPtr<TextureImage> > mImages;
     460                 :     bool mInUpdate;
     461                 :     nsIntSize mSize;
     462                 :     unsigned int mTileSize;
     463                 :     unsigned int mRows, mColumns;
     464                 :     GLContext* mGL;
     465                 :     bool mUseNearestFilter;
     466                 :     // A temporary surface to faciliate cross-tile updates.
     467                 :     nsRefPtr<gfxASurface> mUpdateSurface;
     468                 :     // The region of update requested
     469                 :     nsIntRegion mUpdateRegion;
     470                 :     TextureState mTextureState;
     471                 : };
     472                 : 
     473                 : struct THEBES_API ContextFormat
     474                 : {
     475                 :     static const ContextFormat BasicRGBA32Format;
     476                 : 
     477                 :     enum StandardContextFormat {
     478                 :         Empty,
     479                 :         BasicRGBA32,
     480                 :         StrictBasicRGBA32,
     481                 :         BasicRGB24,
     482                 :         StrictBasicRGB24,
     483                 :         BasicRGB16_565,
     484                 :         StrictBasicRGB16_565
     485                 :     };
     486                 : 
     487                 :     ContextFormat() {
     488                 :         memset(this, 0, sizeof(ContextFormat));
     489                 :     }
     490                 : 
     491            1464 :     ContextFormat(const StandardContextFormat cf) {
     492            1464 :         memset(this, 0, sizeof(ContextFormat));
     493            1464 :         switch (cf) {
     494                 :         case BasicRGBA32:
     495            1464 :             red = green = blue = alpha = 8;
     496            1464 :             minRed = minGreen = minBlue = minAlpha = 1;
     497            1464 :             break;
     498                 : 
     499                 :         case StrictBasicRGBA32:
     500               0 :             red = green = blue = alpha = 8;
     501               0 :             minRed = minGreen = minBlue = minAlpha = 8;
     502               0 :             break;
     503                 : 
     504                 :         case BasicRGB24:
     505               0 :             red = green = blue = 8;
     506               0 :             minRed = minGreen = minBlue = 1;
     507               0 :             break;
     508                 : 
     509                 :         case StrictBasicRGB24:
     510               0 :             red = green = blue = 8;
     511               0 :             minRed = minGreen = minBlue = 8;
     512               0 :             break;
     513                 : 
     514                 :         case StrictBasicRGB16_565:
     515               0 :             red = minRed = 5;
     516               0 :             green = minGreen = 6;
     517               0 :             blue = minBlue = 5;
     518               0 :             break;
     519                 : 
     520                 :         default:
     521               0 :             break;
     522                 :         }
     523            1464 :     }
     524                 : 
     525                 :     int depth, minDepth;
     526                 :     int stencil, minStencil;
     527                 :     int red, minRed;
     528                 :     int green, minGreen;
     529                 :     int blue, minBlue;
     530                 :     int alpha, minAlpha;
     531                 :     int samples;
     532                 : 
     533                 :     int colorBits() const { return red + green + blue; }
     534                 : };
     535                 : 
     536                 : class GLContext
     537                 :     : public LibrarySymbolLoader
     538                 : {
     539               0 :     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GLContext)
     540                 : public:
     541                 :     GLContext(const ContextFormat& aFormat,
     542                 :               bool aIsOffscreen = false,
     543                 :               GLContext *aSharedContext = nsnull)
     544                 :       : mFlushGuaranteesResolve(false),
     545                 :         mUserBoundDrawFBO(0),
     546                 :         mUserBoundReadFBO(0),
     547                 :         mInternalBoundDrawFBO(0),
     548                 :         mInternalBoundReadFBO(0),
     549                 : #ifdef DEBUG
     550                 :         mInInternalBindingMode_DrawFBO(true),
     551                 :         mInInternalBindingMode_ReadFBO(true),
     552                 : #endif
     553                 :         mOffscreenFBOsDirty(false),
     554                 :         mInitialized(false),
     555                 :         mIsOffscreen(aIsOffscreen),
     556                 : #ifdef USE_GLES2
     557                 :         mIsGLES2(true),
     558                 : #else
     559                 :         mIsGLES2(false),
     560                 : #endif
     561                 :         mIsGlobalSharedContext(false),
     562                 :         mHasRobustness(false),
     563                 :         mContextLost(false),
     564                 :         mVendor(-1),
     565                 :         mRenderer(-1),
     566                 :         mCreationFormat(aFormat),
     567                 :         mSharedContext(aSharedContext),
     568                 :         mOffscreenTexture(0),
     569                 :         mFlipped(false),
     570                 :         mBlitProgram(0),
     571                 :         mBlitFramebuffer(0),
     572                 :         mOffscreenDrawFBO(0),
     573                 :         mOffscreenReadFBO(0),
     574                 :         mOffscreenColorRB(0),
     575                 :         mOffscreenDepthRB(0),
     576                 :         mOffscreenStencilRB(0),
     577                 :         mMaxTextureSize(0),
     578                 :         mMaxCubeMapTextureSize(0),
     579                 :         mMaxTextureImageSize(0),
     580                 :         mMaxRenderbufferSize(0)
     581                 : #ifdef DEBUG
     582                 :         , mGLError(LOCAL_GL_NO_ERROR)
     583                 : #endif
     584                 :     {
     585                 :         mUserData.Init();
     586                 :     }
     587                 : 
     588                 :     virtual ~GLContext() {
     589                 :         NS_ASSERTION(IsDestroyed(), "GLContext implementation must call MarkDestroyed in destructor!");
     590                 : #ifdef DEBUG
     591                 :         if (mSharedContext) {
     592                 :             GLContext *tip = mSharedContext;
     593                 :             while (tip->mSharedContext)
     594                 :                 tip = tip->mSharedContext;
     595                 :             tip->SharedContextDestroyed(this);
     596                 :             tip->ReportOutstandingNames();
     597                 :         }
     598                 : #endif
     599                 :     }
     600                 : 
     601                 :     enum GLContextType {
     602                 :         ContextTypeUnknown,
     603                 :         ContextTypeWGL,
     604                 :         ContextTypeCGL,
     605                 :         ContextTypeGLX,
     606                 :         ContextTypeEGL,
     607                 :         ContextTypeOSMesa
     608                 :     };
     609                 : 
     610                 :     virtual GLContextType GetContextType() { return ContextTypeUnknown; }
     611                 : 
     612                 :     virtual bool MakeCurrentImpl(bool aForce = false) = 0;
     613                 : 
     614                 : #ifdef DEBUG
     615               3 :     static void StaticInit() {
     616               3 :         PR_NewThreadPrivateIndex(&sCurrentGLContextTLS, NULL);
     617               3 :     }
     618                 : #endif
     619                 : 
     620               0 :     bool MakeCurrent(bool aForce = false) {
     621                 : #ifdef DEBUG
     622               0 :         PR_SetThreadPrivate(sCurrentGLContextTLS, this);
     623                 : #endif
     624               0 :         return MakeCurrentImpl(aForce);
     625                 :     }
     626                 : 
     627               0 :     bool IsContextLost() { return mContextLost; }
     628                 : 
     629                 :     virtual bool SetupLookupFunction() = 0;
     630                 : 
     631                 :     virtual void WindowDestroyed() {}
     632                 : 
     633                 :     virtual void ReleaseSurface() {}
     634                 : 
     635               0 :     void *GetUserData(void *aKey) {
     636               0 :         void *result = nsnull;
     637               0 :         mUserData.Get(aKey, &result);
     638               0 :         return result;
     639                 :     }
     640                 : 
     641               0 :     void SetUserData(void *aKey, void *aValue) {
     642               0 :         mUserData.Put(aKey, aValue);
     643               0 :     }
     644                 : 
     645                 :     // Mark this context as destroyed.  This will NULL out all
     646                 :     // the GL function pointers!
     647                 :     void THEBES_API MarkDestroyed();
     648                 : 
     649               0 :     bool IsDestroyed() {
     650                 :         // MarkDestroyed will mark all these as null.
     651               0 :         return mSymbols.fUseProgram == nsnull;
     652                 :     }
     653                 : 
     654                 :     enum NativeDataType {
     655                 :       NativeGLContext,
     656                 :       NativeImageSurface,
     657                 :       NativeThebesSurface,
     658                 :       NativeDataTypeMax
     659                 :     };
     660                 : 
     661                 :     virtual void *GetNativeData(NativeDataType aType) { return NULL; }
     662               0 :     GLContext *GetSharedContext() { return mSharedContext; }
     663                 : 
     664               0 :     bool IsGlobalSharedContext() { return mIsGlobalSharedContext; }
     665                 :     void SetIsGlobalSharedContext(bool aIsOne) { mIsGlobalSharedContext = aIsOne; }
     666                 : 
     667               0 :     const ContextFormat& CreationFormat() { return mCreationFormat; }
     668               0 :     const ContextFormat& ActualFormat() { return mActualFormat; }
     669                 : 
     670                 :     /**
     671                 :      * If this GL context has a D3D texture share handle, returns non-null.
     672                 :      */
     673                 :     virtual void *GetD3DShareHandle() { return nsnull; }
     674                 : 
     675                 :     /**
     676                 :      * If this context is double-buffered, returns TRUE.
     677                 :      */
     678                 :     virtual bool IsDoubleBuffered() { return false; }
     679                 : 
     680                 :     /**
     681                 :      * If this context is the GLES2 API, returns TRUE.
     682                 :      * This means that various GLES2 restrictions might be in effect (modulo
     683                 :      * extensions).
     684                 :      */
     685               0 :     bool IsGLES2() const {
     686               0 :         return mIsGLES2;
     687                 :     }
     688                 :     
     689                 :     /**
     690                 :      * Returns true if either this is the GLES2 API, or had the GL_ARB_ES2_compatibility extension
     691                 :      */
     692               0 :     bool HasES2Compatibility() {
     693               0 :         return mIsGLES2 || IsExtensionSupported(ARB_ES2_compatibility);
     694                 :     }
     695                 : 
     696                 :     /**
     697                 :      * Returns true if the context is using ANGLE. This should only be overridden for an ANGLE
     698                 :      * implementation.
     699                 :      */
     700                 :     virtual bool IsANGLE() {
     701                 :         return false;
     702                 :     }
     703                 : 
     704                 :     /**
     705                 :      * The derived class is expected to provide information on whether or not it
     706                 :      * supports robustness.
     707                 :      */
     708                 :     virtual bool SupportsRobustness() = 0;
     709                 : 
     710                 :     enum {
     711                 :         VendorIntel,
     712                 :         VendorNVIDIA,
     713                 :         VendorATI,
     714                 :         VendorQualcomm,
     715                 :         VendorOther
     716                 :     };
     717                 : 
     718                 :     enum {
     719                 :         RendererAdreno200,
     720                 :         RendererOther
     721                 :     };
     722                 : 
     723               0 :     int Vendor() const {
     724               0 :         return mVendor;
     725                 :     }
     726                 : 
     727                 :     int Renderer() const {
     728                 :         return mRenderer;
     729                 :     }
     730                 : 
     731                 :     bool CanUploadSubTextures();
     732                 : 
     733                 :     /**
     734                 :      * If this context wraps a double-buffered target, swap the back
     735                 :      * and front buffers.  It should be assumed that after a swap, the
     736                 :      * contents of the new back buffer are undefined.
     737                 :      */
     738                 :     virtual bool SwapBuffers() { return false; }
     739                 : 
     740                 :     /**
     741                 :      * Defines a two-dimensional texture image for context target surface
     742                 :      */
     743                 :     virtual bool BindTexImage() { return false; }
     744                 :     /*
     745                 :      * Releases a color buffer that is being used as a texture
     746                 :      */
     747                 :     virtual bool ReleaseTexImage() { return false; }
     748                 : 
     749                 :     /**
     750                 :      * Applies aFilter to the texture currently bound to GL_TEXTURE_2D.
     751                 :      */
     752                 :     void ApplyFilterToBoundTexture(gfxPattern::GraphicsFilter aFilter);
     753                 : 
     754                 : 
     755                 :     /*
     756                 :      * Offscreen support API
     757                 :      */
     758                 : 
     759                 :     /*
     760                 :      * Bind aOffscreen's color buffer as a texture to the TEXTURE_2D
     761                 :      * target.  Returns TRUE on success, otherwise FALSE.  If
     762                 :      * aOffscreen is not an offscreen context, returns FALSE.  If
     763                 :      * BindOffscreenNeedsTexture() returns TRUE, then you should have
     764                 :      * a 2D texture name bound whose image will be replaced by the
     765                 :      * contents of the offscreen context.  If it returns FALSE,
     766                 :      * the current 2D texture binding will be replaced.
     767                 :      *
     768                 :      * After a successul call to BindTex2DOffscreen, UnbindTex2DOffscreen
     769                 :      * *must* be called once rendering is complete.
     770                 :      *
     771                 :      * The same texture unit must be active for Bind/Unbind of a given
     772                 :      * context.
     773                 :      */
     774                 :     virtual bool BindOffscreenNeedsTexture(GLContext *aOffscreen) {
     775                 :         return aOffscreen->mOffscreenTexture == 0;
     776                 :     }
     777                 : 
     778                 :     virtual bool BindTex2DOffscreen(GLContext *aOffscreen) {
     779                 :         if (aOffscreen->GetContextType() != GetContextType()) {
     780                 :           return false;
     781                 :         }
     782                 : 
     783                 :         if (!aOffscreen->mSharedContext ||
     784                 :             aOffscreen->mSharedContext != mSharedContext)
     785                 :         {
     786                 :             return false;
     787                 :         }
     788                 : 
     789                 :         if (!aOffscreen->mOffscreenTexture) {
     790                 :             return false;
     791                 :         }
     792                 : 
     793                 :         fBindTexture(LOCAL_GL_TEXTURE_2D, aOffscreen->mOffscreenTexture);
     794                 : 
     795                 :         return true;
     796                 :     }
     797                 : 
     798                 :     virtual void UnbindTex2DOffscreen(GLContext *aOffscreen) { }
     799                 : 
     800               0 :     bool IsOffscreen() {
     801               0 :         return mIsOffscreen;
     802                 :     }
     803                 : 
     804                 : private:
     805                 :     bool mFlushGuaranteesResolve;
     806                 : 
     807                 : public:
     808                 :     void SetFlushGuaranteesResolve(bool aFlushGuaranteesResolve) {
     809                 :         mFlushGuaranteesResolve = aFlushGuaranteesResolve;
     810                 :     }
     811                 :     
     812                 :     // Before reads from offscreen texture
     813               0 :     void GuaranteeResolve() {
     814               0 :         if (mFlushGuaranteesResolve) {
     815               0 :             BlitDirtyFBOs();
     816               0 :             fFlush();
     817                 :         } else {
     818               0 :             fFinish();
     819                 :         }
     820               0 :     }
     821                 : 
     822                 :     /*
     823                 :      * Resize the current offscreen buffer.  Returns true on success.
     824                 :      * If it returns false, the context should be treated as unusable
     825                 :      * and should be recreated.  After the resize, the viewport is not
     826                 :      * changed; glViewport should be called as appropriate.
     827                 :      *
     828                 :      * Only valid if IsOffscreen() returns true.
     829                 :      */
     830                 :     virtual bool ResizeOffscreen(const gfxIntSize& aNewSize) {
     831                 :         if (mOffscreenDrawFBO || mOffscreenReadFBO)
     832                 :             return ResizeOffscreenFBO(aNewSize, mOffscreenReadFBO != 0);
     833                 :         return false;
     834                 :     }
     835                 : 
     836                 :     /*
     837                 :      * Return size of this offscreen context.
     838                 :      *
     839                 :      * Only valid if IsOffscreen() returns true.
     840                 :      */
     841                 :     gfxIntSize OffscreenSize() {
     842                 :         return mOffscreenSize;
     843                 :     }
     844                 : 
     845                 :     /*
     846                 :      * In some cases, we have to allocate a bigger offscreen buffer
     847                 :      * than what's requested.  This is the bigger size.
     848                 :      *
     849                 :      * Only valid if IsOffscreen() returns true.
     850                 :      */
     851               0 :     gfxIntSize OffscreenActualSize() {
     852               0 :         return mOffscreenActualSize;
     853                 :     }
     854                 : 
     855                 :     /*
     856                 :      * If this context is FBO-backed, return the FBO or the color
     857                 :      * buffer texture.  If the context is not FBO-backed, 0 is
     858                 :      * returned (which is also a valid FBO binding).
     859                 :      *
     860                 :      * Only valid if IsOffscreen() returns true.
     861                 :      */
     862               0 :     GLuint GetOffscreenFBO() {
     863                 :         // 0 is interpreted as (off)screen, whether for read or draw operations
     864               0 :         return 0;
     865                 :     }
     866                 : 
     867                 :     GLuint GetOffscreenTexture() {
     868                 :         return mOffscreenTexture;
     869                 :     }
     870                 : 
     871                 :     virtual bool SupportsFramebufferMultisample() {
     872                 :         return IsExtensionSupported(EXT_framebuffer_multisample) || IsExtensionSupported(ANGLE_framebuffer_multisample);
     873                 :     }
     874                 : 
     875                 :     virtual bool SupportsOffscreenSplit() {
     876                 :         return IsExtensionSupported(EXT_framebuffer_blit) || IsExtensionSupported(ANGLE_framebuffer_blit);
     877                 :     }
     878                 : 
     879                 : 
     880                 : 
     881                 : private:
     882                 :     GLuint mUserBoundDrawFBO;
     883                 :     GLuint mUserBoundReadFBO;
     884                 :     GLuint mInternalBoundDrawFBO;
     885                 :     GLuint mInternalBoundReadFBO;
     886                 : 
     887                 : public:
     888               0 :     void fBindFramebuffer(GLenum target, GLuint framebuffer) {
     889               0 :         switch (target) {
     890                 :           case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
     891               0 :             mUserBoundDrawFBO = framebuffer;
     892                 : 
     893               0 :             if (framebuffer == 0) {
     894               0 :                 mInternalBoundDrawFBO = mOffscreenDrawFBO;
     895                 :             } else {
     896               0 :                 mInternalBoundDrawFBO = mUserBoundDrawFBO;
     897                 :             }
     898                 : 
     899                 :             raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT,
     900               0 :                                  mInternalBoundDrawFBO);
     901               0 :             break;
     902                 : 
     903                 :           case LOCAL_GL_READ_FRAMEBUFFER_EXT:
     904               0 :             mUserBoundReadFBO = framebuffer;
     905                 : 
     906               0 :             if (framebuffer == 0) {
     907               0 :                 mInternalBoundReadFBO = mOffscreenReadFBO;
     908                 :             } else {
     909               0 :                 mInternalBoundReadFBO = mUserBoundReadFBO;
     910                 :             }
     911                 : 
     912                 :             raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT,
     913               0 :                                  mInternalBoundReadFBO);
     914               0 :             break;
     915                 : 
     916                 :           case LOCAL_GL_FRAMEBUFFER:
     917               0 :             mUserBoundDrawFBO = mUserBoundReadFBO = framebuffer;
     918                 : 
     919               0 :             if (framebuffer == 0) {
     920               0 :                 mInternalBoundDrawFBO = mOffscreenDrawFBO;
     921               0 :                 mInternalBoundReadFBO = mOffscreenReadFBO;
     922                 :             } else {
     923               0 :                 mInternalBoundDrawFBO = mUserBoundDrawFBO;
     924               0 :                 mInternalBoundReadFBO = mUserBoundReadFBO;
     925                 :             }
     926                 : 
     927               0 :             if (SupportsOffscreenSplit()) {
     928                 :                 raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT,
     929               0 :                                      mInternalBoundDrawFBO);
     930                 :                 raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT,
     931               0 :                                      mInternalBoundReadFBO);
     932                 :             } else {
     933                 :                 raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER,
     934               0 :                                      mInternalBoundDrawFBO);
     935                 :             }
     936                 : 
     937               0 :             break;
     938                 : 
     939                 :           default:
     940               0 :             raw_fBindFramebuffer(target, framebuffer);
     941               0 :             break;
     942                 :         }
     943               0 :     }
     944                 : 
     945                 : #ifdef DEBUG
     946                 :     // See comment near BindInternalDrawFBO()
     947                 :     bool mInInternalBindingMode_DrawFBO;
     948                 :     bool mInInternalBindingMode_ReadFBO;
     949                 : #endif
     950                 : 
     951               0 :     GLuint GetUserBoundDrawFBO() {
     952                 : #ifdef DEBUG
     953               0 :         GLint ret = 0;
     954                 :         // Don't need a branch here, because:
     955                 :         // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT == LOCAL_GL_FRAMEBUFFER_BINDING == 0x8CA6
     956                 :         // We use raw_ here because this is debug code and we need to see what
     957                 :         // the driver thinks.
     958               0 :         raw_fGetIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, &ret);
     959                 : 
     960               0 :         bool abort = false;
     961                 : 
     962               0 :         if (mInInternalBindingMode_DrawFBO) {
     963               0 :             NS_ERROR("Draw FBO still bound internally!");
     964               0 :             printf_stderr("Current internal draw FBO: %d, user: %d)\n", ret, mUserBoundDrawFBO);
     965               0 :             abort = true;
     966                 :         }
     967                 : 
     968               0 :         if (mInternalBoundDrawFBO != (GLuint)ret) {
     969               0 :             NS_ERROR("Draw FBO binding misprediction!");
     970               0 :             printf_stderr("Bound draw FBO was: %d, Expected: %d\n", ret, mInternalBoundDrawFBO);
     971               0 :             abort = true;
     972                 :         }
     973                 : 
     974               0 :         if (abort)
     975               0 :             NS_ABORT();
     976                 : #endif
     977                 : 
     978                 :         // We only ever expose the user's bound FBOs
     979               0 :         return mUserBoundDrawFBO;
     980                 :     }
     981                 : 
     982               0 :     GLuint GetUserBoundReadFBO() {
     983                 : #ifdef DEBUG
     984               0 :         GLint ret = 0;
     985                 :         // We use raw_ here because this is debug code and we need to see what
     986                 :         // the driver thinks.
     987               0 :         if (SupportsOffscreenSplit())
     988               0 :             raw_fGetIntegerv(LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT, &ret);
     989                 :         else
     990               0 :             raw_fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &ret);
     991                 : 
     992               0 :         bool abort = false;
     993                 : 
     994               0 :         if (mInInternalBindingMode_ReadFBO) {
     995               0 :             NS_ERROR("Read FBO still bound internally!");
     996               0 :             printf_stderr("Current internal read FBO: %d, user: %d)\n", ret, mUserBoundReadFBO);
     997               0 :             abort = true;
     998                 :         }
     999                 : 
    1000               0 :         if (mInternalBoundReadFBO != (GLuint)ret) {
    1001               0 :             NS_ERROR("Read FBO binding misprediction!");
    1002               0 :             printf_stderr("Bound read FBO was: %d, Expected: %d\n", ret, mInternalBoundReadFBO);
    1003               0 :             abort = true;
    1004                 :         }
    1005                 : 
    1006               0 :         if (abort)
    1007               0 :             NS_ABORT();
    1008                 : #endif
    1009                 : 
    1010                 :         // We only ever expose the user's bound FBOs
    1011               0 :         return mUserBoundReadFBO;
    1012                 :     }
    1013                 : 
    1014               0 :     void BindUserDrawFBO(GLuint name) {
    1015               0 :         if (SupportsOffscreenSplit())
    1016               0 :             fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, name);
    1017                 :         else
    1018               0 :             fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, name);
    1019                 : #ifdef DEBUG
    1020               0 :         mInInternalBindingMode_DrawFBO = false;
    1021                 : #endif
    1022               0 :     }
    1023                 : 
    1024               0 :     void BindUserReadFBO(GLuint name) {
    1025               0 :         if (SupportsOffscreenSplit())
    1026               0 :             fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, name);
    1027                 :         else
    1028               0 :             fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, name);
    1029                 : #ifdef DEBUG
    1030               0 :         mInInternalBindingMode_ReadFBO = false;
    1031                 : #endif
    1032               0 :     }
    1033                 : 
    1034                 :     // BindInternalDraw/ReadFBO() switch us over into 'internal binding mode'
    1035                 :     //   for the corresponding Draw or Read binding.
    1036                 :     // To exit internal binding mode, use BindUserDraw/ReadFBO().
    1037                 :     // While in internal binding mode for Draw/Read, the corresponding
    1038                 :     //   GetBoundUserDraw/ReadFBO() is undefined, and will trigger ABORT in DEBUG builds.
    1039               0 :     void BindInternalDrawFBO(GLuint name) {
    1040                 : #ifdef DEBUG
    1041               0 :       mInInternalBindingMode_DrawFBO = true;
    1042                 : #endif
    1043               0 :         if (SupportsOffscreenSplit())
    1044               0 :             raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, name);
    1045                 :         else
    1046               0 :             raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, name);
    1047                 : 
    1048               0 :         mInternalBoundDrawFBO = name;
    1049               0 :     }
    1050                 : 
    1051               0 :     void BindInternalReadFBO(GLuint name) {
    1052                 : #ifdef DEBUG
    1053               0 :       mInInternalBindingMode_ReadFBO = true;
    1054                 : #endif
    1055               0 :         if (SupportsOffscreenSplit())
    1056               0 :             raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, name);
    1057                 :         else
    1058               0 :             raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, name);
    1059                 : 
    1060               0 :         mInternalBoundReadFBO = name;
    1061               0 :     }
    1062                 : 
    1063                 :     void BindInternalFBO(GLuint name) {
    1064                 :         BindInternalDrawFBO(name);
    1065                 :         BindInternalReadFBO(name);
    1066                 :     }
    1067                 : 
    1068                 :     void InitFramebuffers() {
    1069                 :         MakeCurrent();
    1070                 :         BindUserDrawFBO(0);
    1071                 :         BindUserReadFBO(0);
    1072                 :     }
    1073                 : 
    1074                 :     GLuint SwapUserDrawFBO(GLuint name) {
    1075                 :         GLuint prev = GetUserBoundDrawFBO();
    1076                 :         BindUserDrawFBO(name);
    1077                 :         return prev;
    1078                 :     }
    1079                 : 
    1080               0 :     GLuint SwapUserReadFBO(GLuint name) {
    1081               0 :         GLuint prev = GetUserBoundReadFBO();
    1082               0 :         BindUserReadFBO(name);
    1083               0 :         return prev;
    1084                 :     }
    1085                 : 
    1086                 : private:
    1087                 :     bool mOffscreenFBOsDirty;
    1088                 : 
    1089               0 :     void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
    1090               0 :         switch (precisiontype) {
    1091                 :             case LOCAL_GL_LOW_FLOAT:
    1092                 :             case LOCAL_GL_MEDIUM_FLOAT:
    1093                 :             case LOCAL_GL_HIGH_FLOAT:
    1094                 :                 // Assume IEEE 754 precision
    1095               0 :                 range[0] = 127;
    1096               0 :                 range[1] = 127;
    1097               0 :                 *precision = 0;
    1098               0 :                 break;
    1099                 :             case LOCAL_GL_LOW_INT:
    1100                 :             case LOCAL_GL_MEDIUM_INT:
    1101                 :             case LOCAL_GL_HIGH_INT:
    1102                 :                 // Some (most) hardware only supports single-precision floating-point numbers,
    1103                 :                 // which can accurately represent integers up to +/-16777216
    1104               0 :                 range[0] = 24;
    1105               0 :                 range[1] = 24;
    1106               0 :                 *precision = 0;
    1107               0 :                 break;
    1108                 :         }
    1109               0 :     }
    1110                 : 
    1111                 :     // Do whatever setup is necessary to draw to our offscreen FBO, if it's
    1112                 :     // bound.
    1113               0 :     void BeforeGLDrawCall() {
    1114               0 :         if (mInternalBoundDrawFBO != mOffscreenDrawFBO)
    1115               0 :             return;
    1116                 : 
    1117               0 :         if (mOffscreenDrawFBO == mOffscreenReadFBO)
    1118               0 :             return;
    1119                 : 
    1120               0 :         mOffscreenFBOsDirty = true;
    1121                 :     }
    1122                 : 
    1123                 :     // Do whatever tear-down is necessary after drawing to our offscreen FBO,
    1124                 :     // if it's bound.
    1125               0 :     void AfterGLDrawCall() {
    1126               0 :     }
    1127                 : 
    1128                 :     // Do whatever setup is necessary to read from our offscreen FBO, if it's
    1129                 :     // bound.
    1130               0 :     void BeforeGLReadCall() {
    1131               0 :         if (mInternalBoundReadFBO != mOffscreenReadFBO)
    1132               0 :             return;
    1133                 : 
    1134               0 :         if (mOffscreenDrawFBO == mOffscreenReadFBO)
    1135               0 :             return;
    1136                 : 
    1137                 :         // If we're not dirty, there's no need to blit
    1138               0 :         if (!mOffscreenFBOsDirty)
    1139               0 :             return;
    1140                 : 
    1141               0 :         const bool scissor = fIsEnabled(LOCAL_GL_SCISSOR_TEST);
    1142               0 :         if (scissor)
    1143               0 :             fDisable(LOCAL_GL_SCISSOR_TEST);
    1144                 : 
    1145                 :         // Store current bindings for restoring later
    1146               0 :         GLuint prevDraw = GetUserBoundDrawFBO();
    1147               0 :         GLuint prevRead = GetUserBoundReadFBO();
    1148                 : 
    1149               0 :         NS_ABORT_IF_FALSE(SupportsOffscreenSplit(), "Doesn't support offscreen split?");
    1150                 : 
    1151                 :         // Manually setting internal bindings, entering internal mode
    1152                 :         // Flip read/draw for blitting
    1153               0 :         BindInternalDrawFBO(mOffscreenReadFBO);
    1154               0 :         BindInternalReadFBO(mOffscreenDrawFBO);
    1155                 : 
    1156               0 :         GLint width = mOffscreenActualSize.width;
    1157               0 :         GLint height = mOffscreenActualSize.height;
    1158                 :         raw_fBlitFramebuffer(0, 0, width, height,
    1159                 :                              0, 0, width, height,
    1160                 :                              LOCAL_GL_COLOR_BUFFER_BIT,
    1161               0 :                              LOCAL_GL_NEAREST);
    1162                 : 
    1163                 :         // Reset to emulated user binding, exiting internal mode
    1164               0 :         BindUserDrawFBO(prevDraw);
    1165               0 :         BindUserReadFBO(prevRead);
    1166                 : 
    1167               0 :         if (scissor)
    1168               0 :             fEnable(LOCAL_GL_SCISSOR_TEST);
    1169                 : 
    1170               0 :         mOffscreenFBOsDirty = false;
    1171                 :     }
    1172                 : 
    1173                 :     // Do whatever tear-down is necessary after reading from our offscreen FBO,
    1174                 :     // if it's bound.
    1175               0 :     void AfterGLReadCall() {
    1176               0 :     }
    1177                 : 
    1178                 : public:
    1179                 :     // Draw call hooks:
    1180               0 :     void fClear(GLbitfield mask) {
    1181               0 :         BeforeGLDrawCall();
    1182               0 :         raw_fClear(mask);
    1183               0 :         AfterGLDrawCall();
    1184               0 :     }
    1185                 : 
    1186               0 :     void fDrawArrays(GLenum mode, GLint first, GLsizei count) {
    1187               0 :         BeforeGLDrawCall();
    1188               0 :         raw_fDrawArrays(mode, first, count);
    1189               0 :         AfterGLDrawCall();
    1190               0 :     }
    1191                 : 
    1192               0 :     void fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {
    1193               0 :         BeforeGLDrawCall();
    1194               0 :         raw_fDrawElements(mode, count, type, indices);
    1195               0 :         AfterGLDrawCall();
    1196               0 :     }
    1197                 : 
    1198                 :     // Read call hooks:
    1199               0 :     void fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
    1200               0 :         BeforeGLReadCall();
    1201               0 :         raw_fReadPixels(x, y, width, height, format, type, pixels);
    1202               0 :         AfterGLReadCall();
    1203               0 :     }
    1204                 : 
    1205               0 :     void fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
    1206               0 :         BeforeGLReadCall();
    1207                 :         raw_fCopyTexImage2D(target, level, internalformat,
    1208               0 :                             x, y, width, height, border);
    1209               0 :         AfterGLReadCall();
    1210               0 :     }
    1211                 : 
    1212               0 :     void fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
    1213               0 :         BeforeGLReadCall();
    1214                 :         raw_fCopyTexSubImage2D(target, level, xoffset, yoffset,
    1215               0 :                                x, y, width, height);
    1216               0 :         AfterGLReadCall();
    1217               0 :     }
    1218                 : 
    1219                 :     void ForceDirtyFBOs() {
    1220                 :         GLuint draw = SwapUserDrawFBO(0);
    1221                 : 
    1222                 :         BeforeGLDrawCall();
    1223                 :         // no-op; just pretend we did something
    1224                 :         AfterGLDrawCall();
    1225                 : 
    1226                 :         BindUserDrawFBO(draw);
    1227                 :     }
    1228                 : 
    1229               0 :     void BlitDirtyFBOs() {
    1230               0 :         GLuint read = SwapUserReadFBO(0);
    1231                 : 
    1232               0 :         BeforeGLReadCall();
    1233                 :         // no-op; we just want to make sure the Read FBO is updated if it needs to be
    1234               0 :         AfterGLReadCall();
    1235                 : 
    1236               0 :         BindUserReadFBO(read);
    1237               0 :     }
    1238                 : 
    1239               0 :     void fFinish() {
    1240               0 :         BeforeGLReadCall();
    1241               0 :         raw_fFinish();
    1242               0 :         AfterGLReadCall();
    1243               0 :     }
    1244                 : 
    1245                 :     // Draw/Read
    1246                 :     void fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
    1247                 :         BeforeGLDrawCall();
    1248                 :         BeforeGLReadCall();
    1249                 :         raw_fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
    1250                 :         AfterGLReadCall();
    1251                 :         AfterGLDrawCall();
    1252                 :     }
    1253                 : 
    1254                 : #if defined(MOZ_X11) && defined(MOZ_EGL_XRENDER_COMPOSITE)
    1255                 :     virtual gfxASurface* GetOffscreenPixmapSurface()
    1256                 :     {
    1257                 :       return 0;
    1258                 :     };
    1259                 :     
    1260                 :     virtual bool WaitNative() { return false; }
    1261                 : #endif
    1262                 : 
    1263                 :     virtual bool TextureImageSupportsGetBackingSurface() {
    1264                 :         return false;
    1265                 :     }
    1266                 : 
    1267                 :     virtual bool RenewSurface() { return false; }
    1268                 : 
    1269                 :     /**`
    1270                 :      * Return a valid, allocated TextureImage of |aSize| with
    1271                 :      * |aContentType|.  The TextureImage's texture is configured to
    1272                 :      * use |aWrapMode| (usually GL_CLAMP_TO_EDGE or GL_REPEAT) and by
    1273                 :      * default, GL_LINEAR filtering.  Specify
    1274                 :      * |aUseNearestFilter=true| for GL_NEAREST filtering.  Return
    1275                 :      * NULL if creating the TextureImage fails.
    1276                 :      *
    1277                 :      * The returned TextureImage may only be used with this GLContext.
    1278                 :      * Attempting to use the returned TextureImage after this
    1279                 :      * GLContext is destroyed will result in undefined (and likely
    1280                 :      * crashy) behavior.
    1281                 :      */
    1282                 :     virtual already_AddRefed<TextureImage>
    1283                 :     CreateTextureImage(const nsIntSize& aSize,
    1284                 :                        TextureImage::ContentType aContentType,
    1285                 :                        GLenum aWrapMode,
    1286                 :                        bool aUseNearestFilter=false);
    1287                 : 
    1288                 :     /**
    1289                 :      * In EGL we want to use Tiled Texture Images, which we return
    1290                 :      * from CreateTextureImage above.
    1291                 :      * Inside TiledTextureImage we need to create actual images and to
    1292                 :      * prevent infinite recursion we need to differentiate the two
    1293                 :      * functions.
    1294                 :      **/
    1295                 :     virtual already_AddRefed<TextureImage>
    1296                 :     TileGenFunc(const nsIntSize& aSize,
    1297                 :                 TextureImage::ContentType aContentType,
    1298                 :                 bool aUseNearestFilter = false)
    1299                 :     {
    1300                 :         return nsnull;
    1301                 :     };
    1302                 : 
    1303                 :     /**
    1304                 :      * Read the image data contained in aTexture, and return it as an ImageSurface.
    1305                 :      * If GL_RGBA is given as the format, a ImageFormatARGB32 surface is returned.
    1306                 :      * Not implemented yet:
    1307                 :      * If GL_RGB is given as the format, a ImageFormatRGB24 surface is returned.
    1308                 :      * If GL_LUMINANCE is given as the format, a ImageFormatA8 surface is returned.
    1309                 :      *
    1310                 :      * THIS IS EXPENSIVE.  It is ridiculously expensive.  Only do this
    1311                 :      * if you absolutely positively must, and never in any performance
    1312                 :      * critical path.
    1313                 :      */
    1314                 :     already_AddRefed<gfxImageSurface> ReadTextureImage(GLuint aTexture,
    1315                 :                                                        const gfxIntSize& aSize,
    1316                 :                                                        GLenum aTextureFormat,
    1317                 :                                                        bool aYInvert = false);
    1318                 : 
    1319                 :     already_AddRefed<gfxImageSurface> GetTexImage(GLuint aTexture, bool aYInvert, ShaderProgramType aShader);
    1320                 : 
    1321                 :     /**
    1322                 :      * Call ReadPixels into an existing gfxImageSurface for the given bounds.
    1323                 :      * The image surface must be using image format RGBA32 or RGB24.
    1324                 :      */
    1325                 :     void THEBES_API ReadPixelsIntoImageSurface(GLint aX, GLint aY,
    1326                 :                                     GLsizei aWidth, GLsizei aHeight,
    1327                 :                                     gfxImageSurface *aDest);
    1328                 : 
    1329                 :     /**
    1330                 :      * Copy a rectangle from one TextureImage into another.  The
    1331                 :      * source and destination are given in integer coordinates, and
    1332                 :      * will be converted to texture coordinates.
    1333                 :      *
    1334                 :      * For the source texture, the wrap modes DO apply -- it's valid
    1335                 :      * to use REPEAT or PAD and expect appropriate behaviour if the source
    1336                 :      * rectangle extends beyond its bounds.
    1337                 :      *
    1338                 :      * For the destination texture, the wrap modes DO NOT apply -- the
    1339                 :      * destination will be clipped by the bounds of the texture.
    1340                 :      *
    1341                 :      * Note: calling this function will cause the following OpenGL state
    1342                 :      * to be changed:
    1343                 :      *
    1344                 :      *   - current program
    1345                 :      *   - framebuffer binding
    1346                 :      *   - viewport
    1347                 :      *   - blend state (will be enabled at end)
    1348                 :      *   - scissor state (will be enabled at end)
    1349                 :      *   - vertex attrib 0 and 1 (pointer and enable state [enable state will be disabled at exit])
    1350                 :      *   - array buffer binding (will be 0)
    1351                 :      *   - active texture (will be 0)
    1352                 :      *   - texture 0 binding
    1353                 :      */
    1354                 :     void BlitTextureImage(TextureImage *aSrc, const nsIntRect& aSrcRect,
    1355                 :                           TextureImage *aDst, const nsIntRect& aDstRect);
    1356                 : 
    1357                 :     /**
    1358                 :      * Creates a RGB/RGBA texture (or uses one provided) and uploads the surface
    1359                 :      * contents to it within aSrcRect.
    1360                 :      *
    1361                 :      * aSrcRect.x/y will be uploaded to 0/0 in the texture, and the size
    1362                 :      * of the texture with be aSrcRect.width/height.
    1363                 :      *
    1364                 :      * If an existing texture is passed through aTexture, it is assumed it
    1365                 :      * has already been initialised with glTexImage2D (or this function),
    1366                 :      * and that its size is equal to or greater than aSrcRect + aDstPoint.
    1367                 :      * You can alternatively set the overwrite flag to true and have a new
    1368                 :      * texture memory block allocated.
    1369                 :      *
    1370                 :      * The aDstPoint parameter is ignored if no texture was provided
    1371                 :      * or aOverwrite is true.
    1372                 :      *
    1373                 :      * \param aSurface Surface to upload. 
    1374                 :      * \param aDstRegion Region of texture to upload to.
    1375                 :      * \param aTexture Texture to use, or 0 to have one created for you.
    1376                 :      * \param aOverwrite Over an existing texture with a new one.
    1377                 :      * \param aSrcPoint Offset into aSrc where the region's bound's 
    1378                 :      *  TopLeft() sits.
    1379                 :      * \param aPixelBuffer Pass true to upload texture data with an
    1380                 :      *  offset from the base data (generally for pixel buffer objects), 
    1381                 :      *  otherwise textures are upload with an absolute pointer to the data.
    1382                 :      * \return Shader program needed to render this texture.
    1383                 :      */
    1384                 :     ShaderProgramType UploadSurfaceToTexture(gfxASurface *aSurface, 
    1385                 :                                              const nsIntRegion& aDstRegion,
    1386                 :                                              GLuint& aTexture,
    1387                 :                                              bool aOverwrite = false,
    1388                 :                                              const nsIntPoint& aSrcPoint = nsIntPoint(0, 0),
    1389                 :                                              bool aPixelBuffer = false);
    1390                 : 
    1391                 :     
    1392                 :     void TexImage2D(GLenum target, GLint level, GLint internalformat, 
    1393                 :                     GLsizei width, GLsizei height, GLsizei stride,
    1394                 :                     GLint pixelsize, GLint border, GLenum format, 
    1395                 :                     GLenum type, const GLvoid *pixels);
    1396                 : 
    1397                 :     void TexSubImage2D(GLenum target, GLint level, 
    1398                 :                        GLint xoffset, GLint yoffset, 
    1399                 :                        GLsizei width, GLsizei height, GLsizei stride,
    1400                 :                        GLint pixelsize, GLenum format, 
    1401                 :                        GLenum type, const GLvoid* pixels);
    1402                 : 
    1403                 :     /**
    1404                 :      * Uses the Khronos GL_EXT_unpack_subimage extension, working around
    1405                 :      * quirks in the Tegra implementation of this extension.
    1406                 :      */
    1407                 :     void TexSubImage2DWithUnpackSubimageGLES(GLenum target, GLint level,
    1408                 :                                              GLint xoffset, GLint yoffset,
    1409                 :                                              GLsizei width, GLsizei height,
    1410                 :                                              GLsizei stride, GLint pixelsize,
    1411                 :                                              GLenum format, GLenum type,
    1412                 :                                              const GLvoid* pixels);
    1413                 : 
    1414                 :     void TexSubImage2DWithoutUnpackSubimage(GLenum target, GLint level,
    1415                 :                                             GLint xoffset, GLint yoffset,
    1416                 :                                             GLsizei width, GLsizei height,
    1417                 :                                             GLsizei stride, GLint pixelsize,
    1418                 :                                             GLenum format, GLenum type,
    1419                 :                                             const GLvoid* pixels);
    1420                 : 
    1421                 :     /** Helper for DecomposeIntoNoRepeatTriangles
    1422                 :      */
    1423               0 :     struct RectTriangles {
    1424               0 :         RectTriangles() { }
    1425                 : 
    1426                 :         void addRect(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
    1427                 :                      GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1);
    1428                 : 
    1429                 :         /**
    1430                 :          * these return a float pointer to the start of each array respectively.
    1431                 :          * Use it for glVertexAttribPointer calls.
    1432                 :          * We can return NULL if we choose to use Vertex Buffer Objects here.
    1433                 :          */
    1434               0 :         float* vertexPointer() {
    1435               0 :             return &vertexCoords[0].x;
    1436                 :         };
    1437                 : 
    1438               0 :         float* texCoordPointer() {
    1439               0 :             return &texCoords[0].u;
    1440                 :         };
    1441                 : 
    1442               0 :         unsigned int elements() {
    1443               0 :             return vertexCoords.Length();
    1444                 :         };
    1445                 : 
    1446               0 :         typedef struct { GLfloat x,y; } vert_coord;
    1447               0 :         typedef struct { GLfloat u,v; } tex_coord;
    1448                 :     private:
    1449                 :         // default is 4 rectangles, each made up of 2 triangles (3 coord vertices each)
    1450                 :         nsAutoTArray<vert_coord, 6> vertexCoords;
    1451                 :         nsAutoTArray<tex_coord, 6>  texCoords;
    1452                 :     };
    1453                 : 
    1454                 :     /**
    1455                 :      * Decompose drawing the possibly-wrapped aTexCoordRect rectangle
    1456                 :      * of a texture of aTexSize into one or more rectangles (represented
    1457                 :      * as 2 triangles) and associated tex coordinates, such that
    1458                 :      * we don't have to use the REPEAT wrap mode.
    1459                 :      *
    1460                 :      * The resulting triangle vertex coordinates will be in the space of
    1461                 :      * (0.0, 0.0) to (1.0, 1.0) -- transform the coordinates appropriately
    1462                 :      * if you need a different space.
    1463                 :      *
    1464                 :      * The resulting vertex coordinates should be drawn using GL_TRIANGLES,
    1465                 :      * and rects.numRects * 3 * 6
    1466                 :      */
    1467                 :     static void DecomposeIntoNoRepeatTriangles(const nsIntRect& aTexCoordRect,
    1468                 :                                                const nsIntSize& aTexSize,
    1469                 :                                                RectTriangles& aRects);
    1470                 : 
    1471                 :     /**
    1472                 :      * Known GL extensions that can be queried by
    1473                 :      * IsExtensionSupported.  The results of this are cached, and as
    1474                 :      * such it's safe to use this even in performance critical code.
    1475                 :      * If you add to this array, remember to add to the string names
    1476                 :      * in GLContext.cpp.
    1477                 :      */
    1478                 :     enum GLExtensions {
    1479                 :         EXT_framebuffer_object,
    1480                 :         ARB_framebuffer_object,
    1481                 :         ARB_texture_rectangle,
    1482                 :         EXT_bgra,
    1483                 :         EXT_texture_format_BGRA8888,
    1484                 :         OES_depth24,
    1485                 :         OES_depth32,
    1486                 :         OES_stencil8,
    1487                 :         OES_texture_npot,
    1488                 :         OES_depth_texture,
    1489                 :         OES_packed_depth_stencil,
    1490                 :         IMG_read_format,
    1491                 :         EXT_read_format_bgra,
    1492                 :         APPLE_client_storage,
    1493                 :         ARB_texture_non_power_of_two,
    1494                 :         ARB_pixel_buffer_object,
    1495                 :         ARB_ES2_compatibility,
    1496                 :         OES_texture_float,
    1497                 :         ARB_texture_float,
    1498                 :         EXT_unpack_subimage,
    1499                 :         OES_standard_derivatives,
    1500                 :         EXT_texture_filter_anisotropic,
    1501                 :         EXT_framebuffer_blit,
    1502                 :         ANGLE_framebuffer_blit,
    1503                 :         EXT_framebuffer_multisample,
    1504                 :         ANGLE_framebuffer_multisample,
    1505                 :         OES_rgb8_rgba8,
    1506                 :         ARB_robustness,
    1507                 :         EXT_robustness,
    1508                 :         Extensions_Max
    1509                 :     };
    1510                 : 
    1511               0 :     bool IsExtensionSupported(GLExtensions aKnownExtension) {
    1512               0 :         return mAvailableExtensions[aKnownExtension];
    1513                 :     }
    1514                 : 
    1515                 :     // for unknown extensions
    1516                 :     bool IsExtensionSupported(const char *extension);
    1517                 : 
    1518                 :     // Shared code for GL extensions and GLX extensions.
    1519                 :     static bool ListHasExtension(const GLubyte *extensions,
    1520                 :                                    const char *extension);
    1521                 : 
    1522               0 :     GLint GetMaxTextureSize() { return mMaxTextureSize; }
    1523               0 :     GLint GetMaxTextureImageSize() { return mMaxTextureImageSize; }
    1524               0 :     void SetFlipped(bool aFlipped) { mFlipped = aFlipped; }
    1525                 : 
    1526                 :     // this should just be a std::bitset, but that ended up breaking
    1527                 :     // MacOS X builds; see bug 584919.  We can replace this with one
    1528                 :     // later on.  This is handy to use in WebGL contexts as well,
    1529                 :     // so making it public.
    1530                 :     template<size_t setlen>
    1531                 :     struct ExtensionBitset {
    1532                 :         ExtensionBitset() {
    1533                 :             for (size_t i = 0; i < setlen; ++i)
    1534                 :                 values[i] = false;
    1535                 :         }
    1536                 : 
    1537               0 :         bool& operator[](size_t index) {
    1538               0 :             NS_ASSERTION(index < setlen, "out of range");
    1539               0 :             return values[index];
    1540                 :         }
    1541                 : 
    1542                 :         bool values[setlen];
    1543                 :     };
    1544                 : 
    1545                 :     /**
    1546                 :      * Context reset constants.
    1547                 :      * These are used to determine who is guilty when a context reset
    1548                 :      * happens.
    1549                 :      */
    1550                 :     enum ContextResetARB {
    1551                 :         CONTEXT_NO_ERROR = 0,
    1552                 :         CONTEXT_GUILTY_CONTEXT_RESET_ARB = 0x8253,
    1553                 :         CONTEXT_INNOCENT_CONTEXT_RESET_ARB = 0x8254,
    1554                 :         CONTEXT_UNKNOWN_CONTEXT_RESET_ARB = 0x8255
    1555                 :     };
    1556                 : 
    1557               0 :     bool HasRobustness() {
    1558               0 :         return mHasRobustness;
    1559                 :     }
    1560                 : 
    1561                 : protected:
    1562                 :     bool mInitialized;
    1563                 :     bool mIsOffscreen;
    1564                 :     bool mIsGLES2;
    1565                 :     bool mIsGlobalSharedContext;
    1566                 :     bool mHasRobustness;
    1567                 :     bool mContextLost;
    1568                 : 
    1569                 :     PRInt32 mVendor;
    1570                 :     PRInt32 mRenderer;
    1571                 : 
    1572                 : public:
    1573                 :     enum {
    1574                 :         DebugEnabled = 1 << 0,
    1575                 :         DebugTrace = 1 << 1,
    1576                 :         DebugAbortOnError = 1 << 2
    1577                 :     };
    1578                 : 
    1579                 :     static PRUint32 sDebugMode;
    1580                 : 
    1581               0 :     static PRUint32 DebugMode() {
    1582                 : #ifdef DEBUG
    1583               0 :         return sDebugMode;
    1584                 : #else
    1585                 :         return 0;
    1586                 : #endif
    1587                 :     }
    1588                 : 
    1589                 : protected:
    1590                 : 
    1591                 :     ContextFormat mCreationFormat;
    1592                 :     nsRefPtr<GLContext> mSharedContext;
    1593                 : 
    1594                 :     GLContextSymbols mSymbols;
    1595                 : 
    1596                 : #ifdef DEBUG
    1597                 :     // GLDebugMode will check that we don't send call
    1598                 :     // to a GLContext that isn't current on the current
    1599                 :     // thread.
    1600                 :     // Store the current context when binding to thread local
    1601                 :     // storage to support DebugMode on an arbitrary thread.
    1602                 :     static PRUintn sCurrentGLContextTLS;
    1603                 : #endif
    1604                 : 
    1605                 :     void UpdateActualFormat();
    1606                 :     ContextFormat mActualFormat;
    1607                 : 
    1608                 :     gfxIntSize mOffscreenSize;
    1609                 :     gfxIntSize mOffscreenActualSize;
    1610                 :     GLuint mOffscreenTexture;
    1611                 :     bool mFlipped;
    1612                 : 
    1613                 :     // lazy-initialized things
    1614                 :     GLuint mBlitProgram, mBlitFramebuffer;
    1615                 :     void UseBlitProgram();
    1616                 :     void SetBlitFramebufferForDestTexture(GLuint aTexture);
    1617                 : 
    1618                 :     // Helper to create/resize an offscreen FBO,
    1619                 :     // for offscreen implementations that use FBOs.
    1620                 :     // Note that it does -not- clear the resized buffers.
    1621                 :     bool ResizeOffscreenFBO(const gfxIntSize& aSize, const bool aUseReadFBO, const bool aDisableAA);
    1622                 :     bool ResizeOffscreenFBO(const gfxIntSize& aSize, const bool aUseReadFBO) {
    1623                 :         if (ResizeOffscreenFBO(aSize, aUseReadFBO, false))
    1624                 :             return true;
    1625                 : 
    1626                 :         if (!mCreationFormat.samples) {
    1627                 :             NS_WARNING("ResizeOffscreenFBO failed to resize non-AA context!");
    1628                 :             return false;
    1629                 :         } else {
    1630                 :             NS_WARNING("ResizeOffscreenFBO failed to resize AA context! Falling back to no AA...");
    1631                 :         }
    1632                 : 
    1633                 :         if (DebugMode()) {
    1634                 :             printf_stderr("Requested level of multisampling is unavailable, continuing without multisampling\n");
    1635                 :         }
    1636                 : 
    1637                 :         if (ResizeOffscreenFBO(aSize, aUseReadFBO, true))
    1638                 :             return true;
    1639                 : 
    1640                 :         NS_WARNING("ResizeOffscreenFBO failed to resize AA context even without AA!");
    1641                 :         return false;
    1642                 :     }
    1643                 : 
    1644                 :     void DeleteOffscreenFBO();
    1645                 : 
    1646                 :     GLuint mOffscreenDrawFBO;
    1647                 :     GLuint mOffscreenReadFBO;
    1648                 :     GLuint mOffscreenColorRB;
    1649                 :     GLuint mOffscreenDepthRB;
    1650                 :     GLuint mOffscreenStencilRB;
    1651                 : 
    1652                 :     ExtensionBitset<Extensions_Max> mAvailableExtensions;
    1653                 : 
    1654                 :     // Clear to transparent black, with 0 depth and stencil,
    1655                 :     // while preserving current ClearColor etc. values.
    1656                 :     // Useful for resizing offscreen buffers.
    1657                 : public:
    1658                 :     void ClearSafely();
    1659                 : 
    1660                 : protected:
    1661                 : 
    1662                 :     nsDataHashtable<nsVoidPtrHashKey, void*> mUserData;
    1663                 : 
    1664                 :     void SetIsGLES2(bool aIsGLES2) {
    1665                 :         NS_ASSERTION(!mInitialized, "SetIsGLES2 can only be called before initialization!");
    1666                 :         mIsGLES2 = aIsGLES2;
    1667                 :     }
    1668                 : 
    1669                 :     bool InitWithPrefix(const char *prefix, bool trygl);
    1670                 : 
    1671                 :     void InitExtensions();
    1672                 : 
    1673                 :     virtual already_AddRefed<TextureImage>
    1674                 :     CreateBasicTextureImage(GLuint aTexture,
    1675                 :                             const nsIntSize& aSize,
    1676                 :                             GLenum aWrapMode,
    1677                 :                             TextureImage::ContentType aContentType,
    1678                 :                             GLContext* aContext)
    1679                 :     {
    1680                 :         nsRefPtr<BasicTextureImage> teximage(
    1681                 :             new BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, aContext));
    1682                 :         return teximage.forget();
    1683                 :     }
    1684                 : 
    1685                 :     bool IsOffscreenSizeAllowed(const gfxIntSize& aSize) const {
    1686                 :         PRInt32 biggerDimension = NS_MAX(aSize.width, aSize.height);
    1687                 :         PRInt32 maxAllowed = NS_MIN(mMaxRenderbufferSize, mMaxTextureSize);
    1688                 :         return biggerDimension <= maxAllowed;
    1689                 :     }
    1690                 : 
    1691                 : protected:
    1692                 :     nsTArray<nsIntRect> mViewportStack;
    1693                 :     nsTArray<nsIntRect> mScissorStack;
    1694                 : 
    1695                 :     GLint mMaxTextureSize;
    1696                 :     GLint mMaxCubeMapTextureSize;
    1697                 :     GLint mMaxTextureImageSize;
    1698                 :     GLint mMaxRenderbufferSize;
    1699                 : 
    1700               0 :     bool IsTextureSizeSafeToPassToDriver(GLenum target, GLsizei width, GLsizei height) const {
    1701                 : #ifdef XP_MACOSX
    1702                 :         if (mVendor == VendorIntel) {
    1703                 :             // see bug 737182 for 2D textures, bug 684822 for cube map textures.
    1704                 :             // some drivers handle incorrectly some large texture sizes that are below the
    1705                 :             // max texture size that they report. So we check ourselves against our own values
    1706                 :             // (mMax[CubeMap]TextureSize).
    1707                 :             GLsizei maxSize = target == LOCAL_GL_TEXTURE_CUBE_MAP ||
    1708                 :                                 (target >= LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
    1709                 :                                 target <= LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
    1710                 :                               ? mMaxCubeMapTextureSize
    1711                 :                               : mMaxTextureSize;
    1712                 :             return width <= maxSize && height <= maxSize;
    1713                 :         }
    1714                 : #endif
    1715               0 :         return true;
    1716                 :     }
    1717                 : 
    1718                 : public:
    1719                 :  
    1720                 :     /** \returns the first GL error, and guarantees that all GL error flags are cleared,
    1721                 :       * i.e. that a subsequent GetError call will return NO_ERROR
    1722                 :       */
    1723               0 :     GLenum GetAndClearError() {
    1724                 :         // the first error is what we want to return
    1725               0 :         GLenum error = fGetError();
    1726                 :         
    1727               0 :         if (error) {
    1728                 :             // clear all pending errors
    1729               0 :             while(fGetError()) {}
    1730                 :         }
    1731                 :         
    1732               0 :         return error;
    1733                 :     }
    1734                 : 
    1735                 : #ifdef DEBUG
    1736                 : 
    1737                 : #ifndef MOZ_FUNCTION_NAME
    1738                 : # ifdef __GNUC__
    1739                 : #  define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
    1740                 : # elif defined(_MSC_VER)
    1741                 : #  define MOZ_FUNCTION_NAME __FUNCTION__
    1742                 : # else
    1743                 : #  define MOZ_FUNCTION_NAME __func__  // defined in C99, supported in various C++ compilers. Just raw function name.
    1744                 : # endif
    1745                 : #endif
    1746                 : 
    1747                 : protected:
    1748                 :     GLenum mGLError;
    1749                 : 
    1750                 : public:
    1751                 : 
    1752               0 :     void BeforeGLCall(const char* glFunction) {
    1753               0 :         if (DebugMode()) {
    1754               0 :             GLContext *currentGLContext = NULL;
    1755                 : 
    1756               0 :             currentGLContext = (GLContext*)PR_GetThreadPrivate(sCurrentGLContextTLS);
    1757                 : 
    1758               0 :             if (DebugMode() & DebugTrace)
    1759               0 :                 printf_stderr("[gl:%p] > %s\n", this, glFunction);
    1760               0 :             if (this != currentGLContext) {
    1761                 :                 printf_stderr("Fatal: %s called on non-current context %p. "
    1762                 :                               "The current context for this thread is %p.\n",
    1763               0 :                                glFunction, this, currentGLContext);
    1764               0 :                 NS_ABORT();
    1765                 :             }
    1766                 :         }
    1767               0 :     }
    1768                 : 
    1769               0 :     void AfterGLCall(const char* glFunction) {
    1770               0 :         if (DebugMode()) {
    1771                 :             // calling fFinish() immediately after every GL call makes sure that if this GL command crashes,
    1772                 :             // the stack trace will actually point to it. Otherwise, OpenGL being an asynchronous API, stack traces
    1773                 :             // tend to be meaningless
    1774               0 :             mSymbols.fFinish();
    1775               0 :             mGLError = mSymbols.fGetError();
    1776               0 :             if (DebugMode() & DebugTrace)
    1777               0 :                 printf_stderr("[gl:%p] < %s [0x%04x]\n", this, glFunction, mGLError);
    1778               0 :             if (mGLError != LOCAL_GL_NO_ERROR) {
    1779                 :                 printf_stderr("GL ERROR: %s generated GL error %s(0x%04x)\n", 
    1780                 :                               glFunction,
    1781                 :                               GLErrorToString(mGLError),
    1782               0 :                               mGLError);
    1783               0 :                 if (DebugMode() & DebugAbortOnError)
    1784               0 :                     NS_ABORT();
    1785                 :             }
    1786                 :         }
    1787               0 :     }
    1788                 : 
    1789               0 :     const char* GLErrorToString(GLenum aError)
    1790                 :     {
    1791               0 :         switch (aError) {
    1792                 :             case LOCAL_GL_INVALID_ENUM:
    1793               0 :                 return "GL_INVALID_ENUM";
    1794                 :             case LOCAL_GL_INVALID_VALUE:
    1795               0 :                 return "GL_INVALID_VALUE";
    1796                 :             case LOCAL_GL_INVALID_OPERATION:
    1797               0 :                 return "GL_INVALID_OPERATION";
    1798                 :             case LOCAL_GL_STACK_OVERFLOW:
    1799               0 :                 return "GL_STACK_OVERFLOW";
    1800                 :             case LOCAL_GL_STACK_UNDERFLOW:
    1801               0 :                 return "GL_STACK_UNDERFLOW";
    1802                 :             case LOCAL_GL_OUT_OF_MEMORY:
    1803               0 :                 return "GL_OUT_OF_MEMORY";
    1804                 :             case LOCAL_GL_TABLE_TOO_LARGE:
    1805               0 :                 return "GL_TABLE_TOO_LARGE";
    1806                 :             case LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION:
    1807               0 :                 return "GL_INVALID_FRAMEBUFFER_OPERATION";
    1808                 :             default:
    1809               0 :                 return "";
    1810                 :         }
    1811                 :      }
    1812                 : 
    1813                 : #define BEFORE_GL_CALL do {                     \
    1814                 :     BeforeGLCall(MOZ_FUNCTION_NAME);            \
    1815                 : } while (0)
    1816                 :     
    1817                 : #define AFTER_GL_CALL do {                      \
    1818                 :     AfterGLCall(MOZ_FUNCTION_NAME);             \
    1819                 : } while (0)
    1820                 : 
    1821                 : #else
    1822                 : 
    1823                 : #define BEFORE_GL_CALL do { } while (0)
    1824                 : #define AFTER_GL_CALL do { } while (0)
    1825                 : 
    1826                 : #endif
    1827                 : 
    1828                 :     /*** In GL debug mode, we completely override glGetError ***/
    1829                 : 
    1830               0 :     GLenum fGetError() {
    1831                 : #ifdef DEBUG
    1832                 :         // debug mode ends up eating the error in AFTER_GL_CALL
    1833               0 :         if (DebugMode()) {
    1834               0 :             GLenum err = mGLError;
    1835               0 :             mGLError = LOCAL_GL_NO_ERROR;
    1836               0 :             return err;
    1837                 :         }
    1838                 : #endif
    1839                 : 
    1840               0 :         return mSymbols.fGetError();
    1841                 :     }
    1842                 : 
    1843                 : 
    1844                 :     /*** Scissor functions ***/
    1845                 : 
    1846                 : protected:
    1847                 : 
    1848               0 :     GLint FixYValue(GLint y, GLint height)
    1849                 :     {
    1850               0 :         return mFlipped ? ViewportRect().height - (height + y) : y;
    1851                 :     }
    1852                 : 
    1853                 :     // only does the glScissor call, no ScissorRect business
    1854               0 :     void raw_fScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
    1855               0 :         BEFORE_GL_CALL;
    1856                 :         // GL's coordinate system is flipped compared to ours (in the Y axis),
    1857                 :         // so we may need to flip our rectangle.
    1858                 :         mSymbols.fScissor(x, 
    1859                 :                           FixYValue(y, height),
    1860                 :                           width, 
    1861               0 :                           height);
    1862               0 :         AFTER_GL_CALL;
    1863               0 :     }
    1864                 : 
    1865                 : public:
    1866                 : 
    1867                 :     // but let GL-using code use that instead, updating the ScissorRect
    1868               0 :     void fScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
    1869               0 :         ScissorRect().SetRect(x, y, width, height);
    1870               0 :         raw_fScissor(x, y, width, height);
    1871               0 :     }
    1872                 : 
    1873               0 :     nsIntRect& ScissorRect() {
    1874               0 :         return mScissorStack[mScissorStack.Length()-1];
    1875                 :     }
    1876                 : 
    1877               0 :     void PushScissorRect() {
    1878               0 :         nsIntRect copy(ScissorRect());
    1879               0 :         mScissorStack.AppendElement(copy);
    1880               0 :     }
    1881                 : 
    1882                 :     void PushScissorRect(const nsIntRect& aRect) {
    1883                 :         mScissorStack.AppendElement(aRect);
    1884                 :         raw_fScissor(aRect.x, aRect.y, aRect.width, aRect.height);
    1885                 :     }
    1886                 : 
    1887               0 :     void PopScissorRect() {
    1888               0 :         if (mScissorStack.Length() < 2) {
    1889               0 :             NS_WARNING("PopScissorRect with Length < 2!");
    1890               0 :             return;
    1891                 :         }
    1892                 : 
    1893               0 :         nsIntRect thisRect = ScissorRect();
    1894               0 :         mScissorStack.TruncateLength(mScissorStack.Length() - 1);
    1895               0 :         if (!thisRect.IsEqualInterior(ScissorRect())) {
    1896               0 :             raw_fScissor(ScissorRect().x, ScissorRect().y,
    1897               0 :                               ScissorRect().width, ScissorRect().height);
    1898                 :         }
    1899                 :     }
    1900                 : 
    1901                 :     /*** Viewport functions ***/
    1902                 : 
    1903                 : protected:
    1904                 : 
    1905                 :     // only does the glViewport call, no ViewportRect business
    1906               0 :     void raw_fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
    1907               0 :         BEFORE_GL_CALL;
    1908                 :         // XXX: Flipping should really happen using the destination height, but
    1909                 :         // we use viewport instead and assume viewport size matches the
    1910                 :         // destination. If we ever try use partial viewports for layers we need
    1911                 :         // to fix this, and remove the assertion.
    1912               0 :         NS_ASSERTION(!mFlipped || (x == 0 && y == 0), "TODO: Need to flip the viewport rect"); 
    1913               0 :         mSymbols.fViewport(x, y, width, height);
    1914               0 :         AFTER_GL_CALL;
    1915               0 :     }
    1916                 : 
    1917                 : public:
    1918                 : 
    1919               0 :     void fViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
    1920               0 :         ViewportRect().SetRect(x, y, width, height);
    1921               0 :         raw_fViewport(x, y, width, height);
    1922               0 :     }
    1923                 : 
    1924               0 :     nsIntRect& ViewportRect() {
    1925               0 :         return mViewportStack[mViewportStack.Length()-1];
    1926                 :     }
    1927                 : 
    1928               0 :     void PushViewportRect() {
    1929               0 :         nsIntRect copy(ViewportRect());
    1930               0 :         mViewportStack.AppendElement(copy);
    1931               0 :     }
    1932                 : 
    1933                 :     void PushViewportRect(const nsIntRect& aRect) {
    1934                 :         mViewportStack.AppendElement(aRect);
    1935                 :         raw_fViewport(aRect.x, aRect.y, aRect.width, aRect.height);
    1936                 :     }
    1937                 : 
    1938               0 :     void PopViewportRect() {
    1939               0 :         if (mViewportStack.Length() < 2) {
    1940               0 :             NS_WARNING("PopViewportRect with Length < 2!");
    1941               0 :             return;
    1942                 :         }
    1943                 : 
    1944               0 :         nsIntRect thisRect = ViewportRect();
    1945               0 :         mViewportStack.TruncateLength(mViewportStack.Length() - 1);
    1946               0 :         if (!thisRect.IsEqualInterior(ViewportRect())) {
    1947               0 :             raw_fViewport(ViewportRect().x, ViewportRect().y,
    1948               0 :                           ViewportRect().width, ViewportRect().height);
    1949                 :         }
    1950                 :     }
    1951                 : 
    1952                 :     /*** other GL functions ***/
    1953                 : 
    1954               0 :     void fActiveTexture(GLenum texture) {
    1955               0 :         BEFORE_GL_CALL;
    1956               0 :         mSymbols.fActiveTexture(texture);
    1957               0 :         AFTER_GL_CALL;
    1958               0 :     }
    1959                 : 
    1960               0 :     void fAttachShader(GLuint program, GLuint shader) {
    1961               0 :         BEFORE_GL_CALL;
    1962               0 :         mSymbols.fAttachShader(program, shader);
    1963               0 :         AFTER_GL_CALL;
    1964               0 :     }
    1965                 : 
    1966               0 :     void fBindAttribLocation(GLuint program, GLuint index, const GLchar* name) {
    1967               0 :         BEFORE_GL_CALL;
    1968               0 :         mSymbols.fBindAttribLocation(program, index, name);
    1969               0 :         AFTER_GL_CALL;
    1970               0 :     }
    1971                 : 
    1972               0 :     void fBindBuffer(GLenum target, GLuint buffer) {
    1973               0 :         BEFORE_GL_CALL;
    1974               0 :         mSymbols.fBindBuffer(target, buffer);
    1975               0 :         AFTER_GL_CALL;
    1976               0 :     }
    1977                 : 
    1978               0 :     void fBindTexture(GLenum target, GLuint texture) {
    1979               0 :         BEFORE_GL_CALL;
    1980               0 :         mSymbols.fBindTexture(target, texture);
    1981               0 :         AFTER_GL_CALL;
    1982               0 :     }
    1983                 : 
    1984               0 :     void fBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
    1985               0 :         BEFORE_GL_CALL;
    1986               0 :         mSymbols.fBlendColor(red, green, blue, alpha);
    1987               0 :         AFTER_GL_CALL;
    1988               0 :     }
    1989                 : 
    1990               0 :     void fBlendEquation(GLenum mode) {
    1991               0 :         BEFORE_GL_CALL;
    1992               0 :         mSymbols.fBlendEquation(mode);
    1993               0 :         AFTER_GL_CALL;
    1994               0 :     }
    1995                 : 
    1996               0 :     void fBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
    1997               0 :         BEFORE_GL_CALL;
    1998               0 :         mSymbols.fBlendEquationSeparate(modeRGB, modeAlpha);
    1999               0 :         AFTER_GL_CALL;
    2000               0 :     }
    2001                 : 
    2002               0 :     void fBlendFunc(GLenum sfactor, GLenum dfactor) {
    2003               0 :         BEFORE_GL_CALL;
    2004               0 :         mSymbols.fBlendFunc(sfactor, dfactor);
    2005               0 :         AFTER_GL_CALL;
    2006               0 :     }
    2007                 : 
    2008               0 :     void fBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {
    2009               0 :         BEFORE_GL_CALL;
    2010               0 :         mSymbols.fBlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha);
    2011               0 :         AFTER_GL_CALL;
    2012               0 :     }
    2013                 : 
    2014               0 :     void fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
    2015               0 :         BEFORE_GL_CALL;
    2016               0 :         mSymbols.fBufferData(target, size, data, usage);
    2017                 : 
    2018                 :         // bug 744888
    2019               0 :         if (!data &&
    2020               0 :             Vendor() == VendorNVIDIA)
    2021                 :         {
    2022               0 :             char c = 0;
    2023               0 :             mSymbols.fBufferSubData(target, size-1, 1, &c);
    2024                 :         }
    2025                 : 
    2026               0 :         AFTER_GL_CALL;
    2027               0 :     }
    2028                 : 
    2029               0 :     void fBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) {
    2030               0 :         BEFORE_GL_CALL;
    2031               0 :         mSymbols.fBufferSubData(target, offset, size, data);
    2032               0 :         AFTER_GL_CALL;
    2033               0 :     }
    2034                 : 
    2035               0 :     void raw_fClear(GLbitfield mask) {
    2036               0 :         BEFORE_GL_CALL;
    2037               0 :         mSymbols.fClear(mask);
    2038               0 :         AFTER_GL_CALL;
    2039               0 :     }
    2040                 : 
    2041               0 :     void fClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a) {
    2042               0 :         BEFORE_GL_CALL;
    2043               0 :         mSymbols.fClearColor(r, g, b, a);
    2044               0 :         AFTER_GL_CALL;
    2045               0 :     }
    2046                 : 
    2047               0 :     void fClearStencil(GLint s) {
    2048               0 :         BEFORE_GL_CALL;
    2049               0 :         mSymbols.fClearStencil(s);
    2050               0 :         AFTER_GL_CALL;
    2051               0 :     }
    2052                 : 
    2053               0 :     void fColorMask(realGLboolean red, realGLboolean green, realGLboolean blue, realGLboolean alpha) {
    2054               0 :         BEFORE_GL_CALL;
    2055               0 :         mSymbols.fColorMask(red, green, blue, alpha);
    2056               0 :         AFTER_GL_CALL;
    2057               0 :     }
    2058                 : 
    2059               0 :     void fCullFace(GLenum mode) {
    2060               0 :         BEFORE_GL_CALL;
    2061               0 :         mSymbols.fCullFace(mode);
    2062               0 :         AFTER_GL_CALL;
    2063               0 :     }
    2064                 : 
    2065               0 :     void fDetachShader(GLuint program, GLuint shader) {
    2066               0 :         BEFORE_GL_CALL;
    2067               0 :         mSymbols.fDetachShader(program, shader);
    2068               0 :         AFTER_GL_CALL;
    2069               0 :     }
    2070                 : 
    2071               0 :     void fDepthFunc(GLenum func) {
    2072               0 :         BEFORE_GL_CALL;
    2073               0 :         mSymbols.fDepthFunc(func);
    2074               0 :         AFTER_GL_CALL;
    2075               0 :     }
    2076                 : 
    2077               0 :     void fDepthMask(realGLboolean flag) {
    2078               0 :         BEFORE_GL_CALL;
    2079               0 :         mSymbols.fDepthMask(flag);
    2080               0 :         AFTER_GL_CALL;
    2081               0 :     }
    2082                 : 
    2083               0 :     void fDisable(GLenum capability) {
    2084               0 :         BEFORE_GL_CALL;
    2085               0 :         mSymbols.fDisable(capability);
    2086               0 :         AFTER_GL_CALL;
    2087               0 :     }
    2088                 : 
    2089               0 :     void fDisableVertexAttribArray(GLuint index) {
    2090               0 :         BEFORE_GL_CALL;
    2091               0 :         mSymbols.fDisableVertexAttribArray(index);
    2092               0 :         AFTER_GL_CALL;
    2093               0 :     }
    2094                 : 
    2095               0 :     void raw_fDrawArrays(GLenum mode, GLint first, GLsizei count) {
    2096               0 :         BEFORE_GL_CALL;
    2097               0 :         mSymbols.fDrawArrays(mode, first, count);
    2098               0 :         AFTER_GL_CALL;
    2099               0 :     }
    2100                 : 
    2101               0 :     void raw_fDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {
    2102               0 :         BEFORE_GL_CALL;
    2103               0 :         mSymbols.fDrawElements(mode, count, type, indices);
    2104               0 :         AFTER_GL_CALL;
    2105               0 :     }
    2106                 : 
    2107               0 :     void fEnable(GLenum capability) {
    2108               0 :         BEFORE_GL_CALL;
    2109               0 :         mSymbols.fEnable(capability);
    2110               0 :         AFTER_GL_CALL;
    2111               0 :     }
    2112                 : 
    2113               0 :     void fEnableVertexAttribArray(GLuint index) {
    2114               0 :         BEFORE_GL_CALL;
    2115               0 :         mSymbols.fEnableVertexAttribArray(index);
    2116               0 :         AFTER_GL_CALL;
    2117               0 :     }
    2118                 : 
    2119               0 :     void raw_fFinish() {
    2120               0 :         BEFORE_GL_CALL;
    2121               0 :         mSymbols.fFinish();
    2122               0 :         AFTER_GL_CALL;
    2123               0 :     }
    2124                 : 
    2125               0 :     void fFlush() {
    2126               0 :         BEFORE_GL_CALL;
    2127               0 :         mSymbols.fFlush();
    2128               0 :         AFTER_GL_CALL;
    2129               0 :     }
    2130                 : 
    2131               0 :     void fFrontFace(GLenum face) {
    2132               0 :         BEFORE_GL_CALL;
    2133               0 :         mSymbols.fFrontFace(face);
    2134               0 :         AFTER_GL_CALL;
    2135               0 :     }
    2136                 : 
    2137               0 :     void fGetActiveAttrib(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
    2138               0 :         BEFORE_GL_CALL;
    2139               0 :         mSymbols.fGetActiveAttrib(program, index, maxLength, length, size, type, name);
    2140               0 :         AFTER_GL_CALL;
    2141               0 :     }
    2142                 : 
    2143               0 :     void fGetActiveUniform(GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
    2144               0 :         BEFORE_GL_CALL;
    2145               0 :         mSymbols.fGetActiveUniform(program, index, maxLength, length, size, type, name);
    2146               0 :         AFTER_GL_CALL;
    2147               0 :     }
    2148                 : 
    2149                 :     void fGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) {
    2150                 :         BEFORE_GL_CALL;
    2151                 :         mSymbols.fGetAttachedShaders(program, maxCount, count, shaders);
    2152                 :         AFTER_GL_CALL;
    2153                 :     }
    2154                 : 
    2155               0 :     GLint fGetAttribLocation (GLuint program, const GLchar* name) {
    2156               0 :         BEFORE_GL_CALL;
    2157               0 :         GLint retval = mSymbols.fGetAttribLocation(program, name);
    2158               0 :         AFTER_GL_CALL;
    2159               0 :         return retval;
    2160                 :     }
    2161                 : 
    2162                 : private:
    2163               0 :     void raw_fGetIntegerv(GLenum pname, GLint *params) {
    2164               0 :         BEFORE_GL_CALL;
    2165               0 :         mSymbols.fGetIntegerv(pname, params);
    2166               0 :         AFTER_GL_CALL;
    2167               0 :     }
    2168                 : 
    2169                 : public:
    2170               0 :     void fGetIntegerv(GLenum pname, GLint *params) {
    2171               0 :         switch (pname)
    2172                 :         {
    2173                 :             // LOCAL_GL_FRAMEBUFFER_BINDING is equal to
    2174                 :             // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, so we don't need two
    2175                 :             // cases.
    2176                 :             case LOCAL_GL_FRAMEBUFFER_BINDING:
    2177               0 :                 *params = GetUserBoundDrawFBO();
    2178               0 :                 break;
    2179                 : 
    2180                 :             case LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT:
    2181               0 :                 *params = GetUserBoundReadFBO();
    2182               0 :                 break;
    2183                 : 
    2184                 :             default:
    2185               0 :                 raw_fGetIntegerv(pname, params);
    2186               0 :                 break;
    2187                 :         }
    2188               0 :     }
    2189                 : 
    2190               0 :     void fGetFloatv(GLenum pname, GLfloat *params) {
    2191               0 :         BEFORE_GL_CALL;
    2192               0 :         mSymbols.fGetFloatv(pname, params);
    2193               0 :         AFTER_GL_CALL;
    2194               0 :     }
    2195                 : 
    2196               0 :     void fGetBooleanv(GLenum pname, realGLboolean *params) {
    2197               0 :         BEFORE_GL_CALL;
    2198               0 :         mSymbols.fGetBooleanv(pname, params);
    2199               0 :         AFTER_GL_CALL;
    2200               0 :     }
    2201                 : 
    2202               0 :     void fGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
    2203               0 :         BEFORE_GL_CALL;
    2204               0 :         mSymbols.fGetBufferParameteriv(target, pname, params);
    2205               0 :         AFTER_GL_CALL;
    2206               0 :     }
    2207                 : 
    2208               0 :     void fGenerateMipmap(GLenum target) {
    2209               0 :         BEFORE_GL_CALL;
    2210               0 :         mSymbols.fGenerateMipmap(target);
    2211               0 :         AFTER_GL_CALL;
    2212               0 :     }
    2213                 : 
    2214               0 :     void fGetProgramiv(GLuint program, GLenum pname, GLint* param) {
    2215               0 :         BEFORE_GL_CALL;
    2216               0 :         mSymbols.fGetProgramiv(program, pname, param);
    2217               0 :         AFTER_GL_CALL;
    2218               0 :     }
    2219                 : 
    2220               0 :     void fGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
    2221               0 :         BEFORE_GL_CALL;
    2222               0 :         mSymbols.fGetProgramInfoLog(program, bufSize, length, infoLog);
    2223               0 :         AFTER_GL_CALL;
    2224               0 :     }
    2225                 : 
    2226               0 :     void fTexParameteri(GLenum target, GLenum pname, GLint param) {
    2227               0 :         BEFORE_GL_CALL;
    2228               0 :         mSymbols.fTexParameteri(target, pname, param);
    2229               0 :         AFTER_GL_CALL;
    2230               0 :     }
    2231                 : 
    2232               0 :     void fTexParameterf(GLenum target, GLenum pname, GLfloat param) {
    2233               0 :         BEFORE_GL_CALL;
    2234               0 :         mSymbols.fTexParameterf(target, pname, param);
    2235               0 :         AFTER_GL_CALL;
    2236               0 :     }
    2237                 : 
    2238               0 :     const GLubyte* fGetString(GLenum name) {
    2239               0 :         BEFORE_GL_CALL;
    2240               0 :         const GLubyte *result = mSymbols.fGetString(name);
    2241               0 :         AFTER_GL_CALL;
    2242               0 :         return result;
    2243                 :     }
    2244                 : 
    2245                 :     void fGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *img) {
    2246                 :         if (!mSymbols.fGetTexImage) {
    2247                 :           return;
    2248                 :         }
    2249                 :         BEFORE_GL_CALL;
    2250                 :         mSymbols.fGetTexImage(target, level, format, type, img);
    2251                 :         AFTER_GL_CALL;
    2252                 :     };
    2253                 : 
    2254                 :     void fGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
    2255                 :     {  
    2256                 :         if (!mSymbols.fGetTexLevelParameteriv) {
    2257                 :           *params = 0;
    2258                 :           return;
    2259                 :         }
    2260                 :         BEFORE_GL_CALL;
    2261                 :         mSymbols.fGetTexLevelParameteriv(target, level, pname, params);
    2262                 :         AFTER_GL_CALL;
    2263                 :     }
    2264                 : 
    2265               0 :     void fGetTexParameterfv(GLenum target, GLenum pname, const GLfloat *params) {
    2266               0 :         BEFORE_GL_CALL;
    2267               0 :         mSymbols.fGetTexParameterfv(target, pname, params);
    2268               0 :         AFTER_GL_CALL;
    2269               0 :     }
    2270                 : 
    2271               0 :     void fGetTexParameteriv(GLenum target, GLenum pname, const GLint *params) {
    2272               0 :         BEFORE_GL_CALL;
    2273               0 :         mSymbols.fGetTexParameteriv(target, pname, params);
    2274               0 :         AFTER_GL_CALL;
    2275               0 :     }
    2276                 : 
    2277               0 :     void fGetUniformfv(GLuint program, GLint location, GLfloat* params) {
    2278               0 :         BEFORE_GL_CALL;
    2279               0 :         mSymbols.fGetUniformfv(program, location, params);
    2280               0 :         AFTER_GL_CALL;
    2281               0 :     }
    2282                 : 
    2283               0 :     void fGetUniformiv(GLuint program, GLint location, GLint* params) {
    2284               0 :         BEFORE_GL_CALL;
    2285               0 :         mSymbols.fGetUniformiv(program, location, params);
    2286               0 :         AFTER_GL_CALL;
    2287               0 :     }
    2288                 : 
    2289               0 :     GLint fGetUniformLocation (GLint programObj, const GLchar* name) {
    2290               0 :         BEFORE_GL_CALL;
    2291               0 :         GLint retval = mSymbols.fGetUniformLocation(programObj, name);
    2292               0 :         AFTER_GL_CALL;
    2293               0 :         return retval;
    2294                 :     }
    2295                 : 
    2296               0 :     void fGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* retval) {
    2297               0 :         BEFORE_GL_CALL;
    2298               0 :         mSymbols.fGetVertexAttribfv(index, pname, retval);
    2299               0 :         AFTER_GL_CALL;
    2300               0 :     }
    2301                 : 
    2302               0 :     void fGetVertexAttribiv(GLuint index, GLenum pname, GLint* retval) {
    2303               0 :         BEFORE_GL_CALL;
    2304               0 :         mSymbols.fGetVertexAttribiv(index, pname, retval);
    2305               0 :         AFTER_GL_CALL;
    2306               0 :     }
    2307                 : 
    2308               0 :     void fHint(GLenum target, GLenum mode) {
    2309               0 :         BEFORE_GL_CALL;
    2310               0 :         mSymbols.fHint(target, mode);
    2311               0 :         AFTER_GL_CALL;
    2312               0 :     }
    2313                 : 
    2314                 :     realGLboolean fIsBuffer(GLuint buffer) {
    2315                 :         BEFORE_GL_CALL;
    2316                 :         realGLboolean retval = mSymbols.fIsBuffer(buffer);
    2317                 :         AFTER_GL_CALL;
    2318                 :         return retval;
    2319                 :     }
    2320                 : 
    2321               0 :     realGLboolean fIsEnabled (GLenum capability) {
    2322               0 :         BEFORE_GL_CALL;
    2323               0 :         realGLboolean retval = mSymbols.fIsEnabled(capability);
    2324               0 :         AFTER_GL_CALL;
    2325               0 :         return retval;
    2326                 :     }
    2327                 : 
    2328                 :     realGLboolean fIsProgram (GLuint program) {
    2329                 :         BEFORE_GL_CALL;
    2330                 :         realGLboolean retval = mSymbols.fIsProgram(program);
    2331                 :         AFTER_GL_CALL;
    2332                 :         return retval;
    2333                 :     }
    2334                 : 
    2335                 :     realGLboolean fIsShader (GLuint shader) {
    2336                 :         BEFORE_GL_CALL;
    2337                 :         realGLboolean retval = mSymbols.fIsShader(shader);
    2338                 :         AFTER_GL_CALL;
    2339                 :         return retval;
    2340                 :     }
    2341                 : 
    2342                 :     realGLboolean fIsTexture (GLuint texture) {
    2343                 :         BEFORE_GL_CALL;
    2344                 :         realGLboolean retval = mSymbols.fIsTexture(texture);
    2345                 :         AFTER_GL_CALL;
    2346                 :         return retval;
    2347                 :     }
    2348                 : 
    2349               0 :     void fLineWidth(GLfloat width) {
    2350               0 :         BEFORE_GL_CALL;
    2351               0 :         mSymbols.fLineWidth(width);
    2352               0 :         AFTER_GL_CALL;
    2353               0 :     }
    2354                 : 
    2355               0 :     void fLinkProgram(GLuint program) {
    2356               0 :         BEFORE_GL_CALL;
    2357               0 :         mSymbols.fLinkProgram(program);
    2358               0 :         AFTER_GL_CALL;
    2359               0 :     }
    2360                 : 
    2361               0 :     void fPixelStorei(GLenum pname, GLint param) {
    2362               0 :         BEFORE_GL_CALL;
    2363               0 :         mSymbols.fPixelStorei(pname, param);
    2364               0 :         AFTER_GL_CALL;
    2365               0 :     }
    2366                 : 
    2367               0 :     void fPolygonOffset(GLfloat factor, GLfloat bias) {
    2368               0 :         BEFORE_GL_CALL;
    2369               0 :         mSymbols.fPolygonOffset(factor, bias);
    2370               0 :         AFTER_GL_CALL;
    2371               0 :     }
    2372                 : 
    2373               0 :     void fReadBuffer(GLenum mode) {
    2374               0 :         BEFORE_GL_CALL;
    2375               0 :         mSymbols.fReadBuffer(mode);
    2376               0 :         AFTER_GL_CALL;
    2377               0 :     }
    2378                 : 
    2379               0 :     void raw_fReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
    2380               0 :         BEFORE_GL_CALL;
    2381               0 :         mSymbols.fReadPixels(x, y, width, height, format, type, pixels);
    2382               0 :         AFTER_GL_CALL;
    2383               0 :     }
    2384                 : 
    2385               0 :     void fSampleCoverage(GLclampf value, realGLboolean invert) {
    2386               0 :         BEFORE_GL_CALL;
    2387               0 :         mSymbols.fSampleCoverage(value, invert);
    2388               0 :         AFTER_GL_CALL;
    2389               0 :     }
    2390                 : 
    2391               0 :     void fStencilFunc(GLenum func, GLint ref, GLuint mask) {
    2392               0 :         BEFORE_GL_CALL;
    2393               0 :         mSymbols.fStencilFunc(func, ref, mask);
    2394               0 :         AFTER_GL_CALL;
    2395               0 :     }
    2396                 : 
    2397               0 :     void fStencilFuncSeparate(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask) {
    2398               0 :         BEFORE_GL_CALL;
    2399               0 :         mSymbols.fStencilFuncSeparate(frontfunc, backfunc, ref, mask);
    2400               0 :         AFTER_GL_CALL;
    2401               0 :     }
    2402                 : 
    2403               0 :     void fStencilMask(GLuint mask) {
    2404               0 :         BEFORE_GL_CALL;
    2405               0 :         mSymbols.fStencilMask(mask);
    2406               0 :         AFTER_GL_CALL;
    2407               0 :     }
    2408                 : 
    2409               0 :     void fStencilMaskSeparate(GLenum face, GLuint mask) {
    2410               0 :         BEFORE_GL_CALL;
    2411               0 :         mSymbols.fStencilMaskSeparate(face, mask);
    2412               0 :         AFTER_GL_CALL;
    2413               0 :     }
    2414                 : 
    2415               0 :     void fStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
    2416               0 :         BEFORE_GL_CALL;
    2417               0 :         mSymbols.fStencilOp(fail, zfail, zpass);
    2418               0 :         AFTER_GL_CALL;
    2419               0 :     }
    2420                 : 
    2421               0 :     void fStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {
    2422               0 :         BEFORE_GL_CALL;
    2423               0 :         mSymbols.fStencilOpSeparate(face, sfail, dpfail, dppass);
    2424               0 :         AFTER_GL_CALL;
    2425               0 :     }
    2426                 : 
    2427               0 :     void fTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
    2428               0 :         BEFORE_GL_CALL;
    2429               0 :         if (IsTextureSizeSafeToPassToDriver(target, width, height)) {
    2430               0 :           mSymbols.fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
    2431                 :         } else {
    2432                 :           // pass wrong values to cause the GL to generate GL_INVALID_VALUE.
    2433                 :           // See bug 737182 and the comment in IsTextureSizeSafeToPassToDriver.
    2434               0 :           mSymbols.fTexImage2D(target, -1, internalformat, -1, -1, -1, format, type, nsnull);
    2435                 :         }
    2436               0 :         AFTER_GL_CALL;
    2437               0 :     }
    2438                 : 
    2439               0 :     void fTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) {
    2440               0 :         BEFORE_GL_CALL;
    2441               0 :         mSymbols.fTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
    2442               0 :         AFTER_GL_CALL;
    2443               0 :     }
    2444                 : 
    2445               0 :     void fUniform1f(GLint location, GLfloat v0) {
    2446               0 :         BEFORE_GL_CALL;
    2447               0 :         mSymbols.fUniform1f(location, v0);
    2448               0 :         AFTER_GL_CALL;
    2449               0 :     }
    2450                 : 
    2451               0 :     void fUniform1fv(GLint location, GLsizei count, const GLfloat* value) {
    2452               0 :         BEFORE_GL_CALL;
    2453               0 :         mSymbols.fUniform1fv(location, count, value);
    2454               0 :         AFTER_GL_CALL;
    2455               0 :     }
    2456                 : 
    2457               0 :     void fUniform1i(GLint location, GLint v0) {
    2458               0 :         BEFORE_GL_CALL;
    2459               0 :         mSymbols.fUniform1i(location, v0);
    2460               0 :         AFTER_GL_CALL;
    2461               0 :     }
    2462                 : 
    2463               0 :     void fUniform1iv(GLint location, GLsizei count, const GLint* value) {
    2464               0 :         BEFORE_GL_CALL;
    2465               0 :         mSymbols.fUniform1iv(location, count, value);
    2466               0 :         AFTER_GL_CALL;
    2467               0 :     }
    2468                 : 
    2469               0 :     void fUniform2f(GLint location, GLfloat v0, GLfloat v1) {
    2470               0 :         BEFORE_GL_CALL;
    2471               0 :         mSymbols.fUniform2f(location, v0, v1);
    2472               0 :         AFTER_GL_CALL;
    2473               0 :     }
    2474                 : 
    2475               0 :     void fUniform2fv(GLint location, GLsizei count, const GLfloat* value) {
    2476               0 :         BEFORE_GL_CALL;
    2477               0 :         mSymbols.fUniform2fv(location, count, value);
    2478               0 :         AFTER_GL_CALL;
    2479               0 :     }
    2480                 : 
    2481               0 :     void fUniform2i(GLint location, GLint v0, GLint v1) {
    2482               0 :         BEFORE_GL_CALL;
    2483               0 :         mSymbols.fUniform2i(location, v0, v1);
    2484               0 :         AFTER_GL_CALL;
    2485               0 :     }
    2486                 : 
    2487               0 :     void fUniform2iv(GLint location, GLsizei count, const GLint* value) {
    2488               0 :         BEFORE_GL_CALL;
    2489               0 :         mSymbols.fUniform2iv(location, count, value);
    2490               0 :         AFTER_GL_CALL;
    2491               0 :     }
    2492                 : 
    2493               0 :     void fUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
    2494               0 :         BEFORE_GL_CALL;
    2495               0 :         mSymbols.fUniform3f(location, v0, v1, v2);
    2496               0 :         AFTER_GL_CALL;
    2497               0 :     }
    2498                 : 
    2499               0 :     void fUniform3fv(GLint location, GLsizei count, const GLfloat* value) {
    2500               0 :         BEFORE_GL_CALL;
    2501               0 :         mSymbols.fUniform3fv(location, count, value);
    2502               0 :         AFTER_GL_CALL;
    2503               0 :     }
    2504                 : 
    2505               0 :     void fUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {
    2506               0 :         BEFORE_GL_CALL;
    2507               0 :         mSymbols.fUniform3i(location, v0, v1, v2);
    2508               0 :         AFTER_GL_CALL;
    2509               0 :     }
    2510                 : 
    2511               0 :     void fUniform3iv(GLint location, GLsizei count, const GLint* value) {
    2512               0 :         BEFORE_GL_CALL;
    2513               0 :         mSymbols.fUniform3iv(location, count, value);
    2514               0 :         AFTER_GL_CALL;
    2515               0 :     }
    2516                 : 
    2517               0 :     void fUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
    2518               0 :         BEFORE_GL_CALL;
    2519               0 :         mSymbols.fUniform4f(location, v0, v1, v2, v3);
    2520               0 :         AFTER_GL_CALL;
    2521               0 :     }
    2522                 : 
    2523               0 :     void fUniform4fv(GLint location, GLsizei count, const GLfloat* value) {
    2524               0 :         BEFORE_GL_CALL;
    2525               0 :         mSymbols.fUniform4fv(location, count, value);
    2526               0 :         AFTER_GL_CALL;
    2527               0 :     }
    2528                 : 
    2529               0 :     void fUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {
    2530               0 :         BEFORE_GL_CALL;
    2531               0 :         mSymbols.fUniform4i(location, v0, v1, v2, v3);
    2532               0 :         AFTER_GL_CALL;
    2533               0 :     }
    2534                 : 
    2535               0 :     void fUniform4iv(GLint location, GLsizei count, const GLint* value) {
    2536               0 :         BEFORE_GL_CALL;
    2537               0 :         mSymbols.fUniform4iv(location, count, value);
    2538               0 :         AFTER_GL_CALL;
    2539               0 :     }
    2540                 : 
    2541               0 :     void fUniformMatrix2fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
    2542               0 :         BEFORE_GL_CALL;
    2543               0 :         mSymbols.fUniformMatrix2fv(location, count, transpose, value);
    2544               0 :         AFTER_GL_CALL;
    2545               0 :     }
    2546                 : 
    2547               0 :     void fUniformMatrix3fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
    2548               0 :         BEFORE_GL_CALL;
    2549               0 :         mSymbols.fUniformMatrix3fv(location, count, transpose, value);
    2550               0 :         AFTER_GL_CALL;
    2551               0 :     }
    2552                 : 
    2553               0 :     void fUniformMatrix4fv(GLint location, GLsizei count, realGLboolean transpose, const GLfloat* value) {
    2554               0 :         BEFORE_GL_CALL;
    2555               0 :         mSymbols.fUniformMatrix4fv(location, count, transpose, value);
    2556               0 :         AFTER_GL_CALL;
    2557               0 :     }
    2558                 : 
    2559               0 :     void fUseProgram(GLuint program) {
    2560               0 :         BEFORE_GL_CALL;
    2561               0 :         mSymbols.fUseProgram(program);
    2562               0 :         AFTER_GL_CALL;
    2563               0 :     }
    2564                 : 
    2565               0 :     void fValidateProgram(GLuint program) {
    2566               0 :         BEFORE_GL_CALL;
    2567               0 :         mSymbols.fValidateProgram(program);
    2568               0 :         AFTER_GL_CALL;
    2569               0 :     }
    2570                 : 
    2571               0 :     void fVertexAttribPointer(GLuint index, GLint size, GLenum type, realGLboolean normalized, GLsizei stride, const GLvoid* pointer) {
    2572               0 :         BEFORE_GL_CALL;
    2573               0 :         mSymbols.fVertexAttribPointer(index, size, type, normalized, stride, pointer);
    2574               0 :         AFTER_GL_CALL;
    2575               0 :     }
    2576                 : 
    2577               0 :     void fVertexAttrib1f(GLuint index, GLfloat x) {
    2578               0 :         BEFORE_GL_CALL;
    2579               0 :         mSymbols.fVertexAttrib1f(index, x);
    2580               0 :         AFTER_GL_CALL;
    2581               0 :     }
    2582                 : 
    2583               0 :     void fVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {
    2584               0 :         BEFORE_GL_CALL;
    2585               0 :         mSymbols.fVertexAttrib2f(index, x, y);
    2586               0 :         AFTER_GL_CALL;
    2587               0 :     }
    2588                 : 
    2589               0 :     void fVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {
    2590               0 :         BEFORE_GL_CALL;
    2591               0 :         mSymbols.fVertexAttrib3f(index, x, y, z);
    2592               0 :         AFTER_GL_CALL;
    2593               0 :     }
    2594                 : 
    2595               0 :     void fVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
    2596               0 :         BEFORE_GL_CALL;
    2597               0 :         mSymbols.fVertexAttrib4f(index, x, y, z, w);
    2598               0 :         AFTER_GL_CALL;
    2599               0 :     }
    2600                 : 
    2601               0 :     void fVertexAttrib1fv(GLuint index, const GLfloat* v) {
    2602               0 :         BEFORE_GL_CALL;
    2603               0 :         mSymbols.fVertexAttrib1fv(index, v);
    2604               0 :         AFTER_GL_CALL;
    2605               0 :     }
    2606                 : 
    2607               0 :     void fVertexAttrib2fv(GLuint index, const GLfloat* v) {
    2608               0 :         BEFORE_GL_CALL;
    2609               0 :         mSymbols.fVertexAttrib2fv(index, v);
    2610               0 :         AFTER_GL_CALL;
    2611               0 :     }
    2612                 : 
    2613               0 :     void fVertexAttrib3fv(GLuint index, const GLfloat* v) {
    2614               0 :         BEFORE_GL_CALL;
    2615               0 :         mSymbols.fVertexAttrib3fv(index, v);
    2616               0 :         AFTER_GL_CALL;
    2617               0 :     }
    2618                 : 
    2619               0 :     void fVertexAttrib4fv(GLuint index, const GLfloat* v) {
    2620               0 :         BEFORE_GL_CALL;
    2621               0 :         mSymbols.fVertexAttrib4fv(index, v);
    2622               0 :         AFTER_GL_CALL;
    2623               0 :     }
    2624                 : 
    2625               0 :     void fCompileShader(GLuint shader) {
    2626               0 :         BEFORE_GL_CALL;
    2627               0 :         mSymbols.fCompileShader(shader);
    2628               0 :         AFTER_GL_CALL;
    2629               0 :     }
    2630                 : 
    2631               0 :     void raw_fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
    2632               0 :         BEFORE_GL_CALL;
    2633               0 :         if (IsTextureSizeSafeToPassToDriver(target, width, height)) {
    2634                 :           mSymbols.fCopyTexImage2D(target, level, internalformat, 
    2635                 :                                    x, FixYValue(y, height),
    2636               0 :                                    width, height, border);
    2637                 : 
    2638                 :         } else {
    2639                 :           // pass wrong values to cause the GL to generate GL_INVALID_VALUE.
    2640                 :           // See bug 737182 and the comment in IsTextureSizeSafeToPassToDriver.
    2641                 :           mSymbols.fCopyTexImage2D(target, -1, internalformat, 
    2642                 :                                    x, FixYValue(y, height),
    2643               0 :                                    -1, -1, -1);
    2644                 : 
    2645                 :         }
    2646               0 :         AFTER_GL_CALL;
    2647               0 :     }
    2648                 : 
    2649               0 :     void raw_fCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
    2650               0 :         BEFORE_GL_CALL;
    2651                 :         mSymbols.fCopyTexSubImage2D(target, level, xoffset, yoffset, 
    2652                 :                                     x, FixYValue(y, height),
    2653               0 :                                     width, height);
    2654               0 :         AFTER_GL_CALL;
    2655               0 :     }
    2656                 : 
    2657               0 :     void fGetShaderiv(GLuint shader, GLenum pname, GLint* param) {
    2658               0 :         BEFORE_GL_CALL;
    2659               0 :         mSymbols.fGetShaderiv(shader, pname, param);
    2660               0 :         AFTER_GL_CALL;
    2661               0 :     }
    2662                 : 
    2663               0 :     void fGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
    2664               0 :         BEFORE_GL_CALL;
    2665               0 :         mSymbols.fGetShaderInfoLog(shader, bufSize, length, infoLog);
    2666               0 :         AFTER_GL_CALL;
    2667               0 :     }
    2668                 : 
    2669               0 :     void fGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
    2670               0 :         BEFORE_GL_CALL;
    2671               0 :         if (mIsGLES2) {
    2672               0 :             mSymbols.fGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
    2673                 :         } else {
    2674                 :             // Fall back to automatic values because almost all desktop hardware supports the OpenGL standard precisions.
    2675               0 :             GetShaderPrecisionFormatNonES2(shadertype, precisiontype, range, precision);
    2676                 :         }
    2677               0 :         AFTER_GL_CALL;
    2678               0 :     }
    2679                 : 
    2680                 :     void fGetShaderSource(GLint obj, GLsizei maxLength, GLsizei* length, GLchar* source) {
    2681                 :         BEFORE_GL_CALL;
    2682                 :         mSymbols.fGetShaderSource(obj, maxLength, length, source);
    2683                 :         AFTER_GL_CALL;
    2684                 :     }
    2685                 : 
    2686               0 :     void fShaderSource(GLuint shader, GLsizei count, const GLchar** strings, const GLint* lengths) {
    2687               0 :         BEFORE_GL_CALL;
    2688               0 :         mSymbols.fShaderSource(shader, count, strings, lengths);
    2689               0 :         AFTER_GL_CALL;
    2690               0 :     }
    2691                 : 
    2692                 : private:
    2693               0 :     void raw_fBindFramebuffer(GLenum target, GLuint framebuffer) {
    2694               0 :         BEFORE_GL_CALL;
    2695               0 :         mSymbols.fBindFramebuffer(target, framebuffer);
    2696               0 :         AFTER_GL_CALL;
    2697               0 :     }
    2698                 : 
    2699                 : public:
    2700               0 :     void fBindRenderbuffer(GLenum target, GLuint renderbuffer) {
    2701               0 :         BEFORE_GL_CALL;
    2702               0 :         mSymbols.fBindRenderbuffer(target, renderbuffer);
    2703               0 :         AFTER_GL_CALL;
    2704               0 :     }
    2705                 : 
    2706               0 :     GLenum fCheckFramebufferStatus (GLenum target) {
    2707               0 :         BEFORE_GL_CALL;
    2708               0 :         GLenum retval = mSymbols.fCheckFramebufferStatus(target);
    2709               0 :         AFTER_GL_CALL;
    2710               0 :         return retval;
    2711                 :     }
    2712                 : 
    2713               0 :     void fFramebufferRenderbuffer(GLenum target, GLenum attachmentPoint, GLenum renderbufferTarget, GLuint renderbuffer) {
    2714               0 :         BEFORE_GL_CALL;
    2715               0 :         mSymbols.fFramebufferRenderbuffer(target, attachmentPoint, renderbufferTarget, renderbuffer);
    2716               0 :         AFTER_GL_CALL;
    2717               0 :     }
    2718                 : 
    2719               0 :     void fFramebufferTexture2D(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint texture, GLint level) {
    2720               0 :         BEFORE_GL_CALL;
    2721               0 :         mSymbols.fFramebufferTexture2D(target, attachmentPoint, textureTarget, texture, level);
    2722               0 :         AFTER_GL_CALL;
    2723               0 :     }
    2724                 : 
    2725                 :     void fGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* value) {
    2726                 :         BEFORE_GL_CALL;
    2727                 :         mSymbols.fGetFramebufferAttachmentParameteriv(target, attachment, pname, value);
    2728                 :         AFTER_GL_CALL;
    2729                 :     }
    2730                 : 
    2731               0 :     void fGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* value) {
    2732               0 :         BEFORE_GL_CALL;
    2733               0 :         mSymbols.fGetRenderbufferParameteriv(target, pname, value);
    2734               0 :         AFTER_GL_CALL;
    2735               0 :     }
    2736                 : 
    2737                 :     realGLboolean fIsFramebuffer (GLuint framebuffer) {
    2738                 :         BEFORE_GL_CALL;
    2739                 :         realGLboolean retval = mSymbols.fIsFramebuffer(framebuffer);
    2740                 :         AFTER_GL_CALL;
    2741                 :         return retval;
    2742                 :     }
    2743                 : 
    2744               0 :     void raw_fBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
    2745               0 :         BEFORE_GL_CALL;
    2746               0 :         mSymbols.fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
    2747               0 :         AFTER_GL_CALL;
    2748               0 :     }
    2749                 : 
    2750                 :     realGLboolean fIsRenderbuffer (GLuint renderbuffer) {
    2751                 :         BEFORE_GL_CALL;
    2752                 :         realGLboolean retval = mSymbols.fIsRenderbuffer(renderbuffer);
    2753                 :         AFTER_GL_CALL;
    2754                 :         return retval;
    2755                 :     }
    2756                 : 
    2757               0 :     void fRenderbufferStorage(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height) {
    2758               0 :         BEFORE_GL_CALL;
    2759               0 :         mSymbols.fRenderbufferStorage(target, internalFormat, width, height);
    2760               0 :         AFTER_GL_CALL;
    2761               0 :     }
    2762                 : 
    2763                 :     void fRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height) {
    2764                 :         BEFORE_GL_CALL;
    2765                 :         mSymbols.fRenderbufferStorageMultisample(target, samples, internalFormat, width, height);
    2766                 :         AFTER_GL_CALL;
    2767                 :     }
    2768                 : 
    2769               0 :     void fDepthRange(GLclampf a, GLclampf b) {
    2770               0 :         BEFORE_GL_CALL;
    2771               0 :         if (mIsGLES2) {
    2772               0 :             mSymbols.fDepthRangef(a, b);
    2773                 :         } else {
    2774               0 :             mSymbols.fDepthRange(a, b);
    2775                 :         }
    2776               0 :         AFTER_GL_CALL;
    2777               0 :     }
    2778                 : 
    2779               0 :     void fClearDepth(GLclampf v) {
    2780               0 :         BEFORE_GL_CALL;
    2781               0 :         if (mIsGLES2) {
    2782               0 :             mSymbols.fClearDepthf(v);
    2783                 :         } else {
    2784               0 :             mSymbols.fClearDepth(v);
    2785                 :         }
    2786               0 :         AFTER_GL_CALL;
    2787               0 :     }
    2788                 : 
    2789                 :     void* fMapBuffer(GLenum target, GLenum access) {
    2790                 :         BEFORE_GL_CALL;
    2791                 :         void *ret = mSymbols.fMapBuffer(target, access);
    2792                 :         AFTER_GL_CALL;
    2793                 :         return ret;
    2794                 :     }
    2795                 : 
    2796                 :     realGLboolean fUnmapBuffer(GLenum target) {
    2797                 :         BEFORE_GL_CALL;
    2798                 :         realGLboolean ret = mSymbols.fUnmapBuffer(target);
    2799                 :         AFTER_GL_CALL;
    2800                 :         return ret;
    2801                 :     }
    2802                 : 
    2803                 : 
    2804                 : #ifdef DEBUG
    2805               0 :      GLContext *TrackingContext() {
    2806               0 :          GLContext *tip = this;
    2807               0 :          while (tip->mSharedContext)
    2808               0 :              tip = tip->mSharedContext;
    2809               0 :          return tip;
    2810                 :      }
    2811                 : 
    2812                 : #define TRACKING_CONTEXT(a) do { TrackingContext()->a; } while (0)
    2813                 : #else
    2814                 : #define TRACKING_CONTEXT(a) do {} while (0)
    2815                 : #endif
    2816                 : 
    2817               0 :      GLuint GLAPIENTRY fCreateProgram() {
    2818               0 :          BEFORE_GL_CALL;
    2819               0 :          GLuint ret = mSymbols.fCreateProgram();
    2820               0 :          AFTER_GL_CALL;
    2821               0 :          TRACKING_CONTEXT(CreatedProgram(this, ret));
    2822               0 :          return ret;
    2823                 :      }
    2824                 : 
    2825               0 :      GLuint GLAPIENTRY fCreateShader(GLenum t) {
    2826               0 :          BEFORE_GL_CALL;
    2827               0 :          GLuint ret = mSymbols.fCreateShader(t);
    2828               0 :          AFTER_GL_CALL;
    2829               0 :          TRACKING_CONTEXT(CreatedShader(this, ret));
    2830               0 :          return ret;
    2831                 :      }
    2832                 : 
    2833               0 :      void GLAPIENTRY fGenBuffers(GLsizei n, GLuint* names) {
    2834               0 :          BEFORE_GL_CALL;
    2835               0 :          mSymbols.fGenBuffers(n, names);
    2836               0 :          AFTER_GL_CALL;
    2837               0 :          TRACKING_CONTEXT(CreatedBuffers(this, n, names));
    2838               0 :      }
    2839                 : 
    2840               0 :      void GLAPIENTRY fGenTextures(GLsizei n, GLuint* names) {
    2841               0 :          BEFORE_GL_CALL;
    2842               0 :          mSymbols.fGenTextures(n, names);
    2843               0 :          AFTER_GL_CALL;
    2844               0 :          TRACKING_CONTEXT(CreatedTextures(this, n, names));
    2845               0 :      }
    2846                 : 
    2847               0 :      void GLAPIENTRY fGenFramebuffers(GLsizei n, GLuint* names) {
    2848               0 :          BEFORE_GL_CALL;
    2849               0 :          mSymbols.fGenFramebuffers(n, names);
    2850               0 :          AFTER_GL_CALL;
    2851               0 :          TRACKING_CONTEXT(CreatedFramebuffers(this, n, names));
    2852               0 :      }
    2853                 : 
    2854               0 :      void GLAPIENTRY fGenRenderbuffers(GLsizei n, GLuint* names) {
    2855               0 :          BEFORE_GL_CALL;
    2856               0 :          mSymbols.fGenRenderbuffers(n, names);
    2857               0 :          AFTER_GL_CALL;
    2858               0 :          TRACKING_CONTEXT(CreatedRenderbuffers(this, n, names));
    2859               0 :      }
    2860                 : 
    2861               0 :      void GLAPIENTRY fDeleteProgram(GLuint program) {
    2862               0 :          BEFORE_GL_CALL;
    2863               0 :          mSymbols.fDeleteProgram(program);
    2864               0 :          AFTER_GL_CALL;
    2865               0 :          TRACKING_CONTEXT(DeletedProgram(this, program));
    2866               0 :      }
    2867                 : 
    2868               0 :      void GLAPIENTRY fDeleteShader(GLuint shader) {
    2869               0 :          BEFORE_GL_CALL;
    2870               0 :          mSymbols.fDeleteShader(shader);
    2871               0 :          AFTER_GL_CALL;
    2872               0 :          TRACKING_CONTEXT(DeletedShader(this, shader));
    2873               0 :      }
    2874                 : 
    2875               0 :      void GLAPIENTRY fDeleteBuffers(GLsizei n, GLuint *names) {
    2876               0 :          BEFORE_GL_CALL;
    2877               0 :          mSymbols.fDeleteBuffers(n, names);
    2878               0 :          AFTER_GL_CALL;
    2879               0 :          TRACKING_CONTEXT(DeletedBuffers(this, n, names));
    2880               0 :      }
    2881                 : 
    2882               0 :      void GLAPIENTRY fDeleteTextures(GLsizei n, GLuint *names) {
    2883               0 :          BEFORE_GL_CALL;
    2884               0 :          mSymbols.fDeleteTextures(n, names);
    2885               0 :          AFTER_GL_CALL;
    2886               0 :          TRACKING_CONTEXT(DeletedTextures(this, n, names));
    2887               0 :      }
    2888                 : 
    2889               0 :      void GLAPIENTRY fDeleteFramebuffers(GLsizei n, GLuint *names) {
    2890               0 :          BEFORE_GL_CALL;
    2891               0 :          if (n == 1 && *names == 0) {
    2892                 :             /* Deleting framebuffer 0 causes hangs on the DROID. See bug 623228 */
    2893                 :          } else {
    2894               0 :             mSymbols.fDeleteFramebuffers(n, names);
    2895                 :          }
    2896               0 :          AFTER_GL_CALL;
    2897               0 :          TRACKING_CONTEXT(DeletedFramebuffers(this, n, names));
    2898               0 :      }
    2899                 : 
    2900               0 :      void GLAPIENTRY fDeleteRenderbuffers(GLsizei n, GLuint *names) {
    2901               0 :          BEFORE_GL_CALL;
    2902               0 :          mSymbols.fDeleteRenderbuffers(n, names);
    2903               0 :          AFTER_GL_CALL;
    2904               0 :          TRACKING_CONTEXT(DeletedRenderbuffers(this, n, names));
    2905               0 :      }
    2906                 : 
    2907               0 :      GLenum GLAPIENTRY fGetGraphicsResetStatus() {
    2908               0 :          BEFORE_GL_CALL;
    2909               0 :          GLenum ret = mHasRobustness ? mSymbols.fGetGraphicsResetStatus() : 0;
    2910               0 :          AFTER_GL_CALL;
    2911               0 :          return ret;
    2912                 :      }
    2913                 : 
    2914                 : #ifdef DEBUG
    2915                 :     void THEBES_API CreatedProgram(GLContext *aOrigin, GLuint aName);
    2916                 :     void THEBES_API CreatedShader(GLContext *aOrigin, GLuint aName);
    2917                 :     void THEBES_API CreatedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
    2918                 :     void THEBES_API CreatedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
    2919                 :     void THEBES_API CreatedFramebuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
    2920                 :     void THEBES_API CreatedRenderbuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
    2921                 :     void THEBES_API DeletedProgram(GLContext *aOrigin, GLuint aName);
    2922                 :     void THEBES_API DeletedShader(GLContext *aOrigin, GLuint aName);
    2923                 :     void THEBES_API DeletedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
    2924                 :     void THEBES_API DeletedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
    2925                 :     void THEBES_API DeletedFramebuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
    2926                 :     void THEBES_API DeletedRenderbuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
    2927                 : 
    2928                 :     void SharedContextDestroyed(GLContext *aChild);
    2929                 :     void ReportOutstandingNames();
    2930                 : 
    2931                 :     struct NamedResource {
    2932                 :         NamedResource()
    2933                 :             : origin(nsnull), name(0), originDeleted(false)
    2934                 :         { }
    2935                 : 
    2936                 :         NamedResource(GLContext *aOrigin, GLuint aName)
    2937                 :             : origin(aOrigin), name(aName), originDeleted(false)
    2938                 :         { }
    2939                 : 
    2940                 :         GLContext *origin;
    2941                 :         GLuint name;
    2942                 :         bool originDeleted;
    2943                 : 
    2944                 :         // for sorting
    2945                 :         bool operator<(const NamedResource& aOther) const {
    2946                 :             if (intptr_t(origin) < intptr_t(aOther.origin))
    2947                 :                 return true;
    2948                 :             if (name < aOther.name)
    2949                 :                 return true;
    2950                 :             return false;
    2951                 :         }
    2952                 :         bool operator==(const NamedResource& aOther) const {
    2953                 :             return origin == aOther.origin &&
    2954                 :                 name == aOther.name &&
    2955                 :                 originDeleted == aOther.originDeleted;
    2956                 :         }
    2957                 :     };
    2958                 : 
    2959                 :     nsTArray<NamedResource> mTrackedPrograms;
    2960                 :     nsTArray<NamedResource> mTrackedShaders;
    2961                 :     nsTArray<NamedResource> mTrackedTextures;
    2962                 :     nsTArray<NamedResource> mTrackedFramebuffers;
    2963                 :     nsTArray<NamedResource> mTrackedRenderbuffers;
    2964                 :     nsTArray<NamedResource> mTrackedBuffers;
    2965                 : #endif
    2966                 : 
    2967                 : };
    2968                 : 
    2969                 : inline bool
    2970                 : DoesStringMatch(const char* aString, const char *aWantedString)
    2971                 : {
    2972                 :     if (!aString || !aWantedString)
    2973                 :         return false;
    2974                 : 
    2975                 :     const char *occurrence = strstr(aString, aWantedString);
    2976                 : 
    2977                 :     // aWanted not found
    2978                 :     if (!occurrence)
    2979                 :         return false;
    2980                 : 
    2981                 :     // aWantedString preceded by alpha character
    2982                 :     if (occurrence != aString && isalpha(*(occurrence-1)))
    2983                 :         return false;
    2984                 : 
    2985                 :     // aWantedVendor followed by alpha character
    2986                 :     const char *afterOccurrence = occurrence + strlen(aWantedString);
    2987                 :     if (isalpha(*afterOccurrence))
    2988                 :         return false;
    2989                 : 
    2990                 :     return true;
    2991                 : }
    2992                 : 
    2993                 : } /* namespace gl */
    2994                 : } /* namespace mozilla */
    2995                 : 
    2996                 : #endif /* GLCONTEXT_H_ */

Generated by: LCOV version 1.7