Bug 561959. Implement ColorLayer, which paints a solid color into its layer. r=bas,sr=vlad

This commit is contained in:
Robert O'Callahan 2010-05-13 12:56:11 +12:00
parent 9023fab06f
commit 26569a71da
10 changed files with 330 additions and 6 deletions

View File

@ -45,6 +45,7 @@
#include "nsISupportsImpl.h"
#include "nsAutoPtr.h"
#include "gfx3DMatrix.h"
#include "gfxColor.h"
class gfxContext;
class nsPaintEvent;
@ -56,6 +57,7 @@ class Layer;
class ThebesLayer;
class ContainerLayer;
class ImageLayer;
class ColorLayer;
class ImageContainer;
/*
@ -164,6 +166,11 @@ public:
* Create an ImageLayer for this manager's layer tree.
*/
virtual already_AddRefed<ImageLayer> CreateImageLayer() = 0;
/**
* CONSTRUCTION PHASE ONLY
* Create a ColorLayer for this manager's layer tree.
*/
virtual already_AddRefed<ColorLayer> CreateColorLayer() = 0;
/**
* Can be called anytime
@ -402,6 +409,32 @@ protected:
Layer* mFirstChild;
};
/**
* A Layer which just renders a solid color in its visible region.
*/
class THEBES_API ColorLayer : public Layer {
public:
/**
* CONSTRUCTION PHASE ONLY
* Set the color of the layer.
*/
virtual void SetColor(const gfxRGBA& aColor)
{
mColor = aColor;
}
// This getter can be used anytime.
virtual const gfxRGBA& GetColor() { return mColor; }
protected:
ColorLayer(LayerManager* aManager, void* aImplData)
: Layer(aManager, aImplData),
mColor(0.0, 0.0, 0.0, 0.0)
{}
gfxRGBA mColor;
};
}
}

View File

@ -64,6 +64,7 @@ CPPSRCS = \
BasicImages.cpp \
BasicLayers.cpp \
LayerManagerOGL.cpp \
ColorLayerOGL.cpp \
ThebesLayerOGL.cpp \
ContainerLayerOGL.cpp \
ImageLayerOGL.cpp \

View File

@ -343,6 +343,41 @@ BasicImageLayer::Paint(gfxContext* aContext)
aContext->Fill();
}
class BasicColorLayer : public ColorLayer, BasicImplData {
public:
BasicColorLayer(BasicLayerManager* aLayerManager) :
ColorLayer(aLayerManager, static_cast<BasicImplData*>(this))
{
MOZ_COUNT_CTOR(BasicColorLayer);
}
virtual ~BasicColorLayer()
{
MOZ_COUNT_DTOR(BasicColorLayer);
}
virtual void SetVisibleRegion(const nsIntRegion& aRegion)
{
NS_ASSERTION(BasicManager()->InConstruction(),
"Can only set properties in construction phase");
mVisibleRegion = aRegion;
}
virtual void Paint(gfxContext* aContext);
protected:
BasicLayerManager* BasicManager()
{
return static_cast<BasicLayerManager*>(mManager);
}
};
void
BasicColorLayer::Paint(gfxContext* aContext)
{
aContext->SetColor(mColor);
aContext->Paint();
}
BasicLayerManager::BasicLayerManager(gfxContext* aContext) :
mDefaultTarget(aContext), mLastPainted(nsnull)
#ifdef DEBUG
@ -584,6 +619,14 @@ BasicLayerManager::CreateImageLayer()
return layer.forget();
}
already_AddRefed<ColorLayer>
BasicLayerManager::CreateColorLayer()
{
NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
nsRefPtr<ColorLayer> layer = new BasicColorLayer(this);
return layer.forget();
}
#ifdef DEBUG
static void
AppendAncestors(Layer* aLayer, nsTArray<Layer*>* aAncestors)

View File

@ -87,6 +87,7 @@ public:
virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
virtual already_AddRefed<ImageLayer> CreateImageLayer();
virtual already_AddRefed<ImageContainer> CreateImageContainer();
virtual already_AddRefed<ColorLayer> CreateColorLayer();
virtual LayersBackend GetBackendType() { return LAYERS_BASIC; }
#ifdef DEBUG

View File

@ -0,0 +1,94 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** 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) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Robert O'Callahan <robert@ocallahan.org>
*
* 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 ***** */
#include "ColorLayerOGL.h"
namespace mozilla {
namespace layers {
LayerOGL::LayerType
ColorLayerOGL::GetType()
{
return TYPE_COLOR;
}
Layer*
ColorLayerOGL::GetLayer()
{
return this;
}
void
ColorLayerOGL::RenderLayer(int)
{
static_cast<LayerManagerOGL*>(mManager)->MakeCurrent();
// XXX we might be able to improve performance by using glClear
float quadTransform[4][4];
nsIntRect visibleRect = mVisibleRegion.GetBounds();
// Transform the quad to the size of the visible area.
memset(&quadTransform, 0, sizeof(quadTransform));
quadTransform[0][0] = (float)visibleRect.width;
quadTransform[1][1] = (float)visibleRect.height;
quadTransform[2][2] = 1.0f;
quadTransform[3][0] = (float)visibleRect.x;
quadTransform[3][1] = (float)visibleRect.y;
quadTransform[3][3] = 1.0f;
ColorLayerProgram *program =
static_cast<LayerManagerOGL*>(mManager)->GetColorLayerProgram();
program->Activate();
program->SetLayerQuadTransform(&quadTransform[0][0]);
gfxRGBA color = mColor;
// color is premultiplied, so we need to adjust all channels
color.r *= GetOpacity();
color.g *= GetOpacity();
color.b *= GetOpacity();
color.a *= GetOpacity();
program->SetLayerColor(color);
program->SetLayerTransform(&mTransform._11);
program->Apply();
gl()->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
}
} /* layers */
} /* mozilla */

View File

@ -0,0 +1,72 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** 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) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Robert O'Callahan <robert@ocallahan.org>
*
* 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_COLORLAYEROGL_H
#define GFX_COLORLAYEROGL_H
#include "LayerManagerOGL.h"
namespace mozilla {
namespace layers {
class THEBES_API ColorLayerOGL : public ColorLayer,
public LayerOGL
{
public:
ColorLayerOGL(LayerManagerOGL *aManager)
: ColorLayer(aManager, NULL)
, LayerOGL(aManager)
{
mImplData = static_cast<LayerOGL*>(this);
}
virtual void SetVisibleRegion(const nsIntRegion& aRegion) { mVisibleRegion = aRegion; }
// LayerOGL Implementation
virtual LayerType GetType();
virtual Layer* GetLayer();
virtual void RenderLayer(int aPreviousDestination);
protected:
nsIntRegion mVisibleRegion;
};
} /* layers */
} /* mozilla */
#endif /* GFX_COLORLAYEROGL_H */

View File

@ -134,6 +134,8 @@ ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer)
GLuint frameBuffer;
RGBLayerProgram *rgbProgram =
static_cast<LayerManagerOGL*>(mManager)->GetRGBLayerProgram();
ColorLayerProgram *colorProgram =
static_cast<LayerManagerOGL*>(mManager)->GetColorLayerProgram();
YCbCrLayerProgram *yCbCrProgram =
static_cast<LayerManagerOGL*>(mManager)->GetYCbCrLayerProgram();
@ -174,11 +176,13 @@ ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer)
*/
rgbProgram->Activate();
rgbProgram->PushRenderTargetOffset((GLfloat)GetVisibleRect().x,
(GLfloat)GetVisibleRect().y);
rgbProgram->PushRenderTargetOffset((GLfloat)GetVisibleRect().x, (GLfloat)GetVisibleRect().y);
colorProgram->Activate();
colorProgram->PushRenderTargetOffset((GLfloat)GetVisibleRect().x, (GLfloat)GetVisibleRect().y);
yCbCrProgram->Activate();
yCbCrProgram->PushRenderTargetOffset((GLfloat)GetVisibleRect().x,
(GLfloat)GetVisibleRect().y);
yCbCrProgram->PushRenderTargetOffset((GLfloat)GetVisibleRect().x, (GLfloat)GetVisibleRect().y);
} else {
frameBuffer = aPreviousFrameBuffer;
}
@ -211,6 +215,9 @@ ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer)
yCbCrProgram->Activate();
yCbCrProgram->PopRenderTargetOffset();
colorProgram->Activate();
colorProgram->PopRenderTargetOffset();
rgbProgram->Activate();
rgbProgram->PopRenderTargetOffset();

View File

@ -39,6 +39,7 @@
#include "ThebesLayerOGL.h"
#include "ContainerLayerOGL.h"
#include "ImageLayerOGL.h"
#include "ColorLayerOGL.h"
#include "LayerManagerOGLShaders.h"
#include "gfxContext.h"
@ -76,6 +77,7 @@ LayerManagerOGL::~LayerManagerOGL()
{
mGLContext->MakeCurrent();
delete mRGBLayerProgram;
delete mColorLayerProgram;
delete mYCbCrLayerProgram;
}
@ -97,14 +99,17 @@ LayerManagerOGL::Initialize()
mVertexShader = mGLContext->fCreateShader(LOCAL_GL_VERTEX_SHADER);
mRGBShader = mGLContext->fCreateShader(LOCAL_GL_FRAGMENT_SHADER);
mColorShader = mGLContext->fCreateShader(LOCAL_GL_FRAGMENT_SHADER);
mYUVShader = mGLContext->fCreateShader(LOCAL_GL_FRAGMENT_SHADER);
mGLContext->fShaderSource(mVertexShader, 1, (const GLchar**)&sVertexShader, NULL);
mGLContext->fShaderSource(mRGBShader, 1, (const GLchar**)&sRGBLayerPS, NULL);
mGLContext->fShaderSource(mColorShader, 1, (const GLchar**)&sColorLayerPS, NULL);
mGLContext->fShaderSource(mYUVShader, 1, (const GLchar**)&sYUVLayerPS, NULL);
mGLContext->fCompileShader(mVertexShader);
mGLContext->fCompileShader(mRGBShader);
mGLContext->fCompileShader(mColorShader);
mGLContext->fCompileShader(mYUVShader);
GLint status;
@ -118,8 +123,12 @@ LayerManagerOGL::Initialize()
return false;
}
mGLContext->fGetShaderiv(mYUVShader, LOCAL_GL_COMPILE_STATUS, &status);
mGLContext->fGetShaderiv(mColorShader, LOCAL_GL_COMPILE_STATUS, &status);
if (!status) {
return false;
}
mGLContext->fGetShaderiv(mYUVShader, LOCAL_GL_COMPILE_STATUS, &status);
if (!status) {
return false;
}
@ -183,12 +192,17 @@ LayerManagerOGL::Initialize()
if (!mRGBLayerProgram->Initialize(mVertexShader, mRGBShader, mGLContext)) {
return false;
}
mColorLayerProgram = new ColorLayerProgram();
if (!mColorLayerProgram->Initialize(mVertexShader, mColorShader, mGLContext)) {
return false;
}
mYCbCrLayerProgram = new YCbCrLayerProgram();
if (!mYCbCrLayerProgram->Initialize(mVertexShader, mYUVShader, mGLContext)) {
return false;
}
mRGBLayerProgram->UpdateLocations();
mColorLayerProgram->UpdateLocations();
mYCbCrLayerProgram->UpdateLocations();
mGLContext->fGenBuffers(1, &mVBO);
@ -200,6 +214,13 @@ LayerManagerOGL::Initialize()
mGLContext->fBufferData(LOCAL_GL_ARRAY_BUFFER, sizeof(vertices), vertices, LOCAL_GL_STATIC_DRAW);
mRGBLayerProgram->Activate();
mGLContext->fVertexAttribPointer(VERTEX_ATTRIB_LOCATION,
2,
LOCAL_GL_FLOAT,
LOCAL_GL_FALSE,
0,
0);
mColorLayerProgram->Activate();
mGLContext->fVertexAttribPointer(VERTEX_ATTRIB_LOCATION,
2,
LOCAL_GL_FLOAT,
@ -304,6 +325,13 @@ LayerManagerOGL::CreateImageLayer()
return layer.forget();
}
already_AddRefed<ColorLayer>
LayerManagerOGL::CreateColorLayer()
{
nsRefPtr<ColorLayer> layer = new ColorLayerOGL(this);
return layer.forget();
}
void
LayerManagerOGL::SetClippingEnabled(PRBool aEnabled)
{
@ -440,6 +468,9 @@ LayerManagerOGL::SetupPipeline()
mRGBLayerProgram->Activate();
mRGBLayerProgram->SetMatrixProj(&viewMatrix[0][0]);
mColorLayerProgram->Activate();
mColorLayerProgram->SetMatrixProj(&viewMatrix[0][0]);
mYCbCrLayerProgram->Activate();
mYCbCrLayerProgram->SetMatrixProj(&viewMatrix[0][0]);
}
@ -625,6 +656,12 @@ LayerProgram::SetInt(GLint aLocation, GLint aValue)
mGLContext->fUniform1i(aLocation, aValue);
}
void
LayerProgram::SetColor(GLint aLocation, const gfxRGBA& aColor)
{
mGLContext->fUniform4f(aLocation, aColor.r, aColor.g, aColor.b, aColor.a);
}
void
LayerProgram::SetLayerOpacity(GLfloat aValue)
{
@ -667,6 +704,14 @@ RGBLayerProgram::UpdateLocations()
mLayerTextureLocation = mGLContext->fGetUniformLocation(mProgram, "uLayerTexture");
}
void
ColorLayerProgram::UpdateLocations()
{
LayerProgram::UpdateLocations();
mRenderColorLocation = mGLContext->fGetUniformLocation(mProgram, "uRenderColor");
}
void
YCbCrLayerProgram::UpdateLocations()
{

View File

@ -90,6 +90,7 @@ public:
void SetMatrixUniform(GLint aLocation, const GLfloat *aValue);
void SetInt(GLint aLocation, GLint aValue);
void SetColor(GLint aLocation, const gfxRGBA& aColor);
void SetMatrixProj(GLfloat *aValue)
{
@ -139,6 +140,20 @@ protected:
GLint mLayerTextureLocation;
};
class ColorLayerProgram : public LayerProgram
{
public:
void UpdateLocations();
void SetLayerColor(const gfxRGBA& aColor)
{
SetColor(mRenderColorLocation, aColor);
}
protected:
GLint mRenderColorLocation;
};
class YCbCrLayerProgram : public LayerProgram
{
public:
@ -211,6 +226,8 @@ public:
virtual already_AddRefed<ImageLayer> CreateImageLayer();
virtual already_AddRefed<ColorLayer> CreateColorLayer();
virtual already_AddRefed<ImageContainer> CreateImageContainer();
virtual LayersBackend GetBackendType() { return LAYERS_OPENGL; }
@ -223,6 +240,7 @@ public:
void MakeCurrent();
RGBLayerProgram *GetRGBLayerProgram() { return mRGBLayerProgram; }
ColorLayerProgram *GetColorLayerProgram() { return mColorLayerProgram; }
YCbCrLayerProgram *GetYCbCrLayerProgram() { return mYCbCrLayerProgram; }
typedef mozilla::gl::GLContext GLContext;
@ -247,12 +265,16 @@ private:
GLuint mFrameBuffer;
/** RGB Layer Program */
RGBLayerProgram *mRGBLayerProgram;
/** Color Layer Program */
ColorLayerProgram *mColorLayerProgram;
/** YUV Layer Program */
YCbCrLayerProgram *mYCbCrLayerProgram;
/** Vertex Shader */
GLuint mVertexShader;
/** RGB fragment shader */
GLuint mRGBShader;
/** Solid color shader */
GLuint mColorShader;
/** YUV fragment shader */
GLuint mYUVShader;
/** Current root layer. */
@ -294,7 +316,7 @@ class LayerOGL
public:
LayerOGL(LayerManagerOGL *aManager);
enum LayerType { TYPE_THEBES, TYPE_CONTAINER, TYPE_IMAGE };
enum LayerType { TYPE_THEBES, TYPE_CONTAINER, TYPE_IMAGE, TYPE_COLOR };
virtual LayerType GetType() = 0;

View File

@ -2,6 +2,7 @@
uniform mat4 uLayerQuadTransform; \
uniform mat4 uLayerTransform; \
uniform vec4 uRenderTargetOffset; \
uniform vec4 uRenderColor; \
uniform float uLayerOpacity; \
\
uniform sampler2D uLayerTexture; \
@ -27,6 +28,11 @@ static const GLchar *sRGBLayerPS = SHADER_GLOBAL_VARS "void main() \
gl_FragColor = texture2D(uLayerTexture, vTextureCoordinate) * uLayerOpacity; \
}";
static const GLchar *sColorLayerPS = SHADER_GLOBAL_VARS "void main() \
{ \
gl_FragColor = uRenderColor; \
}";
static const GLchar *sYUVLayerPS = SHADER_GLOBAL_VARS "void main() \
{ \
vec4 yuv; \