gfx/layers/opengl/OGLShaderProgram.h

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

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

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

     1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef GFX_OGLSHADERPROGRAM_H
     7 #define GFX_OGLSHADERPROGRAM_H
     9 #include "GLContext.h"                  // for fast inlines of glUniform*
    10 #include "gfx3DMatrix.h"                // for gfx3DMatrix
    11 #include "gfxTypes.h"
    12 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
    13 #include "mozilla/RefPtr.h"             // for RefPtr
    14 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
    15 #include "mozilla/gfx/Rect.h"           // for Rect
    16 #include "mozilla/gfx/Types.h"
    17 #include "nsDebug.h"                    // for NS_ASSERTION
    18 #include "nsPoint.h"                    // for nsIntPoint
    19 #include "nsTArray.h"                   // for nsTArray
    20 #include "mozilla/layers/CompositorTypes.h"
    22 #include <string>
    24 struct gfxRGBA;
    25 struct nsIntRect;
    27 namespace mozilla {
    28 namespace layers {
    30 class Layer;
    32 enum ShaderFeatures {
    33   ENABLE_RENDER_COLOR=0x01,
    34   ENABLE_TEXTURE_RECT=0x02,
    35   ENABLE_TEXTURE_EXTERNAL=0x04,
    36   ENABLE_TEXTURE_YCBCR=0x08,
    37   ENABLE_TEXTURE_COMPONENT_ALPHA=0x10,
    38   ENABLE_TEXTURE_NO_ALPHA=0x20,
    39   ENABLE_TEXTURE_RB_SWAP=0x40,
    40   ENABLE_OPACITY=0x80,
    41   ENABLE_BLUR=0x100,
    42   ENABLE_COLOR_MATRIX=0x200,
    43   ENABLE_MASK_2D=0x400,
    44   ENABLE_MASK_3D=0x800
    45 };
    47 class KnownUniform {
    48 public:
    49   enum KnownUniformName {
    50     NotAKnownUniform = -1,
    52     LayerTransform = 0,
    53     MaskQuadTransform,
    54     LayerQuadTransform,
    55     MatrixProj,
    56     TextureTransform,
    57     RenderTargetOffset,
    58     LayerOpacity,
    59     Texture,
    60     YTexture,
    61     CbTexture,
    62     CrTexture,
    63     BlackTexture,
    64     WhiteTexture,
    65     MaskTexture,
    66     RenderColor,
    67     TexCoordMultiplier,
    68     TexturePass2,
    70     KnownUniformCount
    71   };
    73   KnownUniform()
    74   {
    75     mName = NotAKnownUniform;
    76     mNameString = nullptr;
    77     mLocation = -1;
    78     memset(&mValue, 0, sizeof(mValue));
    79   }
    81   bool UpdateUniform(int32_t i1) {
    82     if (mLocation == -1) return false;
    83     if (mValue.i1 != i1) {
    84       mValue.i1 = i1;
    85       return true;
    86     }
    87     return false;
    88   }
    90   bool UpdateUniform(float f1) {
    91     if (mLocation == -1) return false;
    92     if (mValue.f1 != f1) {
    93       mValue.f1 = f1;
    94       return true;
    95     }
    96     return false;
    97   }
    99   bool UpdateUniform(float f1, float f2) {
   100     if (mLocation == -1) return false;
   101     if (mValue.f16v[0] != f1 ||
   102         mValue.f16v[1] != f2)
   103     {
   104       mValue.f16v[0] = f1;
   105       mValue.f16v[1] = f2;
   106       return true;
   107     }
   108     return false;
   109   }
   111   bool UpdateUniform(float f1, float f2, float f3, float f4) {
   112     if (mLocation == -1) return false;
   113     if (mValue.f16v[0] != f1 ||
   114         mValue.f16v[1] != f2 ||
   115         mValue.f16v[2] != f3 ||
   116         mValue.f16v[3] != f4)
   117     {
   118       mValue.f16v[0] = f1;
   119       mValue.f16v[1] = f2;
   120       mValue.f16v[2] = f3;
   121       mValue.f16v[3] = f4;
   122       return true;
   123     }
   124     return false;
   125   }
   127   bool UpdateUniform(int cnt, const float *fp) {
   128     if (mLocation == -1) return false;
   129     switch (cnt) {
   130     case 1:
   131     case 2:
   132     case 3:
   133     case 4:
   134     case 16:
   135       if (memcmp(mValue.f16v, fp, sizeof(float) * cnt) != 0) {
   136         memcpy(mValue.f16v, fp, sizeof(float) * cnt);
   137         return true;
   138       }
   139       return false;
   140     }
   142     NS_NOTREACHED("cnt must be 1 2 3 4 or 16");
   143     return false;
   144   }
   146   KnownUniformName mName;
   147   const char *mNameString;
   148   int32_t mLocation;
   150   union {
   151     int i1;
   152     float f1;
   153     float f16v[16];
   154   } mValue;
   155 };
   157 class ShaderConfigOGL
   158 {
   159 public:
   160   ShaderConfigOGL() :
   161     mFeatures(0) {}
   163   void SetRenderColor(bool aEnabled);
   164   void SetTextureTarget(GLenum aTarget);
   165   void SetRBSwap(bool aEnabled);
   166   void SetNoAlpha(bool aEnabled);
   167   void SetOpacity(bool aEnabled);
   168   void SetYCbCr(bool aEnabled);
   169   void SetComponentAlpha(bool aEnabled);
   170   void SetColorMatrix(bool aEnabled);
   171   void SetBlur(bool aEnabled);
   172   void SetMask2D(bool aEnabled);
   173   void SetMask3D(bool aEnabled);
   175   bool operator< (const ShaderConfigOGL& other) const {
   176     return mFeatures < other.mFeatures;
   177   }
   179 public:
   180   void SetFeature(int aBitmask, bool aState) {
   181     if (aState)
   182       mFeatures |= aBitmask;
   183     else
   184       mFeatures &= (~aBitmask);
   185   }
   187   int mFeatures;
   188 };
   190 static inline ShaderConfigOGL
   191 ShaderConfigFromTargetAndFormat(GLenum aTarget,
   192                                 gfx::SurfaceFormat aFormat)
   193 {
   194   ShaderConfigOGL config;
   195   config.SetTextureTarget(aTarget);
   196   config.SetRBSwap(aFormat == gfx::SurfaceFormat::B8G8R8A8 ||
   197                    aFormat == gfx::SurfaceFormat::B8G8R8X8);
   198   config.SetNoAlpha(aFormat == gfx::SurfaceFormat::B8G8R8X8 ||
   199                     aFormat == gfx::SurfaceFormat::R8G8B8X8 ||
   200                     aFormat == gfx::SurfaceFormat::R5G6B5);
   201   return config;
   202 }
   204 /**
   205  * This struct represents the shaders that make up a program and the uniform
   206  * and attribute parmeters that those shaders take.
   207  * It is used by ShaderProgramOGL.
   208  * Use the factory method GetProfileFor to create instances.
   209  */
   210 struct ProgramProfileOGL
   211 {
   212   /**
   213    * Factory method; creates an instance of this class for the given
   214    * ShaderConfigOGL
   215    */
   216   static ProgramProfileOGL GetProfileFor(ShaderConfigOGL aConfig);
   218   /**
   219    * These two methods lookup the location of a uniform and attribute,
   220    * respectively. Returns -1 if the named uniform/attribute does not
   221    * have a location for the shaders represented by this profile.
   222    */
   223   GLint LookupAttributeLocation(const char* aName)
   224   {
   225     for (uint32_t i = 0; i < mAttributes.Length(); ++i) {
   226       if (strcmp(mAttributes[i].mName, aName) == 0) {
   227         return mAttributes[i].mLocation;
   228       }
   229     }
   231     return -1;
   232   }
   234   // represents the name and location of a uniform or attribute
   235   struct Argument
   236   {
   237     Argument(const char* aName) :
   238       mName(aName) {}
   239     const char* mName;
   240     GLint mLocation;
   241   };
   243   // the source code for the program's shaders
   244   std::string mVertexShaderString;
   245   std::string mFragmentShaderString;
   247   KnownUniform mUniforms[KnownUniform::KnownUniformCount];
   248   nsTArray<Argument> mAttributes;
   249   nsTArray<const char *> mDefines;
   250   uint32_t mTextureCount;
   252   ProgramProfileOGL() :
   253     mTextureCount(0)
   254   {}
   255 };
   258 #if defined(DEBUG)
   259 #define CHECK_CURRENT_PROGRAM 1
   260 #define ASSERT_THIS_PROGRAM                                             \
   261   do {                                                                  \
   262     GLuint currentProgram;                                              \
   263     mGL->GetUIntegerv(LOCAL_GL_CURRENT_PROGRAM, &currentProgram);       \
   264     NS_ASSERTION(currentProgram == mProgram,                            \
   265                  "SetUniform with wrong program active!");              \
   266   } while (0)
   267 #else
   268 #define ASSERT_THIS_PROGRAM                                             \
   269   do { } while (0)
   270 #endif
   272 /**
   273  * Represents an OGL shader program. The details of a program are represented
   274  * by a ProgramProfileOGL
   275  */
   276 class ShaderProgramOGL
   277 {
   278 public:
   279   typedef mozilla::gl::GLContext GLContext;
   281   ShaderProgramOGL(GLContext* aGL, const ProgramProfileOGL& aProfile);
   283   ~ShaderProgramOGL();
   285   bool HasInitialized() {
   286     NS_ASSERTION(mProgramState != STATE_OK || mProgram > 0, "Inconsistent program state");
   287     return mProgramState == STATE_OK;
   288   }
   290   void Activate();
   292   bool Initialize();
   294   GLint CreateShader(GLenum aShaderType, const char *aShaderSource);
   296   /**
   297    * Creates a program and stores its id.
   298    */
   299   bool CreateProgram(const char *aVertexShaderString,
   300                      const char *aFragmentShaderString);
   302   /**
   303    * Lookup the location of an attribute
   304    */
   305   GLint AttribLocation(const char* aName) {
   306     return mProfile.LookupAttributeLocation(aName);
   307   }
   309   /**
   310    * The following set of methods set a uniform argument to the shader program.
   311    * Not all uniforms may be set for all programs, and such uses will throw
   312    * an assertion.
   313    */
   314   void SetLayerTransform(const gfx::Matrix4x4& aMatrix) {
   315     SetMatrixUniform(KnownUniform::LayerTransform, aMatrix);
   316   }
   318   void SetMaskLayerTransform(const gfx::Matrix4x4& aMatrix) {
   319     SetMatrixUniform(KnownUniform::MaskQuadTransform, aMatrix);
   320   }
   322   void SetLayerQuadRect(const nsIntRect& aRect) {
   323     gfx3DMatrix m;
   324     m._11 = float(aRect.width);
   325     m._22 = float(aRect.height);
   326     m._41 = float(aRect.x);
   327     m._42 = float(aRect.y);
   328     SetMatrixUniform(KnownUniform::LayerQuadTransform, m);
   329   }
   331   void SetLayerQuadRect(const gfx::Rect& aRect) {
   332     gfx3DMatrix m;
   333     m._11 = aRect.width;
   334     m._22 = aRect.height;
   335     m._41 = aRect.x;
   336     m._42 = aRect.y;
   337     SetMatrixUniform(KnownUniform::LayerQuadTransform, m);
   338   }
   340   void SetProjectionMatrix(const gfx::Matrix4x4& aMatrix) {
   341     SetMatrixUniform(KnownUniform::MatrixProj, aMatrix);
   342   }
   344   // sets this program's texture transform, if it uses one
   345   void SetTextureTransform(const gfx::Matrix4x4& aMatrix) {
   346     SetMatrixUniform(KnownUniform::TextureTransform, aMatrix);
   347   }
   349   void SetRenderOffset(const nsIntPoint& aOffset) {
   350     float vals[4] = { float(aOffset.x), float(aOffset.y), 0.0f, 0.0f };
   351     SetUniform(KnownUniform::RenderTargetOffset, 4, vals);
   352   }
   354   void SetRenderOffset(float aX, float aY) {
   355     float vals[4] = { aX, aY, 0.0f, 0.0f };
   356     SetUniform(KnownUniform::RenderTargetOffset, 4, vals);
   357   }
   359   void SetLayerOpacity(float aOpacity) {
   360     SetUniform(KnownUniform::LayerOpacity, aOpacity);
   361   }
   363   void SetTextureUnit(GLint aUnit) {
   364     SetUniform(KnownUniform::Texture, aUnit);
   365   }
   366   void SetYTextureUnit(GLint aUnit) {
   367     SetUniform(KnownUniform::YTexture, aUnit);
   368   }
   370   void SetCbTextureUnit(GLint aUnit) {
   371     SetUniform(KnownUniform::CbTexture, aUnit);
   372   }
   374   void SetCrTextureUnit(GLint aUnit) {
   375     SetUniform(KnownUniform::CrTexture, aUnit);
   376   }
   378   void SetYCbCrTextureUnits(GLint aYUnit, GLint aCbUnit, GLint aCrUnit) {
   379     SetUniform(KnownUniform::YTexture, aYUnit);
   380     SetUniform(KnownUniform::CbTexture, aCbUnit);
   381     SetUniform(KnownUniform::CrTexture, aCrUnit);
   382   }
   384   void SetBlackTextureUnit(GLint aUnit) {
   385     SetUniform(KnownUniform::BlackTexture, aUnit);
   386   }
   388   void SetWhiteTextureUnit(GLint aUnit) {
   389     SetUniform(KnownUniform::WhiteTexture, aUnit);
   390   }
   392   void SetMaskTextureUnit(GLint aUnit) {
   393     SetUniform(KnownUniform::MaskTexture, aUnit);
   394   }
   396   void SetRenderColor(const gfxRGBA& aColor) {
   397     SetUniform(KnownUniform::RenderColor, aColor);
   398   }
   400   void SetRenderColor(const gfx::Color& aColor) {
   401     SetUniform(KnownUniform::RenderColor, aColor);
   402   }
   404   void SetTexCoordMultiplier(float aWidth, float aHeight) {
   405     float f[] = {aWidth, aHeight};
   406     SetUniform(KnownUniform::TexCoordMultiplier, 2, f);
   407   }
   409   // Set whether we want the component alpha shader to return the color
   410   // vector (pass 1, false) or the alpha vector (pass2, true). With support
   411   // for multiple render targets we wouldn't need two passes here.
   412   void SetTexturePass2(bool aFlag) {
   413     SetUniform(KnownUniform::TexturePass2, aFlag ? 1 : 0);
   414   }
   416   // the names of attributes
   417   static const char* const VertexCoordAttrib;
   418   static const char* const TexCoordAttrib;
   420 protected:
   421   RefPtr<GLContext> mGL;
   422   // the OpenGL id of the program
   423   GLuint mProgram;
   424   ProgramProfileOGL mProfile;
   425   enum {
   426     STATE_NEW,
   427     STATE_OK,
   428     STATE_ERROR
   429   } mProgramState;
   431 #ifdef CHECK_CURRENT_PROGRAM
   432   static int sCurrentProgramKey;
   433 #endif
   435   void SetUniform(KnownUniform::KnownUniformName aKnownUniform, float aFloatValue)
   436   {
   437     ASSERT_THIS_PROGRAM;
   438     NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
   440     KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
   441     if (ku.UpdateUniform(aFloatValue)) {
   442       mGL->fUniform1f(ku.mLocation, aFloatValue);
   443     }
   444   }
   446   void SetUniform(KnownUniform::KnownUniformName aKnownUniform, const gfxRGBA& aColor)
   447   {
   448     ASSERT_THIS_PROGRAM;
   449     NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
   451     KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
   452     if (ku.UpdateUniform(aColor.r, aColor.g, aColor.b, aColor.a)) {
   453       mGL->fUniform4fv(ku.mLocation, 1, ku.mValue.f16v);
   454     }
   455   }
   457   void SetUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx::Color& aColor) {
   458     ASSERT_THIS_PROGRAM;
   459     NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
   461     KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
   462     if (ku.UpdateUniform(aColor.r, aColor.g, aColor.b, aColor.a)) {
   463       mGL->fUniform4fv(ku.mLocation, 1, ku.mValue.f16v);
   464     }
   465   }
   467   void SetUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, float *aFloatValues)
   468   {
   469     ASSERT_THIS_PROGRAM;
   470     NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
   472     KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
   473     if (ku.UpdateUniform(aLength, aFloatValues)) {
   474       switch (aLength) {
   475       case 1: mGL->fUniform1fv(ku.mLocation, 1, ku.mValue.f16v); break;
   476       case 2: mGL->fUniform2fv(ku.mLocation, 1, ku.mValue.f16v); break;
   477       case 3: mGL->fUniform3fv(ku.mLocation, 1, ku.mValue.f16v); break;
   478       case 4: mGL->fUniform4fv(ku.mLocation, 1, ku.mValue.f16v); break;
   479       default:
   480         NS_NOTREACHED("Bogus aLength param");
   481       }
   482     }
   483   }
   485   void SetUniform(KnownUniform::KnownUniformName aKnownUniform, GLint aIntValue) {
   486     ASSERT_THIS_PROGRAM;
   487     NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
   489     KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
   490     if (ku.UpdateUniform(aIntValue)) {
   491       mGL->fUniform1i(ku.mLocation, aIntValue);
   492     }
   493   }
   495   void SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const float *aFloatValues) {
   496     ASSERT_THIS_PROGRAM;
   497     NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
   499     KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
   500     if (ku.UpdateUniform(16, aFloatValues)) {
   501       mGL->fUniformMatrix4fv(ku.mLocation, 1, false, ku.mValue.f16v);
   502     }
   503   }
   505   void SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx3DMatrix& aMatrix) {
   506     SetMatrixUniform(aKnownUniform, &aMatrix._11);
   507   }
   509   void SetMatrixUniform(KnownUniform::KnownUniformName aKnownUniform, const gfx::Matrix4x4& aMatrix) {
   510     SetMatrixUniform(aKnownUniform, &aMatrix._11);
   511   }
   512 };
   515 } /* layers */
   516 } /* mozilla */
   518 #endif /* GFX_OGLSHADERPROGRAM_H */

mercurial