diff --git a/gfx/gl/DecomposeIntoNoRepeatTriangles.cpp b/gfx/gl/DecomposeIntoNoRepeatTriangles.cpp index 5b990ab9bde2..1bb08b8749ef 100644 --- a/gfx/gl/DecomposeIntoNoRepeatTriangles.cpp +++ b/gfx/gl/DecomposeIntoNoRepeatTriangles.cpp @@ -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); diff --git a/gfx/gl/DecomposeIntoNoRepeatTriangles.h b/gfx/gl/DecomposeIntoNoRepeatTriangles.h index 94243f5d4da9..18c02f74b670 100644 --- a/gfx/gl/DecomposeIntoNoRepeatTriangles.h +++ b/gfx/gl/DecomposeIntoNoRepeatTriangles.h @@ -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 vertexCoords; nsAutoTArray texCoords; + gfx3DMatrix mTextureTransform; + bool mIsSimpleQuad; }; /** diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index bede34b5e08f..08d54dc70ad6 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -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,12 +1202,11 @@ 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; + gfx3DMatrix textureTransform = source->AsSourceOGL()->GetTextureTransform(); + #ifdef MOZ_WIDGET_ANDROID + gfxMatrix textureTransform2D; if (filter != GraphicsFilter::FILTER_NEAREST && aTransform.Is2DIntegerTranslation() && textureTransform.Is2D(&textureTransform2D) && @@ -1218,7 +1228,8 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect, BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE1, maskQuadTransform); } - BindAndDrawQuadWithTextureRect(program, texturedEffect->mTextureCoords, source); + BindAndDrawQuadWithTextureRect(program, textureTransform, + texturedEffect->mTextureCoords, source); if (!texturedEffect->mPremultiplied) { mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA, @@ -1251,13 +1262,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 +1345,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 +1352,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); diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index ceb97fe34c09..85bb62ae2bb2 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -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);