diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-24 16:36:50 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-24 16:36:50 +0100 |
commit | ad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (patch) | |
tree | b34b0daceb7c8e7fdde4b4ec43650ab7caadb0a9 /Source/WebCore/rendering/RenderLayerBacking.cpp | |
parent | 03e12282df9aa1e1fb05a8b90f1cfc2e08764cec (diff) | |
download | qtwebkit-ad0d549d4cc13433f77c1ac8f0ab379c83d93f28.tar.gz |
Imported WebKit commit bb52bf3c0119e8a128cd93afe5572413a8617de9 (http://svn.webkit.org/repository/webkit/trunk@108790)
Diffstat (limited to 'Source/WebCore/rendering/RenderLayerBacking.cpp')
-rw-r--r-- | Source/WebCore/rendering/RenderLayerBacking.cpp | 177 |
1 files changed, 122 insertions, 55 deletions
diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp index 9503a8275..f559970b4 100644 --- a/Source/WebCore/rendering/RenderLayerBacking.cpp +++ b/Source/WebCore/rendering/RenderLayerBacking.cpp @@ -70,7 +70,7 @@ using namespace HTMLNames; static bool hasBoxDecorations(const RenderStyle*); static bool hasBoxDecorationsOrBackground(const RenderObject*); static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*); -static LayoutRect clipBox(RenderBox* renderer); +static IntRect clipBox(RenderBox* renderer); static inline bool isAcceleratedCanvas(RenderObject* renderer) { @@ -101,7 +101,7 @@ RenderLayerBacking::RenderLayerBacking(RenderLayer* layer) if (page && frame && page->mainFrame() == frame) { m_isMainFrameRenderViewLayer = true; -#if ENABLE(THREADED_SCROLLING) +#if PLATFORM(MAC) // FIXME: It's a little weird that we base this decision on whether there's a scrolling coordinator or not. if (page->scrollingCoordinator()) m_usingTiledCacheLayer = true; @@ -229,7 +229,7 @@ static bool layerOrAncestorIsFullScreen(RenderLayer* layer) void RenderLayerBacking::updateCompositedBounds() { - LayoutRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer); + IntRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer); // Clip to the size of the document or enclosing overflow-scroll layer. // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with. @@ -254,7 +254,7 @@ void RenderLayerBacking::updateCompositedBounds() m_owningLayer->convertToLayerCoords(rootLayer, delta); clippingBounds.move(-delta.x(), -delta.y()); - layerBounds.intersect(clippingBounds); + layerBounds.intersect(pixelSnappedIntRect(clippingBounds)); } // If the element has a transform-origin that has fixed lengths, and the renderer has zero size, @@ -371,7 +371,7 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration() return layerConfigChanged; } -static LayoutRect clipBox(RenderBox* renderer) +static IntRect clipBox(RenderBox* renderer) { LayoutRect result = PaintInfo::infiniteRect(); if (renderer->hasOverflowClip()) @@ -380,7 +380,7 @@ static LayoutRect clipBox(RenderBox* renderer) if (renderer->hasClip()) result.intersect(renderer->clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions. - return result; + return pixelSnappedIntRect(result); } void RenderLayerBacking::updateGraphicsLayerGeometry() @@ -416,24 +416,24 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer(); // We compute everything relative to the enclosing compositing layer. - LayoutRect ancestorCompositingBounds; + IntRect ancestorCompositingBounds; if (compAncestor) { ASSERT(compAncestor->backing()); - ancestorCompositingBounds = compAncestor->backing()->compositedBounds(); + ancestorCompositingBounds = pixelSnappedIntRect(compAncestor->backing()->compositedBounds()); } - LayoutRect localCompositingBounds = compositedBounds(); + IntRect localCompositingBounds = pixelSnappedIntRect(compositedBounds()); - LayoutRect relativeCompositingBounds(localCompositingBounds); - LayoutPoint delta; - m_owningLayer->convertToLayerCoords(compAncestor, delta); + IntRect relativeCompositingBounds(localCompositingBounds); + IntPoint delta; + m_owningLayer->convertToPixelSnappedLayerCoords(compAncestor, delta); relativeCompositingBounds.moveBy(delta); - LayoutPoint graphicsLayerParentLocation; + IntPoint graphicsLayerParentLocation; if (compAncestor && compAncestor->backing()->hasClippingLayer()) { // If the compositing ancestor has a layer to clip children, we parent in that, and therefore // position relative to it. - LayoutRect clippingBox = clipBox(toRenderBox(compAncestor->renderer())); + IntRect clippingBox = clipBox(toRenderBox(compAncestor->renderer())); graphicsLayerParentLocation = clippingBox.location(); } else if (compAncestor) graphicsLayerParentLocation = ancestorCompositingBounds.location(); @@ -444,7 +444,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects // for a compositing layer, rootLayer is the layer itself. - LayoutRect parentClipRect = m_owningLayer->backgroundClipRect(compAncestor, 0, true).rect(); // FIXME: Incorrect for CSS regions. + IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->backgroundClipRect(compAncestor, 0, true).rect()); // FIXME: Incorrect for CSS regions. ASSERT(parentClipRect != PaintInfo::infiniteRect()); m_ancestorClippingLayer->setPosition(FloatPoint() + (parentClipRect.location() - graphicsLayerParentLocation)); m_ancestorClippingLayer->setSize(parentClipRect.size()); @@ -457,7 +457,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() } m_graphicsLayer->setPosition(FloatPoint() + (relativeCompositingBounds.location() - graphicsLayerParentLocation)); - m_graphicsLayer->setOffsetFromRenderer(localCompositingBounds.location() - LayoutPoint()); + m_graphicsLayer->setOffsetFromRenderer(localCompositingBounds.location() - IntPoint()); FloatSize oldSize = m_graphicsLayer->size(); FloatSize newSize = relativeCompositingBounds.size(); @@ -470,12 +470,12 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() } // If we have a layer that clips children, position it. - LayoutRect clippingBox; + IntRect clippingBox; if (m_clippingLayer) { clippingBox = clipBox(toRenderBox(renderer())); m_clippingLayer->setPosition(FloatPoint() + (clippingBox.location() - localCompositingBounds.location())); m_clippingLayer->setSize(clippingBox.size()); - m_clippingLayer->setOffsetFromRenderer(clippingBox.location() - LayoutPoint()); + m_clippingLayer->setOffsetFromRenderer(clippingBox.location() - IntPoint()); } if (m_maskLayer) { @@ -488,10 +488,10 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() } if (m_owningLayer->hasTransform()) { - const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect(); + const IntRect borderBox = pixelSnappedIntRect(toRenderBox(renderer())->borderBoxRect()); // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds. - LayoutRect layerBounds = LayoutRect(delta, borderBox.size()); + IntRect layerBounds = IntRect(delta, borderBox.size()); // Update properties that depend on layer dimensions FloatPoint3D transformOrigin = computeTransformOrigin(borderBox); @@ -524,12 +524,12 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() if (m_foregroundLayer) { FloatPoint foregroundPosition; FloatSize foregroundSize = newSize; - LayoutSize foregroundOffset = m_graphicsLayer->offsetFromRenderer(); + IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer(); if (m_clippingLayer) { // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it, // so that it gets correctly sorted with children. In that case, position relative to the clipping layer. foregroundSize = FloatSize(clippingBox.size()); - foregroundOffset = clippingBox.location() - LayoutPoint(); + foregroundOffset = clippingBox.location() - IntPoint(); } m_foregroundLayer->setPosition(foregroundPosition); @@ -1002,7 +1002,7 @@ void RenderLayerBacking::updateImageContents() image->startAnimation(); } -FloatPoint3D RenderLayerBacking::computeTransformOrigin(const LayoutRect& borderBox) const +FloatPoint3D RenderLayerBacking::computeTransformOrigin(const IntRect& borderBox) const { RenderStyle* style = renderer()->style(); @@ -1014,7 +1014,7 @@ FloatPoint3D RenderLayerBacking::computeTransformOrigin(const LayoutRect& border return origin; } -FloatPoint RenderLayerBacking::computePerspectiveOrigin(const LayoutRect& borderBox) const +FloatPoint RenderLayerBacking::computePerspectiveOrigin(const IntRect& borderBox) const { RenderStyle* style = renderer()->style(); @@ -1029,26 +1029,26 @@ FloatPoint RenderLayerBacking::computePerspectiveOrigin(const LayoutRect& border } // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted. -LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const +IntSize RenderLayerBacking::contentOffsetInCompostingLayer() const { - return LayoutSize(-m_compositedBounds.x(), -m_compositedBounds.y()); + return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y()); } -LayoutRect RenderLayerBacking::contentsBox() const +IntRect RenderLayerBacking::contentsBox() const { if (!renderer()->isBox()) - return LayoutRect(); + return IntRect(); - LayoutRect contentsRect; + IntRect contentsRect; #if ENABLE(VIDEO) if (renderer()->isVideo()) { RenderVideo* videoRenderer = toRenderVideo(renderer()); contentsRect = videoRenderer->videoBox(); } else #endif - contentsRect = toRenderBox(renderer())->contentBoxRect(); + contentsRect = pixelSnappedIntRect(toRenderBox(renderer())->contentBoxRect()); - LayoutSize contentOffset = contentOffsetInCompostingLayer(); + IntSize contentOffset = contentOffsetInCompostingLayer(); contentsRect.move(contentOffset); return contentsRect; } @@ -1077,29 +1077,29 @@ void RenderLayerBacking::setContentsNeedDisplay() } // r is in the coordinate space of the layer's render object -void RenderLayerBacking::setContentsNeedDisplayInRect(const LayoutRect& r) +void RenderLayerBacking::setContentsNeedDisplayInRect(const IntRect& r) { if (m_graphicsLayer && m_graphicsLayer->drawsContent()) { - LayoutRect layerDirtyRect = r; + IntRect layerDirtyRect = r; layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer()); m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect); } if (m_foregroundLayer && m_foregroundLayer->drawsContent()) { - LayoutRect layerDirtyRect = r; + IntRect layerDirtyRect = r; layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer()); m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect); } if (m_maskLayer && m_maskLayer->drawsContent()) { - LayoutRect layerDirtyRect = r; + IntRect layerDirtyRect = r; layerDirtyRect.move(-m_maskLayer->offsetFromRenderer()); m_maskLayer->setNeedsDisplayInRect(layerDirtyRect); } } void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* context, - const LayoutRect& paintDirtyRect, // In the coords of rootLayer. + const IntRect& paintDirtyRect, // In the coords of rootLayer. PaintBehavior paintBehavior, GraphicsLayerPaintingPhase paintingPhase, RenderObject* paintingRoot) { @@ -1124,28 +1124,28 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* ASSERT(!m_owningLayer->m_usedTransparency); } -static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const LayoutRect& clip) +static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip) { if (!scrollbar) return; context.save(); - const LayoutRect& scrollbarRect = scrollbar->frameRect(); + const IntRect& scrollbarRect = scrollbar->frameRect(); context.translate(-scrollbarRect.x(), -scrollbarRect.y()); - LayoutRect transformedClip = clip; + IntRect transformedClip = clip; transformedClip.moveBy(scrollbarRect.location()); scrollbar->paint(&context, transformedClip); context.restore(); } // Up-call from compositing layer drawing callback. -void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const LayoutRect& clip) +void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip) { if (graphicsLayer == m_graphicsLayer.get() || graphicsLayer == m_foregroundLayer.get() || graphicsLayer == m_maskLayer.get()) { - InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_owningLayer->renderer()->frame(), clip); + InspectorInstrumentationCookie cookie = InspectorInstrumentation::willPaint(m_owningLayer->renderer()->frame(), &context, clip); // The dirtyRect is in the coords of the painting root. - LayoutRect dirtyRect = compositedBounds(); + IntRect dirtyRect = compositedBounds(); dirtyRect.intersect(clip); // We have to use the same root as for hit testing, because both methods can compute and cache clipRects. @@ -1157,13 +1157,13 @@ void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, Graph } else if (graphicsLayer == layerForVerticalScrollbar()) { paintScrollbar(m_owningLayer->verticalScrollbar(), context, clip); } else if (graphicsLayer == layerForScrollCorner()) { - const LayoutRect& scrollCornerAndResizer = m_owningLayer->scrollCornerAndResizerRect(); + const IntRect& scrollCornerAndResizer = m_owningLayer->scrollCornerAndResizerRect(); context.save(); context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y()); - LayoutRect transformedClip = clip; + IntRect transformedClip = clip; transformedClip.moveBy(scrollCornerAndResizer.location()); - m_owningLayer->paintScrollCorner(&context, LayoutPoint(), transformedClip); - m_owningLayer->paintResizer(&context, LayoutPoint(), transformedClip); + m_owningLayer->paintScrollCorner(&context, IntPoint(), transformedClip); + m_owningLayer->paintResizer(&context, IntPoint(), transformedClip); context.restore(); } } @@ -1197,12 +1197,20 @@ bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim { bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity); bool hasTransform = renderer()->isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform); - - if (!hasOpacity && !hasTransform) +#if ENABLE(CSS_FILTERS) + bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter); +#else + bool hasFilter = false; +#endif + + if (!hasOpacity && !hasTransform && !hasFilter) return false; KeyframeValueList transformVector(AnimatedPropertyWebkitTransform); KeyframeValueList opacityVector(AnimatedPropertyOpacity); +#if ENABLE(CSS_FILTERS) + KeyframeValueList filterVector(AnimatedPropertyWebkitFilter); +#endif size_t numKeyframes = keyframes.size(); for (size_t i = 0; i < numKeyframes; ++i) { @@ -1222,22 +1230,41 @@ bool RenderLayerBacking::startAnimation(double timeOffset, const Animation* anim if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity)) opacityVector.insert(new FloatAnimationValue(key, keyframeStyle->opacity(), tf)); + +#if ENABLE(CSS_FILTERS) + if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitFilter)) + filterVector.insert(new FilterAnimationValue(key, &(keyframeStyle->filter()), tf)); +#endif } bool didAnimateTransform = false; bool didAnimateOpacity = false; +#if ENABLE(CSS_FILTERS) + bool didAnimateFilter = false; +#endif - if (hasTransform && m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), anim, keyframes.animationName(), timeOffset)) { + if (hasTransform && m_graphicsLayer->addAnimation(transformVector, pixelSnappedIntRect(toRenderBox(renderer())->borderBoxRect()).size(), anim, keyframes.animationName(), timeOffset)) { didAnimateTransform = true; compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitTransform); } - if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, LayoutSize(), anim, keyframes.animationName(), timeOffset)) { + if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset)) { didAnimateOpacity = true; compositor()->didStartAcceleratedAnimation(CSSPropertyOpacity); } +#if ENABLE(CSS_FILTERS) + if (hasFilter && m_graphicsLayer->addAnimation(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset)) { + didAnimateFilter = true; + compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitFilter); + } +#endif + +#if ENABLE(CSS_FILTERS) + return didAnimateTransform || didAnimateOpacity || didAnimateFilter; +#else return didAnimateTransform || didAnimateOpacity; +#endif } void RenderLayerBacking::animationPaused(double timeOffset, const String& animationName) @@ -1254,6 +1281,10 @@ bool RenderLayerBacking::startTransition(double timeOffset, int property, const { bool didAnimateOpacity = false; bool didAnimateTransform = false; +#if ENABLE(CSS_FILTERS) + bool didAnimateFilter = false; +#endif + ASSERT(property != cAnimateAll); if (property == (int)CSSPropertyOpacity) { @@ -1263,7 +1294,7 @@ bool RenderLayerBacking::startTransition(double timeOffset, int property, const opacityVector.insert(new FloatAnimationValue(0, compositingOpacity(fromStyle->opacity()))); opacityVector.insert(new FloatAnimationValue(1, compositingOpacity(toStyle->opacity()))); // The boxSize param is only used for transform animations (which can only run on RenderBoxes), so we pass an empty size here. - if (m_graphicsLayer->addAnimation(opacityVector, LayoutSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) { + if (m_graphicsLayer->addAnimation(opacityVector, IntSize(), opacityAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyOpacity), timeOffset)) { // To ensure that the correct opacity is visible when the animation ends, also set the final opacity. updateLayerOpacity(toStyle); didAnimateOpacity = true; @@ -1277,21 +1308,46 @@ bool RenderLayerBacking::startTransition(double timeOffset, int property, const KeyframeValueList transformVector(AnimatedPropertyWebkitTransform); transformVector.insert(new TransformAnimationValue(0, &fromStyle->transform())); transformVector.insert(new TransformAnimationValue(1, &toStyle->transform())); - if (m_graphicsLayer->addAnimation(transformVector, toRenderBox(renderer())->borderBoxRect().size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) { - // To ensure that the correct transform is visible when the animation ends, also set the final opacity. + if (m_graphicsLayer->addAnimation(transformVector, pixelSnappedIntRect(toRenderBox(renderer())->borderBoxRect()).size(), transformAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset)) { + // To ensure that the correct transform is visible when the animation ends, also set the final transform. updateLayerTransform(toStyle); didAnimateTransform = true; } } } +#if ENABLE(CSS_FILTERS) + if (property == (int)CSSPropertyWebkitFilter && m_owningLayer->hasFilter()) { + const Animation* filterAnim = toStyle->transitionForProperty(CSSPropertyWebkitFilter); + if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) { + KeyframeValueList filterVector(AnimatedPropertyWebkitFilter); + filterVector.insert(new FilterAnimationValue(0, &fromStyle->filter())); + filterVector.insert(new FilterAnimationValue(1, &toStyle->filter())); + if (m_graphicsLayer->addAnimation(filterVector, IntSize(), filterAnim, GraphicsLayer::animationNameForTransition(AnimatedPropertyWebkitFilter), timeOffset)) { + // To ensure that the correct filter is visible when the animation ends, also set the final filter. + updateLayerFilters(toStyle); + didAnimateFilter = true; + } + } + } +#endif + if (didAnimateOpacity) compositor()->didStartAcceleratedAnimation(CSSPropertyOpacity); if (didAnimateTransform) compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitTransform); +#if ENABLE(CSS_FILTERS) + if (didAnimateFilter) + compositor()->didStartAcceleratedAnimation(CSSPropertyWebkitFilter); +#endif + +#if ENABLE(CSS_FILTERS) + return didAnimateOpacity || didAnimateTransform || didAnimateFilter; +#else return didAnimateOpacity || didAnimateTransform; +#endif } void RenderLayerBacking::transitionPaused(double timeOffset, int property) @@ -1330,12 +1386,12 @@ void RenderLayerBacking::resumeAnimations() m_graphicsLayer->resumeAnimations(); } -LayoutRect RenderLayerBacking::compositedBounds() const +IntRect RenderLayerBacking::compositedBounds() const { return m_compositedBounds; } -void RenderLayerBacking::setCompositedBounds(const LayoutRect& bounds) +void RenderLayerBacking::setCompositedBounds(const IntRect& bounds) { m_compositedBounds = bounds; @@ -1353,6 +1409,13 @@ int RenderLayerBacking::graphicsLayerToCSSProperty(AnimatedPropertyID property) case AnimatedPropertyBackgroundColor: cssProperty = CSSPropertyBackgroundColor; break; + case AnimatedPropertyWebkitFilter: +#if ENABLE(CSS_FILTERS) + cssProperty = CSSPropertyWebkitFilter; +#else + ASSERT_NOT_REACHED(); +#endif + break; case AnimatedPropertyInvalid: ASSERT_NOT_REACHED(); } @@ -1368,6 +1431,10 @@ AnimatedPropertyID RenderLayerBacking::cssToGraphicsLayerProperty(int cssPropert return AnimatedPropertyOpacity; case CSSPropertyBackgroundColor: return AnimatedPropertyBackgroundColor; +#if ENABLE(CSS_FILTERS) + case CSSPropertyWebkitFilter: + return AnimatedPropertyWebkitFilter; +#endif // It's fine if we see other css properties here; they are just not accelerated. } return AnimatedPropertyInvalid; |