Bug 956266 - Don't rebuffer quad vertex + texture coordinates when drawing simple quads in CompositorOGL. r=nrc

This commit is contained in:
Markus Stange 2014-01-08 10:31:07 +01:00
parent a1e1aa68f2
commit d7c5f41aa5
4 changed files with 51 additions and 10 deletions

View File

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DecomposeIntoNoRepeatTriangles.h"
#include "gfxMatrix.h"
namespace mozilla {
namespace gl {
@ -14,6 +15,19 @@ RectTriangles::addRect(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1,
bool flip_y /* = false */)
{
if (vertexCoords.IsEmpty() &&
x0 == 0.0f && y0 == 0.0f && x1 == 1.0f && y1 == 1.0f) {
mIsSimpleQuad = true;
if (flip_y) {
mTextureTransform = gfx3DMatrix::From2D(gfxMatrix(tx1 - tx0, 0, 0, ty0 - ty1, tx0, ty1));
} else {
mTextureTransform = gfx3DMatrix::From2D(gfxMatrix(tx1 - tx0, 0, 0, ty1 - ty0, tx0, ty0));
}
} else if (mIsSimpleQuad) {
mIsSimpleQuad = false;
mTextureTransform = gfx3DMatrix();
}
vert_coord v;
v.x = x0; v.y = y0;
vertexCoords.AppendElement(v);

View File

@ -10,6 +10,7 @@
#include "GLTypes.h"
#include "nsRect.h"
#include "nsTArray.h"
#include "gfx3DMatrix.h"
namespace mozilla {
namespace gl {
@ -18,7 +19,7 @@ namespace gl {
*/
class RectTriangles {
public:
RectTriangles() { }
RectTriangles() : mIsSimpleQuad(false) { }
// Always pass texture coordinates upright. If you want to flip the
// texture coordinates emitted to the tex_coords array, set flip_y to
@ -27,6 +28,16 @@ public:
GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1,
bool flip_y = false);
// Returns whether this object is made of only one rect that can be drawn
// with a pre-buffered unity quad which has 0,0,1,1 as both vertex
// positions and texture coordinates.
// aOutTextureTransform returns the transform that maps 0,0,1,1 texture
// coordinates to the correct ones.
bool IsSimpleQuad(gfx3DMatrix& aOutTextureTransform) const {
aOutTextureTransform = mTextureTransform;
return mIsSimpleQuad;
}
/**
* these return a float pointer to the start of each array respectively.
* Use it for glVertexAttribPointer calls.
@ -50,6 +61,8 @@ private:
// default is 4 rectangles, each made up of 2 triangles (3 coord vertices each)
nsAutoTArray<vert_coord, 6> vertexCoords;
nsAutoTArray<tex_coord, 6> texCoords;
gfx3DMatrix mTextureTransform;
bool mIsSimpleQuad;
};
/**

View File

@ -557,6 +557,9 @@ CompositorOGL::Initialize()
return true;
}
// |aTextureTransform| is the texture transform that will be set on
// aProg, possibly multiplied with another texture transform of our
// own.
// |aTexCoordRect| is the rectangle from the texture that we want to
// draw using the given program. The program already has a necessary
// offset and scale, so the geometry that needs to be drawn is a unit
@ -566,6 +569,7 @@ CompositorOGL::Initialize()
// larger than the rectangle given by |aTexCoordRect|.
void
CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
const gfx3DMatrix& aTextureTransform,
const Rect& aTexCoordRect,
TextureSource *aTexture)
{
@ -622,7 +626,14 @@ CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
rects, flipped);
}
DrawQuads(mGLContext, mVBOs, aProg, rects);
gfx3DMatrix textureTransform;
if (rects.IsSimpleQuad(textureTransform)) {
aProg->SetTextureTransform(aTextureTransform * textureTransform);
BindAndDrawQuad(aProg, false);
} else {
aProg->SetTextureTransform(aTextureTransform);
DrawQuads(mGLContext, mVBOs, aProg, rects);
}
}
void
@ -1191,9 +1202,6 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect,
AutoBindTexture bindSource(mGLContext, source->AsSourceOGL(), LOCAL_GL_TEXTURE0);
gfx3DMatrix textureTransform = source->AsSourceOGL()->GetTextureTransform();
program->SetTextureTransform(textureTransform);
GraphicsFilter filter = ThebesFilter(texturedEffect->mFilter);
gfxMatrix textureTransform2D;
#ifdef MOZ_WIDGET_ANDROID
@ -1218,7 +1226,8 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect,
BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE1, maskQuadTransform);
}
BindAndDrawQuadWithTextureRect(program, texturedEffect->mTextureCoords, source);
BindAndDrawQuadWithTextureRect(program, source->AsSourceOGL()->GetTextureTransform(),
texturedEffect->mTextureCoords, source);
if (!texturedEffect->mPremultiplied) {
mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
@ -1251,13 +1260,15 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect,
program->SetYCbCrTextureUnits(Y, Cb, Cr);
program->SetLayerOpacity(aOpacity);
program->SetTextureTransform(gfx3DMatrix());
AutoSaveTexture bindMask(mGLContext, LOCAL_GL_TEXTURE3);
if (maskType != MaskNone) {
BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE3, maskQuadTransform);
}
BindAndDrawQuadWithTextureRect(program, effectYCbCr->mTextureCoords, sourceYCbCr->GetSubSource(Y));
BindAndDrawQuadWithTextureRect(program,
gfx3DMatrix(),
effectYCbCr->mTextureCoords,
sourceYCbCr->GetSubSource(Y));
}
break;
case EFFECT_RENDER_TARGET: {
@ -1332,7 +1343,6 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect,
program->SetWhiteTextureUnit(1);
program->SetLayerOpacity(aOpacity);
program->SetLayerTransform(aTransform);
program->SetTextureTransform(gfx3DMatrix());
program->SetRenderOffset(offset.x, offset.y);
program->SetLayerQuadRect(aRect);
AutoSaveTexture bindMask(mGLContext, LOCAL_GL_TEXTURE2);
@ -1340,7 +1350,10 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect,
BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE2, maskQuadTransform);
}
BindAndDrawQuadWithTextureRect(program, effectComponentAlpha->mTextureCoords, effectComponentAlpha->mOnBlack);
BindAndDrawQuadWithTextureRect(program,
gfx3DMatrix(),
effectComponentAlpha->mTextureCoords,
effectComponentAlpha->mOnBlack);
mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
LOCAL_GL_ONE, LOCAL_GL_ONE);

View File

@ -309,6 +309,7 @@ private:
bool aFlipped = false,
GLuint aDrawMode = LOCAL_GL_TRIANGLE_STRIP);
void BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
const gfx3DMatrix& aTextureTransform,
const gfx::Rect& aTexCoordRect,
TextureSource *aTexture);