2010-05-25 06:35:35 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
|
|
|
*
|
|
|
|
* The Original Code is Mozilla Corporation code.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Mozilla Foundation.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2010
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
* Vladimir Vukicevic <vladimir@pobox.com>
|
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
|
|
* the provisions above, a recipient may use your version of this file under
|
|
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
|
|
*
|
|
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
|
|
|
|
#ifndef GFX_LAYERMANAGEROGLPROGRAM_H
|
|
|
|
#define GFX_LAYERMANAGEROGLPROGRAM_H
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "prenv.h"
|
|
|
|
|
|
|
|
#include "nsString.h"
|
|
|
|
#include "GLContext.h"
|
2012-03-18 20:07:25 +00:00
|
|
|
#include "Layers.h"
|
|
|
|
|
2010-05-25 06:35:35 +00:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace layers {
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
// The kinds of mask layer a shader can support
|
|
|
|
// We rely on the items in this enum being sequential
|
|
|
|
enum MaskType {
|
|
|
|
MaskNone = 0, // no mask layer
|
|
|
|
Mask2d, // mask layer for layers with 2D transforms
|
|
|
|
Mask3d, // mask layer for layers with 3D transforms
|
|
|
|
NumMaskTypes
|
|
|
|
};
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
/**
|
|
|
|
* This struct represents the shaders that make up a program and the uniform
|
|
|
|
* and attribute parmeters that those shaders take.
|
|
|
|
* It is used by ShaderProgramOGL.
|
|
|
|
* Use the factory method GetProfileFor to create instances.
|
|
|
|
*/
|
|
|
|
struct ProgramProfileOGL
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Factory method; creates an instance of this class for the given
|
|
|
|
* ShaderProgramType
|
|
|
|
*/
|
2012-03-18 20:07:25 +00:00
|
|
|
static ProgramProfileOGL GetProfileFor(gl::ShaderProgramType aType,
|
|
|
|
MaskType aMask);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* returns true if such a shader program exists
|
|
|
|
*/
|
|
|
|
static bool ProgramExists(gl::ShaderProgramType aType, MaskType aMask)
|
|
|
|
{
|
|
|
|
if (aType < 0 ||
|
|
|
|
aType >= gl::NumProgramTypes)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (aMask < MaskNone ||
|
|
|
|
aMask >= NumMaskTypes)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (aMask == Mask2d &&
|
|
|
|
(aType == gl::Copy2DProgramType ||
|
|
|
|
aType == gl::Copy2DRectProgramType))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return aMask != Mask3d ||
|
|
|
|
aType == gl::RGBARectLayerProgramType ||
|
|
|
|
aType == gl::RGBALayerProgramType;
|
|
|
|
}
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* These two methods lookup the location of a uniform and attribute,
|
|
|
|
* respectively. Returns -1 if the named uniform/attribute does not
|
|
|
|
* have a location for the shaders represented by this profile.
|
|
|
|
*/
|
|
|
|
GLint LookupUniformLocation(const char* aName)
|
|
|
|
{
|
|
|
|
for (PRUint32 i = 0; i < mUniforms.Length(); ++i) {
|
|
|
|
if (strcmp(mUniforms[i].mName, aName) == 0) {
|
|
|
|
return mUniforms[i].mLocation;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
GLint LookupAttributeLocation(const char* aName)
|
|
|
|
{
|
|
|
|
for (PRUint32 i = 0; i < mAttributes.Length(); ++i) {
|
|
|
|
if (strcmp(mAttributes[i].mName, aName) == 0) {
|
|
|
|
return mAttributes[i].mLocation;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// represents the name and location of a uniform or attribute
|
|
|
|
struct Argument
|
|
|
|
{
|
|
|
|
Argument(const char* aName) :
|
|
|
|
mName(aName) {}
|
|
|
|
const char* mName;
|
|
|
|
GLint mLocation;
|
|
|
|
};
|
|
|
|
|
|
|
|
// the source code for the program's shaders
|
|
|
|
const char *mVertexShaderString;
|
|
|
|
const char *mFragmentShaderString;
|
|
|
|
|
|
|
|
nsTArray<Argument> mUniforms;
|
|
|
|
nsTArray<Argument> mAttributes;
|
2012-03-18 20:07:25 +00:00
|
|
|
PRUint32 mTextureCount;
|
|
|
|
bool mHasMatrixProj;
|
2012-03-18 20:07:25 +00:00
|
|
|
private:
|
2012-03-18 20:07:25 +00:00
|
|
|
ProgramProfileOGL() :
|
|
|
|
mTextureCount(0),
|
|
|
|
mHasMatrixProj(false) {}
|
2012-03-18 20:07:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2011-05-23 16:54:47 +00:00
|
|
|
#if defined(DEBUG)
|
2011-01-07 20:32:42 +00:00
|
|
|
#define CHECK_CURRENT_PROGRAM 1
|
2010-05-25 06:35:35 +00:00
|
|
|
#define ASSERT_THIS_PROGRAM \
|
|
|
|
do { \
|
|
|
|
NS_ASSERTION(mGL->GetUserData(&sCurrentProgramKey) == this, \
|
|
|
|
"SetUniform with wrong program active!"); \
|
|
|
|
} while (0)
|
2011-01-07 20:32:42 +00:00
|
|
|
#else
|
|
|
|
#define ASSERT_THIS_PROGRAM
|
|
|
|
#endif
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
/**
|
|
|
|
* Represents an OGL shader program. The details of a program are represented
|
|
|
|
* by a ProgramProfileOGL
|
|
|
|
*/
|
|
|
|
class ShaderProgramOGL
|
|
|
|
{
|
2010-05-25 06:35:35 +00:00
|
|
|
public:
|
|
|
|
typedef mozilla::gl::GLContext GLContext;
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
ShaderProgramOGL(GLContext* aGL, const ProgramProfileOGL& aProfile) :
|
|
|
|
mGL(aGL), mProgram(-1), mProfile(aProfile) { }
|
2010-05-25 06:35:35 +00:00
|
|
|
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
~ShaderProgramOGL() {
|
2010-07-20 04:05:42 +00:00
|
|
|
nsRefPtr<GLContext> ctx = mGL->GetSharedContext();
|
|
|
|
if (!ctx) {
|
|
|
|
ctx = mGL;
|
|
|
|
}
|
|
|
|
ctx->MakeCurrent();
|
|
|
|
ctx->fDeleteProgram(mProgram);
|
2010-07-19 05:01:14 +00:00
|
|
|
}
|
2010-05-25 06:35:35 +00:00
|
|
|
|
|
|
|
void Activate() {
|
|
|
|
NS_ASSERTION(mProgram != 0, "Attempting to activate a program that's not in use!");
|
|
|
|
mGL->fUseProgram(mProgram);
|
2011-01-07 20:32:42 +00:00
|
|
|
#if CHECK_CURRENT_PROGRAM
|
2010-05-25 06:35:35 +00:00
|
|
|
mGL->SetUserData(&sCurrentProgramKey, this);
|
2011-01-07 20:32:42 +00:00
|
|
|
#endif
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
bool Initialize();
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
GLint CreateShader(GLenum aShaderType, const char *aShaderSource);
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
/**
|
|
|
|
* Creates a program and stores its id.
|
|
|
|
*/
|
2010-05-25 06:35:35 +00:00
|
|
|
bool CreateProgram(const char *aVertexShaderString,
|
2012-03-18 20:07:25 +00:00
|
|
|
const char *aFragmentShaderString);
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
/**
|
|
|
|
* Lookup the location of an attribute
|
|
|
|
*/
|
|
|
|
GLint AttribLocation(const char* aName) {
|
|
|
|
return mProfile.LookupAttributeLocation(aName);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
GLint GetTexCoordMultiplierUniformLocation() {
|
|
|
|
return mTexCoordMultiplierUniformLocation;
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
2012-03-18 20:08:49 +00:00
|
|
|
/**
|
|
|
|
* aLayer is the mask layer to use for rendering, or null, if there is no
|
|
|
|
* mask layer.
|
|
|
|
* If aLayer is non-null, then the result of rendering aLayer is stored as
|
|
|
|
* as a texture to be used by the shader. It is stored in the next available
|
|
|
|
* texture unit, as determined by the texture unit requirements for the
|
|
|
|
* shader.
|
|
|
|
* Any other features of the mask layer required by the shader are also
|
|
|
|
* loaded to graphics memory. In particular the transform used to move from
|
|
|
|
* the layer's coordinates to the mask's coordinates is loaded; this must be
|
|
|
|
* a 2D transform.
|
|
|
|
*/
|
|
|
|
bool LoadMask(Layer* aLayer);
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
/**
|
|
|
|
* The following set of methods set a uniform argument to the shader program.
|
|
|
|
* Not all uniforms may be set for all programs, and such uses will throw
|
|
|
|
* an assertion.
|
|
|
|
*/
|
2010-05-25 06:35:35 +00:00
|
|
|
void SetLayerTransform(const gfx3DMatrix& aMatrix) {
|
2012-03-18 20:07:25 +00:00
|
|
|
SetMatrixUniform(mProfile.LookupUniformLocation("uLayerTransform"), aMatrix);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetLayerQuadRect(const nsIntRect& aRect) {
|
|
|
|
gfx3DMatrix m;
|
|
|
|
m._11 = float(aRect.width);
|
|
|
|
m._22 = float(aRect.height);
|
|
|
|
m._41 = float(aRect.x);
|
|
|
|
m._42 = float(aRect.y);
|
2012-03-18 20:07:25 +00:00
|
|
|
SetMatrixUniform(mProfile.LookupUniformLocation("uLayerQuadTransform"), m);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
// activates this program and sets its projection matrix, if the program uses one
|
|
|
|
void CheckAndSetProjectionMatrix(const gfx3DMatrix& aMatrix);
|
|
|
|
|
2010-05-25 06:35:35 +00:00
|
|
|
void SetProjectionMatrix(const gfx3DMatrix& aMatrix) {
|
2012-03-18 20:07:25 +00:00
|
|
|
SetMatrixUniform(mProfile.LookupUniformLocation("uMatrixProj"), aMatrix);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetRenderOffset(const nsIntPoint& aOffset) {
|
|
|
|
float vals[4] = { float(aOffset.x), float(aOffset.y), 0.0f, 0.0f };
|
2012-03-18 20:07:25 +00:00
|
|
|
SetUniform(mProfile.LookupUniformLocation("uRenderTargetOffset"), 4, vals);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetRenderOffset(float aX, float aY) {
|
|
|
|
float vals[4] = { aX, aY, 0.0f, 0.0f };
|
2012-03-18 20:07:25 +00:00
|
|
|
SetUniform(mProfile.LookupUniformLocation("uRenderTargetOffset"), 4, vals);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetLayerOpacity(float aOpacity) {
|
2012-03-18 20:07:25 +00:00
|
|
|
SetUniform(mProfile.LookupUniformLocation("uLayerOpacity"), aOpacity);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetTextureUnit(GLint aUnit) {
|
2012-03-18 20:07:25 +00:00
|
|
|
SetUniform(mProfile.LookupUniformLocation("uTexture"), aUnit);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
void SetYTextureUnit(GLint aUnit) {
|
2012-03-18 20:07:25 +00:00
|
|
|
SetUniform(mProfile.LookupUniformLocation("uYTexture"), aUnit);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetCbTextureUnit(GLint aUnit) {
|
2012-03-18 20:07:25 +00:00
|
|
|
SetUniform(mProfile.LookupUniformLocation("uCbTexture"), aUnit);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetCrTextureUnit(GLint aUnit) {
|
2012-03-18 20:07:25 +00:00
|
|
|
SetUniform(mProfile.LookupUniformLocation("uCrTexture"), aUnit);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetYCbCrTextureUnits(GLint aYUnit, GLint aCbUnit, GLint aCrUnit) {
|
2012-03-18 20:07:25 +00:00
|
|
|
SetUniform(mProfile.LookupUniformLocation("uYTexture"), aYUnit);
|
|
|
|
SetUniform(mProfile.LookupUniformLocation("uCbTexture"), aCbUnit);
|
|
|
|
SetUniform(mProfile.LookupUniformLocation("uCrTexture"), aCrUnit);
|
2011-01-18 07:22:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetBlackTextureUnit(GLint aUnit) {
|
2012-03-18 20:07:25 +00:00
|
|
|
SetUniform(mProfile.LookupUniformLocation("uBlackTexture"), aUnit);
|
2011-01-18 07:22:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetWhiteTextureUnit(GLint aUnit) {
|
2012-03-18 20:07:25 +00:00
|
|
|
SetUniform(mProfile.LookupUniformLocation("uWhiteTexture"), aUnit);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetRenderColor(const gfxRGBA& aColor) {
|
2012-03-18 20:07:25 +00:00
|
|
|
SetUniform(mProfile.LookupUniformLocation("uRenderColor"), aColor);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
void SetTexCoordMultiplier(float aWidth, float aHeight) {
|
|
|
|
float f[] = {aWidth, aHeight};
|
|
|
|
SetUniform(mTexCoordMultiplierUniformLocation, 2, f);
|
|
|
|
}
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
// the names of attributes
|
|
|
|
static const char* const VertexCoordAttrib;
|
|
|
|
static const char* const TexCoordAttrib;
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
protected:
|
|
|
|
nsRefPtr<GLContext> mGL;
|
|
|
|
GLuint mProgram;
|
|
|
|
ProgramProfileOGL mProfile;
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
GLint mTexCoordMultiplierUniformLocation;
|
|
|
|
#ifdef CHECK_CURRENT_PROGRAM
|
|
|
|
static int sCurrentProgramKey;
|
|
|
|
#endif
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
void SetUniform(GLint aLocation, float aFloatValue) {
|
2012-03-18 20:07:25 +00:00
|
|
|
ASSERT_THIS_PROGRAM;
|
2012-03-18 20:07:25 +00:00
|
|
|
NS_ASSERTION(aLocation >= 0, "Invalid location");
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
mGL->fUniform1f(aLocation, aFloatValue);
|
|
|
|
}
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
void SetUniform(GLint aLocation, const gfxRGBA& aColor) {
|
2012-03-18 20:07:25 +00:00
|
|
|
ASSERT_THIS_PROGRAM;
|
2012-03-18 20:07:25 +00:00
|
|
|
NS_ASSERTION(aLocation >= 0, "Invalid location");
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
mGL->fUniform4f(aLocation, float(aColor.r), float(aColor.g), float(aColor.b), float(aColor.a));
|
|
|
|
}
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
void SetUniform(GLint aLocation, int aLength, float *aFloatValues) {
|
2012-03-18 20:07:25 +00:00
|
|
|
ASSERT_THIS_PROGRAM;
|
2012-03-18 20:07:25 +00:00
|
|
|
NS_ASSERTION(aLocation >= 0, "Invalid location");
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
if (aLength == 1) {
|
|
|
|
mGL->fUniform1fv(aLocation, 1, aFloatValues);
|
|
|
|
} else if (aLength == 2) {
|
|
|
|
mGL->fUniform2fv(aLocation, 1, aFloatValues);
|
|
|
|
} else if (aLength == 3) {
|
|
|
|
mGL->fUniform3fv(aLocation, 1, aFloatValues);
|
|
|
|
} else if (aLength == 4) {
|
|
|
|
mGL->fUniform4fv(aLocation, 1, aFloatValues);
|
|
|
|
} else {
|
|
|
|
NS_NOTREACHED("Bogus aLength param");
|
|
|
|
}
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
void SetUniform(GLint aLocation, GLint aIntValue) {
|
2012-03-18 20:07:25 +00:00
|
|
|
ASSERT_THIS_PROGRAM;
|
2012-03-18 20:07:25 +00:00
|
|
|
NS_ASSERTION(aLocation >= 0, "Invalid location");
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
mGL->fUniform1i(aLocation, aIntValue);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
void SetMatrixUniform(GLint aLocation, const gfx3DMatrix& aMatrix) {
|
2012-03-18 20:07:25 +00:00
|
|
|
SetMatrixUniform(aLocation, &aMatrix._11);
|
2010-05-25 06:35:35 +00:00
|
|
|
}
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
void SetMatrixUniform(GLint aLocation, const float *aFloatValues) {
|
2012-03-18 20:07:25 +00:00
|
|
|
ASSERT_THIS_PROGRAM;
|
2012-03-18 20:07:25 +00:00
|
|
|
NS_ASSERTION(aLocation >= 0, "Invalid location");
|
2010-05-25 06:35:35 +00:00
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
mGL->fUniformMatrix4fv(aLocation, 1, false, aFloatValues);
|
|
|
|
}
|
2010-05-25 06:35:35 +00:00
|
|
|
};
|
|
|
|
|
2012-03-18 20:07:25 +00:00
|
|
|
|
2010-05-25 06:35:35 +00:00
|
|
|
} /* layers */
|
|
|
|
} /* mozilla */
|
|
|
|
|
|
|
|
#endif /* GFX_LAYERMANAGEROGLPROGRAM_H */
|