Crash in WebCore::RenderLayer::FilterInfo::updateReferenceFilterClients
[WebKit-https.git] / Source / WebCore / rendering / RenderLayer.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 "AnimationController.h"
48 #include "BoxShape.h"
49 #include "ColumnInfo.h"
50 #include "CSSPropertyNames.h"
51 #include "Chrome.h"
52 #include "Document.h"
53 #include "DocumentEventQueue.h"
54 #include "Element.h"
55 #include "EventHandler.h"
56 #include "FloatConversion.h"
57 #include "FloatPoint3D.h"
58 #include "FloatRect.h"
59 #include "FloatRoundedRect.h"
60 #include "FlowThreadController.h"
61 #include "FocusController.h"
62 #include "Frame.h"
63 #include "FrameLoader.h"
64 #include "FrameLoaderClient.h"
65 #include "FrameSelection.h"
66 #include "FrameTree.h"
67 #include "FrameView.h"
68 #include "Gradient.h"
69 #include "GraphicsContext.h"
70 #include "HTMLFrameElement.h"
71 #include "HTMLFrameOwnerElement.h"
72 #include "HTMLNames.h"
73 #include "HistogramSupport.h"
74 #include "HitTestingTransformState.h"
75 #include "HitTestRequest.h"
76 #include "HitTestResult.h"
77 #include "InspectorInstrumentation.h"
78 #include "OverflowEvent.h"
79 #include "OverlapTestRequestClient.h"
80 #include "Page.h"
81 #include "PlatformMouseEvent.h"
82 #include "RenderFlowThread.h"
83 #include "RenderGeometryMap.h"
84 #include "RenderInline.h"
85 #include "RenderIterator.h"
86 #include "RenderLayerBacking.h"
87 #include "RenderLayerCompositor.h"
88 #include "RenderMarquee.h"
89 #include "RenderNamedFlowFragment.h"
90 #include "RenderNamedFlowThread.h"
91 #include "RenderRegion.h"
92 #include "RenderReplica.h"
93 #include "RenderSVGResourceClipper.h"
94 #include "RenderScrollbar.h"
95 #include "RenderScrollbarPart.h"
96 #include "RenderTableCell.h"
97 #include "RenderTableRow.h"
98 #include "RenderTheme.h"
99 #include "RenderTreeAsText.h"
100 #include "RenderView.h"
101 #include "SVGNames.h"
102 #include "ScaleTransformOperation.h"
103 #include "ScrollAnimator.h"
104 #include "Scrollbar.h"
105 #include "ScrollbarTheme.h"
106 #include "ScrollingCoordinator.h"
107 #include "Settings.h"
108 #include "ShadowRoot.h"
109 #include "SourceGraphic.h"
110 #include "StyleProperties.h"
111 #include "StyleResolver.h"
112 #include "TextStream.h"
113 #include "TransformationMatrix.h"
114 #include "TranslateTransformOperation.h"
115 #include <stdio.h>
116 #include <wtf/StdLibExtras.h>
117 #include <wtf/text/CString.h>
118
119 #if ENABLE(CSS_FILTERS)
120 #include "FEColorMatrix.h"
121 #include "FEMerge.h"
122 #include "FilterEffectRenderer.h"
123 #include "RenderLayerFilterInfo.h"
124 #endif
125
126 #define MIN_INTERSECT_FOR_REVEAL 32
127
128 namespace WebCore {
129
130 using namespace HTMLNames;
131
132 bool ClipRect::intersects(const HitTestLocation& hitTestLocation) const
133 {
134     return hitTestLocation.intersects(m_rect);
135 }
136
137 void makeMatrixRenderable(TransformationMatrix& matrix, bool has3DRendering)
138 {
139 #if !ENABLE(3D_RENDERING)
140     UNUSED_PARAM(has3DRendering);
141     matrix.makeAffine();
142 #else
143     if (!has3DRendering)
144         matrix.makeAffine();
145 #endif
146 }
147
148 RenderLayer::RenderLayer(RenderLayerModelObject& rendererLayerModelObject)
149     : m_inResizeMode(false)
150     , m_scrollDimensionsDirty(true)
151     , m_normalFlowListDirty(true)
152     , m_hasSelfPaintingLayerDescendant(false)
153     , m_hasSelfPaintingLayerDescendantDirty(false)
154     , m_hasOutOfFlowPositionedDescendant(false)
155     , m_hasOutOfFlowPositionedDescendantDirty(true)
156     , m_needsCompositedScrolling(false)
157     , m_descendantsAreContiguousInStackingOrder(false)
158     , m_isRootLayer(rendererLayerModelObject.isRenderView())
159     , m_usedTransparency(false)
160     , m_paintingInsideReflection(false)
161     , m_inOverflowRelayout(false)
162     , m_repaintStatus(NeedsNormalRepaint)
163     , m_visibleContentStatusDirty(true)
164     , m_hasVisibleContent(false)
165     , m_visibleDescendantStatusDirty(false)
166     , m_hasVisibleDescendant(false)
167     , m_isPaginated(false)
168     , m_3DTransformedDescendantStatusDirty(true)
169     , m_has3DTransformedDescendant(false)
170     , m_hasCompositingDescendant(false)
171     , m_indirectCompositingReason(NoIndirectCompositingReason)
172     , m_viewportConstrainedNotCompositedReason(NoNotCompositedReason)
173 #if PLATFORM(IOS)
174     , m_adjustForIOSCaretWhenScrolling(false)
175     , m_registeredAsTouchEventListenerForScrolling(false)
176     , m_inUserScroll(false)
177     , m_requiresScrollBoundsOriginUpdate(false)
178 #endif
179     , m_containsDirtyOverlayScrollbars(false)
180     , m_updatingMarqueePosition(false)
181 #if !ASSERT_DISABLED
182     , m_layerListMutationAllowed(true)
183 #endif
184 #if ENABLE(CSS_FILTERS)
185     , m_hasFilterInfo(false)
186 #endif
187 #if ENABLE(CSS_COMPOSITING)
188     , m_blendMode(BlendModeNormal)
189     , m_hasBlendedElementInChildStackingContext(false)
190     , m_hasBlendedElementInChildStackingContextStatusDirty(false)
191 #endif
192     , m_renderer(rendererLayerModelObject)
193     , m_parent(0)
194     , m_previous(0)
195     , m_next(0)
196     , m_first(0)
197     , m_last(0)
198     , m_staticInlinePosition(0)
199     , m_staticBlockPosition(0)
200     , m_enclosingPaginationLayer(0)
201 {
202     m_isNormalFlowOnly = shouldBeNormalFlowOnly();
203     m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
204
205     // Non-stacking containers should have empty z-order lists. As this is already the case,
206     // there is no need to dirty / recompute these lists.
207     m_zOrderListsDirty = isStackingContainer();
208
209     ScrollableArea::setConstrainsScrollingToContentEdge(false);
210
211     if (!renderer().firstChild()) {
212         m_visibleContentStatusDirty = false;
213         m_hasVisibleContent = renderer().style().visibility() == VISIBLE;
214     }
215
216     if (Element* element = renderer().element()) {
217         // We save and restore only the scrollOffset as the other scroll values are recalculated.
218         m_scrollOffset = element->savedLayerScrollOffset();
219         if (!m_scrollOffset.isZero())
220             scrollAnimator()->setCurrentPosition(FloatPoint(m_scrollOffset.width(), m_scrollOffset.height()));
221         element->setSavedLayerScrollOffset(IntSize());
222     }
223 }
224
225 RenderLayer::~RenderLayer()
226 {
227     if (inResizeMode() && !renderer().documentBeingDestroyed())
228         renderer().frame().eventHandler().resizeLayerDestroyed();
229
230     renderer().view().frameView().removeScrollableArea(this);
231
232     if (!renderer().documentBeingDestroyed()) {
233 #if PLATFORM(IOS)
234         unregisterAsTouchEventListenerForScrolling();
235 #endif
236         if (Element* element = renderer().element())
237             element->setSavedLayerScrollOffset(m_scrollOffset);
238     }
239
240     destroyScrollbar(HorizontalScrollbar);
241     destroyScrollbar(VerticalScrollbar);
242
243     if (renderer().frame().page()) {
244         if (ScrollingCoordinator* scrollingCoordinator = renderer().frame().page()->scrollingCoordinator())
245             scrollingCoordinator->willDestroyScrollableArea(this);
246     }
247
248     if (m_reflection)
249         removeReflection();
250     
251 #if ENABLE(CSS_FILTERS)
252     FilterInfo::remove(*this);
253 #endif
254
255     // Child layers will be deleted by their corresponding render objects, so
256     // we don't need to delete them ourselves.
257
258     clearBacking(true);
259 }
260
261 String RenderLayer::name() const
262 {
263     StringBuilder name;
264     name.append(renderer().renderName());
265
266     if (Element* element = renderer().element()) {
267         name.append(' ');
268         name.append(element->tagName());
269
270         if (element->hasID()) {
271             name.appendLiteral(" id=\'");
272             name.append(element->getIdAttribute());
273             name.append('\'');
274         }
275
276         if (element->hasClass()) {
277             name.appendLiteral(" class=\'");
278             for (size_t i = 0; i < element->classNames().size(); ++i) {
279                 if (i > 0)
280                     name.append(' ');
281                 name.append(element->classNames()[i]);
282             }
283             name.append('\'');
284         }
285     }
286
287     if (isReflection())
288         name.appendLiteral(" (reflection)");
289
290     return name.toString();
291 }
292
293 RenderLayerCompositor& RenderLayer::compositor() const
294 {
295     return renderer().view().compositor();
296 }
297
298 void RenderLayer::contentChanged(ContentChangeType changeType)
299 {
300     // This can get called when video becomes accelerated, so the layers may change.
301     if ((changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged) && compositor().updateLayerCompositingState(*this))
302         compositor().setCompositingLayersNeedRebuild();
303
304     if (m_backing)
305         m_backing->contentChanged(changeType);
306 }
307
308 bool RenderLayer::canRender3DTransforms() const
309 {
310     return compositor().canRender3DTransforms();
311 }
312
313 #if ENABLE(CSS_FILTERS)
314
315 bool RenderLayer::paintsWithFilters() const
316 {
317     // FIXME: Eventually there will be cases where we paint with filters even without accelerated compositing,
318     // and this whole function won't be inside the #if below.
319
320     if (!renderer().hasFilter())
321         return false;
322         
323     if (!isComposited())
324         return true;
325
326     if (!m_backing || !m_backing->canCompositeFilters())
327         return true;
328
329     return false;
330 }
331
332 bool RenderLayer::requiresFullLayerImageForFilters() const 
333 {
334     if (!paintsWithFilters())
335         return false;
336     FilterEffectRenderer* renderer = filterRenderer();
337     return renderer && renderer->hasFilterThatMovesPixels();
338 }
339
340 FilterEffectRenderer* RenderLayer::filterRenderer() const
341 {
342     FilterInfo* filterInfo = FilterInfo::getIfExists(*this);
343     return filterInfo ? filterInfo->renderer() : 0;
344 }
345
346 #endif
347
348 LayoutPoint RenderLayer::computeOffsetFromRoot(bool& hasLayerOffset) const
349 {
350     hasLayerOffset = true;
351
352     if (!parent())
353         return LayoutPoint();
354
355     // This is similar to root() but we check if an ancestor layer would
356     // prevent the optimization from working.
357     const RenderLayer* rootLayer = 0;
358     for (const RenderLayer* parentLayer = parent(); parentLayer; rootLayer = parentLayer, parentLayer = parentLayer->parent()) {
359         hasLayerOffset = parentLayer->canUseConvertToLayerCoords();
360         if (!hasLayerOffset)
361             return LayoutPoint();
362     }
363     ASSERT(rootLayer == root());
364
365     LayoutPoint offset;
366     parent()->convertToLayerCoords(rootLayer, offset);
367     return offset;
368 }
369
370 void RenderLayer::updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, UpdateLayerPositionsFlags flags)
371 {
372     RenderGeometryMap geometryMap(UseTransforms);
373     if (this != rootLayer)
374         geometryMap.pushMappingsToAncestor(parent(), 0);
375     updateLayerPositions(&geometryMap, flags);
376 }
377
378 void RenderLayer::updateLayerPositions(RenderGeometryMap* geometryMap, UpdateLayerPositionsFlags flags)
379 {
380     updateLayerPosition(); // For relpositioned layers or non-positioned layers,
381                            // we need to keep in sync, since we may have shifted relative
382                            // to our parent layer.
383     if (geometryMap)
384         geometryMap->pushMappingsToAncestor(this, parent());
385
386     // Clear our cached clip rect information.
387     clearClipRects();
388     
389     if (hasOverflowControls()) {
390         LayoutPoint offsetFromRoot;
391         if (geometryMap)
392             offsetFromRoot = LayoutPoint(geometryMap->absolutePoint(FloatPoint()));
393         else {
394             // FIXME: It looks suspicious to call convertToLayerCoords here
395             // as canUseConvertToLayerCoords may be true for an ancestor layer.
396             convertToLayerCoords(root(), offsetFromRoot);
397         }
398         positionOverflowControls(toIntSize(roundedIntPoint(offsetFromRoot)));
399     }
400
401     updateDescendantDependentFlags();
402
403     if (flags & UpdatePagination)
404         updatePagination();
405     else {
406         m_isPaginated = false;
407         m_enclosingPaginationLayer = 0;
408     }
409
410     if (m_hasVisibleContent) {
411         // FIXME: LayoutState does not work with RenderLayers as there is not a 1-to-1
412         // mapping between them and the RenderObjects. It would be neat to enable
413         // LayoutState outside the layout() phase and use it here.
414         ASSERT(!renderer().view().layoutStateEnabled());
415
416         RenderLayerModelObject* repaintContainer = renderer().containerForRepaint();
417         LayoutRect oldRepaintRect = m_repaintRect;
418         LayoutRect oldOutlineBox = m_outlineBox;
419         computeRepaintRects(repaintContainer, geometryMap);
420
421         // FIXME: Should ASSERT that value calculated for m_outlineBox using the cached offset is the same
422         // as the value not using the cached offset, but we can't due to https://bugs.webkit.org/show_bug.cgi?id=37048
423         if (flags & CheckForRepaint) {
424             if (!renderer().view().printing()) {
425                 bool didRepaint = false;
426                 if (m_repaintStatus & NeedsFullRepaint) {
427                     renderer().repaintUsingContainer(repaintContainer, oldRepaintRect);
428                     if (m_repaintRect != oldRepaintRect) {
429                         renderer().repaintUsingContainer(repaintContainer, m_repaintRect);
430                         didRepaint = true;
431                     }
432                 } else if (shouldRepaintAfterLayout()) {
433                     renderer().repaintAfterLayoutIfNeeded(repaintContainer, oldRepaintRect, oldOutlineBox, &m_repaintRect, &m_outlineBox);
434                     didRepaint = true;
435                 }
436
437                 if (didRepaint && renderer().isRenderNamedFlowFragmentContainer()) {
438                     // If we just repainted a region, we must also repaint the flow thread since it is the one
439                     // doing the actual painting of the flowed content.
440                     RenderNamedFlowFragment* region = toRenderBlockFlow(&renderer())->renderNamedFlowFragment();
441                     if (region->flowThread())
442                         region->flowThread()->layer()->repaintIncludingDescendants();
443                 }
444             }
445         }
446     } else
447         clearRepaintRects();
448
449     m_repaintStatus = NeedsNormalRepaint;
450
451     // Go ahead and update the reflection's position and size.
452     if (m_reflection)
453         m_reflection->layout();
454
455     // Clear the IsCompositingUpdateRoot flag once we've found the first compositing layer in this update.
456     bool isUpdateRoot = (flags & IsCompositingUpdateRoot);
457     if (isComposited())
458         flags &= ~IsCompositingUpdateRoot;
459
460     if (useRegionBasedColumns() && renderer().isInFlowRenderFlowThread()) {
461         updatePagination();
462         flags |= UpdatePagination;
463     }
464     
465     if (renderer().hasColumns())
466         flags |= UpdatePagination;
467
468     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
469         child->updateLayerPositions(geometryMap, flags);
470
471     if ((flags & UpdateCompositingLayers) && isComposited()) {
472         RenderLayerBacking::UpdateAfterLayoutFlags updateFlags = RenderLayerBacking::CompositingChildrenOnly;
473         if (flags & NeedsFullRepaintInBacking)
474             updateFlags |= RenderLayerBacking::NeedsFullRepaint;
475         if (isUpdateRoot)
476             updateFlags |= RenderLayerBacking::IsUpdateRoot;
477         backing()->updateAfterLayout(updateFlags);
478     }
479         
480     // With all our children positioned, now update our marquee if we need to.
481     if (m_marquee) {
482         // FIXME: would like to use TemporaryChange<> but it doesn't work with bitfields.
483         bool oldUpdatingMarqueePosition = m_updatingMarqueePosition;
484         m_updatingMarqueePosition = true;
485         m_marquee->updateMarqueePosition();
486         m_updatingMarqueePosition = oldUpdatingMarqueePosition;
487     }
488
489     if (geometryMap)
490         geometryMap->popMappingsToAncestor(parent());
491 }
492
493 LayoutRect RenderLayer::repaintRectIncludingNonCompositingDescendants() const
494 {
495     LayoutRect repaintRect = m_repaintRect;
496     for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
497         // Don't include repaint rects for composited child layers; they will paint themselves and have a different origin.
498         if (child->isComposited())
499             continue;
500
501         repaintRect.unite(child->repaintRectIncludingNonCompositingDescendants());
502     }
503     return repaintRect;
504 }
505
506 void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant()
507 {
508     for (RenderLayer* layer = this; layer; layer = layer->parent()) {
509         if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaintingLayerDescendant())
510             break;
511
512         layer->m_hasSelfPaintingLayerDescendantDirty = false;
513         layer->m_hasSelfPaintingLayerDescendant = true;
514     }
515 }
516
517 void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus()
518 {
519     for (RenderLayer* layer = this; layer; layer = layer->parent()) {
520         layer->m_hasSelfPaintingLayerDescendantDirty = true;
521         // If we have reached a self-painting layer, we know our parent should have a self-painting descendant
522         // in this case, there is no need to dirty our ancestors further.
523         if (layer->isSelfPaintingLayer()) {
524             ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->hasSelfPaintingLayerDescendant());
525             break;
526         }
527     }
528 }
529
530 bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const
531 {
532     return renderer().frame().settings().acceleratedCompositingForOverflowScrollEnabled();
533 }
534
535 // If we are a stacking container, then this function will determine if our
536 // descendants for a contiguous block in stacking order. This is required in
537 // order for an element to be safely promoted to a stacking container. It is safe
538 // to become a stacking container if this change would not alter the stacking
539 // order of layers on the page. That can only happen if a non-descendant appear
540 // between us and our descendants in stacking order. Here's an example:
541 //
542 //                                 this
543 //                                /  |  \.
544 //                               A   B   C
545 //                              /\   |   /\.
546 //                             0 -8  D  2  7
547 //                                   |
548 //                                   5
549 //
550 // I've labeled our normal flow descendants A, B, C, and D, our stacking
551 // container descendants with their z indices, and us with 'this' (we're a
552 // stacking container and our zIndex doesn't matter here). These nodes appear in
553 // three lists: posZOrder, negZOrder, and normal flow (keep in mind that normal
554 // flow layers don't overlap). So if we arrange these lists in order we get our
555 // stacking order:
556 //
557 //                     [-8], [A-D], [0, 2, 5, 7]--> pos z-order.
558 //                       |     |
559 //        Neg z-order. <-+     +--> Normal flow descendants.
560 //
561 // We can then assign new, 'stacking' order indices to these elements as follows:
562 //
563 //                     [-8], [A-D], [0, 2, 5, 7]
564 // 'Stacking' indices:  -1     0     1  2  3  4
565 //
566 // Note that the normal flow descendants can share an index because they don't
567 // stack/overlap. Now our problem becomes very simple: a layer can safely become
568 // a stacking container if the stacking-order indices of it and its descendants
569 // appear in a contiguous block in the list of stacking indices. This problem
570 // can be solved very efficiently by calculating the min/max stacking indices in
571 // the subtree, and the number stacking container descendants. Once we have this
572 // information, we know that the subtree's indices form a contiguous block if:
573 //
574 //           maxStackIndex - minStackIndex == numSCDescendants
575 //
576 // So for node A in the example above we would have:
577 //   maxStackIndex = 1
578 //   minStackIndex = -1
579 //   numSCDecendants = 2
580 //
581 // and so,
582 //       maxStackIndex - minStackIndex == numSCDescendants
583 //  ===>                      1 - (-1) == 2
584 //  ===>                             2 == 2
585 //
586 //  Since this is true, A can safely become a stacking container.
587 //  Now, for node C we have:
588 //
589 //   maxStackIndex = 4
590 //   minStackIndex = 0 <-- because C has stacking index 0.
591 //   numSCDecendants = 2
592 //
593 // and so,
594 //       maxStackIndex - minStackIndex == numSCDescendants
595 //  ===>                         4 - 0 == 2
596 //  ===>                             4 == 2
597 //
598 // Since this is false, C cannot be safely promoted to a stacking container. This
599 // happened because of the elements with z-index 5 and 0. Now if 5 had been a
600 // child of C rather than D, and A had no child with Z index 0, we would have had:
601 //
602 //   maxStackIndex = 3
603 //   minStackIndex = 0 <-- because C has stacking index 0.
604 //   numSCDecendants = 3
605 //
606 // and so,
607 //       maxStackIndex - minStackIndex == numSCDescendants
608 //  ===>                         3 - 0 == 3
609 //  ===>                             3 == 3
610 //
611 //  And we would conclude that C could be promoted.
612 void RenderLayer::updateDescendantsAreContiguousInStackingOrder()
613 {
614     if (!isStackingContext() || !acceleratedCompositingForOverflowScrollEnabled())
615         return;
616
617     ASSERT(!m_normalFlowListDirty);
618     ASSERT(!m_zOrderListsDirty);
619
620     std::unique_ptr<Vector<RenderLayer*>> posZOrderList;
621     std::unique_ptr<Vector<RenderLayer*>> negZOrderList;
622     rebuildZOrderLists(StopAtStackingContexts, posZOrderList, negZOrderList);
623
624     // Create a reverse lookup.
625     HashMap<const RenderLayer*, int> lookup;
626
627     if (negZOrderList) {
628         int stackingOrderIndex = -1;
629         size_t listSize = negZOrderList->size();
630         for (size_t i = 0; i < listSize; ++i) {
631             RenderLayer* currentLayer = negZOrderList->at(listSize - i - 1);
632             if (!currentLayer->isStackingContext())
633                 continue;
634             lookup.set(currentLayer, stackingOrderIndex--);
635         }
636     }
637
638     if (posZOrderList) {
639         size_t listSize = posZOrderList->size();
640         int stackingOrderIndex = 1;
641         for (size_t i = 0; i < listSize; ++i) {
642             RenderLayer* currentLayer = posZOrderList->at(i);
643             if (!currentLayer->isStackingContext())
644                 continue;
645             lookup.set(currentLayer, stackingOrderIndex++);
646         }
647     }
648
649     int minIndex = 0;
650     int maxIndex = 0;
651     int count = 0;
652     bool firstIteration = true;
653     updateDescendantsAreContiguousInStackingOrderRecursive(lookup, minIndex, maxIndex, count, firstIteration);
654 }
655
656 void RenderLayer::updateDescendantsAreContiguousInStackingOrderRecursive(const HashMap<const RenderLayer*, int>& lookup, int& minIndex, int& maxIndex, int& count, bool firstIteration)
657 {
658     if (isStackingContext() && !firstIteration) {
659         if (lookup.contains(this)) {
660             minIndex = std::min(minIndex, lookup.get(this));
661             maxIndex = std::max(maxIndex, lookup.get(this));
662             count++;
663         }
664         return;
665     }
666
667     for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
668         int childMinIndex = 0;
669         int childMaxIndex = 0;
670         int childCount = 0;
671         child->updateDescendantsAreContiguousInStackingOrderRecursive(lookup, childMinIndex, childMaxIndex, childCount, false);
672         if (childCount) {
673             count += childCount;
674             minIndex = std::min(minIndex, childMinIndex);
675             maxIndex = std::max(maxIndex, childMaxIndex);
676         }
677     }
678
679     if (!isStackingContext()) {
680         bool newValue = maxIndex - minIndex == count;
681         bool didUpdate = newValue != m_descendantsAreContiguousInStackingOrder;
682         m_descendantsAreContiguousInStackingOrder = newValue;
683         if (didUpdate)
684             updateNeedsCompositedScrolling();
685     }
686 }
687
688 void RenderLayer::computeRepaintRects(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* geometryMap)
689 {
690     ASSERT(!m_visibleContentStatusDirty);
691
692     m_repaintRect = renderer().clippedOverflowRectForRepaint(repaintContainer);
693     m_outlineBox = renderer().outlineBoundsForRepaint(repaintContainer, geometryMap);
694 }
695
696
697 void RenderLayer::computeRepaintRectsIncludingDescendants()
698 {
699     // FIXME: computeRepaintRects() has to walk up the parent chain for every layer to compute the rects.
700     // We should make this more efficient.
701     // FIXME: it's wrong to call this when layout is not up-to-date, which we do.
702     computeRepaintRects(renderer().containerForRepaint());
703
704     for (RenderLayer* layer = firstChild(); layer; layer = layer->nextSibling())
705         layer->computeRepaintRectsIncludingDescendants();
706 }
707
708 void RenderLayer::clearRepaintRects()
709 {
710     ASSERT(!m_hasVisibleContent);
711     ASSERT(!m_visibleContentStatusDirty);
712
713     m_repaintRect = LayoutRect();
714     m_outlineBox = LayoutRect();
715 }
716
717 void RenderLayer::updateLayerPositionsAfterDocumentScroll()
718 {
719     ASSERT(this == renderer().view().layer());
720
721     RenderGeometryMap geometryMap(UseTransforms);
722     updateLayerPositionsAfterScroll(&geometryMap);
723 }
724
725 void RenderLayer::updateLayerPositionsAfterOverflowScroll()
726 {
727     RenderGeometryMap geometryMap(UseTransforms);
728     if (this != renderer().view().layer())
729         geometryMap.pushMappingsToAncestor(parent(), 0);
730
731     // FIXME: why is it OK to not check the ancestors of this layer in order to
732     // initialize the HasSeenViewportConstrainedAncestor and HasSeenAncestorWithOverflowClip flags?
733     updateLayerPositionsAfterScroll(&geometryMap, IsOverflowScroll);
734 }
735
736 void RenderLayer::updateLayerPositionsAfterScroll(RenderGeometryMap* geometryMap, UpdateLayerPositionsAfterScrollFlags flags)
737 {
738     // FIXME: This shouldn't be needed, but there are some corner cases where
739     // these flags are still dirty. Update so that the check below is valid.
740     updateDescendantDependentFlags();
741
742     // If we have no visible content and no visible descendants, there is no point recomputing
743     // our rectangles as they will be empty. If our visibility changes, we are expected to
744     // recompute all our positions anyway.
745     if (!m_hasVisibleDescendant && !m_hasVisibleContent)
746         return;
747
748     bool positionChanged = updateLayerPosition();
749     if (positionChanged)
750         flags |= HasChangedAncestor;
751
752     if (geometryMap)
753         geometryMap->pushMappingsToAncestor(this, parent());
754
755     if (flags & HasChangedAncestor || flags & HasSeenViewportConstrainedAncestor || flags & IsOverflowScroll)
756         clearClipRects();
757
758     if (renderer().style().hasViewportConstrainedPosition())
759         flags |= HasSeenViewportConstrainedAncestor;
760
761     if (renderer().hasOverflowClip())
762         flags |= HasSeenAncestorWithOverflowClip;
763
764     if (flags & HasSeenViewportConstrainedAncestor
765         || (flags & IsOverflowScroll && flags & HasSeenAncestorWithOverflowClip)) {
766         // FIXME: We could track the repaint container as we walk down the tree.
767         computeRepaintRects(renderer().containerForRepaint(), geometryMap);
768     } else {
769         // Check that our cached rects are correct.
770         ASSERT(m_repaintRect == renderer().clippedOverflowRectForRepaint(renderer().containerForRepaint()));
771         ASSERT(m_outlineBox == renderer().outlineBoundsForRepaint(renderer().containerForRepaint(), geometryMap));
772     }
773     
774     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
775         child->updateLayerPositionsAfterScroll(geometryMap, flags);
776
777     // We don't update our reflection as scrolling is a translation which does not change the size()
778     // of an object, thus RenderReplica will still repaint itself properly as the layer position was
779     // updated above.
780
781     if (m_marquee) {
782         bool oldUpdatingMarqueePosition = m_updatingMarqueePosition;
783         m_updatingMarqueePosition = true;
784         m_marquee->updateMarqueePosition();
785         m_updatingMarqueePosition = oldUpdatingMarqueePosition;
786     }
787
788     if (geometryMap)
789         geometryMap->popMappingsToAncestor(parent());
790 }
791
792 void RenderLayer::positionNewlyCreatedOverflowControls()
793 {
794     if (!backing()->hasUnpositionedOverflowControlsLayers())
795         return;
796
797     RenderGeometryMap geometryMap(UseTransforms);
798     if (this != renderer().view().layer() && parent())
799         geometryMap.pushMappingsToAncestor(parent(), 0);
800
801     LayoutPoint offsetFromRoot = LayoutPoint(geometryMap.absolutePoint(FloatPoint()));
802     positionOverflowControls(toIntSize(roundedIntPoint(offsetFromRoot)));
803 }
804
805 #if ENABLE(CSS_COMPOSITING)
806
807 void RenderLayer::updateBlendMode()
808 {
809     bool hadBlendMode = m_blendMode != BlendModeNormal;
810     if (hadBlendMode != hasBlendMode()) {
811         if (hasBlendMode())
812             updateNonCompositedParentStackingContextHasBlendedChild(true);
813         else
814             dirtyAncestorParentStackingContextHasBlendedElement();
815     }
816
817     BlendMode newBlendMode = renderer().style().blendMode();
818     if (newBlendMode != m_blendMode)
819         m_blendMode = newBlendMode;
820 }
821
822 void RenderLayer::updateNonCompositedParentStackingContextHasBlendedChild(bool hasBlendedChild)
823 {
824     if (isComposited())
825         return;
826
827     for (auto ancestor = parent(); ancestor && !ancestor->isComposited() && !ancestor->renderer().isRoot(); ancestor = ancestor->parent()) {
828         ancestor->m_hasBlendedElementInChildStackingContext = hasBlendedChild;
829
830         if (ancestor->isStackingContext())
831             break;
832     }
833 }
834
835 void RenderLayer::dirtyAncestorParentStackingContextHasBlendedElement()
836 {
837     for (auto layer = this; layer && !layer->isComposited() && !layer->m_hasBlendedElementInChildStackingContextStatusDirty; layer = layer->parent()) {
838         layer->m_hasBlendedElementInChildStackingContextStatusDirty = true;
839
840         if (layer->isStackingContext())
841             break;
842     }
843 }
844
845 bool RenderLayer::nonCompositedParentStackingContextHasBlendedChild() const
846 {
847     for (auto ancestor = parent(); ancestor && !ancestor->isComposited() && !ancestor->renderer().isRoot(); ancestor = ancestor->parent()) {
848         if (ancestor->isStackingContext())
849             return ancestor->hasBlendedElementInChildStackingContext();
850     }
851
852     return false;
853 }
854
855 #endif
856
857 void RenderLayer::updateTransform()
858 {
859     // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
860     // so check style too.
861     bool hasTransform = renderer().hasTransform() && renderer().style().hasTransform();
862     bool had3DTransform = has3DTransform();
863
864     bool hadTransform = !!m_transform;
865     if (hasTransform != hadTransform) {
866         if (hasTransform)
867             m_transform = std::make_unique<TransformationMatrix>();
868         else
869             m_transform = nullptr;
870         
871         // Layers with transforms act as clip rects roots, so clear the cached clip rects here.
872         clearClipRectsIncludingDescendants();
873     }
874     
875     if (hasTransform) {
876         RenderBox* box = renderBox();
877         ASSERT(box);
878         m_transform->makeIdentity();
879         box->style().applyTransform(*m_transform, pixelSnappedForPainting(box->borderBoxRect(), box->document().deviceScaleFactor()), RenderStyle::IncludeTransformOrigin);
880         makeMatrixRenderable(*m_transform, canRender3DTransforms());
881     }
882
883     if (had3DTransform != has3DTransform())
884         dirty3DTransformedDescendantStatus();
885 }
886
887 TransformationMatrix RenderLayer::currentTransform(RenderStyle::ApplyTransformOrigin applyOrigin) const
888 {
889     if (!m_transform)
890         return TransformationMatrix();
891
892     RenderBox* box = renderBox();
893     ASSERT(box);
894     FloatRect pixelSnappedBorderRect = pixelSnappedForPainting(box->borderBoxRect(), box->document().deviceScaleFactor());
895     if (renderer().style().isRunningAcceleratedAnimation()) {
896         TransformationMatrix currTransform;
897         RefPtr<RenderStyle> style = renderer().animation().getAnimatedStyleForRenderer(&renderer());
898         style->applyTransform(currTransform, pixelSnappedBorderRect, applyOrigin);
899         makeMatrixRenderable(currTransform, canRender3DTransforms());
900         return currTransform;
901     }
902
903     // m_transform includes transform-origin, so we need to recompute the transform here.
904     if (applyOrigin == RenderStyle::ExcludeTransformOrigin) {
905         TransformationMatrix currTransform;
906         box->style().applyTransform(currTransform, pixelSnappedBorderRect, RenderStyle::ExcludeTransformOrigin);
907         makeMatrixRenderable(currTransform, canRender3DTransforms());
908         return currTransform;
909     }
910
911     return *m_transform;
912 }
913
914 TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavior) const
915 {
916     if (!m_transform)
917         return TransformationMatrix();
918     
919     if (paintBehavior & PaintBehaviorFlattenCompositingLayers) {
920         TransformationMatrix matrix = *m_transform;
921         makeMatrixRenderable(matrix, false /* flatten 3d */);
922         return matrix;
923     }
924
925     return *m_transform;
926 }
927
928 RenderLayer* RenderLayer::enclosingOverflowClipLayer(IncludeSelfOrNot includeSelf) const
929 {
930     const RenderLayer* layer = (includeSelf == IncludeSelf) ? this : parent();
931     while (layer) {
932         if (layer->renderer().hasOverflowClip())
933             return const_cast<RenderLayer*>(layer);
934
935         layer = layer->parent();
936     }
937     return 0;
938 }
939
940 static bool checkContainingBlockChainForPagination(RenderLayerModelObject* renderer, RenderBox* ancestorColumnsRenderer)
941 {
942     RenderLayerModelObject* prevBlock = renderer;
943     RenderBlock* containingBlock;
944     for (containingBlock = renderer->containingBlock();
945         containingBlock && containingBlock != &renderer->view() && containingBlock != ancestorColumnsRenderer;
946         containingBlock = containingBlock->containingBlock()) {
947         prevBlock = containingBlock;
948     }
949     
950     // If the columns block wasn't in our containing block chain, then we aren't paginated by it.
951     if (containingBlock != ancestorColumnsRenderer)
952         return false;
953         
954     // If the previous block is absolutely positioned, then we can't be paginated by the columns block.
955     if (prevBlock->isOutOfFlowPositioned())
956         return false;
957         
958     // Otherwise we are paginated by the columns block.
959     return true;
960 }
961
962 bool RenderLayer::useRegionBasedColumns() const
963 {
964     const Settings& settings = renderer().frame().settings();
965     return settings.regionBasedColumnsEnabled();
966 }
967
968 void RenderLayer::updatePagination()
969 {
970     m_isPaginated = false;
971     m_enclosingPaginationLayer = 0;
972
973     if (isComposited() || !parent())
974         return; // FIXME: We will have to deal with paginated compositing layers someday.
975                 // FIXME: For now the RenderView can't be paginated.  Eventually printing will move to a model where it is though.
976
977     // The main difference between the paginated booleans for the old column code and the new column code
978     // is that each paginated layer has to paint on its own with the new code. There is no
979     // recurring into child layers. This means that the m_isPaginated bits for the new column code can't just be set on
980     // "roots" that get split and paint all their descendants. Instead each layer has to be checked individually and
981     // genuinely know if it is going to have to split itself up when painting only its contents (and not any other descendant
982     // layers). We track an enclosingPaginationLayer instead of using a simple bit, since we want to be able to get back
983     // to that layer easily.
984     bool regionBasedColumnsUsed = useRegionBasedColumns();
985     if (regionBasedColumnsUsed && renderer().isInFlowRenderFlowThread()) {
986         m_enclosingPaginationLayer = this;
987         return;
988     }
989
990     if (isNormalFlowOnly()) {
991         if (regionBasedColumnsUsed) {
992             // Content inside a transform is not considered to be paginated, since we simply
993             // paint the transform multiple times in each column, so we don't have to use
994             // fragments for the transformed content.
995             m_enclosingPaginationLayer = parent()->enclosingPaginationLayer();
996             if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform())
997                 m_enclosingPaginationLayer = 0;
998         } else
999             m_isPaginated = parent()->renderer().hasColumns();
1000         return;
1001     }
1002
1003     // For the new columns code, we want to walk up our containing block chain looking for an enclosing layer. Once
1004     // we find one, then we just check its pagination status.
1005     if (regionBasedColumnsUsed) {
1006         RenderView* renderView = &renderer().view();
1007         RenderBlock* containingBlock;
1008         for (containingBlock = renderer().containingBlock();
1009             containingBlock && containingBlock != renderView;
1010             containingBlock = containingBlock->containingBlock()) {
1011             if (containingBlock->hasLayer()) {
1012                 // Content inside a transform is not considered to be paginated, since we simply
1013                 // paint the transform multiple times in each column, so we don't have to use
1014                 // fragments for the transformed content.
1015                 m_enclosingPaginationLayer = containingBlock->layer()->enclosingPaginationLayer();
1016                 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform())
1017                     m_enclosingPaginationLayer = 0;
1018                 return;
1019             }
1020         }
1021         return;
1022     }
1023
1024     // If we're not normal flow, then we need to look for a multi-column object between us and our stacking container.
1025     RenderLayer* ancestorStackingContainer = stackingContainer();
1026     for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
1027         if (curr->renderer().hasColumns()) {
1028             m_isPaginated = checkContainingBlockChainForPagination(&renderer(), curr->renderBox());
1029             return;
1030         }
1031         if (curr == ancestorStackingContainer)
1032             return;
1033     }
1034 }
1035
1036 bool RenderLayer::canBeStackingContainer() const
1037 {
1038     if (isStackingContext() || !stackingContainer())
1039         return true;
1040
1041     return m_descendantsAreContiguousInStackingOrder;
1042 }
1043
1044 void RenderLayer::setHasVisibleContent()
1045
1046     if (m_hasVisibleContent && !m_visibleContentStatusDirty) {
1047         ASSERT(!parent() || parent()->hasVisibleDescendant());
1048         return;
1049     }
1050
1051     m_visibleContentStatusDirty = false; 
1052     m_hasVisibleContent = true;
1053     computeRepaintRects(renderer().containerForRepaint());
1054     if (!isNormalFlowOnly()) {
1055         // We don't collect invisible layers in z-order lists if we are not in compositing mode.
1056         // As we became visible, we need to dirty our stacking containers ancestors to be properly
1057         // collected. FIXME: When compositing, we could skip this dirtying phase.
1058         for (RenderLayer* sc = stackingContainer(); sc; sc = sc->stackingContainer()) {
1059             sc->dirtyZOrderLists();
1060             if (sc->hasVisibleContent())
1061                 break;
1062         }
1063     }
1064
1065     if (parent())
1066         parent()->setAncestorChainHasVisibleDescendant();
1067 }
1068
1069 void RenderLayer::dirtyVisibleContentStatus() 
1070
1071     m_visibleContentStatusDirty = true; 
1072     if (parent())
1073         parent()->dirtyAncestorChainVisibleDescendantStatus();
1074 }
1075
1076 void RenderLayer::dirtyAncestorChainVisibleDescendantStatus()
1077 {
1078     for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1079         if (layer->m_visibleDescendantStatusDirty)
1080             break;
1081
1082         layer->m_visibleDescendantStatusDirty = true;
1083     }
1084 }
1085
1086 void RenderLayer::setAncestorChainHasVisibleDescendant()
1087 {
1088     for (RenderLayer* layer = this; layer; layer = layer->parent()) {
1089         if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendant())
1090             break;
1091
1092         layer->m_hasVisibleDescendant = true;
1093         layer->m_visibleDescendantStatusDirty = false;
1094     }
1095 }
1096
1097 void RenderLayer::updateDescendantDependentFlags(HashSet<const RenderObject*>* outOfFlowDescendantContainingBlocks)
1098 {
1099     if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty || hasBlendedElementInChildStackingContextStatusDirty()) {
1100         m_hasVisibleDescendant = false;
1101         m_hasSelfPaintingLayerDescendant = false;
1102         m_hasOutOfFlowPositionedDescendant = false;
1103         setHasBlendedElementInChildStackingContext(false);
1104
1105         HashSet<const RenderObject*> childOutOfFlowDescendantContainingBlocks;
1106         for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
1107             childOutOfFlowDescendantContainingBlocks.clear();
1108             child->updateDescendantDependentFlags(&childOutOfFlowDescendantContainingBlocks);
1109
1110             bool childIsOutOfFlowPositioned = child->renderer().isOutOfFlowPositioned();
1111             if (childIsOutOfFlowPositioned)
1112                 childOutOfFlowDescendantContainingBlocks.add(child->renderer().containingBlock());
1113
1114             if (outOfFlowDescendantContainingBlocks) {
1115                 HashSet<const RenderObject*>::const_iterator it = childOutOfFlowDescendantContainingBlocks.begin();
1116                 for (; it != childOutOfFlowDescendantContainingBlocks.end(); ++it)
1117                     outOfFlowDescendantContainingBlocks->add(*it);
1118             }
1119
1120             bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_hasVisibleDescendant;
1121             bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant();
1122             bool hasOutOfFlowPositionedDescendant = !childOutOfFlowDescendantContainingBlocks.isEmpty();
1123             bool hasBlendedElementInChildStackingContext = child->hasBlendMode() || child->hasBlendedElementInChildStackingContext();
1124
1125             m_hasVisibleDescendant |= hasVisibleDescendant;
1126             m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant;
1127             m_hasOutOfFlowPositionedDescendant |= hasOutOfFlowPositionedDescendant;
1128             setHasBlendedElementInChildStackingContext(this->hasBlendedElementInChildStackingContext() | hasBlendedElementInChildStackingContext);
1129
1130             if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && m_hasOutOfFlowPositionedDescendant && this->hasBlendedElementInChildStackingContext())
1131                 break;
1132         }
1133
1134         if (outOfFlowDescendantContainingBlocks)
1135             outOfFlowDescendantContainingBlocks->remove(&renderer());
1136
1137         m_visibleDescendantStatusDirty = false;
1138         m_hasSelfPaintingLayerDescendantDirty = false;
1139
1140         if (m_hasOutOfFlowPositionedDescendantDirty)
1141             updateNeedsCompositedScrolling();
1142
1143         m_hasOutOfFlowPositionedDescendantDirty = false;
1144
1145         setHasBlendedElementInChildStackingContextStatusDirty(false);
1146     }
1147
1148     if (m_visibleContentStatusDirty) {
1149         if (renderer().style().visibility() == VISIBLE)
1150             m_hasVisibleContent = true;
1151         else {
1152             // layer may be hidden but still have some visible content, check for this
1153             m_hasVisibleContent = false;
1154             RenderObject* r = renderer().firstChild();
1155             while (r) {
1156                 if (r->style().visibility() == VISIBLE && !r->hasLayer()) {
1157                     m_hasVisibleContent = true;
1158                     break;
1159                 }
1160                 RenderObject* child;
1161                 if (!r->hasLayer() && (child = r->firstChildSlow()))
1162                     r = child;
1163                 else if (r->nextSibling())
1164                     r = r->nextSibling();
1165                 else {
1166                     do {
1167                         r = r->parent();
1168                         if (r == &renderer())
1169                             r = 0;
1170                     } while (r && !r->nextSibling());
1171                     if (r)
1172                         r = r->nextSibling();
1173                 }
1174             }
1175         }    
1176         m_visibleContentStatusDirty = false; 
1177     }
1178 }
1179
1180 // Return true if the new clipping behaviour requires layer update.
1181 bool RenderLayer::checkIfDescendantClippingContextNeedsUpdate(bool isClipping)
1182 {
1183     for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
1184         RenderLayerBacking* backing = child->backing();
1185         // Layer subtree needs update when new clipping is added or existing clipping is removed.
1186         if (backing && (isClipping || backing->hasAncestorClippingLayer()))
1187             return true;
1188
1189         if (child->checkIfDescendantClippingContextNeedsUpdate(isClipping))
1190             return true;
1191     }
1192     return false;
1193 }
1194
1195 void RenderLayer::dirty3DTransformedDescendantStatus()
1196 {
1197     RenderLayer* curr = stackingContainer();
1198     if (curr)
1199         curr->m_3DTransformedDescendantStatusDirty = true;
1200         
1201     // This propagates up through preserve-3d hierarchies to the enclosing flattening layer.
1202     // Note that preserves3D() creates stacking context, so we can just run up the stacking containers.
1203     while (curr && curr->preserves3D()) {
1204         curr->m_3DTransformedDescendantStatusDirty = true;
1205         curr = curr->stackingContainer();
1206     }
1207 }
1208
1209 // Return true if this layer or any preserve-3d descendants have 3d.
1210 bool RenderLayer::update3DTransformedDescendantStatus()
1211 {
1212     if (m_3DTransformedDescendantStatusDirty) {
1213         m_has3DTransformedDescendant = false;
1214
1215         updateZOrderLists();
1216
1217         // Transformed or preserve-3d descendants can only be in the z-order lists, not
1218         // in the normal flow list, so we only need to check those.
1219         if (Vector<RenderLayer*>* positiveZOrderList = posZOrderList()) {
1220             for (unsigned i = 0; i < positiveZOrderList->size(); ++i)
1221                 m_has3DTransformedDescendant |= positiveZOrderList->at(i)->update3DTransformedDescendantStatus();
1222         }
1223
1224         // Now check our negative z-index children.
1225         if (Vector<RenderLayer*>* negativeZOrderList = negZOrderList()) {
1226             for (unsigned i = 0; i < negativeZOrderList->size(); ++i)
1227                 m_has3DTransformedDescendant |= negativeZOrderList->at(i)->update3DTransformedDescendantStatus();
1228         }
1229         
1230         m_3DTransformedDescendantStatusDirty = false;
1231     }
1232     
1233     // If we live in a 3d hierarchy, then the layer at the root of that hierarchy needs
1234     // the m_has3DTransformedDescendant set.
1235     if (preserves3D())
1236         return has3DTransform() || m_has3DTransformedDescendant;
1237
1238     return has3DTransform();
1239 }
1240
1241 bool RenderLayer::updateLayerPosition()
1242 {
1243     LayoutPoint localPoint;
1244     LayoutSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done.
1245     if (renderer().isInline() && renderer().isRenderInline()) {
1246         RenderInline& inlineFlow = toRenderInline(renderer());
1247         IntRect lineBox = inlineFlow.linesBoundingBox();
1248         setSize(lineBox.size());
1249         inlineBoundingBoxOffset = toLayoutSize(lineBox.location());
1250         localPoint += inlineBoundingBoxOffset;
1251     } else if (RenderBox* box = renderBox()) {
1252         // FIXME: Is snapping the size really needed here for the RenderBox case?
1253         setSize(pixelSnappedIntSize(box->size(), box->location()));
1254         localPoint += box->topLeftLocationOffset();
1255     }
1256
1257     if (!renderer().isOutOfFlowPositioned() && renderer().parent()) {
1258         // We must adjust our position by walking up the render tree looking for the
1259         // nearest enclosing object with a layer.
1260         RenderElement* curr = renderer().parent();
1261         while (curr && !curr->hasLayer()) {
1262             if (curr->isBox() && !curr->isTableRow()) {
1263                 // Rows and cells share the same coordinate space (that of the section).
1264                 // Omit them when computing our xpos/ypos.
1265                 localPoint += toRenderBox(curr)->topLeftLocationOffset();
1266             }
1267             curr = curr->parent();
1268         }
1269         if (curr->isBox() && curr->isTableRow()) {
1270             // Put ourselves into the row coordinate space.
1271             localPoint -= toRenderBox(curr)->topLeftLocationOffset();
1272         }
1273     }
1274     
1275     // Subtract our parent's scroll offset.
1276     if (renderer().isOutOfFlowPositioned() && enclosingPositionedAncestor()) {
1277         RenderLayer* positionedParent = enclosingPositionedAncestor();
1278
1279         // For positioned layers, we subtract out the enclosing positioned layer's scroll offset.
1280         if (positionedParent->renderer().hasOverflowClip()) {
1281             LayoutSize offset = positionedParent->scrolledContentOffset();
1282             localPoint -= offset;
1283         }
1284         
1285         if (renderer().isOutOfFlowPositioned() && positionedParent->renderer().isInFlowPositioned() && positionedParent->renderer().isRenderInline()) {
1286             LayoutSize offset = toRenderInline(positionedParent->renderer()).offsetForInFlowPositionedInline(&toRenderBox(renderer()));
1287             localPoint += offset;
1288         }
1289     } else if (parent()) {
1290         if (parent()->renderer().hasOverflowClip()) {
1291             IntSize scrollOffset = parent()->scrolledContentOffset();
1292             localPoint -= scrollOffset;
1293         }
1294     }
1295     
1296     bool positionOrOffsetChanged = false;
1297     if (renderer().isInFlowPositioned()) {
1298         LayoutSize newOffset = toRenderBoxModelObject(renderer()).offsetForInFlowPosition();
1299         positionOrOffsetChanged = newOffset != m_offsetForInFlowPosition;
1300         m_offsetForInFlowPosition = newOffset;
1301         localPoint.move(m_offsetForInFlowPosition);
1302     } else {
1303         m_offsetForInFlowPosition = LayoutSize();
1304     }
1305
1306     // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
1307     localPoint -= inlineBoundingBoxOffset;
1308     
1309     positionOrOffsetChanged |= location() != localPoint;
1310     setLocation(localPoint);
1311     return positionOrOffsetChanged;
1312 }
1313
1314 TransformationMatrix RenderLayer::perspectiveTransform() const
1315 {
1316     if (!renderer().hasTransform())
1317         return TransformationMatrix();
1318
1319     const RenderStyle& style = renderer().style();
1320     if (!style.hasPerspective())
1321         return TransformationMatrix();
1322
1323     // Maybe fetch the perspective from the backing?
1324     const IntRect borderBox = toRenderBox(renderer()).pixelSnappedBorderBoxRect();
1325     const float boxWidth = borderBox.width();
1326     const float boxHeight = borderBox.height();
1327
1328     float perspectiveOriginX = floatValueForLength(style.perspectiveOriginX(), boxWidth);
1329     float perspectiveOriginY = floatValueForLength(style.perspectiveOriginY(), boxHeight);
1330
1331     // A perspective origin of 0,0 makes the vanishing point in the center of the element.
1332     // We want it to be in the top-left, so subtract half the height and width.
1333     perspectiveOriginX -= boxWidth / 2.0f;
1334     perspectiveOriginY -= boxHeight / 2.0f;
1335     
1336     TransformationMatrix t;
1337     t.translate(perspectiveOriginX, perspectiveOriginY);
1338     t.applyPerspective(style.perspective());
1339     t.translate(-perspectiveOriginX, -perspectiveOriginY);
1340     
1341     return t;
1342 }
1343
1344 FloatPoint RenderLayer::perspectiveOrigin() const
1345 {
1346     if (!renderer().hasTransform())
1347         return FloatPoint();
1348
1349     const LayoutRect borderBox = toRenderBox(renderer()).borderBoxRect();
1350     const RenderStyle& style = renderer().style();
1351
1352     return FloatPoint(floatValueForLength(style.perspectiveOriginX(), borderBox.width()),
1353                       floatValueForLength(style.perspectiveOriginY(), borderBox.height()));
1354 }
1355
1356 RenderLayer* RenderLayer::stackingContainer() const
1357 {
1358     RenderLayer* layer = parent();
1359     while (layer && !layer->isStackingContainer())
1360         layer = layer->parent();
1361
1362     ASSERT(!layer || layer->isStackingContainer());
1363     return layer;
1364 }
1365
1366 static inline bool isPositionedContainer(RenderLayer* layer)
1367 {
1368     return layer->isRootLayer() || layer->renderer().isPositioned() || layer->hasTransform();
1369 }
1370
1371 static inline bool isFixedPositionedContainer(RenderLayer* layer)
1372 {
1373     return layer->isRootLayer() || layer->hasTransform();
1374 }
1375
1376 RenderLayer* RenderLayer::enclosingPositionedAncestor() const
1377 {
1378     RenderLayer* curr = parent();
1379     while (curr && !isPositionedContainer(curr))
1380         curr = curr->parent();
1381
1382     return curr;
1383 }
1384
1385 static RenderLayer* parentLayerCrossFrame(const RenderLayer* layer)
1386 {
1387     ASSERT(layer);
1388     if (layer->parent())
1389         return layer->parent();
1390
1391     HTMLFrameOwnerElement* ownerElement = layer->renderer().document().ownerElement();
1392     if (!ownerElement)
1393         return 0;
1394
1395     RenderElement* ownerRenderer = ownerElement->renderer();
1396     if (!ownerRenderer)
1397         return 0;
1398
1399     return ownerRenderer->enclosingLayer();
1400 }
1401
1402 RenderLayer* RenderLayer::enclosingScrollableLayer() const
1403 {
1404     for (RenderLayer* nextLayer = parentLayerCrossFrame(this); nextLayer; nextLayer = parentLayerCrossFrame(nextLayer)) {
1405         if (nextLayer->renderer().isBox() && toRenderBox(nextLayer->renderer()).canBeScrolledAndHasScrollableArea())
1406             return nextLayer;
1407     }
1408
1409     return 0;
1410 }
1411
1412 IntRect RenderLayer::scrollableAreaBoundingBox() const
1413 {
1414     return renderer().absoluteBoundingBoxRect();
1415 }
1416
1417 RenderLayer* RenderLayer::enclosingTransformedAncestor() const
1418 {
1419     RenderLayer* curr = parent();
1420     while (curr && !curr->isRootLayer() && !curr->transform())
1421         curr = curr->parent();
1422
1423     return curr;
1424 }
1425
1426 static inline const RenderLayer* compositingContainer(const RenderLayer* layer)
1427 {
1428     return layer->isNormalFlowOnly() ? layer->parent() : layer->stackingContainer();
1429 }
1430
1431 inline bool RenderLayer::shouldRepaintAfterLayout() const
1432 {
1433     if (m_repaintStatus == NeedsNormalRepaint)
1434         return true;
1435
1436     // Composited layers that were moved during a positioned movement only
1437     // layout, don't need to be repainted. They just need to be recomposited.
1438     ASSERT(m_repaintStatus == NeedsFullRepaintForPositionedMovementLayout);
1439     return !isComposited() || backing()->paintsIntoCompositedAncestor();
1440 }
1441
1442 static bool compositedWithOwnBackingStore(const RenderLayer* layer)
1443 {
1444     return layer->isComposited() && !layer->backing()->paintsIntoCompositedAncestor();
1445 }
1446
1447 RenderLayer* RenderLayer::enclosingCompositingLayer(IncludeSelfOrNot includeSelf) const
1448 {
1449     if (includeSelf == IncludeSelf && isComposited())
1450         return const_cast<RenderLayer*>(this);
1451
1452     for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) {
1453         if (curr->isComposited())
1454             return const_cast<RenderLayer*>(curr);
1455     }
1456          
1457     return 0;
1458 }
1459
1460 RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(IncludeSelfOrNot includeSelf) const
1461 {
1462     if (includeSelf == IncludeSelf && isComposited() && !backing()->paintsIntoCompositedAncestor())
1463         return const_cast<RenderLayer*>(this);
1464
1465     for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) {
1466         if (compositedWithOwnBackingStore(curr))
1467             return const_cast<RenderLayer*>(curr);
1468     }
1469          
1470     return 0;
1471 }
1472
1473 #if ENABLE(CSS_FILTERS)
1474
1475 RenderLayer* RenderLayer::enclosingFilterLayer(IncludeSelfOrNot includeSelf) const
1476 {
1477     const RenderLayer* curr = (includeSelf == IncludeSelf) ? this : parent();
1478     for (; curr; curr = curr->parent()) {
1479         if (curr->requiresFullLayerImageForFilters())
1480             return const_cast<RenderLayer*>(curr);
1481     }
1482     
1483     return 0;
1484 }
1485
1486 RenderLayer* RenderLayer::enclosingFilterRepaintLayer() const
1487 {
1488     for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1489         if ((curr != this && curr->requiresFullLayerImageForFilters()) || compositedWithOwnBackingStore(curr) || curr->isRootLayer())
1490             return const_cast<RenderLayer*>(curr);
1491     }
1492     return 0;
1493 }
1494
1495 void RenderLayer::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect)
1496 {
1497     if (rect.isEmpty())
1498         return;
1499     
1500     LayoutRect rectForRepaint = rect;
1501     renderer().style().filterOutsets().expandRect(rectForRepaint);
1502
1503     FilterInfo& filterInfo = FilterInfo::get(*this);
1504     filterInfo.expandDirtySourceRect(rectForRepaint);
1505     
1506     RenderLayer* parentLayer = enclosingFilterRepaintLayer();
1507     ASSERT(parentLayer);
1508     FloatQuad repaintQuad(rectForRepaint);
1509     LayoutRect parentLayerRect = renderer().localToContainerQuad(repaintQuad, &parentLayer->renderer()).enclosingBoundingBox();
1510
1511     if (parentLayer->isComposited()) {
1512         if (!parentLayer->backing()->paintsIntoWindow()) {
1513             parentLayer->setBackingNeedsRepaintInRect(parentLayerRect);
1514             return;
1515         }
1516         // If the painting goes to window, redirect the painting to the parent RenderView.
1517         parentLayer = renderer().view().layer();
1518         parentLayerRect = renderer().localToContainerQuad(repaintQuad, &parentLayer->renderer()).enclosingBoundingBox();
1519     }
1520
1521     if (parentLayer->paintsWithFilters()) {
1522         parentLayer->setFilterBackendNeedsRepaintingInRect(parentLayerRect);
1523         return;        
1524     }
1525     
1526     if (parentLayer->isRootLayer()) {
1527         toRenderView(parentLayer->renderer()).repaintViewRectangle(parentLayerRect);
1528         return;
1529     }
1530     
1531     ASSERT_NOT_REACHED();
1532 }
1533
1534 bool RenderLayer::hasAncestorWithFilterOutsets() const
1535 {
1536     for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
1537         if (curr->renderer().style().hasFilterOutsets())
1538             return true;
1539     }
1540     return false;
1541 }
1542
1543 #endif
1544
1545 RenderLayer* RenderLayer::clippingRootForPainting() const
1546 {
1547     if (isComposited())
1548         return const_cast<RenderLayer*>(this);
1549
1550     const RenderLayer* current = this;
1551     while (current) {
1552         if (current->isRootLayer())
1553             return const_cast<RenderLayer*>(current);
1554
1555         current = compositingContainer(current);
1556         ASSERT(current);
1557         if (current->transform() || compositedWithOwnBackingStore(current))
1558             return const_cast<RenderLayer*>(current);
1559     }
1560
1561     ASSERT_NOT_REACHED();
1562     return 0;
1563 }
1564
1565 LayoutPoint RenderLayer::absoluteToContents(const LayoutPoint& absolutePoint) const
1566 {
1567     // We don't use convertToLayerCoords because it doesn't know about transforms
1568     return roundedLayoutPoint(renderer().absoluteToLocal(absolutePoint, UseTransforms));
1569 }
1570
1571 bool RenderLayer::cannotBlitToWindow() const
1572 {
1573     if (isTransparent() || hasReflection() || hasTransform())
1574         return true;
1575     if (!parent())
1576         return false;
1577     return parent()->cannotBlitToWindow();
1578 }
1579
1580 bool RenderLayer::isTransparent() const
1581 {
1582     if (renderer().element() && renderer().element()->isSVGElement())
1583         return false;
1584     return renderer().isTransparent() || renderer().hasMask();
1585 }
1586
1587 RenderLayer* RenderLayer::transparentPaintingAncestor()
1588 {
1589     if (isComposited())
1590         return 0;
1591
1592     for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
1593         if (curr->isComposited())
1594             return 0;
1595         if (curr->isTransparent())
1596             return curr;
1597     }
1598     return 0;
1599 }
1600
1601 enum TransparencyClipBoxBehavior {
1602     PaintingTransparencyClipBox,
1603     HitTestingTransparencyClipBox
1604 };
1605
1606 enum TransparencyClipBoxMode {
1607     DescendantsOfTransparencyClipBox,
1608     RootOfTransparencyClipBox
1609 };
1610
1611 static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, PaintBehavior = 0);
1612
1613 static void expandClipRectForRegionAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
1614     TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior)
1615 {
1616     // If this is a region, then the painting is actually done by its flow thread's layer.
1617     if (layer->renderer().isRenderNamedFlowFragmentContainer()) {
1618         RenderBlockFlow* regionContainer = toRenderBlockFlow(&layer->renderer());
1619         RenderNamedFlowFragment* region = regionContainer->renderNamedFlowFragment();
1620         RenderLayer* flowThreadLayer = region->flowThread()->layer();
1621         if (!layer->reflection() || layer->reflectionLayer() != flowThreadLayer) {
1622             LayoutRect flowThreadClipRect = transparencyClipBox(flowThreadLayer, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior);
1623             
1624             LayoutPoint offsetFromRoot;
1625             layer->convertToLayerCoords(flowThreadLayer, offsetFromRoot);
1626
1627             LayoutSize moveOffset = (offsetFromRoot + regionContainer->contentBoxRect().location()) - region->flowThreadPortionRect().location();
1628             flowThreadClipRect.move(moveOffset);
1629             
1630             clipRect.unite(flowThreadClipRect);
1631         }
1632     }
1633 }
1634
1635 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
1636     TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior)
1637 {
1638     // If we have a mask, then the clip is limited to the border box area (and there is
1639     // no need to examine child layers).
1640     if (!layer->renderer().hasMask()) {
1641         // Note: we don't have to walk z-order lists since transparent elements always establish
1642         // a stacking container. This means we can just walk the layer tree directly.
1643         for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling()) {
1644             if (!layer->reflection() || layer->reflectionLayer() != curr)
1645                 clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior));
1646         }
1647     }
1648
1649     expandClipRectForRegionAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
1650
1651     // If we have a reflection, then we need to account for that when we push the clip.  Reflect our entire
1652     // current transparencyClipBox to catch all child layers.
1653     // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this
1654     // size into the parent layer.
1655     if (layer->renderer().hasReflection()) {
1656         LayoutPoint delta;
1657         layer->convertToLayerCoords(rootLayer, delta);
1658         clipRect.move(-delta.x(), -delta.y());
1659         clipRect.unite(layer->renderBox()->reflectedRect(clipRect));
1660         clipRect.moveBy(delta);
1661     }
1662 }
1663
1664 static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
1665     TransparencyClipBoxMode transparencyMode, PaintBehavior paintBehavior)
1666 {
1667     // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
1668     // paintDirtyRect, and that should cut down on the amount we have to paint.  Still it
1669     // would be better to respect clips.
1670     
1671     if (rootLayer != layer && ((transparencyBehavior == PaintingTransparencyClipBox && layer->paintsWithTransform(paintBehavior))
1672         || (transparencyBehavior == HitTestingTransparencyClipBox && layer->hasTransform()))) {
1673         // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
1674         // the transformed layer and all of its children.
1675         const RenderLayer* paginationLayer = transparencyMode == DescendantsOfTransparencyClipBox ? layer->enclosingPaginationLayer() : 0;
1676         const RenderLayer* rootLayerForTransform = paginationLayer ? paginationLayer : rootLayer;
1677         LayoutPoint delta;
1678         layer->convertToLayerCoords(rootLayerForTransform, delta);
1679
1680         TransformationMatrix transform;
1681         transform.translate(delta.x(), delta.y());
1682         transform = transform * *layer->transform();
1683
1684         // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
1685         // paints unfragmented.
1686         LayoutRect clipRect = layer->boundingBox(layer);
1687         expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, paintBehavior);
1688 #if ENABLE(CSS_FILTERS)
1689         layer->renderer().style().filterOutsets().expandRect(clipRect);
1690 #endif
1691         LayoutRect result = transform.mapRect(clipRect);
1692         if (!paginationLayer)
1693             return result;
1694         
1695         // We have to break up the transformed extent across our columns.
1696         // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
1697         // get our true bounding box.
1698         RenderFlowThread& enclosingFlowThread = toRenderFlowThread(paginationLayer->renderer());
1699         result = enclosingFlowThread.fragmentsBoundingBox(result);
1700         
1701         LayoutPoint rootLayerDelta;
1702         paginationLayer->convertToLayerCoords(rootLayer, rootLayerDelta);
1703         result.moveBy(rootLayerDelta);
1704         return result;
1705     }
1706     
1707     LayoutRect clipRect = layer->boundingBox(rootLayer, RenderLayer::UseFragmentBoxes);
1708     expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
1709 #if ENABLE(CSS_FILTERS)
1710     layer->renderer().style().filterOutsets().expandRect(clipRect);
1711 #endif
1712     return clipRect;
1713 }
1714
1715 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
1716 {
1717     return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect);
1718 }
1719
1720 void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
1721 {
1722     if (context->paintingDisabled() || (paintsWithTransparency(paintBehavior) && m_usedTransparency))
1723         return;
1724     
1725     RenderLayer* ancestor = transparentPaintingAncestor();
1726     if (ancestor)
1727         ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
1728     
1729     if (paintsWithTransparency(paintBehavior)) {
1730         m_usedTransparency = true;
1731         context->save();
1732         LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBehavior);
1733         context->clip(clipRect);
1734
1735 #if ENABLE(CSS_COMPOSITING)
1736         if (hasBlendMode())
1737             context->setCompositeOperation(context->compositeOperation(), m_blendMode);
1738 #endif
1739
1740         context->beginTransparencyLayer(renderer().opacity());
1741
1742 #if ENABLE(CSS_COMPOSITING)
1743         if (hasBlendMode())
1744             context->setCompositeOperation(context->compositeOperation(), BlendModeNormal);
1745 #endif
1746
1747 #ifdef REVEAL_TRANSPARENCY_LAYERS
1748         context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f), ColorSpaceDeviceRGB);
1749         context->fillRect(clipRect);
1750 #endif
1751     }
1752 }
1753
1754 #if PLATFORM(IOS)
1755 void RenderLayer::willBeDestroyed()
1756 {
1757     if (RenderLayerBacking* layerBacking = backing())
1758         layerBacking->layerWillBeDestroyed();
1759 }
1760 #endif
1761
1762 void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
1763 {
1764     RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChild();
1765     if (prevSibling) {
1766         child->setPreviousSibling(prevSibling);
1767         prevSibling->setNextSibling(child);
1768         ASSERT(prevSibling != child);
1769     } else
1770         setFirstChild(child);
1771
1772     if (beforeChild) {
1773         beforeChild->setPreviousSibling(child);
1774         child->setNextSibling(beforeChild);
1775         ASSERT(beforeChild != child);
1776     } else
1777         setLastChild(child);
1778
1779     child->setParent(this);
1780
1781     if (child->isNormalFlowOnly())
1782         dirtyNormalFlowList();
1783
1784     if (!child->isNormalFlowOnly() || child->firstChild()) {
1785         // Dirty the z-order list in which we are contained. The stackingContainer() can be null in the
1786         // case where we're building up generated content layers. This is ok, since the lists will start
1787         // off dirty in that case anyway.
1788         child->dirtyStackingContainerZOrderLists();
1789     }
1790
1791     child->updateDescendantDependentFlags();
1792     if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
1793         setAncestorChainHasVisibleDescendant();
1794
1795     if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant())
1796         setAncestorChainHasSelfPaintingLayerDescendant();
1797
1798     if (child->renderer().isOutOfFlowPositioned() || child->hasOutOfFlowPositionedDescendant())
1799         setAncestorChainHasOutOfFlowPositionedDescendant(child->renderer().containingBlock());
1800
1801 #if ENABLE(CSS_COMPOSITING)
1802     if (child->hasBlendMode() || (!child->isStackingContext() && child->hasBlendedElementInChildStackingContext()))
1803         child->updateNonCompositedParentStackingContextHasBlendedChild(true);
1804 #endif
1805
1806     compositor().layerWasAdded(*this, *child);
1807 }
1808
1809 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
1810 {
1811     if (!renderer().documentBeingDestroyed())
1812         compositor().layerWillBeRemoved(*this, *oldChild);
1813
1814     // remove the child
1815     if (oldChild->previousSibling())
1816         oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
1817     if (oldChild->nextSibling())
1818         oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling());
1819
1820     if (m_first == oldChild)
1821         m_first = oldChild->nextSibling();
1822     if (m_last == oldChild)
1823         m_last = oldChild->previousSibling();
1824
1825     if (oldChild->isNormalFlowOnly())
1826         dirtyNormalFlowList();
1827     if (!oldChild->isNormalFlowOnly() || oldChild->firstChild()) { 
1828         // Dirty the z-order list in which we are contained.  When called via the
1829         // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
1830         // from the main layer tree, so we need to null-check the |stackingContainer| value.
1831         oldChild->dirtyStackingContainerZOrderLists();
1832     }
1833
1834     if (oldChild->renderer().isOutOfFlowPositioned() || oldChild->hasOutOfFlowPositionedDescendant())
1835         dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
1836
1837     oldChild->setPreviousSibling(0);
1838     oldChild->setNextSibling(0);
1839     oldChild->setParent(0);
1840     
1841     oldChild->updateDescendantDependentFlags();
1842     if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
1843         dirtyAncestorChainVisibleDescendantStatus();
1844
1845     if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescendant())
1846         dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
1847
1848 #if ENABLE(CSS_COMPOSITING)
1849     if (oldChild->hasBlendMode() || oldChild->isolatesBlending())
1850         dirtyAncestorParentStackingContextHasBlendedElement();
1851 #endif
1852
1853     return oldChild;
1854 }
1855
1856 void RenderLayer::removeOnlyThisLayer()
1857 {
1858     if (!m_parent)
1859         return;
1860
1861     // Mark that we are about to lose our layer. This makes render tree
1862     // walks ignore this layer while we're removing it.
1863     renderer().setHasLayer(false);
1864
1865     compositor().layerWillBeRemoved(*m_parent, *this);
1866
1867     // Dirty the clip rects.
1868     clearClipRectsIncludingDescendants();
1869
1870     RenderLayer* nextSib = nextSibling();
1871
1872     // Remove the child reflection layer before moving other child layers.
1873     // The reflection layer should not be moved to the parent.
1874     if (reflection())
1875         removeChild(reflectionLayer());
1876
1877     // Now walk our kids and reattach them to our parent.
1878     RenderLayer* current = m_first;
1879     while (current) {
1880         RenderLayer* next = current->nextSibling();
1881         removeChild(current);
1882         m_parent->addChild(current, nextSib);
1883         current->setRepaintStatus(NeedsFullRepaint);
1884         // updateLayerPositions depends on hasLayer() already being false for proper layout.
1885         ASSERT(!renderer().hasLayer());
1886         current->updateLayerPositions(0); // FIXME: use geometry map.
1887         current = next;
1888     }
1889
1890     // Remove us from the parent.
1891     m_parent->removeChild(this);
1892     renderer().destroyLayer();
1893 }
1894
1895 void RenderLayer::insertOnlyThisLayer()
1896 {
1897     if (!m_parent && renderer().parent()) {
1898         // We need to connect ourselves when our renderer() has a parent.
1899         // Find our enclosingLayer and add ourselves.
1900         RenderLayer* parentLayer = renderer().parent()->enclosingLayer();
1901         ASSERT(parentLayer);
1902         RenderLayer* beforeChild = parentLayer->reflectionLayer() != this ? renderer().parent()->findNextLayer(parentLayer, &renderer()) : 0;
1903         parentLayer->addChild(this, beforeChild);
1904     }
1905
1906     // Remove all descendant layers from the hierarchy and add them to the new position.
1907     for (auto& child : childrenOfType<RenderElement>(renderer()))
1908         child.moveLayers(m_parent, this);
1909
1910     // Clear out all the clip rects.
1911     clearClipRectsIncludingDescendants();
1912 }
1913
1914 void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& roundedLocation, ColumnOffsetAdjustment adjustForColumns) const
1915 {
1916     LayoutPoint location = roundedLocation;
1917     convertToLayerCoords(ancestorLayer, location, adjustForColumns);
1918     roundedLocation = roundedIntPoint(location);
1919 }
1920
1921 void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntRect& roundedRect, ColumnOffsetAdjustment adjustForColumns) const
1922 {
1923     LayoutRect rect = roundedRect;
1924     convertToLayerCoords(ancestorLayer, rect, adjustForColumns);
1925     roundedRect = pixelSnappedIntRect(rect);
1926 }
1927
1928 // Returns the layer reached on the walk up towards the ancestor.
1929 static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location, RenderLayer::ColumnOffsetAdjustment adjustForColumns)
1930 {
1931     ASSERT(ancestorLayer != layer);
1932
1933     const RenderLayerModelObject& renderer = layer->renderer();
1934     EPosition position = renderer.style().position();
1935
1936     // FIXME: Special casing RenderFlowThread so much for fixed positioning here is not great.
1937     RenderFlowThread* fixedFlowThreadContainer = position == FixedPosition ? renderer.flowThreadContainingBlock() : 0;
1938     if (fixedFlowThreadContainer && !fixedFlowThreadContainer->isOutOfFlowPositioned())
1939         fixedFlowThreadContainer = 0;
1940
1941     // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFlowThread
1942     // may need to be revisited in a future patch.
1943     // If the fixed renderer is inside a RenderFlowThread, we should not compute location using localToAbsolute,
1944     // since localToAbsolute maps the coordinates from named flow to regions coordinates and regions can be
1945     // positioned in a completely different place in the viewport (RenderView).
1946     if (position == FixedPosition && !fixedFlowThreadContainer && (!ancestorLayer || ancestorLayer == renderer.view().layer())) {
1947         // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
1948         // localToAbsolute() on the RenderView.
1949         FloatPoint absPos = renderer.localToAbsolute(FloatPoint(), IsFixed);
1950         location += LayoutSize(absPos.x(), absPos.y());
1951         return ancestorLayer;
1952     }
1953
1954     // For the fixed positioned elements inside a render flow thread, we should also skip the code path below
1955     // Otherwise, for the case of ancestorLayer == rootLayer and fixed positioned element child of a transformed
1956     // element in render flow thread, we will hit the fixed positioned container before hitting the ancestor layer.
1957     if (position == FixedPosition && !fixedFlowThreadContainer) {
1958         // For a fixed layers, we need to walk up to the root to see if there's a fixed position container
1959         // (e.g. a transformed layer). It's an error to call convertToLayerCoords() across a layer with a transform,
1960         // so we should always find the ancestor at or before we find the fixed position container.
1961         RenderLayer* fixedPositionContainerLayer = 0;
1962         bool foundAncestor = false;
1963         for (RenderLayer* currLayer = layer->parent(); currLayer; currLayer = currLayer->parent()) {
1964             if (currLayer == ancestorLayer)
1965                 foundAncestor = true;
1966
1967             if (isFixedPositionedContainer(currLayer)) {
1968                 fixedPositionContainerLayer = currLayer;
1969                 ASSERT_UNUSED(foundAncestor, foundAncestor);
1970                 break;
1971             }
1972         }
1973         
1974         ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
1975
1976         if (fixedPositionContainerLayer != ancestorLayer) {
1977             LayoutPoint fixedContainerCoords;
1978             layer->convertToLayerCoords(fixedPositionContainerLayer, fixedContainerCoords);
1979
1980             LayoutPoint ancestorCoords;
1981             ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorCoords);
1982
1983             location += (fixedContainerCoords - ancestorCoords);
1984             return ancestorLayer;
1985         }
1986     }
1987
1988     if (position == FixedPosition && fixedFlowThreadContainer) {
1989         ASSERT(ancestorLayer);
1990         if (ancestorLayer->isOutOfFlowRenderFlowThread()) {
1991             location += toLayoutSize(layer->location());
1992             return ancestorLayer;
1993         }
1994
1995         if (ancestorLayer == renderer.view().layer()) {
1996             // Add location in flow thread coordinates.
1997             location += toLayoutSize(layer->location());
1998
1999             // Add flow thread offset in view coordinates since the view may be scrolled.
2000             FloatPoint absPos = renderer.view().localToAbsolute(FloatPoint(), IsFixed);
2001             location += LayoutSize(absPos.x(), absPos.y());
2002             return ancestorLayer;
2003         }
2004     }
2005
2006     RenderLayer* parentLayer;
2007     if (position == AbsolutePosition || position == FixedPosition) {
2008         // Do what enclosingPositionedAncestor() does, but check for ancestorLayer along the way.
2009         parentLayer = layer->parent();
2010         bool foundAncestorFirst = false;
2011         while (parentLayer) {
2012             // RenderFlowThread is a positioned container, child of RenderView, positioned at (0,0).
2013             // This implies that, for out-of-flow positioned elements inside a RenderFlowThread,
2014             // we are bailing out before reaching root layer.
2015             if (isPositionedContainer(parentLayer))
2016                 break;
2017
2018             if (parentLayer == ancestorLayer) {
2019                 foundAncestorFirst = true;
2020                 break;
2021             }
2022
2023             parentLayer = parentLayer->parent();
2024         }
2025
2026         // We should not reach RenderView layer past the RenderFlowThread layer for any
2027         // children of the RenderFlowThread.
2028         if (renderer.flowThreadContainingBlock() && !layer->isOutOfFlowRenderFlowThread())
2029             ASSERT(parentLayer != renderer.view().layer());
2030
2031         if (foundAncestorFirst) {
2032             // Found ancestorLayer before the abs. positioned container, so compute offset of both relative
2033             // to enclosingPositionedAncestor and subtract.
2034             RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor();
2035
2036             LayoutPoint thisCoords;
2037             layer->convertToLayerCoords(positionedAncestor, thisCoords);
2038             
2039             LayoutPoint ancestorCoords;
2040             ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorCoords);
2041
2042             location += (thisCoords - ancestorCoords);
2043             return ancestorLayer;
2044         }
2045     } else
2046         parentLayer = layer->parent();
2047     
2048     if (!parentLayer)
2049         return 0;
2050
2051     location += toLayoutSize(layer->location());
2052
2053     if (adjustForColumns == RenderLayer::AdjustForColumns) {
2054         if (RenderLayer* parentLayer = layer->parent()) {
2055             LayoutSize layerColumnOffset;
2056             parentLayer->renderer().adjustForColumns(layerColumnOffset, location);
2057             location += layerColumnOffset;
2058         }
2059     }
2060
2061     return parentLayer;
2062 }
2063
2064 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location, ColumnOffsetAdjustment adjustForColumns) const
2065 {
2066     if (ancestorLayer == this)
2067         return;
2068
2069     const RenderLayer* currLayer = this;
2070     while (currLayer && currLayer != ancestorLayer)
2071         currLayer = accumulateOffsetTowardsAncestor(currLayer, ancestorLayer, location, adjustForColumns);
2072 }
2073
2074 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect& rect, ColumnOffsetAdjustment adjustForColumns) const
2075 {
2076     LayoutPoint delta;
2077     convertToLayerCoords(ancestorLayer, delta, adjustForColumns);
2078     rect.move(-delta.x(), -delta.y());
2079 }
2080
2081 #if PLATFORM(IOS)
2082 bool RenderLayer::hasAcceleratedTouchScrolling() const
2083 {
2084 #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
2085     if (!scrollsOverflow())
2086         return false;
2087
2088     Settings* settings = renderer().document().settings();
2089     // FIXME: settings should not be null at this point. If you find a reliable way to hit this assertion, please file a bug.
2090     // See <rdar://problem/10266101>.
2091     ASSERT(settings);
2092
2093     return renderer().style().useTouchOverflowScrolling() || (settings && settings->alwaysUseAcceleratedOverflowScroll());
2094 #else
2095     return false;
2096 #endif
2097 }
2098
2099 #if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
2100 bool RenderLayer::handleTouchEvent(const PlatformTouchEvent& touchEvent)
2101 {
2102     // If we have accelerated scrolling, let the scrolling be handled outside of WebKit.
2103     if (hasAcceleratedTouchScrolling())
2104         return false;
2105
2106     return ScrollableArea::handleTouchEvent(touchEvent);
2107 }
2108 #endif
2109
2110 void RenderLayer::registerAsTouchEventListenerForScrolling()
2111 {
2112     if (!renderer().element() || m_registeredAsTouchEventListenerForScrolling)
2113         return;
2114     
2115     renderer().document().addTouchEventListener(renderer().element());
2116     m_registeredAsTouchEventListenerForScrolling = true;
2117 }
2118
2119 void RenderLayer::unregisterAsTouchEventListenerForScrolling()
2120 {
2121     if (!renderer().element() || !m_registeredAsTouchEventListenerForScrolling)
2122         return;
2123
2124     renderer().document().removeTouchEventListener(renderer().element());
2125     m_registeredAsTouchEventListenerForScrolling = false;
2126 }
2127 #endif // PLATFORM(IOS)
2128
2129 bool RenderLayer::usesCompositedScrolling() const
2130 {
2131     return isComposited() && backing()->scrollingLayer();
2132 }
2133
2134 bool RenderLayer::needsCompositedScrolling() const
2135 {
2136     return m_needsCompositedScrolling;
2137 }
2138
2139 void RenderLayer::updateNeedsCompositedScrolling()
2140 {
2141     bool oldNeedsCompositedScrolling = m_needsCompositedScrolling;
2142
2143     if (!renderer().view().frameView().containsScrollableArea(this))
2144         m_needsCompositedScrolling = false;
2145     else {
2146         bool forceUseCompositedScrolling = acceleratedCompositingForOverflowScrollEnabled()
2147             && canBeStackingContainer()
2148             && !hasOutOfFlowPositionedDescendant();
2149
2150 #if !PLATFORM(IOS) && ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
2151         m_needsCompositedScrolling = forceUseCompositedScrolling || renderer().style().useTouchOverflowScrolling();
2152 #else
2153         // On iOS we don't want to opt into accelerated composited scrolling, which creates scroll bar
2154         // layers in WebCore, because we use UIKit to composite our scroll bars.
2155         m_needsCompositedScrolling = forceUseCompositedScrolling;
2156 #endif
2157         // We gather a boolean value for use with Google UMA histograms to
2158         // quantify the actual effects of a set of patches attempting to
2159         // relax composited scrolling requirements, thereby increasing the
2160         // number of composited overflow divs.
2161         if (acceleratedCompositingForOverflowScrollEnabled())
2162             HistogramSupport::histogramEnumeration("Renderer.NeedsCompositedScrolling", m_needsCompositedScrolling, 2);
2163     }
2164
2165     if (oldNeedsCompositedScrolling != m_needsCompositedScrolling) {
2166         updateSelfPaintingLayer();
2167         if (isStackingContainer())
2168             dirtyZOrderLists();
2169         else
2170             clearZOrderLists();
2171
2172         dirtyStackingContainerZOrderLists();
2173
2174         compositor().setShouldReevaluateCompositingAfterLayout();
2175         compositor().setCompositingLayersNeedRebuild();
2176     }
2177 }
2178
2179 static inline int adjustedScrollDelta(int beginningDelta) {
2180     // This implemention matches Firefox's.
2181     // http://mxr.mozilla.org/firefox/source/toolkit/content/widgets/browser.xml#856.
2182     const int speedReducer = 12;
2183
2184     int adjustedDelta = beginningDelta / speedReducer;
2185     if (adjustedDelta > 1)
2186         adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(adjustedDelta))) - 1;
2187     else if (adjustedDelta < -1)
2188         adjustedDelta = static_cast<int>(adjustedDelta * sqrt(static_cast<double>(-adjustedDelta))) + 1;
2189
2190     return adjustedDelta;
2191 }
2192
2193 static inline IntSize adjustedScrollDelta(const IntSize& delta)
2194 {
2195     return IntSize(adjustedScrollDelta(delta.width()), adjustedScrollDelta(delta.height()));
2196 }
2197
2198 void RenderLayer::panScrollFromPoint(const IntPoint& sourcePoint)
2199 {
2200     IntPoint lastKnownMousePosition = renderer().frame().eventHandler().lastKnownMousePosition();
2201     
2202     // We need to check if the last known mouse position is out of the window. When the mouse is out of the window, the position is incoherent
2203     static IntPoint previousMousePosition;
2204     if (lastKnownMousePosition.x() < 0 || lastKnownMousePosition.y() < 0)
2205         lastKnownMousePosition = previousMousePosition;
2206     else
2207         previousMousePosition = lastKnownMousePosition;
2208
2209     IntSize delta = lastKnownMousePosition - sourcePoint;
2210
2211     if (abs(delta.width()) <= ScrollView::noPanScrollRadius) // at the center we let the space for the icon
2212         delta.setWidth(0);
2213     if (abs(delta.height()) <= ScrollView::noPanScrollRadius)
2214         delta.setHeight(0);
2215
2216     scrollByRecursively(adjustedScrollDelta(delta), ScrollOffsetClamped);
2217 }
2218
2219 void RenderLayer::scrollByRecursively(const IntSize& delta, ScrollOffsetClamping clamp, ScrollableArea** scrolledArea)
2220 {
2221     if (delta.isZero())
2222         return;
2223
2224     bool restrictedByLineClamp = false;
2225     if (renderer().parent())
2226         restrictedByLineClamp = !renderer().parent()->style().lineClamp().isNone();
2227
2228     if (renderer().hasOverflowClip() && !restrictedByLineClamp) {
2229         IntSize newScrollOffset = scrollOffset() + delta;
2230         scrollToOffset(newScrollOffset, clamp);
2231         if (scrolledArea)
2232             *scrolledArea = this;
2233
2234         // If this layer can't do the scroll we ask the next layer up that can scroll to try
2235         IntSize remainingScrollOffset = newScrollOffset - scrollOffset();
2236         if (!remainingScrollOffset.isZero() && renderer().parent()) {
2237             if (RenderLayer* scrollableLayer = enclosingScrollableLayer())
2238                 scrollableLayer->scrollByRecursively(remainingScrollOffset, clamp, scrolledArea);
2239
2240             renderer().frame().eventHandler().updateAutoscrollRenderer();
2241         }
2242     } else {
2243         // If we are here, we were called on a renderer that can be programmatically scrolled, but doesn't
2244         // have an overflow clip. Which means that it is a document node that can be scrolled.
2245         renderer().view().frameView().scrollBy(delta);
2246         if (scrolledArea)
2247             *scrolledArea = &renderer().view().frameView();
2248
2249         // FIXME: If we didn't scroll the whole way, do we want to try looking at the frames ownerElement? 
2250         // https://bugs.webkit.org/show_bug.cgi?id=28237
2251     }
2252 }
2253
2254 IntSize RenderLayer::clampScrollOffset(const IntSize& scrollOffset) const
2255 {
2256     RenderBox* box = renderBox();
2257     ASSERT(box);
2258
2259     int maxX = scrollWidth() - box->pixelSnappedClientWidth();
2260     int maxY = scrollHeight() - box->pixelSnappedClientHeight();
2261
2262     int x = std::max(std::min(scrollOffset.width(), maxX), 0);
2263     int y = std::max(std::min(scrollOffset.height(), maxY), 0);
2264     return IntSize(x, y);
2265 }
2266
2267 void RenderLayer::scrollToOffset(const IntSize& scrollOffset, ScrollOffsetClamping clamp)
2268 {
2269     IntSize newScrollOffset = clamp == ScrollOffsetClamped ? clampScrollOffset(scrollOffset) : scrollOffset;
2270     if (newScrollOffset != this->scrollOffset())
2271         scrollToOffsetWithoutAnimation(IntPoint(newScrollOffset));
2272 }
2273
2274 void RenderLayer::scrollTo(int x, int y)
2275 {
2276     RenderBox* box = renderBox();
2277     if (!box)
2278         return;
2279
2280     if (box->style().overflowX() != OMARQUEE) {
2281         // Ensure that the dimensions will be computed if they need to be (for overflow:hidden blocks).
2282         if (m_scrollDimensionsDirty)
2283             computeScrollDimensions();
2284 #if PLATFORM(IOS)
2285         if (adjustForIOSCaretWhenScrolling()) {
2286             int maxX = scrollWidth() - box->clientWidth();
2287             if (x > maxX - caretWidth) {
2288                 x += caretWidth;
2289                 if (x <= caretWidth)
2290                     x = 0;
2291             } else if (x < m_scrollOffset.width() - caretWidth)
2292                 x -= caretWidth;
2293         }
2294 #endif
2295     }
2296     
2297     // FIXME: Eventually, we will want to perform a blit.  For now never
2298     // blit, since the check for blitting is going to be very
2299     // complicated (since it will involve testing whether our layer
2300     // is either occluded by another layer or clipped by an enclosing
2301     // layer or contains fixed backgrounds, etc.).
2302     IntSize newScrollOffset = IntSize(x - scrollOrigin().x(), y - scrollOrigin().y());
2303     if (m_scrollOffset == newScrollOffset) {
2304 #if PLATFORM(IOS)
2305         if (m_requiresScrollBoundsOriginUpdate)
2306             updateCompositingLayersAfterScroll();
2307 #endif
2308         return;
2309     }
2310     m_scrollOffset = newScrollOffset;
2311
2312     InspectorInstrumentation::willScrollLayer(&renderer().frame());
2313
2314     RenderView& view = renderer().view();
2315
2316     // Update the positions of our child layers (if needed as only fixed layers should be impacted by a scroll).
2317     // We don't update compositing layers, because we need to do a deep update from the compositing ancestor.
2318     bool inLayout = view.frameView().isInLayout();
2319     if (!inLayout) {
2320         // If we're in the middle of layout, we'll just update layers once layout has finished.
2321         updateLayerPositionsAfterOverflowScroll();
2322         // Update regions, scrolling may change the clip of a particular region.
2323 #if ENABLE(DASHBOARD_SUPPORT)
2324         view.frameView().updateAnnotatedRegions();
2325 #endif
2326         view.frameView().updateWidgetPositions();
2327
2328         if (!m_updatingMarqueePosition) {
2329             // Avoid updating compositing layers if, higher on the stack, we're already updating layer
2330             // positions. Updating layer positions requires a full walk of up-to-date RenderLayers, and
2331             // in this case we're still updating their positions; we'll update compositing layers later
2332             // when that completes.
2333             updateCompositingLayersAfterScroll();
2334         }
2335
2336 #if PLATFORM(IOS) && ENABLE(TOUCH_EVENTS)
2337         renderer().document().dirtyTouchEventRects();
2338 #endif
2339     }
2340
2341     Frame& frame = renderer().frame();
2342     RenderLayerModelObject* repaintContainer = renderer().containerForRepaint();
2343     // The caret rect needs to be invalidated after scrolling
2344     frame.selection().setCaretRectNeedsUpdate();
2345
2346     FloatQuad quadForFakeMouseMoveEvent = FloatQuad(m_repaintRect);
2347     if (repaintContainer)
2348         quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
2349     frame.eventHandler().dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
2350
2351     bool requiresRepaint = true;
2352     if (compositor().inCompositingMode() && usesCompositedScrolling())
2353         requiresRepaint = false;
2354
2355     // Just schedule a full repaint of our object.
2356 #if PLATFORM(IOS)
2357     if (!hasAcceleratedTouchScrolling())
2358 #else
2359     if (requiresRepaint)
2360 #endif
2361         renderer().repaintUsingContainer(repaintContainer, m_repaintRect);
2362
2363     // Schedule the scroll DOM event.
2364     if (Element* element = renderer().element())
2365         element->document().eventQueue().enqueueOrDispatchScrollEvent(*element);
2366
2367     InspectorInstrumentation::didScrollLayer(&frame);
2368     if (scrollsOverflow())
2369         frame.loader().client().didChangeScrollOffset();
2370 }
2371
2372 static inline bool frameElementAndViewPermitScroll(HTMLFrameElementBase* frameElementBase, FrameView* frameView) 
2373 {
2374     // If scrollbars aren't explicitly forbidden, permit scrolling.
2375     if (frameElementBase && frameElementBase->scrollingMode() != ScrollbarAlwaysOff)
2376         return true;
2377
2378     // If scrollbars are forbidden, user initiated scrolls should obviously be ignored.
2379     if (frameView->wasScrolledByUser())
2380         return false;
2381
2382     // Forbid autoscrolls when scrollbars are off, but permits other programmatic scrolls,
2383     // like navigation to an anchor.
2384     return !frameView->frame().eventHandler().autoscrollInProgress();
2385 }
2386
2387 void RenderLayer::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
2388 {
2389     RenderLayer* parentLayer = 0;
2390     LayoutRect newRect = rect;
2391
2392     // We may end up propagating a scroll event. It is important that we suspend events until 
2393     // the end of the function since they could delete the layer or the layer's renderer().
2394     FrameView& frameView = renderer().view().frameView();
2395
2396     bool restrictedByLineClamp = false;
2397     if (renderer().parent()) {
2398         parentLayer = renderer().parent()->enclosingLayer();
2399         restrictedByLineClamp = !renderer().parent()->style().lineClamp().isNone();
2400     }
2401
2402     if (renderer().hasOverflowClip() && !restrictedByLineClamp) {
2403         // Don't scroll to reveal an overflow layer that is restricted by the -webkit-line-clamp property.
2404         // This will prevent us from revealing text hidden by the slider in Safari RSS.
2405         RenderBox* box = renderBox();
2406         ASSERT(box);
2407         LayoutRect localExposeRect(box->absoluteToLocalQuad(FloatQuad(FloatRect(rect)), UseTransforms).boundingBox());
2408         LayoutRect layerBounds(0, 0, box->clientWidth(), box->clientHeight());
2409         LayoutRect r = getRectToExpose(layerBounds, layerBounds, localExposeRect, alignX, alignY);
2410
2411         IntSize clampedScrollOffset = clampScrollOffset(scrollOffset() + toIntSize(roundedIntRect(r).location()));
2412         if (clampedScrollOffset != scrollOffset()) {
2413             IntSize oldScrollOffset = scrollOffset();
2414             scrollToOffset(clampedScrollOffset);
2415             IntSize scrollOffsetDifference = scrollOffset() - oldScrollOffset;
2416             localExposeRect.move(-scrollOffsetDifference);
2417             newRect = LayoutRect(box->localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox());
2418         }
2419     } else if (!parentLayer && renderer().isBox() && renderBox()->canBeProgramaticallyScrolled()) {
2420         Element* ownerElement = renderer().document().ownerElement();
2421
2422         if (ownerElement && ownerElement->renderer()) {
2423             HTMLFrameElementBase* frameElementBase = 0;
2424
2425             if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))
2426                 frameElementBase = toHTMLFrameElementBase(ownerElement);
2427
2428             if (frameElementAndViewPermitScroll(frameElementBase, &frameView)) {
2429                 LayoutRect viewRect = frameView.visibleContentRect(LegacyIOSDocumentVisibleRect);
2430                 LayoutRect exposeRect = getRectToExpose(viewRect, viewRect, rect, alignX, alignY);
2431
2432                 int xOffset = roundToInt(exposeRect.x());
2433                 int yOffset = roundToInt(exposeRect.y());
2434                 // Adjust offsets if they're outside of the allowable range.
2435                 xOffset = std::max(0, std::min(frameView.contentsWidth(), xOffset));
2436                 yOffset = std::max(0, std::min(frameView.contentsHeight(), yOffset));
2437
2438                 frameView.setScrollPosition(IntPoint(xOffset, yOffset));
2439                 if (frameView.safeToPropagateScrollToParent()) {
2440                     parentLayer = ownerElement->renderer()->enclosingLayer();
2441                     // FIXME: This doesn't correctly convert the rect to
2442                     // absolute coordinates in the parent.
2443                     newRect.setX(rect.x() - frameView.scrollX() + frameView.x());
2444                     newRect.setY(rect.y() - frameView.scrollY() + frameView.y());
2445                 } else
2446                     parentLayer = 0;
2447             }
2448         } else {
2449 #if !PLATFORM(IOS)
2450             LayoutRect viewRect = frameView.visibleContentRect();
2451             LayoutRect visibleRectRelativeToDocument = viewRect;
2452             IntSize scrollOffsetRelativeToDocument = frameView.scrollOffsetRelativeToDocument();
2453             visibleRectRelativeToDocument.setLocation(IntPoint(scrollOffsetRelativeToDocument.width(), scrollOffsetRelativeToDocument.height()));
2454 #else
2455             LayoutRect viewRect = frameView.unobscuredContentRect();
2456             LayoutRect visibleRectRelativeToDocument = viewRect;
2457 #endif
2458
2459             LayoutRect r = getRectToExpose(viewRect, visibleRectRelativeToDocument, rect, alignX, alignY);
2460                 
2461             frameView.setScrollPosition(roundedIntPoint(r.location()));
2462
2463             // This is the outermost view of a web page, so after scrolling this view we
2464             // scroll its container by calling Page::scrollRectIntoView.
2465             // This only has an effect on the Mac platform in applications
2466             // that put web views into scrolling containers, such as Mac OS X Mail.
2467             // The canAutoscroll function in EventHandler also knows about this.
2468             if (Page* page = frameView.frame().page())
2469                 page->chrome().scrollRectIntoView(pixelSnappedIntRect(rect));
2470         }
2471     }
2472     
2473     if (renderer().frame().eventHandler().autoscrollInProgress())
2474         parentLayer = enclosingScrollableLayer();
2475
2476     if (parentLayer)
2477         parentLayer->scrollRectToVisible(newRect, alignX, alignY);
2478 }
2479
2480 void RenderLayer::updateCompositingLayersAfterScroll()
2481 {
2482     if (compositor().inCompositingMode()) {
2483         // Our stacking container is guaranteed to contain all of our descendants that may need
2484         // repositioning, so update compositing layers from there.
2485         if (RenderLayer* compositingAncestor = stackingContainer()->enclosingCompositingLayer()) {
2486             if (usesCompositedScrolling() && !hasOutOfFlowPositionedDescendant())
2487                 compositor().updateCompositingLayers(CompositingUpdateOnCompositedScroll, compositingAncestor);
2488             else
2489                 compositor().updateCompositingLayers(CompositingUpdateOnScroll, compositingAncestor);
2490         }
2491     }
2492 }
2493
2494 LayoutRect RenderLayer::getRectToExpose(const LayoutRect &visibleRect, const LayoutRect &visibleRectRelativeToDocument, const LayoutRect &exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
2495 {
2496     // Determine the appropriate X behavior.
2497     ScrollBehavior scrollX;
2498     LayoutRect exposeRectX(exposeRect.x(), visibleRect.y(), exposeRect.width(), visibleRect.height());
2499     LayoutUnit intersectWidth = intersection(visibleRect, exposeRectX).width();
2500     if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_FOR_REVEAL)
2501         // If the rectangle is fully visible, use the specified visible behavior.
2502         // If the rectangle is partially visible, but over a certain threshold,
2503         // then treat it as fully visible to avoid unnecessary horizontal scrolling
2504         scrollX = ScrollAlignment::getVisibleBehavior(alignX);
2505     else if (intersectWidth == visibleRect.width()) {
2506         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
2507         scrollX = ScrollAlignment::getVisibleBehavior(alignX);
2508         if (scrollX == alignCenter)
2509             scrollX = noScroll;
2510     } else if (intersectWidth > 0)
2511         // If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior
2512         scrollX = ScrollAlignment::getPartialBehavior(alignX);
2513     else
2514         scrollX = ScrollAlignment::getHiddenBehavior(alignX);
2515     // If we're trying to align to the closest edge, and the exposeRect is further right
2516     // than the visibleRect, and not bigger than the visible area, then align with the right.
2517     if (scrollX == alignToClosestEdge && exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visibleRect.width())
2518         scrollX = alignRight;
2519
2520     // Given the X behavior, compute the X coordinate.
2521     LayoutUnit x;
2522     if (scrollX == noScroll) 
2523         x = visibleRect.x();
2524     else if (scrollX == alignRight)
2525         x = exposeRect.maxX() - visibleRect.width();
2526     else if (scrollX == alignCenter)
2527         x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
2528     else
2529         x = exposeRect.x();
2530
2531     // Determine the appropriate Y behavior.
2532     ScrollBehavior scrollY;
2533     LayoutRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(), exposeRect.height());
2534     LayoutUnit intersectHeight = intersection(visibleRectRelativeToDocument, exposeRectY).height();
2535     if (intersectHeight == exposeRect.height())
2536         // If the rectangle is fully visible, use the specified visible behavior.
2537         scrollY = ScrollAlignment::getVisibleBehavior(alignY);
2538     else if (intersectHeight == visibleRect.height()) {
2539         // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
2540         scrollY = ScrollAlignment::getVisibleBehavior(alignY);
2541         if (scrollY == alignCenter)
2542             scrollY = noScroll;
2543     } else if (intersectHeight > 0)
2544         // If the rectangle is partially visible, use the specified partial behavior
2545         scrollY = ScrollAlignment::getPartialBehavior(alignY);
2546     else
2547         scrollY = ScrollAlignment::getHiddenBehavior(alignY);
2548     // If we're trying to align to the closest edge, and the exposeRect is further down
2549     // than the visibleRect, and not bigger than the visible area, then align with the bottom.
2550     if (scrollY == alignToClosestEdge && exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < visibleRect.height())
2551         scrollY = alignBottom;
2552
2553     // Given the Y behavior, compute the Y coordinate.
2554     LayoutUnit y;
2555     if (scrollY == noScroll) 
2556         y = visibleRect.y();
2557     else if (scrollY == alignBottom)
2558         y = exposeRect.maxY() - visibleRect.height();
2559     else if (scrollY == alignCenter)
2560         y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
2561     else
2562         y = exposeRect.y();
2563
2564     return LayoutRect(LayoutPoint(x, y), visibleRect.size());
2565 }
2566
2567 void RenderLayer::autoscroll(const IntPoint& position)
2568 {
2569     IntPoint currentDocumentPosition = renderer().view().frameView().windowToContents(position);
2570     scrollRectToVisible(LayoutRect(currentDocumentPosition, LayoutSize(1, 1)), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
2571 }
2572
2573 bool RenderLayer::canResize() const
2574 {
2575     // We need a special case for <iframe> because they never have
2576     // hasOverflowClip(). However, they do "implicitly" clip their contents, so
2577     // we want to allow resizing them also.
2578     return (renderer().hasOverflowClip() || renderer().isRenderIFrame()) && renderer().style().resize() != RESIZE_NONE;
2579 }
2580
2581 void RenderLayer::resize(const PlatformMouseEvent& evt, const LayoutSize& oldOffset)
2582 {
2583     // FIXME: This should be possible on generated content but is not right now.
2584     if (!inResizeMode() || !canResize() || !renderer().element())
2585         return;
2586
2587     // FIXME: The only case where renderer->element()->renderer() != renderer is with continuations. Do they matter here?
2588     // If they do it would still be better to deal with them explicitly.
2589     Element* element = renderer().element();
2590     RenderBox* renderer = toRenderBox(element->renderer());
2591
2592     Document& document = element->document();
2593     if (!document.frame()->eventHandler().mousePressed())
2594         return;
2595
2596     float zoomFactor = renderer->style().effectiveZoom();
2597
2598     LayoutSize newOffset = offsetFromResizeCorner(document.view()->windowToContents(evt.position()));
2599     newOffset.setWidth(newOffset.width() / zoomFactor);
2600     newOffset.setHeight(newOffset.height() / zoomFactor);
2601     
2602     LayoutSize currentSize = LayoutSize(renderer->width() / zoomFactor, renderer->height() / zoomFactor);
2603     LayoutSize minimumSize = element->minimumSizeForResizing().shrunkTo(currentSize);
2604     element->setMinimumSizeForResizing(minimumSize);
2605     
2606     LayoutSize adjustedOldOffset = LayoutSize(oldOffset.width() / zoomFactor, oldOffset.height() / zoomFactor);
2607     if (renderer->style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
2608         newOffset.setWidth(-newOffset.width());
2609         adjustedOldOffset.setWidth(-adjustedOldOffset.width());
2610     }
2611     
2612     LayoutSize difference = (currentSize + newOffset - adjustedOldOffset).expandedTo(minimumSize) - currentSize;
2613
2614     StyledElement* styledElement = toStyledElement(element);
2615     bool isBoxSizingBorder = renderer->style().boxSizing() == BORDER_BOX;
2616
2617     EResize resize = renderer->style().resize();
2618     if (resize != RESIZE_VERTICAL && difference.width()) {
2619         if (element->isFormControlElement()) {
2620             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
2621             styledElement->setInlineStyleProperty(CSSPropertyMarginLeft, renderer->marginLeft() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2622             styledElement->setInlineStyleProperty(CSSPropertyMarginRight, renderer->marginRight() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2623         }
2624         LayoutUnit baseWidth = renderer->width() - (isBoxSizingBorder ? LayoutUnit() : renderer->horizontalBorderAndPaddingExtent());
2625         baseWidth = baseWidth / zoomFactor;
2626         styledElement->setInlineStyleProperty(CSSPropertyWidth, roundToInt(baseWidth + difference.width()), CSSPrimitiveValue::CSS_PX);
2627     }
2628
2629     if (resize != RESIZE_HORIZONTAL && difference.height()) {
2630         if (element->isFormControlElement()) {
2631             // Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
2632             styledElement->setInlineStyleProperty(CSSPropertyMarginTop, renderer->marginTop() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2633             styledElement->setInlineStyleProperty(CSSPropertyMarginBottom, renderer->marginBottom() / zoomFactor, CSSPrimitiveValue::CSS_PX);
2634         }
2635         LayoutUnit baseHeight = renderer->height() - (isBoxSizingBorder ? LayoutUnit() : renderer->verticalBorderAndPaddingExtent());
2636         baseHeight = baseHeight / zoomFactor;
2637         styledElement->setInlineStyleProperty(CSSPropertyHeight, roundToInt(baseHeight + difference.height()), CSSPrimitiveValue::CSS_PX);
2638     }
2639
2640     document.updateLayout();
2641
2642     // FIXME (Radar 4118564): We should also autoscroll the window as necessary to keep the point under the cursor in view.
2643 }
2644
2645 int RenderLayer::scrollSize(ScrollbarOrientation orientation) const
2646 {
2647     Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_hBar : m_vBar).get();
2648     return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
2649 }
2650
2651 void RenderLayer::setScrollOffset(const IntPoint& offset)
2652 {
2653     scrollTo(offset.x(), offset.y());
2654 }
2655
2656 int RenderLayer::scrollPosition(Scrollbar* scrollbar) const
2657 {
2658     if (scrollbar->orientation() == HorizontalScrollbar)
2659         return scrollXOffset();
2660     if (scrollbar->orientation() == VerticalScrollbar)
2661         return scrollYOffset();
2662     return 0;
2663 }
2664
2665 IntPoint RenderLayer::scrollPosition() const
2666 {
2667     return IntPoint(m_scrollOffset);
2668 }
2669
2670 IntPoint RenderLayer::minimumScrollPosition() const
2671 {
2672     return -scrollOrigin();
2673 }
2674
2675 IntPoint RenderLayer::maximumScrollPosition() const
2676 {
2677     // FIXME: m_scrollSize may not be up-to-date if m_scrollDimensionsDirty is true.
2678     return -scrollOrigin() + roundedIntSize(m_scrollSize) - visibleContentRectIncludingScrollbars(ContentsVisibleRect).size();
2679 }
2680
2681 IntRect RenderLayer::visibleContentRectInternal(VisibleContentRectIncludesScrollbars scrollbarInclusion, VisibleContentRectBehavior) const
2682 {
2683     int verticalScrollbarWidth = 0;
2684     int horizontalScrollbarHeight = 0;
2685     if (scrollbarInclusion == IncludeScrollbars) {
2686         verticalScrollbarWidth = (verticalScrollbar() && !verticalScrollbar()->isOverlayScrollbar()) ? verticalScrollbar()->width() : 0;
2687         horizontalScrollbarHeight = (horizontalScrollbar() && !horizontalScrollbar()->isOverlayScrollbar()) ? horizontalScrollbar()->height() : 0;
2688
2689 #if PLATFORM(IOS)
2690         if (hasAcceleratedTouchScrolling()) {
2691             verticalScrollbarWidth = 0;
2692             horizontalScrollbarHeight = 0;
2693         }
2694 #endif
2695     }
2696     
2697     return IntRect(IntPoint(scrollXOffset(), scrollYOffset()),
2698                    IntSize(std::max(0, m_layerSize.width() - verticalScrollbarWidth),
2699                            std::max(0, m_layerSize.height() - horizontalScrollbarHeight)));
2700 }
2701
2702 IntSize RenderLayer::overhangAmount() const
2703 {
2704     return IntSize();
2705 }
2706
2707 bool RenderLayer::isActive() const
2708 {
2709     Page* page = renderer().frame().page();
2710     return page && page->focusController().isActive();
2711 }
2712
2713 static int cornerStart(const RenderLayer* layer, int minX, int maxX, int thickness)
2714 {
2715     if (layer->renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
2716         return minX + layer->renderer().style().borderLeftWidth();
2717     return maxX - thickness - layer->renderer().style().borderRightWidth();
2718 }
2719
2720 static LayoutRect cornerRect(const RenderLayer* layer, const LayoutRect& bounds)
2721 {
2722     int horizontalThickness;
2723     int verticalThickness;
2724     if (!layer->verticalScrollbar() && !layer->horizontalScrollbar()) {
2725         // FIXME: This isn't right.  We need to know the thickness of custom scrollbars
2726         // even when they don't exist in order to set the resizer square size properly.
2727         horizontalThickness = ScrollbarTheme::theme()->scrollbarThickness();
2728         verticalThickness = horizontalThickness;
2729     } else if (layer->verticalScrollbar() && !layer->horizontalScrollbar()) {
2730         horizontalThickness = layer->verticalScrollbar()->width();
2731         verticalThickness = horizontalThickness;
2732     } else if (layer->horizontalScrollbar() && !layer->verticalScrollbar()) {
2733         verticalThickness = layer->horizontalScrollbar()->height();
2734         horizontalThickness = verticalThickness;
2735     } else {
2736         horizontalThickness = layer->verticalScrollbar()->width();
2737         verticalThickness = layer->horizontalScrollbar()->height();
2738     }
2739     return LayoutRect(cornerStart(layer, bounds.x(), bounds.maxX(), horizontalThickness),
2740         bounds.maxY() - verticalThickness - layer->renderer().style().borderBottomWidth(),
2741         horizontalThickness, verticalThickness);
2742 }
2743
2744 IntRect RenderLayer::scrollCornerRect() const
2745 {
2746     // We have a scrollbar corner when a scrollbar is visible and not filling the entire length of the box.
2747     // This happens when:
2748     // (a) A resizer is present and at least one scrollbar is present
2749     // (b) Both scrollbars are present.
2750     bool hasHorizontalBar = horizontalScrollbar();
2751     bool hasVerticalBar = verticalScrollbar();
2752     bool hasResizer = renderer().style().resize() != RESIZE_NONE;
2753     if ((hasHorizontalBar && hasVerticalBar) || (hasResizer && (hasHorizontalBar || hasVerticalBar)))
2754         return pixelSnappedIntRect(cornerRect(this, renderBox()->borderBoxRect()));
2755     return IntRect();
2756 }
2757
2758 static LayoutRect resizerCornerRect(const RenderLayer* layer, const LayoutRect& bounds)
2759 {
2760     ASSERT(layer->renderer().isBox());
2761     if (layer->renderer().style().resize() == RESIZE_NONE)
2762         return LayoutRect();
2763     return cornerRect(layer, bounds);
2764 }
2765
2766 LayoutRect RenderLayer::scrollCornerAndResizerRect() const
2767 {
2768     RenderBox* box = renderBox();
2769     if (!box)
2770         return LayoutRect();
2771     LayoutRect scrollCornerAndResizer = scrollCornerRect();
2772     if (scrollCornerAndResizer.isEmpty())
2773         scrollCornerAndResizer = resizerCornerRect(this, box->borderBoxRect());
2774     return scrollCornerAndResizer;
2775 }
2776
2777 bool RenderLayer::isScrollCornerVisible() const
2778 {
2779     ASSERT(renderer().isBox());
2780     return !scrollCornerRect().isEmpty();
2781 }
2782
2783 IntRect RenderLayer::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
2784 {
2785     IntRect rect = scrollbarRect;
2786     rect.move(scrollbarOffset(scrollbar));
2787
2788     return renderer().view().frameView().convertFromRenderer(&renderer(), rect);
2789 }
2790
2791 IntRect RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
2792 {
2793     IntRect rect = renderer().view().frameView().convertToRenderer(&renderer(), parentRect);
2794     rect.move(-scrollbarOffset(scrollbar));
2795     return rect;
2796 }
2797
2798 IntPoint RenderLayer::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
2799 {
2800     IntPoint point = scrollbarPoint;
2801     point.move(scrollbarOffset(scrollbar));
2802     return renderer().view().frameView().convertFromRenderer(&renderer(), point);
2803 }
2804
2805 IntPoint RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
2806 {
2807     IntPoint point = renderer().view().frameView().convertToRenderer(&renderer(), parentPoint);
2808     point.move(-scrollbarOffset(scrollbar));
2809     return point;
2810 }
2811
2812 IntSize RenderLayer::contentsSize() const
2813 {
2814     return IntSize(scrollWidth(), scrollHeight());
2815 }
2816
2817 bool RenderLayer::shouldSuspendScrollAnimations() const
2818 {
2819     return renderer().view().frameView().shouldSuspendScrollAnimations();
2820 }
2821
2822 #if PLATFORM(IOS)
2823 void RenderLayer::didStartScroll()
2824 {
2825     if (Page* page = renderer().frame().page())
2826         page->chrome().client().didStartOverflowScroll();
2827 }
2828
2829 void RenderLayer::didEndScroll()
2830 {
2831     if (Page* page = renderer().frame().page())
2832         page->chrome().client().didEndOverflowScroll();
2833 }
2834     
2835 void RenderLayer::didUpdateScroll()
2836 {
2837     // Send this notification when we scroll, since this is how we keep selection updated.
2838     if (Page* page = renderer().frame().page())
2839         page->chrome().client().didLayout(ChromeClient::Scroll);
2840 }
2841 #endif
2842
2843 IntPoint RenderLayer::lastKnownMousePosition() const
2844 {
2845     return renderer().frame().eventHandler().lastKnownMousePosition();
2846 }
2847
2848 bool RenderLayer::isHandlingWheelEvent() const
2849 {
2850     return renderer().frame().eventHandler().isHandlingWheelEvent();
2851 }
2852
2853 IntRect RenderLayer::rectForHorizontalScrollbar(const IntRect& borderBoxRect) const
2854 {
2855     if (!m_hBar)
2856         return IntRect();
2857
2858     const RenderBox* box = renderBox();
2859     const IntRect& scrollCorner = scrollCornerRect();
2860
2861     return IntRect(horizontalScrollbarStart(borderBoxRect.x()),
2862         borderBoxRect.maxY() - box->borderBottom() - m_hBar->height(),
2863         borderBoxRect.width() - (box->borderLeft() + box->borderRight()) - scrollCorner.width(),
2864         m_hBar->height());
2865 }
2866
2867 IntRect RenderLayer::rectForVerticalScrollbar(const IntRect& borderBoxRect) const
2868 {
2869     if (!m_vBar)
2870         return IntRect();
2871
2872     const RenderBox* box = renderBox();
2873     const IntRect& scrollCorner = scrollCornerRect();
2874
2875     return IntRect(verticalScrollbarStart(borderBoxRect.x(), borderBoxRect.maxX()),
2876         borderBoxRect.y() + box->borderTop(),
2877         m_vBar->width(),
2878         borderBoxRect.height() - (box->borderTop() + box->borderBottom()) - scrollCorner.height());
2879 }
2880
2881 LayoutUnit RenderLayer::verticalScrollbarStart(int minX, int maxX) const
2882 {
2883     const RenderBox* box = renderBox();
2884     if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
2885         return minX + box->borderLeft();
2886     return maxX - box->borderRight() - m_vBar->width();
2887 }
2888
2889 LayoutUnit RenderLayer::horizontalScrollbarStart(int minX) const
2890 {
2891     const RenderBox* box = renderBox();
2892     int x = minX + box->borderLeft();
2893     if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
2894         x += m_vBar ? m_vBar->width() : roundToInt(resizerCornerRect(this, box->borderBoxRect()).width());
2895     return x;
2896 }
2897
2898 IntSize RenderLayer::scrollbarOffset(const Scrollbar* scrollbar) const
2899 {
2900     RenderBox* box = renderBox();
2901
2902     if (scrollbar == m_vBar.get())
2903         return IntSize(verticalScrollbarStart(0, box->width()), box->borderTop());
2904
2905     if (scrollbar == m_hBar.get())
2906         return IntSize(horizontalScrollbarStart(0), box->height() - box->borderBottom() - scrollbar->height());
2907     
2908     ASSERT_NOT_REACHED();
2909     return IntSize();
2910 }
2911
2912 void RenderLayer::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
2913 {
2914 #if PLATFORM(IOS)
2915     // No need to invalidate scrollbars if we're using accelerated scrolling.
2916     if (hasAcceleratedTouchScrolling())
2917         return;
2918 #endif
2919
2920     if (scrollbar == m_vBar.get()) {
2921         if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
2922             layer->setNeedsDisplayInRect(rect);
2923             return;
2924         }
2925     } else {
2926         if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
2927             layer->setNeedsDisplayInRect(rect);
2928             return;
2929         }
2930     }
2931
2932     IntRect scrollRect = rect;
2933     RenderBox* box = renderBox();
2934     ASSERT(box);
2935     // If we are not yet inserted into the tree, there is no need to repaint.
2936     if (!box->parent())
2937         return;
2938
2939     if (scrollbar == m_vBar.get())
2940         scrollRect.move(verticalScrollbarStart(0, box->width()), box->borderTop());
2941     else
2942         scrollRect.move(horizontalScrollbarStart(0), box->height() - box->borderBottom() - scrollbar->height());
2943     LayoutRect repaintRect = scrollRect;
2944     renderBox()->flipForWritingMode(repaintRect);
2945     renderer().repaintRectangle(repaintRect);
2946 }
2947
2948 void RenderLayer::invalidateScrollCornerRect(const IntRect& rect)
2949 {
2950 #if PLATFORM(IOS)
2951     // No need to invalidate the scroll corner if we're using accelerated scrolling.
2952     if (hasAcceleratedTouchScrolling())
2953         return;
2954 #endif
2955
2956     if (GraphicsLayer* layer = layerForScrollCorner()) {
2957         layer->setNeedsDisplayInRect(rect);
2958         return;
2959     }
2960
2961     if (m_scrollCorner)
2962         m_scrollCorner->repaintRectangle(rect);
2963     if (m_resizer)
2964         m_resizer->repaintRectangle(rect);
2965 }
2966
2967 static inline RenderElement* rendererForScrollbar(RenderLayerModelObject& renderer)
2968 {
2969     if (Element* element = renderer.element()) {
2970         if (ShadowRoot* shadowRoot = element->containingShadowRoot()) {
2971             if (shadowRoot->type() == ShadowRoot::UserAgentShadowRoot)
2972                 return shadowRoot->hostElement()->renderer();
2973         }
2974     }
2975
2976     return &renderer;
2977 }
2978
2979 PassRefPtr<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientation)
2980 {
2981     RefPtr<Scrollbar> widget;
2982     RenderElement* actualRenderer = rendererForScrollbar(renderer());
2983     bool hasCustomScrollbarStyle = actualRenderer->isBox() && actualRenderer->style().hasPseudoStyle(SCROLLBAR);
2984     if (hasCustomScrollbarStyle)
2985         widget = RenderScrollbar::createCustomScrollbar(this, orientation, actualRenderer->element());
2986     else {
2987         widget = Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
2988         didAddScrollbar(widget.get(), orientation);
2989     }
2990     renderer().view().frameView().addChild(widget.get());
2991     return widget.release();
2992 }
2993
2994 void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation)
2995 {
2996     RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_hBar : m_vBar;
2997     if (!scrollbar)
2998         return;
2999
3000     if (!scrollbar->isCustomScrollbar())
3001         willRemoveScrollbar(scrollbar.get(), orientation);
3002
3003     scrollbar->removeFromParent();
3004     scrollbar->disconnectFromScrollableArea();
3005     scrollbar = 0;
3006 }
3007
3008 bool RenderLayer::scrollsOverflow() const
3009 {
3010     if (!renderer().isBox())
3011         return false;
3012
3013     return toRenderBox(renderer()).scrollsOverflow();
3014 }
3015
3016 void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
3017 {
3018     if (hasScrollbar == hasHorizontalScrollbar())
3019         return;
3020
3021     if (hasScrollbar)
3022         m_hBar = createScrollbar(HorizontalScrollbar);
3023     else
3024         destroyScrollbar(HorizontalScrollbar);
3025
3026     // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
3027     if (m_hBar)
3028         m_hBar->styleChanged();
3029     if (m_vBar)
3030         m_vBar->styleChanged();
3031
3032     // Force an update since we know the scrollbars have changed things.
3033 #if ENABLE(DASHBOARD_SUPPORT)
3034     if (renderer().document().hasAnnotatedRegions())
3035         renderer().document().setAnnotatedRegionsDirty(true);
3036 #endif
3037 }
3038
3039 void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
3040 {
3041     if (hasScrollbar == hasVerticalScrollbar())
3042         return;
3043
3044     if (hasScrollbar)
3045         m_vBar = createScrollbar(VerticalScrollbar);
3046     else
3047         destroyScrollbar(VerticalScrollbar);
3048
3049      // Destroying or creating one bar can cause our scrollbar corner to come and go.  We need to update the opposite scrollbar's style.
3050     if (m_hBar)
3051         m_hBar->styleChanged();
3052     if (m_vBar)
3053         m_vBar->styleChanged();
3054
3055     // Force an update since we know the scrollbars have changed things.
3056 #if ENABLE(DASHBOARD_SUPPORT)
3057     if (renderer().document().hasAnnotatedRegions())
3058         renderer().document().setAnnotatedRegionsDirty(true);
3059 #endif
3060 }
3061
3062 ScrollableArea* RenderLayer::enclosingScrollableArea() const
3063 {
3064     if (RenderLayer* scrollableLayer = enclosingScrollableLayer())
3065         return scrollableLayer;
3066
3067     // FIXME: We should return the frame view here (or possibly an ancestor frame view,
3068     // if the frame view isn't scrollable.
3069     return 0;
3070 }
3071
3072 int RenderLayer::verticalScrollbarWidth(OverlayScrollbarSizeRelevancy relevancy) const
3073 {
3074     if (!m_vBar || (m_vBar->isOverlayScrollbar() && (relevancy == IgnoreOverlayScrollbarSize || !m_vBar->shouldParticipateInHitTesting())))
3075         return 0;
3076
3077 #if PLATFORM(IOS)
3078     if (hasAcceleratedTouchScrolling()) 
3079         return 0;
3080 #endif
3081
3082     return m_vBar->width();
3083 }
3084
3085 int RenderLayer::horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy relevancy) const
3086 {
3087     if (!m_hBar || (m_hBar->isOverlayScrollbar() && (relevancy == IgnoreOverlayScrollbarSize || !m_hBar->shouldParticipateInHitTesting())))
3088         return 0;
3089
3090 #if PLATFORM(IOS)
3091     if (hasAcceleratedTouchScrolling()) 
3092         return 0;
3093 #endif
3094
3095     return m_hBar->height();
3096 }
3097
3098 IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& absolutePoint) const
3099 {
3100     // Currently the resize corner is either the bottom right corner or the bottom left corner.
3101     // FIXME: This assumes the location is 0, 0. Is this guaranteed to always be the case?
3102     IntSize elementSize = size();
3103     if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
3104         elementSize.setWidth(0);
3105     IntPoint resizerPoint = IntPoint(elementSize);
3106     IntPoint localPoint = roundedIntPoint(absoluteToContents(absolutePoint));
3107     return localPoint - resizerPoint;
3108 }
3109
3110 bool RenderLayer::hasOverflowControls() const
3111 {
3112     return m_hBar || m_vBar || m_scrollCorner || renderer().style().resize() != RESIZE_NONE;
3113 }
3114
3115 void RenderLayer::positionOverflowControls(const IntSize& offsetFromRoot)
3116 {
3117     if (!m_hBar && !m_vBar && !canResize())
3118         return;
3119     
3120     RenderBox* box = renderBox();
3121     if (!box)
3122         return;
3123
3124     const IntRect borderBox = box->pixelSnappedBorderBoxRect();
3125     const IntRect& scrollCorner = scrollCornerRect();
3126     IntRect absBounds(borderBox.location() + offsetFromRoot, borderBox.size());
3127     if (m_vBar) {
3128         IntRect vBarRect = rectForVerticalScrollbar(borderBox);
3129         vBarRect.move(offsetFromRoot);
3130         m_vBar->setFrameRect(vBarRect);
3131     }
3132     
3133     if (m_hBar) {
3134         IntRect hBarRect = rectForHorizontalScrollbar(borderBox);
3135         hBarRect.move(offsetFromRoot);
3136         m_hBar->setFrameRect(hBarRect);
3137     }
3138     
3139     if (m_scrollCorner)
3140         m_scrollCorner->setFrameRect(scrollCorner);
3141     if (m_resizer)
3142         m_resizer->setFrameRect(resizerCornerRect(this, borderBox));
3143
3144     if (isComposited())
3145         backing()->positionOverflowControlsLayers();
3146 }
3147
3148 int RenderLayer::scrollWidth() const
3149 {
3150     ASSERT(renderBox());
3151     if (m_scrollDimensionsDirty)
3152         const_cast<RenderLayer*>(this)->computeScrollDimensions();
3153     return snapSizeToPixel(m_scrollSize.width(), renderBox()->clientLeft() + renderBox()->x());
3154 }
3155
3156 int RenderLayer::scrollHeight() const
3157 {
3158     ASSERT(renderBox());
3159     if (m_scrollDimensionsDirty)
3160         const_cast<RenderLayer*>(this)->computeScrollDimensions();
3161     return snapSizeToPixel(m_scrollSize.height(), renderBox()->clientTop() + renderBox()->y());
3162 }
3163
3164 LayoutUnit RenderLayer::overflowTop() const
3165 {
3166     RenderBox* box = renderBox();
3167     LayoutRect overflowRect(box->layoutOverflowRect());
3168     box->flipForWritingMode(overflowRect);
3169     return overflowRect.y();
3170 }
3171
3172 LayoutUnit RenderLayer::overflowBottom() const
3173 {
3174     RenderBox* box = renderBox();
3175     LayoutRect overflowRect(box->layoutOverflowRect());
3176     box->flipForWritingMode(overflowRect);
3177     return overflowRect.maxY();
3178 }
3179
3180 LayoutUnit RenderLayer::overflowLeft() const
3181 {
3182     RenderBox* box = renderBox();
3183     LayoutRect overflowRect(box->layoutOverflowRect());
3184     box->flipForWritingMode(overflowRect);
3185     return overflowRect.x();
3186 }
3187
3188 LayoutUnit RenderLayer::overflowRight() const
3189 {
3190     RenderBox* box = renderBox();
3191     LayoutRect overflowRect(box->layoutOverflowRect());
3192     box->flipForWritingMode(overflowRect);
3193     return overflowRect.maxX();
3194 }
3195
3196 void RenderLayer::computeScrollDimensions()
3197 {
3198     RenderBox* box = renderBox();
3199     ASSERT(box);
3200
3201     m_scrollDimensionsDirty = false;
3202
3203     m_scrollSize.setWidth(overflowRight() - overflowLeft());
3204     m_scrollSize.setHeight(overflowBottom() - overflowTop());
3205
3206     int scrollableLeftOverflow = overflowLeft() - box->borderLeft();
3207     int scrollableTopOverflow = overflowTop() - box->borderTop();
3208     setScrollOrigin(IntPoint(-scrollableLeftOverflow, -scrollableTopOverflow));
3209 }
3210
3211 bool RenderLayer::hasScrollableHorizontalOverflow() const
3212 {
3213     return hasHorizontalOverflow() && renderBox()->scrollsOverflowX();
3214 }
3215
3216 bool RenderLayer::hasScrollableVerticalOverflow() const
3217 {
3218     return hasVerticalOverflow() && renderBox()->scrollsOverflowY();
3219 }
3220
3221 bool RenderLayer::hasHorizontalOverflow() const
3222 {
3223     ASSERT(!m_scrollDimensionsDirty);
3224
3225     return scrollWidth() > renderBox()->pixelSnappedClientWidth();
3226 }
3227
3228 bool RenderLayer::hasVerticalOverflow() const
3229 {
3230     ASSERT(!m_scrollDimensionsDirty);
3231
3232     return scrollHeight() > renderBox()->pixelSnappedClientHeight();
3233 }
3234
3235 void RenderLayer::updateScrollbarsAfterLayout()
3236 {
3237     RenderBox* box = renderBox();
3238     ASSERT(box);
3239
3240     // List box parts handle the scrollbars by themselves so we have nothing to do.
3241     if (box->style().appearance() == ListboxPart)
3242         return;
3243
3244     bool hasHorizontalOverflow = this->hasHorizontalOverflow();
3245     bool hasVerticalOverflow = this->hasVerticalOverflow();
3246
3247     // overflow:scroll should just enable/disable.
3248     if (renderer().style().overflowX() == OSCROLL)
3249         m_hBar->setEnabled(hasHorizontalOverflow);
3250     if (renderer().style().overflowY() == OSCROLL)
3251         m_vBar->setEnabled(hasVerticalOverflow);
3252
3253     // overflow:auto may need to lay out again if scrollbars got added/removed.
3254     bool autoHorizontalScrollBarChanged = box->hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow);
3255     bool autoVerticalScrollBarChanged = box->hasAutoVerticalScrollbar() && (hasVerticalScrollbar() != hasVerticalOverflow);
3256
3257     if (autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged) {
3258         if (box->hasAutoHorizontalScrollbar())
3259             setHasHorizontalScrollbar(hasHorizontalOverflow);
3260         if (box->hasAutoVerticalScrollbar())
3261             setHasVerticalScrollbar(hasVerticalOverflow);
3262
3263         updateSelfPaintingLayer();
3264
3265         // Force an update since we know the scrollbars have changed things.
3266 #if ENABLE(DASHBOARD_SUPPORT)
3267         if (renderer().document().hasAnnotatedRegions())
3268             renderer().document().setAnnotatedRegionsDirty(true);
3269 #endif
3270
3271         renderer().repaint();
3272
3273         if (renderer().style().overflowX() == OAUTO || renderer().style().overflowY() == OAUTO) {
3274             if (!m_inOverflowRelayout) {
3275                 // Our proprietary overflow: overlay value doesn't trigger a layout.
3276                 m_inOverflowRelayout = true;
3277                 renderer().setNeedsLayout(MarkOnlyThis);
3278                 if (renderer().isRenderBlock()) {
3279                     RenderBlock& block = toRenderBlock(renderer());
3280                     block.scrollbarsChanged(autoHorizontalScrollBarChanged, autoVerticalScrollBarChanged);
3281                     block.layoutBlock(true);
3282                 } else
3283                     renderer().layout();
3284                 m_inOverflowRelayout = false;
3285             }
3286         }
3287     }
3288
3289     // Set up the range (and page step/line step).
3290     if (m_hBar) {
3291         int clientWidth = box->pixelSnappedClientWidth();
3292         int pageStep = std::max(std::max<int>(clientWidth * Scrollbar::minFractionToStepWhenPaging(), clientWidth - Scrollbar::maxOverlapBetweenPages()), 1);
3293         m_hBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
3294         m_hBar->setProportion(clientWidth, m_scrollSize.width());
3295     }
3296     if (m_vBar) {
3297         int clientHeight = box->pixelSnappedClientHeight();
3298         int pageStep = std::max(std::max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
3299         m_vBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
3300         m_vBar->setProportion(clientHeight, m_scrollSize.height());
3301     }
3302
3303     updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
3304 }
3305
3306 void RenderLayer::updateScrollInfoAfterLayout()
3307 {
3308     RenderBox* box = renderBox();
3309     if (!box)
3310         return;
3311
3312     m_scrollDimensionsDirty = true;
3313     IntSize originalScrollOffset = scrollOffset();
3314
3315     computeScrollDimensions();
3316
3317     if (box->style().overflowX() != OMARQUEE) {
3318         // Layout may cause us to be at an invalid scroll position. In this case we need
3319         // to pull our scroll offsets back to the max (or push them up to the min).
3320         IntSize clampedScrollOffset = clampScrollOffset(scrollOffset());
3321 #if PLATFORM(IOS)
3322         // FIXME: This looks wrong. The caret adjust mode should only be enabled on editing related entry points.
3323         // This code was added to fix an issue where the text insertion point would always be drawn on the right edge
3324         // of a text field whose content overflowed its bounds. See <rdar://problem/15579797> for more details.
3325         setAdjustForIOSCaretWhenScrolling(true);
3326 #endif
3327         if (clampedScrollOffset != scrollOffset())
3328             scrollToOffset(clampedScrollOffset);
3329
3330 #if PLATFORM(IOS)
3331         setAdjustForIOSCaretWhenScrolling(false);
3332 #endif
3333     }
3334
3335     updateScrollbarsAfterLayout();
3336
3337     if (originalScrollOffset != scrollOffset())
3338         scrollToOffsetWithoutAnimation(IntPoint(scrollOffset()));
3339
3340     // Composited scrolling may need to be enabled or disabled if the amount of overflow changed.
3341     if (compositor().updateLayerCompositingState(*this))
3342         compositor().setCompositingLayersNeedRebuild();
3343 }
3344
3345 bool RenderLayer::overflowControlsIntersectRect(const IntRect& localRect) const
3346 {
3347     const IntRect borderBox = renderBox()->pixelSnappedBorderBoxRect();
3348
3349     if (rectForHorizontalScrollbar(borderBox).intersects(localRect))
3350         return true;
3351
3352     if (rectForVerticalScrollbar(borderBox).intersects(localRect))
3353         return true;
3354
3355     if (scrollCornerRect().intersects(localRect))
3356         return true;
3357     
3358     if (resizerCornerRect(this, borderBox).intersects(localRect))
3359         return true;
3360
3361     return false;
3362 }
3363
3364 void RenderLayer::paintOverflowControls(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls)
3365 {
3366     // Don't do anything if we have no overflow.
3367     if (!renderer().hasOverflowClip())
3368         return;
3369
3370 #if PLATFORM(IOS)
3371     // Don't render (custom) scrollbars if we have accelerated scrolling.
3372     if (hasAcceleratedTouchScrolling())
3373         return;
3374 #endif
3375
3376     // Overlay scrollbars paint in a second pass through the layer tree so that they will paint
3377     // on top of everything else. If this is the normal painting pass, paintingOverlayControls
3378     // will be false, and we should just tell the root layer that there are overlay scrollbars
3379     // that need to be painted. That will cause the second pass through the layer tree to run,
3380     // and we'll paint the scrollbars then. In the meantime, cache tx and ty so that the 
3381     // second pass doesn't need to re-enter the RenderTree to get it right.
3382     if (hasOverlayScrollbars() && !paintingOverlayControls) {
3383         m_cachedOverlayScrollbarOffset = paintOffset;
3384
3385         // It's not necessary to do the second pass if the scrollbars paint into layers.
3386         if ((m_hBar && layerForHorizontalScrollbar()) || (m_vBar && layerForVerticalScrollbar()))
3387             return;
3388         IntRect localDamgeRect = damageRect;
3389         localDamgeRect.moveBy(-paintOffset);
3390         if (!overflowControlsIntersectRect(localDamgeRect))
3391             return;
3392
3393         RenderLayer* paintingRoot = enclosingCompositingLayer();
3394         if (!paintingRoot)
3395             paintingRoot = renderer().view().layer();
3396
3397         paintingRoot->setContainsDirtyOverlayScrollbars(true);
3398         return;
3399     }
3400
3401     // This check is required to avoid painting custom CSS scrollbars twice.
3402     if (paintingOverlayControls && !hasOverlayScrollbars())
3403         return;
3404
3405     IntPoint adjustedPaintOffset = paintOffset;