Changeset 148090 in webkit


Ignore:
Timestamp:
Apr 10, 2013 4:48:32 AM (11 years ago)
Author:
commit-queue@webkit.org
Message:

[Texmap] Hierarchy of layers with opacity may result in wrong blending.
https://bugs.webkit.org/show_bug.cgi?id=113732

Patch by Noam Rosenthal <Noam Rosenthal> on 2013-04-10
Reviewed by Allan Sandfeld Jensen.

Source/WebCore:

This is a combination of three issues with nested intermediate surfaces:

  • glScissor inside an intermediate surface should not be mirrored.
  • The current surface should be passed to the next surface in paintOptions.
  • When clipping for the non-overlap region, the containing surface offset

should be applied.

Though the changes are separate, they cannot be tested separately as neither
fixes a testable case on its own.

Tests: compositing/overlap-blending/nested-non-overlap-clipping.html

compositing/overlap-blending/nested-overlap.html

  • platform/graphics/texmap/TextureMapperGL.cpp:

(WebCore::TextureMapperGL::ClipStack::reset):
(WebCore::TextureMapperGL::ClipStack::apply):
(WebCore::TextureMapperGL::beginPainting):
(WebCore::BitmapTextureGL::clearIfNeeded):

  • platform/graphics/texmap/TextureMapperGL.h:

(ClipStack):

Do not mirror the scissor clip when painting to an FBO.
Also a minor refactor to avoid reading the viewport values from the driver.

  • platform/graphics/texmap/TextureMapperLayer.cpp:

(WebCore::TextureMapperLayer::paintUsingOverlapRegions):

Apply the offset when clipping for a non-overlap region.

(WebCore::TextureMapperLayer::paintIntoSurface):

Make sure the current surface is passed to the next one.

LayoutTests:

Added two ref-tests for nested composited overlaps.
This ref-test does not work on Mac due to a slight mismatch opacity value on CoreAnimation.
A new bug has been posted, and TestExpectations has been updated.

  • compositing/overlap-blending/nested-non-overlap-clipping-expected.html: Added.
  • compositing/overlap-blending/nested-non-overlap-clipping.html: Added.
  • compositing/overlap-blending/nested-overlap-expected.html: Added.
  • compositing/overlap-blending/nested-overlap.html: Added.
  • platform/mac/TestExpectations: Skipped new tests and created bug.
Location:
trunk
Files:
4 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r148089 r148090  
     12013-04-10  Noam Rosenthal  <noam@webkit.org>
     2
     3        [Texmap] Hierarchy of layers with opacity may result in wrong blending.
     4        https://bugs.webkit.org/show_bug.cgi?id=113732
     5
     6        Reviewed by Allan Sandfeld Jensen.
     7
     8        Added two ref-tests for nested composited overlaps.
     9        This ref-test does not work on Mac due to a slight mismatch opacity value on CoreAnimation.
     10        A new bug has been posted, and TestExpectations has been updated.
     11
     12        * compositing/overlap-blending/nested-non-overlap-clipping-expected.html: Added.
     13        * compositing/overlap-blending/nested-non-overlap-clipping.html: Added.
     14        * compositing/overlap-blending/nested-overlap-expected.html: Added.
     15        * compositing/overlap-blending/nested-overlap.html: Added.
     16        * platform/mac/TestExpectations: Skipped new tests and created bug.
     17
    1182013-04-10  Antti Koivisto  <antti@apple.com>
    219
  • trunk/LayoutTests/platform/mac/TestExpectations

    r148076 r148090  
    937937# https://bugs.webkit.org/show_bug.cgi?id=110871
    938938compositing/overlap-blending/reflection-opacity-huge.html
     939
     940# https://bugs.webkit.org/show_bug.cgi?id=114340
     941compositing/overlap-blending/nested-overlap.html
     942compositing/overlap-blending/nested-non-overlap-clipping.html
    939943
    940944# https://bugs.webkit.org/show_bug.cgi?id=95027
  • trunk/Source/WebCore/ChangeLog

    r148089 r148090  
     12013-04-10  Noam Rosenthal  <noam@webkit.org>
     2
     3        [Texmap] Hierarchy of layers with opacity may result in wrong blending.
     4        https://bugs.webkit.org/show_bug.cgi?id=113732
     5
     6        Reviewed by Allan Sandfeld Jensen.
     7
     8        This is a combination of three issues with nested intermediate surfaces:
     9        - glScissor inside an intermediate surface should not be mirrored.
     10        - The current surface should be passed to the next surface in paintOptions.
     11        - When clipping for the non-overlap region, the containing surface offset
     12        should be applied.
     13
     14        Though the changes are separate, they cannot be tested separately as neither
     15        fixes a testable case on its own.
     16
     17        Tests: compositing/overlap-blending/nested-non-overlap-clipping.html
     18               compositing/overlap-blending/nested-overlap.html
     19
     20        * platform/graphics/texmap/TextureMapperGL.cpp:
     21        (WebCore::TextureMapperGL::ClipStack::reset):
     22        (WebCore::TextureMapperGL::ClipStack::apply):
     23        (WebCore::TextureMapperGL::beginPainting):
     24        (WebCore::BitmapTextureGL::clearIfNeeded):
     25        * platform/graphics/texmap/TextureMapperGL.h:
     26        (ClipStack):
     27            Do not mirror the scissor clip when painting to an FBO.
     28            Also a minor refactor to avoid reading the viewport values from the driver.
     29
     30        * platform/graphics/texmap/TextureMapperLayer.cpp:
     31        (WebCore::TextureMapperLayer::paintUsingOverlapRegions):
     32            Apply the offset when clipping for a non-overlap region.
     33        (WebCore::TextureMapperLayer::paintIntoSurface):
     34            Make sure the current surface is passed to the next one.
     35
    1362013-04-10  Antti Koivisto  <antti@apple.com>
    237
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp

    r147742 r148090  
    175175}
    176176
    177 void TextureMapperGL::ClipStack::reset(const IntRect& rect)
     177void TextureMapperGL::ClipStack::reset(const IntRect& rect, TextureMapperGL::ClipStack::YAxisMode mode)
    178178{
    179179    clipStack.clear();
     180    size = rect.size();
     181    yAxisMode = mode;
    180182    clipState = TextureMapperGL::ClipState(rect);
    181183    clipStateDirty = true;
     
    209211}
    210212
    211 static void scissorClip(GraphicsContext3D* context, const IntRect& rect)
    212 {
    213     if (rect.isEmpty())
    214         return;
    215 
    216     GC3Dint viewport[4];
    217     context->getIntegerv(GraphicsContext3D::VIEWPORT, viewport);
    218     context->scissor(rect.x(), viewport[3] - rect.maxY(), rect.width(), rect.height());
    219 }
    220 
    221213void TextureMapperGL::ClipStack::apply(GraphicsContext3D* context)
    222214{
    223     scissorClip(context, clipState.scissorBox);
     215    if (clipState.scissorBox.isEmpty())
     216        return;
     217
     218    context->scissor(clipState.scissorBox.x(),
     219        (yAxisMode == InvertedYAxis) ? size.height() - clipState.scissorBox.maxY() : clipState.scissorBox.y(),
     220        clipState.scissorBox.width(), clipState.scissorBox.height());
    224221    context->stencilOp(GraphicsContext3D::KEEP, GraphicsContext3D::KEEP, GraphicsContext3D::KEEP);
    225222    context->stencilFunc(GraphicsContext3D::EQUAL, clipState.stencilIndex - 1, clipState.stencilIndex - 1);
     
    238235    apply(context);
    239236}
    240 
    241237
    242238void TextureMapperGLData::initializeStencil()
     
    294290    m_context3D->getIntegerv(GraphicsContext3D::VIEWPORT, data().viewport);
    295291    m_context3D->getIntegerv(GraphicsContext3D::SCISSOR_BOX, data().previousScissor);
    296     m_clipStack.reset(IntRect(0, 0, data().viewport[2], data().viewport[3]));
     292    m_clipStack.reset(IntRect(0, 0, data().viewport[2], data().viewport[3]), ClipStack::InvertedYAxis);
    297293    m_context3D->getIntegerv(GraphicsContext3D::FRAMEBUFFER_BINDING, &data().targetFrameBuffer);
    298294    data().PaintFlags = flags;
     
    10411037        return;
    10421038
    1043     m_clipStack.reset(IntRect(IntPoint::zero(), m_textureSize));
     1039    m_clipStack.reset(IntRect(IntPoint::zero(), m_textureSize), TextureMapperGL::ClipStack::DefaultYAxis);
    10441040    m_clipStack.applyIfNeeded(m_context3D.get());
    10451041    m_context3D->clearColor(0, 0, 0, 0);
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h

    r146640 r148090  
    9595        { }
    9696
     97        // Y-axis should be inverted only when painting into the window.
     98        enum YAxisMode {
     99            DefaultYAxis,
     100            InvertedYAxis
     101        };
     102
    97103        void push();
    98104        void pop();
     
    100106        void applyIfNeeded(GraphicsContext3D*);
    101107        inline ClipState& current() { return clipState; }
    102         void reset(const IntRect&);
     108        void reset(const IntRect&, YAxisMode);
    103109        void intersect(const IntRect&);
    104110        void setStencilIndex(int);
     
    116122        Vector<ClipState> clipStack;
    117123        bool clipStateDirty;
     124        IntSize size;
     125        YAxisMode yAxisMode;
    118126    };
    119127
  • trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp

    r148020 r148090  
    157157
    158158    bool shouldClip = m_state.masksToBounds && !m_state.preserves3D;
    159     if (shouldClip)
    160         options.textureMapper->beginClip(TransformationMatrix(options.transform).multiply(m_currentTransform.combined()), layerRect());
     159    if (shouldClip) {
     160        TransformationMatrix clipTransform;
     161        clipTransform.translate(options.offset.width(), options.offset.height());
     162        clipTransform.multiply(options.transform);
     163        clipTransform.multiply(m_currentTransform.combined());
     164        options.textureMapper->beginClip(clipTransform, layerRect());
     165    }
    161166
    162167    for (size_t i = 0; i < m_children.size(); ++i)
     
    334339    }
    335340
    336     Vector<IntRect> rects = nonOverlapRegion.rects();
     341    Vector<IntRect> rects;
     342
     343    nonOverlapRegion.translate(options.offset);
     344    rects = nonOverlapRegion.rects();
    337345    for (size_t i = 0; i < rects.size(); ++i) {
    338346        options.textureMapper->beginClip(TransformationMatrix(), rects[i]);
     
    366374{
    367375    RefPtr<BitmapTexture> surface = options.textureMapper->acquireTextureFromPool(size);
     376    TextureMapperPaintOptions paintOptions(options);
     377    paintOptions.surface = surface;
    368378    options.textureMapper->bindSurface(surface.get());
    369     paintSelfAndChildren(options);
     379    paintSelfAndChildren(paintOptions);
    370380    if (m_state.maskLayer)
    371381        m_state.maskLayer->applyMask(options);
Note: See TracChangeset for help on using the changeset viewer.