LCOV - app.info - objdir/dist/include/GLContext.h

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