Created
April 9, 2013 12:51
-
-
Save noamr/5345472 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 9d43fe8d9d79a4d7b7c9cc4953aa465df8a26ed2 | |
Author: Noam Rosenthal <[email protected]> | |
Date: Tue Apr 9 14:50:43 2013 +0200 | |
WIP overlap clipping | |
diff --git a/LayoutTests/compositing/overlap-blending/nested-overlap-outline.html b/LayoutTests/compositing/overlap-blending/nested-overlap-outline.html | |
new file mode 100644 | |
index 0000000..4c14f0a | |
--- /dev/null | |
+++ b/LayoutTests/compositing/overlap-blending/nested-overlap-outline.html | |
@@ -0,0 +1,26 @@ | |
+<html> | |
+ <head> | |
+ <style> | |
+ div { | |
+ opacity: 0.5; | |
+ -webkit-transform: translateZ(0); | |
+ border-radius: 10px; | |
+ outline: solid 5px green; | |
+ width: 60%; | |
+ height: 50%; | |
+ margin: 0; | |
+ } | |
+ | |
+ body > div { | |
+ width: 500px; height: 500px; | |
+ } | |
+ </style> | |
+ </head> | |
+ <body> | |
+ <div> | |
+ <div> | |
+ <div></div> | |
+ </div> | |
+ </div> | |
+ </body> | |
+</html> | |
\ No newline at end of file | |
diff --git a/LayoutTests/compositing/overlap-blending/nested-overlap-overflow.html b/LayoutTests/compositing/overlap-blending/nested-overlap-overflow.html | |
new file mode 100644 | |
index 0000000..5186725 | |
--- /dev/null | |
+++ b/LayoutTests/compositing/overlap-blending/nested-overlap-overflow.html | |
@@ -0,0 +1,36 @@ | |
+<!DOCTYPE html> | |
+<html> | |
+ <head> | |
+ <style> | |
+ div { | |
+ opacity: 0.8; | |
+ -webkit-transform: translateZ(0px); | |
+ border-radius: 1px; | |
+ } | |
+ body > div > div > div { | |
+ width: 150px; | |
+ height: 150px; | |
+ margin-left: -10px; | |
+ position: relative; | |
+ top: 0; | |
+ background: green; | |
+ } | |
+ body > div { | |
+ height: 100px; | |
+ overflow: hidden; | |
+ } | |
+ body > div > div { | |
+ width: 200px; | |
+ height: 200px; | |
+ position: absolute; | |
+ } | |
+ </style> | |
+ </head> | |
+ <body> | |
+ <div> | |
+ <div> | |
+ <div></div> | |
+ </div> | |
+ </div> | |
+ </body> | |
+</html> | |
diff --git a/LayoutTests/compositing/overlap-blending/nested-overlap.html b/LayoutTests/compositing/overlap-blending/nested-overlap.html | |
new file mode 100644 | |
index 0000000..1c0222f | |
--- /dev/null | |
+++ b/LayoutTests/compositing/overlap-blending/nested-overlap.html | |
@@ -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> | |
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp | |
index 3142015..7621595 100644 | |
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp | |
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.cpp | |
@@ -179,6 +179,7 @@ TextureMapperGLData::~TextureMapperGLData() | |
void TextureMapperGL::ClipStack::reset(const IntRect& rect) | |
{ | |
clipStack.clear(); | |
+ size = rect.size(); | |
clipState = TextureMapperGL::ClipState(rect); | |
clipStateDirty = true; | |
} | |
@@ -210,19 +211,13 @@ void TextureMapperGL::ClipStack::pop() | |
clipStateDirty = true; | |
} | |
-static void scissorClip(GraphicsContext3D* context, const IntRect& rect) | |
-{ | |
- if (rect.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); | |
+ if (clipState.scissorBox.isEmpty()) | |
+ context->scissor(0, 0, size.width(), size.height()); | |
+ else | |
+ context->scissor(clipState.scissorBox.x(), size.height() - clipState.scissorBox.maxY(), 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) | |
@@ -233,6 +228,7 @@ void TextureMapperGL::ClipStack::apply(GraphicsContext3D* context) | |
void TextureMapperGL::ClipStack::applyIfNeeded(GraphicsContext3D* context) | |
{ | |
+ clipStateDirty = true; | |
if (!clipStateDirty) | |
return; | |
@@ -240,7 +236,6 @@ void TextureMapperGL::ClipStack::applyIfNeeded(GraphicsContext3D* context) | |
apply(context); | |
} | |
- | |
void TextureMapperGLData::initializeStencil() | |
{ | |
if (currentSurface) { | |
@@ -1075,7 +1070,7 @@ void BitmapTextureGL::bind(TextureMapperGL* textureMapper) | |
m_context3D->viewport(0, 0, m_textureSize.width(), m_textureSize.height()); | |
clearIfNeeded(); | |
textureMapper->data().projectionMatrix = createProjectionMatrix(m_textureSize, true /* mirrored */); | |
- m_clipStack.applyIfNeeded(m_context3D.get()); | |
+ m_clipStack.apply(m_context3D.get()); | |
} | |
BitmapTextureGL::~BitmapTextureGL() | |
@@ -1136,14 +1131,11 @@ bool TextureMapperGL::beginScissorClip(const TransformationMatrix& modelViewMatr | |
if (!modelViewMatrix.isAffine()) | |
return false; | |
- FloatQuad quad = modelViewMatrix.projectQuad(targetRect); | |
- IntRect rect = quad.enclosingBoundingBox(); | |
- | |
- // Only use scissors on rectilinear clips. | |
- if (!quad.isRectilinear() || rect.isEmpty()) | |
+ FloatRect rect = modelViewMatrix.mapRect(targetRect); | |
+ if (rect.isEmpty() || !rect.isExpressibleAsIntRect()) | |
return false; | |
- clipStack().intersect(rect); | |
+ clipStack().intersect(IntRect(rect)); | |
clipStack().applyIfNeeded(m_context3D.get()); | |
return true; | |
} | |
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h | |
index e7d7982..086bacd 100644 | |
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h | |
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperGL.h | |
@@ -115,6 +115,7 @@ private: | |
ClipState clipState; | |
Vector<ClipState> clipStack; | |
bool clipStateDirty; | |
+ IntSize size; | |
}; | |
TextureMapperGL(); | |
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp | |
index 61e975f..d5df3ae 100644 | |
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp | |
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp | |
@@ -157,8 +157,13 @@ void TextureMapperLayer::paintSelfAndChildren(const TextureMapperPaintOptions& o | |
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); | |
@@ -335,13 +340,9 @@ void TextureMapperLayer::paintUsingOverlapRegions(const TextureMapperPaintOption | |
return; | |
} | |
- Vector<IntRect> rects = nonOverlapRegion.rects(); | |
- for (size_t i = 0; i < rects.size(); ++i) { | |
- options.textureMapper->beginClip(TransformationMatrix(), rects[i]); | |
- paintSelfAndChildrenWithReplica(options); | |
- options.textureMapper->endClip(); | |
- } | |
+ Vector<IntRect> rects; | |
+ nonOverlapRegion.translate(options.offset); | |
rects = overlapRegion.rects(); | |
IntSize maxTextureSize = options.textureMapper->maxTextureSize(); | |
for (size_t i = 0; i < rects.size(); ++i) { | |
@@ -354,6 +355,14 @@ void TextureMapperLayer::paintUsingOverlapRegions(const TextureMapperPaintOption | |
} | |
} | |
} | |
+ | |
+ rects = nonOverlapRegion.rects(); | |
+ for (size_t i = 0; i < rects.size(); ++i) { | |
+ options.textureMapper->beginClip(TransformationMatrix(), rects[i]); | |
+ paintSelfAndChildrenWithReplica(options); | |
+ options.textureMapper->endClip(); | |
+ } | |
+ | |
} | |
void TextureMapperLayer::applyMask(const TextureMapperPaintOptions& options) | |
@@ -366,8 +375,10 @@ void TextureMapperLayer::applyMask(const TextureMapperPaintOptions& options) | |
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) | |
@@ -378,14 +389,14 @@ PassRefPtr<BitmapTexture> TextureMapperLayer::paintIntoSurface(const TextureMapp | |
return surface; | |
} | |
-static PassRefPtr<BitmapTexture> commitSurface(const TextureMapperPaintOptions& options, PassRefPtr<BitmapTexture> surface, const IntRect& rect, float opacity) | |
+static void commitSurface(const TextureMapperPaintOptions& options, PassRefPtr<BitmapTexture> surface, const IntRect& rect, float opacity) | |
{ | |
options.textureMapper->bindSurface(options.surface.get()); | |
TransformationMatrix targetTransform; | |
targetTransform.translate(options.offset.width(), options.offset.height()); | |
targetTransform.multiply(options.transform); | |
options.textureMapper->drawTexture(*surface.get(), rect, targetTransform, opacity); | |
- return 0; | |
+ options.textureMapper->drawBorder(Color(255, 0, 0, 255), 5, rect, targetTransform); | |
} | |
void TextureMapperLayer::paintWithIntermediateSurface(const TextureMapperPaintOptions& options, const IntRect& rect) | |
@@ -404,8 +415,10 @@ void TextureMapperLayer::paintWithIntermediateSurface(const TextureMapperPaintOp | |
m_state.replicaLayer->m_state.maskLayer->applyMask(paintOptions); | |
} | |
- if (replicaSurface && options.opacity == 1) | |
- replicaSurface = commitSurface(options, replicaSurface, rect, 1); | |
+ if (replicaSurface && options.opacity == 1) { | |
+ commitSurface(options, replicaSurface, rect, 1); | |
+ replicaSurface.clear(); | |
+ } | |
mainSurface = paintIntoSurface(paintOptions, rect.size()); | |
if (replicaSurface) { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment