diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index b2d99014148c..6450e7f08814 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -307,11 +307,24 @@ CompositorOGL::Initialize() mGLContext->fGenBuffers(1, &mQuadVBO); mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO); + // 4 quads, with the number of the quad (vertexID) encoded in w. GLfloat vertices[] = { - /* First quad vertices */ - 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, - /* Then quad texcoords */ - 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 1.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 0.0f, 2.0f, + 1.0f, 0.0f, 0.0f, 2.0f, + 0.0f, 1.0f, 0.0f, 2.0f, + 1.0f, 1.0f, 0.0f, 2.0f, + 0.0f, 0.0f, 0.0f, 3.0f, + 1.0f, 0.0f, 0.0f, 3.0f, + 0.0f, 1.0f, 0.0f, 3.0f, + 1.0f, 1.0f, 0.0f, 3.0f, }; HeapCopyOfStackArray verticesOnHeap(vertices); mGLContext->fBufferData(LOCAL_GL_ARRAY_BUFFER, @@ -516,9 +529,7 @@ CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg, aTexCoordRect, layerRects, textureRects); - for (int n = 0; n < rects; ++n) { - BindAndDrawQuad(aProg, layerRects[n], textureRects[n]); - } + BindAndDrawQuads(aProg, rects, layerRects, textureRects); } void @@ -1482,26 +1493,27 @@ CompositorOGL::BindQuadVBO() { void CompositorOGL::QuadVBOVerticesAttrib(GLuint aAttribIndex) { - mGLContext->fVertexAttribPointer(aAttribIndex, 2, - LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, - (GLvoid*) QuadVBOVertexOffset()); + mGLContext->fVertexAttribPointer(aAttribIndex, 4, + LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, + (GLvoid*) 0); } void CompositorOGL::QuadVBOTexCoordsAttrib(GLuint aAttribIndex) { - mGLContext->fVertexAttribPointer(aAttribIndex, 2, - LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, - (GLvoid*) QuadVBOTexCoordOffset()); + mGLContext->fVertexAttribPointer(aAttribIndex, 4, + LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, + (GLvoid*) 0); } void -CompositorOGL::BindAndDrawQuad(ShaderProgramOGL *aProg, - const Rect& aLayerRect, - const Rect& aTextureRect) +CompositorOGL::BindAndDrawQuads(ShaderProgramOGL *aProg, + int aQuads, + const Rect* aLayerRects, + const Rect* aTextureRects) { NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized"); - aProg->SetLayerRect(aLayerRect); + aProg->SetLayerRects(aLayerRects); GLuint vertAttribIndex = aProg->AttribLocation(ShaderProgramOGL::VertexCoordAttrib); GLuint texCoordAttribIndex = aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib); @@ -1513,11 +1525,11 @@ CompositorOGL::BindAndDrawQuad(ShaderProgramOGL *aProg, QuadVBOTexCoordsAttrib(texCoordAttribIndex); mGLContext->fEnableVertexAttribArray(texCoordAttribIndex); - aProg->SetTextureRect(aTextureRect); + aProg->SetTextureRects(aTextureRects); } mGLContext->fEnableVertexAttribArray(vertAttribIndex); - mGLContext->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); + mGLContext->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4 * aQuads); } GLuint diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index 890bba2d1698..3a725e87c0e1 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -362,15 +362,22 @@ private: GLuint aSourceFrameBuffer, GLuint *aFBO, GLuint *aTexture); - GLintptr QuadVBOVertexOffset() { return 0; } - GLintptr QuadVBOTexCoordOffset() { return sizeof(float)*4*2; } - void BindQuadVBO(); void QuadVBOVerticesAttrib(GLuint aAttribIndex); void QuadVBOTexCoordsAttrib(GLuint aAttribIndex); + void BindAndDrawQuads(ShaderProgramOGL *aProg, + int aQuads, + const gfx::Rect* aLayerRect, + const gfx::Rect* aTextureRect); void BindAndDrawQuad(ShaderProgramOGL *aProg, const gfx::Rect& aLayerRect, - const gfx::Rect& aTextureRect = gfx::Rect(0.0f, 0.0f, 1.0f, 1.0f)); + const gfx::Rect& aTextureRect = gfx::Rect(0.0f, 0.0f, 1.0f, 1.0f)) { + gfx::Rect layerRects[4]; + gfx::Rect textureRects[4]; + layerRects[0] = aLayerRect; + textureRects[0] = aTextureRect; + BindAndDrawQuads(aProg, 1, layerRects, textureRects); + } void BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg, const gfx::Rect& aRect, const gfx::Rect& aTexCoordRect, diff --git a/gfx/layers/opengl/OGLShaderProgram.cpp b/gfx/layers/opengl/OGLShaderProgram.cpp index 7570cd395eb9..59b1a8ba1dc2 100644 --- a/gfx/layers/opengl/OGLShaderProgram.cpp +++ b/gfx/layers/opengl/OGLShaderProgram.cpp @@ -32,10 +32,10 @@ AddUniforms(ProgramProfileOGL& aProfile) static const char *sKnownUniformNames[] = { "uLayerTransform", "uMaskTransform", - "uLayerRect", + "uLayerRects", "uMatrixProj", "uTextureTransform", - "uTextureRect", + "uTextureRects", "uRenderTargetOffset", "uLayerOpacity", "uTexture", @@ -146,7 +146,7 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig) AddUniforms(result); vs << "uniform mat4 uMatrixProj;" << endl; - vs << "uniform vec4 uLayerRect;" << endl; + vs << "uniform vec4 uLayerRects[4];" << endl; vs << "uniform mat4 uLayerTransform;" << endl; vs << "uniform vec4 uRenderTargetOffset;" << endl; @@ -154,8 +154,8 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig) if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) { vs << "uniform mat4 uTextureTransform;" << endl; - vs << "uniform vec4 uTextureRect;" << endl; - vs << "attribute vec2 aTexCoord;" << endl; + vs << "uniform vec4 uTextureRects[4];" << endl; + vs << "attribute vec4 aTexCoord;" << endl; vs << "varying vec2 vTexCoord;" << endl; } @@ -166,7 +166,9 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig) } vs << "void main() {" << endl; - vs << " vec4 finalPosition = vec4(aVertexCoord.xy * uLayerRect.zw + uLayerRect.xy, 0.0, 1.0);" << endl; + vs << " int vertexID = int(aVertexCoord.w);" << endl; + vs << " vec4 layerRect = uLayerRects[vertexID];" << endl; + vs << " vec4 finalPosition = vec4(aVertexCoord.xy * layerRect.zw + layerRect.xy, 0.0, 1.0);" << endl; vs << " finalPosition = uLayerTransform * finalPosition;" << endl; vs << " finalPosition.xyz /= finalPosition.w;" << endl; @@ -184,7 +186,8 @@ ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig) vs << " finalPosition = uMatrixProj * finalPosition;" << endl; if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) { - vs << " vec2 texCoord = aTexCoord * uTextureRect.zw + uTextureRect.xy;" << endl; + vs << " vec4 textureRect = uTextureRects[vertexID];" << endl; + vs << " vec2 texCoord = aTexCoord.xy * textureRect.zw + textureRect.xy;" << endl; vs << " vTexCoord = (uTextureTransform * vec4(texCoord, 0.0, 1.0)).xy;" << endl; } diff --git a/gfx/layers/opengl/OGLShaderProgram.h b/gfx/layers/opengl/OGLShaderProgram.h index 216bf4ca812b..b09935c1392f 100644 --- a/gfx/layers/opengl/OGLShaderProgram.h +++ b/gfx/layers/opengl/OGLShaderProgram.h @@ -52,10 +52,10 @@ public: LayerTransform = 0, MaskTransform, - LayerRect, + LayerRects, MatrixProj, TextureTransform, - TextureRect, + TextureRects, RenderTargetOffset, LayerOpacity, Texture, @@ -322,9 +322,12 @@ public: SetMatrixUniform(KnownUniform::MaskTransform, aMatrix); } - void SetLayerRect(const gfx::Rect& aRect) { - float vals[4] = { float(aRect.x), float(aRect.y), float(aRect.width), float(aRect.height) }; - SetUniform(KnownUniform::LayerRect, 4, vals); + void SetLayerRects(const gfx::Rect* aRects) { + float vals[16] = { aRects[0].x, aRects[0].y, aRects[0].width, aRects[0].height, + aRects[1].x, aRects[1].y, aRects[1].width, aRects[1].height, + aRects[2].x, aRects[2].y, aRects[2].width, aRects[2].height, + aRects[3].x, aRects[3].y, aRects[3].width, aRects[3].height }; + SetUniform(KnownUniform::LayerRects, 16, vals); } void SetProjectionMatrix(const gfx::Matrix4x4& aMatrix) { @@ -336,9 +339,12 @@ public: SetMatrixUniform(KnownUniform::TextureTransform, aMatrix); } - void SetTextureRect(const gfx::Rect& aRect) { - float vals[4] = { float(aRect.x), float(aRect.y), float(aRect.width), float(aRect.height) }; - SetUniform(KnownUniform::TextureRect, 4, vals); + void SetTextureRects(const gfx::Rect* aRects) { + float vals[16] = { aRects[0].x, aRects[0].y, aRects[0].width, aRects[0].height, + aRects[1].x, aRects[1].y, aRects[1].width, aRects[1].height, + aRects[2].x, aRects[2].y, aRects[2].width, aRects[2].height, + aRects[3].x, aRects[3].y, aRects[3].width, aRects[3].height }; + SetUniform(KnownUniform::TextureRects, 16, vals); } void SetRenderOffset(const nsIntPoint& aOffset) { @@ -471,6 +477,7 @@ protected: case 2: mGL->fUniform2fv(ku.mLocation, 1, ku.mValue.f16v); break; case 3: mGL->fUniform3fv(ku.mLocation, 1, ku.mValue.f16v); break; case 4: mGL->fUniform4fv(ku.mLocation, 1, ku.mValue.f16v); break; + case 16: mGL->fUniform4fv(ku.mLocation, 4, ku.mValue.f16v); break; default: NS_NOTREACHED("Bogus aLength param"); } diff --git a/widget/cocoa/nsChildView.mm b/widget/cocoa/nsChildView.mm index 9bfaaa83d65a..9d5a3cb365d1 100644 --- a/widget/cocoa/nsChildView.mm +++ b/widget/cocoa/nsChildView.mm @@ -2810,8 +2810,14 @@ GLPresenter::BindAndDrawQuad(ShaderProgramOGL *aProgram, { mGLContext->MakeCurrent(); - aProgram->SetLayerRect(aLayerRect); - aProgram->SetTextureRect(aTextureRect); + gfx::Rect layerRects[4]; + gfx::Rect textureRects[4]; + + layerRects[0] = aLayerRect; + textureRects[0] = aTextureRect; + + aProgram->SetLayerRects(layerRects); + aProgram->SetTextureRects(textureRects); GLuint vertAttribIndex = aProgram->AttribLocation(ShaderProgramOGL::VertexCoordAttrib); GLuint texCoordAttribIndex = aProgram->AttribLocation(ShaderProgramOGL::TexCoordAttrib);