Changeset 121729 in webkit


Ignore:
Timestamp:
Jul 2, 2012 9:25:35 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

[TextureMapper] The TextureMapper should support edge-distance anti-antialiasing
https://bugs.webkit.org/show_bug.cgi?id=90308

Patch by Martin Robinson <mrobinson@igalia.com> on 2012-07-02
Reviewed by Noam Rosenthal.

Source/WebCore:

Add an edge-distance anti-aliasing implementation for the TextureMapper. Currently
this implementation is not active for tiled layers. This implementation is based
on the one in the Chromium compositor originally written by David Raveman.

When a layer is transformed in a way that leaves its edge dimensions across pixel
boundaries, edge distance anti-aliasing will do a cheaper form of anti-aliasing
than full-scene anti-aliasing to make the transition from the layer pixel
to the background pixel smoother.

No new tests. This will be covered by pixel tests for Qt and GTK+ accelerated
compositing and 3D transforms, when those test harnesses are capable of
producing pixel output (in progress).

  • platform/graphics/texmap/TextureMapper.h: Add an enum which is used to tell

the texture mapper what edges of a texture are exposed. This will be used for
properly dealing with tiled layers in the future.

  • platform/graphics/texmap/TextureMapperBackingStore.cpp: Properly pass information

about exposed layer edges to the TextureMapper while painting.

  • platform/graphics/texmap/TextureMapperBackingStore.h:

(TextureMapperTile): Modified arguments include exposed edges.

  • platform/graphics/texmap/TextureMapperGL.cpp:

(WebCore::TextureMapperGL::drawQuad): Renamed from drawRect, this method can now
draw quads that have non unit-rect texture coordinates. This is necessary because
the edge distance approach draws such quad.
(WebCore::TextureMapperGL::drawBorder): Call drawQuad now instead of drawRect.
(WebCore::TextureMapperGL::drawTexture): Pass the exposedEdges argument down.
(WebCore::TextureMapperGL::drawTextureRectangleARB): Call drawQuad now instead of
drawRect.
(WebCore::viewportMatrix): Added this helper which can calculate the viewport
transform based on the current OpenGL viewport settings.
(WebCore::scaleLineEquationCoeffecientsToOptimizeDistanceCalculation): Added this
helper which optimizes the fragment shader by precalculating some constant parts
of the distance calculation.
(WebCore::getStandardEquationCoeffecientsForLine): Given two end points of line segment
get the coeffecients of the line in the standard form of the line equation.
(WebCore::quadToEdgeArray): Converts a FloatQuad to an array of four sets of pre-scaled
line coefficients so that they can be passed to OpenGL.
(WebCore::scaledVectorDifference): Helper which helps expand a quad of arbitrary
orientation.
(WebCore::inflateQuad): Inflate a quad of arbitrary orientation. The transform may
flip it so we have to look at neighboring points to expand the quad.
(WebCore::TextureMapperGL::drawTextureWithAntialiasing): Activate the anti-aliasing
program and set up all uniforms.
(WebCore::TextureMapperGL::drawTexturedQuadWithProgram): Abstract out common operations
from drawTexture to be used with drawTextureWithAntialiasing.

  • platform/graphics/texmap/TextureMapperGL.h:

(WebCore::TextureMapperGL::DrawQuad::DrawQuad): Add this small type which stores information
necessary to draw a quad -- it's original destination rect and the final size mapped to
texture coordinates.
(TextureMapperGL):

  • platform/graphics/texmap/TextureMapperImageBuffer.cpp: Add the new exposedEdges argument.
  • platform/graphics/texmap/TextureMapperImageBuffer.h: Ditto.
  • platform/graphics/texmap/TextureMapperShaderManager.cpp: Add the new fragment shader for

doing edge-distance AA and a program which uses that shader.

  • platform/graphics/texmap/TextureMapperShaderManager.h: Ditto.

Source/WebKit2:

  • UIProcess/texmap/LayerBackingStore.cpp:

(WebKit::LayerBackingStore::paintToTextureMapper): Update the method to call paint with
the new argument.

Location:
trunk/Source
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r121728 r121729  
     12012-07-02  Martin Robinson  <mrobinson@igalia.com>
     2
     3        [TextureMapper] The TextureMapper should support edge-distance anti-antialiasing
     4        https://bugs.webkit.org/show_bug.cgi?id=90308
     5
     6        Reviewed by Noam Rosenthal.
     7
     8        Add an edge-distance anti-aliasing implementation for the TextureMapper. Currently
     9        this implementation is not active for tiled layers. This implementation is based
     10        on the one in the Chromium compositor originally written by David Raveman.
     11
     12        When a layer is transformed in a way that leaves its edge dimensions across pixel
     13        boundaries, edge distance anti-aliasing will do a cheaper form of anti-aliasing
     14        than full-scene anti-aliasing to make the transition from the layer pixel
     15        to the background pixel smoother.
     16
     17        No new tests. This will be covered by pixel tests for Qt and GTK+ accelerated
     18        compositing and 3D transforms, when those test harnesses are capable of
     19        producing pixel output (in progress).
     20
     21        * platform/graphics/texmap/TextureMapper.h: Add an enum which is used to tell
     22        the texture mapper what edges of a texture are exposed. This will be used for
     23        properly dealing with tiled layers in the future.
     24        * platform/graphics/texmap/TextureMapperBackingStore.cpp: Properly pass information
     25        about exposed layer edges to the TextureMapper while painting.
     26        * platform/graphics/texmap/TextureMapperBackingStore.h:
     27        (TextureMapperTile): Modified arguments include exposed edges.
     28        * platform/graphics/texmap/TextureMapperGL.cpp:
     29        (WebCore::TextureMapperGL::drawQuad): Renamed from drawRect, this method can now
     30        draw quads that have non unit-rect texture coordinates. This is necessary because
     31        the edge distance approach draws such quad.
     32        (WebCore::TextureMapperGL::drawBorder): Call drawQuad now instead of drawRect.
     33        (WebCore::TextureMapperGL::drawTexture): Pass the exposedEdges argument down.
     34        (WebCore::TextureMapperGL::drawTextureRectangleARB): Call drawQuad now instead of
     35        drawRect.
     36        (WebCore::viewportMatrix): Added this helper which can calculate the viewport
     37        transform based on the current OpenGL viewport settings.
     38        (WebCore::scaleLineEquationCoeffecientsToOptimizeDistanceCalculation): Added this
     39        helper which optimizes the fragment shader by precalculating some constant parts
     40        of the distance calculation.
     41        (WebCore::getStandardEquationCoeffecientsForLine): Given two end points of line segment
     42        get the coeffecients of the line in the standard form of the line equation.
     43        (WebCore::quadToEdgeArray): Converts a FloatQuad to an array of four sets of pre-scaled
     44        line coefficients so that they can be passed to OpenGL.
     45        (WebCore::scaledVectorDifference): Helper which helps expand a quad of arbitrary
     46        orientation.
     47        (WebCore::inflateQuad): Inflate a quad of arbitrary orientation. The transform may
     48        flip it so we have to look at neighboring points to expand the quad.
     49        (WebCore::TextureMapperGL::drawTextureWithAntialiasing): Activate the anti-aliasing
     50        program and set up all uniforms.
     51        (WebCore::TextureMapperGL::drawTexturedQuadWithProgram): Abstract out common operations
     52        from drawTexture to be used with drawTextureWithAntialiasing.
     53        * platform/graphics/texmap/TextureMapperGL.h:
     54        (WebCore::TextureMapperGL::DrawQuad::DrawQuad): Add this small type which stores information
     55        necessary to draw a quad -- it's original destination rect and the final size mapped to
     56        texture coordinates.
     57        (TextureMapperGL):
     58        * platform/graphics/texmap/TextureMapperImageBuffer.cpp: Add the new exposedEdges argument.
     59        * platform/graphics/texmap/TextureMapperImageBuffer.h: Ditto.
     60        * platform/graphics/texmap/TextureMapperShaderManager.cpp: Add the new fragment shader for
     61        doing edge-distance AA and a program which uses that shader.
     62        * platform/graphics/texmap/TextureMapperShaderManager.h: Ditto.
     63
    1642012-07-02  Dan Bernstein  <mitz@apple.com>
    265
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapper.h

    r121136 r121729  
    113113    virtual ~TextureMapper() { }
    114114
     115    enum ExposedEdges {
     116        NoEdges = 0,
     117        LeftEdge = 1 << 0,
     118        RightEdge = 1 << 1,
     119        TopEdge = 1 << 2,
     120        BottomEdge = 1 << 3,
     121        AllEdges = LeftEdge | RightEdge | TopEdge | BottomEdge,
     122    };
     123
    115124    virtual void drawBorder(const Color&, float borderWidth, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix = TransformationMatrix()) = 0;
    116     virtual void drawTexture(const BitmapTexture&, const FloatRect& target, const TransformationMatrix& modelViewMatrix = TransformationMatrix(), float opacity = 1.0f, const BitmapTexture* maskTexture = 0) = 0;
     125    virtual void drawTexture(const BitmapTexture&, const FloatRect& target, const TransformationMatrix& modelViewMatrix = TransformationMatrix(), float opacity = 1.0f, const BitmapTexture* maskTexture = 0, unsigned exposedEdges = AllEdges) = 0;
    117126
    118127    // makes a surface the target for the following drawTexture calls.
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.cpp

    r120533 r121729  
    8888}
    8989
    90 void TextureMapperTile::paint(TextureMapper* textureMapper, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
     90void TextureMapperTile::paint(TextureMapper* textureMapper, const TransformationMatrix& transform, float opacity, BitmapTexture* mask, const unsigned exposedEdges)
    9191{
    9292    if (texture().get())
    93         textureMapper->drawTexture(*texture().get(), rect(), transform, opacity, mask);
     93        textureMapper->drawTexture(*texture().get(), rect(), transform, opacity, mask, exposedEdges);
    9494}
    9595
     
    106106    updateContents(textureMapper, m_image.get());
    107107    m_image.clear();
     108}
     109
     110unsigned TextureMapperBackingStore::calculateExposedTileEdges(const FloatRect& totalRect, const FloatRect& tileRect)
     111{
     112    unsigned exposedEdges = TextureMapper::NoEdges;
     113    if (!tileRect.x())
     114        exposedEdges |= TextureMapper::LeftEdge;
     115    if (!tileRect.y())
     116        exposedEdges |= TextureMapper::TopEdge;
     117    if (tileRect.width() + tileRect.x() >= totalRect.width())
     118        exposedEdges |= TextureMapper::RightEdge;
     119    if (tileRect.height() + tileRect.y() >= totalRect.height())
     120        exposedEdges |= TextureMapper::BottomEdge;
     121    return exposedEdges;
    108122}
    109123
     
    114128    adjustedTransform.multiply(TransformationMatrix::rectToRect(rect(), targetRect));
    115129    for (size_t i = 0; i < m_tiles.size(); ++i) {
    116         m_tiles[i].paint(textureMapper, adjustedTransform, opacity, mask);
     130        m_tiles[i].paint(textureMapper, adjustedTransform, opacity, mask, calculateExposedTileEdges(rect(), m_tiles[i].rect()));
    117131        if (m_drawsDebugBorders)
    118132            textureMapper->drawBorder(m_debugBorderColor, m_debugBorderWidth, m_tiles[i].rect(), adjustedTransform);
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperBackingStore.h

    r119567 r121729  
    4040    virtual void paintToTextureMapper(TextureMapper*, const FloatRect&, const TransformationMatrix&, float, BitmapTexture*) = 0;
    4141    virtual ~TextureMapperBackingStore() { }
     42
     43protected:
     44    static unsigned calculateExposedTileEdges(const FloatRect& totalRect, const FloatRect& tileRect);
    4245};
    4346
     
    8386
    8487    void updateContents(TextureMapper*, Image*, const IntRect&);
    85     virtual void paint(TextureMapper*, const TransformationMatrix&, float, BitmapTexture*);
     88    virtual void paint(TextureMapper*, const TransformationMatrix&, float, BitmapTexture*, const unsigned exposedEdges);
    8689    virtual ~TextureMapperTile() { }
    8790
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp

    r121462 r121729  
    237237    , m_data(new TextureMapperGLData)
    238238    , m_context(0)
     239    , m_enableEdgeDistanceAntialiasing(false)
    239240{
    240241}
     
    305306}
    306307
    307 void TextureMapperGL::drawRect(const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, TextureMapperShaderProgram* shaderProgram, GLenum drawingMode, bool needsBlending)
     308void TextureMapperGL::drawQuad(const DrawQuad& quadToDraw, const TransformationMatrix& modelViewMatrix, TextureMapperShaderProgram* shaderProgram, GLenum drawingMode, bool needsBlending)
    308309{
    309310    GL_CMD(glEnableVertexAttribArray(shaderProgram->vertexAttrib()));
    310311    GL_CMD(glBindBuffer(GL_ARRAY_BUFFER, 0));
    311     const GLfloat unitRect[] = {0, 0, 1, 0, 1, 1, 0, 1};
    312     GL_CMD(glVertexAttribPointer(shaderProgram->vertexAttrib(), 2, GL_FLOAT, GL_FALSE, 0, unitRect));
     312
     313    const GLfloat quad[] = {
     314        quadToDraw.targetRectMappedToUnitSquare.p1().x(), quadToDraw.targetRectMappedToUnitSquare.p1().x(),
     315        quadToDraw.targetRectMappedToUnitSquare.p2().x(), quadToDraw.targetRectMappedToUnitSquare.p2().y(),
     316        quadToDraw.targetRectMappedToUnitSquare.p3().x(), quadToDraw.targetRectMappedToUnitSquare.p3().y(),
     317        quadToDraw.targetRectMappedToUnitSquare.p4().x(), quadToDraw.targetRectMappedToUnitSquare.p4().y()
     318    };
     319    GL_CMD(glVertexAttribPointer(shaderProgram->vertexAttrib(), 2, GL_FLOAT, GL_FALSE, 0, quad));
    313320
    314321    TransformationMatrix matrix = TransformationMatrix(data().projectionMatrix).multiply(modelViewMatrix).multiply(TransformationMatrix(
    315             targetRect.width(), 0, 0, 0,
    316             0, targetRect.height(), 0, 0,
     322            quadToDraw.originalTargetRect.width(), 0, 0, 0,
     323            0, quadToDraw.originalTargetRect.height(), 0, 0,
    317324            0, 0, 1, 0,
    318             targetRect.x(), targetRect.y(), 0, 1));
    319 
     325            quadToDraw.originalTargetRect.x(), quadToDraw.originalTargetRect.y(), 0, 1));
    320326    const GLfloat m4[] = {
    321327        matrix.m11(), matrix.m12(), matrix.m13(), matrix.m14(),
     
    352358    GL_CMD(glLineWidth(width));
    353359
    354     drawRect(targetRect, modelViewMatrix, program.get(), GL_LINE_LOOP, color.hasAlpha());
    355 }
    356 
    357 void TextureMapperGL::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* mask)
     360    drawQuad(targetRect, modelViewMatrix, program.get(), GL_LINE_LOOP, color.hasAlpha());
     361}
     362
     363void TextureMapperGL::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* mask, unsigned exposedEdges)
    358364{
    359365    if (!texture.isValid())
     
    364370
    365371    const BitmapTextureGL& textureGL = static_cast<const BitmapTextureGL&>(texture);
    366     drawTexture(textureGL.id(), textureGL.isOpaque() ? 0 : SupportsBlending, textureGL.size(), targetRect, matrix, opacity, mask);
     372    drawTexture(textureGL.id(), textureGL.isOpaque() ? 0 : SupportsBlending, textureGL.size(), targetRect, matrix, opacity, mask, exposedEdges);
    367373}
    368374
     
    397403
    398404    bool needsBlending = (flags & SupportsBlending) || opacity < 0.99 || maskTexture;
    399     drawRect(targetRect, modelViewMatrix, program.get(), GL_TRIANGLE_FAN, needsBlending);
     405    drawQuad(targetRect, modelViewMatrix, program.get(), GL_TRIANGLE_FAN, needsBlending);
    400406}
    401407#endif // defined(GL_ARB_texture_rectangle)
    402408
    403 void TextureMapperGL::drawTexture(uint32_t texture, Flags flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture)
    404 {
     409void TextureMapperGL::drawTexture(uint32_t texture, Flags flags, const IntSize& /* textureSize */, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture, unsigned exposedEdges)
     410{
     411    bool needsAntiliaing = m_enableEdgeDistanceAntialiasing && !modelViewMatrix.isIntegerTranslation();
     412    if (needsAntiliaing && drawTextureWithAntialiasing(texture, flags, targetRect, modelViewMatrix, opacity, maskTexture, exposedEdges))
     413       return;
     414
    405415    RefPtr<TextureMapperShaderProgram> program;
    406416    if (maskTexture)
     
    410420    GL_CMD(glUseProgram(program->id()));
    411421
     422    drawTexturedQuadWithProgram(program.get(), texture, flags, targetRect, modelViewMatrix, opacity, maskTexture);
     423}
     424
     425static TransformationMatrix viewportMatrix()
     426{
     427    GLint viewport[4];
     428    GL_CMD(glGetIntegerv(GL_VIEWPORT, viewport));
     429
     430    TransformationMatrix matrix;
     431    matrix.translate3d(viewport[0], viewport[1], 0);
     432    matrix.scale3d(viewport[2], viewport[3], 0);
     433
     434    // Map x, y and z to unit square from OpenGL normalized device
     435    // coordinates which are -1 to 1 on every axis.
     436    matrix.translate3d(0.5, 0.5, 0.5);
     437    matrix.scale3d(0.5, 0.5, 0.5);
     438
     439    return matrix;
     440}
     441
     442static void scaleLineEquationCoeffecientsToOptimizeDistanceCalculation(float* coeffecients)
     443{
     444    // In the fragment shader we want to calculate the distance from this
     445    // line to a point (p), which is given by the formula:
     446    // (A*p.x + B*p.y + C) / sqrt (a^2 + b^2)
     447    // We can do a small amount of precalculation here to reduce the
     448    // amount of math in the shader by scaling the coeffecients now.
     449    float scale = 1.0 / FloatPoint(coeffecients[0], coeffecients[1]).length();
     450    coeffecients[0] = coeffecients[0] * scale;
     451    coeffecients[1] = coeffecients[1] * scale;
     452    coeffecients[2] = coeffecients[2] * scale;
     453}
     454
     455static void getStandardEquationCoeffecientsForLine(const FloatPoint& p1, const FloatPoint& p2, float* coeffecients)
     456{
     457    // Given two points, the standard equation of a line (Ax + By + C = 0)
     458    // can be calculated via the formula:
     459    // (p1.y – p2.y)x + (p1.x – p2.x)y + ((p1.x*p2.y) – (p2.x*p1.y)) = 0
     460    coeffecients[0] = p1.y() - p2.y();
     461    coeffecients[1] = p2.x() - p1.x();
     462    coeffecients[2] = p1.x() * p2.y() - p2.x() * p1.y();
     463    scaleLineEquationCoeffecientsToOptimizeDistanceCalculation(coeffecients);
     464}
     465
     466static void quadToEdgeArray(const FloatQuad& quad, float* edgeArray)
     467{
     468    if (quad.isCounterclockwise()) {
     469        getStandardEquationCoeffecientsForLine(quad.p4(), quad.p3(), edgeArray);
     470        getStandardEquationCoeffecientsForLine(quad.p3(), quad.p2(), edgeArray + 3);
     471        getStandardEquationCoeffecientsForLine(quad.p2(), quad.p1(), edgeArray + 6);
     472        getStandardEquationCoeffecientsForLine(quad.p1(), quad.p4(), edgeArray + 9);
     473        return;
     474    }
     475    getStandardEquationCoeffecientsForLine(quad.p4(), quad.p1(), edgeArray);
     476    getStandardEquationCoeffecientsForLine(quad.p1(), quad.p2(), edgeArray + 3);
     477    getStandardEquationCoeffecientsForLine(quad.p2(), quad.p3(), edgeArray + 6);
     478    getStandardEquationCoeffecientsForLine(quad.p3(), quad.p4(), edgeArray + 9);
     479}
     480
     481static FloatSize scaledVectorDifference(const FloatPoint& point1, const FloatPoint& point2, float scale)
     482{
     483    FloatSize vector = point1 - point2;
     484    if (vector.diagonalLengthSquared())
     485        vector.scale(1.0 / vector.diagonalLength());
     486
     487    vector.scale(scale);
     488    return vector;
     489}
     490
     491static FloatQuad inflateQuad(const FloatQuad& quad, float distance)
     492{
     493    FloatQuad expandedQuad = quad;
     494    expandedQuad.setP1(expandedQuad.p1() + scaledVectorDifference(quad.p1(), quad.p2(), distance));
     495    expandedQuad.setP4(expandedQuad.p4() + scaledVectorDifference(quad.p4(), quad.p3(), distance));
     496
     497    expandedQuad.setP1(expandedQuad.p1() + scaledVectorDifference(quad.p1(), quad.p4(), distance));
     498    expandedQuad.setP2(expandedQuad.p2() + scaledVectorDifference(quad.p2(), quad.p3(), distance));
     499
     500    expandedQuad.setP2(expandedQuad.p2() + scaledVectorDifference(quad.p2(), quad.p1(), distance));
     501    expandedQuad.setP3(expandedQuad.p3() + scaledVectorDifference(quad.p3(), quad.p4(), distance));
     502
     503    expandedQuad.setP3(expandedQuad.p3() + scaledVectorDifference(quad.p3(), quad.p2(), distance));
     504    expandedQuad.setP4(expandedQuad.p4() + scaledVectorDifference(quad.p4(), quad.p1(), distance));
     505
     506    return expandedQuad;
     507}
     508
     509bool TextureMapperGL::drawTextureWithAntialiasing(uint32_t texture, Flags flags, const FloatRect& originalTargetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture, unsigned exposedEdges)
     510{
     511    // The antialiasing path does not support mask textures at the moment.
     512    if (maskTexture)
     513        return false;
     514
     515    // For now we punt on rendering tiled layers with antialiasing. It's quite hard
     516    // to render them without seams.
     517    if (exposedEdges != AllEdges)
     518        return false;
     519
     520    // The goal here is render a slightly larger (0.75 pixels in screen space) quad and to
     521    // gradually taper off the alpha values to do a simple version of edge distance
     522    // antialiasing. Note here that we are also including the viewport matrix (which
     523    // translates from normalized device coordinates to screen coordinates), because these
     524    // values are consumed in the fragment shader, which works in screen coordinates.
     525    TransformationMatrix screenSpaceTransform = viewportMatrix().multiply(TransformationMatrix(data().projectionMatrix)).multiply(modelViewMatrix).to2dTransform();
     526    if (!screenSpaceTransform.isInvertible())
     527        return false;
     528    FloatQuad quadInScreenSpace = screenSpaceTransform.mapQuad(originalTargetRect);
     529
     530    const float inflationDistance = 0.75;
     531    FloatQuad expandedQuadInScreenSpace = inflateQuad(quadInScreenSpace, inflationDistance);
     532
     533    // In the non-antialiased case the vertices passed are the unit rectangle and double
     534    // as the texture coordinates (0,0 1,0, 1,1 and 0,1). Here we map the expanded quad
     535    // coordinates in screen space back to the original rect's texture coordinates.
     536    // This has the effect of slightly increasing the size of the original quad's geometry
     537    // in the vertex shader.
     538    FloatQuad expandedQuadInTextureCoordinates = screenSpaceTransform.inverse().mapQuad(expandedQuadInScreenSpace);
     539    expandedQuadInTextureCoordinates.move(-originalTargetRect.x(), -originalTargetRect.y());
     540    expandedQuadInTextureCoordinates.scale(1 / originalTargetRect.width(), 1 / originalTargetRect.height());
     541
     542    // We prepare both the expanded quad for the fragment shader as well as the rectangular bounding
     543    // box of that quad, as that seems necessary to properly antialias backfacing quads.
     544    float targetQuadEdges[24];
     545    quadToEdgeArray(expandedQuadInScreenSpace, targetQuadEdges);
     546    quadToEdgeArray(inflateQuad(quadInScreenSpace.boundingBox(),  inflationDistance), targetQuadEdges + 12);
     547
     548    RefPtr<TextureMapperShaderProgramAntialiasingNoMask> program = data().sharedGLData().textureMapperShaderManager.antialiasingNoMaskProgram();
     549    GL_CMD(glUseProgram(program->id()));
     550    GL_CMD(glUniform3fv(program->expandedQuadEdgesInScreenSpaceLocation(), 8, targetQuadEdges));
     551
     552    drawTexturedQuadWithProgram(program.get(), texture, flags, DrawQuad(originalTargetRect, expandedQuadInTextureCoordinates), modelViewMatrix, opacity, 0 /* maskTexture */);
     553    return true;
     554}
     555
     556void TextureMapperGL::drawTexturedQuadWithProgram(TextureMapperShaderProgram* program, uint32_t texture, Flags flags, const DrawQuad& quadToDraw, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture)
     557{
    412558    GL_CMD(glEnableVertexAttribArray(program->vertexAttrib()));
    413559    GL_CMD(glActiveTexture(GL_TEXTURE0));
     
    429575
    430576    bool needsBlending = (flags & SupportsBlending) || opacity < 0.99 || maskTexture;
    431     drawRect(targetRect, modelViewMatrix, program.get(), GL_TRIANGLE_FAN, needsBlending);
     577    drawQuad(quadToDraw, modelViewMatrix, program, GL_TRIANGLE_FAN, needsBlending);
    432578}
    433579
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h

    r121136 r121729  
    5151    // TextureMapper implementation
    5252    virtual void drawBorder(const Color&, float borderWidth, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix = TransformationMatrix()) OVERRIDE;
    53     virtual void drawTexture(const BitmapTexture&, const FloatRect&, const TransformationMatrix&, float opacity, const BitmapTexture* maskTexture) OVERRIDE;
    54     virtual void drawTexture(uint32_t texture, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture);
     53    virtual void drawTexture(const BitmapTexture&, const FloatRect&, const TransformationMatrix&, float opacity, const BitmapTexture* maskTexture, unsigned exposedEdges) OVERRIDE;
     54    virtual void drawTexture(uint32_t texture, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture, unsigned exposedEdges = AllEdges);
     55
    5556#if defined(GL_ARB_texture_rectangle)
    5657    virtual void drawTextureRectangleARB(uint32_t texture, Flags, const IntSize& textureSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture);
    5758#endif
     59
    5860    virtual void bindSurface(BitmapTexture* surface) OVERRIDE;
    5961    virtual void beginClip(const TransformationMatrix&, const FloatRect&) OVERRIDE;
     
    7072#endif
    7173
     74    void setEnableEdgeDistanceAntialiasing(bool enabled) { m_enableEdgeDistanceAntialiasing = enabled; }
    7275
    7376private:
     
    9598    };
    9699
    97     void drawRect(const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, TextureMapperShaderProgram*, GLenum drawingMode, bool needsBlending);
     100    struct DrawQuad {
     101        DrawQuad(const FloatRect& originalTargetRect, const FloatQuad& targetRectMappedToUnitSquare = FloatRect(FloatPoint(), FloatSize(1, 1)))
     102            : originalTargetRect(originalTargetRect)
     103            , targetRectMappedToUnitSquare(targetRectMappedToUnitSquare)
     104        {
     105        }
     106
     107        FloatRect originalTargetRect;
     108        FloatQuad targetRectMappedToUnitSquare;
     109    };
     110
     111    bool drawTextureWithAntialiasing(uint32_t texture, Flags, const FloatRect& originalTargetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture, unsigned exposedEdges);
     112    void drawTexturedQuadWithProgram(TextureMapperShaderProgram*, uint32_t texture, Flags, const DrawQuad&, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture);
     113    void drawQuad(const DrawQuad&, const TransformationMatrix& modelViewMatrix, TextureMapperShaderProgram*, GLenum drawingMode, bool needsBlending);
     114
    98115    bool beginScissorClip(const TransformationMatrix&, const FloatRect&);
    99116    void bindDefaultSurface();
     
    103120    GraphicsContext* m_context;
    104121    ClipStack m_clipStack;
     122    bool m_enableEdgeDistanceAntialiasing;
     123
    105124    friend class BitmapTextureGL;
    106125};
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.cpp

    r120359 r121729  
    8383}
    8484
    85 void TextureMapperImageBuffer::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture)
     85void TextureMapperImageBuffer::drawTexture(const BitmapTexture& texture, const FloatRect& targetRect, const TransformationMatrix& matrix, float opacity, const BitmapTexture* maskTexture, unsigned /* exposedEdges */)
    8686{
    8787    GraphicsContext* context = currentContext();
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperImageBuffer.h

    r121136 r121729  
    5353    // TextureMapper implementation
    5454    virtual void drawBorder(const Color& color, float borderWidth, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix = TransformationMatrix()) OVERRIDE { };
    55     virtual void drawTexture(const BitmapTexture&, const FloatRect& targetRect, const TransformationMatrix&, float opacity, const BitmapTexture* maskTexture) OVERRIDE;
     55    virtual void drawTexture(const BitmapTexture&, const FloatRect& targetRect, const TransformationMatrix&, float opacity, const BitmapTexture* maskTexture, unsigned exposedEdges) OVERRIDE;
    5656    virtual void beginClip(const TransformationMatrix&, const FloatRect&) OVERRIDE;
    5757    virtual void bindSurface(BitmapTexture* surface) OVERRIDE { m_currentSurface = surface;}
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.cpp

    r121462 r121729  
    22 Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
    33 Copyright (C) 2012 Igalia S.L.
     4 Copyright (C) 2011 Google Inc. All rights reserved.
    45
    56 This library is free software; you can redistribute it and/or
     
    106107    );
    107108
     109static const char* fragmentShaderSourceAntialiasingNoMask =
     110    FRAGMENT_SHADER(
     111        uniform sampler2D s_source;
     112        varying highp vec2 v_sourceTexCoord;
     113        uniform lowp float u_opacity;
     114        uniform vec3 u_expandedQuadEdgesInScreenSpace[8];
     115        void main()
     116        {
     117            vec4 sampledColor = texture2D(s_source, clamp(v_sourceTexCoord, 0.0, 1.0));
     118            vec3 pos = vec3(gl_FragCoord.xy, 1);
     119
     120            // The data passed in u_expandedQuadEdgesInScreenSpace is merely the
     121            // pre-scaled coeffecients of the line equations describing the four edges
     122            // of the expanded quad in screen space and the rectangular bounding box
     123            // of the expanded quad.
     124            //
     125            // We are doing a simple distance calculation here according to the formula:
     126            // (A*p.x + B*p.y + C) / sqrt(A^2 + B^2) = distance from line to p
     127            // Note that A, B and C have already been scaled by 1 / sqrt(A^2 + B^2).
     128            float a0 = clamp(dot(u_expandedQuadEdgesInScreenSpace[0], pos), 0.0, 1.0);
     129            float a1 = clamp(dot(u_expandedQuadEdgesInScreenSpace[1], pos), 0.0, 1.0);
     130            float a2 = clamp(dot(u_expandedQuadEdgesInScreenSpace[2], pos), 0.0, 1.0);
     131            float a3 = clamp(dot(u_expandedQuadEdgesInScreenSpace[3], pos), 0.0, 1.0);
     132            float a4 = clamp(dot(u_expandedQuadEdgesInScreenSpace[4], pos), 0.0, 1.0);
     133            float a5 = clamp(dot(u_expandedQuadEdgesInScreenSpace[5], pos), 0.0, 1.0);
     134            float a6 = clamp(dot(u_expandedQuadEdgesInScreenSpace[6], pos), 0.0, 1.0);
     135            float a7 = clamp(dot(u_expandedQuadEdgesInScreenSpace[7], pos), 0.0, 1.0);
     136
     137            // Now we want to reduce the alpha value of the fragment if it is close to the
     138            // edges of the expanded quad (or rectangular bounding box -- which seems to be
     139            // important for backfacing quads). Note that we are combining the contribution
     140            // from the (top || bottom) and (left || right) edge by simply multiplying. This follows
     141            // the approach described at: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter22.html,
     142            // in this case without using Gaussian weights.
     143            gl_FragColor = sampledColor * u_opacity * min(min(a0, a2) * min(a1, a3), min(a4, a6) * min(a5, a7));
     144        }
     145    );
     146
    108147static const char* fragmentShaderSourceRectSimple =
    109148    FRAGMENT_SHADER(
     
    157196}
    158197
     198PassRefPtr<TextureMapperShaderProgramAntialiasingNoMask> TextureMapperShaderManager::antialiasingNoMaskProgram()
     199{
     200    return static_pointer_cast<TextureMapperShaderProgramAntialiasingNoMask>(getShaderProgram(AntialiasingNoMask));
     201}
     202
    159203PassRefPtr<TextureMapperShaderProgram> TextureMapperShaderManager::getShaderProgram(ShaderType shaderType)
    160204{
     
    173217    case RectSimple:
    174218        program = TextureMapperShaderProgramRectSimple::create();
     219        break;
     220    case AntialiasingNoMask:
     221        program = TextureMapperShaderProgramAntialiasingNoMask::create();
    175222        break;
    176223    case OpacityAndMask:
     
    217264    glCompileShader(vertexShader);
    218265    glCompileShader(fragmentShader);
     266
    219267    glAttachShader(programID, vertexShader);
    220268    glAttachShader(programID, fragmentShader);
     
    222270
    223271    m_vertexAttrib = glGetAttribLocation(programID, "a_vertex");
     272
    224273    m_id = programID;
    225274    m_vertexShader = vertexShader;
     
    295344    getUniformLocation(m_maskTextureLocation, "s_mask");
    296345    getUniformLocation(m_opacityLocation, "u_opacity");
     346}
     347
     348TextureMapperShaderProgramAntialiasingNoMask::TextureMapperShaderProgramAntialiasingNoMask()
     349    : TextureMapperShaderProgram(vertexShaderSourceSimple, fragmentShaderSourceAntialiasingNoMask)
     350{
     351    initializeProgram();
     352    getUniformLocation(m_matrixLocation, "u_matrix");
     353    getUniformLocation(m_sourceTextureLocation, "s_source");
     354    getUniformLocation(m_opacityLocation, "u_opacity");
     355    getUniformLocation(m_expandedQuadEdgesInScreenSpaceLocation, "u_expandedQuadEdgesInScreenSpace");
     356    getUniformLocation(m_flipLocation, "u_flip");
    297357}
    298358
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperShaderManager.h

    r121462 r121729  
    178178};
    179179
     180class TextureMapperShaderProgramAntialiasingNoMask : public TextureMapperShaderProgram {
     181public:
     182    static PassRefPtr<TextureMapperShaderProgramAntialiasingNoMask> create()
     183    {
     184        return adoptRef(new TextureMapperShaderProgramAntialiasingNoMask());
     185    }
     186
     187    GLint expandedQuadVerticesInTextureCoordinatesLocation() { return m_expandedQuadVerticesInTextureCordinatesLocation; }
     188    GLint expandedQuadEdgesInScreenSpaceLocation() { return m_expandedQuadEdgesInScreenSpaceLocation; }
     189
     190private:
     191    TextureMapperShaderProgramAntialiasingNoMask();
     192
     193    GLint m_expandedQuadVerticesInTextureCordinatesLocation;
     194    GLint m_expandedQuadEdgesInScreenSpaceLocation;
     195};
     196
    180197class TextureMapperShaderManager {
    181198public:
     
    183200        Invalid = 0, // HashMaps do not like 0 as a key.
    184201        Simple,
     202        AntialiasingNoMask,
    185203        RectSimple,
    186204        OpacityAndMask,
     
    199217    PassRefPtr<TextureMapperShaderProgram> getShaderProgram(ShaderType);
    200218    PassRefPtr<TextureMapperShaderProgramSolidColor> solidColorProgram();
     219    PassRefPtr<TextureMapperShaderProgramAntialiasingNoMask> antialiasingNoMaskProgram();
    201220
    202221private:
  • trunk/Source/WebKit2/ChangeLog

    r121707 r121729  
     12012-07-02  Martin Robinson  <mrobinson@igalia.com>
     2
     3        [TextureMapper] The TextureMapper should support edge-distance anti-antialiasing
     4        https://bugs.webkit.org/show_bug.cgi?id=90308
     5
     6        Reviewed by Noam Rosenthal.
     7
     8        * UIProcess/texmap/LayerBackingStore.cpp:
     9        (WebKit::LayerBackingStore::paintToTextureMapper): Update the method to call paint with
     10        the new argument.
     11
    1122012-07-02  Benjamin Poulain  <bpoulain@apple.com>
    213
  • trunk/Source/WebKit2/UIProcess/texmap/LayerBackingStore.cpp

    r121151 r121729  
    122122    }
    123123
     124    // TODO: When the TextureMapper makes a distinction between some edges exposed and no edges
     125    // exposed, the value passed should be an accurate reflection of the tile subset that we are
     126    // passing. For now we just "estimate" since LayerBackingStore doesn't keep information about
     127    // the total tiled surface rect at the moment.
     128    unsigned edgesExposed = m_tiles.size() > 1 ? TextureMapper::NoEdges : TextureMapper::AllEdges;
    124129    for (size_t i = 0; i < tilesToPaint.size(); ++i)
    125         tilesToPaint[i]->paint(textureMapper, transform, opacity, mask);
     130        tilesToPaint[i]->paint(textureMapper, transform, opacity, mask, edgesExposed);
    126131}
    127132
Note: See TracChangeset for help on using the changeset viewer.