Cache isSelfPaintingLayer() for better performance
[WebKit-https.git] / Source / WebCore / rendering / RenderLayer.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
3  *
4  * Portions are Copyright (C) 1998 Netscape Communications Corporation.
5  *
6  * Other contributors:
7  *   Robert O'Callahan <roc+@cs.cmu.edu>
8  *   David Baron <dbaron@fas.harvard.edu>
9  *   Christian Biesinger <cbiesinger@web.de>
10  *   Randall Jesup <rjesup@wgate.com>
11  *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
12  *   Josh Soref <timeless@mac.com>
13  *   Boris Zbarsky <bzbarsky@mit.edu>
14  *
15  * This library is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU Lesser General Public
17  * License as published by the Free Software Foundation; either
18  * version 2.1 of the License, or (at your option) any later version.
19  *
20  * This library is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23  * Lesser General Public License for more details.
24  *
25  * You should have received a copy of the GNU Lesser General Public
26  * License along with this library; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
28  *
29  * Alternatively, the contents of this file may be used under the terms
30  * of either the Mozilla Public License Version 1.1, found at
31  * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
32  * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
33  * (the "GPL"), in which case the provisions of the MPL or the GPL are
34  * applicable instead of those above.  If you wish to allow use of your
35  * version of this file only under the terms of one of those two
36  * licenses (the MPL or the GPL) and not to allow others to use your
37  * version of this file under the LGPL, indicate your decision by
38  * deletingthe provisions above and replace them with the notice and
39  * other provisions required by the MPL or the GPL, as the case may be.
40  * If you do not delete the provisions above, a recipient may use your
41  * version of this file under any of the LGPL, the MPL or the GPL.
42  */
43
44 #include "config.h"
45 #include "RenderLayer.h"
46
47 #include "ColumnInfo.h"
48 #include "CSSPropertyNames.h"
49 #include "Chrome.h"
50 #include "Document.h"
51 #include "DocumentEventQueue.h"
52 #include "EventHandler.h"
53 #if ENABLE(CSS_FILTERS)
54 #include "FEColorMatrix.h"
55 #include "FEMerge.h"
56 #include "FilterEffectRenderer.h"
57 #endif
58 #include "FloatConversion.h"
59 #include "FloatPoint3D.h"
60 #include "FloatRect.h"
61 #include "FocusController.h"
62 #include "Frame.h"
63 #include "FrameSelection.h"
64 #include "FrameTree.h"
65 #include "FrameView.h"
66 #include "Gradient.h"
67 #include "GraphicsContext.h"
68 #include "HTMLFrameElement.h"
69 #include "HTMLFrameOwnerElement.h"
70 #include "HTMLNames.h"
71 #include "HitTestingTransformState.h"
72 #include "HitTestRequest.h"
73 #include "HitTestResult.h"
74 #include "OverflowEvent.h"
75 #include "OverlapTestRequestClient.h"
76 #include "Page.h"
77 #include "PlatformMouseEvent.h"
78 #include "RenderArena.h"
79 #include "RenderFlowThread.h"
80 #include "RenderInline.h"
81 #include "RenderMarquee.h"
82 #include "RenderReplica.h"
83 #include "RenderScrollbar.h"
84 #include "RenderScrollbarPart.h"
85 #include "RenderTheme.h"
86 #include "RenderTreeAsText.h"
87 #include "RenderView.h"
88 #include "ScaleTransformOperation.h"
89 #include "Scrollbar.h"
90 #include "ScrollbarTheme.h"
91 #include "Settings.h"
92 #include "SourceGraphic.h"
93 #include "StylePropertySet.h"
94 #include "StyleResolver.h"
95 #include "TextStream.h"
96 #include "TransformationMatrix.h"
97 #include "TranslateTransformOperation.h"
98 #include <wtf/StdLibExtras.h>
99 #include <wtf/UnusedParam.h>
100 #include <wtf/text/CString.h>
101
102 #if USE(ACCELERATED_COMPOSITING)
103 #include "RenderLayerBacking.h"
104 #include "RenderLayerCompositor.h"
105 #endif
106
107 #if ENABLE(SVG)
108 #include "SVGNames.h"
109 #endif
110
111 #if PLATFORM(CHROMIUM) || PLATFORM(BLACKBERRY)
112 // FIXME: border radius clipping triggers too-slow path on Chromium
113 // https://bugs.webkit.org/show_bug.cgi?id=69866
114 #define DISABLE_ROUNDED_CORNER_CLIPPING
115 #endif
116
117 #define MIN_INTERSECT_FOR_REVEAL 32
118
119 using namespace std;
120
121 namespace WebCore {
122
123 using namespace HTMLNames;
124
125 const int MinimumWidthWhileResizing = 100;
126 const int MinimumHeightWhileResizing = 40;
127
128 RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
129     : m_inResizeMode(false)
130     , m_scrollDimensionsDirty(true)
131     , m_normalFlowListDirty(true)
132     , m_usedTransparency(false)
133     , m_paintingInsideReflection(false)
134     , m_inOverflowRelayout(false)
135     , m_repaintStatus(NeedsNormalRepaint)
136     , m_visibleContentStatusDirty(true)
137     , m_hasVisibleContent(false)
138     , m_visibleDescendantStatusDirty(false)
139     , m_hasVisibleDescendant(false)
140     , m_isPaginated(false)
141     , m_3DTransformedDescendantStatusDirty(true)
142     , m_has3DTransformedDescendant(false)
143 #if USE(ACCELERATED_COMPOSITING)
144     , m_hasCompositingDescendant(false)
145     , m_indirectCompositingReason(NoIndirectCompositingReason)
146 #endif
147     , m_containsDirtyOverlayScrollbars(false)
148 #if !ASSERT_DISABLED
149     , m_layerListMutationAllowed(true)
150 #endif
151     , m_canSkipRepaintRectsUpdateOnScroll(renderer->isTableCell())
152 #if ENABLE(CSS_FILTERS)
153     , m_hasFilterInfo(false)
154 #endif
155     , m_renderer(renderer)
156     , m_parent(0)
157     , m_previous(0)
158     , m_next(0)
159     , m_first(0)
160     , m_last(0)
161     , m_posZOrderList(0)
162     , m_negZOrderList(0)
163     , m_normalFlowList(0)
164     , m_marquee(0)
165     , m_staticInlinePosition(0)
166     , m_staticBlockPosition(0)
167     , m_reflection(0)
168     , m_scrollCorner(0)
169     , m_resizer(0)
170 {
171     m_isNormalFlowOnly = shouldBeNormalFlowOnly();
172     m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
173
174     // Non-stacking contexts should have empty z-order lists. As this is already the case,
175     // there is no need to dirty / recompute these lists.
176     m_zOrderListsDirty = isStackingContext();
177
178     ScrollableArea::setConstrainsScrollingToContentEdge(false);
179
180     if (!renderer->firstChild() && renderer->style()) {
181         m_visibleContentStatusDirty = false;
182         m_hasVisibleContent = renderer->style()->visibility() == VISIBLE;
183     }
184
185     Node* node = renderer->node();
186     if (node && node->isElementNode()) {
187         // We save and restore only the scrollOffset as the other scroll values are recalculated.
188         Element* element = toElement(node);
189         m_scrollOffset = element->savedLayerScrollOffset();
190         element->setSavedLayerScrollOffset(IntSize());
191     }
192 }
193
194 RenderLayer::~RenderLayer()
195 {
196     if (inResizeMode() && !renderer()->documentBeingDestroyed()) {
197         if (Frame* frame = renderer()->frame())
198             frame->eventHandler()->resizeLayerDestroyed();
199     }
200
201     if (Frame* frame = renderer()->frame()) {
202         if (FrameView* frameView = frame->view())
203             frameView->removeScrollableArea(this);
204     }
205
206     if (!m_renderer->documentBeingDestroyed()) {
207         Node* node = m_renderer->node();
208         if (node && node->isElementNode())
209             toElement(node)->setSavedLayerScrollOffset(m_scrollOffset);
210     }
211
212     destroyScrollbar(HorizontalScrollbar);
213     destroyScrollbar(VerticalScrollbar);
214
215     if (m_reflection)
216         removeReflection();
217     
218 #if ENABLE(CSS_FILTERS)
219     removeFilterInfoIfNeeded();
220 #endif
221
222     // Child layers will be deleted by their corresponding render objects, so
223     // we don't need to delete them ourselves.
224
225     delete m_posZOrderList;
226     delete m_negZOrderList;
227     delete m_normalFlowList;
228     delete m_marquee;
229
230 #if USE(ACCELERATED_COMPOSITING)
231     clearBacking(true);
232 #endif
233     
234     if (m_scrollCorner)
235         m_scrollCorner->destroy();
236     if (m_resizer)
237         m_resizer->destroy();
238 }
239
240 #if USE(ACCELERATED_COMPOSITING)
241 RenderLayerCompositor* RenderLayer::compositor() const
242 {
243     ASSERT(renderer()->view());
244     return renderer()->view()->compositor();
245 }
246
247 void RenderLayer::contentChanged(ContentChangeType changeType)
248 {
249     // This can get called when video becomes accelerated, so the layers may change.
250     if ((changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged) && compositor()->updateLayerCompositingState(this))
251         compositor()->setCompositingLayersNeedRebuild();
252
253     if (m_backing)
254         m_backing->contentChanged(changeType);
255 }
256 #endif // USE(ACCELERATED_COMPOSITING)
257
258 bool RenderLayer::canRender3DTransforms() const
259 {
260 #if USE(ACCELERATED_COMPOSITING)
261     return compositor()->canRender3DTransforms();
262 #else
263     return false;
264 #endif
265 }
266
267 #if ENABLE(CSS_FILTERS)
268 bool RenderLayer::paintsWithFilters() const
269 {
270     // FIXME: Eventually there will be more factors than isComposited() to decide whether or not to render the filter
271     if (!renderer()->hasFilter())
272         return false;
273         
274 #if USE(ACCELERATED_COMPOSITING)
275     if (!isComposited())
276         return true;
277
278     if (!m_backing || !m_backing->canCompositeFilters())
279         return true;
280 #endif
281
282     return false;
283 }
284     
285 bool RenderLayer::requiresFullLayerImageForFilters() const 
286 {
287     if (!paintsWithFilters())
288         return false;
289     FilterEffectRenderer* filter = filterRenderer();
290     return filter ? filter->hasFilterThatMovesPixels() : false;
291 }
292 #endif
293
294 LayoutPoint RenderLayer::computeOffsetFromRoot(bool& hasLayerOffset) const
295 {
296     hasLayerOffset = true;
297
298     if (!parent())
299         return LayoutPoint();
300
301     // This is similar to root() but we check if an ancestor layer would
302     // prevent the optimization from working.
303     const RenderLayer* rootLayer = 0;
304     for (const RenderLayer* parentLayer = parent(); parentLayer; rootLayer = parentLayer, parentLayer = parentLayer->parent()) {
305         hasLayerOffset = parentLayer->canUseConvertToLayerCoords();
306         if (!hasLayerOffset)
307             return LayoutPoint();
308     }
309     ASSERT(rootLayer == root());
310
311     LayoutPoint offset;
312     parent()->convertToLayerCoords(rootLayer, offset);
313     return offset;
314 }
315
316 void RenderLayer::updateLayerPositions(LayoutPoint* offsetFromRoot, UpdateLayerPositionsFlags flags)
317 {
318 #if !ASSERT_DISABLED
319     if (offsetFromRoot) {
320         bool hasLayerOffset;
321         LayoutPoint computedOffsetFromRoot = computeOffsetFromRoot(hasLayerOffset);
322         ASSERT(hasLayerOffset);
323         ASSERT(*offsetFromRoot == computedOffsetFromRoot);
324     }
325 #endif
326
327     updateLayerPosition(); // For relpositioned layers or non-positioned layers,
328                            // we need to keep in sync, since we may have shifted relative
329                            // to our parent layer.
330     LayoutPoint oldOffsetFromRoot;
331     if (offsetFromRoot) {
332         // We can't cache our offset to the repaint container if the mapping is anything more complex than a simple translation
333         if (!canUseConvertToLayerCoords())
334             offsetFromRoot = 0; // If our cached offset is invalid make sure it's not passed to any of our children
335         else {
336             oldOffsetFromRoot = *offsetFromRoot;
337             // Frequently our parent layer's renderer will be the same as our renderer's containing block.  In that case,
338             // we just update the cache using our offset to our parent (which is m_topLeft). Otherwise, regenerated cached
339             // offsets to the root from the render tree.
340             if (!m_parent || m_parent->renderer() == renderer()->containingBlock())
341                 offsetFromRoot->move(m_topLeft.x(), m_topLeft.y()); // Fast case
342             else {
343                 LayoutPoint offset;
344                 convertToLayerCoords(root(), offset);
345                 *offsetFromRoot = offset;
346             }
347         }
348     }
349
350     LayoutPoint offset;
351     if (offsetFromRoot) {
352         offset = *offsetFromRoot;
353 #ifndef NDEBUG
354         LayoutPoint computedOffsetFromRoot;
355         convertToLayerCoords(root(), computedOffsetFromRoot);
356         ASSERT(offset == computedOffsetFromRoot);
357 #endif
358     } else {
359         // FIXME: It looks suspicious to call convertToLayerCoords here
360         // as canUseConvertToLayerCoords may be true for an ancestor layer.
361         convertToLayerCoords(root(), offset);
362     }
363     positionOverflowControls(toSize(roundedIntPoint(offset)));
364
365     updateVisibilityStatus();
366
367     if (flags & UpdatePagination)
368         updatePagination();
369     else
370         m_isPaginated = false;
371
372     if (m_hasVisibleContent) {
373         RenderView* view = renderer()->view();
374         ASSERT(view);
375         // FIXME: LayoutState does not work with RenderLayers as there is not a 1-to-1
376         // mapping between them and the RenderObjects. It would be neat to enable
377         // LayoutState outside the layout() phase and use it here.
378         ASSERT(!view->layoutStateEnabled());
379
380         RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
381         LayoutRect oldRepaintRect = m_repaintRect;
382         LayoutRect oldOutlineBox = m_outlineBox;
383         computeRepaintRects(offsetFromRoot);
384         // FIXME: Should ASSERT that value calculated for m_outlineBox using the cached offset is the same
385         // as the value not using the cached offset, but we can't due to https://bugs.webkit.org/show_bug.cgi?id=37048
386         if (flags & CheckForRepaint) {
387             if (view && !view->printing()) {
388                 if (m_repaintStatus & NeedsFullRepaint) {
389                     renderer()->repaintUsingContainer(repaintContainer, oldRepaintRect);
390                     if (m_repaintRect != oldRepaintRect)
391                         renderer()->repaintUsingContainer(repaintContainer, m_repaintRect);
392                 } else if (shouldRepaintAfterLayout())
393                     renderer()->repaintAfterLayoutIfNeeded(repaintContainer, oldRepaintRect, oldOutlineBox, &m_repaintRect, &m_outlineBox);
394             }
395         }
396     } else
397         clearRepaintRects();
398
399     m_repaintStatus = NeedsNormalRepaint;
400
401     // Go ahead and update the reflection's position and size.
402     if (m_reflection)
403         m_reflection->layout();
404
405 #if USE(ACCELERATED_COMPOSITING)
406     // Clear the IsCompositingUpdateRoot flag once we've found the first compositing layer in this update.
407     bool isUpdateRoot = (flags & IsCompositingUpdateRoot);
408     if (isComposited())
409         flags &= ~IsCompositingUpdateRoot;
410 #endif
411
412     if (renderer()->hasColumns())
413         flags |= UpdatePagination;
414
415     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
416         child->updateLayerPositions(offsetFromRoot, flags);
417
418 #if USE(ACCELERATED_COMPOSITING)
419     if ((flags & UpdateCompositingLayers) && isComposited())
420         backing()->updateAfterLayout(RenderLayerBacking::CompositingChildren, isUpdateRoot);
421 #endif
422         
423     // With all our children positioned, now update our marquee if we need to.
424     if (m_marquee)
425         m_marquee->updateMarqueePosition();
426
427     if (offsetFromRoot)
428         *offsetFromRoot = oldOffsetFromRoot;
429 }
430
431 LayoutRect RenderLayer::repaintRectIncludingNonCompositingDescendants() const
432 {
433     LayoutRect repaintRect = m_repaintRect;
434     for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
435         // Don't include repaint rects for composited child layers; they will paint themselves and have a different origin.
436         if (child->isComposited())
437             continue;
438
439         repaintRect.unite(child->repaintRectIncludingNonCompositingDescendants());
440     }
441     return repaintRect;
442 }
443
444 void RenderLayer::computeRepaintRects(LayoutPoint* offsetFromRoot)
445 {
446     ASSERT(!m_visibleContentStatusDirty);
447
448     RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
449     m_repaintRect = renderer()->clippedOverflowRectForRepaint(repaintContainer);
450     m_outlineBox = renderer()->outlineBoundsForRepaint(repaintContainer, offsetFromRoot);
451 }
452
453 void RenderLayer::clearRepaintRects()
454 {
455     ASSERT(!m_hasVisibleContent);
456     ASSERT(!m_visibleContentStatusDirty);
457
458     m_repaintRect = IntRect();
459     m_outlineBox = IntRect();
460 }
461
462 void RenderLayer::updateLayerPositionsAfterScroll(UpdateLayerPositionsAfterScrollFlags flags)
463 {
464     // FIXME: This shouldn't be needed, but there are some corner cases where
465     // these flags are still dirty. Update so that the check below is valid.
466     updateVisibilityStatus();
467
468     // If we have no visible content and no visible descendants, there is no point recomputing
469     // our rectangles as they will be empty. If our visibility changes, we are expected to
470     // recompute all our positions anyway.
471     if (!m_hasVisibleDescendant && !m_hasVisibleContent)
472         return;
473
474     updateLayerPosition();
475
476     if ((flags & HasSeenFixedPositionedAncestor) || renderer()->style()->position() == FixedPosition) {
477         // FIXME: Is it worth passing the offsetFromRoot around like in updateLayerPositions?
478         computeRepaintRects();
479         flags |= HasSeenFixedPositionedAncestor;
480     } else if ((flags & HasSeenAncestorWithOverflowClip) && !m_canSkipRepaintRectsUpdateOnScroll) {
481         // If we have seen an overflow clip, we should update our repaint rects as clippedOverflowRectForRepaint
482         // intersects it with our ancestor overflow clip that may have moved.
483         computeRepaintRects();
484     }
485
486     if (renderer()->hasOverflowClip())
487         flags |= HasSeenAncestorWithOverflowClip;
488
489     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
490         child->updateLayerPositionsAfterScroll(flags);
491
492     // We don't update our reflection as scrolling is a translation which does not change the size()
493     // of an object, thus RenderReplica will still repaint itself properly as the layer position was
494     // updated above.
495
496     if (m_marquee)
497         m_marquee->updateMarqueePosition();
498 }
499
500 void RenderLayer::updateTransform()
501 {
502     // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
503     // so check style too.
504     bool hasTransform = renderer()->hasTransform() && renderer()->style()->hasTransform();
505     bool had3DTransform = has3DTransform();
506
507     bool hadTransform = m_transform;
508     if (hasTransform != hadTransform) {
509         if (hasTransform)
510             m_transform = adoptPtr(new TransformationMatrix);
511         else
512             m_transform.clear();
513         
514         // Layers with transforms act as clip rects roots, so clear the cached clip rects here.
515         clearClipRectsIncludingDescendants();
516     }
517     
518     if (hasTransform) {
519         RenderBox* box = renderBox();
520         ASSERT(box);
521         m_transform->makeIdentity();
522         box->style()->applyTransform(*m_transform, box->borderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
523         makeMatrixRenderable(*m_transform, canRender3DTransforms());
524     }
525
526     if (had3DTransform != has3DTransform())
527         dirty3DTransformedDescendantStatus();
528 }
529
530 TransformationMatrix RenderLayer::currentTransform() const
531 {
532     if (!m_transform)
533         return TransformationMatrix();
534
535 #if USE(ACCELERATED_COMPOSITING)
536     if (renderer()->style()->isRunningAcceleratedAnimation()) {
537         TransformationMatrix currTransform;
538         RefPtr<RenderStyle> style = renderer()->animation()->getAnimatedStyleForRenderer(renderer());
539         style->applyTransform(currTransform, renderBox()->borderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
540         makeMatrixRenderable(currTransform, canRender3DTransforms());
541         return currTransform;
542     }
543 #endif
544
545     return *m_transform;
546 }
547
548 TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavior) const
549 {
550     if (!m_transform)
551         return TransformationMatrix();
552     
553     if (paintBehavior & PaintBehaviorFlattenCompositingLayers) {
554         TransformationMatrix matrix = *m_transform;
555         makeMatrixRenderable(matrix, false /* flatten 3d */);
556         return matrix;
557     }
558
559     return *m_transform;
560 }
561
562 static bool checkContainingBlockChainForPagination(RenderBoxModelObject* renderer, RenderBox* ancestorColumnsRenderer)
563 {
564     RenderView* view = renderer->view();
565     RenderBoxModelObject* prevBlock = renderer;
566     RenderBlock* containingBlock;
567     for (containingBlock = renderer->containingBlock();
568          containingBlock && containingBlock != view && containingBlock != ancestorColumnsRenderer;
569          containingBlock = containingBlock->containingBlock())
570         prevBlock = containingBlock;
571     
572     // If the columns block wasn't in our containing block chain, then we aren't paginated by it.
573     if (containingBlock != ancestorColumnsRenderer)
574         return false;
575         
576     // If the previous block is absolutely positioned, then we can't be paginated by the columns block.
577     if (prevBlock->isPositioned())
578         return false;
579         
580     // Otherwise we are paginated by the columns block.
581     return true;
582 }
583
584 void RenderLayer::updatePagination()
585 {
586     m_isPaginated = false;
587     if (isComposited() || !parent())
588         return; // FIXME: We will have to deal with paginated compositing layers someday.
589                 // FIXME: For now the RenderView can't be paginated.  Eventually printing will move to a model where it is though.
590     
591     if (isNormalFlowOnly()) {
592         m_isPaginated = parent()->renderer()->hasColumns();
593         return;
594     }
595
596     // If we're not normal flow, then we need to look for a multi-column object between us and our stacking context.
597     RenderLayer* ancestorStackingContext = stackingContext();
598     for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
599         if (curr->renderer()->hasColumns()) {
600             m_isPaginated = checkContainingBlockChainForPagination(renderer(), curr->renderBox());
601             return;
602         }
603         if (curr == ancestorStackingContext)
604             return;
605     }
606 }
607
608 void RenderLayer::setHasVisibleContent(bool b)
609
610     if (m_hasVisibleContent == b && !m_visibleContentStatusDirty)
611         return;
612     m_visibleContentStatusDirty = false; 
613     m_hasVisibleContent = b;
614     if (m_hasVisibleContent) {
615         computeRepaintRects();
616         if (!isNormalFlowOnly()) {
617             for (RenderLayer* sc = stackingContext(); sc; sc = sc->stackingContext()) {
618                 sc->dirtyZOrderLists();
619                 if (sc->hasVisibleContent())
620                     break;
621             }
622         }
623     }
624     if (parent())
625         parent()->childVisibilityChanged(m_hasVisibleContent);
626 }
627
628 void RenderLayer::dirtyVisibleContentStatus() 
629
630     m_visibleContentStatusDirty = true; 
631     if (parent())
632         parent()->dirtyVisibleDescendantStatus();
633 }
634
635 void RenderLayer::childVisibilityChanged(bool newVisibility) 
636
637     if (m_hasVisibleDescendant == newVisibility || m_visibleDescendantStatusDirty)
638         return;
639     if (newVisibility) {
640         RenderLayer* l = this;
641         while (l && !l->m_visibleDescendantStatusDirty && !l->m_hasVisibleDescendant) {
642             l->m_hasVisibleDescendant = true;
643             l = l->parent();
644         }
645     } else 
646         dirtyVisibleDescendantStatus();
647 }
648
649 void RenderLayer::dirtyVisibleDescendantStatus()
650 {
651     RenderLayer* l = this;
652     while (l && !l->m_visibleDescendantStatusDirty) {
653         l->m_visibleDescendantStatusDirty = true;
654         l = l->parent();
655     }
656 }
657
658 void RenderLayer::updateVisibilityStatus()
659 {
660     if (m_visibleDescendantStatusDirty) {
661         m_hasVisibleDescendant = false;
662         for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
663             child->updateVisibilityStatus();        
664             if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) {
665                 m_hasVisibleDescendant = true;
666                 break;
667             }
668         }
669         m_visibleDescendantStatusDirty = false;
670     }
671
672     if (m_visibleContentStatusDirty) {
673         if (renderer()->style()->visibility() == VISIBLE)
674             m_hasVisibleContent = true;
675         else {
676             // layer may be hidden but still have some visible content, check for this
677             m_hasVisibleContent = false;
678             RenderObject* r = renderer()->firstChild();
679             while (r) {
680                 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) {
681                     m_hasVisibleContent = true;
682                     break;
683                 }
684                 if (r->firstChild() && !r->hasLayer())
685                     r = r->firstChild();
686                 else if (r->nextSibling())
687                     r = r->nextSibling();
688                 else {
689                     do {
690                         r = r->parent();
691                         if (r == renderer())
692                             r = 0;
693                     } while (r && !r->nextSibling());
694                     if (r)
695                         r = r->nextSibling();
696                 }
697             }
698         }    
699         m_visibleContentStatusDirty = false; 
700     }
701 }
702
703 void RenderLayer::dirty3DTransformedDescendantStatus()
704 {
705     RenderLayer* curr = stackingContext();
706     if (curr)
707         curr->m_3DTransformedDescendantStatusDirty = true;
708         
709     // This propagates up through preserve-3d hierarchies to the enclosing flattening layer.
710     // Note that preserves3D() creates stacking context, so we can just run up the stacking contexts.
711     while (curr && curr->preserves3D()) {
712         curr->m_3DTransformedDescendantStatusDirty = true;
713         curr = curr->stackingContext();
714     }
715 }
716
717 // Return true if this layer or any preserve-3d descendants have 3d.
718 bool RenderLayer::update3DTransformedDescendantStatus()
719 {
720     if (m_3DTransformedDescendantStatusDirty) {
721         m_has3DTransformedDescendant = false;
722
723         updateZOrderLists();
724
725         // Transformed or preserve-3d descendants can only be in the z-order lists, not
726         // in the normal flow list, so we only need to check those.
727         if (Vector<RenderLayer*>* positiveZOrderList = posZOrderList()) {
728             for (unsigned i = 0; i < positiveZOrderList->size(); ++i)
729                 m_has3DTransformedDescendant |= positiveZOrderList->at(i)->update3DTransformedDescendantStatus();
730         }
731
732         // Now check our negative z-index children.
733         if (Vector<RenderLayer*>* negativeZOrderList = negZOrderList()) {
734             for (unsigned i = 0; i < negativeZOrderList->size(); ++i)
735                 m_has3DTransformedDescendant |= negativeZOrderList->at(i)->update3DTransformedDescendantStatus();
736         }
737         
738         m_3DTransformedDescendantStatusDirty = false;
739     }
740     
741     // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs
742     // the m_has3DTransformedDescendant set.
743     if (preserves3D())
744         return has3DTransform() || m_has3DTransformedDescendant;
745
746     return has3DTransform();
747 }
748
749 void RenderLayer::updateLayerPosition()
750 {
751     LayoutPoint localPoint;
752     LayoutSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done.
753     if (renderer()->isRenderInline()) {
754         RenderInline* inlineFlow = toRenderInline(renderer());
755         IntRect lineBox = inlineFlow->linesBoundingBox();
756         setSize(lineBox.size());
757         inlineBoundingBoxOffset = toSize(lineBox.location());
758         localPoint += inlineBoundingBoxOffset;
759     } else if (RenderBox* box = renderBox()) {
760         // FIXME: Is snapping the size really needed here for the RenderBox case?
761         setSize(pixelSnappedIntSize(box->size(), box->location()));
762         localPoint += box->topLeftLocationOffset();
763     }
764
765     // Clear our cached clip rect information.
766     clearClipRects();
767  
768     if (!renderer()->isPositioned() && renderer()->parent()) {
769         // We must adjust our position by walking up the render tree looking for the
770         // nearest enclosing object with a layer.
771         RenderObject* curr = renderer()->parent();
772         while (curr && !curr->hasLayer()) {
773             if (curr->isBox() && !curr->isTableRow()) {
774                 // Rows and cells share the same coordinate space (that of the section).
775                 // Omit them when computing our xpos/ypos.
776                 localPoint += toRenderBox(curr)->topLeftLocationOffset();
777             }
778             curr = curr->parent();
779         }
780         if (curr->isBox() && curr->isTableRow()) {
781             // Put ourselves into the row coordinate space.
782             localPoint -= toRenderBox(curr)->topLeftLocationOffset();
783         }
784     }
785     
786     // Subtract our parent's scroll offset.
787     if (renderer()->isPositioned() && enclosingPositionedAncestor()) {
788         RenderLayer* positionedParent = enclosingPositionedAncestor();
789
790         // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
791         LayoutSize offset = positionedParent->scrolledContentOffset();
792         localPoint -= offset;
793         
794         if (renderer()->isPositioned() && positionedParent->renderer()->isRelPositioned() && positionedParent->renderer()->isRenderInline()) {
795             LayoutSize offset = toRenderInline(positionedParent->renderer())->relativePositionedInlineOffset(toRenderBox(renderer()));
796             localPoint += offset;
797         }
798     } else if (parent()) {
799         if (isComposited()) {
800             // FIXME: Composited layers ignore pagination, so about the best we can do is make sure they're offset into the appropriate column.
801             // They won't split across columns properly.
802             LayoutSize columnOffset;
803             parent()->renderer()->adjustForColumns(columnOffset, localPoint);
804             localPoint += columnOffset;
805         }
806
807         LayoutSize scrollOffset = parent()->scrolledContentOffset();
808         localPoint -= scrollOffset;
809     }
810         
811     if (renderer()->isRelPositioned()) {
812         m_relativeOffset = renderer()->relativePositionOffset();
813         localPoint.move(m_relativeOffset);
814     } else {
815         m_relativeOffset = LayoutSize();
816     }
817
818     // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
819     localPoint -= inlineBoundingBoxOffset;
820     setLocation(localPoint.x(), localPoint.y());
821 }
822
823 TransformationMatrix RenderLayer::perspectiveTransform() const
824 {
825     if (!renderer()->hasTransform())
826         return TransformationMatrix();
827
828     RenderStyle* style = renderer()->style();
829     if (!style->hasPerspective())
830         return TransformationMatrix();
831
832     // Maybe fetch the perspective from the backing?
833     const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect();
834     const float boxWidth = borderBox.width();
835     const float boxHeight = borderBox.height();
836
837     float perspectiveOriginX = floatValueForLength(style->perspectiveOriginX(), boxWidth);
838     float perspectiveOriginY = floatValueForLength(style->perspectiveOriginY(), boxHeight);
839
840     // A perspective origin of 0,0 makes the vanishing point in the center of the element.
841     // We want it to be in the top-left, so subtract half the height and width.
842     perspectiveOriginX -= boxWidth / 2.0f;
843     perspectiveOriginY -= boxHeight / 2.0f;
844     
845     TransformationMatrix t;
846     t.translate(perspectiveOriginX, perspectiveOriginY);
847     t.applyPerspective(style->perspective());
848     t.translate(-perspectiveOriginX, -perspectiveOriginY);
849     
850     return t;
851 }
852
853 FloatPoint RenderLayer::perspectiveOrigin() const
854 {
855     if (!renderer()->hasTransform())
856         return FloatPoint();
857
858     const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect();
859     RenderStyle* style = renderer()->style();
860
861     return FloatPoint(floatValueForLength(style->perspectiveOriginX(), borderBox.width()),
862                       floatValueForLength(style->perspectiveOriginY(), borderBox.height()));
863 }
864
865 RenderLayer* RenderLayer::stackingContext() const
866 {
867     RenderLayer* layer = parent();
868     while (layer && !layer->renderer()->isRenderView() && !layer->renderer()->isRoot() && layer->renderer()->style()->hasAutoZIndex())
869         layer = layer->parent();
870     return layer;
871 }
872
873 static inline bool isPositionedContainer(RenderLayer* layer)
874 {
875     RenderObject* o = layer->renderer();
876     return o->isRenderView() || o->isPositioned() || o->isRelPositioned() || layer->hasTransform();
877 }
878
879 static inline bool isFixedPositionedContainer(RenderLayer* layer)
880 {
881     RenderObject* o = layer->renderer();
882     return o->isRenderView() || layer->hasTransform();
883 }
884
885 RenderLayer* RenderLayer::enclosingPositionedAncestor() const
886 {
887     RenderLayer* curr = parent();
888     while (curr && !isPositionedContainer(curr))
889         curr = curr->parent();
890
891     return curr;
892 }
893
894 RenderLayer* RenderLayer::enclosingScrollableLayer() const
895 {
896     for (RenderObject* nextRenderer = renderer()->parent(); nextRenderer; nextRenderer = nextRenderer->parent()) {
897         if (nextRenderer->isBox() && toRenderBox(nextRenderer)->canBeScrolledAndHasScrollableArea())
898             return nextRenderer->enclosingLayer();
899     }
900
901     return 0;
902 }
903
904 IntRect RenderLayer::scrollableAreaBoundingBox() const
905 {
906     return renderer()->absoluteBoundingBoxRect();
907 }
908
909 RenderLayer* RenderLayer::enclosingTransformedAncestor() const
910 {
911     RenderLayer* curr = parent();
912     while (curr && !curr->renderer()->isRenderView() && !curr->transform())
913         curr = curr->parent();
914
915     return curr;
916 }
917
918 static inline const RenderLayer* compositingContainer(const RenderLayer* layer)
919 {
920     return layer->isNormalFlowOnly() ? layer->parent() : layer->stackingContext();
921 }
922
923 inline bool RenderLayer::shouldRepaintAfterLayout() const
924 {
925 #if USE(ACCELERATED_COMPOSITING)
926     if (m_repaintStatus == NeedsNormalRepaint)
927         return true;
928
929     // Composited layers that were moved during a positioned movement only
930     // layout, don't need to be repainted. They just need to be recomposited.
931     ASSERT(m_repaintStatus == NeedsFullRepaintForPositionedMovementLayout);
932     return !isComposited();
933 #else
934     return true;
935 #endif
936 }
937
938 #if USE(ACCELERATED_COMPOSITING)
939 RenderLayer* RenderLayer::enclosingCompositingLayer(bool includeSelf) const
940 {
941     if (includeSelf && isComposited())
942         return const_cast<RenderLayer*>(this);
943
944     for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) {
945         if (curr->isComposited())
946             return const_cast<RenderLayer*>(curr);
947     }
948          
949     return 0;
950 }
951
952 RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(bool includeSelf) const
953 {
954     if (includeSelf && isComposited() && !backing()->paintsIntoCompositedAncestor())
955         return const_cast<RenderLayer*>(this);
956
957     for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) {
958         if (curr->isComposited() && !curr->backing()->paintsIntoCompositedAncestor())
959             return const_cast<RenderLayer*>(curr);
960     }
961          
962     return 0;
963 }
964 #endif
965
966 #if ENABLE(CSS_FILTERS)
967 RenderLayer* RenderLayer::enclosingFilterLayer(bool includeSelf) const
968 {
969     const RenderLayer* curr = includeSelf ? this : parent();
970     for (; curr; curr = curr->parent()) {
971         if (curr->requiresFullLayerImageForFilters())
972             return const_cast<RenderLayer*>(curr);
973     }
974     
975     return 0;
976 }
977
978 RenderLayer* RenderLayer::enclosingFilterRepaintLayer() const
979 {
980     for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
981         if ((curr != this && curr->requiresFullLayerImageForFilters()) || curr->isComposited() || curr->isRootLayer())
982             return const_cast<RenderLayer*>(curr);
983     }
984     return 0;
985 }
986
987 void RenderLayer::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect, bool immediate)
988 {
989     if (rect.isEmpty())
990         return;
991     
992     LayoutRect rectForRepaint = rect;
993     
994 #if ENABLE(CSS_FILTERS)
995     if (renderer()->style()->hasFilterOutsets()) {
996         int topOutset;
997         int rightOutset;
998         int bottomOutset;
999         int leftOutset;
1000         renderer()->style()->getFilterOutsets(topOutset, rightOutset, bottomOutset, leftOutset);
1001         rectForRepaint.move(-leftOutset, -topOutset);
1002         rectForRepaint.expand(leftOutset + rightOutset, topOutset + bottomOutset);
1003     }
1004 #endif
1005
1006     RenderLayerFilterInfo* filterInfo = this->filterInfo();
1007     ASSERT(filterInfo);
1008     filterInfo->expandDirtySourceRect(rectForRepaint);
1009     
1010 #if ENABLE(CSS_SHADERS)
1011     ASSERT(filterInfo->renderer());
1012     if (filterInfo->renderer()->hasCustomShaderFilter()) {
1013         // If we have at least one custom shader, we need to update the whole bounding box of the layer, because the
1014         // shader can address any ouput pixel.
1015         // Note: This is only for output rect, so there's no need to expand the dirty source rect.
1016         rectForRepaint.unite(calculateLayerBounds(this, this));
1017     }
1018 #endif
1019     
1020     RenderLayer* parentLayer = enclosingFilterRepaintLayer();
1021     ASSERT(parentLayer);
1022     FloatQuad repaintQuad(rectForRepaint);
1023     LayoutRect parentLayerRect = renderer()->localToContainerQuad(repaintQuad, parentLayer->renderer()).enclosingBoundingBox();
1024     
1025 #if USE(ACCELERATED_COMPOSITING)
1026     if (parentLayer->isComposited()) {
1027         if (!parentLayer->backing()->paintsIntoWindow()) {
1028             parentLayer->setBackingNeedsRepaintInRect(parentLayerRect);
1029             return;
1030         }
1031         // If the painting goes to window, redirect the painting to the parent RenderView.
1032         parentLayer = renderer()->view()->layer();
1033         parentLayerRect = renderer()->localToContainerQuad(repaintQuad, parentLayer->renderer()).enclosingBoundingBox();
1034     }
1035 #endif
1036
1037     if (parentLayer->paintsWithFilters()) {
1038         parentLayer->setFilterBackendNeedsRepaintingInRect(parentLayerRect, immediate);
1039         return;        
1040     }
1041     
1042     if (parentLayer->isRootLayer()) {
1043         RenderView* view = toRenderView(parentLayer->renderer());
1044         view->repaintViewRectangle(parentLayerRect, immediate);
1045         return;
1046     }
1047     
1048     ASSERT_NOT_REACHED();
1049 }
1050 #endif
1051     
1052 RenderLayer* RenderLayer::clippingRootForPainting() const
1053 {
1054 #if USE(ACCELERATED_COMPOSITING)
1055     if (isComposited())
1056         return const_cast<RenderLayer*>(this);
1057 #endif
1058
1059     const RenderLayer* current = this;
1060     while (current) {
1061         if (current->renderer()->isRenderView())
1062             return const_cast<RenderLayer*>(current);
1063
1064         current = compositingContainer(current);
1065         ASSERT(current);
1066         if (current->transform()
1067 #if USE(ACCELERATED_COMPOSITING)
1068             || (current->isComposited() && !current->backing()->paintsIntoCompositedAncestor())
1069 #endif
1070         )
1071             return const_cast<RenderLayer*>(current);
1072     }
1073
1074     ASSERT_NOT_REACHED();
1075     return 0;
1076 }
1077
1078 LayoutPoint RenderLayer::absoluteToContents(const LayoutPoint& absolutePoint) const
1079 {
1080     // We don't use convertToLayerCoords because it doesn't know about transforms
1081     return roundedLayoutPoint(renderer()->absoluteToLocal(absolutePoint, false, true));
1082 }
1083
1084 bool RenderLayer::cannotBlitToWindow() const
1085 {
1086     if (isTransparent() || hasReflection() || hasTransform())
1087         return true;
1088     if (!parent())
1089         return false;
1090     return parent()->cannotBlitToWindow();
1091 }
1092
1093 bool RenderLayer::isTransparent() const
1094 {
1095 #if ENABLE(SVG)
1096     if (renderer()->node() && renderer()->node()->namespaceURI() == SVGNames::svgNamespaceURI)
1097         return false;
1098 #endif
1099     return renderer()->isTransparent() || renderer()->hasMask();
1100 }
1101
1102 RenderLayer* RenderLayer::transparentPaintingAncestor()
1103 {
1104     if (isComposited())
1105         return 0;
1106
1107     for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
1108         if (curr->isComposited())
1109             return 0;
1110         if (curr->isTransparent())
1111             return curr;
1112     }
1113     return 0;
1114 }
1115
1116 static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, PaintBehavior);
1117
1118 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
1119 {
1120     // If we have a mask, then the clip is limited to the border box area (and there is
1121     // no need to examine child layers).
1122     if (!layer->renderer()->hasMask()) {
1123         // Note: we don't have to walk z-order lists since transparent elements always establish
1124         // a stacking context.  This means we can just walk the layer tree directly.
1125         for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling()) {
1126             if (!layer->reflection() || layer->reflectionLayer() != curr)
1127                 clipRect.unite(transparencyClipBox(curr, rootLayer, paintBehavior));
1128         }
1129     }
1130
1131     // If we have a reflection, then we need to account for that when we push the clip.  Reflect our entire
1132     // current transparencyClipBox to catch all child layers.
1133     // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this
1134     // size into the parent layer.
1135     if (layer->renderer()->hasReflection()) {
1136         LayoutPoint delta;
1137         layer->convertToLayerCoords(rootLayer, delta);
1138         clipRect.move(-delta.x(), -delta.y());
1139         clipRect.unite(layer->renderBox()->reflectedRect(clipRect));
1140         clipRect.moveBy(delta);
1141     }
1142 }
1143
1144 static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, PaintBehavior paintBehavior)
1145 {
1146     // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
1147     // paintDirtyRect, and that should cut down on the amount we have to paint.  Still it
1148     // would be better to respect clips.
1149     
1150     if (rootLayer != layer && layer->paintsWithTransform(paintBehavior)) {
1151         // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
1152         // the transformed layer and all of its children.
1153         LayoutPoint delta;
1154         layer->convertToLayerCoords(rootLayer, delta);
1155
1156         TransformationMatrix transform;
1157         transform.translate(delta.x(), delta.y());
1158         transform = transform * *layer->transform();
1159
1160         LayoutRect clipRect = layer->boundingBox(layer);
1161         expandClipRectForDescendantsAndReflection(clipRect, layer, layer, paintBehavior);
1162         return transform.mapRect(clipRect);
1163     }
1164     
1165     LayoutRect clipRect = layer->boundingBox(rootLayer);
1166     expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, paintBehavior);
1167     return clipRect;
1168 }
1169
1170 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
1171 {
1172     return intersection(transparencyClipBox(this, rootLayer, paintBehavior), paintDirtyRect);
1173 }
1174
1175 void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
1176 {
1177     if (context->paintingDisabled() || (paintsWithTransparency(paintBehavior) && m_usedTransparency))
1178         return;
1179     
1180     RenderLayer* ancestor = transparentPaintingAncestor();
1181     if (ancestor)
1182         ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
1183     
1184     if (paintsWithTransparency(paintBehavior)) {
1185         m_usedTransparency = true;
1186         context->save();
1187         LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBehavior);
1188         context->clip(clipRect);
1189         context->beginTransparencyLayer(renderer()->opacity());
1190 #ifdef REVEAL_TRANSPARENCY_LAYERS
1191         context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f), ColorSpaceDeviceRGB);
1192         context->fillRect(clipRect);
1193 #endif
1194     }
1195 }
1196
1197 void* RenderLayer::operator new(size_t sz, RenderArena* renderArena)
1198 {
1199     return renderArena->allocate(sz);
1200 }
1201
1202 void RenderLayer::operator delete(void* ptr, size_t sz)
1203 {
1204     // Stash size where destroy can find it.
1205     *(size_t *)ptr = sz;
1206 }
1207
1208 void RenderLayer::destroy(RenderArena* renderArena)
1209 {
1210     delete this;
1211
1212     // Recover the size left there for us by operator delete and free the memory.
1213     renderArena->free(*(size_t *)this, this);
1214 }
1215
1216 void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
1217 {
1218     RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
1219     if (prevSibling) {
1220         child->setPreviousSibling(prevSibling);
1221         prevSibling->setNextSibling(child);
1222         ASSERT(prevSibling != child);
1223     } else
1224         setFirstChild(child);
1225
1226     if (beforeChild) {
1227         beforeChild->setPreviousSibling(child);
1228         child->setNextSibling(beforeChild);
1229         ASSERT(beforeChild != child);
1230     } else
1231         setLastChild(child);
1232
1233     child->setParent(this);
1234
1235     if (child->isNormalFlowOnly())
1236         dirtyNormalFlowList();
1237
1238     if (!child->isNormalFlowOnly() || child->firstChild()) {
1239         // Dirty the z-order list in which we are contained.  The stackingContext() can be null in the
1240         // case where we're building up generated content layers.  This is ok, since the lists will start
1241         // off dirty in that case anyway.
1242         child->dirtyStackingContextZOrderLists();
1243     }
1244
1245     child->updateVisibilityStatus();
1246     if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
1247         childVisibilityChanged(true);
1248     
1249 #if USE(ACCELERATED_COMPOSITING)
1250     compositor()->layerWasAdded(this, child);
1251 #endif
1252 }
1253
1254 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
1255 {
1256 #if USE(ACCELERATED_COMPOSITING)
1257     if (!renderer()->documentBeingDestroyed())
1258         compositor()->layerWillBeRemoved(this, oldChild);
1259 #endif
1260
1261     // remove the child
1262     if (oldChild->previousSibling())
1263         oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
1264     if (oldChild->nextSibling())
1265         oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
1266
1267     if (m_first == oldChild)
1268         m_first = oldChild->nextSibling();
1269     if (m_last == oldChild)
1270         m_last = oldChild->previousSibling();
1271
1272     if (oldChild->isNormalFlowOnly())
1273         dirtyNormalFlowList();
1274     if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) { 
1275         // Dirty the z-order list in which we are contained.  When called via the
1276         // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
1277         // from the main layer tree, so we need to null-check the |stackingContext| value.
1278         oldChild->dirtyStackingContextZOrderLists();
1279     }
1280
1281     oldChild->setPreviousSibling(0);
1282     oldChild->setNextSibling(0);
1283     oldChild->setParent(0);
1284     
1285     oldChild->updateVisibilityStatus();
1286     if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
1287         childVisibilityChanged(false);
1288     
1289     return oldChild;
1290 }
1291
1292 void RenderLayer::removeOnlyThisLayer()
1293 {
1294     if (!m_parent)
1295         return;
1296
1297     // Mark that we are about to lose our layer. This makes render tree
1298     // walks ignore this layer while we're removing it.
1299     m_renderer->setHasLayer(false);
1300
1301 #if USE(ACCELERATED_COMPOSITING)
1302     compositor()->layerWillBeRemoved(m_parent, this);
1303 #endif
1304
1305     // Dirty the clip rects.
1306     clearClipRectsIncludingDescendants();
1307
1308     RenderLayer* nextSib = nextSibling();
1309     bool hasLayerOffset;
1310     const LayoutPoint offsetFromRootBeforeMove = computeOffsetFromRoot(hasLayerOffset);
1311
1312     // Remove the child reflection layer before moving other child layers.
1313     // The reflection layer should not be moved to the parent.
1314     if (reflection())
1315         removeChild(reflectionLayer());
1316
1317     // Now walk our kids and reattach them to our parent.
1318     RenderLayer* current = m_first;
1319     while (current) {
1320         RenderLayer* next = current->nextSibling();
1321         removeChild(current);
1322         m_parent->addChild(current, nextSib);
1323         current->setRepaintStatus(NeedsFullRepaint);
1324         LayoutPoint offsetFromRoot = offsetFromRootBeforeMove;
1325         // updateLayerPositions depends on hasLayer() already being false for proper layout.
1326         ASSERT(!renderer()->hasLayer());
1327         current->updateLayerPositions(hasLayerOffset ? &offsetFromRoot : 0);
1328         current = next;
1329     }
1330
1331     // Remove us from the parent.
1332     m_parent->removeChild(this);
1333     m_renderer->destroyLayer();
1334 }
1335
1336 void RenderLayer::insertOnlyThisLayer()
1337 {
1338     if (!m_parent && renderer()->parent()) {
1339         // We need to connect ourselves when our renderer() has a parent.
1340         // Find our enclosingLayer and add ourselves.
1341         RenderLayer* parentLayer = renderer()->parent()->enclosingLayer();
1342         ASSERT(parentLayer);
1343         RenderLayer* beforeChild = parentLayer->reflectionLayer() != this ? renderer()->parent()->findNextLayer(parentLayer, renderer()) : 0;
1344         parentLayer->addChild(this, beforeChild);
1345     }
1346
1347     // Remove all descendant layers from the hierarchy and add them to the new position.
1348     for (RenderObject* curr = renderer()->firstChild(); curr; curr = curr->nextSibling())
1349         curr->moveLayers(m_parent, this);
1350
1351     // Clear out all the clip rects.
1352     clearClipRectsIncludingDescendants();
1353 }
1354
1355 void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& roundedLocation) const
1356 {
1357     LayoutPoint location = roundedLocation;
1358     convertToLayerCoords(ancestorLayer, location);
1359     roundedLocation = roundedIntPoint(location);
1360 }
1361
1362 void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntRect& roundedRect) const
1363 {
1364     LayoutRect rect = roundedRect;
1365     convertToLayerCoords(ancestorLayer, rect);
1366     roundedRect = pixelSnappedIntRect(rect);
1367 }
1368
1369 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location) const
1370 {
1371     if (ancestorLayer == this)
1372         return;
1373
1374     EPosition position = renderer()->style()->position();
1375     if (position == FixedPosition && (!ancestorLayer || ancestorLayer == renderer()->view()->layer())) {
1376         // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
1377         // localToAbsolute() on the RenderView.
1378         FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), true);
1379         location += flooredLayoutSize(absPos);
1380         return;
1381     }
1382  
1383     if (position == FixedPosition) {
1384         // For a fixed layers, we need to walk up to the root to see if there's a fixed position container
1385         // (e.g. a transformed layer). It's an error to call convertToLayerCoords() across a layer with a transform,
1386         // so we should always find the ancestor at or before we find the fixed position container.
1387         RenderLayer* fixedPositionContainerLayer = 0;
1388         bool foundAncestor = false;
1389         for (RenderLayer* currLayer = parent(); currLayer; currLayer = currLayer->parent()) {
1390             if (currLayer == ancestorLayer)
1391                 foundAncestor = true;
1392
1393             if (isFixedPositionedContainer(currLayer)) {
1394                 fixedPositionContainerLayer = currLayer;
1395                 ASSERT_UNUSED(foundAncestor, foundAncestor);
1396                 break;
1397             }
1398         }
1399         
1400         ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
1401
1402         if (fixedPositionContainerLayer != ancestorLayer) {
1403             LayoutPoint fixedContainerCoords;
1404             convertToLayerCoords(fixedPositionContainerLayer, fixedContainerCoords);
1405
1406             LayoutPoint ancestorCoords;
1407             ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorCoords);
1408
1409             location += (fixedContainerCoords - ancestorCoords);
1410             return;
1411         }
1412     }
1413     
1414     RenderLayer* parentLayer;
1415     if (position == AbsolutePosition || position == FixedPosition) {
1416         // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way.
1417         parentLayer = parent();
1418         bool foundAncestorFirst = false;
1419         while (parentLayer) {
1420             if (isPositionedContainer(parentLayer))
1421                 break;
1422
1423             if (parentLayer == ancestorLayer) {
1424                 foundAncestorFirst = true;
1425                 break;
1426             }
1427
1428             parentLayer = parentLayer->parent();
1429         }
1430
1431         if (foundAncestorFirst) {
1432             // Found ancestorLayer before the abs. positioned container, so compute offset of both relative
1433             // to enclosingPositionedAncestor and subtract.
1434             RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor();
1435
1436             LayoutPoint thisCoords;
1437             convertToLayerCoords(positionedAncestor, thisCoords);
1438             
1439             LayoutPoint ancestorCoords;
1440             ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorCoords);
1441
1442             location += (thisCoords - ancestorCoords);
1443             return;
1444         }
1445     } else
1446         parentLayer = parent();
1447     
1448     if (!parentLayer)
1449         return;
1450
1451     parentLayer->convertToLayerCoords(ancestorLayer, location);
1452
1453     location += toSize(m_topLeft);
1454 }
1455
1456 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect& rect) const
1457 {
1458     LayoutPoint delta;
1459     convertToLayerCoords(ancestorLayer, delta);
1460     rect.move(-delta.x(), -delta.y());
1461 }
1462
1463 static inline int adjustedScrollDelta(int beginningDelta) {
1464     // This implemention matches Firefox's.
1465     // http://mxr.mozilla.org/firefox/source/toolkit/content/widgets/browser.xml#856.
1466     const int speedReducer = 12;
1467
1468     int adjustedDelta = beginningDelta / speedReducer;
1469     if (adjustedDelta > 1)
1470         adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(adjustedDelta))) - 1;
1471     else if (adjustedDelta < -1)
1472         adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(-adjustedDelta))) + 1;
1473
1474     return adjustedDelta;
1475 }
1476
1477 void RenderLayer::panScrollFromPoint(const LayoutPoint& sourcePoint) 
1478 {
1479     Frame* frame = renderer()->frame();
1480     if (!frame)
1481         return;
1482     
1483     IntPoint currentMousePosition = frame->eventHandler()->currentMousePosition();
1484     
1485     // We need to check if the current mouse position is out of the window. When the mouse is out of the window, the position is incoherent
1486     static IntPoint previousMousePosition;
1487     if (currentMousePosition.x() < 0 || currentMousePosition.y() < 0)
1488         currentMousePosition = previousMousePosition;
1489     else
1490         previousMousePosition = currentMousePosition;
1491
1492     int xDelta = currentMousePosition.x() - sourcePoint.x();
1493     int yDelta = currentMousePosition.y() - sourcePoint.y();
1494
1495     if (abs(xDelta) <= ScrollView::noPanScrollRadius) // at the center we let the space for the icon
1496         xDelta = 0;
1497     if (abs(yDelta) <= ScrollView::noPanScrollRadius)
1498         yDelta = 0;
1499
1500     scrollByRecursively(adjustedScrollDelta(xDelta), adjustedScrollDelta(yDelta), ScrollOffsetClamped);
1501 }
1502
1503 void RenderLayer::scrollByRecursively(int xDelta, int yDelta, ScrollOffsetClamping clamp)
1504 {
1505     if (!xDelta && !yDelta)
1506         return;
1507
1508     bool restrictedByLineClamp = false;
1509     if (renderer()->parent())
1510         restrictedByLineClamp = !renderer()->parent()->style()->lineClamp().isNone();
1511
1512     if (renderer()->hasOverflowClip() && !restrictedByLineClamp) {
1513         int newOffsetX = scrollXOffset() + xDelta;
1514         int newOffsetY = scrollYOffset() + yDelta;
1515         scrollToOffset(newOffsetX, newOffsetY, clamp);
1516
1517         // If this layer can't do the scroll we ask the next layer up that can scroll to try
1518         int leftToScrollX = newOffsetX - scrollXOffset();
1519         int leftToScrollY = newOffsetY - scrollYOffset();
1520         if ((leftToScrollX || leftToScrollY) && renderer()->parent()) {
1521             if (RenderLayer* scrollableLayer = enclosingScrollableLayer())
1522                 scrollableLayer->scrollByRecursively(leftToScrollX, leftToScrollY);
1523
1524             Frame* frame = renderer()->frame();
1525             if (frame)
1526                 frame->eventHandler()->updateAutoscrollRenderer();
1527         }
1528     } else if (renderer()->view()->frameView()) {
1529         // If we are here, we were called on a renderer that can be programmatically scrolled, but doesn't
1530         // have an overflow clip. Which means that it is a document node that can be scrolled.
1531         renderer()->view()->frameView()->scrollBy(IntSize(xDelta, yDelta));
1532         // FIXME: If we didn't scroll the whole way, do we want to try looking at the frames ownerElement? 
1533         // https://bugs.webkit.org/show_bug.cgi?id=28237
1534     }
1535 }
1536
1537 void RenderLayer::scrollToOffset(int x, int y, ScrollOffsetClamping clamp)
1538 {
1539     if (clamp == ScrollOffsetClamped) {
1540         RenderBox* box = renderBox();
1541         if (!box)
1542             return;
1543
1544         int maxX = scrollWidth() - box->clientWidth();
1545         int maxY = scrollHeight() - box->clientHeight();
1546
1547         x = min(max(x, 0), maxX);
1548         y = min(max(y, 0), maxY);
1549     }
1550
1551     IntPoint newScrollOffset(x, y);
1552     if (newScrollOffset != LayoutPoint(scrollXOffset(), scrollYOffset()))
1553         scrollToOffsetWithoutAnimation(newScrollOffset);
1554 }
1555
1556 void RenderLayer::scrollTo(int x, int y)
1557 {
1558     RenderBox* box = renderBox();
1559     if (!box)
1560         return;
1561
1562     if (box->style()->overflowX() != OMARQUEE) {
1563         // Ensure that the dimensions will be computed if they need to be (for overflow:hidden blocks).
1564         if (m_scrollDimensionsDirty)
1565             computeScrollDimensions();
1566     }
1567     
1568     // FIXME: Eventually, we will want to perform a blit.  For now never
1569     // blit, since the check for blitting is going to be very
1570     // complicated (since it will involve testing whether our layer
1571     // is either occluded by another layer or clipped by an enclosing
1572     // layer or contains fixed backgrounds, etc.).
1573     IntSize newScrollOffset = IntSize(x - scrollOrigin().x(), y - scrollOrigin().y());
1574     if (m_scrollOffset == newScrollOffset)
1575         return;
1576     m_scrollOffset = newScrollOffset;
1577
1578     // Update the positions of our child layers (if needed as only fixed layers should be impacted by a scroll).
1579     // We don't update compositing layers, because we need to do a deep update from the compositing ancestor.
1580     updateLayerPositionsAfterScroll();
1581
1582     RenderView* view = renderer()->view();
1583     
1584     // We should have a RenderView if we're trying to scroll.
1585     ASSERT(view);
1586     if (view) {
1587 #if ENABLE(DASHBOARD_SUPPORT)
1588         // Update dashboard regions, scrolling may change the clip of a
1589         // particular region.
1590         view->frameView()->updateDashboardRegions();
1591 #endif
1592
1593         view->updateWidgetPositions();
1594     }
1595
1596     updateCompositingLayersAfterScroll();
1597
1598     RenderBoxModelObject* repaintContainer = renderer()->containerForRepaint();
1599     Frame* frame = renderer()->frame();
1600     if (frame) {
1601         // The caret rect needs to be invalidated after scrolling
1602         frame->selection()->setCaretRectNeedsUpdate();
1603
1604         FloatQuad quadForFakeMouseMoveEvent = FloatQuad(m_repaintRect);
1605         if (repaintContainer)
1606             quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
1607         frame->eventHandler()->dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
1608     }
1609
1610     // Just schedule a full repaint of our object.
1611     if (view)
1612         renderer()->repaintUsingContainer(repaintContainer, m_repaintRect);
1613
1614     // Schedule the scroll DOM event.
1615     if (renderer()->node())
1616         renderer()->node()->document()->eventQueue()->enqueueOrDispatchScrollEvent(renderer()->node(), DocumentEventQueue::ScrollEventElementTarget);
1617 }
1618
1619 void RenderLayer::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
1620 {
1621     RenderLayer* parentLayer = 0;
1622     LayoutRect newRect = rect;
1623
1624     // We may end up propagating a scroll event. It is important that we suspend events until 
1625     // the end of the function since they could delete the layer or the layer's renderer().
1626     FrameView* frameView = renderer()->document()->view();
1627     if (frameView)
1628         frameView->pauseScheduledEvents();
1629
1630     bool restrictedByLineClamp = false;
1631     if (renderer()->parent()) {
1632         parentLayer = renderer()->parent()->enclosingLayer();
1633         restrictedByLineClamp = !renderer()->parent()->style()->lineClamp().isNone();
1634     }
1635
1636     if (renderer()->hasOverflowClip() && !restrictedByLineClamp) {
1637         // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
1638         // This will prevent us from revealing text hidden by the slider in Safari RSS.
1639         RenderBox* box = renderBox();
1640         ASSERT(box);
1641         FloatPoint absPos = box->localToAbsolute();
1642         absPos.move(box->borderLeft(), box->borderTop());
1643
1644         LayoutRect layerBounds = LayoutRect(absPos.x() + scrollXOffset(), absPos.y() + scrollYOffset(), box->clientWidth(), box->clientHeight());
1645         LayoutRect exposeRect = LayoutRect(rect.x() + scrollXOffset(), rect.y() + scrollYOffset(), rect.width(), rect.height());
1646         LayoutRect r = getRectToExpose(layerBounds, exposeRect, alignX, alignY);
1647         
1648         LayoutUnit adjustedX = r.x() - absPos.x();
1649         LayoutUnit adjustedY = r.y() - absPos.y();
1650         // Adjust offsets if they're outside of the allowable range.
1651         adjustedX = max<LayoutUnit>(0, min(scrollWidth() - layerBounds.width(), adjustedX));
1652         adjustedY = max<LayoutUnit>(0, min(scrollHeight() - layerBounds.height(), adjustedY));
1653
1654         int xOffset = roundToInt(adjustedX);
1655         int yOffset = roundToInt(adjustedY);
1656         
1657         if (xOffset != scrollXOffset() || yOffset != scrollYOffset()) {
1658             int diffX = scrollXOffset();
1659             int diffY = scrollYOffset();
1660             scrollToOffset(xOffset, yOffset);
1661             diffX = scrollXOffset() - diffX;
1662             diffY = scrollYOffset() - diffY;
1663             newRect.setX(rect.x() - diffX);
1664             newRect.setY(rect.y() - diffY);
1665         }
1666     } else if (!parentLayer && renderer()->isBox() && renderBox()->canBeProgramaticallyScrolled()) {
1667         if (frameView) {
1668             Element* ownerElement = 0;
1669             if (renderer()->document())
1670                 ownerElement = renderer()->document()->ownerElement();
1671
1672             if (ownerElement && ownerElement->renderer()) {
1673                 HTMLFrameElement* frameElement = 0;
1674
1675                 if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))
1676                     frameElement = static_cast<HTMLFrameElement*>(ownerElement);
1677
1678                 if (frameElement && frameElement->scrollingMode() != ScrollbarAlwaysOff) {
1679                     LayoutRect viewRect = frameView->visibleContentRect();
1680                     LayoutRect exposeRect = getRectToExpose(viewRect, rect, alignX, alignY);
1681
1682                     int xOffset = roundToInt(exposeRect.x());
1683                     int yOffset = roundToInt(exposeRect.y());
1684                     // Adjust offsets if they're outside of the allowable range.
1685                     xOffset = max(0, min(frameView->contentsWidth(), xOffset));
1686                     yOffset = max(0, min(frameView->contentsHeight(), yOffset));
1687
1688                     frameView->setScrollPosition(IntPoint(xOffset, yOffset));
1689                     if (frameView->safeToPropagateScrollToParent()) {
1690                         parentLayer = ownerElement->renderer()->enclosingLayer();
1691                         newRect.setX(rect.x() - frameView->scrollX() + frameView->x());
1692                         newRect.setY(rect.y() - frameView->scrollY() + frameView->y());
1693                     } else
1694                         parentLayer = 0;
1695                 }
1696             } else {
1697                 LayoutRect viewRect = frameView->visibleContentRect();
1698                 LayoutRect r = getRectToExpose(viewRect, rect, alignX, alignY);
1699                 
1700                 frameView->setScrollPosition(roundedIntPoint(r.location()));
1701
1702                 // This is the outermost view of a web page, so after scrolling this view we
1703                 // scroll its container by calling Page::scrollRectIntoView.
1704                 // This only has an effect on the Mac platform in applications
1705                 // that put web views into scrolling containers, such as Mac OS X Mail.
1706                 // The canAutoscroll function in EventHandler also knows about this.
1707                 if (Frame* frame = frameView->frame()) {
1708                     if (Page* page = frame->page())
1709                         page->chrome()->scrollRectIntoView(pixelSnappedIntRect(rect));
1710                 }
1711             }
1712         }
1713     }
1714     
1715     if (parentLayer)
1716         parentLayer->scrollRectToVisible(newRect, alignX, alignY);
1717
1718     if (frameView)
1719         frameView->resumeScheduledEvents();
1720 }
1721
1722 void RenderLayer::updateCompositingLayersAfterScroll()
1723 {
1724 #if USE(ACCELERATED_COMPOSITING)
1725     if (compositor()->inCompositingMode()) {
1726         // Our stacking context is guaranteed to contain all of our descendants that may need
1727         // repositioning, so update compositing layers from there.
1728         if (RenderLayer* compositingAncestor = stackingContext()->enclosingCompositingLayer()) {
1729             if (compositor()->compositingConsultsOverlap())
1730                 compositor()->updateCompositingLayers(CompositingUpdateOnScroll, compositingAncestor);
1731             else {
1732                 bool isUpdateRoot = true;
1733                 compositingAncestor->backing()->updateAfterLayout(RenderLayerBacking::AllDescendants, isUpdateRoot);
1734             }
1735         }
1736     }
1737 #endif
1738 }
1739
1740 LayoutRect RenderLayer::getRectToExpose(const LayoutRect &visibleRect, const LayoutRect &exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
1741 {
1742     // Determine the appropriate X behavior.
1743     ScrollBehavior scrollX;
1744     LayoutRect exposeRectX(exposeRect.x(), visibleRect.y(), exposeRect.width(), visibleRect.height());
1745     LayoutUnit intersectWidth = intersection(visibleRect, exposeRectX).width();
1746     if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_FOR_REVEAL)
1747         // If the rectangle is fully visible, use the specified visible behavior.
1748         // If the rectangle is partially visible, but over a certain threshold,
1749         // then treat it as fully visible to avoid unnecessary horizontal scrolling
1750         scrollX = ScrollAlignment::getVisibleBehavior(alignX);
1751     else if (intersectWidth == visibleRect.width()) {
1752         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
1753         scrollX = ScrollAlignment::getVisibleBehavior(alignX);
1754         if (scrollX == alignCenter)
1755             scrollX = noScroll;
1756     } else if (intersectWidth > 0)
1757         // If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior
1758         scrollX = ScrollAlignment::getPartialBehavior(alignX);
1759     else
1760         scrollX = ScrollAlignment::getHiddenBehavior(alignX);
1761     // If we're trying to align to the closest edge, and the exposeRect is further right
1762     // than the visibleRect, and not bigger than the visible area, then align with the right.
1763     if (scrollX == alignToClosestEdge && exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visibleRect.width())
1764         scrollX = alignRight;
1765
1766     // Given the X behavior, compute the X coordinate.
1767     LayoutUnit x;
1768     if (scrollX == noScroll) 
1769         x = visibleRect.x();
1770     else if (scrollX == alignRight)
1771         x = exposeRect.maxX() - visibleRect.width();
1772     else if (scrollX == alignCenter)
1773         x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
1774     else
1775         x = exposeRect.x();
1776
1777     // Determine the appropriate Y behavior.
1778     ScrollBehavior scrollY;
1779     LayoutRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(), exposeRect.height());
1780     LayoutUnit intersectHeight = intersection(visibleRect, exposeRectY).height();
1781     if (intersectHeight == exposeRect.height())
1782         // If the rectangle is fully visible, use the specified visible behavior.
1783         scrollY = ScrollAlignment::getVisibleBehavior(alignY);
1784     else if (intersectHeight == visibleRect.height()) {
1785         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
1786         scrollY = ScrollAlignment::getVisibleBehavior(alignY);
1787         if (scrollY == alignCenter)
1788             scrollY = noScroll;
1789     } else if (intersectHeight > 0)
1790         // If the rectangle is partially visible, use the specified partial behavior
1791         scrollY = ScrollAlignment::getPartialBehavior(alignY);
1792     else
1793         scrollY = ScrollAlignment::getHiddenBehavior(alignY);
1794     // If we're trying to align to the closest edge, and the exposeRect is further down
1795     // than the visibleRect, and not bigger than the visible area, then align with the bottom.
1796     if (scrollY == alignToClosestEdge && exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < visibleRect.height())
1797         scrollY = alignBottom;
1798
1799     // Given the Y behavior, compute the Y coordinate.
1800     LayoutUnit y;
1801     if (scrollY == noScroll) 
1802         y = visibleRect.y();
1803     else if (scrollY == alignBottom)
1804         y = exposeRect.maxY() - visibleRect.height();
1805     else if (scrollY == alignCenter)
1806         y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
1807     else
1808         y = exposeRect.y();
1809
1810     return LayoutRect(LayoutPoint(x, y), visibleRect.size());
1811 }
1812
1813 void RenderLayer::autoscroll()
1814 {
1815     Frame* frame = renderer()->frame();
1816     if (!frame)
1817         return;
1818
1819     FrameView* frameView = frame->view();
1820     if (!frameView)
1821         return;
1822
1823 #if ENABLE(DRAG_SUPPORT)
1824     frame->eventHandler()->updateSelectionForMouseDrag();
1825 #endif
1826
1827     IntPoint currentDocumentPosition = frameView->windowToContents(frame->eventHandler()->currentMousePosition());
1828     scrollRectToVisible(LayoutRect(currentDocumentPosition, LayoutSize(1, 1)), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
1829 }
1830
1831 void RenderLayer::resize(const PlatformMouseEvent& evt, const LayoutSize& oldOffset)
1832 {
1833     // FIXME: This should be possible on generated content but is not right now.
1834     if (!inResizeMode() || !renderer()->hasOverflowClip() || !renderer()->node())
1835         return;
1836
1837     ASSERT(renderer()->node()->isElementNode());
1838     Element* element = static_cast<Element*>(renderer()->node());
1839     RenderBox* renderer = toRenderBox(element->renderer());
1840
1841     EResize resize = renderer->style()->resize();
1842     if (resize == RESIZE_NONE)
1843         return;
1844
1845     Document* document = element->document();
1846     if (!document->frame()->eventHandler()->mousePressed())
1847         return;
1848
1849     float zoomFactor = renderer->style()->effectiveZoom();
1850
1851     LayoutSize newOffset = offsetFromResizeCorner(document->view()->windowToContents(evt.position()));
1852     newOffset.setWidth(newOffset.width() / zoomFactor);
1853     newOffset.setHeight(newOffset.height() / zoomFactor);
1854     
1855     LayoutSize currentSize = LayoutSize(renderer->width() / zoomFactor, renderer->height() / zoomFactor);
1856     LayoutSize minimumSize = element->minimumSizeForResizing().shrunkTo(currentSize);
1857     element->setMinimumSizeForResizing(minimumSize);
1858     
1859     LayoutSize adjustedOldOffset = LayoutSize(oldOffset.width() / zoomFactor, oldOffset.height() / zoomFactor);
1860     if (renderer->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
1861         newOffset.setWidth(-newOffset.width());
1862         adjustedOldOffset.setWidth(-adjustedOldOffset.width());
1863     }
1864     
1865     LayoutSize difference = (currentSize + newOffset - adjustedOldOffset).expandedTo(minimumSize) - currentSize;
1866
1867     ASSERT(element->isStyledElement());
1868     StyledElement* styledElement = static_cast<StyledElement*>(element);
1869     bool isBoxSizingBorder = renderer->style()->boxSizing() == BORDER_BOX;
1870
1871     if (resize != RESIZE_VERTICAL && difference.width()) {
1872         if (element->isFormControlElement()) {
1873             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
1874             styledElement->setInlineStyleProperty(CSSPropertyMarginLeft, String::number(renderer->marginLeft() / zoomFactor) + "px", false);
1875             styledElement->setInlineStyleProperty(CSSPropertyMarginRight, String::number(renderer->marginRight() / zoomFactor) + "px", false);
1876         }
1877         LayoutUnit baseWidth = renderer->width() - (isBoxSizingBorder ? ZERO_LAYOUT_UNIT : renderer->borderAndPaddingWidth());
1878         baseWidth = baseWidth / zoomFactor;
1879         styledElement->setInlineStyleProperty(CSSPropertyWidth, String::number(roundToInt(baseWidth + difference.width())) + "px", false);
1880     }
1881
1882     if (resize != RESIZE_HORIZONTAL && difference.height()) {
1883         if (element->isFormControlElement()) {
1884             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
1885             styledElement->setInlineStyleProperty(CSSPropertyMarginTop, String::number(renderer->marginTop() / zoomFactor) + "px", false);
1886             styledElement->setInlineStyleProperty(CSSPropertyMarginBottom, String::number(renderer->marginBottom() / zoomFactor) + "px", false);
1887         }
1888         LayoutUnit baseHeight = renderer->height() - (isBoxSizingBorder ? ZERO_LAYOUT_UNIT : renderer->borderAndPaddingHeight());
1889         baseHeight = baseHeight / zoomFactor;
1890         styledElement->setInlineStyleProperty(CSSPropertyHeight, String::number(roundToInt(baseHeight + difference.height())) + "px", false);
1891     }
1892
1893     document->updateLayout();
1894
1895     // FIXME (Radar 4118564): We should also autoscroll the window as necessary to keep the point under the cursor in view.
1896 }
1897
1898 int RenderLayer::scrollSize(ScrollbarOrientation orientation) const
1899 {
1900     Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_hBar : m_vBar).get();
1901     return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
1902 }
1903
1904 void RenderLayer::setScrollOffset(const IntPoint& offset)
1905 {
1906     scrollTo(offset.x(), offset.y());
1907 }
1908
1909 int RenderLayer::scrollPosition(Scrollbar* scrollbar) const
1910 {
1911     if (scrollbar->orientation() == HorizontalScrollbar)
1912         return scrollXOffset();
1913     if (scrollbar->orientation() == VerticalScrollbar)
1914         return scrollYOffset();
1915     return 0;
1916 }
1917
1918 IntPoint RenderLayer::scrollPosition() const
1919 {
1920     return scrollOrigin() + m_scrollOffset;
1921 }
1922
1923 IntPoint RenderLayer::minimumScrollPosition() const
1924 {
1925     return scrollOrigin();
1926 }
1927
1928 IntPoint RenderLayer::maximumScrollPosition() const
1929 {
1930     // FIXME: m_scrollSize may not be up-to-date if m_scrollDimensionsDirty is true.
1931     return scrollOrigin() + roundedIntSize(m_scrollSize) - visibleContentRect(true).size();
1932 }
1933
1934 IntRect RenderLayer::visibleContentRect(bool includeScrollbars) const
1935 {
1936     int verticalScrollbarWidth = 0;
1937     int horizontalScrollbarHeight = 0;
1938     if (includeScrollbars) {
1939         verticalScrollbarWidth = (verticalScrollbar() && !verticalScrollbar()->isOverlayScrollbar()) ? verticalScrollbar()->width() : 0;
1940         horizontalScrollbarHeight = (horizontalScrollbar() && !horizontalScrollbar()->isOverlayScrollbar()) ? horizontalScrollbar()->height() : 0;
1941     }
1942     
1943     return IntRect(IntPoint(scrollXOffset(), scrollYOffset()),
1944                    IntSize(max(0, m_layerSize.width() - verticalScrollbarWidth), 
1945                            max(0, m_layerSize.height() - horizontalScrollbarHeight)));
1946 }
1947
1948 IntSize RenderLayer::overhangAmount() const
1949 {
1950     return IntSize();
1951 }
1952
1953 bool RenderLayer::isActive() const
1954 {
1955     Page* page = renderer()->frame()->page();
1956     return page && page->focusController()->isActive();
1957 }
1958
1959 static int cornerStart(const RenderLayer* layer, int minX, int maxX, int thickness)
1960 {
1961     if (layer->renderer()->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
1962         return minX + layer->renderer()->style()->borderLeftWidth();
1963     return maxX - thickness - layer->renderer()->style()->borderRightWidth();
1964 }
1965
1966 static IntRect cornerRect(const RenderLayer* layer, const IntRect& bounds)
1967 {
1968     int horizontalThickness;
1969     int verticalThickness;
1970     if (!layer->verticalScrollbar() && !layer->horizontalScrollbar()) {
1971         // FIXME: This isn't right.  We need to know the thickness of custom scrollbars
1972         // even when they don't exist in order to set the resizer square size properly.
1973         horizontalThickness = ScrollbarTheme::theme()->scrollbarThickness();
1974         verticalThickness = horizontalThickness;
1975     } else if (layer->verticalScrollbar() && !layer->horizontalScrollbar()) {
1976         horizontalThickness = layer->verticalScrollbar()->width();
1977         verticalThickness = horizontalThickness;
1978     } else if (layer->horizontalScrollbar() && !layer->verticalScrollbar()) {
1979         verticalThickness = layer->horizontalScrollbar()->height();
1980         horizontalThickness = verticalThickness;
1981     } else {
1982         horizontalThickness = layer->verticalScrollbar()->width();
1983         verticalThickness = layer->horizontalScrollbar()->height();
1984     }
1985     return IntRect(cornerStart(layer, bounds.x(), bounds.maxX(), horizontalThickness),
1986                    bounds.maxY() - verticalThickness - layer->renderer()->style()->borderBottomWidth(),
1987                    horizontalThickness, verticalThickness);
1988 }
1989
1990 IntRect RenderLayer::scrollCornerRect() const
1991 {
1992     // We have a scrollbar corner when a scrollbar is visible and not filling the entire length of the box.
1993     // This happens when:
1994     // (a) A resizer is present and at least one scrollbar is present
1995     // (b) Both scrollbars are present.
1996     bool hasHorizontalBar = horizontalScrollbar();
1997     bool hasVerticalBar = verticalScrollbar();
1998     bool hasResizer = renderer()->style()->resize() != RESIZE_NONE;
1999     if ((hasHorizontalBar && hasVerticalBar) || (hasResizer && (hasHorizontalBar || hasVerticalBar)))
2000         return cornerRect(this, renderBox()->pixelSnappedBorderBoxRect());
2001     return IntRect();
2002 }
2003
2004 static IntRect resizerCornerRect(const RenderLayer* layer, const IntRect& bounds)
2005 {
2006     ASSERT(layer->renderer()->isBox());
2007     if (layer->renderer()->style()->resize() == RESIZE_NONE)
2008         return IntRect();
2009     return cornerRect(layer, bounds);
2010 }
2011
2012 IntRect RenderLayer::scrollCornerAndResizerRect() const
2013 {
2014     RenderBox* box = renderBox();
2015     if (!box)
2016         return IntRect();
2017     IntRect scrollCornerAndResizer = scrollCornerRect();
2018     if (scrollCornerAndResizer.isEmpty())
2019         scrollCornerAndResizer = resizerCornerRect(this, box->pixelSnappedBorderBoxRect());
2020     return scrollCornerAndResizer;
2021 }
2022
2023 bool RenderLayer::isScrollCornerVisible() const
2024 {
2025     ASSERT(renderer()->isBox());
2026     return !scrollCornerRect().isEmpty();
2027 }
2028
2029 IntRect RenderLayer::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
2030 {
2031     RenderView* view = renderer()->view();
2032     if (!view)
2033         return scrollbarRect;
2034
2035     IntRect rect = scrollbarRect;
2036     rect.move(scrollbarOffset(scrollbar));
2037
2038     return view->frameView()->convertFromRenderer(renderer(), rect);
2039 }
2040
2041 IntRect RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
2042 {
2043     RenderView* view = renderer()->view();
2044     if (!view)
2045         return parentRect;
2046
2047     IntRect rect = view->frameView()->convertToRenderer(renderer(), parentRect);
2048     rect.move(-scrollbarOffset(scrollbar));
2049     return rect;
2050 }
2051
2052 IntPoint RenderLayer::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
2053 {
2054     RenderView* view = renderer()->view();
2055     if (!view)
2056         return scrollbarPoint;
2057
2058     IntPoint point = scrollbarPoint;
2059     point.move(scrollbarOffset(scrollbar));
2060     return view->frameView()->convertFromRenderer(renderer(), point);
2061 }
2062
2063 IntPoint RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
2064 {
2065     RenderView* view = renderer()->view();
2066     if (!view)
2067         return parentPoint;
2068
2069     IntPoint point = view->frameView()->convertToRenderer(renderer(), parentPoint);
2070
2071     point.move(-scrollbarOffset(scrollbar));
2072     return point;
2073 }
2074
2075 IntSize RenderLayer::contentsSize() const
2076 {
2077     return IntSize(scrollWidth(), scrollHeight());
2078 }
2079
2080 int RenderLayer::visibleHeight() const
2081 {
2082     return m_layerSize.height();
2083 }
2084
2085 int RenderLayer::visibleWidth() const
2086 {
2087     return m_layerSize.width();
2088 }
2089
2090 bool RenderLayer::shouldSuspendScrollAnimations() const
2091 {
2092     RenderView* view = renderer()->view();
2093     if (!view)
2094         return true;
2095     return view->frameView()->shouldSuspendScrollAnimations();
2096 }
2097
2098 bool RenderLayer::isOnActivePage() const
2099 {
2100     return !m_renderer->document()->inPageCache();
2101 }
2102
2103 IntPoint RenderLayer::currentMousePosition() const
2104 {
2105     return renderer()->frame() ? renderer()->frame()->eventHandler()->currentMousePosition() : IntPoint();
2106 }
2107
2108 LayoutUnit RenderLayer::verticalScrollbarStart(int minX, int maxX) const
2109 {
2110     const RenderBox* box = renderBox();
2111     if (renderer()->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
2112         return minX + box->borderLeft();
2113     return maxX - box->borderRight() - m_vBar->width();
2114 }
2115
2116 LayoutUnit RenderLayer::horizontalScrollbarStart(int minX) const
2117 {
2118     const RenderBox* box = renderBox();
2119     int x = minX + box->borderLeft();
2120     if (renderer()->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
2121         x += m_vBar ? m_vBar->width() : resizerCornerRect(this, box->pixelSnappedBorderBoxRect()).width();
2122     return x;
2123 }
2124
2125 IntSize RenderLayer::scrollbarOffset(const Scrollbar* scrollbar) const
2126 {
2127     RenderBox* box = renderBox();
2128
2129     if (scrollbar == m_vBar.get())
2130         return IntSize(verticalScrollbarStart(0, box->width()), box->borderTop());
2131
2132     if (scrollbar == m_hBar.get())
2133         return IntSize(horizontalScrollbarStart(0), box->height() - box->borderBottom() - scrollbar->height());
2134     
2135     ASSERT_NOT_REACHED();
2136     return IntSize();
2137 }
2138
2139 void RenderLayer::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
2140 {
2141 #if USE(ACCELERATED_COMPOSITING)
2142     if (scrollbar == m_vBar.get()) {
2143         if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
2144             layer->setNeedsDisplayInRect(rect);
2145             return;
2146         }
2147     } else {
2148         if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
2149             layer->setNeedsDisplayInRect(rect);
2150             return;
2151         }
2152     }
2153 #endif
2154     IntRect scrollRect = rect;
2155     RenderBox* box = renderBox();
2156     ASSERT(box);
2157     if (scrollbar == m_vBar.get())
2158         scrollRect.move(verticalScrollbarStart(0, box->width()), box->borderTop());
2159     else
2160         scrollRect.move(horizontalScrollbarStart(0), box->height() - box->borderBottom() - scrollbar->height());
2161     renderer()->repaintRectangle(scrollRect);
2162 }
2163
2164 void RenderLayer::invalidateScrollCornerRect(const IntRect& rect)
2165 {
2166 #if USE(ACCELERATED_COMPOSITING)
2167     if (GraphicsLayer* layer = layerForScrollCorner()) {
2168         layer->setNeedsDisplayInRect(rect);
2169         return;
2170     }
2171 #endif
2172     if (m_scrollCorner)
2173         m_scrollCorner->repaintRectangle(rect);
2174     if (m_resizer)
2175         m_resizer->repaintRectangle(rect);
2176 }
2177
2178 PassRefPtr<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientation)
2179 {
2180     RefPtr<Scrollbar> widget;
2181     RenderObject* actualRenderer = renderer()->node() ? renderer()->node()->shadowAncestorNode()->renderer() : renderer();
2182     bool hasCustomScrollbarStyle = actualRenderer->isBox() && actualRenderer->style()->hasPseudoStyle(SCROLLBAR);
2183     if (hasCustomScrollbarStyle)
2184         widget = RenderScrollbar::createCustomScrollbar(this, orientation, actualRenderer->node());
2185     else {
2186         widget = Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
2187         if (orientation == HorizontalScrollbar)
2188             didAddHorizontalScrollbar(widget.get());
2189         else 
2190             didAddVerticalScrollbar(widget.get());
2191     }
2192     renderer()->document()->view()->addChild(widget.get());        
2193     return widget.release();
2194 }
2195
2196 void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation)
2197 {
2198     RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_hBar : m_vBar;
2199     if (!scrollbar)
2200         return;
2201
2202     if (!scrollbar->isCustomScrollbar()) {
2203         if (orientation == HorizontalScrollbar)
2204             willRemoveHorizontalScrollbar(scrollbar.get());
2205         else
2206             willRemoveVerticalScrollbar(scrollbar.get());
2207     }
2208
2209     scrollbar->removeFromParent();
2210     scrollbar->disconnectFromScrollableArea();
2211     scrollbar = 0;
2212 }
2213
2214 bool RenderLayer::scrollsOverflow() const
2215 {
2216     if (!renderer()->isBox())
2217         return false;
2218
2219     return toRenderBox(renderer())->scrollsOverflow();
2220 }
2221
2222 bool RenderLayer::allowsScrolling() const
2223 {
2224     return (m_hBar && m_hBar->enabled()) || (m_vBar && m_vBar->enabled());
2225 }
2226
2227 void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
2228 {
2229     if (hasScrollbar == hasHorizontalScrollbar())
2230         return;
2231
2232     if (hasScrollbar)
2233         m_hBar = createScrollbar(HorizontalScrollbar);
2234     else
2235         destroyScrollbar(HorizontalScrollbar);
2236
2237     // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
2238     if (m_hBar)
2239         m_hBar->styleChanged();
2240     if (m_vBar)
2241         m_vBar->styleChanged();
2242
2243 #if ENABLE(DASHBOARD_SUPPORT)
2244     // Force an update since we know the scrollbars have changed things.
2245     if (renderer()->document()->hasDashboardRegions())
2246         renderer()->document()->setDashboardRegionsDirty(true);
2247 #endif
2248 }
2249
2250 void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
2251 {
2252     if (hasScrollbar == hasVerticalScrollbar())
2253         return;
2254
2255     if (hasScrollbar)
2256         m_vBar = createScrollbar(VerticalScrollbar);
2257     else
2258         destroyScrollbar(VerticalScrollbar);
2259
2260      // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
2261     if (m_hBar)
2262         m_hBar->styleChanged();
2263     if (m_vBar)
2264         m_vBar->styleChanged();
2265
2266 #if ENABLE(DASHBOARD_SUPPORT)
2267     // Force an update since we know the scrollbars have changed things.
2268     if (renderer()->document()->hasDashboardRegions())
2269         renderer()->document()->setDashboardRegionsDirty(true);
2270 #endif
2271 }
2272
2273 ScrollableArea* RenderLayer::enclosingScrollableArea() const
2274 {
2275     if (RenderLayer* scrollableLayer = enclosingScrollableLayer())
2276         return scrollableLayer;
2277
2278     // FIXME: We should return the frame view here (or possibly an ancestor frame view,
2279     // if the frame view isn't scrollable.
2280     return 0;
2281 }
2282
2283 int RenderLayer::verticalScrollbarWidth(OverlayScrollbarSizeRelevancy relevancy) const
2284 {
2285     if (!m_vBar || (m_vBar->isOverlayScrollbar() && relevancy == IgnoreOverlayScrollbarSize))
2286         return 0;
2287     return m_vBar->width();
2288 }
2289
2290 int RenderLayer::horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy relevancy) const
2291 {
2292     if (!m_hBar || (m_hBar->isOverlayScrollbar() && relevancy == IgnoreOverlayScrollbarSize))
2293         return 0;
2294     return m_hBar->height();
2295 }
2296
2297 IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& absolutePoint) const
2298 {
2299     // Currently the resize corner is either the bottom right corner or the bottom left corner.
2300     // FIXME: This assumes the location is 0, 0. Is this guaranteed to always be the case?
2301     IntSize elementSize = size();
2302     if (renderer()->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
2303         elementSize.setWidth(0);
2304     IntPoint resizerPoint = toPoint(elementSize);
2305     IntPoint localPoint = roundedIntPoint(absoluteToContents(absolutePoint));
2306     return localPoint - resizerPoint;
2307 }
2308
2309 bool RenderLayer::hasOverflowControls() const
2310 {
2311     return m_hBar || m_vBar || m_scrollCorner || renderer()->style()->resize() != RESIZE_NONE;
2312 }
2313
2314 void RenderLayer::positionOverflowControls(const IntSize& offsetFromLayer)
2315 {
2316     if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
2317         return;
2318     
2319     RenderBox* box = renderBox();
2320     if (!box)
2321         return;
2322
2323     const IntRect borderBox = box->pixelSnappedBorderBoxRect();
2324     const IntRect& scrollCorner = scrollCornerRect();
2325     IntRect absBounds(borderBox.location() + offsetFromLayer, borderBox.size());
2326     if (m_vBar)
2327         m_vBar->setFrameRect(IntRect(verticalScrollbarStart(absBounds.x(), absBounds.maxX()),
2328                                      absBounds.y() + box->borderTop(),
2329                                      m_vBar->width(),
2330                                      absBounds.height() - (box->borderTop() + box->borderBottom()) - scrollCorner.height()));
2331
2332     if (m_hBar)
2333         m_hBar->setFrameRect(IntRect(horizontalScrollbarStart(absBounds.x()),
2334                                      absBounds.maxY() - box->borderBottom() - m_hBar->height(),
2335                                      absBounds.width() - (box->borderLeft() + box->borderRight()) - scrollCorner.width(),
2336                                      m_hBar->height()));
2337
2338 #if USE(ACCELERATED_COMPOSITING)
2339     if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
2340         if (m_hBar) {
2341             layer->setPosition(m_hBar->frameRect().location() - offsetFromLayer);
2342             layer->setSize(m_hBar->frameRect().size());
2343         }
2344         layer->setDrawsContent(m_hBar);
2345     }
2346     if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
2347         if (m_vBar) {
2348             layer->setPosition(m_vBar->frameRect().location() - offsetFromLayer);
2349             layer->setSize(m_vBar->frameRect().size());
2350         }
2351         layer->setDrawsContent(m_vBar);
2352     }
2353
2354     if (GraphicsLayer* layer = layerForScrollCorner()) {
2355         const LayoutRect& scrollCornerAndResizer = scrollCornerAndResizerRect();
2356         layer->setPosition(scrollCornerAndResizer.location());
2357         layer->setSize(scrollCornerAndResizer.size());
2358         layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
2359     }
2360 #endif
2361
2362     if (m_scrollCorner)
2363         m_scrollCorner->setFrameRect(scrollCorner);
2364     if (m_resizer)
2365         m_resizer->setFrameRect(resizerCornerRect(this, borderBox));
2366 }
2367
2368 int RenderLayer::scrollWidth() const
2369 {
2370     ASSERT(renderBox());
2371     if (m_scrollDimensionsDirty)
2372         const_cast<RenderLayer*>(this)->computeScrollDimensions();
2373     return snapSizeToPixel(m_scrollSize.width(), renderBox()->clientLeft());
2374 }
2375
2376 int RenderLayer::scrollHeight() const
2377 {
2378     ASSERT(renderBox());
2379     if (m_scrollDimensionsDirty)
2380         const_cast<RenderLayer*>(this)->computeScrollDimensions();
2381     return snapSizeToPixel(m_scrollSize.height(), renderBox()->clientTop());
2382 }
2383
2384 LayoutUnit RenderLayer::overflowTop() const
2385 {
2386     RenderBox* box = renderBox();
2387     LayoutRect overflowRect(box->layoutOverflowRect());
2388     box->flipForWritingMode(overflowRect);
2389     return overflowRect.y();
2390 }
2391
2392 LayoutUnit RenderLayer::overflowBottom() const
2393 {
2394     RenderBox* box = renderBox();
2395     LayoutRect overflowRect(box->layoutOverflowRect());
2396     box->flipForWritingMode(overflowRect);
2397     return overflowRect.maxY();
2398 }
2399
2400 LayoutUnit RenderLayer::overflowLeft() const
2401 {
2402     RenderBox* box = renderBox();
2403     LayoutRect overflowRect(box->layoutOverflowRect());
2404     box->flipForWritingMode(overflowRect);
2405     return overflowRect.x();
2406 }
2407
2408 LayoutUnit RenderLayer::overflowRight() const
2409 {
2410     RenderBox* box = renderBox();
2411     LayoutRect overflowRect(box->layoutOverflowRect());
2412     box->flipForWritingMode(overflowRect);
2413     return overflowRect.maxX();
2414 }
2415
2416 void RenderLayer::computeScrollDimensions()
2417 {
2418     RenderBox* box = renderBox();
2419     ASSERT(box);
2420
2421     m_scrollDimensionsDirty = false;
2422
2423     m_scrollSize.setWidth(overflowRight() - overflowLeft());
2424     m_scrollSize.setHeight(overflowBottom() - overflowTop());
2425
2426     int scrollableLeftOverflow = overflowLeft() - box->borderLeft();
2427     int scrollableTopOverflow = overflowTop() - box->borderTop();
2428     setScrollOrigin(IntPoint(-scrollableLeftOverflow, -scrollableTopOverflow));
2429 }
2430
2431 bool RenderLayer::hasHorizontalOverflow() const
2432 {
2433     ASSERT(!m_scrollDimensionsDirty);
2434
2435     return scrollWidth() > renderBox()->pixelSnappedClientWidth();
2436 }
2437
2438 bool RenderLayer::hasVerticalOverflow() const
2439 {
2440     ASSERT(!m_scrollDimensionsDirty);
2441
2442     return scrollHeight() > renderBox()->pixelSnappedClientHeight();
2443 }
2444
2445 void RenderLayer::updateScrollbarsAfterLayout()
2446 {
2447     RenderBox* box = renderBox();
2448     ASSERT(box);
2449
2450     bool hasHorizontalOverflow = this->hasHorizontalOverflow();
2451     bool hasVerticalOverflow = this->hasVerticalOverflow();
2452
2453     // overflow:scroll should just enable/disable.
2454     if (m_hBar && renderer()->style()->overflowX() == OSCROLL)
2455         m_hBar->setEnabled(hasHorizontalOverflow);
2456     if (m_vBar && renderer()->style()->overflowY() == OSCROLL)
2457         m_vBar->setEnabled(hasVerticalOverflow);
2458
2459     // overflow:auto may need to lay out again if scrollbars got added/removed.
2460     bool autoHorizontalScrollBarChanged = box->hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow);
2461     bool autoVerticalScrollBarChanged = box->hasAutoVerticalScrollbar() && (hasVerticalScrollbar() != hasVerticalOverflow);
2462
2463     if (autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged) {
2464         if (box->hasAutoHorizontalScrollbar())
2465             setHasHorizontalScrollbar(hasHorizontalOverflow);
2466         if (box->hasAutoVerticalScrollbar())
2467             setHasVerticalScrollbar(hasVerticalOverflow);
2468
2469 #if ENABLE(DASHBOARD_SUPPORT)
2470         // Force an update since we know the scrollbars have changed things.
2471         if (renderer()->document()->hasDashboardRegions())
2472             renderer()->document()->setDashboardRegionsDirty(true);
2473 #endif
2474
2475         renderer()->repaint();
2476
2477         if (renderer()->style()->overflowX() == OAUTO || renderer()->style()->overflowY() == OAUTO) {
2478             if (!m_inOverflowRelayout) {
2479                 // Our proprietary overflow: overlay value doesn't trigger a layout.
2480                 m_inOverflowRelayout = true;
2481                 renderer()->setNeedsLayout(true, MarkOnlyThis);
2482                 if (renderer()->isRenderBlock()) {
2483                     RenderBlock* block = toRenderBlock(renderer());
2484                     block->scrollbarsChanged(autoHorizontalScrollBarChanged, autoVerticalScrollBarChanged);
2485                     block->layoutBlock(true);
2486                 } else
2487                     renderer()->layout();
2488                 m_inOverflowRelayout = false;
2489             }
2490         }
2491     }
2492
2493     // Set up the range (and page step/line step).
2494     if (m_hBar) {
2495         int clientWidth = box->pixelSnappedClientWidth();
2496         int pageStep = max(max<int>(clientWidth * Scrollbar::minFractionToStepWhenPaging(), clientWidth - Scrollbar::maxOverlapBetweenPages()), 1);
2497         m_hBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
2498         m_hBar->setProportion(clientWidth, m_scrollSize.width());
2499     }
2500     if (m_vBar) {
2501         int clientHeight = box->pixelSnappedClientHeight();
2502         int pageStep = max(max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
2503         m_vBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
2504         m_vBar->setProportion(clientHeight, m_scrollSize.height());
2505     }
2506
2507     updateScrollableAreaSet((hasHorizontalOverflow || hasVerticalOverflow) && scrollsOverflow());
2508 }
2509
2510 void RenderLayer::updateScrollInfoAfterLayout()
2511 {
2512     RenderBox* box = renderBox();
2513     if (!box)
2514         return;
2515
2516     m_scrollDimensionsDirty = true;
2517     IntSize scrollOffsetOriginal(scrollXOffset(), scrollYOffset());
2518
2519     computeScrollDimensions();
2520
2521     if (box->style()->overflowX() != OMARQUEE) {
2522         // Layout may cause us to be at an invalid scroll position. In this case we need
2523         // to pull our scroll offsets back to the max (or push them up to the min).
2524         int newX = max(0, min<int>(scrollXOffset(), scrollWidth() - box->clientWidth()));
2525         int newY = max(0, min<int>(scrollYOffset(), scrollHeight() - box->clientHeight()));
2526         if (newX != scrollXOffset() || newY != scrollYOffset())
2527             scrollToOffset(newX, newY);
2528     }
2529
2530     updateScrollbarsAfterLayout();
2531
2532     if (scrollOffsetOriginal != scrollOffset())
2533         scrollToOffsetWithoutAnimation(IntPoint(scrollXOffset(), scrollYOffset()));
2534 }
2535
2536 void RenderLayer::paintOverflowControls(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls)
2537 {
2538     // Don't do anything if we have no overflow.
2539     if (!renderer()->hasOverflowClip())
2540         return;
2541
2542     // Overlay scrollbars paint in a second pass through the layer tree so that they will paint
2543     // on top of everything else. If this is the normal painting pass, paintingOverlayControls
2544     // will be false, and we should just tell the root layer that there are overlay scrollbars
2545     // that need to be painted. That will cause the second pass through the layer tree to run,
2546     // and we'll paint the scrollbars then. In the meantime, cache tx and ty so that the 
2547     // second pass doesn't need to re-enter the RenderTree to get it right.
2548     if (hasOverlayScrollbars() && !paintingOverlayControls) {
2549         m_cachedOverlayScrollbarOffset = paintOffset;
2550 #if USE(ACCELERATED_COMPOSITING)
2551         // It's not necessary to do the second pass if the scrollbars paint into layers.
2552         if ((m_hBar && layerForHorizontalScrollbar()) || (m_vBar && layerForVerticalScrollbar()))
2553             return;
2554 #endif
2555         RenderView* renderView = renderer()->view();
2556         renderView->layer()->setContainsDirtyOverlayScrollbars(true);
2557         renderView->frameView()->setContainsScrollableAreaWithOverlayScrollbars(true);
2558         return;
2559     }
2560
2561     // This check is required to avoid painting custom CSS scrollbars twice.
2562     if (paintingOverlayControls && !hasOverlayScrollbars())
2563         return;
2564
2565     IntPoint adjustedPaintOffset = paintOffset;
2566     if (paintingOverlayControls)
2567         adjustedPaintOffset = m_cachedOverlayScrollbarOffset;
2568
2569     // Move the scrollbar widgets if necessary.  We normally move and resize widgets during layout, but sometimes
2570     // widgets can move without layout occurring (most notably when you scroll a document that
2571     // contains fixed positioned elements).
2572     positionOverflowControls(toSize(adjustedPaintOffset));
2573
2574     // Now that we're sure the scrollbars are in the right place, paint them.
2575     if (m_hBar
2576 #if USE(ACCELERATED_COMPOSITING)
2577         && !layerForHorizontalScrollbar()
2578 #endif
2579               )
2580         m_hBar->paint(context, damageRect);
2581     if (m_vBar
2582 #if USE(ACCELERATED_COMPOSITING)
2583         && !layerForVerticalScrollbar()
2584 #endif
2585               )
2586         m_vBar->paint(context, damageRect);
2587
2588 #if USE(ACCELERATED_COMPOSITING)
2589     if (layerForScrollCorner())
2590         return;
2591 #endif
2592
2593     // We fill our scroll corner with white if we have a scrollbar that doesn't run all the way up to the
2594     // edge of the box.
2595     paintScrollCorner(context, adjustedPaintOffset, damageRect);
2596     
2597     // Paint our resizer last, since it sits on top of the scroll corner.
2598     paintResizer(context, adjustedPaintOffset, damageRect);
2599 }
2600
2601 void RenderLayer::paintScrollCorner(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect)
2602 {
2603     RenderBox* box = renderBox();
2604     ASSERT(box);
2605
2606     IntRect absRect = scrollCornerRect();
2607     absRect.moveBy(paintOffset);
2608     if (!absRect.intersects(damageRect))
2609         return;
2610
2611     if (context->updatingControlTints()) {
2612         updateScrollCornerStyle();
2613         return;
2614     }
2615
2616     if (m_scrollCorner) {
2617         m_scrollCorner->paintIntoRect(context, paintOffset, absRect);
2618         return;
2619     }
2620
2621     // We don't want to paint white if we have overlay scrollbars, since we need
2622     // to see what is behind it.
2623     if (!hasOverlayScrollbars())
2624         context->fillRect(absRect, Color::white, box->style()->colorSpace());
2625 }
2626
2627 void RenderLayer::drawPlatformResizerImage(GraphicsContext* context, IntRect resizerCornerRect)
2628 {
2629     float deviceScaleFactor = WebCore::deviceScaleFactor(renderer()->frame());
2630
2631     RefPtr<Image> resizeCornerImage;
2632     IntSize cornerResizerSize;
2633     if (deviceScaleFactor >= 2) {
2634         DEFINE_STATIC_LOCAL(Image*, resizeCornerImageHiRes, (Image::loadPlatformResource("textAreaResizeCorner@2x").leakRef()));
2635         resizeCornerImage = resizeCornerImageHiRes;
2636         cornerResizerSize = resizeCornerImage->size();
2637         cornerResizerSize.scale(0.5f);
2638     } else {
2639         DEFINE_STATIC_LOCAL(Image*, resizeCornerImageLoRes, (Image::loadPlatformResource("textAreaResizeCorner").leakRef()));
2640         resizeCornerImage = resizeCornerImageLoRes;
2641         cornerResizerSize = resizeCornerImage->size();
2642     }
2643
2644     if (renderer()->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
2645         context->save();
2646         context->translate(resizerCornerRect.x() + cornerResizerSize.width(), resizerCornerRect.y() + resizerCornerRect.height() - cornerResizerSize.height());
2647         context->scale(FloatSize(-1.0, 1.0));
2648         context->drawImage(resizeCornerImage.get(), renderer()->style()->colorSpace(), IntRect(IntPoint(), cornerResizerSize));
2649         context->restore();
2650         return;
2651     }
2652     IntRect imageRect(resizerCornerRect.maxXMaxYCorner() - cornerResizerSize, cornerResizerSize);
2653     context->drawImage(resizeCornerImage.get(), renderer()->style()->colorSpace(), imageRect);
2654 }
2655
2656 void RenderLayer::paintResizer(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect)
2657 {
2658     if (renderer()->style()->resize() == RESIZE_NONE)
2659         return;
2660
2661     RenderBox* box = renderBox();
2662     ASSERT(box);
2663
2664     IntRect absRect = resizerCornerRect(this, box->pixelSnappedBorderBoxRect());
2665     absRect.moveBy(paintOffset);
2666     if (!absRect.intersects(damageRect))
2667         return;
2668
2669     if (context->updatingControlTints()) {
2670         updateResizerStyle();
2671         return;
2672     }
2673     
2674     if (m_resizer) {
2675         m_resizer->paintIntoRect(context, paintOffset, absRect);
2676         return;
2677     }
2678
2679     drawPlatformResizerImage(context, absRect);
2680
2681     // Draw a frame around the resizer (1px grey line) if there are any scrollbars present.
2682     // Clipping will exclude the right and bottom edges of this frame.
2683     if (!hasOverlayScrollbars() && (m_vBar || m_hBar)) {
2684         GraphicsContextStateSaver stateSaver(*context);
2685         context->clip(absRect);
2686         IntRect largerCorner = absRect;
2687         largerCorner.setSize(IntSize(largerCorner.width() + 1, largerCorner.height() + 1));
2688         context->setStrokeColor(Color(makeRGB(217, 217, 217)), ColorSpaceDeviceRGB);
2689         context->setStrokeThickness(1.0f);
2690         context->setFillColor(Color::transparent, ColorSpaceDeviceRGB);
2691         context->drawRect(largerCorner);
2692     }
2693 }
2694
2695 bool RenderLayer::isPointInResizeControl(const IntPoint& absolutePoint) const
2696 {
2697     if (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE)
2698         return false;
2699     
2700     RenderBox* box = renderBox();
2701     ASSERT(box);
2702
2703     IntPoint localPoint = roundedIntPoint(absoluteToContents(absolutePoint));
2704
2705     IntRect localBounds(0, 0, box->pixelSnappedWidth(), box->pixelSnappedHeight());
2706     return resizerCornerRect(this, localBounds).contains(localPoint);
2707 }
2708     
2709 bool RenderLayer::hitTestOverflowControls(HitTestResult& result, const IntPoint& localPoint)
2710 {
2711     if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
2712         return false;
2713
2714     RenderBox* box = renderBox();
2715     ASSERT(box);
2716     
2717     IntRect resizeControlRect;
2718     if (renderer()->style()->resize() != RESIZE_NONE) {
2719         resizeControlRect = resizerCornerRect(this, box->pixelSnappedBorderBoxRect());
2720         if (resizeControlRect.contains(localPoint))
2721             return true;
2722     }
2723
2724     int resizeControlSize = max(resizeControlRect.height(), 0);
2725
2726     if (m_vBar && m_vBar->shouldParticipateInHitTesting()) {
2727         LayoutRect vBarRect(verticalScrollbarStart(0, box->width()),
2728                             box->borderTop(),
2729                             m_vBar->width(),
2730                             box->height() - (box->borderTop() + box->borderBottom()) - (m_hBar ? m_hBar->height() : resizeControlSize));
2731         if (vBarRect.contains(localPoint)) {
2732             result.setScrollbar(m_vBar.get());
2733             return true;
2734         }
2735     }
2736
2737     resizeControlSize = max(resizeControlRect.width(), 0);
2738     if (m_hBar && m_hBar->shouldParticipateInHitTesting()) {
2739         LayoutRect hBarRect(horizontalScrollbarStart(0),
2740                             box->height() - box->borderBottom() - m_hBar->height(),
2741                             box->width() - (box->borderLeft() + box->borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize),
2742                             m_hBar->height());
2743         if (hBarRect.contains(localPoint)) {
2744             result.setScrollbar(m_hBar.get());
2745             return true;
2746         }
2747     }
2748
2749     return false;
2750 }
2751
2752 bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
2753 {
2754     return ScrollableArea::scroll(direction, granularity, multiplier);
2755 }
2756
2757 void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot, RenderRegion* region, PaintLayerFlags paintFlags)
2758 {
2759     OverlapTestRequestMap overlapTestRequests;
2760     paintLayer(this, context, damageRect, paintBehavior, paintingRoot, region, &overlapTestRequests, paintFlags);
2761     OverlapTestRequestMap::iterator end = overlapTestRequests.end();
2762     for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it)
2763         it->first->setOverlapTestResult(false);
2764 }
2765
2766 void RenderLayer::paintOverlayScrollbars(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot)
2767 {
2768     if (!m_containsDirtyOverlayScrollbars)
2769         return;
2770     paintLayer(this, context, damageRect, paintBehavior, paintingRoot, 0, 0, PaintLayerHaveTransparency | PaintLayerTemporaryClipRects 
2771                | PaintLayerPaintingOverlayScrollbars);
2772     m_containsDirtyOverlayScrollbars = false;
2773 }
2774
2775 #ifndef DISABLE_ROUNDED_CORNER_CLIPPING
2776 static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLayer)
2777 {
2778     if (startLayer == endLayer)
2779         return true;
2780     
2781     RenderView* view = startLayer->renderer()->view();
2782     for (RenderBlock* currentBlock = startLayer->renderer()->containingBlock(); currentBlock && currentBlock != view; currentBlock = currentBlock->containingBlock()) {
2783         if (currentBlock->layer() == endLayer)
2784             return true;
2785     }
2786     
2787     return false;
2788 }
2789 #endif
2790
2791 void RenderLayer::clipToRect(RenderLayer* rootLayer, GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect,
2792                              BorderRadiusClippingRule rule)
2793 {
2794     if (clipRect.rect() == paintDirtyRect)
2795         return;
2796     context->save();
2797     context->clip(pixelSnappedIntRect(clipRect.rect()));
2798     
2799     if (!clipRect.hasRadius())
2800         return;
2801
2802 #ifndef DISABLE_ROUNDED_CORNER_CLIPPING
2803     // If the clip rect has been tainted by a border radius, then we have to walk up our layer chain applying the clips from
2804     // any layers with overflow. The condition for being able to apply these clips is that the overflow object be in our
2805     // containing block chain so we check that also.
2806     for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer->parent()) {
2807         if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->hasBorderRadius() && inContainingBlockChain(this, layer)) {
2808                 LayoutPoint delta;
2809                 layer->convertToLayerCoords(rootLayer, delta);
2810                 context->addRoundedRectClip(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, layer->size())));
2811         }
2812
2813         if (layer == rootLayer)
2814             break;
2815     }
2816 #endif
2817 }
2818
2819 void RenderLayer::restoreClip(GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect)
2820 {
2821     if (clipRect.rect() == paintDirtyRect)
2822         return;
2823     context->restore();
2824 }
2825
2826 static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, const RenderLayer* rootLayer, const RenderLayer* layer)
2827 {
2828     Vector<OverlapTestRequestClient*> overlappedRequestClients;
2829     OverlapTestRequestMap::iterator end = overlapTestRequests.end();
2830     LayoutRect boundingBox = layer->boundingBox(rootLayer);
2831     for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it) {
2832         if (!boundingBox.intersects(it->second))
2833             continue;
2834
2835         it->first->setOverlapTestResult(true);
2836         overlappedRequestClients.append(it->first);
2837     }
2838     for (size_t i = 0; i < overlappedRequestClients.size(); ++i)
2839         overlapTestRequests.remove(overlappedRequestClients[i]);
2840 }
2841
2842 #if USE(ACCELERATED_COMPOSITING)
2843 static bool shouldDoSoftwarePaint(const RenderLayer* layer, bool paintingReflection)
2844 {
2845     return paintingReflection && !layer->has3DTransform();
2846 }
2847 #endif
2848     
2849 static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
2850 {
2851     // Avoid painting descendants of the root layer when stylesheets haven't loaded. This eliminates FOUC.
2852     // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
2853     // will do a full repaint().
2854     if (layer->renderer()->document()->didLayoutWithPendingStylesheets() && !layer->renderer()->isRenderView() && !layer->renderer()->isRoot())
2855         return true;
2856
2857     // Avoid painting all layers if the document is in a state where visual updates aren't allowed.
2858     // A full repaint will occur in Document::implicitClose() if painting is suppressed here.
2859     if (!layer->renderer()->document()->visualUpdatesAllowed())
2860         return true;
2861
2862     return false;
2863 }
2864
2865
2866 void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* context,
2867                         const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior,
2868                         RenderObject* paintingRoot, RenderRegion* region, OverlapTestRequestMap* overlapTestRequests,
2869                         PaintLayerFlags paintFlags)
2870 {
2871 #if USE(ACCELERATED_COMPOSITING)
2872     if (isComposited()) {
2873         // The updatingControlTints() painting pass goes through compositing layers,
2874         // but we need to ensure that we don't cache clip rects computed with the wrong root in this case.
2875         if (context->updatingControlTints() || (paintBehavior & PaintBehaviorFlattenCompositingLayers))
2876             paintFlags |= PaintLayerTemporaryClipRects;
2877         else if (!backing()->paintsIntoWindow() && !backing()->paintsIntoCompositedAncestor() && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection) && !(rootLayer->containsDirtyOverlayScrollbars() && (paintFlags & PaintLayerPaintingOverlayScrollbars))) {
2878             // If this RenderLayer should paint into its backing, that will be done via RenderLayerBacking::paintIntoLayer().
2879             return;
2880         }
2881     }
2882 #endif
2883
2884     // Non self-painting leaf layers don't need to be painted as their renderer() should properly paint itself.
2885     if (!isSelfPaintingLayer() && !firstChild())
2886         return;
2887
2888     if (shouldSuppressPaintingLayer(this))
2889         return;
2890     
2891     // If this layer is totally invisible then there is nothing to paint.
2892     if (!renderer()->opacity())
2893         return;
2894
2895     if (paintsWithTransparency(paintBehavior))
2896         paintFlags |= PaintLayerHaveTransparency;
2897
2898     // PaintLayerAppliedTransform is used in RenderReplica, to avoid applying the transform twice.
2899     if (paintsWithTransform(paintBehavior) && !(paintFlags & PaintLayerAppliedTransform)) {
2900         TransformationMatrix layerTransform = renderableTransform(paintBehavior);
2901         // If the transform can't be inverted, then don't paint anything.
2902         if (!layerTransform.isInvertible())
2903             return;
2904
2905         // If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency
2906         // layer from the parent now, assuming there is a parent
2907         if (paintFlags & PaintLayerHaveTransparency) {
2908             if (parent())
2909                 parent()->beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
2910             else
2911                 beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
2912         }
2913
2914         // Make sure the parent's clip rects have been calculated.
2915         ClipRect clipRect = paintDirtyRect;
2916         if (parent()) {
2917             clipRect = backgroundClipRect(rootLayer, region, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects);
2918             clipRect.intersect(paintDirtyRect);
2919         
2920             // Push the parent coordinate space's clip.
2921             parent()->clipToRect(rootLayer, context, paintDirtyRect, clipRect);
2922         }
2923
2924         // Adjust the transform such that the renderer's upper left corner will paint at (0,0) in user space.
2925         // This involves subtracting out the position of the layer in our current coordinate space.
2926         LayoutPoint delta;
2927         convertToLayerCoords(rootLayer, delta);
2928         TransformationMatrix transform(layerTransform);
2929         transform.translateRight(delta.x(), delta.y());
2930         
2931         // Apply the transform.
2932         {
2933             GraphicsContextStateSaver stateSaver(*context);
2934             context->concatCTM(transform.toAffineTransform());
2935
2936             // Now do a paint with the root layer shifted to be us.
2937             paintLayerContentsAndReflection(this, context, transform.inverse().mapRect(paintDirtyRect), paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
2938         }        
2939
2940         // Restore the clip.
2941         if (parent())
2942             parent()->restoreClip(context, paintDirtyRect, clipRect);
2943
2944         return;
2945     }
2946     
2947     paintLayerContentsAndReflection(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
2948 }
2949
2950 void RenderLayer::paintLayerContentsAndReflection(RenderLayer* rootLayer, GraphicsContext* context,
2951                         const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior,
2952                         RenderObject* paintingRoot, RenderRegion* region, OverlapTestRequestMap* overlapTestRequests,
2953                         PaintLayerFlags paintFlags)
2954 {
2955     PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform);
2956
2957     // Paint the reflection first if we have one.
2958     if (m_reflection && !m_paintingInsideReflection) {
2959         // Mark that we are now inside replica painting.
2960         m_paintingInsideReflection = true;
2961         reflectionLayer()->paintLayer(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags | PaintLayerPaintingReflection);
2962         m_paintingInsideReflection = false;
2963     }
2964
2965     localPaintFlags |= PaintLayerPaintingCompositingAllPhases;
2966     paintLayerContents(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags);
2967 }
2968
2969 void RenderLayer::paintLayerContents(RenderLayer* rootLayer, GraphicsContext* context, 
2970                         const LayoutRect& parentPaintDirtyRect, PaintBehavior paintBehavior,
2971                         RenderObject* paintingRoot, RenderRegion* region, OverlapTestRequestMap* overlapTestRequests,
2972                         PaintLayerFlags paintFlags)
2973 {
2974     PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform);
2975     bool haveTransparency = localPaintFlags & PaintLayerHaveTransparency;
2976     bool isSelfPaintingLayer = this->isSelfPaintingLayer();
2977     bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars;
2978     // Outline always needs to be painted even if we have no visible content.
2979     bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars;
2980     bool shouldPaintContent = m_hasVisibleContent && isSelfPaintingLayer && !isPaintingOverlayScrollbars;
2981
2982     // Calculate the clip rects we should use only when we need them.
2983     LayoutRect layerBounds;
2984     ClipRect damageRect, clipRectToApply, outlineRect;
2985     LayoutPoint paintOffset;
2986     LayoutRect paintDirtyRect = parentPaintDirtyRect;
2987     
2988     bool useClipRect = true;
2989     GraphicsContext* transparencyLayerContext = context;
2990     
2991     // Ensure our lists are up-to-date.
2992     updateLayerListsIfNeeded();
2993
2994 #if ENABLE(CSS_FILTERS)
2995     FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilters());
2996     if (filterPainter.haveFilterEffect() && !context->paintingDisabled()) {
2997         LayoutPoint rootLayerOffset;
2998         convertToLayerCoords(rootLayer, rootLayerOffset);
2999         RenderLayerFilterInfo* filterInfo = this->filterInfo();
3000         ASSERT(filterInfo);
3001         LayoutRect filterRepaintRect = filterInfo->dirtySourceRect();
3002         filterRepaintRect.move(rootLayerOffset.x(), rootLayerOffset.y());
3003         if (filterPainter.prepareFilterEffect(this, calculateLayerBounds(this, rootLayer, 0), parentPaintDirtyRect, filterRepaintRect)) {
3004             // Now we know for sure, that the source image will be updated, so we can revert our tracking repaint rect back to zero.
3005             filterInfo->resetDirtySourceRect();
3006
3007             // Rewire the old context to a memory buffer, so that we can capture the contents of the layer.
3008             // NOTE: We saved the old context in the "transparencyLayerContext" local variable, to be able to start a transparency layer
3009             // on the original context and avoid duplicating "beginFilterEffect" after each transpareny layer call. Also, note that 
3010             // beginTransparencyLayers will only create a single lazy transparency layer, even though it is called twice in this method.
3011             context = filterPainter.beginFilterEffect(context);
3012
3013             // Check that we didn't fail to allocate the graphics context for the offscreen buffer.
3014             if (filterPainter.hasStartedFilterEffect()) {
3015                 paintDirtyRect = filterPainter.repaintRect();
3016                 // If the filter needs the full source image, we need to avoid using the clip rectangles.
3017                 // Otherwise, if for example this layer has overflow:hidden, a drop shadow will not compute correctly.
3018                 // Note that we will still apply the clipping on the final rendering of the filter.
3019                 useClipRect = !filterRenderer()->hasFilterThatMovesPixels();
3020             }
3021         }
3022     }
3023 #endif
3024     
3025     if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
3026         calculateRects(rootLayer, region, (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
3027         paintOffset = toPoint(layerBounds.location() - renderBoxLocation());
3028     }
3029
3030     bool forceBlackText = paintBehavior & PaintBehaviorForceBlackText;
3031     bool selectionOnly  = paintBehavior & PaintBehaviorSelectionOnly;
3032     
3033     // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
3034     // is done by passing a nil paintingRoot down to our renderer (as if no paintingRoot was ever set).
3035     // Else, our renderer tree may or may not contain the painting root, so we pass that root along
3036     // so it will be tested against as we descend through the renderers.
3037     RenderObject* paintingRootForRenderer = 0;
3038     if (paintingRoot && !renderer()->isDescendantOf(paintingRoot))
3039         paintingRootForRenderer = paintingRoot;
3040
3041     if (overlapTestRequests && isSelfPaintingLayer)
3042         performOverlapTests(*overlapTestRequests, rootLayer, this);
3043
3044     // We want to paint our layer, but only if we intersect the damage rect.
3045     shouldPaintContent &= intersectsDamageRect(layerBounds, damageRect.rect(), rootLayer);
3046     
3047     if (localPaintFlags & PaintLayerPaintingCompositingBackgroundPhase) {
3048         if (shouldPaintContent && !selectionOnly) {
3049             // Begin transparency layers lazily now that we know we have to paint something.
3050             if (haveTransparency)
3051                 beginTransparencyLayers(transparencyLayerContext, rootLayer, paintDirtyRect, paintBehavior);
3052         
3053             if (useClipRect) {
3054                 // Paint our background first, before painting any child layers.
3055                 // Establish the clip used to paint our background.
3056                 clipToRect(rootLayer, context, paintDirtyRect, damageRect, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
3057             }
3058             
3059             // Paint the background.
3060             PaintInfo paintInfo(context, pixelSnappedIntRect(damageRect.rect()), PaintPhaseBlockBackground, false, paintingRootForRenderer, region, 0);
3061             renderer()->paint(paintInfo, paintOffset);
3062
3063             if (useClipRect) {
3064                 // Restore the clip.
3065                 restoreClip(context, paintDirtyRect, damageRect);
3066             }
3067         }
3068
3069         // Now walk the sorted list of children with negative z-indices.
3070         paintList(negZOrderList(), rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags);
3071     }
3072     
3073     if (localPaintFlags & PaintLayerPaintingCompositingForegroundPhase) {
3074         // Now establish the appropriate clip and paint our child RenderObjects.
3075         if (shouldPaintContent && !clipRectToApply.isEmpty()) {
3076             // Begin transparency layers lazily now that we know we have to paint something.
3077             if (haveTransparency)
3078                 beginTransparencyLayers(transparencyLayerContext, rootLayer, paintDirtyRect, paintBehavior);
3079
3080             if (useClipRect) {
3081                 // Set up the clip used when painting our children.
3082                 clipToRect(rootLayer, context, paintDirtyRect, clipRectToApply);
3083             }
3084             
3085             PaintInfo paintInfo(context, pixelSnappedIntRect(clipRectToApply.rect()),
3086                                 selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds,
3087                                 forceBlackText, paintingRootForRenderer, region, 0);
3088             renderer()->paint(paintInfo, paintOffset);
3089             if (!selectionOnly) {
3090                 paintInfo.phase = PaintPhaseFloat;
3091                 renderer()->paint(paintInfo, paintOffset);
3092                 paintInfo.phase = PaintPhaseForeground;
3093                 paintInfo.overlapTestRequests = overlapTestRequests;
3094                 renderer()->paint(paintInfo, paintOffset);
3095                 paintInfo.phase = PaintPhaseChildOutlines;
3096                 renderer()->paint(paintInfo, paintOffset);
3097             }
3098
3099             if (useClipRect) {
3100                 // Now restore our clip.
3101                 restoreClip(context, paintDirtyRect, clipRectToApply);
3102             }
3103         }
3104
3105         if (shouldPaintOutline && !outlineRect.isEmpty()) {
3106             // Paint our own outline
3107             PaintInfo paintInfo(context, pixelSnappedIntRect(outlineRect.rect()), PaintPhaseSelfOutline, false, paintingRootForRenderer, region, 0);
3108             clipToRect(rootLayer, context, paintDirtyRect, outlineRect, DoNotIncludeSelfForBorderRadius);
3109             renderer()->paint(paintInfo, paintOffset);
3110             restoreClip(context, paintDirtyRect, outlineRect);
3111         }
3112     
3113         // Paint any child layers that have overflow.
3114         paintList(m_normalFlowList, rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags);
3115     
3116         // Now walk the sorted list of children with positive z-indices.
3117         paintList(posZOrderList(), rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, localPaintFlags);
3118     }
3119     
3120     if ((localPaintFlags & PaintLayerPaintingCompositingMaskPhase) && shouldPaintContent && renderer()->hasMask() && !selectionOnly) {
3121         if (useClipRect)
3122             clipToRect(rootLayer, context, paintDirtyRect, damageRect, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
3123
3124         // Paint the mask.
3125         PaintInfo paintInfo(context, pixelSnappedIntRect(damageRect.rect()), PaintPhaseMask, false, paintingRootForRenderer, region, 0);
3126         renderer()->paint(paintInfo, paintOffset);
3127         
3128         if (useClipRect) {
3129             // Restore the clip.
3130             restoreClip(context, paintDirtyRect, damageRect);
3131         }
3132     }
3133
3134     if (isPaintingOverlayScrollbars) {
3135         clipToRect(rootLayer, context, paintDirtyRect, damageRect);
3136         paintOverflowControls(context, roundedIntPoint(paintOffset), pixelSnappedIntRect(damageRect.rect()), true);
3137         restoreClip(context, paintDirtyRect, damageRect);
3138     }
3139
3140 #if ENABLE(CSS_FILTERS)
3141     if (filterPainter.hasStartedFilterEffect()) {
3142         // Apply the correct clipping (ie. overflow: hidden).
3143         clipToRect(rootLayer, transparencyLayerContext, paintDirtyRect, damageRect);
3144         context = filterPainter.applyFilterEffect();
3145         restoreClip(transparencyLayerContext, paintDirtyRect, damageRect);
3146     }
3147 #endif
3148
3149     // Make sure that we now use the original transparency context.
3150     ASSERT(transparencyLayerContext == context);
3151     
3152     // End our transparency layer
3153     if (haveTransparency && m_usedTransparency && !m_paintingInsideReflection) {
3154         context->endTransparencyLayer();
3155         context->restore();
3156         m_usedTransparency = false;
3157     }
3158 }
3159
3160 void RenderLayer::paintList(Vector<RenderLayer*>* list, RenderLayer* rootLayer, GraphicsContext* context,
3161                             const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior,
3162                             RenderObject* paintingRoot, RenderRegion* region, OverlapTestRequestMap* overlapTestRequests,
3163                             PaintLayerFlags paintFlags)
3164 {
3165     if (!list)
3166         return;
3167
3168 #if !ASSERT_DISABLED
3169     LayerListMutationDetector mutationChecker(this);
3170 #endif
3171
3172     for (size_t i = 0; i < list->size(); ++i) {
3173         RenderLayer* childLayer = list->at(i);
3174         if (!childLayer->isPaginated())
3175             childLayer->paintLayer(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
3176         else
3177             paintPaginatedChildLayer(childLayer, rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
3178     }
3179 }
3180
3181 void RenderLayer::paintPaginatedChildLayer(RenderLayer* childLayer, RenderLayer* rootLayer, GraphicsContext* context,
3182                                            const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior,
3183                                            RenderObject* paintingRoot, RenderRegion* region, OverlapTestRequestMap* overlapTestRequests,
3184                                            PaintLayerFlags paintFlags)
3185 {
3186     // We need to do multiple passes, breaking up our child layer into strips.
3187     Vector<RenderLayer*> columnLayers;
3188     RenderLayer* ancestorLayer = isNormalFlowOnly() ? parent() : stackingContext();
3189     for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
3190         if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
3191             columnLayers.append(curr);
3192         if (curr == ancestorLayer)
3193             break;
3194     }
3195
3196     // It is possible for paintLayer() to be called after the child layer ceases to be paginated but before
3197     // updateLayerPositions() is called and resets the isPaginated() flag, see <rdar://problem/10098679>.
3198     // If this is the case, just bail out, since the upcoming call to updateLayerPositions() will repaint the layer.
3199     if (!columnLayers.size())
3200         return;
3201
3202     paintChildLayerIntoColumns(childLayer, rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags, columnLayers, columnLayers.size() - 1);
3203 }
3204
3205 void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLayer* rootLayer, GraphicsContext* context,
3206                                              const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior,
3207                                              RenderObject* paintingRoot, RenderRegion* region, OverlapTestRequestMap* overlapTestRequests,
3208                                              PaintLayerFlags paintFlags, const Vector<RenderLayer*>& columnLayers, size_t colIndex)
3209 {
3210     RenderBlock* columnBlock = toRenderBlock(columnLayers[colIndex]->renderer());
3211
3212     ASSERT(columnBlock && columnBlock->hasColumns());
3213     if (!columnBlock || !columnBlock->hasColumns())
3214         return;
3215     
3216     LayoutPoint layerOffset;
3217     // FIXME: It looks suspicious to call convertToLayerCoords here
3218     // as canUseConvertToLayerCoords is true for this layer.
3219     columnBlock->layer()->convertToLayerCoords(rootLayer, layerOffset);
3220     
3221     bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
3222
3223     ColumnInfo* colInfo = columnBlock->columnInfo();
3224     unsigned colCount = columnBlock->columnCount(colInfo);
3225     int currLogicalTopOffset = 0;
3226     for (unsigned i = 0; i < colCount; i++) {
3227         // For each rect, we clip to the rect, and then we adjust our coords.
3228         LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
3229         columnBlock->flipForWritingMode(colRect);
3230         int logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - columnBlock->logicalLeftOffsetForContent();
3231         LayoutSize offset;
3232         if (isHorizontal) {
3233             if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3234                 offset = LayoutSize(logicalLeftOffset, currLogicalTopOffset);
3235             else
3236                 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - columnBlock->borderTop() - columnBlock->paddingTop());
3237         } else {
3238             if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3239                 offset = LayoutSize(currLogicalTopOffset, logicalLeftOffset);
3240             else
3241                 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnBlock->borderLeft() - columnBlock->paddingLeft(), 0);
3242         }
3243
3244         colRect.moveBy(layerOffset);
3245
3246         LayoutRect localDirtyRect(paintDirtyRect);
3247         localDirtyRect.intersect(colRect);
3248         
3249         if (!localDirtyRect.isEmpty()) {
3250             GraphicsContextStateSaver stateSaver(*context);
3251             
3252             // Each strip pushes a clip, since column boxes are specified as being
3253             // like overflow:hidden.
3254             context->clip(colRect);
3255
3256             if (!colIndex) {
3257                 // Apply a translation transform to change where the layer paints.
3258                 TransformationMatrix oldTransform;
3259                 bool oldHasTransform = childLayer->transform();
3260                 if (oldHasTransform)
3261                     oldTransform = *childLayer->transform();
3262                 TransformationMatrix newTransform(oldTransform);
3263                 newTransform.translateRight(offset.width(), offset.height());
3264                 
3265                 childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform));
3266                 childLayer->paintLayer(rootLayer, context, localDirtyRect, paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
3267                 if (oldHasTransform)
3268                     childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform));
3269                 else
3270                     childLayer->m_transform.clear();
3271             } else {
3272                 // Adjust the transform such that the renderer's upper left corner will paint at (0,0) in user space.
3273                 // This involves subtracting out the position of the layer in our current coordinate space.
3274                 LayoutPoint childOffset;
3275                 columnLayers[colIndex - 1]->convertToLayerCoords(rootLayer, childOffset);
3276                 TransformationMatrix transform;
3277                 transform.translateRight(childOffset.x() + offset.width(), childOffset.y() + offset.height());
3278                 
3279                 // Apply the transform.
3280                 context->concatCTM(transform.toAffineTransform());
3281
3282                 // Now do a paint with the root layer shifted to be the next multicol block.
3283                 paintChildLayerIntoColumns(childLayer, columnLayers[colIndex - 1], context, transform.inverse().mapRect(localDirtyRect), paintBehavior, 
3284                                            paintingRoot, region, overlapTestRequests, paintFlags, 
3285                                            columnLayers, colIndex - 1);
3286             }
3287         }
3288
3289         // Move to the next position.
3290         int blockDelta = isHorizontal ? colRect.height() : colRect.width();
3291         if (columnBlock->style()->isFlippedBlocksWritingMode())
3292             currLogicalTopOffset += blockDelta;
3293         else
3294             currLogicalTopOffset -= blockDelta;
3295     }
3296 }
3297
3298 static inline LayoutRect frameVisibleRect(RenderObject* renderer)
3299 {
3300     FrameView* frameView = renderer->document()->view();
3301     if (!frameView)
3302         return LayoutRect();
3303
3304     return frameView->visibleContentRect();
3305 }
3306
3307 bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result)
3308 {
3309     renderer()->document()->updateLayout();
3310     
3311     LayoutRect hitTestArea = renderer()->isRenderFlowThread() ? toRenderFlowThread(renderer())->borderBoxRect() : renderer()->view()->documentRect();
3312     if (!request.ignoreClipping())
3313         hitTestArea.intersect(frameVisibleRect(renderer()));
3314
3315     RenderLayer* insideLayer = hitTestLayer(this, 0, request, result, hitTestArea, result.point(), false);
3316     if (!insideLayer) {
3317         // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down, 
3318         // return ourselves. We do this so mouse events continue getting delivered after a drag has 
3319         // exited the WebView, and so hit testing over a scrollbar hits the content document.
3320         if ((request.active() || request.release()) && renderer()->isRenderView()) {
3321             renderer()->updateHitTestResult(result, result.point());
3322             insideLayer = this;
3323         }
3324     }
3325
3326     // Now determine if the result is inside an anchor - if the urlElement isn't already set.
3327     Node* node = result.innerNode();
3328     if (node && !result.URLElement())
3329         result.setURLElement(static_cast<Element*>(node->enclosingLinkEventParentOrSelf()));
3330
3331     // Next set up the correct :hover/:active state along the new chain.
3332     updateHoverActiveState(request, result);
3333     
3334     // Now return whether we were inside this layer (this will always be true for the root
3335     // layer).
3336     return insideLayer;
3337 }
3338
3339 Node* RenderLayer::enclosingElement() const
3340 {
3341     for (RenderObject* r = renderer(); r; r = r->parent()) {
3342         if (Node* e = r->node())
3343             return e;
3344     }
3345     ASSERT_NOT_REACHED();
3346     return 0;
3347 }
3348
3349 // Compute the z-offset of the point in the transformState.
3350 // This is effectively projecting a ray normal to the plane of ancestor, finding where that
3351 // ray intersects target, and computing the z delta between those two points.
3352 static double computeZOffset(const HitTestingTransformState& transformState)
3353 {
3354     // We got an affine transform, so no z-offset
3355     if (transformState.m_accumulatedTransform.isAffine())
3356         return 0;
3357
3358     // Flatten the point into the target plane
3359     FloatPoint targetPoint = transformState.mappedPoint();
3360     
3361     // Now map the point back through the transform, which computes Z.
3362     FloatPoint3D backmappedPoint = transformState.m_accumulatedTransform.mapPoint(FloatPoint3D(targetPoint));
3363     return backmappedPoint.z();
3364 }
3365
3366 PassRefPtr<HitTestingTransformState> RenderLayer::createLocalTransformState(RenderLayer* rootLayer, RenderLayer* containerLayer,
3367                                         const LayoutRect& hitTestRect, const LayoutPoint& hitTestPoint,
3368                                         const HitTestingTransformState* containerTransformState) const
3369 {
3370     RefPtr<HitTestingTransformState> transformState;
3371     LayoutPoint offset;
3372     if (containerTransformState) {
3373         // If we're already computing transform state, then it's relative to the container (which we know is non-null).
3374         transformState = HitTestingTransformState::create(*containerTransformState);
3375         convertToLayerCoords(containerLayer, offset);
3376     } else {
3377         // If this is the first time we need to make transform state, then base it off of hitTestPoint,
3378         // which is relative to rootLayer.
3379         transformState = HitTestingTransformState::create(hitTestPoint, FloatQuad(hitTestRect));
3380         convertToLayerCoords(rootLayer, offset);
3381     }
3382     
3383     RenderObject* containerRenderer = containerLayer ? containerLayer->renderer() : 0;
3384     if (renderer()->shouldUseTransformFromContainer(containerRenderer)) {
3385         TransformationMatrix containerTransform;
3386         renderer()->getTransformFromContainer(containerRenderer, toLayoutSize(offset), containerTransform);
3387         transformState->applyTransform(containerTransform, HitTestingTransformState::AccumulateTransform);
3388     } else {
3389         transformState->translate(offset.x(), offset.y(), HitTestingTransformState::AccumulateTransform);
3390     }
3391     
3392     return transformState;
3393 }
3394
3395
3396 static bool isHitCandidate(const RenderLayer* hitLayer, bool canDepthSort, double* zOffset, const HitTestingTransformState* transformState)
3397 {
3398     if (!hitLayer)
3399         return false;
3400
3401     // The hit layer is depth-sorting with other layers, so just say that it was hit.
3402     if (canDepthSort)
3403         return true;
3404     
3405     // We need to look at z-depth to decide if this layer was hit.
3406     if (zOffset) {
3407         ASSERT(transformState);
3408         // This is actually computing our z, but that's OK because the hitLayer is coplanar with us.
3409         double childZOffset = computeZOffset(*transformState);
3410         if (childZOffset > *zOffset) {
3411             *zOffset = childZOffset;
3412             return true;
3413         }
3414         return false;
3415     }
3416
3417     return true;
3418 }
3419
3420 // hitTestPoint and hitTestRect are relative to rootLayer.
3421 // A 'flattening' layer is one preserves3D() == false.
3422 // transformState.m_accumulatedTransform holds the transform from the containing flattening layer.
3423 // transformState.m_lastPlanarPoint is the hitTestPoint in the plane of the containing flattening layer.
3424 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of the containing flattening layer.
3425 // 
3426 // If zOffset is non-null (which indicates that the caller wants z offset information), 
3427 //  *zOffset on return is the z offset of the hit point relative to the containing flattening layer.
3428 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
3429                                        const LayoutRect& hitTestRect, const LayoutPoint& hitTestPoint, bool appliedTransform,
3430                                        const HitTestingTransformState* transformState, double* zOffset)
3431 {
3432     // The natural thing would be to keep HitTestingTransformState on the stack, but it's big, so we heap-allocate.
3433
3434     bool useTemporaryClipRects = renderer()->view()->frameView()->containsScrollableAreaWithOverlayScrollbars();
3435
3436     LayoutRect hitTestArea = result.rectForPoint(hitTestPoint);
3437
3438     // Apply a transform if we have one.
3439     if (transform() && !appliedTransform) {
3440         // Make sure the parent's clip rects have been calculated.
3441         if (parent()) {
3442             ClipRect clipRect = backgroundClipRect(rootLayer, result.region(), useTemporaryClipRects ? TemporaryClipRects : RootRelativeClipRects, IncludeOverlayScrollbarSize);
3443             // Go ahead and test the enclosing clip now.
3444             if (!clipRect.intersects(hitTestArea))
3445                 return 0;
3446         }
3447
3448         // Create a transform state to accumulate this transform.
3449         RefPtr<HitTestingTransformState> newTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestPoint, transformState);
3450
3451         // If the transform can't be inverted, then don't hit test this layer at all.
3452         if (!newTransformState->m_accumulatedTransform.isInvertible())
3453             return 0;
3454
3455         // Compute the point and the hit test rect in the coords of this layer by using the values
3456         // from the transformState, which store the point and quad in the coords of the last flattened
3457         // layer, and the accumulated transform which lets up map through preserve-3d layers.
3458         //
3459         // We can't just map hitTestPoint and hitTestRect because they may have been flattened (losing z)
3460         // by our container.
3461         LayoutPoint localPoint = roundedLayoutPoint(newTransformState->mappedPoint());
3462         LayoutRect localHitTestRect = newTransformState->boundsOfMappedQuad();
3463
3464         // Now do a hit test with the root layer shifted to be us.
3465         return hitTestLayer(this, containerLayer, request, result, localHitTestRect, localPoint, true, newTransformState.get(), zOffset);
3466     }
3467
3468     // Ensure our lists and 3d status are up-to-date.
3469     updateCompositingAndLayerListsIfNeeded();
3470     update3DTransformedDescendantStatus();
3471     
3472     RefPtr<HitTestingTransformState> localTransformState;
3473     if (appliedTransform) {
3474         // We computed the correct state in the caller (above code), so just reference it.
3475         ASSERT(transformState);
3476         localTransformState = const_cast<HitTestingTransformState*>(transformState);
3477     } else if (transformState || m_has3DTransformedDescendant || preserves3D()) {
3478         // We need transform state for the first time, or to offset the container state, so create it here.
3479         localTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestPoint, transformState);
3480     }
3481
3482     // Check for hit test on backface if backface-visibility is 'hidden'
3483     if (localTransformState && renderer()->style()->backfaceVisibility() == BackfaceVisibilityHidden) {
3484         TransformationMatrix invertedMatrix = localTransformState->m_accumulatedTransform.inverse();
3485         // If the z-vector of the matrix is negative, the back is facing towards the viewer.
3486         if (invertedMatrix.m33() < 0)
3487             return 0;
3488     }
3489
3490     RefPtr<HitTestingTransformState> unflattenedTransformState = localTransformState;
3491     if (localTransformState && !preserves3D()) {
3492         // Keep a copy of the pre-flattening state, for computing z-offsets for the container
3493         unflattenedTransformState = HitTestingTransformState::create(*localTransformState);
3494         // This layer is flattening, so flatten the state passed to descendants.
3495         localTransformState->flatten();
3496     }
3497     
3498     // Calculate the clip rects we should use.
3499     LayoutRect layerBounds;
3500     ClipRect bgRect;
3501     ClipRect fgRect;
3502     ClipRect outlineRect;
3503     calculateRects(rootLayer, result.region(), useTemporaryClipRects ? TemporaryClipRects : RootRelativeClipRects, hitTestRect, layerBounds, bgRect, fgRect, outlineRect, IncludeOverlayScrollbarSize);
3504     
3505     // The following are used for keeping track of the z-depth of the hit point of 3d-transformed
3506     // descendants.
3507     double localZOffset = -numeric_limits<double>::infinity();
3508     double* zOffsetForDescendantsPtr = 0;
3509     double* zOffsetForContentsPtr = 0;
3510     
3511     bool depthSortDescendants = false;
3512     if (preserves3D()) {
3513         depthSortDescendants = true;
3514         // Our layers can depth-test with our container, so share the z depth pointer with the container, if it passed one down.
3515         zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
3516         zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
3517     } else if (m_has3DTransformedDescendant) {
3518         // Flattening layer with 3d children; use a local zOffset pointer to depth-test children and foreground.
3519         depthSortDescendants = true;
3520         zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
3521         zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
3522     } else if (zOffset) {
3523         zOffsetForDescendantsPtr = 0;
3524         // Container needs us to give back a z offset for the hit layer.
3525         zOffsetForContentsPtr = zOffset;
3526     }
3527     
3528     // This variable tracks which layer the mouse ends up being inside. 
3529     RenderLayer* candidateLayer = 0;
3530
3531     // Begin by walking our list of positive layers from highest z-index down to the lowest z-index.
3532     RenderLayer* hitLayer = hitTestList(posZOrderList(), rootLayer, request, result, hitTestRect, hitTestPoint,
3533                                         localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
3534     if (hitLayer) {
3535         if (!depthSortDescendants)
3536             return hitLayer;
3537         candidateLayer = hitLayer;
3538     }
3539
3540     // Now check our overflow objects.
3541     hitLayer = hitTestList(m_normalFlowList, rootLayer, request, result, hitTestRect, hitTestPoint,
3542                            localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
3543     if (hitLayer) {
3544         if (!depthSortDescendants)
3545             return hitLayer;
3546         candidateLayer = hitLayer;
3547     }
3548
3549     // Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
3550     if (fgRect.intersects(hitTestArea) && isSelfPaintingLayer()) {
3551         // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
3552         HitTestResult tempResult(result.hitTestPoint(), result.shadowContentFilterPolicy());
3553         if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestDescendants) &&
3554             isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
3555             if (result.isRectBasedTest())
3556                 result.append(tempResult);
3557             else
3558                 result = tempResult;
3559             if (!depthSortDescendants)
3560                 return this;
3561             // Foreground can depth-sort with descendant layers, so keep this as a candidate.
3562             candidateLayer = this;
3563         } else if (result.isRectBasedTest())
3564             result.append(tempResult);
3565     }
3566
3567     // Now check our negative z-index children.
3568     hitLayer = hitTestList(negZOrderList(), rootLayer, request, result, hitTestRect, hitTestPoint,
3569                                         localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
3570     if (hitLayer) {
3571         if (!depthSortDescendants)
3572             return hitLayer;
3573         candidateLayer = hitLayer;
3574     }
3575
3576     // If we found a layer, return. Child layers, and foreground always render in front of background.
3577     if (candidateLayer)
3578         return candidateLayer;
3579
3580     if (bgRect.intersects(hitTestArea) && isSelfPaintingLayer()) {
3581         HitTestResult tempResult(result.hitTestPoint(), result.shadowContentFilterPolicy());
3582         if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestSelf) &&
3583             isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
3584             if (result.isRectBasedTest())
3585                 result.append(tempResult);
3586             else
3587                 result = tempResult;
3588             return this;
3589         } else if (result.isRectBasedTest())
3590             result.append(tempResult);
3591     }
3592     
3593     return 0;
3594 }
3595
3596 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult& result, const LayoutRect& layerBounds, const LayoutPoint& hitTestPoint, HitTestFilter hitTestFilter) const
3597 {
3598     if (!renderer()->hitTest(request, result, hitTestPoint,
3599                             toLayoutPoint(layerBounds.location() - renderBoxLocation()),
3600                             hitTestFilter)) {
3601         // It's wrong to set innerNode, but then claim that you didn't hit anything, unless it is
3602         // a rect-based test.
3603         ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBasedTestResult().size()));
3604         return false;
3605     }
3606
3607     // For positioned generated content, we might still not have a
3608     // node by the time we get to the layer level, since none of
3609     // the content in the layer has an element. So just walk up
3610     // the tree.
3611     if (!result.innerNode() || !result.innerNonSharedNode()) {
3612         Node* e = enclosingElement();
3613         if (!result.innerNode())
3614             result.setInnerNode(e);
3615         if (!result.innerNonSharedNode())
3616             result.setInnerNonSharedNode(e);
3617     }
3618         
3619     return true;
3620 }
3621
3622 RenderLayer* RenderLayer::hitTestList(Vector<RenderLayer*>* list, RenderLayer* rootLayer,
3623                                       const HitTestRequest& request, HitTestResult& result,
3624                                       const LayoutRect& hitTestRect, const LayoutPoint& hitTestPoint,
3625                                       const HitTestingTransformState* transformState, 
3626                                       double* zOffsetForDescendants, double* zOffset,
3627                                       const HitTestingTransformState* unflattenedTransformState,
3628                                       bool depthSortDescendants)
3629 {
3630     if (!list)
3631         return 0;
3632     
3633     RenderLayer* resultLayer = 0;
3634     for (int i = list->size() - 1; i >= 0; --i) {
3635         RenderLayer* childLayer = list->at(i);
3636         RenderLayer* hitLayer = 0;
3637         HitTestResult tempResult(result.hitTestPoint(), result.shadowContentFilterPolicy());
3638         if (childLayer->isPaginated())
3639             hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, request, tempResult, hitTestRect, hitTestPoint, transformState, zOffsetForDescendants);
3640         else
3641             hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestPoint, false, transformState, zOffsetForDescendants);
3642
3643         // If it a rect-based test, we can safely append the temporary result since it might had hit
3644         // nodes but not necesserily had hitLayer set.
3645         if (result.isRectBasedTest())
3646             result.append(tempResult);
3647
3648         if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState)) {
3649             resultLayer = hitLayer;
3650             if (!result.isRectBasedTest())
3651                 result = tempResult;
3652             if (!depthSortDescendants)
3653                 break;
3654         }
3655     }
3656     
3657     return resultLayer;
3658 }
3659
3660 RenderLayer* RenderLayer::hitTestPaginatedChildLayer(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
3661                                                      const LayoutRect& hitTestRect, const LayoutPoint& hitTestPoint, const HitTestingTransformState* transformState, double* zOffset)
3662 {
3663     Vector<RenderLayer*> columnLayers;
3664     RenderLayer* ancestorLayer = isNormalFlowOnly() ? parent() : stackingContext();
3665     for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
3666         if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
3667             columnLayers.append(curr);
3668         if (curr == ancestorLayer)
3669             break;
3670     }
3671
3672     ASSERT(columnLayers.size());
3673     return hitTestChildLayerColumns(childLayer, rootLayer, request, result, hitTestRect, hitTestPoint, transformState, zOffset,
3674                                     columnLayers, columnLayers.size() - 1);
3675 }
3676
3677 RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, RenderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result,
3678                                                    const LayoutRect& hitTestRect, const LayoutPoint& hitTestPoint, const HitTestingTransformState* transformState, double* zOffset,
3679                                                    const Vector<RenderLayer*>& columnLayers, size_t columnIndex)
3680 {
3681     RenderBlock* columnBlock = toRenderBlock(columnLayers[columnIndex]->renderer());
3682
3683     ASSERT(columnBlock && columnBlock->hasColumns());
3684     if (!columnBlock || !columnBlock->hasColumns())
3685         return 0;
3686
3687     LayoutPoint layerOffset;
3688     columnBlock->layer()->convertToLayerCoords(rootLayer, layerOffset);
3689     
3690     ColumnInfo* colInfo = columnBlock->columnInfo();
3691     int colCount = columnBlock->columnCount(colInfo);
3692     
3693     // We have to go backwards from the last column to the first.
3694     bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
3695     LayoutUnit logicalLeft = columnBlock->logicalLeftOffsetForContent();
3696     LayoutUnit currLogicalTopOffset = 0;
3697     int i;
3698     for (i = 0; i < colCount; i++) {
3699         LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
3700         LayoutUnit blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
3701         if (columnBlock->style()->isFlippedBlocksWritingMode())
3702             currLogicalTopOffset += blockDelta;
3703         else
3704             currLogicalTopOffset -= blockDelta;
3705     }
3706     for (i = colCount - 1; i >= 0; i--) {
3707         // For each rect, we clip to the rect, and then we adjust our coords.
3708         LayoutRect colRect = columnBlock->columnRectAt(colInfo, i);
3709         columnBlock->flipForWritingMode(colRect);
3710         LayoutUnit currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
3711         LayoutUnit blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
3712         if (columnBlock->style()->isFlippedBlocksWritingMode())
3713             currLogicalTopOffset -= blockDelta;
3714         else
3715             currLogicalTopOffset += blockDelta;
3716
3717         LayoutSize offset;
3718         if (isHorizontal) {
3719             if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3720                 offset = LayoutSize(currLogicalLeftOffset, currLogicalTopOffset);
3721             else
3722                 offset = LayoutSize(0, colRect.y() + currLogicalTopOffset - columnBlock->borderTop() - columnBlock->paddingTop());
3723         } else {
3724             if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
3725                 offset = LayoutSize(currLogicalTopOffset, currLogicalLeftOffset);
3726             else
3727                 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnBlock->borderLeft() - columnBlock->paddingLeft(), 0);
3728         }
3729
3730         colRect.moveBy(layerOffset);
3731
3732         LayoutRect localClipRect(hitTestRect);
3733         localClipRect.intersect(colRect);
3734
3735         if (!localClipRect.isEmpty() && localClipRect.intersects(result.rectForPoint(hitTestPoint))) {
3736             RenderLayer* hitLayer = 0;
3737             if (!columnIndex) {
3738                 // Apply a translation transform to change where the layer paints.
3739                 TransformationMatrix oldTransform;
3740                 bool oldHasTransform = childLayer->transform();
3741                 if (oldHasTransform)
3742                     oldTransform = *childLayer->transform();
3743                 TransformationMatrix newTransform(oldTransform);
3744                 newTransform.translateRight(offset.width(), offset.height());
3745                 
3746                 childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform));
3747                 hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0], request, result, localClipRect, hitTestPoint, false, transformState, zOffset);
3748                 if (oldHasTransform)
3749                     childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform));
3750                 else
3751                     childLayer->m_transform.clear();
3752             } else {
3753                 // Adjust the transform such that the renderer's upper left corner will be at (0,0) in user space.
3754                 // This involves subtracting out the position of the layer in our current coordinate space.
3755                 RenderLayer* nextLayer = columnLayers[columnIndex - 1];
3756                 RefPtr<HitTestingTransformState> newTransformState = nextLayer->createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestPoint, transformState);
3757                 newTransformState->translate(offset.width(), offset.height(), HitTestingTransformState::AccumulateTransform);
3758                 LayoutPoint localPoint = roundedLayoutPoint(newTransformState->mappedPoint());
3759                 LayoutRect localHitTestRect = newTransformState->mappedQuad().enclosingBoundingBox();
3760                 newTransformState->flatten();
3761
3762                 hitLayer = hitTestChildLayerColumns(childLayer, columnLayers[columnIndex - 1], request, result, localHitTestRect, localPoint,
3763                                                     newTransformState.get(), zOffset, columnLayers, columnIndex - 1);
3764             }
3765
3766             if (hitLayer)
3767                 return hitLayer;
3768         }
3769     }
3770
3771     return 0;
3772 }
3773
3774 void RenderLayer::updateClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy relevancy)
3775 {
3776     ASSERT(clipRectsType < NumCachedClipRectsTypes);
3777     if (m_clipRectsCache && m_clipRectsCache->m_clipRects[clipRectsType]) {
3778         ASSERT(rootLayer == m_clipRectsCache->m_clipRectsRoot[clipRectsType]);
3779         return; // We have the correct cached value.
3780     }
3781     
3782     // For transformed layers, the root layer was shifted to be us, so there is no need to
3783     // examine the parent.  We want to cache clip rects with us as the root.
3784     RenderLayer* parentLayer = rootLayer != this ? parent() : 0;
3785     if (parentLayer)
3786         parentLayer->updateClipRects(rootLayer, region, clipRectsType, relevancy);
3787
3788     ClipRects clipRects;
3789     calculateClipRects(rootLayer, region, clipRectsType, clipRects, relevancy);
3790
3791     if (!m_clipRectsCache)
3792         m_clipRectsCache = adoptPtr(new ClipRectsCache);
3793
3794     if (parentLayer && parentLayer->clipRects(clipRectsType) && clipRects == *parentLayer->clipRects(clipRectsType))
3795         m_clipRectsCache->m_clipRects[clipRectsType] = parentLayer->clipRects(clipRectsType);
3796     else
3797         m_clipRectsCache->m_clipRects[clipRectsType] = ClipRects::create(clipRects);
3798
3799 #ifndef NDEBUG
3800     m_clipRectsCache->m_clipRectsRoot[clipRectsType] = rootLayer;
3801 #endif
3802 }
3803
3804 void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, RenderRegion* region, ClipRectsType clipRectsType, ClipRects& clipRects, OverlayScrollbarSizeRelevancy relevancy) const
3805 {
3806     if (!parent()) {
3807         // The root layer's clip rect is always infinite.
3808         clipRects.reset(PaintInfo::infiniteRect());
3809         return;
3810     }
3811     
3812     bool useCached = clipRectsType != TemporaryClipRects;
3813
3814     // For transformed layers, the root layer was shifted to be us, so there is no need to
3815     // examine the parent.  We want to cache clip rects with us as the root.
3816     RenderLayer* parentLayer = rootLayer != this ? parent() : 0;
3817     
3818     // Ensure that our parent's clip has been calculated so that we can examine the values.
3819     if (parentLayer) {
3820         if (useCached && parentLayer->clipRects(clipRectsType))
3821             clipRects = *parentLayer->clipRects(clipRectsType);
3822         else
3823             parentLayer->calculateClipRects(rootLayer, region, clipRectsType, clipRects);
3824     } else
3825         clipRects.reset(PaintInfo::infiniteRect());
3826
3827     // A fixed object is essentially the root of its containing block hierarchy, so when
3828     // we encounter such an object, we reset our clip rects to the fixedClipRect.
3829     if (renderer()->style()->position() == FixedPosition) {
3830         clipRects.setPosClipRect(clipRects.fixedClipRect());
3831         clipRects.setOverflowClipRect(clipRects.fixedClipRect());
3832         clipRects.setFixed(true);
3833     }
3834     else if (renderer()->style()->position() == RelativePosition)
3835         clipRects.setPosClipRect(clipRects.overflowClipRect());
3836     else if (renderer()->style()->position() == AbsolutePosition)
3837         clipRects.setOverflowClipRect(clipRects.posClipRect());
3838     
3839     // Update the clip rects that will be passed to child layers.
3840     if (renderer()->hasOverflowClip() || renderer()->hasClip()) {
3841         // This layer establishes a clip of some kind.
3842
3843         // This offset cannot use convertToLayerCoords, because sometimes our rootLayer may be across