summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/RenderLayer.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-02-03 09:55:33 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-02-03 09:55:33 +0100
commitcd44dc59cdfc39534aef4d417e9f3c412e3be139 (patch)
tree8d89889ba95ed6ec9322e733846cc9cce9d7dff1 /Source/WebCore/rendering/RenderLayer.cpp
parentd11f84f5b5cdc0d92a08af01b13472fdd5f9acb9 (diff)
downloadqtwebkit-cd44dc59cdfc39534aef4d417e9f3c412e3be139.tar.gz
Imported WebKit commit fce473cb4d55aa9fe9d0b0322a2fffecb731b961 (http://svn.webkit.org/repository/webkit/trunk@106560)
Diffstat (limited to 'Source/WebCore/rendering/RenderLayer.cpp')
-rw-r--r--Source/WebCore/rendering/RenderLayer.cpp369
1 files changed, 181 insertions, 188 deletions
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index 90915a3d9..d06b30d7d 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -45,8 +45,8 @@
#include "RenderLayer.h"
#include "ColumnInfo.h"
+#include "CSSMutableStyleDeclaration.h"
#include "CSSPropertyNames.h"
-#include "CSSStyleDeclaration.h"
#include "CSSStyleSelector.h"
#include "Chrome.h"
#include "Document.h"
@@ -451,12 +451,13 @@ void RenderLayer::clearRepaintRects()
void RenderLayer::updateLayerPositionsAfterScroll(UpdateLayerPositionsAfterScrollFlags flags)
{
+ ASSERT(!m_visibleDescendantStatusDirty);
ASSERT(!m_visibleContentStatusDirty);
- // If we have no visible content, there is no point recomputing our rectangles as
- // they will be empty. If our visibility changes, we are expected to recompute all
- // our positions anyway.
- if (!m_hasVisibleContent)
+ // If we have no visible content and no visible descendants, there is no point recomputing
+ // our rectangles as they will be empty. If our visibility changes, we are expected to
+ // recompute all our positions anyway.
+ if (!m_hasVisibleDescendant && !m_hasVisibleContent)
return;
updateLayerPosition();
@@ -1045,24 +1046,29 @@ static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLaye
return clipRect;
}
-void RenderLayer::beginTransparencyLayers(GraphicsContext* p, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
+LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
{
- if (p->paintingDisabled() || (paintsWithTransparency(paintBehavior) && m_usedTransparency))
+ return intersection(transparencyClipBox(this, rootLayer, paintBehavior), paintDirtyRect);
+}
+
+void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
+{
+ if (context->paintingDisabled() || (paintsWithTransparency(paintBehavior) && m_usedTransparency))
return;
RenderLayer* ancestor = transparentPaintingAncestor();
if (ancestor)
- ancestor->beginTransparencyLayers(p, rootLayer, paintBehavior);
+ ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
if (paintsWithTransparency(paintBehavior)) {
m_usedTransparency = true;
- p->save();
- LayoutRect clipRect = transparencyClipBox(this, rootLayer, paintBehavior);
- p->clip(clipRect);
- p->beginTransparencyLayer(renderer()->opacity());
+ context->save();
+ LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBehavior);
+ context->clip(clipRect);
+ context->beginTransparencyLayer(renderer()->opacity());
#ifdef REVEAL_TRANSPARENCY_LAYERS
- p->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f), ColorSpaceDeviceRGB);
- p->fillRect(clipRect);
+ context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f), ColorSpaceDeviceRGB);
+ context->fillRect(clipRect);
#endif
}
}
@@ -1700,31 +1706,30 @@ void RenderLayer::resize(const PlatformMouseEvent& evt, const LayoutSize& oldOff
LayoutSize difference = (currentSize + newOffset - adjustedOldOffset).expandedTo(minimumSize) - currentSize;
- CSSStyleDeclaration* style = element->style();
+ ASSERT(element->isStyledElement());
+ CSSMutableStyleDeclaration* styleDeclaration = static_cast<StyledElement*>(element)->ensureInlineStyleDecl();
bool isBoxSizingBorder = renderer->style()->boxSizing() == BORDER_BOX;
- ExceptionCode ec;
-
if (resize != RESIZE_VERTICAL && difference.width()) {
if (element->isFormControlElement()) {
// Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
- style->setProperty(CSSPropertyMarginLeft, String::number(renderer->marginLeft() / zoomFactor) + "px", false, ec);
- style->setProperty(CSSPropertyMarginRight, String::number(renderer->marginRight() / zoomFactor) + "px", false, ec);
+ styleDeclaration->setProperty(CSSPropertyMarginLeft, String::number(renderer->marginLeft() / zoomFactor) + "px", false);
+ styleDeclaration->setProperty(CSSPropertyMarginRight, String::number(renderer->marginRight() / zoomFactor) + "px", false);
}
LayoutUnit baseWidth = renderer->width() - (isBoxSizingBorder ? 0 : renderer->borderAndPaddingWidth());
baseWidth = baseWidth / zoomFactor;
- style->setProperty(CSSPropertyWidth, String::number(baseWidth + difference.width()) + "px", false, ec);
+ styleDeclaration->setProperty(CSSPropertyWidth, String::number(baseWidth + difference.width()) + "px", false);
}
if (resize != RESIZE_HORIZONTAL && difference.height()) {
if (element->isFormControlElement()) {
// Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
- style->setProperty(CSSPropertyMarginTop, String::number(renderer->marginTop() / zoomFactor) + "px", false, ec);
- style->setProperty(CSSPropertyMarginBottom, String::number(renderer->marginBottom() / zoomFactor) + "px", false, ec);
+ styleDeclaration->setProperty(CSSPropertyMarginTop, String::number(renderer->marginTop() / zoomFactor) + "px", false);
+ styleDeclaration->setProperty(CSSPropertyMarginBottom, String::number(renderer->marginBottom() / zoomFactor) + "px", false);
}
LayoutUnit baseHeight = renderer->height() - (isBoxSizingBorder ? 0 : renderer->borderAndPaddingHeight());
baseHeight = baseHeight / zoomFactor;
- style->setProperty(CSSPropertyHeight, String::number(baseHeight + difference.height()) + "px", false, ec);
+ styleDeclaration->setProperty(CSSPropertyHeight, String::number(baseHeight + difference.height()) + "px", false);
}
document->updateLayout();
@@ -2286,6 +2291,7 @@ void RenderLayer::updateScrollInfoAfterLayout()
return;
m_scrollDimensionsDirty = true;
+ IntSize scrollOffsetOriginal(scrollXOffset(), scrollYOffset());
bool horizontalOverflow, verticalOverflow;
computeScrollDimensions(&horizontalOverflow, &verticalOverflow);
@@ -2368,8 +2374,9 @@ void RenderLayer::updateScrollInfoAfterLayout()
m_vBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
m_vBar->setProportion(clientHeight, m_scrollSize.height());
}
-
- scrollToOffset(scrollXOffset(), scrollYOffset());
+
+ if (scrollOffsetOriginal != scrollOffset())
+ scrollToOffsetWithoutAnimation(LayoutPoint(scrollXOffset(), scrollYOffset()));
if (renderer()->node() && renderer()->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
updateOverflowStatus(horizontalOverflow, verticalOverflow);
@@ -2552,7 +2559,7 @@ bool RenderLayer::hitTestOverflowControls(HitTestResult& result, const LayoutPoi
int resizeControlSize = max(resizeControlRect.height(), 0);
- if (m_vBar) {
+ if (m_vBar && m_vBar->shouldParticipateInHitTesting()) {
LayoutRect vBarRect(box->width() - box->borderRight() - m_vBar->width(),
box->borderTop(),
m_vBar->width(),
@@ -2564,7 +2571,7 @@ bool RenderLayer::hitTestOverflowControls(HitTestResult& result, const LayoutPoi
}
resizeControlSize = max(resizeControlRect.width(), 0);
- if (m_hBar) {
+ if (m_hBar && m_hBar->shouldParticipateInHitTesting()) {
LayoutRect hBarRect(box->borderLeft(),
box->height() - box->borderBottom() - m_hBar->height(),
box->width() - (box->borderLeft() + box->borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize),
@@ -2583,21 +2590,20 @@ bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularit
return ScrollableArea::scroll(direction, granularity, multiplier);
}
-void RenderLayer::paint(GraphicsContext* p, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject *paintingRoot,
- RenderRegion* region, PaintLayerFlags paintFlags)
+void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot, RenderRegion* region, PaintLayerFlags paintFlags)
{
OverlapTestRequestMap overlapTestRequests;
- paintLayer(this, p, damageRect, paintBehavior, paintingRoot, region, &overlapTestRequests, paintFlags);
+ paintLayer(this, context, damageRect, paintBehavior, paintingRoot, region, &overlapTestRequests, paintFlags);
OverlapTestRequestMap::iterator end = overlapTestRequests.end();
for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it)
it->first->setOverlapTestResult(false);
}
-void RenderLayer::paintOverlayScrollbars(GraphicsContext* p, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject *paintingRoot)
+void RenderLayer::paintOverlayScrollbars(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot)
{
if (!m_containsDirtyOverlayScrollbars)
return;
- paintLayer(this, p, damageRect, paintBehavior, paintingRoot, 0, 0, PaintLayerHaveTransparency | PaintLayerTemporaryClipRects
+ paintLayer(this, context, damageRect, paintBehavior, paintingRoot, 0, 0, PaintLayerHaveTransparency | PaintLayerTemporaryClipRects
| PaintLayerPaintingOverlayScrollbars);
m_containsDirtyOverlayScrollbars = false;
}
@@ -2646,11 +2652,11 @@ void RenderLayer::clipToRect(RenderLayer* rootLayer, GraphicsContext* context, c
#endif
}
-void RenderLayer::restoreClip(GraphicsContext* p, const LayoutRect& paintDirtyRect, const ClipRect& clipRect)
+void RenderLayer::restoreClip(GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect)
{
if (clipRect.rect() == paintDirtyRect)
return;
- p->restore();
+ context->restore();
}
static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, const RenderLayer* rootLayer, const RenderLayer* layer)
@@ -2693,11 +2699,24 @@ static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
}
-void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
+void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* context,
const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior,
RenderObject* paintingRoot, RenderRegion* region, OverlapTestRequestMap* overlapTestRequests,
PaintLayerFlags paintFlags)
{
+#if USE(ACCELERATED_COMPOSITING)
+ if (isComposited()) {
+ // The updatingControlTints() painting pass goes through compositing layers,
+ // but we need to ensure that we don't cache clip rects computed with the wrong root in this case.
+ if (context->updatingControlTints() || (paintBehavior & PaintBehaviorFlattenCompositingLayers))
+ paintFlags |= PaintLayerTemporaryClipRects;
+ else if (!backing()->paintingGoesToWindow() && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)) {
+ // If this RenderLayer should paint into its backing, that will be done via RenderLayerBacking::paintIntoLayer().
+ return;
+ }
+ }
+#endif
+
if (shouldSuppressPaintingLayer(this))
return;
@@ -2708,6 +2727,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
if (paintsWithTransparency(paintBehavior))
paintFlags |= PaintLayerHaveTransparency;
+ // PaintLayerAppliedTransform is used in RenderReplica, to avoid applying the transform twice.
if (paintsWithTransform(paintBehavior) && !(paintFlags & PaintLayerAppliedTransform)) {
TransformationMatrix layerTransform = renderableTransform(paintBehavior);
// If the transform can't be inverted, then don't paint anything.
@@ -2718,9 +2738,9 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// layer from the parent now, assuming there is a parent
if (paintFlags & PaintLayerHaveTransparency) {
if (parent())
- parent()->beginTransparencyLayers(p, rootLayer, paintBehavior);
+ parent()->beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
else
- beginTransparencyLayers(p, rootLayer, paintBehavior);
+ beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
}
// Make sure the parent's clip rects have been calculated.
@@ -2730,7 +2750,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
clipRect.intersect(paintDirtyRect);
// Push the parent coordinate space's clip.
- parent()->clipToRect(rootLayer, p, paintDirtyRect, clipRect);
+ parent()->clipToRect(rootLayer, context, paintDirtyRect, clipRect);
}
// Adjust the transform such that the renderer's upper left corner will paint at (0,0) in user space.
@@ -2742,103 +2762,49 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
// Apply the transform.
{
- GraphicsContextStateSaver stateSaver(*p);
- p->concatCTM(transform.toAffineTransform());
+ GraphicsContextStateSaver stateSaver(*context);
+ context->concatCTM(transform.toAffineTransform());
// Now do a paint with the root layer shifted to be us.
- paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags | PaintLayerAppliedTransform);
+ paintLayerContentsAndReflection(this, context, transform.inverse().mapRect(paintDirtyRect), paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
}
// Restore the clip.
if (parent())
- parent()->restoreClip(p, paintDirtyRect, clipRect);
+ parent()->restoreClip(context, paintDirtyRect, clipRect);
return;
}
-#if ENABLE(CSS_FILTERS)
- if (paintsWithFilters() && !(paintFlags & PaintLayerAppliedFilters)) {
- ASSERT(m_filter);
-
- // Update the filter's image if necessary.
- // The filter is always built at this point.
- LayoutRect filterRect = transparencyClipBox(this, rootLayer, paintBehavior);
-
- FloatRect filterSourceRect = filterRect;
- filterSourceRect.setLocation(LayoutPoint());
-
- updateFilterBackingStore(filterSourceRect);
- m_filter->prepare();
-
- // Paint into the context that represents the SourceGraphic of the filter.
- GraphicsContext* sourceGraphicsContext = m_filter->inputContext();
- if (!sourceGraphicsContext)
- return;
-
- {
- GraphicsContextStateSaver sourceSaver(*sourceGraphicsContext);
- sourceGraphicsContext->translate(-filterRect.x(), -filterRect.y());
-
- sourceGraphicsContext->clearRect(filterRect);
-
- // Now paint the layer and its children into the image buffer.
- paintLayer(rootLayer, sourceGraphicsContext, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags | PaintLayerAppliedFilters);
- }
-
- m_filter->apply();
-
- // Get the filtered output and draw it in place.
- IntRect destRect = m_filter->outputRect();
- destRect.move(filterRect.x(), filterRect.y());
-
- p->drawImageBuffer(m_filter->output(), renderer()->style()->colorSpace(), destRect, CompositeSourceOver);
- return;
- }
-#endif
-
- paintLayerContents(rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
+ paintLayerContentsAndReflection(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
}
-void RenderLayer::paintLayerContents(RenderLayer* rootLayer, GraphicsContext* p,
+void RenderLayer::paintLayerContentsAndReflection(RenderLayer* rootLayer, GraphicsContext* context,
const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior,
RenderObject* paintingRoot, RenderRegion* region, OverlapTestRequestMap* overlapTestRequests,
PaintLayerFlags paintFlags)
{
-#if USE(ACCELERATED_COMPOSITING)
- if (isComposited()) {
- // The updatingControlTints() painting pass goes through compositing layers,
- // but we need to ensure that we don't cache clip rects computed with the wrong root in this case.
- if (p->updatingControlTints() || (paintBehavior & PaintBehaviorFlattenCompositingLayers))
- paintFlags |= PaintLayerTemporaryClipRects;
- else if (!backing()->paintingGoesToWindow() && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)) {
- // If this RenderLayer should paint into its backing, that will be done via RenderLayerBacking::paintIntoLayer().
- return;
- }
- }
-#endif
-
- if (shouldSuppressPaintingLayer(this))
- return;
-
- // If this layer is totally invisible then there is nothing to paint.
- if (!renderer()->opacity())
- return;
-
- PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform
-#if ENABLE(CSS_FILTERS)
- | PaintLayerAppliedFilters
-#endif
- );
- bool haveTransparency = localPaintFlags & PaintLayerHaveTransparency;
+ PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform);
// Paint the reflection first if we have one.
if (m_reflection && !m_paintingInsideReflection) {
// Mark that we are now inside replica painting.
m_paintingInsideReflection = true;
- reflectionLayer()->paintLayer(rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags | PaintLayerPaintingReflection);
+ reflectionLayer()->paintLayer(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags | PaintLayerPaintingReflection);
m_paintingInsideReflection = false;
}
+ localPaintFlags |= PaintLayerPaintingCompositingAllPhases;
+ paintLayerContents(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags);
+}
+
+void RenderLayer::paintLayerContents(RenderLayer* rootLayer, GraphicsContext* context,
+ const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior,
+ RenderObject* paintingRoot, RenderRegion* region, OverlapTestRequestMap* overlapTestRequests,
+ PaintLayerFlags paintFlags)
+{
+ PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform);
+ bool haveTransparency = localPaintFlags & PaintLayerHaveTransparency;
bool isSelfPaintingLayer = this->isSelfPaintingLayer();
bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars;
// Outline always needs to be painted even if we have no visible content.
@@ -2871,94 +2837,118 @@ void RenderLayer::paintLayerContents(RenderLayer* rootLayer, GraphicsContext* p,
if (overlapTestRequests && isSelfPaintingLayer)
performOverlapTests(*overlapTestRequests, rootLayer, this);
+#if ENABLE(CSS_FILTERS)
+ FilterEffectRendererHelper filterPainter(paintsWithFilters());
+#endif
+
// We want to paint our layer, but only if we intersect the damage rect.
shouldPaintContent &= intersectsDamageRect(layerBounds, damageRect.rect(), rootLayer);
- if (shouldPaintContent && !selectionOnly) {
- // Begin transparency layers lazily now that we know we have to paint something.
- if (haveTransparency)
- beginTransparencyLayers(p, rootLayer, paintBehavior);
+
+ if (localPaintFlags & PaintLayerPaintingCompositingBackgroundPhase) {
+ if (shouldPaintContent && !selectionOnly) {
+ // Begin transparency layers lazily now that we know we have to paint something.
+ if (haveTransparency)
+ beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
- // Paint our background first, before painting any child layers.
- // Establish the clip used to paint our background.
- clipToRect(rootLayer, p, paintDirtyRect, damageRect, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
+#if ENABLE(CSS_FILTERS)
+ if (filterPainter.haveFilterEffect() && !context->paintingDisabled())
+ context = filterPainter.beginFilterEffect(this, context, paintingExtent(rootLayer, paintDirtyRect, paintBehavior));
+#endif
+
+ // Paint our background first, before painting any child layers.
+ // Establish the clip used to paint our background.
+ clipToRect(rootLayer, context, paintDirtyRect, damageRect, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
- // Paint the background.
- PaintInfo paintInfo(p, damageRect.rect(), PaintPhaseBlockBackground, false, paintingRootForRenderer, region, 0);
- renderer()->paint(paintInfo, paintOffset);
+ // Paint the background.
+ PaintInfo paintInfo(context, damageRect.rect(), PaintPhaseBlockBackground, false, paintingRootForRenderer, region, 0);
+ renderer()->paint(paintInfo, paintOffset);
- // Restore the clip.
- restoreClip(p, paintDirtyRect, damageRect);
+ // Restore the clip.
+ restoreClip(context, paintDirtyRect, damageRect);
+ }
+
+ // Now walk the sorted list of children with negative z-indices.
+ paintList(m_negZOrderList, rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags);
}
+
+ if (localPaintFlags & PaintLayerPaintingCompositingForegroundPhase) {
+ // Now establish the appropriate clip and paint our child RenderObjects.
+ if (shouldPaintContent && !clipRectToApply.isEmpty()) {
+ // Begin transparency layers lazily now that we know we have to paint something.
+ if (haveTransparency)
+ beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
- // Now walk the sorted list of children with negative z-indices.
- paintList(m_negZOrderList, rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags);
+#if ENABLE(CSS_FILTERS)
+ // If the filter was not started yet, start it now, after the transparency layer was lazily created.
+ if (filterPainter.haveFilterEffect() && !filterPainter.hasStartedFilterEffect() && !context->paintingDisabled())
+ context = filterPainter.beginFilterEffect(this, context, paintingExtent(rootLayer, paintDirtyRect, paintBehavior));
+#endif
+ // Set up the clip used when painting our children.
+ clipToRect(rootLayer, context, paintDirtyRect, clipRectToApply);
+ PaintInfo paintInfo(context, clipRectToApply.rect(),
+ selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds,
+ forceBlackText, paintingRootForRenderer, region, 0);
+ renderer()->paint(paintInfo, paintOffset);
+ if (!selectionOnly) {
+ paintInfo.phase = PaintPhaseFloat;
+ renderer()->paint(paintInfo, paintOffset);
+ paintInfo.phase = PaintPhaseForeground;
+ paintInfo.overlapTestRequests = overlapTestRequests;
+ renderer()->paint(paintInfo, paintOffset);
+ paintInfo.phase = PaintPhaseChildOutlines;
+ renderer()->paint(paintInfo, paintOffset);
+ }
- // Now establish the appropriate clip and paint our child RenderObjects.
- if (shouldPaintContent && !clipRectToApply.isEmpty()) {
- // Begin transparency layers lazily now that we know we have to paint something.
- if (haveTransparency)
- beginTransparencyLayers(p, rootLayer, paintBehavior);
+ // Now restore our clip.
+ restoreClip(context, paintDirtyRect, clipRectToApply);
+ }
- // Set up the clip used when painting our children.
- clipToRect(rootLayer, p, paintDirtyRect, clipRectToApply);
- PaintInfo paintInfo(p, clipRectToApply.rect(),
- selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds,
- forceBlackText, paintingRootForRenderer, region, 0);
- renderer()->paint(paintInfo, paintOffset);
- if (!selectionOnly) {
- paintInfo.phase = PaintPhaseFloat;
- renderer()->paint(paintInfo, paintOffset);
- paintInfo.phase = PaintPhaseForeground;
- paintInfo.overlapTestRequests = overlapTestRequests;
- renderer()->paint(paintInfo, paintOffset);
- paintInfo.phase = PaintPhaseChildOutlines;
+ if (shouldPaintOutline && !outlineRect.isEmpty()) {
+ // Paint our own outline
+ PaintInfo paintInfo(context, outlineRect.rect(), PaintPhaseSelfOutline, false, paintingRootForRenderer, region, 0);
+ clipToRect(rootLayer, context, paintDirtyRect, outlineRect, DoNotIncludeSelfForBorderRadius);
renderer()->paint(paintInfo, paintOffset);
+ restoreClip(context, paintDirtyRect, outlineRect);
}
-
- // Now restore our clip.
- restoreClip(p, paintDirtyRect, clipRectToApply);
- }
-
- if (shouldPaintOutline && !outlineRect.isEmpty()) {
- // Paint our own outline
- PaintInfo paintInfo(p, outlineRect.rect(), PaintPhaseSelfOutline, false, paintingRootForRenderer, region, 0);
- clipToRect(rootLayer, p, paintDirtyRect, outlineRect, DoNotIncludeSelfForBorderRadius);
- renderer()->paint(paintInfo, paintOffset);
- restoreClip(p, paintDirtyRect, outlineRect);
- }
- // Paint any child layers that have overflow.
- paintList(m_normalFlowList, rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags);
+ // Paint any child layers that have overflow.
+ paintList(m_normalFlowList, rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags);
- // Now walk the sorted list of children with positive z-indices.
- paintList(m_posZOrderList, rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags);
-
- if (shouldPaintContent && renderer()->hasMask() && !selectionOnly) {
- clipToRect(rootLayer, p, paintDirtyRect, damageRect, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
+ // Now walk the sorted list of children with positive z-indices.
+ paintList(m_posZOrderList, rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags);
+ }
+
+ if ((localPaintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && renderer()->hasMask() && !selectionOnly) {
+ clipToRect(rootLayer, context, paintDirtyRect, damageRect, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
// Paint the mask.
- PaintInfo paintInfo(p, damageRect.rect(), PaintPhaseMask, false, paintingRootForRenderer, region, 0);
+ PaintInfo paintInfo(context, damageRect.rect(), PaintPhaseMask, false, paintingRootForRenderer, region, 0);
renderer()->paint(paintInfo, paintOffset);
// Restore the clip.
- restoreClip(p, paintDirtyRect, damageRect);
+ restoreClip(context, paintDirtyRect, damageRect);
}
if (isPaintingOverlayScrollbars) {
- clipToRect(rootLayer, p, paintDirtyRect, damageRect);
- paintOverflowControls(p, paintOffset, damageRect.rect(), true);
- restoreClip(p, paintDirtyRect, damageRect);
+ clipToRect(rootLayer, context, paintDirtyRect, damageRect);
+ paintOverflowControls(context, paintOffset, damageRect.rect(), true);
+ restoreClip(context, paintDirtyRect, damageRect);
}
+#if ENABLE(CSS_FILTERS)
+ if (filterPainter.hasStartedFilterEffect())
+ context = filterPainter.applyFilterEffect();
+#endif
+
// End our transparency layer
if (haveTransparency && m_usedTransparency && !m_paintingInsideReflection) {
- p->endTransparencyLayer();
- p->restore();
+ context->endTransparencyLayer();
+ context->restore();
m_usedTransparency = false;
}
}
-void RenderLayer::paintList(Vector<RenderLayer*>* list, RenderLayer* rootLayer, GraphicsContext* p,
+void RenderLayer::paintList(Vector<RenderLayer*>* list, RenderLayer* rootLayer, GraphicsContext* context,
const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior,
RenderObject* paintingRoot, RenderRegion* region, OverlapTestRequestMap* overlapTestRequests,
PaintLayerFlags paintFlags)
@@ -2969,9 +2959,9 @@ void RenderLayer::paintList(Vector<RenderLayer*>* list, RenderLayer* rootLayer,
for (size_t i = 0; i < list->size(); ++i) {
RenderLayer* childLayer = list->at(i);
if (!childLayer->isPaginated())
- childLayer->paintLayer(rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
+ childLayer->paintLayer(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
else
- paintPaginatedChildLayer(childLayer, rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
+ paintPaginatedChildLayer(childLayer, rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
}
}
@@ -3114,7 +3104,7 @@ bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
// We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down,
// return ourselves. We do this so mouse events continue getting delivered after a drag has
// exited the WebView, and so hit testing over a scrollbar hits the content document.
- if ((request.active() || request.mouseUp()) && renderer()->isRenderView()) {
+ if ((request.active() || request.release()) && renderer()->isRenderView()) {
renderer()->updateHitTestResult(result, result.point());
insideLayer = this;
}
@@ -4023,13 +4013,12 @@ void RenderLayer::updateHoverActiveState(const HitTestRequest& request, HitTestR
doc->setActiveNode(0);
} else {
Node* newActiveNode = result.innerNode();
- if (!activeNode && newActiveNode && request.active()) {
+ if (!activeNode && newActiveNode && request.active() && !request.touchMove()) {
// We are setting the :active chain and freezing it. If future moves happen, they
// will need to reference this chain.
for (RenderObject* curr = newActiveNode->renderer(); curr; curr = curr->parent()) {
- if (curr->node() && !curr->isText()) {
+ if (curr->node() && !curr->isText())
curr->node()->setInActiveChain();
- }
}
doc->setActiveNode(newActiveNode);
}
@@ -4041,11 +4030,24 @@ void RenderLayer::updateHoverActiveState(const HitTestRequest& request, HitTestR
// If the mouse is down and if this is a mouse move event, we want to restrict changes in
// :hover/:active to only apply to elements that are in the :active chain that we froze
// at the time the mouse went down.
- bool mustBeInActiveChain = request.active() && request.mouseMove();
+ bool mustBeInActiveChain = request.active() && request.move();
- // Check to see if the hovered node has changed. If not, then we don't need to
- // do anything.
RefPtr<Node> oldHoverNode = doc->hoverNode();
+ // Clear the :hover chain when the touch gesture is over.
+ if (request.touchRelease()) {
+ if (oldHoverNode) {
+ for (RenderObject* curr = oldHoverNode->renderer(); curr; curr = curr->parent()) {
+ if (curr->node() && !curr->isText())
+ curr->node()->setHovered(false);
+ }
+ doc->setHoverNode(0);
+ }
+ // A touch release can not set new hover or active target.
+ return;
+ }
+
+ // Check to see if the hovered node has changed.
+ // If it hasn't, we do not need to do anything.
Node* newHoverNode = result.innerNode();
if (newHoverNode && !newHoverNode->renderer())
newHoverNode = result.innerNonSharedNode();
@@ -4477,15 +4479,6 @@ void RenderLayer::updateOrRemoveFilterEffect()
}
}
-void RenderLayer::updateFilterBackingStore(const FloatRect& filterRect)
-{
- if (!filterRect.isZero()) {
- FloatRect currentSourceRect = m_filter->sourceImageRect();
- if (filterRect != currentSourceRect)
- m_filter->setSourceImageRect(filterRect);
- }
-}
-
void RenderLayer::filterNeedsRepaint()
{
renderer()->node()->setNeedsStyleRecalc(SyntheticStyleChange);