Diff
Modified: trunk/LayoutTests/ChangeLog (148089 => 148090)
--- trunk/LayoutTests/ChangeLog 2013-04-10 11:34:53 UTC (rev 148089)
+++ trunk/LayoutTests/ChangeLog 2013-04-10 11:48:32 UTC (rev 148090)
@@ -1,3 +1,20 @@
+2013-04-10 Noam Rosenthal <[email protected]>
+
+ [Texmap] Hierarchy of layers with opacity may result in wrong blending.
+ https://bugs.webkit.org/show_bug.cgi?id=113732
+
+ Reviewed by Allan Sandfeld Jensen.
+
+ 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.
+
2013-04-10 Antti Koivisto <[email protected]>
Create fewer tiles when page is loading
Added: trunk/LayoutTests/compositing/overlap-blending/nested-non-overlap-clipping-expected.html (0 => 148090)
--- trunk/LayoutTests/compositing/overlap-blending/nested-non-overlap-clipping-expected.html (rev 0)
+++ trunk/LayoutTests/compositing/overlap-blending/nested-non-overlap-clipping-expected.html 2013-04-10 11:48:32 UTC (rev 148090)
@@ -0,0 +1,27 @@
+<html>
+ <head>
+ <style>
+ div {
+ opacity: 0.5;
+ height: 50%;
+ width: 50%;
+ }
+
+ body > div > div {
+ background-color: green;
+ }
+
+ .composited {
+ width: 100%;
+ height: 50%;
+ }
+ </style>
+ </head>
+ <body>
+ <div><span></span>
+ <div><span></span>
+ <div class="composited"><span></span></div>
+ </div>
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/compositing/overlap-blending/nested-non-overlap-clipping.html (0 => 148090)
--- trunk/LayoutTests/compositing/overlap-blending/nested-non-overlap-clipping.html (rev 0)
+++ trunk/LayoutTests/compositing/overlap-blending/nested-non-overlap-clipping.html 2013-04-10 11:48:32 UTC (rev 148090)
@@ -0,0 +1,28 @@
+<html>
+ <head>
+ <style>
+ div {
+ opacity: 0.5;
+ height: 50%;
+ width: 50%;
+ }
+
+ body > div > div {
+ background-color: green;
+ }
+
+ .composited {
+ -webkit-transform: translateZ(0);
+ width: 100%;
+ height: 50%;
+ }
+ </style>
+ </head>
+ <body>
+ <div><span></span>
+ <div><span></span>
+ <div class="composited"><span></span></div>
+ </div>
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/compositing/overlap-blending/nested-overlap-expected.html (0 => 148090)
--- trunk/LayoutTests/compositing/overlap-blending/nested-overlap-expected.html (rev 0)
+++ trunk/LayoutTests/compositing/overlap-blending/nested-overlap-expected.html 2013-04-10 11:48:32 UTC (rev 148090)
@@ -0,0 +1,33 @@
+<html>
+ <head>
+ <style>
+ div {
+ width: 200px;
+ height: 200px;
+ }
+
+ span {
+ position: absolute;
+ opacity: 0;
+ }
+
+ .child {
+ opacity: 0.7;
+ background: green;
+ }
+ .container {
+ opacity: 0.7;
+ }
+ body > div {
+ opacity: 0.7;
+ }
+ </style>
+ </head>
+ <body>
+ <div><span></span>
+ <div class="container"><span></span>
+ <div class="child"><span></span></div>
+ </div>
+ </div>
+ </body>
+</html>
Added: trunk/LayoutTests/compositing/overlap-blending/nested-overlap.html (0 => 148090)
--- trunk/LayoutTests/compositing/overlap-blending/nested-overlap.html (rev 0)
+++ trunk/LayoutTests/compositing/overlap-blending/nested-overlap.html 2013-04-10 11:48:32 UTC (rev 148090)
@@ -0,0 +1,34 @@
+<html>
+ <head>
+ <style>
+ div {
+ -webkit-transform: translateZ(0);
+ width: 200px;
+ height: 200px;
+ }
+
+ span {
+ position: absolute;
+ opacity: 0;
+ }
+
+ .child {
+ opacity: 0.7;
+ background: green;
+ }
+ .container {
+ opacity: 0.7;
+ }
+ body > div {
+ opacity: 0.7;
+ }
+ </style>
+ </head>
+ <body>
+ <div><span></span>
+ <div class="container"><span></span>
+ <div class="child"><span></span></div>
+ </div>
+ </div>
+ </body>
+</html>
Modified: trunk/LayoutTests/platform/mac/TestExpectations (148089 => 148090)
--- trunk/LayoutTests/platform/mac/TestExpectations 2013-04-10 11:34:53 UTC (rev 148089)
+++ trunk/LayoutTests/platform/mac/TestExpectations 2013-04-10 11:48:32 UTC (rev 148090)
@@ -937,6 +937,10 @@
# https://bugs.webkit.org/show_bug.cgi?id=110871
compositing/overlap-blending/reflection-opacity-huge.html
+# https://bugs.webkit.org/show_bug.cgi?id=114340
+compositing/overlap-blending/nested-overlap.html
+compositing/overlap-blending/nested-non-overlap-clipping.html
+
# https://bugs.webkit.org/show_bug.cgi?id=95027
fast/block/float/016.html
Modified: trunk/Source/WebCore/ChangeLog (148089 => 148090)
--- trunk/Source/WebCore/ChangeLog 2013-04-10 11:34:53 UTC (rev 148089)
+++ trunk/Source/WebCore/ChangeLog 2013-04-10 11:48:32 UTC (rev 148090)
@@ -1,3 +1,38 @@
+2013-04-10 Noam Rosenthal <[email protected]>
+
+ [Texmap] Hierarchy of layers with opacity may result in wrong blending.
+ https://bugs.webkit.org/show_bug.cgi?id=113732
+
+ Reviewed by Allan Sandfeld Jensen.
+
+ 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.
+
2013-04-10 Antti Koivisto <[email protected]>
Create fewer tiles when page is loading
Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp (148089 => 148090)
--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp 2013-04-10 11:34:53 UTC (rev 148089)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp 2013-04-10 11:48:32 UTC (rev 148090)
@@ -174,9 +174,11 @@
context->deleteBuffer(it->value);
}
-void TextureMapperGL::ClipStack::reset(const IntRect& rect)
+void TextureMapperGL::ClipStack::reset(const IntRect& rect, TextureMapperGL::ClipStack::YAxisMode mode)
{
clipStack.clear();
+ size = rect.size();
+ yAxisMode = mode;
clipState = TextureMapperGL::ClipState(rect);
clipStateDirty = true;
}
@@ -208,19 +210,14 @@
clipStateDirty = true;
}
-static void scissorClip(GraphicsContext3D* context, const IntRect& rect)
+void TextureMapperGL::ClipStack::apply(GraphicsContext3D* context)
{
- if (rect.isEmpty())
+ if (clipState.scissorBox.isEmpty())
return;
- GC3Dint viewport[4];
- context->getIntegerv(GraphicsContext3D::VIEWPORT, viewport);
- context->scissor(rect.x(), viewport[3] - rect.maxY(), rect.width(), rect.height());
-}
-
-void TextureMapperGL::ClipStack::apply(GraphicsContext3D* context)
-{
- scissorClip(context, clipState.scissorBox);
+ context->scissor(clipState.scissorBox.x(),
+ (yAxisMode == InvertedYAxis) ? size.height() - clipState.scissorBox.maxY() : clipState.scissorBox.y(),
+ clipState.scissorBox.width(), clipState.scissorBox.height());
context->stencilOp(GraphicsContext3D::KEEP, GraphicsContext3D::KEEP, GraphicsContext3D::KEEP);
context->stencilFunc(GraphicsContext3D::EQUAL, clipState.stencilIndex - 1, clipState.stencilIndex - 1);
if (clipState.stencilIndex == 1)
@@ -238,7 +235,6 @@
apply(context);
}
-
void TextureMapperGLData::initializeStencil()
{
if (currentSurface) {
@@ -293,7 +289,7 @@
m_context3D->depthMask(0);
m_context3D->getIntegerv(GraphicsContext3D::VIEWPORT, data().viewport);
m_context3D->getIntegerv(GraphicsContext3D::SCISSOR_BOX, data().previousScissor);
- m_clipStack.reset(IntRect(0, 0, data().viewport[2], data().viewport[3]));
+ m_clipStack.reset(IntRect(0, 0, data().viewport[2], data().viewport[3]), ClipStack::InvertedYAxis);
m_context3D->getIntegerv(GraphicsContext3D::FRAMEBUFFER_BINDING, &data().targetFrameBuffer);
data().PaintFlags = flags;
bindSurface(0);
@@ -1040,7 +1036,7 @@
if (!m_shouldClear)
return;
- m_clipStack.reset(IntRect(IntPoint::zero(), m_textureSize));
+ m_clipStack.reset(IntRect(IntPoint::zero(), m_textureSize), TextureMapperGL::ClipStack::DefaultYAxis);
m_clipStack.applyIfNeeded(m_context3D.get());
m_context3D->clearColor(0, 0, 0, 0);
m_context3D->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h (148089 => 148090)
--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h 2013-04-10 11:34:53 UTC (rev 148089)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h 2013-04-10 11:48:32 UTC (rev 148090)
@@ -94,12 +94,18 @@
: clipStateDirty(false)
{ }
+ // Y-axis should be inverted only when painting into the window.
+ enum YAxisMode {
+ DefaultYAxis,
+ InvertedYAxis
+ };
+
void push();
void pop();
void apply(GraphicsContext3D*);
void applyIfNeeded(GraphicsContext3D*);
inline ClipState& current() { return clipState; }
- void reset(const IntRect&);
+ void reset(const IntRect&, YAxisMode);
void intersect(const IntRect&);
void setStencilIndex(int);
inline int getStencilIndex() const
@@ -115,6 +121,8 @@
ClipState clipState;
Vector<ClipState> clipStack;
bool clipStateDirty;
+ IntSize size;
+ YAxisMode yAxisMode;
};
TextureMapperGL();
Modified: trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp (148089 => 148090)
--- trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp 2013-04-10 11:34:53 UTC (rev 148089)
+++ trunk/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp 2013-04-10 11:48:32 UTC (rev 148090)
@@ -156,8 +156,13 @@
return;
bool shouldClip = m_state.masksToBounds && !m_state.preserves3D;
- if (shouldClip)
- options.textureMapper->beginClip(TransformationMatrix(options.transform).multiply(m_currentTransform.combined()), layerRect());
+ if (shouldClip) {
+ TransformationMatrix clipTransform;
+ clipTransform.translate(options.offset.width(), options.offset.height());
+ clipTransform.multiply(options.transform);
+ clipTransform.multiply(m_currentTransform.combined());
+ options.textureMapper->beginClip(clipTransform, layerRect());
+ }
for (size_t i = 0; i < m_children.size(); ++i)
m_children[i]->paintRecursive(options);
@@ -333,7 +338,10 @@
return;
}
- Vector<IntRect> rects = nonOverlapRegion.rects();
+ Vector<IntRect> rects;
+
+ nonOverlapRegion.translate(options.offset);
+ rects = nonOverlapRegion.rects();
for (size_t i = 0; i < rects.size(); ++i) {
options.textureMapper->beginClip(TransformationMatrix(), rects[i]);
paintSelfAndChildrenWithReplica(options);
@@ -365,8 +373,10 @@
PassRefPtr<BitmapTexture> TextureMapperLayer::paintIntoSurface(const TextureMapperPaintOptions& options, const IntSize& size)
{
RefPtr<BitmapTexture> surface = options.textureMapper->acquireTextureFromPool(size);
+ TextureMapperPaintOptions paintOptions(options);
+ paintOptions.surface = surface;
options.textureMapper->bindSurface(surface.get());
- paintSelfAndChildren(options);
+ paintSelfAndChildren(paintOptions);
if (m_state.maskLayer)
m_state.maskLayer->applyMask(options);
#if ENABLE(CSS_FILTERS)