OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions | |
6 * are met: | |
7 * 1. Redistributions of source code must retain the above copyright | |
8 * notice, this list of conditions and the following disclaimer. | |
9 * 2. Redistributions in binary form must reproduce the above copyright | |
10 * notice, this list of conditions and the following disclaimer in the | |
11 * documentation and/or other materials provided with the distribution. | |
12 * | |
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | |
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
24 */ | |
25 | |
26 #include "config.h" | |
27 | |
28 #include "core/layout/compositing/RenderLayerCompositor.h" | |
29 | |
30 #include "core/animation/DocumentAnimations.h" | |
31 #include "core/dom/Fullscreen.h" | |
32 #include "core/editing/FrameSelection.h" | |
33 #include "core/frame/FrameHost.h" | |
34 #include "core/frame/FrameView.h" | |
35 #include "core/frame/LocalFrame.h" | |
36 #include "core/frame/Settings.h" | |
37 #include "core/html/HTMLIFrameElement.h" | |
38 #include "core/inspector/InspectorInstrumentation.h" | |
39 #include "core/inspector/InspectorNodeIds.h" | |
40 #include "core/layout/compositing/CompositedLayerMapping.h" | |
41 #include "core/layout/compositing/CompositingInputsUpdater.h" | |
42 #include "core/layout/compositing/CompositingLayerAssigner.h" | |
43 #include "core/layout/compositing/CompositingRequirementsUpdater.h" | |
44 #include "core/layout/compositing/GraphicsLayerTreeBuilder.h" | |
45 #include "core/layout/compositing/GraphicsLayerUpdater.h" | |
46 #include "core/loader/FrameLoaderClient.h" | |
47 #include "core/page/Chrome.h" | |
48 #include "core/page/ChromeClient.h" | |
49 #include "core/page/Page.h" | |
50 #include "core/page/scrolling/ScrollingCoordinator.h" | |
51 #include "core/paint/FramePainter.h" | |
52 #include "core/paint/TransformRecorder.h" | |
53 #include "core/rendering/RenderEmbeddedObject.h" | |
54 #include "core/rendering/RenderLayerStackingNode.h" | |
55 #include "core/rendering/RenderLayerStackingNodeIterator.h" | |
56 #include "core/rendering/RenderPart.h" | |
57 #include "core/rendering/RenderVideo.h" | |
58 #include "core/rendering/RenderView.h" | |
59 #include "platform/RuntimeEnabledFeatures.h" | |
60 #include "platform/ScriptForbiddenScope.h" | |
61 #include "platform/TraceEvent.h" | |
62 #include "platform/graphics/GraphicsLayer.h" | |
63 #include "platform/graphics/paint/DisplayItemList.h" | |
64 #include "platform/graphics/paint/DrawingRecorder.h" | |
65 #include "platform/graphics/paint/TransformDisplayItem.h" | |
66 #include "public/platform/Platform.h" | |
67 | |
68 namespace blink { | |
69 | |
70 RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView) | |
71 : m_renderView(renderView) | |
72 , m_compositingReasonFinder(renderView) | |
73 , m_pendingUpdateType(CompositingUpdateNone) | |
74 , m_hasAcceleratedCompositing(true) | |
75 , m_compositing(false) | |
76 , m_rootShouldAlwaysCompositeDirty(true) | |
77 , m_needsUpdateFixedBackground(false) | |
78 , m_isTrackingPaintInvalidations(false) | |
79 , m_rootLayerAttachment(RootLayerUnattached) | |
80 , m_inOverlayFullscreenVideo(false) | |
81 { | |
82 updateAcceleratedCompositingSettings(); | |
83 } | |
84 | |
85 RenderLayerCompositor::~RenderLayerCompositor() | |
86 { | |
87 ASSERT(m_rootLayerAttachment == RootLayerUnattached); | |
88 } | |
89 | |
90 bool RenderLayerCompositor::inCompositingMode() const | |
91 { | |
92 // FIXME: This should assert that lifecycle is >= CompositingClean since | |
93 // the last step of updateIfNeeded can set this bit to false. | |
94 ASSERT(m_renderView.layer()->isAllowedToQueryCompositingState()); | |
95 return m_compositing; | |
96 } | |
97 | |
98 bool RenderLayerCompositor::staleInCompositingMode() const | |
99 { | |
100 return m_compositing; | |
101 } | |
102 | |
103 void RenderLayerCompositor::setCompositingModeEnabled(bool enable) | |
104 { | |
105 if (enable == m_compositing) | |
106 return; | |
107 | |
108 m_compositing = enable; | |
109 | |
110 // RenderPart::requiresAcceleratedCompositing is used to determine self-pain
tingness | |
111 // and bases it's return value for frames on the m_compositing bit here. | |
112 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerEleme
nt()) { | |
113 if (RenderPart* renderer = ownerElement->renderPart()) | |
114 renderer->layer()->updateSelfPaintingLayer(); | |
115 } | |
116 | |
117 if (m_compositing) | |
118 ensureRootLayer(); | |
119 else | |
120 destroyRootLayer(); | |
121 | |
122 // Compositing also affects the answer to RenderIFrame::requiresAcceleratedC
ompositing(), so | |
123 // we need to schedule a style recalc in our parent document. | |
124 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerEleme
nt()) | |
125 ownerElement->setNeedsCompositingUpdate(); | |
126 } | |
127 | |
128 void RenderLayerCompositor::enableCompositingModeIfNeeded() | |
129 { | |
130 if (!m_rootShouldAlwaysCompositeDirty) | |
131 return; | |
132 | |
133 m_rootShouldAlwaysCompositeDirty = false; | |
134 if (m_compositing) | |
135 return; | |
136 | |
137 if (rootShouldAlwaysComposite()) { | |
138 // FIXME: Is this needed? It was added in https://bugs.webkit.org/show_b
ug.cgi?id=26651. | |
139 // No tests fail if it's deleted. | |
140 setNeedsCompositingUpdate(CompositingUpdateRebuildTree); | |
141 setCompositingModeEnabled(true); | |
142 } | |
143 } | |
144 | |
145 bool RenderLayerCompositor::rootShouldAlwaysComposite() const | |
146 { | |
147 if (!m_hasAcceleratedCompositing) | |
148 return false; | |
149 return m_renderView.frame()->isLocalRoot() || m_compositingReasonFinder.requ
iresCompositingForScrollableFrame(); | |
150 } | |
151 | |
152 void RenderLayerCompositor::updateAcceleratedCompositingSettings() | |
153 { | |
154 m_compositingReasonFinder.updateTriggers(); | |
155 m_hasAcceleratedCompositing = m_renderView.document().settings()->accelerate
dCompositingEnabled(); | |
156 m_rootShouldAlwaysCompositeDirty = true; | |
157 if (m_rootLayerAttachment != RootLayerUnattached) | |
158 rootRenderLayer()->setNeedsCompositingInputsUpdate(); | |
159 } | |
160 | |
161 bool RenderLayerCompositor::preferCompositingToLCDTextEnabled() const | |
162 { | |
163 return m_compositingReasonFinder.hasOverflowScrollTrigger(); | |
164 } | |
165 | |
166 static RenderVideo* findFullscreenVideoRenderer(Document& document) | |
167 { | |
168 // Recursively find the document that is in fullscreen. | |
169 Element* fullscreenElement = Fullscreen::fullscreenElementFrom(document); | |
170 Document* contentDocument = &document; | |
171 while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) { | |
172 contentDocument = toHTMLFrameOwnerElement(fullscreenElement)->contentDoc
ument(); | |
173 if (!contentDocument) | |
174 return 0; | |
175 fullscreenElement = Fullscreen::fullscreenElementFrom(*contentDocument); | |
176 } | |
177 // Get the current fullscreen element from the document. | |
178 fullscreenElement = Fullscreen::currentFullScreenElementFrom(*contentDocumen
t); | |
179 if (!isHTMLVideoElement(fullscreenElement)) | |
180 return 0; | |
181 RenderObject* renderer = fullscreenElement->renderer(); | |
182 if (!renderer) | |
183 return 0; | |
184 return toRenderVideo(renderer); | |
185 } | |
186 | |
187 void RenderLayerCompositor::updateIfNeededRecursive() | |
188 { | |
189 for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); c
hild; child = child->tree().nextSibling()) { | |
190 if (child->isLocalFrame()) | |
191 toLocalFrame(child)->contentRenderer()->compositor()->updateIfNeeded
Recursive(); | |
192 } | |
193 | |
194 TRACE_EVENT0("blink", "RenderLayerCompositor::updateIfNeededRecursive"); | |
195 | |
196 ASSERT(!m_renderView.needsLayout()); | |
197 | |
198 ScriptForbiddenScope forbidScript; | |
199 | |
200 // FIXME: enableCompositingModeIfNeeded can trigger a CompositingUpdateRebui
ldTree, | |
201 // which asserts that it's not InCompositingUpdate. | |
202 enableCompositingModeIfNeeded(); | |
203 | |
204 rootRenderLayer()->updateDescendantDependentFlagsForEntireSubtree(); | |
205 m_renderView.commitPendingSelection(); | |
206 | |
207 lifecycle().advanceTo(DocumentLifecycle::InCompositingUpdate); | |
208 updateIfNeeded(); | |
209 lifecycle().advanceTo(DocumentLifecycle::CompositingClean); | |
210 | |
211 DocumentAnimations::startPendingAnimations(m_renderView.document()); | |
212 | |
213 m_renderView.frameView()->updateCompositorScrollAnimations(); | |
214 if (const FrameView::ScrollableAreaSet* animatingScrollableAreas = m_renderV
iew.frameView()->animatingScrollableAreas()) { | |
215 for (ScrollableArea* scrollableArea : *animatingScrollableAreas) | |
216 scrollableArea->updateCompositorScrollAnimations(); | |
217 } | |
218 | |
219 #if ENABLE(ASSERT) | |
220 ASSERT(lifecycle().state() == DocumentLifecycle::CompositingClean); | |
221 assertNoUnresolvedDirtyBits(); | |
222 for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); c
hild; child = child->tree().nextSibling()) { | |
223 if (child->isLocalFrame()) | |
224 toLocalFrame(child)->contentRenderer()->compositor()->assertNoUnreso
lvedDirtyBits(); | |
225 } | |
226 #endif | |
227 } | |
228 | |
229 void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType upda
teType) | |
230 { | |
231 ASSERT(updateType != CompositingUpdateNone); | |
232 m_pendingUpdateType = std::max(m_pendingUpdateType, updateType); | |
233 page()->animator().scheduleVisualUpdate(m_renderView.frame()); | |
234 lifecycle().ensureStateAtMost(DocumentLifecycle::LayoutClean); | |
235 } | |
236 | |
237 void RenderLayerCompositor::didLayout() | |
238 { | |
239 // FIXME: Technically we only need to do this when the FrameView's | |
240 // isScrollable method would return a different value. | |
241 m_rootShouldAlwaysCompositeDirty = true; | |
242 enableCompositingModeIfNeeded(); | |
243 | |
244 // FIXME: Rather than marking the entire RenderView as dirty, we should | |
245 // track which RenderLayers moved during layout and only dirty those | |
246 // specific RenderLayers. | |
247 rootRenderLayer()->setNeedsCompositingInputsUpdate(); | |
248 } | |
249 | |
250 #if ENABLE(ASSERT) | |
251 | |
252 void RenderLayerCompositor::assertNoUnresolvedDirtyBits() | |
253 { | |
254 ASSERT(m_pendingUpdateType == CompositingUpdateNone); | |
255 ASSERT(!m_rootShouldAlwaysCompositeDirty); | |
256 } | |
257 | |
258 #endif | |
259 | |
260 void RenderLayerCompositor::applyOverlayFullscreenVideoAdjustment() | |
261 { | |
262 m_inOverlayFullscreenVideo = false; | |
263 if (!m_rootContentLayer) | |
264 return; | |
265 | |
266 bool isLocalRoot = m_renderView.frame()->isLocalRoot(); | |
267 RenderVideo* video = findFullscreenVideoRenderer(m_renderView.document()); | |
268 if (!video || !video->layer()->hasCompositedLayerMapping()) { | |
269 if (isLocalRoot) { | |
270 GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer(); | |
271 if (backgroundLayer && !backgroundLayer->parent()) | |
272 rootFixedBackgroundsChanged(); | |
273 } | |
274 return; | |
275 } | |
276 | |
277 GraphicsLayer* videoLayer = video->layer()->compositedLayerMapping()->mainGr
aphicsLayer(); | |
278 | |
279 // The fullscreen video has layer position equal to its enclosing frame's sc
roll position because fullscreen container is fixed-positioned. | |
280 // We should reset layer position here since we are going to reattach the la
yer at the very top level. | |
281 videoLayer->setPosition(IntPoint()); | |
282 | |
283 // Only steal fullscreen video layer and clear all other layers if we are th
e main frame. | |
284 if (!isLocalRoot) | |
285 return; | |
286 | |
287 m_rootContentLayer->removeAllChildren(); | |
288 m_overflowControlsHostLayer->addChild(videoLayer); | |
289 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer()) | |
290 backgroundLayer->removeFromParent(); | |
291 m_inOverlayFullscreenVideo = true; | |
292 } | |
293 | |
294 void RenderLayerCompositor::updateWithoutAcceleratedCompositing(CompositingUpdat
eType updateType) | |
295 { | |
296 ASSERT(!hasAcceleratedCompositing()); | |
297 | |
298 if (updateType >= CompositingUpdateAfterCompositingInputChange) | |
299 CompositingInputsUpdater(rootRenderLayer()).update(); | |
300 | |
301 #if ENABLE(ASSERT) | |
302 CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(root
RenderLayer()); | |
303 #endif | |
304 } | |
305 | |
306 static void forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendan
ts(RenderObject* renderer) | |
307 { | |
308 // We clear the previous paint invalidation rect as it's wrong (paint invali
ation container | |
309 // changed, ...). Forcing a full invalidation will make us recompute it. Als
o we are not | |
310 // changing the previous position from our paint invalidation container, whi
ch is fine as | |
311 // we want a full paint invalidation anyway. | |
312 renderer->setPreviousPaintInvalidationRect(LayoutRect()); | |
313 renderer->setShouldDoFullPaintInvalidation(); | |
314 | |
315 for (RenderObject* child = renderer->slowFirstChild(); child; child = child-
>nextSibling()) { | |
316 if (!child->isPaintInvalidationContainer()) | |
317 forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendan
ts(child); | |
318 } | |
319 } | |
320 | |
321 | |
322 void RenderLayerCompositor::updateIfNeeded() | |
323 { | |
324 CompositingUpdateType updateType = m_pendingUpdateType; | |
325 m_pendingUpdateType = CompositingUpdateNone; | |
326 | |
327 if (!hasAcceleratedCompositing()) { | |
328 updateWithoutAcceleratedCompositing(updateType); | |
329 return; | |
330 } | |
331 | |
332 if (updateType == CompositingUpdateNone) | |
333 return; | |
334 | |
335 RenderLayer* updateRoot = rootRenderLayer(); | |
336 | |
337 Vector<RenderLayer*> layersNeedingPaintInvalidation; | |
338 | |
339 if (updateType >= CompositingUpdateAfterCompositingInputChange) { | |
340 CompositingInputsUpdater(updateRoot).update(); | |
341 | |
342 #if ENABLE(ASSERT) | |
343 // FIXME: Move this check to the end of the compositing update. | |
344 CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(
updateRoot); | |
345 #endif | |
346 | |
347 CompositingRequirementsUpdater(m_renderView, m_compositingReasonFinder).
update(updateRoot); | |
348 | |
349 CompositingLayerAssigner layerAssigner(this); | |
350 layerAssigner.assign(updateRoot, layersNeedingPaintInvalidation); | |
351 | |
352 bool layersChanged = layerAssigner.layersChanged(); | |
353 | |
354 { | |
355 TRACE_EVENT0("blink", "RenderLayerCompositor::updateAfterCompositing
Change"); | |
356 if (const FrameView::ScrollableAreaSet* scrollableAreas = m_renderVi
ew.frameView()->scrollableAreas()) { | |
357 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas
->begin(); it != scrollableAreas->end(); ++it) | |
358 layersChanged |= (*it)->updateAfterCompositingChange(); | |
359 } | |
360 } | |
361 | |
362 if (layersChanged) | |
363 updateType = std::max(updateType, CompositingUpdateRebuildTree); | |
364 } | |
365 | |
366 if (updateType != CompositingUpdateNone) { | |
367 GraphicsLayerUpdater updater; | |
368 updater.update(*updateRoot, layersNeedingPaintInvalidation); | |
369 | |
370 if (updater.needsRebuildTree()) | |
371 updateType = std::max(updateType, CompositingUpdateRebuildTree); | |
372 | |
373 #if ENABLE(ASSERT) | |
374 // FIXME: Move this check to the end of the compositing update. | |
375 GraphicsLayerUpdater::assertNeedsToUpdateGraphicsLayerBitsCleared(*updat
eRoot); | |
376 #endif | |
377 } | |
378 | |
379 if (updateType >= CompositingUpdateRebuildTree) { | |
380 GraphicsLayerTreeBuilder::AncestorInfo ancestorInfo; | |
381 GraphicsLayerVector childList; | |
382 ancestorInfo.childLayersOfEnclosingCompositedLayer = &childList; | |
383 { | |
384 TRACE_EVENT0("blink", "GraphicsLayerTreeBuilder::rebuild"); | |
385 GraphicsLayerTreeBuilder().rebuild(*updateRoot, ancestorInfo); | |
386 } | |
387 | |
388 if (childList.isEmpty()) | |
389 destroyRootLayer(); | |
390 else | |
391 m_rootContentLayer->setChildren(childList); | |
392 | |
393 if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled()) | |
394 applyOverlayFullscreenVideoAdjustment(); | |
395 } | |
396 | |
397 if (m_needsUpdateFixedBackground) { | |
398 rootFixedBackgroundsChanged(); | |
399 m_needsUpdateFixedBackground = false; | |
400 } | |
401 | |
402 for (unsigned i = 0; i < layersNeedingPaintInvalidation.size(); i++) | |
403 forceRecomputePaintInvalidationRectsIncludingNonCompositingDescendants(l
ayersNeedingPaintInvalidation[i]->renderer()); | |
404 | |
405 // Inform the inspector that the layer tree has changed. | |
406 if (m_renderView.frame()->isMainFrame()) | |
407 InspectorInstrumentation::layerTreeDidChange(m_renderView.frame()); | |
408 } | |
409 | |
410 bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* l
ayer, const CompositingStateTransitionType compositedLayerUpdate) | |
411 { | |
412 bool compositedLayerMappingChanged = false; | |
413 | |
414 // FIXME: It would be nice to directly use the layer's compositing reason, | |
415 // but allocateOrClearCompositedLayerMapping also gets called without having
updated compositing | |
416 // requirements fully. | |
417 switch (compositedLayerUpdate) { | |
418 case AllocateOwnCompositedLayerMapping: | |
419 ASSERT(!layer->hasCompositedLayerMapping()); | |
420 setCompositingModeEnabled(true); | |
421 | |
422 // If we need to issue paint invalidations, do so before allocating the
compositedLayerMapping and clearing out the groupedMapping. | |
423 paintInvalidationOnCompositingChange(layer); | |
424 | |
425 // If this layer was previously squashed, we need to remove its referenc
e to a groupedMapping right away, so | |
426 // that computing paint invalidation rects will know the layer's correct
compositingState. | |
427 // FIXME: do we need to also remove the layer from it's location in the
squashing list of its groupedMapping? | |
428 // Need to create a test where a squashed layer pops into compositing. A
nd also to cover all other | |
429 // sorts of compositingState transitions. | |
430 layer->setLostGroupedMapping(false); | |
431 layer->setGroupedMapping(0); | |
432 | |
433 layer->ensureCompositedLayerMapping(); | |
434 compositedLayerMappingChanged = true; | |
435 | |
436 // At this time, the ScrollingCooridnator only supports the top-level fr
ame. | |
437 if (layer->isRootLayer() && m_renderView.frame()->isLocalRoot()) { | |
438 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoor
dinator()) | |
439 scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.f
rameView()); | |
440 } | |
441 break; | |
442 case RemoveOwnCompositedLayerMapping: | |
443 // PutInSquashingLayer means you might have to remove the composited layer m
apping first. | |
444 case PutInSquashingLayer: | |
445 if (layer->hasCompositedLayerMapping()) { | |
446 // If we're removing the compositedLayerMapping from a reflection, c
lear the source GraphicsLayer's pointer to | |
447 // its replica GraphicsLayer. In practice this should never happen b
ecause reflectee and reflection | |
448 // are both either composited, or not composited. | |
449 if (layer->isReflection()) { | |
450 RenderLayer* sourceLayer = toRenderLayerModelObject(layer->rende
rer()->parent())->layer(); | |
451 if (sourceLayer->hasCompositedLayerMapping()) { | |
452 ASSERT(sourceLayer->compositedLayerMapping()->mainGraphicsLa
yer()->replicaLayer() == layer->compositedLayerMapping()->mainGraphicsLayer()); | |
453 sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->
setReplicatedByLayer(0); | |
454 } | |
455 } | |
456 | |
457 layer->clearCompositedLayerMapping(); | |
458 compositedLayerMappingChanged = true; | |
459 } | |
460 | |
461 break; | |
462 case RemoveFromSquashingLayer: | |
463 case NoCompositingStateChange: | |
464 // Do nothing. | |
465 break; | |
466 } | |
467 | |
468 if (compositedLayerMappingChanged && layer->renderer()->isRenderPart()) { | |
469 RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRende
rPart(layer->renderer())); | |
470 if (innerCompositor && innerCompositor->staleInCompositingMode()) | |
471 innerCompositor->updateRootLayerAttachment(); | |
472 } | |
473 | |
474 if (compositedLayerMappingChanged) | |
475 layer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects); | |
476 | |
477 // If a fixed position layer gained/lost a compositedLayerMapping or the rea
son not compositing it changed, | |
478 // the scrolling coordinator needs to recalculate whether it can do fast scr
olling. | |
479 if (compositedLayerMappingChanged) { | |
480 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordina
tor()) | |
481 scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView.fr
ameView()); | |
482 } | |
483 | |
484 return compositedLayerMappingChanged; | |
485 } | |
486 | |
487 void RenderLayerCompositor::paintInvalidationOnCompositingChange(RenderLayer* la
yer) | |
488 { | |
489 // If the renderer is not attached yet, no need to issue paint invalidations
. | |
490 if (layer->renderer() != &m_renderView && !layer->renderer()->parent()) | |
491 return; | |
492 | |
493 // For querying RenderLayer::compositingState() | |
494 // Eager invalidation here is correct, since we are invalidating with respec
t to the previous frame's | |
495 // compositing state when changing the compositing backing of the layer. | |
496 DisableCompositingQueryAsserts disabler; | |
497 | |
498 layer->renderer()->invalidatePaintIncludingNonCompositingDescendants(); | |
499 } | |
500 | |
501 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsO
ffset) | |
502 { | |
503 if (m_overflowControlsHostLayer) | |
504 m_overflowControlsHostLayer->setPosition(contentsOffset); | |
505 } | |
506 | |
507 void RenderLayerCompositor::frameViewDidChangeSize() | |
508 { | |
509 if (m_containerLayer) { | |
510 FrameView* frameView = m_renderView.frameView(); | |
511 m_containerLayer->setSize(frameView->unscaledVisibleContentSize()); | |
512 m_overflowControlsHostLayer->setSize(frameView->unscaledVisibleContentSi
ze(IncludeScrollbars)); | |
513 | |
514 frameViewDidScroll(); | |
515 updateOverflowControlsLayers(); | |
516 } | |
517 } | |
518 | |
519 enum AcceleratedFixedRootBackgroundHistogramBuckets { | |
520 ScrolledMainFrameBucket = 0, | |
521 ScrolledMainFrameWithAcceleratedFixedRootBackground = 1, | |
522 ScrolledMainFrameWithUnacceleratedFixedRootBackground = 2, | |
523 AcceleratedFixedRootBackgroundHistogramMax = 3 | |
524 }; | |
525 | |
526 void RenderLayerCompositor::frameViewDidScroll() | |
527 { | |
528 FrameView* frameView = m_renderView.frameView(); | |
529 IntPoint scrollPosition = frameView->scrollPosition(); | |
530 | |
531 if (!m_scrollLayer) | |
532 return; | |
533 | |
534 bool scrollingCoordinatorHandlesOffset = false; | |
535 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator(
)) { | |
536 if (Settings* settings = m_renderView.document().settings()) { | |
537 if (m_renderView.frame()->isLocalRoot() || settings->preferCompositi
ngToLCDTextEnabled()) | |
538 scrollingCoordinatorHandlesOffset = scrollingCoordinator->scroll
ableAreaScrollLayerDidChange(frameView); | |
539 } | |
540 } | |
541 | |
542 // Scroll position = scroll minimum + scroll offset. Adjust the layer's | |
543 // position to handle whatever the scroll coordinator isn't handling. | |
544 // The minimum scroll position is non-zero for RTL pages with overflow. | |
545 if (scrollingCoordinatorHandlesOffset) | |
546 m_scrollLayer->setPosition(-frameView->minimumScrollPosition()); | |
547 else | |
548 m_scrollLayer->setPosition(-scrollPosition); | |
549 | |
550 | |
551 Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBack
ground", | |
552 ScrolledMainFrameBucket, | |
553 AcceleratedFixedRootBackgroundHistogramMax); | |
554 } | |
555 | |
556 void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange() | |
557 { | |
558 if (m_containerLayer) | |
559 updateOverflowControlsLayers(); | |
560 } | |
561 | |
562 void RenderLayerCompositor::rootFixedBackgroundsChanged() | |
563 { | |
564 if (!supportsFixedRootBackgroundCompositing()) | |
565 return; | |
566 | |
567 // To avoid having to make the fixed root background layer fixed positioned
to | |
568 // stay put, we position it in the layer tree as follows: | |
569 // | |
570 // + Overflow controls host | |
571 // + LocalFrame clip | |
572 // + (Fixed root background) <-- Here. | |
573 // + LocalFrame scroll | |
574 // + Root content layer | |
575 // + Scrollbars | |
576 // | |
577 // That is, it needs to be the first child of the frame clip, the sibling of | |
578 // the frame scroll layer. The compositor does not own the background layer,
it | |
579 // just positions it (like the foreground layer). | |
580 if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer()) | |
581 m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get()); | |
582 } | |
583 | |
584 bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer) | |
585 { | |
586 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator(
)) | |
587 return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->s
crollableArea()); | |
588 return false; | |
589 } | |
590 | |
591 String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags) | |
592 { | |
593 ASSERT(lifecycle().state() >= DocumentLifecycle::PaintInvalidationClean); | |
594 | |
595 if (!m_rootContentLayer) | |
596 return String(); | |
597 | |
598 // We skip dumping the scroll and clip layers to keep layerTreeAsText output | |
599 // similar between platforms (unless we explicitly request dumping from the | |
600 // root. | |
601 GraphicsLayer* rootLayer = m_rootContentLayer.get(); | |
602 if (flags & LayerTreeIncludesRootLayer) | |
603 rootLayer = rootGraphicsLayer(); | |
604 | |
605 String layerTreeText = rootLayer->layerTreeAsText(flags); | |
606 | |
607 // The true root layer is not included in the dump, so if we want to report | |
608 // its paint invalidation rects, they must be included here. | |
609 if (flags & LayerTreeIncludesPaintInvalidationRects) | |
610 return m_renderView.frameView()->trackedPaintInvalidationRectsAsText() +
layerTreeText; | |
611 | |
612 return layerTreeText; | |
613 } | |
614 | |
615 RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart
* renderer) | |
616 { | |
617 if (!renderer->node()->isFrameOwnerElement()) | |
618 return 0; | |
619 | |
620 HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(renderer->node()); | |
621 if (Document* contentDocument = element->contentDocument()) { | |
622 if (RenderView* view = contentDocument->renderView()) | |
623 return view->compositor(); | |
624 } | |
625 return 0; | |
626 } | |
627 | |
628 // FIXME: What does this function do? It needs a clearer name. | |
629 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer) | |
630 { | |
631 RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer); | |
632 if (!innerCompositor || !innerCompositor->staleInCompositingMode() || innerC
ompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame) | |
633 return false; | |
634 | |
635 RenderLayer* layer = renderer->layer(); | |
636 if (!layer->hasCompositedLayerMapping()) | |
637 return false; | |
638 | |
639 CompositedLayerMapping* compositedLayerMapping = layer->compositedLayerMappi
ng(); | |
640 GraphicsLayer* hostingLayer = compositedLayerMapping->parentForSublayers(); | |
641 GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer(); | |
642 if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != r
ootLayer) { | |
643 hostingLayer->removeAllChildren(); | |
644 hostingLayer->addChild(rootLayer); | |
645 } | |
646 return true; | |
647 } | |
648 | |
649 static void fullyInvalidatePaintRecursive(RenderLayer* layer) | |
650 { | |
651 if (layer->compositingState() == PaintsIntoOwnBacking) { | |
652 layer->compositedLayerMapping()->setContentsNeedDisplay(); | |
653 layer->compositedLayerMapping()->setSquashingContentsNeedDisplay(); | |
654 } | |
655 | |
656 for (RenderLayer* child = layer->firstChild(); child; child = child->nextSib
ling()) | |
657 fullyInvalidatePaintRecursive(child); | |
658 } | |
659 | |
660 void RenderLayerCompositor::fullyInvalidatePaint() | |
661 { | |
662 // We're walking all compositing layers and invalidating them, so there's | |
663 // no need to have up-to-date compositing state. | |
664 DisableCompositingQueryAsserts disabler; | |
665 fullyInvalidatePaintRecursive(rootRenderLayer()); | |
666 } | |
667 | |
668 RenderLayer* RenderLayerCompositor::rootRenderLayer() const | |
669 { | |
670 return m_renderView.layer(); | |
671 } | |
672 | |
673 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const | |
674 { | |
675 if (m_overflowControlsHostLayer) | |
676 return m_overflowControlsHostLayer.get(); | |
677 return m_rootContentLayer.get(); | |
678 } | |
679 | |
680 GraphicsLayer* RenderLayerCompositor::frameScrollLayer() const | |
681 { | |
682 return m_scrollLayer.get(); | |
683 } | |
684 | |
685 GraphicsLayer* RenderLayerCompositor::scrollLayer() const | |
686 { | |
687 if (ScrollableArea* scrollableArea = m_renderView.frameView()->scrollableAre
a()) | |
688 return scrollableArea->layerForScrolling(); | |
689 return nullptr; | |
690 } | |
691 | |
692 GraphicsLayer* RenderLayerCompositor::containerLayer() const | |
693 { | |
694 return m_containerLayer.get(); | |
695 } | |
696 | |
697 GraphicsLayer* RenderLayerCompositor::ensureRootTransformLayer() | |
698 { | |
699 ASSERT(rootGraphicsLayer()); | |
700 | |
701 if (!m_rootTransformLayer.get()) { | |
702 m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory(), thi
s); | |
703 m_overflowControlsHostLayer->addChild(m_rootTransformLayer.get()); | |
704 m_rootTransformLayer->addChild(m_containerLayer.get()); | |
705 updateOverflowControlsLayers(); | |
706 } | |
707 | |
708 return m_rootTransformLayer.get(); | |
709 } | |
710 | |
711 void RenderLayerCompositor::setIsInWindow(bool isInWindow) | |
712 { | |
713 if (!staleInCompositingMode()) | |
714 return; | |
715 | |
716 if (isInWindow) { | |
717 if (m_rootLayerAttachment != RootLayerUnattached) | |
718 return; | |
719 | |
720 RootLayerAttachment attachment = m_renderView.frame()->isLocalRoot() ? R
ootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame; | |
721 attachRootLayer(attachment); | |
722 } else { | |
723 if (m_rootLayerAttachment == RootLayerUnattached) | |
724 return; | |
725 | |
726 detachRootLayer(); | |
727 } | |
728 } | |
729 | |
730 void RenderLayerCompositor::updateRootLayerPosition() | |
731 { | |
732 if (m_rootContentLayer) { | |
733 const IntRect& documentRect = m_renderView.documentRect(); | |
734 m_rootContentLayer->setSize(documentRect.size()); | |
735 m_rootContentLayer->setPosition(documentRect.location()); | |
736 } | |
737 if (m_containerLayer) { | |
738 FrameView* frameView = m_renderView.frameView(); | |
739 m_containerLayer->setSize(frameView->unscaledVisibleContentSize()); | |
740 m_overflowControlsHostLayer->setSize(frameView->unscaledVisibleContentSi
ze(IncludeScrollbars)); | |
741 } | |
742 } | |
743 | |
744 void RenderLayerCompositor::updatePotentialCompositingReasonsFromStyle(RenderLay
er* layer) | |
745 { | |
746 layer->setPotentialCompositingReasonsFromStyle(m_compositingReasonFinder.pot
entialCompositingReasonsFromStyle(layer->renderer())); | |
747 } | |
748 | |
749 void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer) | |
750 { | |
751 layer->setCompositingReasons(m_compositingReasonFinder.directReasons(layer),
CompositingReasonComboAllDirectReasons); | |
752 } | |
753 | |
754 void RenderLayerCompositor::setOverlayLayer(GraphicsLayer* layer) | |
755 { | |
756 ASSERT(rootGraphicsLayer()); | |
757 | |
758 if (layer->parent() != m_overflowControlsHostLayer.get()) | |
759 m_overflowControlsHostLayer->addChild(layer); | |
760 } | |
761 | |
762 bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const | |
763 { | |
764 return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && !layer
->subtreeIsInvisible(); | |
765 } | |
766 | |
767 // Return true if the given layer is a stacking context and has compositing chil
d | |
768 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer | |
769 // into the hierarchy between this layer and its children in the z-order hierarc
hy. | |
770 bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer
) const | |
771 { | |
772 return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOver
flowClip(); | |
773 } | |
774 | |
775 // If an element has composited negative z-index children, those children render
in front of the | |
776 // layer background, so we need an extra 'contents' layer for the foreground of
the layer | |
777 // object. | |
778 bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* lay
er) const | |
779 { | |
780 if (!layer->hasCompositingDescendant()) | |
781 return false; | |
782 return layer->stackingNode()->hasNegativeZOrderList(); | |
783 } | |
784 | |
785 static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const
IntRect& clip) | |
786 { | |
787 if (!scrollbar) | |
788 return; | |
789 | |
790 // Frame scrollbars are painted in the space of the containing frame, not th
e local space of the scrollbar. | |
791 const IntPoint& paintOffset = scrollbar->frameRect().location(); | |
792 IntRect transformedClip = clip; | |
793 transformedClip.moveBy(paintOffset); | |
794 | |
795 AffineTransform translation; | |
796 translation.translate(-paintOffset.x(), -paintOffset.y()); | |
797 TransformRecorder transformRecorder(context, scrollbar->displayItemClient(),
translation); | |
798 | |
799 scrollbar->paint(&context, transformedClip); | |
800 } | |
801 | |
802 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, Gr
aphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip) | |
803 { | |
804 if (graphicsLayer == layerForHorizontalScrollbar()) | |
805 paintScrollbar(m_renderView.frameView()->horizontalScrollbar(), context,
clip); | |
806 else if (graphicsLayer == layerForVerticalScrollbar()) | |
807 paintScrollbar(m_renderView.frameView()->verticalScrollbar(), context, c
lip); | |
808 else if (graphicsLayer == layerForScrollCorner()) | |
809 FramePainter(*m_renderView.frameView()).paintScrollCorner(&context, clip
); | |
810 } | |
811 | |
812 bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const | |
813 { | |
814 if (Settings* settings = m_renderView.document().settings()) | |
815 return settings->preferCompositingToLCDTextEnabled(); | |
816 return false; | |
817 } | |
818 | |
819 bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* lay
er) const | |
820 { | |
821 if (layer != m_renderView.layer()) | |
822 return false; | |
823 | |
824 return supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgrou
ndIsEntirelyFixed(); | |
825 } | |
826 | |
827 GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const | |
828 { | |
829 // Get the fixed root background from the RenderView layer's compositedLayer
Mapping. | |
830 RenderLayer* viewLayer = m_renderView.layer(); | |
831 if (!viewLayer) | |
832 return 0; | |
833 | |
834 if (viewLayer->compositingState() == PaintsIntoOwnBacking && viewLayer->comp
ositedLayerMapping()->backgroundLayerPaintsFixedRootBackground()) | |
835 return viewLayer->compositedLayerMapping()->backgroundLayer(); | |
836 | |
837 return 0; | |
838 } | |
839 | |
840 static void resetTrackedPaintInvalidationRectsRecursive(GraphicsLayer* graphicsL
ayer) | |
841 { | |
842 if (!graphicsLayer) | |
843 return; | |
844 | |
845 graphicsLayer->resetTrackedPaintInvalidations(); | |
846 | |
847 for (size_t i = 0; i < graphicsLayer->children().size(); ++i) | |
848 resetTrackedPaintInvalidationRectsRecursive(graphicsLayer->children()[i]
); | |
849 | |
850 if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer()) | |
851 resetTrackedPaintInvalidationRectsRecursive(replicaLayer); | |
852 | |
853 if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer()) | |
854 resetTrackedPaintInvalidationRectsRecursive(maskLayer); | |
855 | |
856 if (GraphicsLayer* clippingMaskLayer = graphicsLayer->contentsClippingMaskLa
yer()) | |
857 resetTrackedPaintInvalidationRectsRecursive(clippingMaskLayer); | |
858 } | |
859 | |
860 void RenderLayerCompositor::resetTrackedPaintInvalidationRects() | |
861 { | |
862 if (GraphicsLayer* rootLayer = rootGraphicsLayer()) | |
863 resetTrackedPaintInvalidationRectsRecursive(rootLayer); | |
864 } | |
865 | |
866 void RenderLayerCompositor::setTracksPaintInvalidations(bool tracksPaintInvalida
tions) | |
867 { | |
868 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationClean); | |
869 m_isTrackingPaintInvalidations = tracksPaintInvalidations; | |
870 } | |
871 | |
872 bool RenderLayerCompositor::isTrackingPaintInvalidations() const | |
873 { | |
874 return m_isTrackingPaintInvalidations; | |
875 } | |
876 | |
877 static bool shouldCompositeOverflowControls(FrameView* view) | |
878 { | |
879 if (Page* page = view->frame().page()) { | |
880 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordina
tor()) { | |
881 if (scrollingCoordinator->coordinatesScrollingForFrameView(view)) | |
882 return true; | |
883 } | |
884 } | |
885 | |
886 return true; | |
887 } | |
888 | |
889 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const | |
890 { | |
891 FrameView* view = m_renderView.frameView(); | |
892 return shouldCompositeOverflowControls(view) && view->horizontalScrollbar(); | |
893 } | |
894 | |
895 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const | |
896 { | |
897 FrameView* view = m_renderView.frameView(); | |
898 return shouldCompositeOverflowControls(view) && view->verticalScrollbar(); | |
899 } | |
900 | |
901 bool RenderLayerCompositor::requiresScrollCornerLayer() const | |
902 { | |
903 FrameView* view = m_renderView.frameView(); | |
904 return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible(
); | |
905 } | |
906 | |
907 void RenderLayerCompositor::updateOverflowControlsLayers() | |
908 { | |
909 GraphicsLayer* controlsParent = m_rootTransformLayer.get() ? m_rootTransform
Layer.get() : m_overflowControlsHostLayer.get(); | |
910 // On Mac, main frame scrollbars should always be stuck to the sides of the
screen (in overscroll and in pinch-zoom), so | |
911 // make the parent for the scrollbars be the viewport container layer. | |
912 #if OS(MACOSX) | |
913 if (m_renderView.frame()->isMainFrame() && m_renderView.frame()->settings()-
>pinchVirtualViewportEnabled()) { | |
914 PinchViewport& pinchViewport = m_renderView.frameView()->page()->frameHo
st().pinchViewport(); | |
915 controlsParent = pinchViewport.containerLayer(); | |
916 } | |
917 #endif | |
918 | |
919 if (requiresHorizontalScrollbarLayer()) { | |
920 if (!m_layerForHorizontalScrollbar) { | |
921 m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerF
actory(), this); | |
922 } | |
923 | |
924 if (m_layerForHorizontalScrollbar->parent() != controlsParent) { | |
925 controlsParent->addChild(m_layerForHorizontalScrollbar.get()); | |
926 | |
927 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoor
dinator()) | |
928 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_re
nderView.frameView(), HorizontalScrollbar); | |
929 } | |
930 } else if (m_layerForHorizontalScrollbar) { | |
931 m_layerForHorizontalScrollbar->removeFromParent(); | |
932 m_layerForHorizontalScrollbar = nullptr; | |
933 | |
934 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordina
tor()) | |
935 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_render
View.frameView(), HorizontalScrollbar); | |
936 } | |
937 | |
938 if (requiresVerticalScrollbarLayer()) { | |
939 if (!m_layerForVerticalScrollbar) { | |
940 m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFac
tory(), this); | |
941 } | |
942 | |
943 if (m_layerForVerticalScrollbar->parent() != controlsParent) { | |
944 controlsParent->addChild(m_layerForVerticalScrollbar.get()); | |
945 | |
946 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoor
dinator()) | |
947 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_re
nderView.frameView(), VerticalScrollbar); | |
948 } | |
949 } else if (m_layerForVerticalScrollbar) { | |
950 m_layerForVerticalScrollbar->removeFromParent(); | |
951 m_layerForVerticalScrollbar = nullptr; | |
952 | |
953 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordina
tor()) | |
954 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_render
View.frameView(), VerticalScrollbar); | |
955 } | |
956 | |
957 if (requiresScrollCornerLayer()) { | |
958 if (!m_layerForScrollCorner) { | |
959 m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(
), this); | |
960 controlsParent->addChild(m_layerForScrollCorner.get()); | |
961 } | |
962 } else if (m_layerForScrollCorner) { | |
963 m_layerForScrollCorner->removeFromParent(); | |
964 m_layerForScrollCorner = nullptr; | |
965 } | |
966 | |
967 m_renderView.frameView()->positionScrollbarLayers(); | |
968 } | |
969 | |
970 void RenderLayerCompositor::ensureRootLayer() | |
971 { | |
972 RootLayerAttachment expectedAttachment = m_renderView.frame()->isLocalRoot()
? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame; | |
973 if (expectedAttachment == m_rootLayerAttachment) | |
974 return; | |
975 | |
976 Settings* settings = m_renderView.document().settings(); | |
977 if (!m_rootContentLayer) { | |
978 m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this)
; | |
979 IntRect overflowRect = m_renderView.pixelSnappedLayoutOverflowRect(); | |
980 m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.
maxY())); | |
981 m_rootContentLayer->setPosition(FloatPoint()); | |
982 m_rootContentLayer->setOwnerNodeId(InspectorNodeIds::idForNode(m_renderV
iew.generatingNode())); | |
983 | |
984 // FIXME: with rootLayerScrolls, we probably don't even need m_rootConte
ntLayer? | |
985 if (!(settings && settings->rootLayerScrolls())) { | |
986 // Need to clip to prevent transformed content showing outside this
frame | |
987 m_rootContentLayer->setMasksToBounds(true); | |
988 } | |
989 } | |
990 | |
991 if (!m_overflowControlsHostLayer) { | |
992 ASSERT(!m_scrollLayer); | |
993 ASSERT(!m_containerLayer); | |
994 | |
995 // Create a layer to host the clipping layer and the overflow controls l
ayers. | |
996 m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory
(), this); | |
997 | |
998 // Clip iframe's overflow controls layer. | |
999 bool containerMasksToBounds = !m_renderView.frame()->isLocalRoot(); | |
1000 m_overflowControlsHostLayer->setMasksToBounds(containerMasksToBounds); | |
1001 | |
1002 // Create a clipping layer if this is an iframe or settings require to c
lip. | |
1003 m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this); | |
1004 if (Settings* settings = m_renderView.document().settings()) { | |
1005 if (settings->mainFrameClipsContent()) | |
1006 containerMasksToBounds = true; | |
1007 } | |
1008 m_containerLayer->setMasksToBounds(containerMasksToBounds); | |
1009 | |
1010 m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this); | |
1011 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordina
tor()) | |
1012 scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_sc
rollLayer.get(), true); | |
1013 | |
1014 // Hook them up | |
1015 m_overflowControlsHostLayer->addChild(m_containerLayer.get()); | |
1016 m_containerLayer->addChild(m_scrollLayer.get()); | |
1017 m_scrollLayer->addChild(m_rootContentLayer.get()); | |
1018 | |
1019 frameViewDidChangeSize(); | |
1020 } | |
1021 | |
1022 // Check to see if we have to change the attachment | |
1023 if (m_rootLayerAttachment != RootLayerUnattached) | |
1024 detachRootLayer(); | |
1025 | |
1026 attachRootLayer(expectedAttachment); | |
1027 } | |
1028 | |
1029 void RenderLayerCompositor::destroyRootLayer() | |
1030 { | |
1031 if (!m_rootContentLayer) | |
1032 return; | |
1033 | |
1034 detachRootLayer(); | |
1035 | |
1036 if (m_layerForHorizontalScrollbar) { | |
1037 m_layerForHorizontalScrollbar->removeFromParent(); | |
1038 m_layerForHorizontalScrollbar = nullptr; | |
1039 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordina
tor()) | |
1040 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_render
View.frameView(), HorizontalScrollbar); | |
1041 if (Scrollbar* horizontalScrollbar = m_renderView.frameView()->verticalS
crollbar()) | |
1042 m_renderView.frameView()->invalidateScrollbar(horizontalScrollbar, I
ntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size())); | |
1043 } | |
1044 | |
1045 if (m_layerForVerticalScrollbar) { | |
1046 m_layerForVerticalScrollbar->removeFromParent(); | |
1047 m_layerForVerticalScrollbar = nullptr; | |
1048 if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordina
tor()) | |
1049 scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_render
View.frameView(), VerticalScrollbar); | |
1050 if (Scrollbar* verticalScrollbar = m_renderView.frameView()->verticalScr
ollbar()) | |
1051 m_renderView.frameView()->invalidateScrollbar(verticalScrollbar, Int
Rect(IntPoint(0, 0), verticalScrollbar->frameRect().size())); | |
1052 } | |
1053 | |
1054 if (m_layerForScrollCorner) { | |
1055 m_layerForScrollCorner = nullptr; | |
1056 m_renderView.frameView()->invalidateScrollCorner(m_renderView.frameView(
)->scrollCornerRect()); | |
1057 } | |
1058 | |
1059 if (m_overflowControlsHostLayer) { | |
1060 m_overflowControlsHostLayer = nullptr; | |
1061 m_containerLayer = nullptr; | |
1062 m_scrollLayer = nullptr; | |
1063 } | |
1064 ASSERT(!m_scrollLayer); | |
1065 m_rootContentLayer = nullptr; | |
1066 m_rootTransformLayer = nullptr; | |
1067 } | |
1068 | |
1069 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment) | |
1070 { | |
1071 if (!m_rootContentLayer) | |
1072 return; | |
1073 | |
1074 switch (attachment) { | |
1075 case RootLayerUnattached: | |
1076 ASSERT_NOT_REACHED(); | |
1077 break; | |
1078 case RootLayerAttachedViaChromeClient: { | |
1079 LocalFrame& frame = m_renderView.frameView()->frame(); | |
1080 Page* page = frame.page(); | |
1081 if (!page) | |
1082 return; | |
1083 page->chrome().client().attachRootGraphicsLayer(rootGraphicsLayer(), &fr
ame); | |
1084 break; | |
1085 } | |
1086 case RootLayerAttachedViaEnclosingFrame: { | |
1087 HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerEleme
nt(); | |
1088 ASSERT(ownerElement); | |
1089 // The layer will get hooked up via CompositedLayerMapping::updateGraphi
csLayerConfiguration() | |
1090 // for the frame's renderer in the parent document. | |
1091 ownerElement->setNeedsCompositingUpdate(); | |
1092 break; | |
1093 } | |
1094 } | |
1095 | |
1096 m_rootLayerAttachment = attachment; | |
1097 } | |
1098 | |
1099 void RenderLayerCompositor::detachRootLayer() | |
1100 { | |
1101 if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached) | |
1102 return; | |
1103 | |
1104 switch (m_rootLayerAttachment) { | |
1105 case RootLayerAttachedViaEnclosingFrame: { | |
1106 // The layer will get unhooked up via CompositedLayerMapping::updateGrap
hicsLayerConfiguration() | |
1107 // for the frame's renderer in the parent document. | |
1108 if (m_overflowControlsHostLayer) | |
1109 m_overflowControlsHostLayer->removeFromParent(); | |
1110 else | |
1111 m_rootContentLayer->removeFromParent(); | |
1112 | |
1113 if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerE
lement()) | |
1114 ownerElement->setNeedsCompositingUpdate(); | |
1115 break; | |
1116 } | |
1117 case RootLayerAttachedViaChromeClient: { | |
1118 LocalFrame& frame = m_renderView.frameView()->frame(); | |
1119 Page* page = frame.page(); | |
1120 if (!page) | |
1121 return; | |
1122 page->chrome().client().attachRootGraphicsLayer(0, &frame); | |
1123 break; | |
1124 } | |
1125 case RootLayerUnattached: | |
1126 break; | |
1127 } | |
1128 | |
1129 m_rootLayerAttachment = RootLayerUnattached; | |
1130 } | |
1131 | |
1132 void RenderLayerCompositor::updateRootLayerAttachment() | |
1133 { | |
1134 ensureRootLayer(); | |
1135 } | |
1136 | |
1137 ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const | |
1138 { | |
1139 if (Page* page = this->page()) | |
1140 return page->scrollingCoordinator(); | |
1141 | |
1142 return 0; | |
1143 } | |
1144 | |
1145 GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const | |
1146 { | |
1147 if (Page* page = this->page()) | |
1148 return page->chrome().client().graphicsLayerFactory(); | |
1149 return 0; | |
1150 } | |
1151 | |
1152 Page* RenderLayerCompositor::page() const | |
1153 { | |
1154 return m_renderView.frameView()->frame().page(); | |
1155 } | |
1156 | |
1157 DocumentLifecycle& RenderLayerCompositor::lifecycle() const | |
1158 { | |
1159 return m_renderView.document().lifecycle(); | |
1160 } | |
1161 | |
1162 String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer) | |
1163 { | |
1164 String name; | |
1165 if (graphicsLayer == m_rootContentLayer.get()) { | |
1166 name = "Content Root Layer"; | |
1167 } else if (graphicsLayer == m_rootTransformLayer.get()) { | |
1168 name = "Root Transform Layer"; | |
1169 } else if (graphicsLayer == m_overflowControlsHostLayer.get()) { | |
1170 name = "Overflow Controls Host Layer"; | |
1171 } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) { | |
1172 name = "Horizontal Scrollbar Layer"; | |
1173 } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) { | |
1174 name = "Vertical Scrollbar Layer"; | |
1175 } else if (graphicsLayer == m_layerForScrollCorner.get()) { | |
1176 name = "Scroll Corner Layer"; | |
1177 } else if (graphicsLayer == m_containerLayer.get()) { | |
1178 name = "LocalFrame Clipping Layer"; | |
1179 } else if (graphicsLayer == m_scrollLayer.get()) { | |
1180 name = "LocalFrame Scrolling Layer"; | |
1181 } else { | |
1182 ASSERT_NOT_REACHED(); | |
1183 } | |
1184 | |
1185 return name; | |
1186 } | |
1187 | |
1188 } // namespace blink | |
OLD | NEW |