| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
reserved. |
| 3 * | 3 * |
| 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
| 5 * | 5 * |
| 6 * Other contributors: | 6 * Other contributors: |
| 7 * Robert O'Callahan <roc+@cs.cmu.edu> | 7 * Robert O'Callahan <roc+@cs.cmu.edu> |
| 8 * David Baron <dbaron@fas.harvard.edu> | 8 * David Baron <dbaron@fas.harvard.edu> |
| 9 * Christian Biesinger <cbiesinger@web.de> | 9 * Christian Biesinger <cbiesinger@web.de> |
| 10 * Randall Jesup <rjesup@wgate.com> | 10 * Randall Jesup <rjesup@wgate.com> |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 * version of this file only under the terms of one of those two | 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 | 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 | 37 * version of this file under the LGPL, indicate your decision by |
| 38 * deletingthe provisions above and replace them with the notice and | 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. | 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 | 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. | 41 * version of this file under any of the LGPL, the MPL or the GPL. |
| 42 */ | 42 */ |
| 43 | 43 |
| 44 #include "config.h" | 44 #include "config.h" |
| 45 #include "core/rendering/RenderLayer.h" | 45 #include "core/layout/Layer.h" |
| 46 | 46 |
| 47 #include "core/CSSPropertyNames.h" | 47 #include "core/CSSPropertyNames.h" |
| 48 #include "core/HTMLNames.h" | 48 #include "core/HTMLNames.h" |
| 49 #include "core/css/PseudoStyleRequest.h" | 49 #include "core/css/PseudoStyleRequest.h" |
| 50 #include "core/dom/Document.h" | 50 #include "core/dom/Document.h" |
| 51 #include "core/dom/shadow/ShadowRoot.h" | 51 #include "core/dom/shadow/ShadowRoot.h" |
| 52 #include "core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h" | 52 #include "core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h" |
| 53 #include "core/frame/FrameView.h" | 53 #include "core/frame/FrameView.h" |
| 54 #include "core/frame/LocalFrame.h" | 54 #include "core/frame/LocalFrame.h" |
| 55 #include "core/html/HTMLFrameElement.h" | 55 #include "core/html/HTMLFrameElement.h" |
| 56 #include "core/layout/HitTestRequest.h" | 56 #include "core/layout/HitTestRequest.h" |
| 57 #include "core/layout/HitTestResult.h" | 57 #include "core/layout/HitTestResult.h" |
| 58 #include "core/layout/HitTestingTransformState.h" | 58 #include "core/layout/HitTestingTransformState.h" |
| 59 #include "core/layout/LayoutTreeAsText.h" | 59 #include "core/layout/LayoutTreeAsText.h" |
| 60 #include "core/layout/compositing/CompositedLayerMapping.h" | 60 #include "core/layout/compositing/CompositedLayerMapping.h" |
| 61 #include "core/layout/compositing/RenderLayerCompositor.h" | 61 #include "core/layout/compositing/LayerCompositor.h" |
| 62 #include "core/page/Page.h" | 62 #include "core/page/Page.h" |
| 63 #include "core/page/scrolling/ScrollingCoordinator.h" | 63 #include "core/page/scrolling/ScrollingCoordinator.h" |
| 64 #include "core/rendering/ColumnInfo.h" | 64 #include "core/rendering/ColumnInfo.h" |
| 65 #include "core/rendering/FilterEffectRenderer.h" | 65 #include "core/rendering/FilterEffectRenderer.h" |
| 66 #include "core/rendering/RenderFlowThread.h" | 66 #include "core/rendering/RenderFlowThread.h" |
| 67 #include "core/rendering/RenderGeometryMap.h" | 67 #include "core/rendering/RenderGeometryMap.h" |
| 68 #include "core/rendering/RenderInline.h" | 68 #include "core/rendering/RenderInline.h" |
| 69 #include "core/rendering/RenderPart.h" | 69 #include "core/rendering/RenderPart.h" |
| 70 #include "core/rendering/RenderReplica.h" | 70 #include "core/rendering/RenderReplica.h" |
| 71 #include "core/rendering/RenderScrollbar.h" | 71 #include "core/rendering/RenderScrollbar.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 93 | 93 |
| 94 namespace { | 94 namespace { |
| 95 | 95 |
| 96 static CompositingQueryMode gCompositingQueryMode = | 96 static CompositingQueryMode gCompositingQueryMode = |
| 97 CompositingQueriesAreOnlyAllowedInCertainDocumentLifecyclePhases; | 97 CompositingQueriesAreOnlyAllowedInCertainDocumentLifecyclePhases; |
| 98 | 98 |
| 99 } // namespace | 99 } // namespace |
| 100 | 100 |
| 101 using namespace HTMLNames; | 101 using namespace HTMLNames; |
| 102 | 102 |
| 103 RenderLayer::RenderLayer(RenderLayerModelObject* renderer, LayerType type) | 103 Layer::Layer(LayoutLayerModelObject* renderer, LayerType type) |
| 104 : m_layerType(type) | 104 : m_layerType(type) |
| 105 , m_hasSelfPaintingLayerDescendant(false) | 105 , m_hasSelfPaintingLayerDescendant(false) |
| 106 , m_hasSelfPaintingLayerDescendantDirty(false) | 106 , m_hasSelfPaintingLayerDescendantDirty(false) |
| 107 , m_isRootLayer(renderer->isRenderView()) | 107 , m_isRootLayer(renderer->isRenderView()) |
| 108 , m_visibleContentStatusDirty(true) | 108 , m_visibleContentStatusDirty(true) |
| 109 , m_hasVisibleContent(false) | 109 , m_hasVisibleContent(false) |
| 110 , m_visibleDescendantStatusDirty(false) | 110 , m_visibleDescendantStatusDirty(false) |
| 111 , m_hasVisibleDescendant(false) | 111 , m_hasVisibleDescendant(false) |
| 112 , m_hasVisibleNonLayerContent(false) | 112 , m_hasVisibleNonLayerContent(false) |
| 113 , m_isPaginated(false) | 113 , m_isPaginated(false) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 144 m_isSelfPaintingLayer = shouldBeSelfPaintingLayer(); | 144 m_isSelfPaintingLayer = shouldBeSelfPaintingLayer(); |
| 145 | 145 |
| 146 if (!renderer->slowFirstChild() && renderer->style()) { | 146 if (!renderer->slowFirstChild() && renderer->style()) { |
| 147 m_visibleContentStatusDirty = false; | 147 m_visibleContentStatusDirty = false; |
| 148 m_hasVisibleContent = renderer->style()->visibility() == VISIBLE; | 148 m_hasVisibleContent = renderer->style()->visibility() == VISIBLE; |
| 149 } | 149 } |
| 150 | 150 |
| 151 updateScrollableArea(); | 151 updateScrollableArea(); |
| 152 } | 152 } |
| 153 | 153 |
| 154 RenderLayer::~RenderLayer() | 154 Layer::~Layer() |
| 155 { | 155 { |
| 156 if (renderer()->frame() && renderer()->frame()->page()) { | 156 if (renderer()->frame() && renderer()->frame()->page()) { |
| 157 if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->pa
ge()->scrollingCoordinator()) | 157 if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->pa
ge()->scrollingCoordinator()) |
| 158 scrollingCoordinator->willDestroyRenderLayer(this); | 158 scrollingCoordinator->willDestroyLayer(this); |
| 159 } | 159 } |
| 160 | 160 |
| 161 removeFilterInfoIfNeeded(); | 161 removeFilterInfoIfNeeded(); |
| 162 | 162 |
| 163 if (groupedMapping()) { | 163 if (groupedMapping()) { |
| 164 DisableCompositingQueryAsserts disabler; | 164 DisableCompositingQueryAsserts disabler; |
| 165 groupedMapping()->removeRenderLayerFromSquashingGraphicsLayer(this); | 165 groupedMapping()->removeLayerFromSquashingGraphicsLayer(this); |
| 166 setGroupedMapping(0); | 166 setGroupedMapping(0); |
| 167 } | 167 } |
| 168 | 168 |
| 169 // Child layers will be deleted by their corresponding render objects, so | 169 // Child layers will be deleted by their corresponding render objects, so |
| 170 // we don't need to delete them ourselves. | 170 // we don't need to delete them ourselves. |
| 171 | 171 |
| 172 clearCompositedLayerMapping(true); | 172 clearCompositedLayerMapping(true); |
| 173 | 173 |
| 174 if (m_reflectionInfo) | 174 if (m_reflectionInfo) |
| 175 m_reflectionInfo->destroy(); | 175 m_reflectionInfo->destroy(); |
| 176 } | 176 } |
| 177 | 177 |
| 178 String RenderLayer::debugName() const | 178 String Layer::debugName() const |
| 179 { | 179 { |
| 180 if (isReflection()) { | 180 if (isReflection()) { |
| 181 return renderer()->parent()->debugName() + " (reflection)"; | 181 return renderer()->parent()->debugName() + " (reflection)"; |
| 182 } | 182 } |
| 183 return renderer()->debugName(); | 183 return renderer()->debugName(); |
| 184 } | 184 } |
| 185 | 185 |
| 186 RenderLayerCompositor* RenderLayer::compositor() const | 186 LayerCompositor* Layer::compositor() const |
| 187 { | 187 { |
| 188 if (!renderer()->view()) | 188 if (!renderer()->view()) |
| 189 return 0; | 189 return 0; |
| 190 return renderer()->view()->compositor(); | 190 return renderer()->view()->compositor(); |
| 191 } | 191 } |
| 192 | 192 |
| 193 void RenderLayer::contentChanged(ContentChangeType changeType) | 193 void Layer::contentChanged(ContentChangeType changeType) |
| 194 { | 194 { |
| 195 // updateLayerCompositingState will query compositingReasons for accelerated
overflow scrolling. | 195 // updateLayerCompositingState will query compositingReasons for accelerated
overflow scrolling. |
| 196 // This is tripped by LayoutTests/compositing/content-changed-chicken-egg.ht
ml | 196 // This is tripped by LayoutTests/compositing/content-changed-chicken-egg.ht
ml |
| 197 DisableCompositingQueryAsserts disabler; | 197 DisableCompositingQueryAsserts disabler; |
| 198 | 198 |
| 199 if (changeType == CanvasChanged) | 199 if (changeType == CanvasChanged) |
| 200 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositin
gInputChange); | 200 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositin
gInputChange); |
| 201 | 201 |
| 202 if (changeType == CanvasContextChanged) { | 202 if (changeType == CanvasContextChanged) { |
| 203 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositin
gInputChange); | 203 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositin
gInputChange); |
| 204 | 204 |
| 205 // Although we're missing test coverage, we need to call | 205 // Although we're missing test coverage, we need to call |
| 206 // GraphicsLayer::setContentsToPlatformLayer with the new platform | 206 // GraphicsLayer::setContentsToPlatformLayer with the new platform |
| 207 // layer for this canvas. | 207 // layer for this canvas. |
| 208 // See http://crbug.com/349195 | 208 // See http://crbug.com/349195 |
| 209 if (hasCompositedLayerMapping()) | 209 if (hasCompositedLayerMapping()) |
| 210 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerU
pdateSubtree); | 210 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerU
pdateSubtree); |
| 211 } | 211 } |
| 212 | 212 |
| 213 if (m_compositedLayerMapping) | 213 if (m_compositedLayerMapping) |
| 214 m_compositedLayerMapping->contentChanged(changeType); | 214 m_compositedLayerMapping->contentChanged(changeType); |
| 215 } | 215 } |
| 216 | 216 |
| 217 bool RenderLayer::paintsWithFilters() const | 217 bool Layer::paintsWithFilters() const |
| 218 { | 218 { |
| 219 if (!renderer()->hasFilter()) | 219 if (!renderer()->hasFilter()) |
| 220 return false; | 220 return false; |
| 221 | 221 |
| 222 // https://code.google.com/p/chromium/issues/detail?id=343759 | 222 // https://code.google.com/p/chromium/issues/detail?id=343759 |
| 223 DisableCompositingQueryAsserts disabler; | 223 DisableCompositingQueryAsserts disabler; |
| 224 return !m_compositedLayerMapping || compositingState() != PaintsIntoOwnBacki
ng; | 224 return !m_compositedLayerMapping || compositingState() != PaintsIntoOwnBacki
ng; |
| 225 } | 225 } |
| 226 | 226 |
| 227 LayoutSize RenderLayer::subpixelAccumulation() const | 227 LayoutSize Layer::subpixelAccumulation() const |
| 228 { | 228 { |
| 229 return m_subpixelAccumulation; | 229 return m_subpixelAccumulation; |
| 230 } | 230 } |
| 231 | 231 |
| 232 void RenderLayer::setSubpixelAccumulation(const LayoutSize& size) | 232 void Layer::setSubpixelAccumulation(const LayoutSize& size) |
| 233 { | 233 { |
| 234 m_subpixelAccumulation = size; | 234 m_subpixelAccumulation = size; |
| 235 } | 235 } |
| 236 | 236 |
| 237 void RenderLayer::updateLayerPositionsAfterLayout() | 237 void Layer::updateLayerPositionsAfterLayout() |
| 238 { | 238 { |
| 239 TRACE_EVENT0("blink,benchmark", "RenderLayer::updateLayerPositionsAfterLayou
t"); | 239 TRACE_EVENT0("blink,benchmark", "Layer::updateLayerPositionsAfterLayout"); |
| 240 | 240 |
| 241 m_clipper.clearClipRectsIncludingDescendants(); | 241 m_clipper.clearClipRectsIncludingDescendants(); |
| 242 updateLayerPositionRecursive(); | 242 updateLayerPositionRecursive(); |
| 243 | 243 |
| 244 { | 244 { |
| 245 // FIXME: Remove incremental compositing updates after fixing the chicke
n/egg issues | 245 // FIXME: Remove incremental compositing updates after fixing the chicke
n/egg issues |
| 246 // https://code.google.com/p/chromium/issues/detail?id=343756 | 246 // https://code.google.com/p/chromium/issues/detail?id=343756 |
| 247 DisableCompositingQueryAsserts disabler; | 247 DisableCompositingQueryAsserts disabler; |
| 248 bool needsPaginationUpdate = isPaginated() || enclosingPaginationLayer()
; | 248 bool needsPaginationUpdate = isPaginated() || enclosingPaginationLayer()
; |
| 249 updatePaginationRecursive(needsPaginationUpdate); | 249 updatePaginationRecursive(needsPaginationUpdate); |
| 250 } | 250 } |
| 251 } | 251 } |
| 252 | 252 |
| 253 void RenderLayer::updateLayerPositionRecursive() | 253 void Layer::updateLayerPositionRecursive() |
| 254 { | 254 { |
| 255 updateLayerPosition(); | 255 updateLayerPosition(); |
| 256 | 256 |
| 257 if (m_reflectionInfo) | 257 if (m_reflectionInfo) |
| 258 m_reflectionInfo->reflection()->layout(); | 258 m_reflectionInfo->reflection()->layout(); |
| 259 | 259 |
| 260 // FIXME: We should be able to remove this call because we don't care about | 260 // FIXME: We should be able to remove this call because we don't care about |
| 261 // any descendant-dependent flags, but code somewhere else is reading these | 261 // any descendant-dependent flags, but code somewhere else is reading these |
| 262 // flags and depending on us to update them. | 262 // flags and depending on us to update them. |
| 263 updateDescendantDependentFlags(); | 263 updateDescendantDependentFlags(); |
| 264 | 264 |
| 265 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) | 265 for (Layer* child = firstChild(); child; child = child->nextSibling()) |
| 266 child->updateLayerPositionRecursive(); | 266 child->updateLayerPositionRecursive(); |
| 267 } | 267 } |
| 268 | 268 |
| 269 void RenderLayer::updateHasSelfPaintingLayerDescendant() const | 269 void Layer::updateHasSelfPaintingLayerDescendant() const |
| 270 { | 270 { |
| 271 ASSERT(m_hasSelfPaintingLayerDescendantDirty); | 271 ASSERT(m_hasSelfPaintingLayerDescendantDirty); |
| 272 | 272 |
| 273 m_hasSelfPaintingLayerDescendant = false; | 273 m_hasSelfPaintingLayerDescendant = false; |
| 274 | 274 |
| 275 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
{ | 275 for (Layer* child = firstChild(); child; child = child->nextSibling()) { |
| 276 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendan
t()) { | 276 if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendan
t()) { |
| 277 m_hasSelfPaintingLayerDescendant = true; | 277 m_hasSelfPaintingLayerDescendant = true; |
| 278 break; | 278 break; |
| 279 } | 279 } |
| 280 } | 280 } |
| 281 | 281 |
| 282 m_hasSelfPaintingLayerDescendantDirty = false; | 282 m_hasSelfPaintingLayerDescendantDirty = false; |
| 283 } | 283 } |
| 284 | 284 |
| 285 void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus() | 285 void Layer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus() |
| 286 { | 286 { |
| 287 for (RenderLayer* layer = this; layer; layer = layer->parent()) { | 287 for (Layer* layer = this; layer; layer = layer->parent()) { |
| 288 layer->m_hasSelfPaintingLayerDescendantDirty = true; | 288 layer->m_hasSelfPaintingLayerDescendantDirty = true; |
| 289 // If we have reached a self-painting layer, we know our parent should h
ave a self-painting descendant | 289 // If we have reached a self-painting layer, we know our parent should h
ave a self-painting descendant |
| 290 // in this case, there is no need to dirty our ancestors further. | 290 // in this case, there is no need to dirty our ancestors further. |
| 291 if (layer->isSelfPaintingLayer()) { | 291 if (layer->isSelfPaintingLayer()) { |
| 292 ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty
|| parent()->m_hasSelfPaintingLayerDescendant); | 292 ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty
|| parent()->m_hasSelfPaintingLayerDescendant); |
| 293 break; | 293 break; |
| 294 } | 294 } |
| 295 } | 295 } |
| 296 } | 296 } |
| 297 | 297 |
| 298 bool RenderLayer::scrollsWithViewport() const | 298 bool Layer::scrollsWithViewport() const |
| 299 { | 299 { |
| 300 return renderer()->style()->position() == FixedPosition && renderer()->conta
inerForFixedPosition() == renderer()->view(); | 300 return renderer()->style()->position() == FixedPosition && renderer()->conta
inerForFixedPosition() == renderer()->view(); |
| 301 } | 301 } |
| 302 | 302 |
| 303 bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const | 303 bool Layer::scrollsWithRespectTo(const Layer* other) const |
| 304 { | 304 { |
| 305 if (scrollsWithViewport() != other->scrollsWithViewport()) | 305 if (scrollsWithViewport() != other->scrollsWithViewport()) |
| 306 return true; | 306 return true; |
| 307 return ancestorScrollingLayer() != other->ancestorScrollingLayer(); | 307 return ancestorScrollingLayer() != other->ancestorScrollingLayer(); |
| 308 } | 308 } |
| 309 | 309 |
| 310 void RenderLayer::updateLayerPositionsAfterOverflowScroll() | 310 void Layer::updateLayerPositionsAfterOverflowScroll() |
| 311 { | 311 { |
| 312 m_clipper.clearClipRectsIncludingDescendants(); | 312 m_clipper.clearClipRectsIncludingDescendants(); |
| 313 updateLayerPositionsAfterScrollRecursive(); | 313 updateLayerPositionsAfterScrollRecursive(); |
| 314 } | 314 } |
| 315 | 315 |
| 316 void RenderLayer::updateLayerPositionsAfterScrollRecursive() | 316 void Layer::updateLayerPositionsAfterScrollRecursive() |
| 317 { | 317 { |
| 318 if (updateLayerPosition()) | 318 if (updateLayerPosition()) |
| 319 m_renderer->setPreviousPaintInvalidationRect(m_renderer->boundsRectForPa
intInvalidation(m_renderer->containerForPaintInvalidation())); | 319 m_renderer->setPreviousPaintInvalidationRect(m_renderer->boundsRectForPa
intInvalidation(m_renderer->containerForPaintInvalidation())); |
| 320 | 320 |
| 321 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) | 321 for (Layer* child = firstChild(); child; child = child->nextSibling()) |
| 322 child->updateLayerPositionsAfterScrollRecursive(); | 322 child->updateLayerPositionsAfterScrollRecursive(); |
| 323 } | 323 } |
| 324 | 324 |
| 325 void RenderLayer::updateTransformationMatrix() | 325 void Layer::updateTransformationMatrix() |
| 326 { | 326 { |
| 327 if (m_transform) { | 327 if (m_transform) { |
| 328 RenderBox* box = renderBox(); | 328 RenderBox* box = renderBox(); |
| 329 ASSERT(box); | 329 ASSERT(box); |
| 330 m_transform->makeIdentity(); | 330 m_transform->makeIdentity(); |
| 331 box->style()->applyTransform(*m_transform, LayoutSize(box->pixelSnappedS
ize()), RenderStyle::IncludeTransformOrigin); | 331 box->style()->applyTransform(*m_transform, LayoutSize(box->pixelSnappedS
ize()), RenderStyle::IncludeTransformOrigin); |
| 332 makeMatrixRenderable(*m_transform, compositor()->hasAcceleratedCompositi
ng()); | 332 makeMatrixRenderable(*m_transform, compositor()->hasAcceleratedCompositi
ng()); |
| 333 } | 333 } |
| 334 } | 334 } |
| 335 | 335 |
| 336 void RenderLayer::updateTransform(const RenderStyle* oldStyle, RenderStyle* newS
tyle) | 336 void Layer::updateTransform(const RenderStyle* oldStyle, RenderStyle* newStyle) |
| 337 { | 337 { |
| 338 if (oldStyle && newStyle->transformDataEquivalent(*oldStyle)) | 338 if (oldStyle && newStyle->transformDataEquivalent(*oldStyle)) |
| 339 return; | 339 return; |
| 340 | 340 |
| 341 // hasTransform() on the renderer is also true when there is transform-style
: preserve-3d or perspective set, | 341 // hasTransform() on the renderer is also true when there is transform-style
: preserve-3d or perspective set, |
| 342 // so check style too. | 342 // so check style too. |
| 343 bool hasTransform = renderer()->hasTransformRelatedProperty() && newStyle->h
asTransform(); | 343 bool hasTransform = renderer()->hasTransformRelatedProperty() && newStyle->h
asTransform(); |
| 344 bool had3DTransform = has3DTransform(); | 344 bool had3DTransform = has3DTransform(); |
| 345 | 345 |
| 346 bool hadTransform = m_transform; | 346 bool hadTransform = m_transform; |
| 347 if (hasTransform != hadTransform) { | 347 if (hasTransform != hadTransform) { |
| 348 if (hasTransform) | 348 if (hasTransform) |
| 349 m_transform = adoptPtr(new TransformationMatrix); | 349 m_transform = adoptPtr(new TransformationMatrix); |
| 350 else | 350 else |
| 351 m_transform.clear(); | 351 m_transform.clear(); |
| 352 | 352 |
| 353 // Layers with transforms act as clip rects roots, so clear the cached c
lip rects here. | 353 // Layers with transforms act as clip rects roots, so clear the cached c
lip rects here. |
| 354 m_clipper.clearClipRectsIncludingDescendants(); | 354 m_clipper.clearClipRectsIncludingDescendants(); |
| 355 } else if (hasTransform) { | 355 } else if (hasTransform) { |
| 356 m_clipper.clearClipRectsIncludingDescendants(AbsoluteClipRects); | 356 m_clipper.clearClipRectsIncludingDescendants(AbsoluteClipRects); |
| 357 } | 357 } |
| 358 | 358 |
| 359 updateTransformationMatrix(); | 359 updateTransformationMatrix(); |
| 360 | 360 |
| 361 if (had3DTransform != has3DTransform()) | 361 if (had3DTransform != has3DTransform()) |
| 362 dirty3DTransformedDescendantStatus(); | 362 dirty3DTransformedDescendantStatus(); |
| 363 } | 363 } |
| 364 | 364 |
| 365 static RenderLayer* enclosingLayerForContainingBlock(RenderLayer* layer) | 365 static Layer* enclosingLayerForContainingBlock(Layer* layer) |
| 366 { | 366 { |
| 367 if (RenderObject* containingBlock = layer->renderer()->containingBlock()) | 367 if (RenderObject* containingBlock = layer->renderer()->containingBlock()) |
| 368 return containingBlock->enclosingLayer(); | 368 return containingBlock->enclosingLayer(); |
| 369 return 0; | 369 return 0; |
| 370 } | 370 } |
| 371 | 371 |
| 372 RenderLayer* RenderLayer::renderingContextRoot() | 372 Layer* Layer::renderingContextRoot() |
| 373 { | 373 { |
| 374 RenderLayer* renderingContext = 0; | 374 Layer* renderingContext = 0; |
| 375 | 375 |
| 376 if (shouldPreserve3D()) | 376 if (shouldPreserve3D()) |
| 377 renderingContext = this; | 377 renderingContext = this; |
| 378 | 378 |
| 379 for (RenderLayer* current = enclosingLayerForContainingBlock(this); current
&& current->shouldPreserve3D(); current = enclosingLayerForContainingBlock(curre
nt)) | 379 for (Layer* current = enclosingLayerForContainingBlock(this); current && cur
rent->shouldPreserve3D(); current = enclosingLayerForContainingBlock(current)) |
| 380 renderingContext = current; | 380 renderingContext = current; |
| 381 | 381 |
| 382 return renderingContext; | 382 return renderingContext; |
| 383 } | 383 } |
| 384 | 384 |
| 385 TransformationMatrix RenderLayer::currentTransform(RenderStyle::ApplyTransformOr
igin applyOrigin) const | 385 TransformationMatrix Layer::currentTransform(RenderStyle::ApplyTransformOrigin a
pplyOrigin) const |
| 386 { | 386 { |
| 387 if (!m_transform) | 387 if (!m_transform) |
| 388 return TransformationMatrix(); | 388 return TransformationMatrix(); |
| 389 | 389 |
| 390 // m_transform includes transform-origin, so we need to recompute the transf
orm here. | 390 // m_transform includes transform-origin, so we need to recompute the transf
orm here. |
| 391 if (applyOrigin == RenderStyle::ExcludeTransformOrigin) { | 391 if (applyOrigin == RenderStyle::ExcludeTransformOrigin) { |
| 392 RenderBox* box = renderBox(); | 392 RenderBox* box = renderBox(); |
| 393 TransformationMatrix currTransform; | 393 TransformationMatrix currTransform; |
| 394 box->style()->applyTransform(currTransform, LayoutSize(box->pixelSnapped
Size()), RenderStyle::ExcludeTransformOrigin); | 394 box->style()->applyTransform(currTransform, LayoutSize(box->pixelSnapped
Size()), RenderStyle::ExcludeTransformOrigin); |
| 395 makeMatrixRenderable(currTransform, compositor()->hasAcceleratedComposit
ing()); | 395 makeMatrixRenderable(currTransform, compositor()->hasAcceleratedComposit
ing()); |
| 396 return currTransform; | 396 return currTransform; |
| 397 } | 397 } |
| 398 | 398 |
| 399 return *m_transform; | 399 return *m_transform; |
| 400 } | 400 } |
| 401 | 401 |
| 402 TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavio
r) const | 402 TransformationMatrix Layer::renderableTransform(PaintBehavior paintBehavior) con
st |
| 403 { | 403 { |
| 404 if (!m_transform) | 404 if (!m_transform) |
| 405 return TransformationMatrix(); | 405 return TransformationMatrix(); |
| 406 | 406 |
| 407 if (paintBehavior & PaintBehaviorFlattenCompositingLayers) { | 407 if (paintBehavior & PaintBehaviorFlattenCompositingLayers) { |
| 408 TransformationMatrix matrix = *m_transform; | 408 TransformationMatrix matrix = *m_transform; |
| 409 makeMatrixRenderable(matrix, false /* flatten 3d */); | 409 makeMatrixRenderable(matrix, false /* flatten 3d */); |
| 410 return matrix; | 410 return matrix; |
| 411 } | 411 } |
| 412 | 412 |
| 413 return *m_transform; | 413 return *m_transform; |
| 414 } | 414 } |
| 415 | 415 |
| 416 static bool checkContainingBlockChainForPagination(RenderLayerModelObject* rende
rer, RenderBox* ancestorColumnsRenderer) | 416 static bool checkContainingBlockChainForPagination(LayoutLayerModelObject* rende
rer, RenderBox* ancestorColumnsRenderer) |
| 417 { | 417 { |
| 418 RenderView* view = renderer->view(); | 418 RenderView* view = renderer->view(); |
| 419 RenderLayerModelObject* prevBlock = renderer; | 419 LayoutLayerModelObject* prevBlock = renderer; |
| 420 RenderBlock* containingBlock; | 420 RenderBlock* containingBlock; |
| 421 for (containingBlock = renderer->containingBlock(); | 421 for (containingBlock = renderer->containingBlock(); |
| 422 containingBlock && containingBlock != view && containingBlock != ancest
orColumnsRenderer; | 422 containingBlock && containingBlock != view && containingBlock != ancesto
rColumnsRenderer; |
| 423 containingBlock = containingBlock->containingBlock()) | 423 containingBlock = containingBlock->containingBlock()) |
| 424 prevBlock = containingBlock; | 424 prevBlock = containingBlock; |
| 425 | 425 |
| 426 // If the columns block wasn't in our containing block chain, then we aren't
paginated by it. | 426 // If the columns block wasn't in our containing block chain, then we aren't
paginated by it. |
| 427 if (containingBlock != ancestorColumnsRenderer) | 427 if (containingBlock != ancestorColumnsRenderer) |
| 428 return false; | 428 return false; |
| 429 | 429 |
| 430 // If the previous block is absolutely positioned, then we can't be paginate
d by the columns block. | 430 // If the previous block is absolutely positioned, then we can't be paginate
d by the columns block. |
| 431 if (prevBlock->isOutOfFlowPositioned()) | 431 if (prevBlock->isOutOfFlowPositioned()) |
| 432 return false; | 432 return false; |
| 433 | 433 |
| 434 // Otherwise we are paginated by the columns block. | 434 // Otherwise we are paginated by the columns block. |
| 435 return true; | 435 return true; |
| 436 } | 436 } |
| 437 | 437 |
| 438 // Convert a bounding box from flow thread coordinates, relative to |layer|, to
visual coordinates, relative to |ancestorLayer|. | 438 // Convert a bounding box from flow thread coordinates, relative to |layer|, to
visual coordinates, relative to |ancestorLayer|. |
| 439 // See http://www.chromium.org/developers/design-documents/multi-column-layout f
or more info on these coordinate types. | 439 // See http://www.chromium.org/developers/design-documents/multi-column-layout f
or more info on these coordinate types. |
| 440 static void convertFromFlowThreadToVisualBoundingBoxInAncestor(const RenderLayer
* layer, const RenderLayer* ancestorLayer, LayoutRect& rect) | 440 static void convertFromFlowThreadToVisualBoundingBoxInAncestor(const Layer* laye
r, const Layer* ancestorLayer, LayoutRect& rect) |
| 441 { | 441 { |
| 442 RenderLayer* paginationLayer = layer->enclosingPaginationLayer(); | 442 Layer* paginationLayer = layer->enclosingPaginationLayer(); |
| 443 ASSERT(paginationLayer); | 443 ASSERT(paginationLayer); |
| 444 RenderFlowThread* flowThread = toRenderFlowThread(paginationLayer->renderer(
)); | 444 RenderFlowThread* flowThread = toRenderFlowThread(paginationLayer->renderer(
)); |
| 445 | 445 |
| 446 // First make the flow thread rectangle relative to the flow thread, not to
|layer|. | 446 // First make the flow thread rectangle relative to the flow thread, not to
|layer|. |
| 447 LayoutPoint offsetWithinPaginationLayer; | 447 LayoutPoint offsetWithinPaginationLayer; |
| 448 layer->convertToLayerCoords(paginationLayer, offsetWithinPaginationLayer); | 448 layer->convertToLayerCoords(paginationLayer, offsetWithinPaginationLayer); |
| 449 rect.moveBy(offsetWithinPaginationLayer); | 449 rect.moveBy(offsetWithinPaginationLayer); |
| 450 | 450 |
| 451 // Then make the rectangle visual, relative to the fragmentation context. Sp
lit our box up into | 451 // Then make the rectangle visual, relative to the fragmentation context. Sp
lit our box up into |
| 452 // the actual fragment boxes that render in the columns/pages and unite thos
e together to get | 452 // the actual fragment boxes that render in the columns/pages and unite thos
e together to get |
| 453 // our true bounding box. | 453 // our true bounding box. |
| 454 rect = flowThread->fragmentsBoundingBox(rect); | 454 rect = flowThread->fragmentsBoundingBox(rect); |
| 455 | 455 |
| 456 // Finally, make the visual rectangle relative to |ancestorLayer|. | 456 // Finally, make the visual rectangle relative to |ancestorLayer|. |
| 457 if (ancestorLayer->enclosingPaginationLayer() != paginationLayer) { | 457 if (ancestorLayer->enclosingPaginationLayer() != paginationLayer) { |
| 458 rect.moveBy(paginationLayer->visualOffsetFromAncestor(ancestorLayer)); | 458 rect.moveBy(paginationLayer->visualOffsetFromAncestor(ancestorLayer)); |
| 459 return; | 459 return; |
| 460 } | 460 } |
| 461 // The ancestor layer is inside the same pagination layer as |layer|, so we
need to subtract | 461 // The ancestor layer is inside the same pagination layer as |layer|, so we
need to subtract |
| 462 // the visual distance from the ancestor layer to the pagination layer. | 462 // the visual distance from the ancestor layer to the pagination layer. |
| 463 rect.moveBy(-ancestorLayer->visualOffsetFromAncestor(paginationLayer)); | 463 rect.moveBy(-ancestorLayer->visualOffsetFromAncestor(paginationLayer)); |
| 464 } | 464 } |
| 465 | 465 |
| 466 bool RenderLayer::useRegionBasedColumns() const | 466 bool Layer::useRegionBasedColumns() const |
| 467 { | 467 { |
| 468 return renderer()->document().regionBasedColumnsEnabled(); | 468 return renderer()->document().regionBasedColumnsEnabled(); |
| 469 } | 469 } |
| 470 | 470 |
| 471 void RenderLayer::updatePaginationRecursive(bool needsPaginationUpdate) | 471 void Layer::updatePaginationRecursive(bool needsPaginationUpdate) |
| 472 { | 472 { |
| 473 m_isPaginated = false; | 473 m_isPaginated = false; |
| 474 m_enclosingPaginationLayer = 0; | 474 m_enclosingPaginationLayer = 0; |
| 475 | 475 |
| 476 if (useRegionBasedColumns() && renderer()->isRenderFlowThread()) | 476 if (useRegionBasedColumns() && renderer()->isRenderFlowThread()) |
| 477 needsPaginationUpdate = true; | 477 needsPaginationUpdate = true; |
| 478 | 478 |
| 479 if (needsPaginationUpdate) | 479 if (needsPaginationUpdate) |
| 480 updatePagination(); | 480 updatePagination(); |
| 481 | 481 |
| 482 if (renderer()->hasColumns()) | 482 if (renderer()->hasColumns()) |
| 483 needsPaginationUpdate = true; | 483 needsPaginationUpdate = true; |
| 484 | 484 |
| 485 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) | 485 for (Layer* child = firstChild(); child; child = child->nextSibling()) |
| 486 child->updatePaginationRecursive(needsPaginationUpdate); | 486 child->updatePaginationRecursive(needsPaginationUpdate); |
| 487 } | 487 } |
| 488 | 488 |
| 489 void RenderLayer::updatePagination() | 489 void Layer::updatePagination() |
| 490 { | 490 { |
| 491 bool usesRegionBasedColumns = useRegionBasedColumns(); | 491 bool usesRegionBasedColumns = useRegionBasedColumns(); |
| 492 if ((!usesRegionBasedColumns && compositingState() != NotComposited) || !par
ent()) | 492 if ((!usesRegionBasedColumns && compositingState() != NotComposited) || !par
ent()) |
| 493 return; // FIXME: For now the RenderView can't be paginated. Eventually
printing will move to a model where it is though. | 493 return; // FIXME: For now the RenderView can't be paginated. Eventually
printing will move to a model where it is though. |
| 494 | 494 |
| 495 // The main difference between the paginated booleans for the old column cod
e and the new column code | 495 // The main difference between the paginated booleans for the old column cod
e and the new column code |
| 496 // is that each paginated layer has to paint on its own with the new code. T
here is no | 496 // is that each paginated layer has to paint on its own with the new code. T
here is no |
| 497 // recurring into child layers. This means that the m_isPaginated bits for t
he new column code can't just be set on | 497 // recurring into child layers. This means that the m_isPaginated bits for t
he new column code can't just be set on |
| 498 // "roots" that get split and paint all their descendants. Instead each laye
r has to be checked individually and | 498 // "roots" that get split and paint all their descendants. Instead each laye
r has to be checked individually and |
| 499 // genuinely know if it is going to have to split itself up when painting on
ly its contents (and not any other descendant | 499 // genuinely know if it is going to have to split itself up when painting on
ly its contents (and not any other descendant |
| (...skipping 17 matching lines...) Expand all Loading... |
| 517 } | 517 } |
| 518 return; | 518 return; |
| 519 } | 519 } |
| 520 | 520 |
| 521 // For the new columns code, we want to walk up our containing block chain l
ooking for an enclosing layer. Once | 521 // For the new columns code, we want to walk up our containing block chain l
ooking for an enclosing layer. Once |
| 522 // we find one, then we just check its pagination status. | 522 // we find one, then we just check its pagination status. |
| 523 if (usesRegionBasedColumns) { | 523 if (usesRegionBasedColumns) { |
| 524 RenderView* view = renderer()->view(); | 524 RenderView* view = renderer()->view(); |
| 525 RenderBlock* containingBlock; | 525 RenderBlock* containingBlock; |
| 526 for (containingBlock = renderer()->containingBlock(); | 526 for (containingBlock = renderer()->containingBlock(); |
| 527 containingBlock && containingBlock != view; | 527 containingBlock && containingBlock != view; |
| 528 containingBlock = containingBlock->containingBlock()) { | 528 containingBlock = containingBlock->containingBlock()) { |
| 529 if (containingBlock->hasLayer()) { | 529 if (containingBlock->hasLayer()) { |
| 530 // Content inside a transform is not considered to be paginated,
since we simply | 530 // Content inside a transform is not considered to be paginated,
since we simply |
| 531 // paint the transform multiple times in each column, so we don'
t have to use | 531 // paint the transform multiple times in each column, so we don'
t have to use |
| 532 // fragments for the transformed content. | 532 // fragments for the transformed content. |
| 533 m_enclosingPaginationLayer = containingBlock->layer()->enclosing
PaginationLayer(); | 533 m_enclosingPaginationLayer = containingBlock->layer()->enclosing
PaginationLayer(); |
| 534 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->ha
sTransformRelatedProperty()) | 534 if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->ha
sTransformRelatedProperty()) |
| 535 m_enclosingPaginationLayer = 0; | 535 m_enclosingPaginationLayer = 0; |
| 536 return; | 536 return; |
| 537 } | 537 } |
| 538 } | 538 } |
| 539 return; | 539 return; |
| 540 } | 540 } |
| 541 | 541 |
| 542 // If we're not normal flow, then we need to look for a multi-column object
between us and our stacking container. | 542 // If we're not normal flow, then we need to look for a multi-column object
between us and our stacking container. |
| 543 RenderLayerStackingNode* ancestorStackingContextNode = m_stackingNode->ances
torStackingContextNode(); | 543 LayerStackingNode* ancestorStackingContextNode = m_stackingNode->ancestorSta
ckingContextNode(); |
| 544 for (RenderLayer* curr = parent(); curr; curr = curr->parent()) { | 544 for (Layer* curr = parent(); curr; curr = curr->parent()) { |
| 545 if (curr->renderer()->hasColumns()) { | 545 if (curr->renderer()->hasColumns()) { |
| 546 m_isPaginated = checkContainingBlockChainForPagination(renderer(), c
urr->renderBox()); | 546 m_isPaginated = checkContainingBlockChainForPagination(renderer(), c
urr->renderBox()); |
| 547 return; | 547 return; |
| 548 } | 548 } |
| 549 if (curr->stackingNode() == ancestorStackingContextNode) | 549 if (curr->stackingNode() == ancestorStackingContextNode) |
| 550 return; | 550 return; |
| 551 } | 551 } |
| 552 } | 552 } |
| 553 | 553 |
| 554 void RenderLayer::clearPaginationRecursive() | 554 void Layer::clearPaginationRecursive() |
| 555 { | 555 { |
| 556 m_enclosingPaginationLayer = 0; | 556 m_enclosingPaginationLayer = 0; |
| 557 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) | 557 for (Layer* child = firstChild(); child; child = child->nextSibling()) |
| 558 child->clearPaginationRecursive(); | 558 child->clearPaginationRecursive(); |
| 559 } | 559 } |
| 560 | 560 |
| 561 LayoutPoint RenderLayer::positionFromPaintInvalidationBacking(const RenderObject
* renderObject, const RenderLayerModelObject* paintInvalidationContainer, const
PaintInvalidationState* paintInvalidationState) | 561 LayoutPoint Layer::positionFromPaintInvalidationBacking(const RenderObject* rend
erObject, const LayoutLayerModelObject* paintInvalidationContainer, const PaintI
nvalidationState* paintInvalidationState) |
| 562 { | 562 { |
| 563 FloatPoint point = renderObject->localToContainerPoint(FloatPoint(), paintIn
validationContainer, 0, 0, paintInvalidationState); | 563 FloatPoint point = renderObject->localToContainerPoint(FloatPoint(), paintIn
validationContainer, 0, 0, paintInvalidationState); |
| 564 | 564 |
| 565 // FIXME: Eventually we are going to unify coordinates in GraphicsLayer spac
e. | 565 // FIXME: Eventually we are going to unify coordinates in GraphicsLayer spac
e. |
| 566 if (paintInvalidationContainer && paintInvalidationContainer->layer()->group
edMapping()) | 566 if (paintInvalidationContainer && paintInvalidationContainer->layer()->group
edMapping()) |
| 567 mapPointToPaintBackingCoordinates(paintInvalidationContainer, point); | 567 mapPointToPaintBackingCoordinates(paintInvalidationContainer, point); |
| 568 | 568 |
| 569 return LayoutPoint(point); | 569 return LayoutPoint(point); |
| 570 } | 570 } |
| 571 | 571 |
| 572 void RenderLayer::mapPointToPaintBackingCoordinates(const RenderLayerModelObject
* paintInvalidationContainer, FloatPoint& point) | 572 void Layer::mapPointToPaintBackingCoordinates(const LayoutLayerModelObject* pain
tInvalidationContainer, FloatPoint& point) |
| 573 { | 573 { |
| 574 RenderLayer* paintInvalidationLayer = paintInvalidationContainer->layer(); | 574 Layer* paintInvalidationLayer = paintInvalidationContainer->layer(); |
| 575 if (!paintInvalidationLayer->groupedMapping()) { | 575 if (!paintInvalidationLayer->groupedMapping()) { |
| 576 point.move(paintInvalidationLayer->compositedLayerMapping()->contentOffs
etInCompositingLayer()); | 576 point.move(paintInvalidationLayer->compositedLayerMapping()->contentOffs
etInCompositingLayer()); |
| 577 return; | 577 return; |
| 578 } | 578 } |
| 579 | 579 |
| 580 RenderLayerModelObject* transformedAncestor = paintInvalidationLayer->enclos
ingTransformedAncestor()->renderer(); | 580 LayoutLayerModelObject* transformedAncestor = paintInvalidationLayer->enclos
ingTransformedAncestor()->renderer(); |
| 581 if (!transformedAncestor) | 581 if (!transformedAncestor) |
| 582 return; | 582 return; |
| 583 | 583 |
| 584 // |paintInvalidationContainer| may have a local 2D transform on it, so take
that into account when mapping into the space of the | 584 // |paintInvalidationContainer| may have a local 2D transform on it, so take
that into account when mapping into the space of the |
| 585 // transformed ancestor. | 585 // transformed ancestor. |
| 586 point = paintInvalidationContainer->localToContainerPoint(point, transformed
Ancestor); | 586 point = paintInvalidationContainer->localToContainerPoint(point, transformed
Ancestor); |
| 587 | 587 |
| 588 point.moveBy(-paintInvalidationLayer->groupedMapping()->squashingOffsetFromT
ransformedAncestor()); | 588 point.moveBy(-paintInvalidationLayer->groupedMapping()->squashingOffsetFromT
ransformedAncestor()); |
| 589 } | 589 } |
| 590 | 590 |
| 591 void RenderLayer::mapRectToPaintBackingCoordinates(const RenderLayerModelObject*
paintInvalidationContainer, LayoutRect& rect) | 591 void Layer::mapRectToPaintBackingCoordinates(const LayoutLayerModelObject* paint
InvalidationContainer, LayoutRect& rect) |
| 592 { | 592 { |
| 593 RenderLayer* paintInvalidationLayer = paintInvalidationContainer->layer(); | 593 Layer* paintInvalidationLayer = paintInvalidationContainer->layer(); |
| 594 if (!paintInvalidationLayer->groupedMapping()) { | 594 if (!paintInvalidationLayer->groupedMapping()) { |
| 595 rect.move(paintInvalidationLayer->compositedLayerMapping()->contentOffse
tInCompositingLayer()); | 595 rect.move(paintInvalidationLayer->compositedLayerMapping()->contentOffse
tInCompositingLayer()); |
| 596 return; | 596 return; |
| 597 } | 597 } |
| 598 | 598 |
| 599 RenderLayerModelObject* transformedAncestor = paintInvalidationLayer->enclos
ingTransformedAncestor()->renderer(); | 599 LayoutLayerModelObject* transformedAncestor = paintInvalidationLayer->enclos
ingTransformedAncestor()->renderer(); |
| 600 if (!transformedAncestor) | 600 if (!transformedAncestor) |
| 601 return; | 601 return; |
| 602 | 602 |
| 603 // |paintInvalidationContainer| may have a local 2D transform on it, so take
that into account when mapping into the space of the | 603 // |paintInvalidationContainer| may have a local 2D transform on it, so take
that into account when mapping into the space of the |
| 604 // transformed ancestor. | 604 // transformed ancestor. |
| 605 rect = LayoutRect(paintInvalidationContainer->localToContainerQuad(FloatRect
(rect), transformedAncestor).boundingBox()); | 605 rect = LayoutRect(paintInvalidationContainer->localToContainerQuad(FloatRect
(rect), transformedAncestor).boundingBox()); |
| 606 | 606 |
| 607 rect.moveBy(-paintInvalidationLayer->groupedMapping()->squashingOffsetFromTr
ansformedAncestor()); | 607 rect.moveBy(-paintInvalidationLayer->groupedMapping()->squashingOffsetFromTr
ansformedAncestor()); |
| 608 } | 608 } |
| 609 | 609 |
| 610 void RenderLayer::mapRectToPaintInvalidationBacking(const RenderObject* renderOb
ject, const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect
, const PaintInvalidationState* paintInvalidationState) | 610 void Layer::mapRectToPaintInvalidationBacking(const RenderObject* renderObject,
const LayoutLayerModelObject* paintInvalidationContainer, LayoutRect& rect, cons
t PaintInvalidationState* paintInvalidationState) |
| 611 { | 611 { |
| 612 if (!paintInvalidationContainer->layer()->groupedMapping()) { | 612 if (!paintInvalidationContainer->layer()->groupedMapping()) { |
| 613 renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContain
er, rect, paintInvalidationState); | 613 renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContain
er, rect, paintInvalidationState); |
| 614 return; | 614 return; |
| 615 } | 615 } |
| 616 | 616 |
| 617 // This code adjusts the paint invalidation rectangle to be in the space of
the transformed ancestor of the grouped (i.e. squashed) | 617 // This code adjusts the paint invalidation rectangle to be in the space of
the transformed ancestor of the grouped (i.e. squashed) |
| 618 // layer. This is because all layers that squash together need to issue pain
t invalidations w.r.t. a single container that is | 618 // layer. This is because all layers that squash together need to issue pain
t invalidations w.r.t. a single container that is |
| 619 // an ancestor of all of them, in order to properly take into account any lo
cal transforms etc. | 619 // an ancestor of all of them, in order to properly take into account any lo
cal transforms etc. |
| 620 // FIXME: remove this special-case code that works around the paint invalida
tion code structure. | 620 // FIXME: remove this special-case code that works around the paint invalida
tion code structure. |
| 621 renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContainer,
rect, paintInvalidationState); | 621 renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContainer,
rect, paintInvalidationState); |
| 622 | 622 |
| 623 mapRectToPaintBackingCoordinates(paintInvalidationContainer, rect); | 623 mapRectToPaintBackingCoordinates(paintInvalidationContainer, rect); |
| 624 } | 624 } |
| 625 | 625 |
| 626 LayoutRect RenderLayer::computePaintInvalidationRect(const RenderObject* renderO
bject, const RenderLayer* paintInvalidationContainer, const PaintInvalidationSta
te* paintInvalidationState) | 626 LayoutRect Layer::computePaintInvalidationRect(const RenderObject* renderObject,
const Layer* paintInvalidationContainer, const PaintInvalidationState* paintInv
alidationState) |
| 627 { | 627 { |
| 628 if (!paintInvalidationContainer->groupedMapping()) | 628 if (!paintInvalidationContainer->groupedMapping()) |
| 629 return renderObject->computePaintInvalidationRect(paintInvalidationConta
iner->renderer(), paintInvalidationState); | 629 return renderObject->computePaintInvalidationRect(paintInvalidationConta
iner->renderer(), paintInvalidationState); |
| 630 | 630 |
| 631 LayoutRect rect = renderObject->clippedOverflowRectForPaintInvalidation(pain
tInvalidationContainer->renderer(), paintInvalidationState); | 631 LayoutRect rect = renderObject->clippedOverflowRectForPaintInvalidation(pain
tInvalidationContainer->renderer(), paintInvalidationState); |
| 632 mapRectToPaintBackingCoordinates(paintInvalidationContainer->renderer(), rec
t); | 632 mapRectToPaintBackingCoordinates(paintInvalidationContainer->renderer(), rec
t); |
| 633 return rect; | 633 return rect; |
| 634 } | 634 } |
| 635 | 635 |
| 636 void RenderLayer::dirtyVisibleContentStatus() | 636 void Layer::dirtyVisibleContentStatus() |
| 637 { | 637 { |
| 638 m_visibleContentStatusDirty = true; | 638 m_visibleContentStatusDirty = true; |
| 639 if (parent()) | 639 if (parent()) |
| 640 parent()->dirtyAncestorChainVisibleDescendantStatus(); | 640 parent()->dirtyAncestorChainVisibleDescendantStatus(); |
| 641 } | 641 } |
| 642 | 642 |
| 643 void RenderLayer::potentiallyDirtyVisibleContentStatus(EVisibility visibility) | 643 void Layer::potentiallyDirtyVisibleContentStatus(EVisibility visibility) |
| 644 { | 644 { |
| 645 if (m_visibleContentStatusDirty) | 645 if (m_visibleContentStatusDirty) |
| 646 return; | 646 return; |
| 647 if (hasVisibleContent() == (visibility == VISIBLE)) | 647 if (hasVisibleContent() == (visibility == VISIBLE)) |
| 648 return; | 648 return; |
| 649 dirtyVisibleContentStatus(); | 649 dirtyVisibleContentStatus(); |
| 650 } | 650 } |
| 651 | 651 |
| 652 void RenderLayer::dirtyAncestorChainVisibleDescendantStatus() | 652 void Layer::dirtyAncestorChainVisibleDescendantStatus() |
| 653 { | 653 { |
| 654 for (RenderLayer* layer = this; layer; layer = layer->parent()) { | 654 for (Layer* layer = this; layer; layer = layer->parent()) { |
| 655 if (layer->m_visibleDescendantStatusDirty) | 655 if (layer->m_visibleDescendantStatusDirty) |
| 656 break; | 656 break; |
| 657 | 657 |
| 658 layer->m_visibleDescendantStatusDirty = true; | 658 layer->m_visibleDescendantStatusDirty = true; |
| 659 } | 659 } |
| 660 } | 660 } |
| 661 | 661 |
| 662 // FIXME: this is quite brute-force. We could be more efficient if we were to | 662 // FIXME: this is quite brute-force. We could be more efficient if we were to |
| 663 // track state and update it as appropriate as changes are made in the Render tr
ee. | 663 // track state and update it as appropriate as changes are made in the Render tr
ee. |
| 664 void RenderLayer::updateScrollingStateAfterCompositingChange() | 664 void Layer::updateScrollingStateAfterCompositingChange() |
| 665 { | 665 { |
| 666 TRACE_EVENT0("blink", "RenderLayer::updateScrollingStateAfterCompositingChan
ge"); | 666 TRACE_EVENT0("blink", "Layer::updateScrollingStateAfterCompositingChange"); |
| 667 m_hasVisibleNonLayerContent = false; | 667 m_hasVisibleNonLayerContent = false; |
| 668 for (RenderObject* r = renderer()->slowFirstChild(); r; r = r->nextSibling()
) { | 668 for (RenderObject* r = renderer()->slowFirstChild(); r; r = r->nextSibling()
) { |
| 669 if (!r->hasLayer()) { | 669 if (!r->hasLayer()) { |
| 670 m_hasVisibleNonLayerContent = true; | 670 m_hasVisibleNonLayerContent = true; |
| 671 break; | 671 break; |
| 672 } | 672 } |
| 673 } | 673 } |
| 674 | 674 |
| 675 m_hasNonCompositedChild = false; | 675 m_hasNonCompositedChild = false; |
| 676 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
{ | 676 for (Layer* child = firstChild(); child; child = child->nextSibling()) { |
| 677 if (child->compositingState() == NotComposited) { | 677 if (child->compositingState() == NotComposited) { |
| 678 m_hasNonCompositedChild = true; | 678 m_hasNonCompositedChild = true; |
| 679 return; | 679 return; |
| 680 } | 680 } |
| 681 } | 681 } |
| 682 } | 682 } |
| 683 | 683 |
| 684 // The descendant-dependent flags system is badly broken because we clean dirty | 684 // The descendant-dependent flags system is badly broken because we clean dirty |
| 685 // bits in upward tree walks, which means we need to call updateDescendantDepend
entFlags | 685 // bits in upward tree walks, which means we need to call updateDescendantDepend
entFlags |
| 686 // at every node in the tree to fully clean all the dirty bits. While we'll in | 686 // at every node in the tree to fully clean all the dirty bits. While we'll in |
| 687 // the process of fixing this issue, updateDescendantDependentFlagsForEntireSubt
ree | 687 // the process of fixing this issue, updateDescendantDependentFlagsForEntireSubt
ree |
| 688 // provides a big hammer for actually cleaning all the dirty bits in a subtree. | 688 // provides a big hammer for actually cleaning all the dirty bits in a subtree. |
| 689 // | 689 // |
| 690 // FIXME: Remove this function once the descendant-dependent flags system keeps | 690 // FIXME: Remove this function once the descendant-dependent flags system keeps |
| 691 // its dirty bits scoped to subtrees. | 691 // its dirty bits scoped to subtrees. |
| 692 void RenderLayer::updateDescendantDependentFlagsForEntireSubtree() | 692 void Layer::updateDescendantDependentFlagsForEntireSubtree() |
| 693 { | 693 { |
| 694 updateDescendantDependentFlags(); | 694 updateDescendantDependentFlags(); |
| 695 | 695 |
| 696 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) | 696 for (Layer* child = firstChild(); child; child = child->nextSibling()) |
| 697 child->updateDescendantDependentFlagsForEntireSubtree(); | 697 child->updateDescendantDependentFlagsForEntireSubtree(); |
| 698 } | 698 } |
| 699 | 699 |
| 700 void RenderLayer::updateDescendantDependentFlags() | 700 void Layer::updateDescendantDependentFlags() |
| 701 { | 701 { |
| 702 if (m_visibleDescendantStatusDirty) { | 702 if (m_visibleDescendantStatusDirty) { |
| 703 m_hasVisibleDescendant = false; | 703 m_hasVisibleDescendant = false; |
| 704 | 704 |
| 705 for (RenderLayer* child = firstChild(); child; child = child->nextSiblin
g()) { | 705 for (Layer* child = firstChild(); child; child = child->nextSibling()) { |
| 706 child->updateDescendantDependentFlags(); | 706 child->updateDescendantDependentFlags(); |
| 707 | 707 |
| 708 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) { | 708 if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) { |
| 709 m_hasVisibleDescendant = true; | 709 m_hasVisibleDescendant = true; |
| 710 break; | 710 break; |
| 711 } | 711 } |
| 712 } | 712 } |
| 713 | 713 |
| 714 m_visibleDescendantStatusDirty = false; | 714 m_visibleDescendantStatusDirty = false; |
| 715 } | 715 } |
| 716 | 716 |
| 717 if (m_visibleContentStatusDirty) { | 717 if (m_visibleContentStatusDirty) { |
| 718 bool previouslyHasVisibleContent = m_hasVisibleContent; | 718 bool previouslyHasVisibleContent = m_hasVisibleContent; |
| 719 if (renderer()->style()->visibility() == VISIBLE) | 719 if (renderer()->style()->visibility() == VISIBLE) { |
| 720 m_hasVisibleContent = true; | 720 m_hasVisibleContent = true; |
| 721 else { | 721 } else { |
| 722 // layer may be hidden but still have some visible content, check fo
r this | 722 // layer may be hidden but still have some visible content, check fo
r this |
| 723 m_hasVisibleContent = false; | 723 m_hasVisibleContent = false; |
| 724 RenderObject* r = renderer()->slowFirstChild(); | 724 RenderObject* r = renderer()->slowFirstChild(); |
| 725 while (r) { | 725 while (r) { |
| 726 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) { | 726 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) { |
| 727 m_hasVisibleContent = true; | 727 m_hasVisibleContent = true; |
| 728 break; | 728 break; |
| 729 } | 729 } |
| 730 RenderObject* rendererFirstChild = r->slowFirstChild(); | 730 RenderObject* rendererFirstChild = r->slowFirstChild(); |
| 731 if (rendererFirstChild && !r->hasLayer()) | 731 if (rendererFirstChild && !r->hasLayer()) { |
| 732 r = rendererFirstChild; | 732 r = rendererFirstChild; |
| 733 else if (r->nextSibling()) | 733 } else if (r->nextSibling()) { |
| 734 r = r->nextSibling(); | 734 r = r->nextSibling(); |
| 735 else { | 735 } else { |
| 736 do { | 736 do { |
| 737 r = r->parent(); | 737 r = r->parent(); |
| 738 if (r == renderer()) | 738 if (r == renderer()) |
| 739 r = 0; | 739 r = 0; |
| 740 } while (r && !r->nextSibling()); | 740 } while (r && !r->nextSibling()); |
| 741 if (r) | 741 if (r) |
| 742 r = r->nextSibling(); | 742 r = r->nextSibling(); |
| 743 } | 743 } |
| 744 } | 744 } |
| 745 } | 745 } |
| 746 m_visibleContentStatusDirty = false; | 746 m_visibleContentStatusDirty = false; |
| 747 | 747 |
| 748 if (hasVisibleContent() != previouslyHasVisibleContent) { | 748 if (hasVisibleContent() != previouslyHasVisibleContent) { |
| 749 setNeedsCompositingInputsUpdate(); | 749 setNeedsCompositingInputsUpdate(); |
| 750 // We need to tell m_renderer to recheck its rect because we | 750 // We need to tell m_renderer to recheck its rect because we |
| 751 // pretend that invisible RenderObjects have 0x0 rects. Changing | 751 // pretend that invisible RenderObjects have 0x0 rects. Changing |
| 752 // visibility therefore changes our rect and we need to visit | 752 // visibility therefore changes our rect and we need to visit |
| 753 // this RenderObject during the invalidateTreeIfNeeded walk. | 753 // this RenderObject during the invalidateTreeIfNeeded walk. |
| 754 m_renderer->setMayNeedPaintInvalidation(); | 754 m_renderer->setMayNeedPaintInvalidation(); |
| 755 } | 755 } |
| 756 } | 756 } |
| 757 } | 757 } |
| 758 | 758 |
| 759 void RenderLayer::dirty3DTransformedDescendantStatus() | 759 void Layer::dirty3DTransformedDescendantStatus() |
| 760 { | 760 { |
| 761 RenderLayerStackingNode* stackingNode = m_stackingNode->ancestorStackingCont
extNode(); | 761 LayerStackingNode* stackingNode = m_stackingNode->ancestorStackingContextNod
e(); |
| 762 if (!stackingNode) | 762 if (!stackingNode) |
| 763 return; | 763 return; |
| 764 | 764 |
| 765 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true; | 765 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true; |
| 766 | 766 |
| 767 // This propagates up through preserve-3d hierarchies to the enclosing flatt
ening layer. | 767 // This propagates up through preserve-3d hierarchies to the enclosing flatt
ening layer. |
| 768 // Note that preserves3D() creates stacking context, so we can just run up t
he stacking containers. | 768 // Note that preserves3D() creates stacking context, so we can just run up t
he stacking containers. |
| 769 while (stackingNode && stackingNode->layer()->preserves3D()) { | 769 while (stackingNode && stackingNode->layer()->preserves3D()) { |
| 770 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true; | 770 stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true; |
| 771 stackingNode = stackingNode->ancestorStackingContextNode(); | 771 stackingNode = stackingNode->ancestorStackingContextNode(); |
| 772 } | 772 } |
| 773 } | 773 } |
| 774 | 774 |
| 775 // Return true if this layer or any preserve-3d descendants have 3d. | 775 // Return true if this layer or any preserve-3d descendants have 3d. |
| 776 bool RenderLayer::update3DTransformedDescendantStatus() | 776 bool Layer::update3DTransformedDescendantStatus() |
| 777 { | 777 { |
| 778 if (m_3DTransformedDescendantStatusDirty) { | 778 if (m_3DTransformedDescendantStatusDirty) { |
| 779 m_has3DTransformedDescendant = false; | 779 m_has3DTransformedDescendant = false; |
| 780 | 780 |
| 781 m_stackingNode->updateZOrderLists(); | 781 m_stackingNode->updateZOrderLists(); |
| 782 | 782 |
| 783 // Transformed or preserve-3d descendants can only be in the z-order lis
ts, not | 783 // Transformed or preserve-3d descendants can only be in the z-order lis
ts, not |
| 784 // in the normal flow list, so we only need to check those. | 784 // in the normal flow list, so we only need to check those. |
| 785 RenderLayerStackingNodeIterator iterator(*m_stackingNode.get(), Positive
ZOrderChildren | NegativeZOrderChildren); | 785 LayerStackingNodeIterator iterator(*m_stackingNode.get(), PositiveZOrder
Children | NegativeZOrderChildren); |
| 786 while (RenderLayerStackingNode* node = iterator.next()) | 786 while (LayerStackingNode* node = iterator.next()) |
| 787 m_has3DTransformedDescendant |= node->layer()->update3DTransformedDe
scendantStatus(); | 787 m_has3DTransformedDescendant |= node->layer()->update3DTransformedDe
scendantStatus(); |
| 788 | 788 |
| 789 m_3DTransformedDescendantStatusDirty = false; | 789 m_3DTransformedDescendantStatusDirty = false; |
| 790 } | 790 } |
| 791 | 791 |
| 792 // If we live in a 3d hierarchy, then the layer at the root of that hierarch
y needs | 792 // If we live in a 3d hierarchy, then the layer at the root of that hierarch
y needs |
| 793 // the m_has3DTransformedDescendant set. | 793 // the m_has3DTransformedDescendant set. |
| 794 if (preserves3D()) | 794 if (preserves3D()) |
| 795 return has3DTransform() || m_has3DTransformedDescendant; | 795 return has3DTransform() || m_has3DTransformedDescendant; |
| 796 | 796 |
| 797 return has3DTransform(); | 797 return has3DTransform(); |
| 798 } | 798 } |
| 799 | 799 |
| 800 bool RenderLayer::updateLayerPosition() | 800 bool Layer::updateLayerPosition() |
| 801 { | 801 { |
| 802 LayoutPoint localPoint; | 802 LayoutPoint localPoint; |
| 803 LayoutPoint inlineBoundingBoxOffset; // We don't put this into the RenderLay
er x/y for inlines, so we need to subtract it out when done. | 803 LayoutPoint inlineBoundingBoxOffset; // We don't put this into the Layer x/y
for inlines, so we need to subtract it out when done. |
| 804 | 804 |
| 805 if (renderer()->isInline() && renderer()->isRenderInline()) { | 805 if (renderer()->isInline() && renderer()->isRenderInline()) { |
| 806 RenderInline* inlineFlow = toRenderInline(renderer()); | 806 RenderInline* inlineFlow = toRenderInline(renderer()); |
| 807 IntRect lineBox = inlineFlow->linesBoundingBox(); | 807 IntRect lineBox = inlineFlow->linesBoundingBox(); |
| 808 m_size = lineBox.size(); | 808 m_size = lineBox.size(); |
| 809 inlineBoundingBoxOffset = lineBox.location(); | 809 inlineBoundingBoxOffset = lineBox.location(); |
| 810 localPoint.moveBy(inlineBoundingBoxOffset); | 810 localPoint.moveBy(inlineBoundingBoxOffset); |
| 811 } else if (RenderBox* box = renderBox()) { | 811 } else if (RenderBox* box = renderBox()) { |
| 812 m_size = pixelSnappedIntSize(box->size(), box->location()); | 812 m_size = pixelSnappedIntSize(box->size(), box->location()); |
| 813 localPoint.moveBy(box->topLeftLocation()); | 813 localPoint.moveBy(box->topLeftLocation()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 826 curr = curr->parent(); | 826 curr = curr->parent(); |
| 827 } | 827 } |
| 828 if (curr->isBox() && curr->isTableRow()) { | 828 if (curr->isBox() && curr->isTableRow()) { |
| 829 // Put ourselves into the row coordinate space. | 829 // Put ourselves into the row coordinate space. |
| 830 localPoint.moveBy(-toRenderBox(curr)->topLeftLocation()); | 830 localPoint.moveBy(-toRenderBox(curr)->topLeftLocation()); |
| 831 } | 831 } |
| 832 } | 832 } |
| 833 | 833 |
| 834 // Subtract our parent's scroll offset. | 834 // Subtract our parent's scroll offset. |
| 835 if (renderer()->isOutOfFlowPositioned() && enclosingPositionedAncestor()) { | 835 if (renderer()->isOutOfFlowPositioned() && enclosingPositionedAncestor()) { |
| 836 RenderLayer* positionedParent = enclosingPositionedAncestor(); | 836 Layer* positionedParent = enclosingPositionedAncestor(); |
| 837 | 837 |
| 838 // For positioned layers, we subtract out the enclosing positioned layer
's scroll offset. | 838 // For positioned layers, we subtract out the enclosing positioned layer
's scroll offset. |
| 839 if (positionedParent->renderer()->hasOverflowClip()) { | 839 if (positionedParent->renderer()->hasOverflowClip()) { |
| 840 IntSize offset = positionedParent->renderBox()->scrolledContentOffse
t(); | 840 IntSize offset = positionedParent->renderBox()->scrolledContentOffse
t(); |
| 841 localPoint -= offset; | 841 localPoint -= offset; |
| 842 } | 842 } |
| 843 | 843 |
| 844 if (positionedParent->renderer()->isRelPositioned() && positionedParent-
>renderer()->isRenderInline()) { | 844 if (positionedParent->renderer()->isRelPositioned() && positionedParent-
>renderer()->isRenderInline()) { |
| 845 LayoutSize offset = toRenderInline(positionedParent->renderer())->of
fsetForInFlowPositionedInline(*toRenderBox(renderer())); | 845 LayoutSize offset = toRenderInline(positionedParent->renderer())->of
fsetForInFlowPositionedInline(*toRenderBox(renderer())); |
| 846 localPoint += offset; | 846 localPoint += offset; |
| 847 } | 847 } |
| 848 } else if (parent()) { | 848 } else if (parent()) { |
| 849 // FIXME: This code is very wrong, but luckily only needed in the old/cu
rrent multicol | 849 // FIXME: This code is very wrong, but luckily only needed in the old/cu
rrent multicol |
| 850 // implementation. The compositing system doesn't understand columns and
we're hacking | 850 // implementation. The compositing system doesn't understand columns and
we're hacking |
| 851 // around that fact by faking the position of the RenderLayers when we t
hink we'll end up | 851 // around that fact by faking the position of the Layers when we think w
e'll end up |
| 852 // being composited. | 852 // being composited. |
| 853 if (hasStyleDeterminedDirectCompositingReasons() && !useRegionBasedColum
ns()) { | 853 if (hasStyleDeterminedDirectCompositingReasons() && !useRegionBasedColum
ns()) { |
| 854 // FIXME: Composited layers ignore pagination, so about the best we
can do is make sure they're offset into the appropriate column. | 854 // FIXME: Composited layers ignore pagination, so about the best we
can do is make sure they're offset into the appropriate column. |
| 855 // They won't split across columns properly. | 855 // They won't split across columns properly. |
| 856 if (!parent()->renderer()->hasColumns() && parent()->renderer()->isD
ocumentElement() && renderer()->view()->hasColumns()) | 856 if (!parent()->renderer()->hasColumns() && parent()->renderer()->isD
ocumentElement() && renderer()->view()->hasColumns()) |
| 857 localPoint += renderer()->view()->columnOffset(localPoint); | 857 localPoint += renderer()->view()->columnOffset(localPoint); |
| 858 else | 858 else |
| 859 localPoint += parent()->renderer()->columnOffset(localPoint); | 859 localPoint += parent()->renderer()->columnOffset(localPoint); |
| 860 } | 860 } |
| 861 | 861 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 881 if (m_location != localPoint) | 881 if (m_location != localPoint) |
| 882 positionOrOffsetChanged = true; | 882 positionOrOffsetChanged = true; |
| 883 m_location = localPoint; | 883 m_location = localPoint; |
| 884 | 884 |
| 885 #if ENABLE(ASSERT) | 885 #if ENABLE(ASSERT) |
| 886 m_needsPositionUpdate = false; | 886 m_needsPositionUpdate = false; |
| 887 #endif | 887 #endif |
| 888 return positionOrOffsetChanged; | 888 return positionOrOffsetChanged; |
| 889 } | 889 } |
| 890 | 890 |
| 891 TransformationMatrix RenderLayer::perspectiveTransform() const | 891 TransformationMatrix Layer::perspectiveTransform() const |
| 892 { | 892 { |
| 893 if (!renderer()->hasTransformRelatedProperty()) | 893 if (!renderer()->hasTransformRelatedProperty()) |
| 894 return TransformationMatrix(); | 894 return TransformationMatrix(); |
| 895 | 895 |
| 896 RenderStyle* style = renderer()->style(); | 896 RenderStyle* style = renderer()->style(); |
| 897 if (!style->hasPerspective()) | 897 if (!style->hasPerspective()) |
| 898 return TransformationMatrix(); | 898 return TransformationMatrix(); |
| 899 | 899 |
| 900 // Maybe fetch the perspective from the backing? | 900 // Maybe fetch the perspective from the backing? |
| 901 const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect
(); | 901 const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect
(); |
| 902 const float boxWidth = borderBox.width(); | 902 const float boxWidth = borderBox.width(); |
| 903 const float boxHeight = borderBox.height(); | 903 const float boxHeight = borderBox.height(); |
| 904 | 904 |
| 905 float perspectiveOriginX = floatValueForLength(style->perspectiveOriginX(),
boxWidth); | 905 float perspectiveOriginX = floatValueForLength(style->perspectiveOriginX(),
boxWidth); |
| 906 float perspectiveOriginY = floatValueForLength(style->perspectiveOriginY(),
boxHeight); | 906 float perspectiveOriginY = floatValueForLength(style->perspectiveOriginY(),
boxHeight); |
| 907 | 907 |
| 908 // A perspective origin of 0,0 makes the vanishing point in the center of th
e element. | 908 // A perspective origin of 0,0 makes the vanishing point in the center of th
e element. |
| 909 // We want it to be in the top-left, so subtract half the height and width. | 909 // We want it to be in the top-left, so subtract half the height and width. |
| 910 perspectiveOriginX -= boxWidth / 2.0f; | 910 perspectiveOriginX -= boxWidth / 2.0f; |
| 911 perspectiveOriginY -= boxHeight / 2.0f; | 911 perspectiveOriginY -= boxHeight / 2.0f; |
| 912 | 912 |
| 913 TransformationMatrix t; | 913 TransformationMatrix t; |
| 914 t.translate(perspectiveOriginX, perspectiveOriginY); | 914 t.translate(perspectiveOriginX, perspectiveOriginY); |
| 915 t.applyPerspective(style->perspective()); | 915 t.applyPerspective(style->perspective()); |
| 916 t.translate(-perspectiveOriginX, -perspectiveOriginY); | 916 t.translate(-perspectiveOriginX, -perspectiveOriginY); |
| 917 | 917 |
| 918 return t; | 918 return t; |
| 919 } | 919 } |
| 920 | 920 |
| 921 FloatPoint RenderLayer::perspectiveOrigin() const | 921 FloatPoint Layer::perspectiveOrigin() const |
| 922 { | 922 { |
| 923 if (!renderer()->hasTransformRelatedProperty()) | 923 if (!renderer()->hasTransformRelatedProperty()) |
| 924 return FloatPoint(); | 924 return FloatPoint(); |
| 925 | 925 |
| 926 const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect(); | 926 const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect(); |
| 927 RenderStyle* style = renderer()->style(); | 927 RenderStyle* style = renderer()->style(); |
| 928 | 928 |
| 929 return FloatPoint(floatValueForLength(style->perspectiveOriginX(), borderBox
.width().toFloat()), floatValueForLength(style->perspectiveOriginY(), borderBox.
height().toFloat())); | 929 return FloatPoint(floatValueForLength(style->perspectiveOriginX(), borderBox
.width().toFloat()), floatValueForLength(style->perspectiveOriginY(), borderBox.
height().toFloat())); |
| 930 } | 930 } |
| 931 | 931 |
| 932 static inline bool isFixedPositionedContainer(RenderLayer* layer) | 932 static inline bool isFixedPositionedContainer(Layer* layer) |
| 933 { | 933 { |
| 934 return layer->isRootLayer() || layer->hasTransformRelatedProperty(); | 934 return layer->isRootLayer() || layer->hasTransformRelatedProperty(); |
| 935 } | 935 } |
| 936 | 936 |
| 937 RenderLayer* RenderLayer::enclosingPositionedAncestor() const | 937 Layer* Layer::enclosingPositionedAncestor() const |
| 938 { | 938 { |
| 939 RenderLayer* curr = parent(); | 939 Layer* curr = parent(); |
| 940 while (curr && !curr->isPositionedContainer()) | 940 while (curr && !curr->isPositionedContainer()) |
| 941 curr = curr->parent(); | 941 curr = curr->parent(); |
| 942 | 942 |
| 943 return curr; | 943 return curr; |
| 944 } | 944 } |
| 945 | 945 |
| 946 RenderLayer* RenderLayer::enclosingTransformedAncestor() const | 946 Layer* Layer::enclosingTransformedAncestor() const |
| 947 { | 947 { |
| 948 RenderLayer* curr = parent(); | 948 Layer* curr = parent(); |
| 949 while (curr && !curr->isRootLayer() && !curr->renderer()->hasTransformRelate
dProperty()) | 949 while (curr && !curr->isRootLayer() && !curr->renderer()->hasTransformRelate
dProperty()) |
| 950 curr = curr->parent(); | 950 curr = curr->parent(); |
| 951 | 951 |
| 952 return curr; | 952 return curr; |
| 953 } | 953 } |
| 954 | 954 |
| 955 LayoutPoint RenderLayer::computeOffsetFromTransformedAncestor() const | 955 LayoutPoint Layer::computeOffsetFromTransformedAncestor() const |
| 956 { | 956 { |
| 957 const AncestorDependentCompositingInputs& properties = ancestorDependentComp
ositingInputs(); | 957 const AncestorDependentCompositingInputs& properties = ancestorDependentComp
ositingInputs(); |
| 958 | 958 |
| 959 TransformState transformState(TransformState::ApplyTransformDirection, Float
Point()); | 959 TransformState transformState(TransformState::ApplyTransformDirection, Float
Point()); |
| 960 // FIXME: add a test that checks flipped writing mode and ApplyContainerFlip
are correct. | 960 // FIXME: add a test that checks flipped writing mode and ApplyContainerFlip
are correct. |
| 961 renderer()->mapLocalToContainer(properties.transformAncestor ? properties.tr
ansformAncestor->renderer() : 0, transformState, ApplyContainerFlip); | 961 renderer()->mapLocalToContainer(properties.transformAncestor ? properties.tr
ansformAncestor->renderer() : 0, transformState, ApplyContainerFlip); |
| 962 transformState.flatten(); | 962 transformState.flatten(); |
| 963 return LayoutPoint(transformState.lastPlanarPoint()); | 963 return LayoutPoint(transformState.lastPlanarPoint()); |
| 964 } | 964 } |
| 965 | 965 |
| 966 const RenderLayer* RenderLayer::compositingContainer() const | 966 const Layer* Layer::compositingContainer() const |
| 967 { | 967 { |
| 968 if (stackingNode()->isNormalFlowOnly()) | 968 if (stackingNode()->isNormalFlowOnly()) |
| 969 return parent(); | 969 return parent(); |
| 970 if (RenderLayerStackingNode* ancestorStackingNode = stackingNode()->ancestor
StackingContextNode()) | 970 if (LayerStackingNode* ancestorStackingNode = stackingNode()->ancestorStacki
ngContextNode()) |
| 971 return ancestorStackingNode->layer(); | 971 return ancestorStackingNode->layer(); |
| 972 return 0; | 972 return 0; |
| 973 } | 973 } |
| 974 | 974 |
| 975 bool RenderLayer::isPaintInvalidationContainer() const | 975 bool Layer::isPaintInvalidationContainer() const |
| 976 { | 976 { |
| 977 return compositingState() == PaintsIntoOwnBacking || compositingState() == P
aintsIntoGroupedBacking; | 977 return compositingState() == PaintsIntoOwnBacking || compositingState() == P
aintsIntoGroupedBacking; |
| 978 } | 978 } |
| 979 | 979 |
| 980 // Note: enclosingCompositingLayer does not include squashed layers. Compositing
stacking children of squashed layers | 980 // Note: enclosingCompositingLayer does not include squashed layers. Compositing
stacking children of squashed layers |
| 981 // receive graphics layers that are parented to the compositing ancestor of the
squashed layer. | 981 // receive graphics layers that are parented to the compositing ancestor of the
squashed layer. |
| 982 RenderLayer* RenderLayer::enclosingLayerWithCompositedLayerMapping(IncludeSelfOr
Not includeSelf) const | 982 Layer* Layer::enclosingLayerWithCompositedLayerMapping(IncludeSelfOrNot includeS
elf) const |
| 983 { | 983 { |
| 984 ASSERT(isAllowedToQueryCompositingState()); | 984 ASSERT(isAllowedToQueryCompositingState()); |
| 985 | 985 |
| 986 if ((includeSelf == IncludeSelf) && compositingState() != NotComposited && c
ompositingState() != PaintsIntoGroupedBacking) | 986 if ((includeSelf == IncludeSelf) && compositingState() != NotComposited && c
ompositingState() != PaintsIntoGroupedBacking) |
| 987 return const_cast<RenderLayer*>(this); | 987 return const_cast<Layer*>(this); |
| 988 | 988 |
| 989 for (const RenderLayer* curr = compositingContainer(); curr; curr = curr->co
mpositingContainer()) { | 989 for (const Layer* curr = compositingContainer(); curr; curr = curr->composit
ingContainer()) { |
| 990 if (curr->compositingState() != NotComposited && curr->compositingState(
) != PaintsIntoGroupedBacking) | 990 if (curr->compositingState() != NotComposited && curr->compositingState(
) != PaintsIntoGroupedBacking) |
| 991 return const_cast<RenderLayer*>(curr); | 991 return const_cast<Layer*>(curr); |
| 992 } | 992 } |
| 993 | 993 |
| 994 return 0; | 994 return 0; |
| 995 } | 995 } |
| 996 | 996 |
| 997 // Return the enclosingCompositedLayerForPaintInvalidation for the given RenderL
ayer | 997 // Return the enclosingCompositedLayerForPaintInvalidation for the given Layer |
| 998 // including crossing frame boundaries. | 998 // including crossing frame boundaries. |
| 999 RenderLayer* RenderLayer::enclosingLayerForPaintInvalidationCrossingFrameBoundar
ies() const | 999 Layer* Layer::enclosingLayerForPaintInvalidationCrossingFrameBoundaries() const |
| 1000 { | 1000 { |
| 1001 const RenderLayer* layer = this; | 1001 const Layer* layer = this; |
| 1002 RenderLayer* compositedLayer = 0; | 1002 Layer* compositedLayer = 0; |
| 1003 while (!compositedLayer) { | 1003 while (!compositedLayer) { |
| 1004 compositedLayer = layer->enclosingLayerForPaintInvalidation(); | 1004 compositedLayer = layer->enclosingLayerForPaintInvalidation(); |
| 1005 if (!compositedLayer) { | 1005 if (!compositedLayer) { |
| 1006 RenderObject* owner = layer->renderer()->frame()->ownerRenderer(); | 1006 RenderObject* owner = layer->renderer()->frame()->ownerRenderer(); |
| 1007 if (!owner) | 1007 if (!owner) |
| 1008 break; | 1008 break; |
| 1009 layer = owner->enclosingLayer(); | 1009 layer = owner->enclosingLayer(); |
| 1010 } | 1010 } |
| 1011 } | 1011 } |
| 1012 return compositedLayer; | 1012 return compositedLayer; |
| 1013 } | 1013 } |
| 1014 | 1014 |
| 1015 RenderLayer* RenderLayer::enclosingLayerForPaintInvalidation() const | 1015 Layer* Layer::enclosingLayerForPaintInvalidation() const |
| 1016 { | 1016 { |
| 1017 ASSERT(isAllowedToQueryCompositingState()); | 1017 ASSERT(isAllowedToQueryCompositingState()); |
| 1018 | 1018 |
| 1019 if (isPaintInvalidationContainer()) | 1019 if (isPaintInvalidationContainer()) |
| 1020 return const_cast<RenderLayer*>(this); | 1020 return const_cast<Layer*>(this); |
| 1021 | 1021 |
| 1022 for (const RenderLayer* curr = compositingContainer(); curr; curr = curr->co
mpositingContainer()) { | 1022 for (const Layer* curr = compositingContainer(); curr; curr = curr->composit
ingContainer()) { |
| 1023 if (curr->isPaintInvalidationContainer()) | 1023 if (curr->isPaintInvalidationContainer()) |
| 1024 return const_cast<RenderLayer*>(curr); | 1024 return const_cast<Layer*>(curr); |
| 1025 } | 1025 } |
| 1026 | 1026 |
| 1027 return 0; | 1027 return 0; |
| 1028 } | 1028 } |
| 1029 | 1029 |
| 1030 void RenderLayer::setNeedsCompositingInputsUpdate() | 1030 void Layer::setNeedsCompositingInputsUpdate() |
| 1031 { | 1031 { |
| 1032 m_needsAncestorDependentCompositingInputsUpdate = true; | 1032 m_needsAncestorDependentCompositingInputsUpdate = true; |
| 1033 m_needsDescendantDependentCompositingInputsUpdate = true; | 1033 m_needsDescendantDependentCompositingInputsUpdate = true; |
| 1034 | 1034 |
| 1035 for (RenderLayer* current = this; current && !current->m_childNeedsCompositi
ngInputsUpdate; current = current->parent()) | 1035 for (Layer* current = this; current && !current->m_childNeedsCompositingInpu
tsUpdate; current = current->parent()) |
| 1036 current->m_childNeedsCompositingInputsUpdate = true; | 1036 current->m_childNeedsCompositingInputsUpdate = true; |
| 1037 | 1037 |
| 1038 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInp
utChange); | 1038 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInp
utChange); |
| 1039 } | 1039 } |
| 1040 | 1040 |
| 1041 void RenderLayer::updateAncestorDependentCompositingInputs(const AncestorDepende
ntCompositingInputs& compositingInputs) | 1041 void Layer::updateAncestorDependentCompositingInputs(const AncestorDependentComp
ositingInputs& compositingInputs) |
| 1042 { | 1042 { |
| 1043 m_ancestorDependentCompositingInputs = compositingInputs; | 1043 m_ancestorDependentCompositingInputs = compositingInputs; |
| 1044 m_needsAncestorDependentCompositingInputsUpdate = false; | 1044 m_needsAncestorDependentCompositingInputsUpdate = false; |
| 1045 } | 1045 } |
| 1046 | 1046 |
| 1047 void RenderLayer::updateDescendantDependentCompositingInputs(const DescendantDep
endentCompositingInputs& compositingInputs) | 1047 void Layer::updateDescendantDependentCompositingInputs(const DescendantDependent
CompositingInputs& compositingInputs) |
| 1048 { | 1048 { |
| 1049 m_descendantDependentCompositingInputs = compositingInputs; | 1049 m_descendantDependentCompositingInputs = compositingInputs; |
| 1050 m_needsDescendantDependentCompositingInputsUpdate = false; | 1050 m_needsDescendantDependentCompositingInputsUpdate = false; |
| 1051 } | 1051 } |
| 1052 | 1052 |
| 1053 void RenderLayer::didUpdateCompositingInputs() | 1053 void Layer::didUpdateCompositingInputs() |
| 1054 { | 1054 { |
| 1055 ASSERT(!needsCompositingInputsUpdate()); | 1055 ASSERT(!needsCompositingInputsUpdate()); |
| 1056 m_childNeedsCompositingInputsUpdate = false; | 1056 m_childNeedsCompositingInputsUpdate = false; |
| 1057 if (m_scrollableArea) | 1057 if (m_scrollableArea) |
| 1058 m_scrollableArea->updateNeedsCompositedScrolling(); | 1058 m_scrollableArea->updateNeedsCompositedScrolling(); |
| 1059 } | 1059 } |
| 1060 | 1060 |
| 1061 bool RenderLayer::hasNonIsolatedDescendantWithBlendMode() const | 1061 bool Layer::hasNonIsolatedDescendantWithBlendMode() const |
| 1062 { | 1062 { |
| 1063 if (descendantDependentCompositingInputs().hasNonIsolatedDescendantWithBlend
Mode) | 1063 if (descendantDependentCompositingInputs().hasNonIsolatedDescendantWithBlend
Mode) |
| 1064 return true; | 1064 return true; |
| 1065 if (renderer()->isSVGRoot()) | 1065 if (renderer()->isSVGRoot()) |
| 1066 return toRenderSVGRoot(renderer())->hasNonIsolatedBlendingDescendants(); | 1066 return toRenderSVGRoot(renderer())->hasNonIsolatedBlendingDescendants(); |
| 1067 return false; | 1067 return false; |
| 1068 } | 1068 } |
| 1069 | 1069 |
| 1070 void RenderLayer::setCompositingReasons(CompositingReasons reasons, CompositingR
easons mask) | 1070 void Layer::setCompositingReasons(CompositingReasons reasons, CompositingReasons
mask) |
| 1071 { | 1071 { |
| 1072 if ((compositingReasons() & mask) == (reasons & mask)) | 1072 if ((compositingReasons() & mask) == (reasons & mask)) |
| 1073 return; | 1073 return; |
| 1074 m_compositingReasons = (reasons & mask) | (compositingReasons() & ~mask); | 1074 m_compositingReasons = (reasons & mask) | (compositingReasons() & ~mask); |
| 1075 } | 1075 } |
| 1076 | 1076 |
| 1077 void RenderLayer::setHasCompositingDescendant(bool hasCompositingDescendant) | 1077 void Layer::setHasCompositingDescendant(bool hasCompositingDescendant) |
| 1078 { | 1078 { |
| 1079 if (m_hasCompositingDescendant == static_cast<unsigned>(hasCompositingDescen
dant)) | 1079 if (m_hasCompositingDescendant == static_cast<unsigned>(hasCompositingDescen
dant)) |
| 1080 return; | 1080 return; |
| 1081 | 1081 |
| 1082 m_hasCompositingDescendant = hasCompositingDescendant; | 1082 m_hasCompositingDescendant = hasCompositingDescendant; |
| 1083 | 1083 |
| 1084 if (hasCompositedLayerMapping()) | 1084 if (hasCompositedLayerMapping()) |
| 1085 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdat
eLocal); | 1085 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdat
eLocal); |
| 1086 } | 1086 } |
| 1087 | 1087 |
| 1088 void RenderLayer::setShouldIsolateCompositedDescendants(bool shouldIsolateCompos
itedDescendants) | 1088 void Layer::setShouldIsolateCompositedDescendants(bool shouldIsolateCompositedDe
scendants) |
| 1089 { | 1089 { |
| 1090 if (m_shouldIsolateCompositedDescendants == static_cast<unsigned>(shouldIsol
ateCompositedDescendants)) | 1090 if (m_shouldIsolateCompositedDescendants == static_cast<unsigned>(shouldIsol
ateCompositedDescendants)) |
| 1091 return; | 1091 return; |
| 1092 | 1092 |
| 1093 m_shouldIsolateCompositedDescendants = shouldIsolateCompositedDescendants; | 1093 m_shouldIsolateCompositedDescendants = shouldIsolateCompositedDescendants; |
| 1094 | 1094 |
| 1095 if (hasCompositedLayerMapping()) | 1095 if (hasCompositedLayerMapping()) |
| 1096 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdat
eLocal); | 1096 compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdat
eLocal); |
| 1097 } | 1097 } |
| 1098 | 1098 |
| 1099 bool RenderLayer::hasAncestorWithFilterOutsets() const | 1099 bool Layer::hasAncestorWithFilterOutsets() const |
| 1100 { | 1100 { |
| 1101 for (const RenderLayer* curr = this; curr; curr = curr->parent()) { | 1101 for (const Layer* curr = this; curr; curr = curr->parent()) { |
| 1102 RenderLayerModelObject* renderer = curr->renderer(); | 1102 LayoutLayerModelObject* renderer = curr->renderer(); |
| 1103 if (renderer->style()->hasFilterOutsets()) | 1103 if (renderer->style()->hasFilterOutsets()) |
| 1104 return true; | 1104 return true; |
| 1105 } | 1105 } |
| 1106 return false; | 1106 return false; |
| 1107 } | 1107 } |
| 1108 | 1108 |
| 1109 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, cons
t RenderLayer* layer, const RenderLayer* rootLayer, | 1109 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, cons
t Layer* layer, const Layer* rootLayer, |
| 1110 RenderLayer::TransparencyClipBoxBehavior transparencyBehavior, const LayoutS
ize& subPixelAccumulation, PaintBehavior paintBehavior) | 1110 Layer::TransparencyClipBoxBehavior transparencyBehavior, const LayoutSize& s
ubPixelAccumulation, PaintBehavior paintBehavior) |
| 1111 { | 1111 { |
| 1112 // If we have a mask, then the clip is limited to the border box area (and t
here is | 1112 // If we have a mask, then the clip is limited to the border box area (and t
here is |
| 1113 // no need to examine child layers). | 1113 // no need to examine child layers). |
| 1114 if (!layer->renderer()->hasMask()) { | 1114 if (!layer->renderer()->hasMask()) { |
| 1115 // Note: we don't have to walk z-order lists since transparent elements
always establish | 1115 // Note: we don't have to walk z-order lists since transparent elements
always establish |
| 1116 // a stacking container. This means we can just walk the layer tree dire
ctly. | 1116 // a stacking container. This means we can just walk the layer tree dire
ctly. |
| 1117 for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSib
ling()) { | 1117 for (Layer* curr = layer->firstChild(); curr; curr = curr->nextSibling()
) { |
| 1118 if (!layer->reflectionInfo() || layer->reflectionInfo()->reflectionL
ayer() != curr) | 1118 if (!layer->reflectionInfo() || layer->reflectionInfo()->reflectionL
ayer() != curr) |
| 1119 clipRect.unite(RenderLayer::transparencyClipBox(curr, rootLayer,
transparencyBehavior, RenderLayer::DescendantsOfTransparencyClipBox, subPixelAc
cumulation, paintBehavior)); | 1119 clipRect.unite(Layer::transparencyClipBox(curr, rootLayer, trans
parencyBehavior, Layer::DescendantsOfTransparencyClipBox, subPixelAccumulation,
paintBehavior)); |
| 1120 } | 1120 } |
| 1121 } | 1121 } |
| 1122 | 1122 |
| 1123 // If we have a reflection, then we need to account for that when we push th
e clip. Reflect our entire | 1123 // If we have a reflection, then we need to account for that when we push th
e clip. Reflect our entire |
| 1124 // current transparencyClipBox to catch all child layers. | 1124 // current transparencyClipBox to catch all child layers. |
| 1125 // FIXME: Accelerated compositing will eventually want to do something smart
here to avoid incorporating this | 1125 // FIXME: Accelerated compositing will eventually want to do something smart
here to avoid incorporating this |
| 1126 // size into the parent layer. | 1126 // size into the parent layer. |
| 1127 if (layer->renderer()->hasReflection()) { | 1127 if (layer->renderer()->hasReflection()) { |
| 1128 LayoutPoint delta; | 1128 LayoutPoint delta; |
| 1129 layer->convertToLayerCoords(rootLayer, delta); | 1129 layer->convertToLayerCoords(rootLayer, delta); |
| 1130 clipRect.move(-delta.x(), -delta.y()); | 1130 clipRect.move(-delta.x(), -delta.y()); |
| 1131 clipRect.unite(layer->renderBox()->reflectedRect(clipRect)); | 1131 clipRect.unite(layer->renderBox()->reflectedRect(clipRect)); |
| 1132 clipRect.moveBy(delta); | 1132 clipRect.moveBy(delta); |
| 1133 } | 1133 } |
| 1134 } | 1134 } |
| 1135 | 1135 |
| 1136 LayoutRect RenderLayer::transparencyClipBox(const RenderLayer* layer, const Rend
erLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior, | 1136 LayoutRect Layer::transparencyClipBox(const Layer* layer, const Layer* rootLayer
, TransparencyClipBoxBehavior transparencyBehavior, |
| 1137 TransparencyClipBoxMode transparencyMode, const LayoutSize& subPixelAccumula
tion, PaintBehavior paintBehavior) | 1137 TransparencyClipBoxMode transparencyMode, const LayoutSize& subPixelAccumula
tion, PaintBehavior paintBehavior) |
| 1138 { | 1138 { |
| 1139 // FIXME: Although this function completely ignores CSS-imposed clipping, we
did already intersect with the | 1139 // FIXME: Although this function completely ignores CSS-imposed clipping, we
did already intersect with the |
| 1140 // paintDirtyRect, and that should cut down on the amount we have to paint.
Still it | 1140 // paintDirtyRect, and that should cut down on the amount we have to paint.
Still it |
| 1141 // would be better to respect clips. | 1141 // would be better to respect clips. |
| 1142 | 1142 |
| 1143 if (rootLayer != layer && ((transparencyBehavior == PaintingTransparencyClip
Box && layer->paintsWithTransform(paintBehavior)) | 1143 if (rootLayer != layer && ((transparencyBehavior == PaintingTransparencyClip
Box && layer->paintsWithTransform(paintBehavior)) |
| 1144 || (transparencyBehavior == HitTestingTransparencyClipBox && layer->hasT
ransformRelatedProperty()))) { | 1144 || (transparencyBehavior == HitTestingTransparencyClipBox && layer->hasT
ransformRelatedProperty()))) { |
| 1145 // The best we can do here is to use enclosed bounding boxes to establis
h a "fuzzy" enough clip to encompass | 1145 // The best we can do here is to use enclosed bounding boxes to establis
h a "fuzzy" enough clip to encompass |
| 1146 // the transformed layer and all of its children. | 1146 // the transformed layer and all of its children. |
| 1147 const RenderLayer* paginationLayer = transparencyMode == DescendantsOfTr
ansparencyClipBox ? layer->enclosingPaginationLayer() : 0; | 1147 const Layer* paginationLayer = transparencyMode == DescendantsOfTranspar
encyClipBox ? layer->enclosingPaginationLayer() : 0; |
| 1148 const RenderLayer* rootLayerForTransform = paginationLayer ? paginationL
ayer : rootLayer; | 1148 const Layer* rootLayerForTransform = paginationLayer ? paginationLayer :
rootLayer; |
| 1149 LayoutPoint delta; | 1149 LayoutPoint delta; |
| 1150 layer->convertToLayerCoords(rootLayerForTransform, delta); | 1150 layer->convertToLayerCoords(rootLayerForTransform, delta); |
| 1151 | 1151 |
| 1152 delta.move(subPixelAccumulation); | 1152 delta.move(subPixelAccumulation); |
| 1153 IntPoint pixelSnappedDelta = roundedIntPoint(delta); | 1153 IntPoint pixelSnappedDelta = roundedIntPoint(delta); |
| 1154 TransformationMatrix transform; | 1154 TransformationMatrix transform; |
| 1155 transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y()); | 1155 transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y()); |
| 1156 transform = transform * *layer->transform(); | 1156 transform = transform * *layer->transform(); |
| 1157 | 1157 |
| 1158 // We don't use fragment boxes when collecting a transformed layer's bou
nding box, since it always | 1158 // We don't use fragment boxes when collecting a transformed layer's bou
nding box, since it always |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1176 return result; | 1176 return result; |
| 1177 } | 1177 } |
| 1178 | 1178 |
| 1179 LayoutRect clipRect = layer->fragmentsBoundingBox(rootLayer); | 1179 LayoutRect clipRect = layer->fragmentsBoundingBox(rootLayer); |
| 1180 expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transp
arencyBehavior, subPixelAccumulation, paintBehavior); | 1180 expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transp
arencyBehavior, subPixelAccumulation, paintBehavior); |
| 1181 clipRect.expand(layer->renderer()->style()->filterOutsets()); | 1181 clipRect.expand(layer->renderer()->style()->filterOutsets()); |
| 1182 clipRect.move(subPixelAccumulation); | 1182 clipRect.move(subPixelAccumulation); |
| 1183 return clipRect; | 1183 return clipRect; |
| 1184 } | 1184 } |
| 1185 | 1185 |
| 1186 LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const Layou
tRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior pai
ntBehavior) | 1186 LayoutRect Layer::paintingExtent(const Layer* rootLayer, const LayoutRect& paint
DirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior) |
| 1187 { | 1187 { |
| 1188 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparenc
yClipBox, RootOfTransparencyClipBox, subPixelAccumulation, paintBehavior), paint
DirtyRect); | 1188 return intersection(transparencyClipBox(this, rootLayer, PaintingTransparenc
yClipBox, RootOfTransparencyClipBox, subPixelAccumulation, paintBehavior), paint
DirtyRect); |
| 1189 } | 1189 } |
| 1190 | 1190 |
| 1191 void* RenderLayer::operator new(size_t sz) | 1191 void* Layer::operator new(size_t sz) |
| 1192 { | 1192 { |
| 1193 return partitionAlloc(Partitions::getRenderingPartition(), sz); | 1193 return partitionAlloc(Partitions::getRenderingPartition(), sz); |
| 1194 } | 1194 } |
| 1195 | 1195 |
| 1196 void RenderLayer::operator delete(void* ptr) | 1196 void Layer::operator delete(void* ptr) |
| 1197 { | 1197 { |
| 1198 partitionFree(ptr); | 1198 partitionFree(ptr); |
| 1199 } | 1199 } |
| 1200 | 1200 |
| 1201 void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild) | 1201 void Layer::addChild(Layer* child, Layer* beforeChild) |
| 1202 { | 1202 { |
| 1203 RenderLayer* prevSibling = beforeChild ? beforeChild->previousSibling() : la
stChild(); | 1203 Layer* prevSibling = beforeChild ? beforeChild->previousSibling() : lastChil
d(); |
| 1204 if (prevSibling) { | 1204 if (prevSibling) { |
| 1205 child->setPreviousSibling(prevSibling); | 1205 child->setPreviousSibling(prevSibling); |
| 1206 prevSibling->setNextSibling(child); | 1206 prevSibling->setNextSibling(child); |
| 1207 ASSERT(prevSibling != child); | 1207 ASSERT(prevSibling != child); |
| 1208 } else | 1208 } else { |
| 1209 setFirstChild(child); | 1209 setFirstChild(child); |
| 1210 } |
| 1210 | 1211 |
| 1211 if (beforeChild) { | 1212 if (beforeChild) { |
| 1212 beforeChild->setPreviousSibling(child); | 1213 beforeChild->setPreviousSibling(child); |
| 1213 child->setNextSibling(beforeChild); | 1214 child->setNextSibling(beforeChild); |
| 1214 ASSERT(beforeChild != child); | 1215 ASSERT(beforeChild != child); |
| 1215 } else | 1216 } else { |
| 1216 setLastChild(child); | 1217 setLastChild(child); |
| 1218 } |
| 1217 | 1219 |
| 1218 child->m_parent = this; | 1220 child->m_parent = this; |
| 1219 | 1221 |
| 1220 setNeedsCompositingInputsUpdate(); | 1222 setNeedsCompositingInputsUpdate(); |
| 1221 | 1223 |
| 1222 if (child->stackingNode()->isNormalFlowOnly()) | 1224 if (child->stackingNode()->isNormalFlowOnly()) |
| 1223 m_stackingNode->dirtyNormalFlowList(); | 1225 m_stackingNode->dirtyNormalFlowList(); |
| 1224 | 1226 |
| 1225 if (!child->stackingNode()->isNormalFlowOnly() || child->firstChild()) { | 1227 if (!child->stackingNode()->isNormalFlowOnly() || child->firstChild()) { |
| 1226 // Dirty the z-order list in which we are contained. The ancestorStackin
gContextNode() can be null in the | 1228 // Dirty the z-order list in which we are contained. The ancestorStackin
gContextNode() can be null in the |
| 1227 // case where we're building up generated content layers. This is ok, si
nce the lists will start | 1229 // case where we're building up generated content layers. This is ok, si
nce the lists will start |
| 1228 // off dirty in that case anyway. | 1230 // off dirty in that case anyway. |
| 1229 child->stackingNode()->dirtyStackingContextZOrderLists(); | 1231 child->stackingNode()->dirtyStackingContextZOrderLists(); |
| 1230 } | 1232 } |
| 1231 | 1233 |
| 1232 dirtyAncestorChainVisibleDescendantStatus(); | 1234 dirtyAncestorChainVisibleDescendantStatus(); |
| 1233 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); | 1235 dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); |
| 1234 | 1236 |
| 1235 child->updateDescendantDependentFlags(); | 1237 child->updateDescendantDependentFlags(); |
| 1236 } | 1238 } |
| 1237 | 1239 |
| 1238 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild) | 1240 Layer* Layer::removeChild(Layer* oldChild) |
| 1239 { | 1241 { |
| 1240 if (oldChild->previousSibling()) | 1242 if (oldChild->previousSibling()) |
| 1241 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); | 1243 oldChild->previousSibling()->setNextSibling(oldChild->nextSibling()); |
| 1242 if (oldChild->nextSibling()) | 1244 if (oldChild->nextSibling()) |
| 1243 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling())
; | 1245 oldChild->nextSibling()->setPreviousSibling(oldChild->previousSibling())
; |
| 1244 | 1246 |
| 1245 if (m_first == oldChild) | 1247 if (m_first == oldChild) |
| 1246 m_first = oldChild->nextSibling(); | 1248 m_first = oldChild->nextSibling(); |
| 1247 if (m_last == oldChild) | 1249 if (m_last == oldChild) |
| 1248 m_last = oldChild->previousSibling(); | 1250 m_last = oldChild->previousSibling(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1270 | 1272 |
| 1271 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant) | 1273 if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant) |
| 1272 dirtyAncestorChainVisibleDescendantStatus(); | 1274 dirtyAncestorChainVisibleDescendantStatus(); |
| 1273 | 1275 |
| 1274 if (oldChild->enclosingPaginationLayer()) | 1276 if (oldChild->enclosingPaginationLayer()) |
| 1275 oldChild->clearPaginationRecursive(); | 1277 oldChild->clearPaginationRecursive(); |
| 1276 | 1278 |
| 1277 return oldChild; | 1279 return oldChild; |
| 1278 } | 1280 } |
| 1279 | 1281 |
| 1280 void RenderLayer::removeOnlyThisLayer() | 1282 void Layer::removeOnlyThisLayer() |
| 1281 { | 1283 { |
| 1282 if (!m_parent) | 1284 if (!m_parent) |
| 1283 return; | 1285 return; |
| 1284 | 1286 |
| 1285 { | 1287 { |
| 1286 DisableCompositingQueryAsserts disabler; // We need the current composit
ing status. | 1288 DisableCompositingQueryAsserts disabler; // We need the current composit
ing status. |
| 1287 if (isPaintInvalidationContainer()) { | 1289 if (isPaintInvalidationContainer()) { |
| 1288 // Our children will be reparented and contained by a new paint inva
lidation container, | 1290 // Our children will be reparented and contained by a new paint inva
lidation container, |
| 1289 // so need paint invalidation. CompositingUpdate can't see this laye
r (which has been | 1291 // so need paint invalidation. CompositingUpdate can't see this laye
r (which has been |
| 1290 // removed) so won't do this for us. | 1292 // removed) so won't do this for us. |
| 1291 setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants()
; | 1293 setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants()
; |
| 1292 } | 1294 } |
| 1293 } | 1295 } |
| 1294 | 1296 |
| 1295 m_clipper.clearClipRectsIncludingDescendants(); | 1297 m_clipper.clearClipRectsIncludingDescendants(); |
| 1296 | 1298 |
| 1297 RenderLayer* nextSib = nextSibling(); | 1299 Layer* nextSib = nextSibling(); |
| 1298 | 1300 |
| 1299 // Remove the child reflection layer before moving other child layers. | 1301 // Remove the child reflection layer before moving other child layers. |
| 1300 // The reflection layer should not be moved to the parent. | 1302 // The reflection layer should not be moved to the parent. |
| 1301 if (m_reflectionInfo) | 1303 if (m_reflectionInfo) |
| 1302 removeChild(m_reflectionInfo->reflectionLayer()); | 1304 removeChild(m_reflectionInfo->reflectionLayer()); |
| 1303 | 1305 |
| 1304 // Now walk our kids and reattach them to our parent. | 1306 // Now walk our kids and reattach them to our parent. |
| 1305 RenderLayer* current = m_first; | 1307 Layer* current = m_first; |
| 1306 while (current) { | 1308 while (current) { |
| 1307 RenderLayer* next = current->nextSibling(); | 1309 Layer* next = current->nextSibling(); |
| 1308 removeChild(current); | 1310 removeChild(current); |
| 1309 m_parent->addChild(current, nextSib); | 1311 m_parent->addChild(current, nextSib); |
| 1310 | 1312 |
| 1311 // FIXME: We should call a specialized version of this function. | 1313 // FIXME: We should call a specialized version of this function. |
| 1312 current->updateLayerPositionsAfterLayout(); | 1314 current->updateLayerPositionsAfterLayout(); |
| 1313 current = next; | 1315 current = next; |
| 1314 } | 1316 } |
| 1315 | 1317 |
| 1316 // Remove us from the parent. | 1318 // Remove us from the parent. |
| 1317 m_parent->removeChild(this); | 1319 m_parent->removeChild(this); |
| 1318 m_renderer->destroyLayer(); | 1320 m_renderer->destroyLayer(); |
| 1319 } | 1321 } |
| 1320 | 1322 |
| 1321 void RenderLayer::insertOnlyThisLayer() | 1323 void Layer::insertOnlyThisLayer() |
| 1322 { | 1324 { |
| 1323 if (!m_parent && renderer()->parent()) { | 1325 if (!m_parent && renderer()->parent()) { |
| 1324 // We need to connect ourselves when our renderer() has a parent. | 1326 // We need to connect ourselves when our renderer() has a parent. |
| 1325 // Find our enclosingLayer and add ourselves. | 1327 // Find our enclosingLayer and add ourselves. |
| 1326 RenderLayer* parentLayer = renderer()->parent()->enclosingLayer(); | 1328 Layer* parentLayer = renderer()->parent()->enclosingLayer(); |
| 1327 ASSERT(parentLayer); | 1329 ASSERT(parentLayer); |
| 1328 RenderLayer* beforeChild = !parentLayer->reflectionInfo() || parentLayer
->reflectionInfo()->reflectionLayer() != this ? renderer()->parent()->findNextLa
yer(parentLayer, renderer()) : 0; | 1330 Layer* beforeChild = !parentLayer->reflectionInfo() || parentLayer->refl
ectionInfo()->reflectionLayer() != this ? renderer()->parent()->findNextLayer(pa
rentLayer, renderer()) : 0; |
| 1329 parentLayer->addChild(this, beforeChild); | 1331 parentLayer->addChild(this, beforeChild); |
| 1330 } | 1332 } |
| 1331 | 1333 |
| 1332 // Remove all descendant layers from the hierarchy and add them to the new p
osition. | 1334 // Remove all descendant layers from the hierarchy and add them to the new p
osition. |
| 1333 for (RenderObject* curr = renderer()->slowFirstChild(); curr; curr = curr->n
extSibling()) | 1335 for (RenderObject* curr = renderer()->slowFirstChild(); curr; curr = curr->n
extSibling()) |
| 1334 curr->moveLayers(m_parent, this); | 1336 curr->moveLayers(m_parent, this); |
| 1335 | 1337 |
| 1336 // Clear out all the clip rects. | 1338 // Clear out all the clip rects. |
| 1337 m_clipper.clearClipRectsIncludingDescendants(); | 1339 m_clipper.clearClipRectsIncludingDescendants(); |
| 1338 } | 1340 } |
| 1339 | 1341 |
| 1340 // Returns the layer reached on the walk up towards the ancestor. | 1342 // Returns the layer reached on the walk up towards the ancestor. |
| 1341 static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLay
er* layer, const RenderLayer* ancestorLayer, LayoutPoint& location) | 1343 static inline const Layer* accumulateOffsetTowardsAncestor(const Layer* layer, c
onst Layer* ancestorLayer, LayoutPoint& location) |
| 1342 { | 1344 { |
| 1343 ASSERT(ancestorLayer != layer); | 1345 ASSERT(ancestorLayer != layer); |
| 1344 | 1346 |
| 1345 const RenderLayerModelObject* renderer = layer->renderer(); | 1347 const LayoutLayerModelObject* renderer = layer->renderer(); |
| 1346 EPosition position = renderer->style()->position(); | 1348 EPosition position = renderer->style()->position(); |
| 1347 | 1349 |
| 1348 // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in
a RenderFlowThread | 1350 // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in
a RenderFlowThread |
| 1349 // may need to be revisited in a future patch. | 1351 // may need to be revisited in a future patch. |
| 1350 // If the fixed renderer is inside a RenderFlowThread, we should not compute
location using localToAbsolute, | 1352 // If the fixed renderer is inside a RenderFlowThread, we should not compute
location using localToAbsolute, |
| 1351 // since localToAbsolute maps the coordinates from flow thread to regions co
ordinates and regions can be | 1353 // since localToAbsolute maps the coordinates from flow thread to regions co
ordinates and regions can be |
| 1352 // positioned in a completely different place in the viewport (RenderView). | 1354 // positioned in a completely different place in the viewport (RenderView). |
| 1353 if (position == FixedPosition && (!ancestorLayer || ancestorLayer == rendere
r->view()->layer())) { | 1355 if (position == FixedPosition && (!ancestorLayer || ancestorLayer == rendere
r->view()->layer())) { |
| 1354 // If the fixed layer's container is the root, just add in the offset of
the view. We can obtain this by calling | 1356 // If the fixed layer's container is the root, just add in the offset of
the view. We can obtain this by calling |
| 1355 // localToAbsolute() on the RenderView. | 1357 // localToAbsolute() on the RenderView. |
| 1356 FloatPoint absPos = renderer->localToAbsolute(FloatPoint(), IsFixed); | 1358 FloatPoint absPos = renderer->localToAbsolute(FloatPoint(), IsFixed); |
| 1357 location += LayoutSize(absPos.x(), absPos.y()); | 1359 location += LayoutSize(absPos.x(), absPos.y()); |
| 1358 return ancestorLayer; | 1360 return ancestorLayer; |
| 1359 } | 1361 } |
| 1360 | 1362 |
| 1361 // For the fixed positioned elements inside a render flow thread, we should
also skip the code path below | 1363 // For the fixed positioned elements inside a render flow thread, we should
also skip the code path below |
| 1362 // Otherwise, for the case of ancestorLayer == rootLayer and fixed positione
d element child of a transformed | 1364 // Otherwise, for the case of ancestorLayer == rootLayer and fixed positione
d element child of a transformed |
| 1363 // element in render flow thread, we will hit the fixed positioned container
before hitting the ancestor layer. | 1365 // element in render flow thread, we will hit the fixed positioned container
before hitting the ancestor layer. |
| 1364 if (position == FixedPosition) { | 1366 if (position == FixedPosition) { |
| 1365 // For a fixed layers, we need to walk up to the root to see if there's
a fixed position container | 1367 // For a fixed layers, we need to walk up to the root to see if there's
a fixed position container |
| 1366 // (e.g. a transformed layer). It's an error to call convertToLayerCoord
s() across a layer with a transform, | 1368 // (e.g. a transformed layer). It's an error to call convertToLayerCoord
s() across a layer with a transform, |
| 1367 // so we should always find the ancestor at or before we find the fixed
position container. | 1369 // so we should always find the ancestor at or before we find the fixed
position container. |
| 1368 RenderLayer* fixedPositionContainerLayer = 0; | 1370 Layer* fixedPositionContainerLayer = 0; |
| 1369 bool foundAncestor = false; | 1371 bool foundAncestor = false; |
| 1370 for (RenderLayer* currLayer = layer->parent(); currLayer; currLayer = cu
rrLayer->parent()) { | 1372 for (Layer* currLayer = layer->parent(); currLayer; currLayer = currLaye
r->parent()) { |
| 1371 if (currLayer == ancestorLayer) | 1373 if (currLayer == ancestorLayer) |
| 1372 foundAncestor = true; | 1374 foundAncestor = true; |
| 1373 | 1375 |
| 1374 if (isFixedPositionedContainer(currLayer)) { | 1376 if (isFixedPositionedContainer(currLayer)) { |
| 1375 fixedPositionContainerLayer = currLayer; | 1377 fixedPositionContainerLayer = currLayer; |
| 1376 ASSERT_UNUSED(foundAncestor, foundAncestor); | 1378 ASSERT_UNUSED(foundAncestor, foundAncestor); |
| 1377 break; | 1379 break; |
| 1378 } | 1380 } |
| 1379 } | 1381 } |
| 1380 | 1382 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1391 } else { | 1393 } else { |
| 1392 // RenderView has been handled in the first top-level 'if' block abo
ve. | 1394 // RenderView has been handled in the first top-level 'if' block abo
ve. |
| 1393 ASSERT(ancestorLayer != renderer->view()->layer()); | 1395 ASSERT(ancestorLayer != renderer->view()->layer()); |
| 1394 ASSERT(ancestorLayer->hasTransformRelatedProperty()); | 1396 ASSERT(ancestorLayer->hasTransformRelatedProperty()); |
| 1395 | 1397 |
| 1396 location += layer->location(); | 1398 location += layer->location(); |
| 1397 | 1399 |
| 1398 // The spec (http://dev.w3.org/csswg/css-transforms/#transform-rende
ring) doesn't say if a | 1400 // The spec (http://dev.w3.org/csswg/css-transforms/#transform-rende
ring) doesn't say if a |
| 1399 // fixed-position element under a scrollable transformed element sho
uld scroll. However, | 1401 // fixed-position element under a scrollable transformed element sho
uld scroll. However, |
| 1400 // other parts of blink scroll the fixed-position element, and the f
ollowing keeps the consistency. | 1402 // other parts of blink scroll the fixed-position element, and the f
ollowing keeps the consistency. |
| 1401 if (RenderLayerScrollableArea* scrollableArea = ancestorLayer->scrol
lableArea()) | 1403 if (LayerScrollableArea* scrollableArea = ancestorLayer->scrollableA
rea()) |
| 1402 location -= LayoutSize(scrollableArea->scrollOffset()); | 1404 location -= LayoutSize(scrollableArea->scrollOffset()); |
| 1403 } | 1405 } |
| 1404 return ancestorLayer; | 1406 return ancestorLayer; |
| 1405 } | 1407 } |
| 1406 | 1408 |
| 1407 RenderLayer* parentLayer; | 1409 Layer* parentLayer; |
| 1408 if (position == AbsolutePosition) { | 1410 if (position == AbsolutePosition) { |
| 1409 // Do what enclosingPositionedAncestor() does, but check for ancestorLay
er along the way. | 1411 // Do what enclosingPositionedAncestor() does, but check for ancestorLay
er along the way. |
| 1410 parentLayer = layer->parent(); | 1412 parentLayer = layer->parent(); |
| 1411 bool foundAncestorFirst = false; | 1413 bool foundAncestorFirst = false; |
| 1412 while (parentLayer) { | 1414 while (parentLayer) { |
| 1413 // RenderFlowThread is a positioned container, child of RenderView,
positioned at (0,0). | 1415 // RenderFlowThread is a positioned container, child of RenderView,
positioned at (0,0). |
| 1414 // This implies that, for out-of-flow positioned elements inside a R
enderFlowThread, | 1416 // This implies that, for out-of-flow positioned elements inside a R
enderFlowThread, |
| 1415 // we are bailing out before reaching root layer. | 1417 // we are bailing out before reaching root layer. |
| 1416 if (parentLayer->isPositionedContainer()) | 1418 if (parentLayer->isPositionedContainer()) |
| 1417 break; | 1419 break; |
| 1418 | 1420 |
| 1419 if (parentLayer == ancestorLayer) { | 1421 if (parentLayer == ancestorLayer) { |
| 1420 foundAncestorFirst = true; | 1422 foundAncestorFirst = true; |
| 1421 break; | 1423 break; |
| 1422 } | 1424 } |
| 1423 | 1425 |
| 1424 parentLayer = parentLayer->parent(); | 1426 parentLayer = parentLayer->parent(); |
| 1425 } | 1427 } |
| 1426 | 1428 |
| 1427 // We should not reach RenderView layer past the RenderFlowThread layer
for any | 1429 // We should not reach RenderView layer past the RenderFlowThread layer
for any |
| 1428 // children of the RenderFlowThread. | 1430 // children of the RenderFlowThread. |
| 1429 ASSERT(!renderer->flowThreadContainingBlock() || parentLayer != renderer
->view()->layer()); | 1431 ASSERT(!renderer->flowThreadContainingBlock() || parentLayer != renderer
->view()->layer()); |
| 1430 | 1432 |
| 1431 if (foundAncestorFirst) { | 1433 if (foundAncestorFirst) { |
| 1432 // Found ancestorLayer before the abs. positioned container, so comp
ute offset of both relative | 1434 // Found ancestorLayer before the abs. positioned container, so comp
ute offset of both relative |
| 1433 // to enclosingPositionedAncestor and subtract. | 1435 // to enclosingPositionedAncestor and subtract. |
| 1434 RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAn
cestor(); | 1436 Layer* positionedAncestor = parentLayer->enclosingPositionedAncestor
(); |
| 1435 | 1437 |
| 1436 LayoutPoint thisCoords; | 1438 LayoutPoint thisCoords; |
| 1437 layer->convertToLayerCoords(positionedAncestor, thisCoords); | 1439 layer->convertToLayerCoords(positionedAncestor, thisCoords); |
| 1438 | 1440 |
| 1439 LayoutPoint ancestorCoords; | 1441 LayoutPoint ancestorCoords; |
| 1440 ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorCoor
ds); | 1442 ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorCoor
ds); |
| 1441 | 1443 |
| 1442 location += (thisCoords - ancestorCoords); | 1444 location += (thisCoords - ancestorCoords); |
| 1443 return ancestorLayer; | 1445 return ancestorLayer; |
| 1444 } | 1446 } |
| 1445 } else if (renderer->isColumnSpanAll()) { | 1447 } else if (renderer->isColumnSpanAll()) { |
| 1446 RenderBlock* multicolContainer = renderer->containingBlock(); | 1448 RenderBlock* multicolContainer = renderer->containingBlock(); |
| 1447 ASSERT(toRenderBlockFlow(multicolContainer)->multiColumnFlowThread()); | 1449 ASSERT(toRenderBlockFlow(multicolContainer)->multiColumnFlowThread()); |
| 1448 parentLayer = multicolContainer->layer(); | 1450 parentLayer = multicolContainer->layer(); |
| 1449 ASSERT(parentLayer); | 1451 ASSERT(parentLayer); |
| 1450 } else { | 1452 } else { |
| 1451 parentLayer = layer->parent(); | 1453 parentLayer = layer->parent(); |
| 1452 } | 1454 } |
| 1453 | 1455 |
| 1454 if (!parentLayer) | 1456 if (!parentLayer) |
| 1455 return 0; | 1457 return 0; |
| 1456 | 1458 |
| 1457 location += layer->location(); | 1459 location += layer->location(); |
| 1458 return parentLayer; | 1460 return parentLayer; |
| 1459 } | 1461 } |
| 1460 | 1462 |
| 1461 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutP
oint& location) const | 1463 void Layer::convertToLayerCoords(const Layer* ancestorLayer, LayoutPoint& locati
on) const |
| 1462 { | 1464 { |
| 1463 if (ancestorLayer == this) | 1465 if (ancestorLayer == this) |
| 1464 return; | 1466 return; |
| 1465 | 1467 |
| 1466 const RenderLayer* currLayer = this; | 1468 const Layer* currLayer = this; |
| 1467 while (currLayer && currLayer != ancestorLayer) | 1469 while (currLayer && currLayer != ancestorLayer) |
| 1468 currLayer = accumulateOffsetTowardsAncestor(currLayer, ancestorLayer, lo
cation); | 1470 currLayer = accumulateOffsetTowardsAncestor(currLayer, ancestorLayer, lo
cation); |
| 1469 } | 1471 } |
| 1470 | 1472 |
| 1471 void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutR
ect& rect) const | 1473 void Layer::convertToLayerCoords(const Layer* ancestorLayer, LayoutRect& rect) c
onst |
| 1472 { | 1474 { |
| 1473 LayoutPoint delta; | 1475 LayoutPoint delta; |
| 1474 convertToLayerCoords(ancestorLayer, delta); | 1476 convertToLayerCoords(ancestorLayer, delta); |
| 1475 rect.moveBy(delta); | 1477 rect.moveBy(delta); |
| 1476 } | 1478 } |
| 1477 | 1479 |
| 1478 LayoutPoint RenderLayer::visualOffsetFromAncestor(const RenderLayer* ancestorLay
er) const | 1480 LayoutPoint Layer::visualOffsetFromAncestor(const Layer* ancestorLayer) const |
| 1479 { | 1481 { |
| 1480 LayoutPoint offset; | 1482 LayoutPoint offset; |
| 1481 if (ancestorLayer == this) | 1483 if (ancestorLayer == this) |
| 1482 return offset; | 1484 return offset; |
| 1483 RenderLayer* paginationLayer = enclosingPaginationLayer(); | 1485 Layer* paginationLayer = enclosingPaginationLayer(); |
| 1484 if (paginationLayer == this) | 1486 if (paginationLayer == this) |
| 1485 paginationLayer = parent()->enclosingPaginationLayer(); | 1487 paginationLayer = parent()->enclosingPaginationLayer(); |
| 1486 if (!paginationLayer) { | 1488 if (!paginationLayer) { |
| 1487 convertToLayerCoords(ancestorLayer, offset); | 1489 convertToLayerCoords(ancestorLayer, offset); |
| 1488 return offset; | 1490 return offset; |
| 1489 } | 1491 } |
| 1490 | 1492 |
| 1491 RenderFlowThread* flowThread = toRenderFlowThread(paginationLayer->renderer(
)); | 1493 RenderFlowThread* flowThread = toRenderFlowThread(paginationLayer->renderer(
)); |
| 1492 convertToLayerCoords(paginationLayer, offset); | 1494 convertToLayerCoords(paginationLayer, offset); |
| 1493 offset = flowThread->flowThreadPointToVisualPoint(offset); | 1495 offset = flowThread->flowThreadPointToVisualPoint(offset); |
| 1494 if (ancestorLayer == paginationLayer) | 1496 if (ancestorLayer == paginationLayer) |
| 1495 return offset; | 1497 return offset; |
| 1496 | 1498 |
| 1497 if (ancestorLayer->enclosingPaginationLayer() != paginationLayer) { | 1499 if (ancestorLayer->enclosingPaginationLayer() != paginationLayer) { |
| 1498 offset.moveBy(paginationLayer->visualOffsetFromAncestor(ancestorLayer)); | 1500 offset.moveBy(paginationLayer->visualOffsetFromAncestor(ancestorLayer)); |
| 1499 } else { | 1501 } else { |
| 1500 // The ancestor layer is also inside the pagination layer, so we need to
subtract the visual | 1502 // The ancestor layer is also inside the pagination layer, so we need to
subtract the visual |
| 1501 // distance from the ancestor layer to the pagination layer. | 1503 // distance from the ancestor layer to the pagination layer. |
| 1502 offset.moveBy(-ancestorLayer->visualOffsetFromAncestor(paginationLayer))
; | 1504 offset.moveBy(-ancestorLayer->visualOffsetFromAncestor(paginationLayer))
; |
| 1503 } | 1505 } |
| 1504 return offset; | 1506 return offset; |
| 1505 } | 1507 } |
| 1506 | 1508 |
| 1507 void RenderLayer::didUpdateNeedsCompositedScrolling() | 1509 void Layer::didUpdateNeedsCompositedScrolling() |
| 1508 { | 1510 { |
| 1509 updateSelfPaintingLayer(); | 1511 updateSelfPaintingLayer(); |
| 1510 } | 1512 } |
| 1511 | 1513 |
| 1512 void RenderLayer::updateReflectionInfo(const RenderStyle* oldStyle) | 1514 void Layer::updateReflectionInfo(const RenderStyle* oldStyle) |
| 1513 { | 1515 { |
| 1514 ASSERT(!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)
); | 1516 ASSERT(!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)
); |
| 1515 if (renderer()->hasReflection()) { | 1517 if (renderer()->hasReflection()) { |
| 1516 if (!m_reflectionInfo) | 1518 if (!m_reflectionInfo) |
| 1517 m_reflectionInfo = adoptPtr(new RenderLayerReflectionInfo(*renderBox
())); | 1519 m_reflectionInfo = adoptPtr(new LayerReflectionInfo(*renderBox())); |
| 1518 m_reflectionInfo->updateAfterStyleChange(oldStyle); | 1520 m_reflectionInfo->updateAfterStyleChange(oldStyle); |
| 1519 } else if (m_reflectionInfo) { | 1521 } else if (m_reflectionInfo) { |
| 1520 m_reflectionInfo->destroy(); | 1522 m_reflectionInfo->destroy(); |
| 1521 m_reflectionInfo = nullptr; | 1523 m_reflectionInfo = nullptr; |
| 1522 } | 1524 } |
| 1523 } | 1525 } |
| 1524 | 1526 |
| 1525 void RenderLayer::updateStackingNode() | 1527 void Layer::updateStackingNode() |
| 1526 { | 1528 { |
| 1527 if (requiresStackingNode()) | 1529 if (requiresStackingNode()) |
| 1528 m_stackingNode = adoptPtr(new RenderLayerStackingNode(this)); | 1530 m_stackingNode = adoptPtr(new LayerStackingNode(this)); |
| 1529 else | 1531 else |
| 1530 m_stackingNode = nullptr; | 1532 m_stackingNode = nullptr; |
| 1531 } | 1533 } |
| 1532 | 1534 |
| 1533 void RenderLayer::updateScrollableArea() | 1535 void Layer::updateScrollableArea() |
| 1534 { | 1536 { |
| 1535 if (requiresScrollableArea()) | 1537 if (requiresScrollableArea()) |
| 1536 m_scrollableArea = adoptPtr(new RenderLayerScrollableArea(*this)); | 1538 m_scrollableArea = adoptPtr(new LayerScrollableArea(*this)); |
| 1537 else | 1539 else |
| 1538 m_scrollableArea = nullptr; | 1540 m_scrollableArea = nullptr; |
| 1539 } | 1541 } |
| 1540 | 1542 |
| 1541 bool RenderLayer::hasOverflowControls() const | 1543 bool Layer::hasOverflowControls() const |
| 1542 { | 1544 { |
| 1543 return m_scrollableArea && (m_scrollableArea->hasScrollbar() || m_scrollable
Area->scrollCorner() || renderer()->style()->resize() != RESIZE_NONE); | 1545 return m_scrollableArea && (m_scrollableArea->hasScrollbar() || m_scrollable
Area->scrollCorner() || renderer()->style()->resize() != RESIZE_NONE); |
| 1544 } | 1546 } |
| 1545 | 1547 |
| 1546 void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer*
rootLayer, const LayoutRect& dirtyRect, | 1548 void Layer::collectFragments(LayerFragments& fragments, const Layer* rootLayer,
const LayoutRect& dirtyRect, |
| 1547 ClipRectsCacheSlot clipRectsCacheSlot, OverlayScrollbarSizeRelevancy inOverl
ayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const L
ayoutPoint* offsetFromRoot, | 1549 ClipRectsCacheSlot clipRectsCacheSlot, OverlayScrollbarSizeRelevancy inOverl
ayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const L
ayoutPoint* offsetFromRoot, |
| 1548 const LayoutSize& subPixelAccumulation, const LayoutRect* layerBoundingBox) | 1550 const LayoutSize& subPixelAccumulation, const LayoutRect* layerBoundingBox) |
| 1549 { | 1551 { |
| 1550 if (!enclosingPaginationLayer() || hasTransformRelatedProperty()) { | 1552 if (!enclosingPaginationLayer() || hasTransformRelatedProperty()) { |
| 1551 // For unpaginated layers, there is only one fragment. | 1553 // For unpaginated layers, there is only one fragment. |
| 1552 LayerFragment fragment; | 1554 LayerFragment fragment; |
| 1553 ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, inOverl
ayScrollbarSizeRelevancy, subPixelAccumulation); | 1555 ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, inOverl
ayScrollbarSizeRelevancy, subPixelAccumulation); |
| 1554 if (respectOverflowClip == IgnoreOverflowClip) | 1556 if (respectOverflowClip == IgnoreOverflowClip) |
| 1555 clipRectsContext.setIgnoreOverflowClip(); | 1557 clipRectsContext.setIgnoreOverflowClip(); |
| 1556 clipper().calculateRects(clipRectsContext, dirtyRect, fragment.layerBoun
ds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offs
etFromRoot); | 1558 clipper().calculateRects(clipRectsContext, dirtyRect, fragment.layerBoun
ds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offs
etFromRoot); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1594 | 1596 |
| 1595 // Tell the flow thread to collect the fragments. We pass enough information
to create a minimal number of fragments based off the pages/columns | 1597 // Tell the flow thread to collect the fragments. We pass enough information
to create a minimal number of fragments based off the pages/columns |
| 1596 // that intersect the actual dirtyRect as well as the pages/columns that int
ersect our layer's bounding box. | 1598 // that intersect the actual dirtyRect as well as the pages/columns that int
ersect our layer's bounding box. |
| 1597 enclosingFlowThread->collectLayerFragments(fragments, layerBoundingBoxInFlow
Thread, dirtyRectInFlowThread); | 1599 enclosingFlowThread->collectLayerFragments(fragments, layerBoundingBoxInFlow
Thread, dirtyRectInFlowThread); |
| 1598 | 1600 |
| 1599 if (fragments.isEmpty()) | 1601 if (fragments.isEmpty()) |
| 1600 return; | 1602 return; |
| 1601 | 1603 |
| 1602 // Get the parent clip rects of the pagination layer, since we need to inter
sect with that when painting column contents. | 1604 // Get the parent clip rects of the pagination layer, since we need to inter
sect with that when painting column contents. |
| 1603 ClipRect ancestorClipRect = dirtyRect; | 1605 ClipRect ancestorClipRect = dirtyRect; |
| 1604 if (const RenderLayer* paginationParentLayer = enclosingPaginationLayer()->p
arent()) { | 1606 if (const Layer* paginationParentLayer = enclosingPaginationLayer()->parent(
)) { |
| 1605 const RenderLayer* ancestorLayer = rootLayerIsInsidePaginationLayer ? pa
ginationParentLayer : rootLayer; | 1607 const Layer* ancestorLayer = rootLayerIsInsidePaginationLayer ? paginati
onParentLayer : rootLayer; |
| 1606 ClipRectsContext clipRectsContext(ancestorLayer, clipRectsCacheSlot, inO
verlayScrollbarSizeRelevancy); | 1608 ClipRectsContext clipRectsContext(ancestorLayer, clipRectsCacheSlot, inO
verlayScrollbarSizeRelevancy); |
| 1607 if (respectOverflowClip == IgnoreOverflowClip) | 1609 if (respectOverflowClip == IgnoreOverflowClip) |
| 1608 clipRectsContext.setIgnoreOverflowClip(); | 1610 clipRectsContext.setIgnoreOverflowClip(); |
| 1609 ancestorClipRect = enclosingPaginationLayer()->clipper().backgroundClipR
ect(clipRectsContext); | 1611 ancestorClipRect = enclosingPaginationLayer()->clipper().backgroundClipR
ect(clipRectsContext); |
| 1610 if (rootLayerIsInsidePaginationLayer) | 1612 if (rootLayerIsInsidePaginationLayer) |
| 1611 ancestorClipRect.moveBy(-rootLayer->visualOffsetFromAncestor(ancesto
rLayer)); | 1613 ancestorClipRect.moveBy(-rootLayer->visualOffsetFromAncestor(ancesto
rLayer)); |
| 1612 ancestorClipRect.intersect(dirtyRect); | 1614 ancestorClipRect.intersect(dirtyRect); |
| 1613 } | 1615 } |
| 1614 | 1616 |
| 1615 for (size_t i = 0; i < fragments.size(); ++i) { | 1617 for (size_t i = 0; i < fragments.size(); ++i) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1633 | 1635 |
| 1634 static inline LayoutRect frameVisibleRect(RenderObject* renderer) | 1636 static inline LayoutRect frameVisibleRect(RenderObject* renderer) |
| 1635 { | 1637 { |
| 1636 FrameView* frameView = renderer->document().view(); | 1638 FrameView* frameView = renderer->document().view(); |
| 1637 if (!frameView) | 1639 if (!frameView) |
| 1638 return LayoutRect(); | 1640 return LayoutRect(); |
| 1639 | 1641 |
| 1640 return frameView->visibleContentRect(); | 1642 return frameView->visibleContentRect(); |
| 1641 } | 1643 } |
| 1642 | 1644 |
| 1643 bool RenderLayer::hitTest(const HitTestRequest& request, HitTestResult& result) | 1645 bool Layer::hitTest(const HitTestRequest& request, HitTestResult& result) |
| 1644 { | 1646 { |
| 1645 return hitTest(request, result.hitTestLocation(), result); | 1647 return hitTest(request, result.hitTestLocation(), result); |
| 1646 } | 1648 } |
| 1647 | 1649 |
| 1648 bool RenderLayer::hitTest(const HitTestRequest& request, const HitTestLocation&
hitTestLocation, HitTestResult& result) | 1650 bool Layer::hitTest(const HitTestRequest& request, const HitTestLocation& hitTes
tLocation, HitTestResult& result) |
| 1649 { | 1651 { |
| 1650 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); | 1652 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); |
| 1651 | 1653 |
| 1652 // RenderView should make sure to update layout before entering hit testing | 1654 // RenderView should make sure to update layout before entering hit testing |
| 1653 ASSERT(!renderer()->frame()->view()->layoutPending()); | 1655 ASSERT(!renderer()->frame()->view()->layoutPending()); |
| 1654 ASSERT(!renderer()->document().renderView()->needsLayout()); | 1656 ASSERT(!renderer()->document().renderView()->needsLayout()); |
| 1655 | 1657 |
| 1656 // Start with frameVisibleRect to ensure we include the scrollbars. | 1658 // Start with frameVisibleRect to ensure we include the scrollbars. |
| 1657 LayoutRect hitTestArea = frameVisibleRect(renderer()); | 1659 LayoutRect hitTestArea = frameVisibleRect(renderer()); |
| 1658 if (request.ignoreClipping()) | 1660 if (request.ignoreClipping()) |
| 1659 hitTestArea.unite(renderer()->view()->documentRect()); | 1661 hitTestArea.unite(renderer()->view()->documentRect()); |
| 1660 | 1662 |
| 1661 RenderLayer* insideLayer = hitTestLayer(this, 0, request, result, hitTestAre
a, hitTestLocation, false); | 1663 Layer* insideLayer = hitTestLayer(this, 0, request, result, hitTestArea, hit
TestLocation, false); |
| 1662 if (!insideLayer) { | 1664 if (!insideLayer) { |
| 1663 // We didn't hit any layer. If we are the root layer and the mouse is --
or just was -- down, | 1665 // We didn't hit any layer. If we are the root layer and the mouse is --
or just was -- down, |
| 1664 // return ourselves. We do this so mouse events continue getting deliver
ed after a drag has | 1666 // return ourselves. We do this so mouse events continue getting deliver
ed after a drag has |
| 1665 // exited the WebView, and so hit testing over a scrollbar hits the cont
ent document. | 1667 // exited the WebView, and so hit testing over a scrollbar hits the cont
ent document. |
| 1666 // In addtion, it is possible for the mouse to stay in the document but
there is no element. | 1668 // In addtion, it is possible for the mouse to stay in the document but
there is no element. |
| 1667 // At that time, the events of the mouse should be fired. | 1669 // At that time, the events of the mouse should be fired. |
| 1668 LayoutPoint hitPoint = hitTestLocation.point(); | 1670 LayoutPoint hitPoint = hitTestLocation.point(); |
| 1669 if (!request.isChildFrameHitTest() && ((request.active() || request.rele
ase()) || (request.move() && hitTestArea.contains(hitPoint.x(), hitPoint.y())))
&& isRootLayer()) { | 1671 if (!request.isChildFrameHitTest() && ((request.active() || request.rele
ase()) || (request.move() && hitTestArea.contains(hitPoint.x(), hitPoint.y())))
&& isRootLayer()) { |
| 1670 renderer()->updateHitTestResult(result, toRenderView(renderer())->fl
ipForWritingMode(hitTestLocation.point())); | 1672 renderer()->updateHitTestResult(result, toRenderView(renderer())->fl
ipForWritingMode(hitTestLocation.point())); |
| 1671 insideLayer = this; | 1673 insideLayer = this; |
| 1672 } | 1674 } |
| 1673 } | 1675 } |
| 1674 | 1676 |
| 1675 // Now determine if the result is inside an anchor - if the urlElement isn't
already set. | 1677 // Now determine if the result is inside an anchor - if the urlElement isn't
already set. |
| 1676 Node* node = result.innerNode(); | 1678 Node* node = result.innerNode(); |
| 1677 if (node && !result.URLElement()) | 1679 if (node && !result.URLElement()) |
| 1678 result.setURLElement(node->enclosingLinkEventParentOrSelf()); | 1680 result.setURLElement(node->enclosingLinkEventParentOrSelf()); |
| 1679 | 1681 |
| 1680 // Now return whether we were inside this layer (this will always be true fo
r the root | 1682 // Now return whether we were inside this layer (this will always be true fo
r the root |
| 1681 // layer). | 1683 // layer). |
| 1682 return insideLayer; | 1684 return insideLayer; |
| 1683 } | 1685 } |
| 1684 | 1686 |
| 1685 Node* RenderLayer::enclosingElement() const | 1687 Node* Layer::enclosingElement() const |
| 1686 { | 1688 { |
| 1687 for (RenderObject* r = renderer(); r; r = r->parent()) { | 1689 for (RenderObject* r = renderer(); r; r = r->parent()) { |
| 1688 if (Node* e = r->node()) | 1690 if (Node* e = r->node()) |
| 1689 return e; | 1691 return e; |
| 1690 } | 1692 } |
| 1691 ASSERT_NOT_REACHED(); | 1693 ASSERT_NOT_REACHED(); |
| 1692 return 0; | 1694 return 0; |
| 1693 } | 1695 } |
| 1694 | 1696 |
| 1695 bool RenderLayer::isInTopLayer() const | 1697 bool Layer::isInTopLayer() const |
| 1696 { | 1698 { |
| 1697 Node* node = renderer()->node(); | 1699 Node* node = renderer()->node(); |
| 1698 return node && node->isElementNode() && toElement(node)->isInTopLayer(); | 1700 return node && node->isElementNode() && toElement(node)->isInTopLayer(); |
| 1699 } | 1701 } |
| 1700 | 1702 |
| 1701 // Compute the z-offset of the point in the transformState. | 1703 // Compute the z-offset of the point in the transformState. |
| 1702 // This is effectively projecting a ray normal to the plane of ancestor, finding
where that | 1704 // This is effectively projecting a ray normal to the plane of ancestor, finding
where that |
| 1703 // ray intersects target, and computing the z delta between those two points. | 1705 // ray intersects target, and computing the z delta between those two points. |
| 1704 static double computeZOffset(const HitTestingTransformState& transformState) | 1706 static double computeZOffset(const HitTestingTransformState& transformState) |
| 1705 { | 1707 { |
| 1706 // We got an affine transform, so no z-offset | 1708 // We got an affine transform, so no z-offset |
| 1707 if (transformState.m_accumulatedTransform.isAffine()) | 1709 if (transformState.m_accumulatedTransform.isAffine()) |
| 1708 return 0; | 1710 return 0; |
| 1709 | 1711 |
| 1710 // Flatten the point into the target plane | 1712 // Flatten the point into the target plane |
| 1711 FloatPoint targetPoint = transformState.mappedPoint(); | 1713 FloatPoint targetPoint = transformState.mappedPoint(); |
| 1712 | 1714 |
| 1713 // Now map the point back through the transform, which computes Z. | 1715 // Now map the point back through the transform, which computes Z. |
| 1714 FloatPoint3D backmappedPoint = transformState.m_accumulatedTransform.mapPoin
t(FloatPoint3D(targetPoint)); | 1716 FloatPoint3D backmappedPoint = transformState.m_accumulatedTransform.mapPoin
t(FloatPoint3D(targetPoint)); |
| 1715 return backmappedPoint.z(); | 1717 return backmappedPoint.z(); |
| 1716 } | 1718 } |
| 1717 | 1719 |
| 1718 PassRefPtr<HitTestingTransformState> RenderLayer::createLocalTransformState(Rend
erLayer* rootLayer, RenderLayer* containerLayer, | 1720 PassRefPtr<HitTestingTransformState> Layer::createLocalTransformState(Layer* roo
tLayer, Layer* containerLayer, |
| 1719 const LayoutRect& hitTestRect, const Hit
TestLocation& hitTestLocation, | 1721 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, |
| 1720 const HitTestingTransformState* containe
rTransformState, | 1722 const HitTestingTransformState* containerTransformState, |
| 1721 const LayoutPoint& translationOffset) co
nst | 1723 const LayoutPoint& translationOffset) const |
| 1722 { | 1724 { |
| 1723 RefPtr<HitTestingTransformState> transformState; | 1725 RefPtr<HitTestingTransformState> transformState; |
| 1724 LayoutPoint offset; | 1726 LayoutPoint offset; |
| 1725 if (containerTransformState) { | 1727 if (containerTransformState) { |
| 1726 // If we're already computing transform state, then it's relative to the
container (which we know is non-null). | 1728 // If we're already computing transform state, then it's relative to the
container (which we know is non-null). |
| 1727 transformState = HitTestingTransformState::create(*containerTransformSta
te); | 1729 transformState = HitTestingTransformState::create(*containerTransformSta
te); |
| 1728 convertToLayerCoords(containerLayer, offset); | 1730 convertToLayerCoords(containerLayer, offset); |
| 1729 } else { | 1731 } else { |
| 1730 // If this is the first time we need to make transform state, then base
it off of hitTestLocation, | 1732 // If this is the first time we need to make transform state, then base
it off of hitTestLocation, |
| 1731 // which is relative to rootLayer. | 1733 // which is relative to rootLayer. |
| 1732 transformState = HitTestingTransformState::create(hitTestLocation.transf
ormedPoint(), hitTestLocation.transformedRect(), FloatQuad(hitTestRect)); | 1734 transformState = HitTestingTransformState::create(hitTestLocation.transf
ormedPoint(), hitTestLocation.transformedRect(), FloatQuad(hitTestRect)); |
| 1733 convertToLayerCoords(rootLayer, offset); | 1735 convertToLayerCoords(rootLayer, offset); |
| 1734 } | 1736 } |
| 1735 offset.moveBy(translationOffset); | 1737 offset.moveBy(translationOffset); |
| 1736 | 1738 |
| 1737 RenderObject* containerRenderer = containerLayer ? containerLayer->renderer(
) : 0; | 1739 RenderObject* containerRenderer = containerLayer ? containerLayer->renderer(
) : 0; |
| 1738 if (renderer()->shouldUseTransformFromContainer(containerRenderer)) { | 1740 if (renderer()->shouldUseTransformFromContainer(containerRenderer)) { |
| 1739 TransformationMatrix containerTransform; | 1741 TransformationMatrix containerTransform; |
| 1740 renderer()->getTransformFromContainer(containerRenderer, toLayoutSize(of
fset), containerTransform); | 1742 renderer()->getTransformFromContainer(containerRenderer, toLayoutSize(of
fset), containerTransform); |
| 1741 transformState->applyTransform(containerTransform, HitTestingTransformSt
ate::AccumulateTransform); | 1743 transformState->applyTransform(containerTransform, HitTestingTransformSt
ate::AccumulateTransform); |
| 1742 } else { | 1744 } else { |
| 1743 transformState->translate(offset.x(), offset.y(), HitTestingTransformSta
te::AccumulateTransform); | 1745 transformState->translate(offset.x(), offset.y(), HitTestingTransformSta
te::AccumulateTransform); |
| 1744 } | 1746 } |
| 1745 | 1747 |
| 1746 return transformState; | 1748 return transformState; |
| 1747 } | 1749 } |
| 1748 | 1750 |
| 1749 | 1751 |
| 1750 static bool isHitCandidate(const RenderLayer* hitLayer, bool canDepthSort, doubl
e* zOffset, const HitTestingTransformState* transformState) | 1752 static bool isHitCandidate(const Layer* hitLayer, bool canDepthSort, double* zOf
fset, const HitTestingTransformState* transformState) |
| 1751 { | 1753 { |
| 1752 if (!hitLayer) | 1754 if (!hitLayer) |
| 1753 return false; | 1755 return false; |
| 1754 | 1756 |
| 1755 // The hit layer is depth-sorting with other layers, so just say that it was
hit. | 1757 // The hit layer is depth-sorting with other layers, so just say that it was
hit. |
| 1756 if (canDepthSort) | 1758 if (canDepthSort) |
| 1757 return true; | 1759 return true; |
| 1758 | 1760 |
| 1759 // We need to look at z-depth to decide if this layer was hit. | 1761 // We need to look at z-depth to decide if this layer was hit. |
| 1760 if (zOffset) { | 1762 if (zOffset) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1772 } | 1774 } |
| 1773 | 1775 |
| 1774 // hitTestLocation and hitTestRect are relative to rootLayer. | 1776 // hitTestLocation and hitTestRect are relative to rootLayer. |
| 1775 // A 'flattening' layer is one preserves3D() == false. | 1777 // A 'flattening' layer is one preserves3D() == false. |
| 1776 // transformState.m_accumulatedTransform holds the transform from the containing
flattening layer. | 1778 // transformState.m_accumulatedTransform holds the transform from the containing
flattening layer. |
| 1777 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the c
ontaining flattening layer. | 1779 // transformState.m_lastPlanarPoint is the hitTestLocation in the plane of the c
ontaining flattening layer. |
| 1778 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of
the containing flattening layer. | 1780 // transformState.m_lastPlanarQuad is the hitTestRect as a quad in the plane of
the containing flattening layer. |
| 1779 // | 1781 // |
| 1780 // If zOffset is non-null (which indicates that the caller wants z offset inform
ation), | 1782 // If zOffset is non-null (which indicates that the caller wants z offset inform
ation), |
| 1781 // *zOffset on return is the z offset of the hit point relative to the containi
ng flattening layer. | 1783 // *zOffset on return is the z offset of the hit point relative to the containi
ng flattening layer. |
| 1782 RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
ainerLayer, const HitTestRequest& request, HitTestResult& result, | 1784 Layer* Layer::hitTestLayer(Layer* rootLayer, Layer* containerLayer, const HitTes
tRequest& request, HitTestResult& result, |
| 1783 const LayoutRect& hitTestRect, const HitT
estLocation& hitTestLocation, bool appliedTransform, | 1785 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, bool
appliedTransform, |
| 1784 const HitTestingTransformState* transform
State, double* zOffset) | 1786 const HitTestingTransformState* transformState, double* zOffset) |
| 1785 { | 1787 { |
| 1786 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) | 1788 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) |
| 1787 return 0; | 1789 return 0; |
| 1788 | 1790 |
| 1789 // The natural thing would be to keep HitTestingTransformState on the stack,
but it's big, so we heap-allocate. | 1791 // The natural thing would be to keep HitTestingTransformState on the stack,
but it's big, so we heap-allocate. |
| 1790 | 1792 |
| 1791 // Apply a transform if we have one. | 1793 // Apply a transform if we have one. |
| 1792 if (transform() && !appliedTransform) { | 1794 if (transform() && !appliedTransform) { |
| 1793 if (enclosingPaginationLayer()) | 1795 if (enclosingPaginationLayer()) |
| 1794 return hitTestTransformedLayerInFragments(rootLayer, containerLayer,
request, result, hitTestRect, hitTestLocation, transformState, zOffset); | 1796 return hitTestTransformedLayerInFragments(rootLayer, containerLayer,
request, result, hitTestRect, hitTestLocation, transformState, zOffset); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1846 // Our layers can depth-test with our container, so share the z depth po
inter with the container, if it passed one down. | 1848 // Our layers can depth-test with our container, so share the z depth po
inter with the container, if it passed one down. |
| 1847 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset; | 1849 zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset; |
| 1848 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset; | 1850 zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset; |
| 1849 } else if (zOffset) { | 1851 } else if (zOffset) { |
| 1850 zOffsetForDescendantsPtr = 0; | 1852 zOffsetForDescendantsPtr = 0; |
| 1851 // Container needs us to give back a z offset for the hit layer. | 1853 // Container needs us to give back a z offset for the hit layer. |
| 1852 zOffsetForContentsPtr = zOffset; | 1854 zOffsetForContentsPtr = zOffset; |
| 1853 } | 1855 } |
| 1854 | 1856 |
| 1855 // This variable tracks which layer the mouse ends up being inside. | 1857 // This variable tracks which layer the mouse ends up being inside. |
| 1856 RenderLayer* candidateLayer = 0; | 1858 Layer* candidateLayer = 0; |
| 1857 | 1859 |
| 1858 // Begin by walking our list of positive layers from highest z-index down to
the lowest z-index. | 1860 // Begin by walking our list of positive layers from highest z-index down to
the lowest z-index. |
| 1859 RenderLayer* hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, r
equest, result, hitTestRect, hitTestLocation, | 1861 Layer* hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, request
, result, hitTestRect, hitTestLocation, |
| 1860 localTransformState.get(), zOffsetForDes
cendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants); | 1862 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattene
dTransformState.get(), depthSortDescendants); |
| 1861 if (hitLayer) { | 1863 if (hitLayer) { |
| 1862 if (!depthSortDescendants) | 1864 if (!depthSortDescendants) |
| 1863 return hitLayer; | 1865 return hitLayer; |
| 1864 candidateLayer = hitLayer; | 1866 candidateLayer = hitLayer; |
| 1865 } | 1867 } |
| 1866 | 1868 |
| 1867 // Now check our overflow objects. | 1869 // Now check our overflow objects. |
| 1868 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, h
itTestRect, hitTestLocation, | 1870 hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, h
itTestRect, hitTestLocation, |
| 1869 localTransformState.get(), zOffsetForDescendantsPtr,
zOffset, unflattenedTransformState.get(), depthSortDescendants); | 1871 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattene
dTransformState.get(), depthSortDescendants); |
| 1870 if (hitLayer) { | 1872 if (hitLayer) { |
| 1871 if (!depthSortDescendants) | 1873 if (!depthSortDescendants) |
| 1872 return hitLayer; | 1874 return hitLayer; |
| 1873 candidateLayer = hitLayer; | 1875 candidateLayer = hitLayer; |
| 1874 } | 1876 } |
| 1875 | 1877 |
| 1876 // Collect the fragments. This will compute the clip rectangles for each lay
er fragment. | 1878 // Collect the fragments. This will compute the clip rectangles for each lay
er fragment. |
| 1877 LayerFragments layerFragments; | 1879 LayerFragments layerFragments; |
| 1878 collectFragments(layerFragments, rootLayer, hitTestRect, RootRelativeClipRec
ts, IncludeOverlayScrollbarSize); | 1880 collectFragments(layerFragments, rootLayer, hitTestRect, RootRelativeClipRec
ts, IncludeOverlayScrollbarSize); |
| 1879 | 1881 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1891 if (hitTestContentsForFragments(layerFragments, request, tempResult, hit
TestLocation, HitTestDescendants, insideFragmentForegroundRect) | 1893 if (hitTestContentsForFragments(layerFragments, request, tempResult, hit
TestLocation, HitTestDescendants, insideFragmentForegroundRect) |
| 1892 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra
nsformState.get())) { | 1894 && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTra
nsformState.get())) { |
| 1893 if (result.isRectBasedTest()) | 1895 if (result.isRectBasedTest()) |
| 1894 result.append(tempResult); | 1896 result.append(tempResult); |
| 1895 else | 1897 else |
| 1896 result = tempResult; | 1898 result = tempResult; |
| 1897 if (!depthSortDescendants) | 1899 if (!depthSortDescendants) |
| 1898 return this; | 1900 return this; |
| 1899 // Foreground can depth-sort with descendant layers, so keep this as
a candidate. | 1901 // Foreground can depth-sort with descendant layers, so keep this as
a candidate. |
| 1900 candidateLayer = this; | 1902 candidateLayer = this; |
| 1901 } else if (insideFragmentForegroundRect && result.isRectBasedTest()) | 1903 } else if (insideFragmentForegroundRect && result.isRectBasedTest()) { |
| 1902 result.append(tempResult); | 1904 result.append(tempResult); |
| 1905 } |
| 1903 } | 1906 } |
| 1904 | 1907 |
| 1905 // Now check our negative z-index children. | 1908 // Now check our negative z-index children. |
| 1906 hitLayer = hitTestChildren(NegativeZOrderChildren, rootLayer, request, resul
t, hitTestRect, hitTestLocation, | 1909 hitLayer = hitTestChildren(NegativeZOrderChildren, rootLayer, request, resul
t, hitTestRect, hitTestLocation, |
| 1907 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattene
dTransformState.get(), depthSortDescendants); | 1910 localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattene
dTransformState.get(), depthSortDescendants); |
| 1908 if (hitLayer) { | 1911 if (hitLayer) { |
| 1909 if (!depthSortDescendants) | 1912 if (!depthSortDescendants) |
| 1910 return hitLayer; | 1913 return hitLayer; |
| 1911 candidateLayer = hitLayer; | 1914 candidateLayer = hitLayer; |
| 1912 } | 1915 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1926 result = tempResult; | 1929 result = tempResult; |
| 1927 return this; | 1930 return this; |
| 1928 } | 1931 } |
| 1929 if (insideFragmentBackgroundRect && result.isRectBasedTest()) | 1932 if (insideFragmentBackgroundRect && result.isRectBasedTest()) |
| 1930 result.append(tempResult); | 1933 result.append(tempResult); |
| 1931 } | 1934 } |
| 1932 | 1935 |
| 1933 return 0; | 1936 return 0; |
| 1934 } | 1937 } |
| 1935 | 1938 |
| 1936 bool RenderLayer::hitTestContentsForFragments(const LayerFragments& layerFragmen
ts, const HitTestRequest& request, HitTestResult& result, | 1939 bool Layer::hitTestContentsForFragments(const LayerFragments& layerFragments, co
nst HitTestRequest& request, HitTestResult& result, |
| 1937 const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter, bool& i
nsideClipRect) const | 1940 const HitTestLocation& hitTestLocation, HitTestFilter hitTestFilter, bool& i
nsideClipRect) const |
| 1938 { | 1941 { |
| 1939 if (layerFragments.isEmpty()) | 1942 if (layerFragments.isEmpty()) |
| 1940 return false; | 1943 return false; |
| 1941 | 1944 |
| 1942 for (int i = layerFragments.size() - 1; i >= 0; --i) { | 1945 for (int i = layerFragments.size() - 1; i >= 0; --i) { |
| 1943 const LayerFragment& fragment = layerFragments.at(i); | 1946 const LayerFragment& fragment = layerFragments.at(i); |
| 1944 if ((hitTestFilter == HitTestSelf && !fragment.backgroundRect.intersects
(hitTestLocation)) | 1947 if ((hitTestFilter == HitTestSelf && !fragment.backgroundRect.intersects
(hitTestLocation)) |
| 1945 || (hitTestFilter == HitTestDescendants && !fragment.foregroundRect.
intersects(hitTestLocation))) | 1948 || (hitTestFilter == HitTestDescendants && !fragment.foregroundRect.
intersects(hitTestLocation))) |
| 1946 continue; | 1949 continue; |
| 1947 insideClipRect = true; | 1950 insideClipRect = true; |
| 1948 if (hitTestContents(request, result, fragment.layerBounds, hitTestLocati
on, hitTestFilter)) | 1951 if (hitTestContents(request, result, fragment.layerBounds, hitTestLocati
on, hitTestFilter)) |
| 1949 return true; | 1952 return true; |
| 1950 } | 1953 } |
| 1951 | 1954 |
| 1952 return false; | 1955 return false; |
| 1953 } | 1956 } |
| 1954 | 1957 |
| 1955 RenderLayer* RenderLayer::hitTestTransformedLayerInFragments(RenderLayer* rootLa
yer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult&
result, | 1958 Layer* Layer::hitTestTransformedLayerInFragments(Layer* rootLayer, Layer* contai
nerLayer, const HitTestRequest& request, HitTestResult& result, |
| 1956 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const
HitTestingTransformState* transformState, double* zOffset) | 1959 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const
HitTestingTransformState* transformState, double* zOffset) |
| 1957 { | 1960 { |
| 1958 LayerFragments enclosingPaginationFragments; | 1961 LayerFragments enclosingPaginationFragments; |
| 1959 LayoutPoint offsetOfPaginationLayerFromRoot; | 1962 LayoutPoint offsetOfPaginationLayerFromRoot; |
| 1960 // FIXME: We're missing a sub-pixel offset here crbug.com/348728 | 1963 // FIXME: We're missing a sub-pixel offset here crbug.com/348728 |
| 1961 LayoutRect transformedExtent = transparencyClipBox(this, enclosingPagination
Layer(), HitTestingTransparencyClipBox, RenderLayer::RootOfTransparencyClipBox,
LayoutSize()); | 1964 LayoutRect transformedExtent = transparencyClipBox(this, enclosingPagination
Layer(), HitTestingTransparencyClipBox, Layer::RootOfTransparencyClipBox, Layout
Size()); |
| 1962 enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, r
ootLayer, hitTestRect, | 1965 enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, r
ootLayer, hitTestRect, |
| 1963 RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip,
&offsetOfPaginationLayerFromRoot, LayoutSize(), &transformedExtent); | 1966 RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip,
&offsetOfPaginationLayerFromRoot, LayoutSize(), &transformedExtent); |
| 1964 | 1967 |
| 1965 for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) { | 1968 for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) { |
| 1966 const LayerFragment& fragment = enclosingPaginationFragments.at(i); | 1969 const LayerFragment& fragment = enclosingPaginationFragments.at(i); |
| 1967 | 1970 |
| 1968 // Apply the page/column clip for this fragment, as well as any clips es
tablished by layers in between us and | 1971 // Apply the page/column clip for this fragment, as well as any clips es
tablished by layers in between us and |
| 1969 // the enclosing pagination layer. | 1972 // the enclosing pagination layer. |
| 1970 LayoutRect clipRect = fragment.backgroundRect.rect(); | 1973 LayoutRect clipRect = fragment.backgroundRect.rect(); |
| 1971 | 1974 |
| 1972 // Now compute the clips within a given fragment | 1975 // Now compute the clips within a given fragment |
| 1973 if (parent() != enclosingPaginationLayer()) { | 1976 if (parent() != enclosingPaginationLayer()) { |
| 1974 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOf
PaginationLayerFromRoot); | 1977 enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOf
PaginationLayerFromRoot); |
| 1975 LayoutRect parentClipRect = clipper().backgroundClipRect(ClipRectsCo
ntext(enclosingPaginationLayer(), RootRelativeClipRects, IncludeOverlayScrollbar
Size)).rect(); | 1978 LayoutRect parentClipRect = clipper().backgroundClipRect(ClipRectsCo
ntext(enclosingPaginationLayer(), RootRelativeClipRects, IncludeOverlayScrollbar
Size)).rect(); |
| 1976 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPagination
LayerFromRoot); | 1979 parentClipRect.moveBy(fragment.paginationOffset + offsetOfPagination
LayerFromRoot); |
| 1977 clipRect.intersect(parentClipRect); | 1980 clipRect.intersect(parentClipRect); |
| 1978 } | 1981 } |
| 1979 | 1982 |
| 1980 if (!hitTestLocation.intersects(clipRect)) | 1983 if (!hitTestLocation.intersects(clipRect)) |
| 1981 continue; | 1984 continue; |
| 1982 | 1985 |
| 1983 RenderLayer* hitLayer = hitTestLayerByApplyingTransform(rootLayer, conta
inerLayer, request, result, hitTestRect, hitTestLocation, | 1986 Layer* hitLayer = hitTestLayerByApplyingTransform(rootLayer, containerLa
yer, request, result, hitTestRect, hitTestLocation, |
| 1984 transformState, zOffset, fragment.paginationOffset); | 1987 transformState, zOffset, fragment.paginationOffset); |
| 1985 if (hitLayer) | 1988 if (hitLayer) |
| 1986 return hitLayer; | 1989 return hitLayer; |
| 1987 } | 1990 } |
| 1988 | 1991 |
| 1989 return 0; | 1992 return 0; |
| 1990 } | 1993 } |
| 1991 | 1994 |
| 1992 RenderLayer* RenderLayer::hitTestLayerByApplyingTransform(RenderLayer* rootLayer
, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& res
ult, | 1995 Layer* Layer::hitTestLayerByApplyingTransform(Layer* rootLayer, Layer* container
Layer, const HitTestRequest& request, HitTestResult& result, |
| 1993 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const
HitTestingTransformState* transformState, double* zOffset, | 1996 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const
HitTestingTransformState* transformState, double* zOffset, |
| 1994 const LayoutPoint& translationOffset) | 1997 const LayoutPoint& translationOffset) |
| 1995 { | 1998 { |
| 1996 // Create a transform state to accumulate this transform. | 1999 // Create a transform state to accumulate this transform. |
| 1997 RefPtr<HitTestingTransformState> newTransformState = createLocalTransformSta
te(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState, tran
slationOffset); | 2000 RefPtr<HitTestingTransformState> newTransformState = createLocalTransformSta
te(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState, tran
slationOffset); |
| 1998 | 2001 |
| 1999 // If the transform can't be inverted, then don't hit test this layer at all
. | 2002 // If the transform can't be inverted, then don't hit test this layer at all
. |
| 2000 if (!newTransformState->m_accumulatedTransform.isInvertible()) | 2003 if (!newTransformState->m_accumulatedTransform.isInvertible()) |
| 2001 return 0; | 2004 return 0; |
| 2002 | 2005 |
| 2003 // Compute the point and the hit test rect in the coords of this layer by us
ing the values | 2006 // Compute the point and the hit test rect in the coords of this layer by us
ing the values |
| 2004 // from the transformState, which store the point and quad in the coords of
the last flattened | 2007 // from the transformState, which store the point and quad in the coords of
the last flattened |
| 2005 // layer, and the accumulated transform which lets up map through preserve-3
d layers. | 2008 // layer, and the accumulated transform which lets up map through preserve-3
d layers. |
| 2006 // | 2009 // |
| 2007 // We can't just map hitTestLocation and hitTestRect because they may have b
een flattened (losing z) | 2010 // We can't just map hitTestLocation and hitTestRect because they may have b
een flattened (losing z) |
| 2008 // by our container. | 2011 // by our container. |
| 2009 FloatPoint localPoint = newTransformState->mappedPoint(); | 2012 FloatPoint localPoint = newTransformState->mappedPoint(); |
| 2010 FloatQuad localPointQuad = newTransformState->mappedQuad(); | 2013 FloatQuad localPointQuad = newTransformState->mappedQuad(); |
| 2011 LayoutRect localHitTestRect = newTransformState->boundsOfMappedArea(); | 2014 LayoutRect localHitTestRect = newTransformState->boundsOfMappedArea(); |
| 2012 HitTestLocation newHitTestLocation; | 2015 HitTestLocation newHitTestLocation; |
| 2013 if (hitTestLocation.isRectBasedTest()) | 2016 if (hitTestLocation.isRectBasedTest()) |
| 2014 newHitTestLocation = HitTestLocation(localPoint, localPointQuad); | 2017 newHitTestLocation = HitTestLocation(localPoint, localPointQuad); |
| 2015 else | 2018 else |
| 2016 newHitTestLocation = HitTestLocation(localPoint); | 2019 newHitTestLocation = HitTestLocation(localPoint); |
| 2017 | 2020 |
| 2018 // Now do a hit test with the root layer shifted to be us. | 2021 // Now do a hit test with the root layer shifted to be us. |
| 2019 return hitTestLayer(this, containerLayer, request, result, localHitTestRect,
newHitTestLocation, true, newTransformState.get(), zOffset); | 2022 return hitTestLayer(this, containerLayer, request, result, localHitTestRect,
newHitTestLocation, true, newTransformState.get(), zOffset); |
| 2020 } | 2023 } |
| 2021 | 2024 |
| 2022 bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult&
result, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation, H
itTestFilter hitTestFilter) const | 2025 bool Layer::hitTestContents(const HitTestRequest& request, HitTestResult& result
, const LayoutRect& layerBounds, const HitTestLocation& hitTestLocation, HitTest
Filter hitTestFilter) const |
| 2023 { | 2026 { |
| 2024 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); | 2027 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); |
| 2025 | 2028 |
| 2026 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(lay
erBounds.location() - renderBoxLocation()), hitTestFilter)) { | 2029 if (!renderer()->hitTest(request, result, hitTestLocation, toLayoutPoint(lay
erBounds.location() - renderBoxLocation()), hitTestFilter)) { |
| 2027 // It's wrong to set innerNode, but then claim that you didn't hit anyth
ing, unless it is | 2030 // It's wrong to set innerNode, but then claim that you didn't hit anyth
ing, unless it is |
| 2028 // a rect-based test. | 2031 // a rect-based test. |
| 2029 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBa
sedTestResult().size())); | 2032 ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBa
sedTestResult().size())); |
| 2030 return false; | 2033 return false; |
| 2031 } | 2034 } |
| 2032 | 2035 |
| 2033 // For positioned generated content, we might still not have a | 2036 // For positioned generated content, we might still not have a |
| 2034 // node by the time we get to the layer level, since none of | 2037 // node by the time we get to the layer level, since none of |
| 2035 // the content in the layer has an element. So just walk up | 2038 // the content in the layer has an element. So just walk up |
| 2036 // the tree. | 2039 // the tree. |
| 2037 if (!result.innerNode() || !result.innerNonSharedNode()) { | 2040 if (!result.innerNode() || !result.innerNonSharedNode()) { |
| 2038 Node* e = enclosingElement(); | 2041 Node* e = enclosingElement(); |
| 2039 if (!result.innerNode()) | 2042 if (!result.innerNode()) |
| 2040 result.setInnerNode(e); | 2043 result.setInnerNode(e); |
| 2041 if (!result.innerNonSharedNode()) | 2044 if (!result.innerNonSharedNode()) |
| 2042 result.setInnerNonSharedNode(e); | 2045 result.setInnerNonSharedNode(e); |
| 2043 } | 2046 } |
| 2044 | 2047 |
| 2045 return true; | 2048 return true; |
| 2046 } | 2049 } |
| 2047 | 2050 |
| 2048 RenderLayer* RenderLayer::hitTestChildren(ChildrenIteration childrentoVisit, Ren
derLayer* rootLayer, | 2051 Layer* Layer::hitTestChildren(ChildrenIteration childrentoVisit, Layer* rootLaye
r, |
| 2049 const HitTestRequest& request, HitTestResult& result, | 2052 const HitTestRequest& request, HitTestResult& result, |
| 2050 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, | 2053 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, |
| 2051 const HitTestingTransformState* transformState, | 2054 const HitTestingTransformState* transformState, |
| 2052 double* zOffsetForDescendants, double* zOffset, | 2055 double* zOffsetForDescendants, double* zOffset, |
| 2053 const HitTestingTransformState* unflattenedTransformState, | 2056 const HitTestingTransformState* unflattenedTransformState, |
| 2054 bool depthSortDescendants) | 2057 bool depthSortDescendants) |
| 2055 { | 2058 { |
| 2056 if (!hasSelfPaintingLayerDescendant()) | 2059 if (!hasSelfPaintingLayerDescendant()) |
| 2057 return 0; | 2060 return 0; |
| 2058 | 2061 |
| 2059 RenderLayer* resultLayer = 0; | 2062 Layer* resultLayer = 0; |
| 2060 RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoV
isit); | 2063 LayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoVisit); |
| 2061 while (RenderLayerStackingNode* child = iterator.next()) { | 2064 while (LayerStackingNode* child = iterator.next()) { |
| 2062 RenderLayer* childLayer = child->layer(); | 2065 Layer* childLayer = child->layer(); |
| 2063 RenderLayer* hitLayer = 0; | 2066 Layer* hitLayer = 0; |
| 2064 HitTestResult tempResult(result.hitTestLocation()); | 2067 HitTestResult tempResult(result.hitTestLocation()); |
| 2065 if (childLayer->isPaginated()) | 2068 if (childLayer->isPaginated()) |
| 2066 hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, request
, tempResult, hitTestRect, hitTestLocation, transformState, zOffsetForDescendant
s); | 2069 hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, request
, tempResult, hitTestRect, hitTestLocation, transformState, zOffsetForDescendant
s); |
| 2067 else | 2070 else |
| 2068 hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempRe
sult, hitTestRect, hitTestLocation, false, transformState, zOffsetForDescendants
); | 2071 hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempRe
sult, hitTestRect, hitTestLocation, false, transformState, zOffsetForDescendants
); |
| 2069 | 2072 |
| 2070 // If it a rect-based test, we can safely append the temporary result si
nce it might had hit | 2073 // If it a rect-based test, we can safely append the temporary result si
nce it might had hit |
| 2071 // nodes but not necesserily had hitLayer set. | 2074 // nodes but not necesserily had hitLayer set. |
| 2072 if (result.isRectBasedTest()) | 2075 if (result.isRectBasedTest()) |
| 2073 result.append(tempResult); | 2076 result.append(tempResult); |
| 2074 | 2077 |
| 2075 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedT
ransformState)) { | 2078 if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedT
ransformState)) { |
| 2076 resultLayer = hitLayer; | 2079 resultLayer = hitLayer; |
| 2077 if (!result.isRectBasedTest()) | 2080 if (!result.isRectBasedTest()) |
| 2078 result = tempResult; | 2081 result = tempResult; |
| 2079 if (!depthSortDescendants) | 2082 if (!depthSortDescendants) |
| 2080 break; | 2083 break; |
| 2081 } | 2084 } |
| 2082 } | 2085 } |
| 2083 | 2086 |
| 2084 return resultLayer; | 2087 return resultLayer; |
| 2085 } | 2088 } |
| 2086 | 2089 |
| 2087 RenderLayer* RenderLayer::hitTestPaginatedChildLayer(RenderLayer* childLayer, Re
nderLayer* rootLayer, const HitTestRequest& request, HitTestResult& result, | 2090 Layer* Layer::hitTestPaginatedChildLayer(Layer* childLayer, Layer* rootLayer, co
nst HitTestRequest& request, HitTestResult& result, |
| 2088 const LayoutRect& hitTestRe
ct, const HitTestLocation& hitTestLocation, const HitTestingTransformState* tran
sformState, double* zOffset) | 2091 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const
HitTestingTransformState* transformState, double* zOffset) |
| 2089 { | 2092 { |
| 2090 Vector<RenderLayer*> columnLayers; | 2093 Vector<Layer*> columnLayers; |
| 2091 RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ?
parent()->stackingNode() : m_stackingNode->ancestorStackingContextNode(); | 2094 LayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? paren
t()->stackingNode() : m_stackingNode->ancestorStackingContextNode(); |
| 2092 for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent())
{ | 2095 for (Layer* curr = childLayer->parent(); curr; curr = curr->parent()) { |
| 2093 if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagina
tion(childLayer->renderer(), curr->renderBox())) | 2096 if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagina
tion(childLayer->renderer(), curr->renderBox())) |
| 2094 columnLayers.append(curr); | 2097 columnLayers.append(curr); |
| 2095 if (curr->stackingNode() == ancestorNode) | 2098 if (curr->stackingNode() == ancestorNode) |
| 2096 break; | 2099 break; |
| 2097 } | 2100 } |
| 2098 | 2101 |
| 2099 ASSERT(columnLayers.size()); | 2102 ASSERT(columnLayers.size()); |
| 2100 return hitTestChildLayerColumns(childLayer, rootLayer, request, result, hitT
estRect, hitTestLocation, transformState, zOffset, | 2103 return hitTestChildLayerColumns(childLayer, rootLayer, request, result, hitT
estRect, hitTestLocation, transformState, zOffset, |
| 2101 columnLayers, columnLayers.size() - 1); | 2104 columnLayers, columnLayers.size() - 1); |
| 2102 } | 2105 } |
| 2103 | 2106 |
| 2104 RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
erLayer* rootLayer, const HitTestRequest& request, HitTestResult& result, | 2107 Layer* Layer::hitTestChildLayerColumns(Layer* childLayer, Layer* rootLayer, cons
t HitTestRequest& request, HitTestResult& result, |
| 2105 const LayoutRect& hitTestRect
, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transf
ormState, double* zOffset, | 2108 const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const
HitTestingTransformState* transformState, double* zOffset, |
| 2106 const Vector<RenderLayer*>& c
olumnLayers, size_t columnIndex) | 2109 const Vector<Layer*>& columnLayers, size_t columnIndex) |
| 2107 { | 2110 { |
| 2108 RenderBlock* columnBlock = toRenderBlock(columnLayers[columnIndex]->renderer
()); | 2111 RenderBlock* columnBlock = toRenderBlock(columnLayers[columnIndex]->renderer
()); |
| 2109 | 2112 |
| 2110 ASSERT(columnBlock && columnBlock->hasColumns()); | 2113 ASSERT(columnBlock && columnBlock->hasColumns()); |
| 2111 if (!columnBlock || !columnBlock->hasColumns()) | 2114 if (!columnBlock || !columnBlock->hasColumns()) |
| 2112 return 0; | 2115 return 0; |
| 2113 | 2116 |
| 2114 LayoutPoint layerOffset; | 2117 LayoutPoint layerOffset; |
| 2115 columnBlock->layer()->convertToLayerCoords(rootLayer, layerOffset); | 2118 columnBlock->layer()->convertToLayerCoords(rootLayer, layerOffset); |
| 2116 | 2119 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2153 else | 2156 else |
| 2154 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnB
lock->borderLeft() - columnBlock->paddingLeft(), 0); | 2157 offset = LayoutSize(colRect.x() + currLogicalTopOffset - columnB
lock->borderLeft() - columnBlock->paddingLeft(), 0); |
| 2155 } | 2158 } |
| 2156 | 2159 |
| 2157 colRect.moveBy(layerOffset); | 2160 colRect.moveBy(layerOffset); |
| 2158 | 2161 |
| 2159 LayoutRect localClipRect(hitTestRect); | 2162 LayoutRect localClipRect(hitTestRect); |
| 2160 localClipRect.intersect(colRect); | 2163 localClipRect.intersect(colRect); |
| 2161 | 2164 |
| 2162 if (!localClipRect.isEmpty() && hitTestLocation.intersects(localClipRect
)) { | 2165 if (!localClipRect.isEmpty() && hitTestLocation.intersects(localClipRect
)) { |
| 2163 RenderLayer* hitLayer = 0; | 2166 Layer* hitLayer = 0; |
| 2164 if (!columnIndex) { | 2167 if (!columnIndex) { |
| 2165 // Apply a translation transform to change where the layer paint
s. | 2168 // Apply a translation transform to change where the layer paint
s. |
| 2166 TransformationMatrix oldTransform; | 2169 TransformationMatrix oldTransform; |
| 2167 bool oldHasTransform = childLayer->transform(); | 2170 bool oldHasTransform = childLayer->transform(); |
| 2168 if (oldHasTransform) | 2171 if (oldHasTransform) |
| 2169 oldTransform = *childLayer->transform(); | 2172 oldTransform = *childLayer->transform(); |
| 2170 TransformationMatrix newTransform(oldTransform); | 2173 TransformationMatrix newTransform(oldTransform); |
| 2171 newTransform.translateRight(offset.width(), offset.height()); | 2174 newTransform.translateRight(offset.width(), offset.height()); |
| 2172 | 2175 |
| 2173 childLayer->m_transform = adoptPtr(new TransformationMatrix(newT
ransform)); | 2176 childLayer->m_transform = adoptPtr(new TransformationMatrix(newT
ransform)); |
| 2174 hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0],
request, result, localClipRect, hitTestLocation, false, transformState, zOffset)
; | 2177 hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0],
request, result, localClipRect, hitTestLocation, false, transformState, zOffset)
; |
| 2175 if (oldHasTransform) | 2178 if (oldHasTransform) |
| 2176 childLayer->m_transform = adoptPtr(new TransformationMatrix(
oldTransform)); | 2179 childLayer->m_transform = adoptPtr(new TransformationMatrix(
oldTransform)); |
| 2177 else | 2180 else |
| 2178 childLayer->m_transform.clear(); | 2181 childLayer->m_transform.clear(); |
| 2179 } else { | 2182 } else { |
| 2180 // Adjust the transform such that the renderer's upper left corn
er will be at (0,0) in user space. | 2183 // Adjust the transform such that the renderer's upper left corn
er will be at (0,0) in user space. |
| 2181 // This involves subtracting out the position of the layer in ou
r current coordinate space. | 2184 // This involves subtracting out the position of the layer in ou
r current coordinate space. |
| 2182 RenderLayer* nextLayer = columnLayers[columnIndex - 1]; | 2185 Layer* nextLayer = columnLayers[columnIndex - 1]; |
| 2183 RefPtr<HitTestingTransformState> newTransformState = nextLayer->
createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestLocation,
transformState); | 2186 RefPtr<HitTestingTransformState> newTransformState = nextLayer->
createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestLocation,
transformState); |
| 2184 newTransformState->translate(offset.width(), offset.height(), Hi
tTestingTransformState::AccumulateTransform); | 2187 newTransformState->translate(offset.width(), offset.height(), Hi
tTestingTransformState::AccumulateTransform); |
| 2185 FloatPoint localPoint = newTransformState->mappedPoint(); | 2188 FloatPoint localPoint = newTransformState->mappedPoint(); |
| 2186 FloatQuad localPointQuad = newTransformState->mappedQuad(); | 2189 FloatQuad localPointQuad = newTransformState->mappedQuad(); |
| 2187 LayoutRect localHitTestRect = newTransformState->mappedArea().en
closingBoundingBox(); | 2190 LayoutRect localHitTestRect = newTransformState->mappedArea().en
closingBoundingBox(); |
| 2188 HitTestLocation newHitTestLocation; | 2191 HitTestLocation newHitTestLocation; |
| 2189 if (hitTestLocation.isRectBasedTest()) | 2192 if (hitTestLocation.isRectBasedTest()) |
| 2190 newHitTestLocation = HitTestLocation(localPoint, localPointQ
uad); | 2193 newHitTestLocation = HitTestLocation(localPoint, localPointQ
uad); |
| 2191 else | 2194 else |
| 2192 newHitTestLocation = HitTestLocation(localPoint); | 2195 newHitTestLocation = HitTestLocation(localPoint); |
| 2193 newTransformState->flatten(); | 2196 newTransformState->flatten(); |
| 2194 | 2197 |
| 2195 hitLayer = hitTestChildLayerColumns(childLayer, columnLayers[col
umnIndex - 1], request, result, localHitTestRect, newHitTestLocation, | 2198 hitLayer = hitTestChildLayerColumns(childLayer, columnLayers[col
umnIndex - 1], request, result, localHitTestRect, newHitTestLocation, |
| 2196 newTransformState.get(), zOf
fset, columnLayers, columnIndex - 1); | 2199 newTransformState.get(), zOffset, columnLayers, columnIndex
- 1); |
| 2197 } | 2200 } |
| 2198 | 2201 |
| 2199 if (hitLayer) | 2202 if (hitLayer) |
| 2200 return hitLayer; | 2203 return hitLayer; |
| 2201 } | 2204 } |
| 2202 } | 2205 } |
| 2203 | 2206 |
| 2204 return 0; | 2207 return 0; |
| 2205 } | 2208 } |
| 2206 | 2209 |
| 2207 void RenderLayer::blockSelectionGapsBoundsChanged() | 2210 void Layer::blockSelectionGapsBoundsChanged() |
| 2208 { | 2211 { |
| 2209 setNeedsCompositingInputsUpdate(); | 2212 setNeedsCompositingInputsUpdate(); |
| 2210 } | 2213 } |
| 2211 | 2214 |
| 2212 void RenderLayer::addBlockSelectionGapsBounds(const LayoutRect& bounds) | 2215 void Layer::addBlockSelectionGapsBounds(const LayoutRect& bounds) |
| 2213 { | 2216 { |
| 2214 m_blockSelectionGapsBounds.unite(enclosingIntRect(bounds)); | 2217 m_blockSelectionGapsBounds.unite(enclosingIntRect(bounds)); |
| 2215 blockSelectionGapsBoundsChanged(); | 2218 blockSelectionGapsBoundsChanged(); |
| 2216 } | 2219 } |
| 2217 | 2220 |
| 2218 void RenderLayer::clearBlockSelectionGapsBounds() | 2221 void Layer::clearBlockSelectionGapsBounds() |
| 2219 { | 2222 { |
| 2220 m_blockSelectionGapsBounds = IntRect(); | 2223 m_blockSelectionGapsBounds = IntRect(); |
| 2221 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) | 2224 for (Layer* child = firstChild(); child; child = child->nextSibling()) |
| 2222 child->clearBlockSelectionGapsBounds(); | 2225 child->clearBlockSelectionGapsBounds(); |
| 2223 blockSelectionGapsBoundsChanged(); | 2226 blockSelectionGapsBoundsChanged(); |
| 2224 } | 2227 } |
| 2225 | 2228 |
| 2226 void RenderLayer::invalidatePaintForBlockSelectionGaps() | 2229 void Layer::invalidatePaintForBlockSelectionGaps() |
| 2227 { | 2230 { |
| 2228 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) | 2231 for (Layer* child = firstChild(); child; child = child->nextSibling()) |
| 2229 child->invalidatePaintForBlockSelectionGaps(); | 2232 child->invalidatePaintForBlockSelectionGaps(); |
| 2230 | 2233 |
| 2231 if (m_blockSelectionGapsBounds.isEmpty()) | 2234 if (m_blockSelectionGapsBounds.isEmpty()) |
| 2232 return; | 2235 return; |
| 2233 | 2236 |
| 2234 LayoutRect rect = m_blockSelectionGapsBounds; | 2237 LayoutRect rect = m_blockSelectionGapsBounds; |
| 2235 if (renderer()->hasOverflowClip()) { | 2238 if (renderer()->hasOverflowClip()) { |
| 2236 RenderBox* box = renderBox(); | 2239 RenderBox* box = renderBox(); |
| 2237 rect.move(-box->scrolledContentOffset()); | 2240 rect.move(-box->scrolledContentOffset()); |
| 2238 if (!scrollableArea()->usesCompositedScrolling()) | 2241 if (!scrollableArea()->usesCompositedScrolling()) |
| 2239 rect.intersect(box->overflowClipRect(LayoutPoint())); | 2242 rect.intersect(box->overflowClipRect(LayoutPoint())); |
| 2240 } | 2243 } |
| 2241 if (renderer()->hasClip()) | 2244 if (renderer()->hasClip()) |
| 2242 rect.intersect(toRenderBox(renderer())->clipRect(LayoutPoint())); | 2245 rect.intersect(toRenderBox(renderer())->clipRect(LayoutPoint())); |
| 2243 if (!rect.isEmpty()) | 2246 if (!rect.isEmpty()) |
| 2244 renderer()->invalidatePaintRectangle(rect); | 2247 renderer()->invalidatePaintRectangle(rect); |
| 2245 } | 2248 } |
| 2246 | 2249 |
| 2247 IntRect RenderLayer::blockSelectionGapsBounds() const | 2250 IntRect Layer::blockSelectionGapsBounds() const |
| 2248 { | 2251 { |
| 2249 if (!renderer()->isRenderBlockFlow()) | 2252 if (!renderer()->isRenderBlockFlow()) |
| 2250 return IntRect(); | 2253 return IntRect(); |
| 2251 | 2254 |
| 2252 RenderBlockFlow* renderBlockFlow = toRenderBlockFlow(renderer()); | 2255 RenderBlockFlow* renderBlockFlow = toRenderBlockFlow(renderer()); |
| 2253 LayoutRect gapRects = renderBlockFlow->selectionGapRectsForPaintInvalidation
(renderBlockFlow); | 2256 LayoutRect gapRects = renderBlockFlow->selectionGapRectsForPaintInvalidation
(renderBlockFlow); |
| 2254 | 2257 |
| 2255 return pixelSnappedIntRect(gapRects); | 2258 return pixelSnappedIntRect(gapRects); |
| 2256 } | 2259 } |
| 2257 | 2260 |
| 2258 bool RenderLayer::hasBlockSelectionGapBounds() const | 2261 bool Layer::hasBlockSelectionGapBounds() const |
| 2259 { | 2262 { |
| 2260 // FIXME: it would be more accurate to return !blockSelectionGapsBounds().is
Empty(), but this is impossible | 2263 // FIXME: it would be more accurate to return !blockSelectionGapsBounds().is
Empty(), but this is impossible |
| 2261 // at the moment because it causes invalid queries to layout-dependent code
(crbug.com/372802). | 2264 // at the moment because it causes invalid queries to layout-dependent code
(crbug.com/372802). |
| 2262 // ASSERT(renderer()->document().lifecycle().state() >= DocumentLifecycle::L
ayoutClean); | 2265 // ASSERT(renderer()->document().lifecycle().state() >= DocumentLifecycle::L
ayoutClean); |
| 2263 | 2266 |
| 2264 if (!renderer()->isRenderBlock()) | 2267 if (!renderer()->isRenderBlock()) |
| 2265 return false; | 2268 return false; |
| 2266 | 2269 |
| 2267 return toRenderBlock(renderer())->shouldPaintSelectionGaps(); | 2270 return toRenderBlock(renderer())->shouldPaintSelectionGaps(); |
| 2268 } | 2271 } |
| 2269 | 2272 |
| 2270 bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const Layo
utRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromR
oot) const | 2273 bool Layer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect
& damageRect, const Layer* rootLayer, const LayoutPoint* offsetFromRoot) const |
| 2271 { | 2274 { |
| 2272 // Always examine the canvas and the root. | 2275 // Always examine the canvas and the root. |
| 2273 // FIXME: Could eliminate the isDocumentElement() check if we fix background
painting so that the RenderView | 2276 // FIXME: Could eliminate the isDocumentElement() check if we fix background
painting so that the RenderView |
| 2274 // paints the root's background. | 2277 // paints the root's background. |
| 2275 if (isRootLayer() || renderer()->isDocumentElement()) | 2278 if (isRootLayer() || renderer()->isDocumentElement()) |
| 2276 return true; | 2279 return true; |
| 2277 | 2280 |
| 2278 // If we aren't an inline flow, and our layer bounds do intersect the damage
rect, then we | 2281 // If we aren't an inline flow, and our layer bounds do intersect the damage
rect, then we |
| 2279 // can go ahead and return true. | 2282 // can go ahead and return true. |
| 2280 RenderView* view = renderer()->view(); | 2283 RenderView* view = renderer()->view(); |
| 2281 ASSERT(view); | 2284 ASSERT(view); |
| 2282 if (view && !renderer()->isRenderInline()) { | 2285 if (view && !renderer()->isRenderInline()) { |
| 2283 if (layerBounds.intersects(damageRect)) | 2286 if (layerBounds.intersects(damageRect)) |
| 2284 return true; | 2287 return true; |
| 2285 } | 2288 } |
| 2286 | 2289 |
| 2287 // Otherwise we need to compute the bounding box of this single layer and se
e if it intersects | 2290 // Otherwise we need to compute the bounding box of this single layer and se
e if it intersects |
| 2288 // the damage rect. | 2291 // the damage rect. |
| 2289 return physicalBoundingBox(rootLayer, offsetFromRoot).intersects(damageRect)
; | 2292 return physicalBoundingBox(rootLayer, offsetFromRoot).intersects(damageRect)
; |
| 2290 } | 2293 } |
| 2291 | 2294 |
| 2292 LayoutRect RenderLayer::logicalBoundingBox() const | 2295 LayoutRect Layer::logicalBoundingBox() const |
| 2293 { | 2296 { |
| 2294 // There are three special cases we need to consider. | 2297 // There are three special cases we need to consider. |
| 2295 // (1) Inline Flows. For inline flows we will create a bounding box that fu
lly encompasses all of the lines occupied by the | 2298 // (1) Inline Flows. For inline flows we will create a bounding box that fu
lly encompasses all of the lines occupied by the |
| 2296 // inline. In other words, if some <span> wraps to three lines, we'll creat
e a bounding box that fully encloses the | 2299 // inline. In other words, if some <span> wraps to three lines, we'll creat
e a bounding box that fully encloses the |
| 2297 // line boxes of all three lines (including overflow on those lines). | 2300 // line boxes of all three lines (including overflow on those lines). |
| 2298 // (2) Left/Top Overflow. The width/height of layers already includes right
/bottom overflow. However, in the case of left/top | 2301 // (2) Left/Top Overflow. The width/height of layers already includes right
/bottom overflow. However, in the case of left/top |
| 2299 // overflow, we have to create a bounding box that will extend to include th
is overflow. | 2302 // overflow, we have to create a bounding box that will extend to include th
is overflow. |
| 2300 // (3) Floats. When a layer has overhanging floats that it paints, we need
to make sure to include these overhanging floats | 2303 // (3) Floats. When a layer has overhanging floats that it paints, we need
to make sure to include these overhanging floats |
| 2301 // as part of our bounding box. We do this because we are the responsible l
ayer for both hit testing and painting those | 2304 // as part of our bounding box. We do this because we are the responsible l
ayer for both hit testing and painting those |
| 2302 // floats. | 2305 // floats. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2328 static inline LayoutRect flippedLogicalBoundingBox(LayoutRect boundingBox, Rende
rObject* renderer) | 2331 static inline LayoutRect flippedLogicalBoundingBox(LayoutRect boundingBox, Rende
rObject* renderer) |
| 2329 { | 2332 { |
| 2330 LayoutRect result = boundingBox; | 2333 LayoutRect result = boundingBox; |
| 2331 if (renderer->isBox()) | 2334 if (renderer->isBox()) |
| 2332 toRenderBox(renderer)->flipForWritingMode(result); | 2335 toRenderBox(renderer)->flipForWritingMode(result); |
| 2333 else | 2336 else |
| 2334 renderer->containingBlock()->flipForWritingMode(result); | 2337 renderer->containingBlock()->flipForWritingMode(result); |
| 2335 return result; | 2338 return result; |
| 2336 } | 2339 } |
| 2337 | 2340 |
| 2338 LayoutRect RenderLayer::physicalBoundingBox(const RenderLayer* ancestorLayer, co
nst LayoutPoint* offsetFromRoot) const | 2341 LayoutRect Layer::physicalBoundingBox(const Layer* ancestorLayer, const LayoutPo
int* offsetFromRoot) const |
| 2339 { | 2342 { |
| 2340 LayoutRect result = flippedLogicalBoundingBox(logicalBoundingBox(), renderer
()); | 2343 LayoutRect result = flippedLogicalBoundingBox(logicalBoundingBox(), renderer
()); |
| 2341 if (offsetFromRoot) | 2344 if (offsetFromRoot) |
| 2342 result.moveBy(*offsetFromRoot); | 2345 result.moveBy(*offsetFromRoot); |
| 2343 else | 2346 else |
| 2344 convertToLayerCoords(ancestorLayer, result); | 2347 convertToLayerCoords(ancestorLayer, result); |
| 2345 return result; | 2348 return result; |
| 2346 } | 2349 } |
| 2347 | 2350 |
| 2348 LayoutRect RenderLayer::fragmentsBoundingBox(const RenderLayer* ancestorLayer) c
onst | 2351 LayoutRect Layer::fragmentsBoundingBox(const Layer* ancestorLayer) const |
| 2349 { | 2352 { |
| 2350 if (!enclosingPaginationLayer()) | 2353 if (!enclosingPaginationLayer()) |
| 2351 return physicalBoundingBox(ancestorLayer); | 2354 return physicalBoundingBox(ancestorLayer); |
| 2352 | 2355 |
| 2353 LayoutRect result = flippedLogicalBoundingBox(logicalBoundingBox(), renderer
()); | 2356 LayoutRect result = flippedLogicalBoundingBox(logicalBoundingBox(), renderer
()); |
| 2354 convertFromFlowThreadToVisualBoundingBoxInAncestor(this, ancestorLayer, resu
lt); | 2357 convertFromFlowThreadToVisualBoundingBoxInAncestor(this, ancestorLayer, resu
lt); |
| 2355 return result; | 2358 return result; |
| 2356 } | 2359 } |
| 2357 | 2360 |
| 2358 LayoutRect RenderLayer::boundingBoxForCompositingOverlapTest() const | 2361 LayoutRect Layer::boundingBoxForCompositingOverlapTest() const |
| 2359 { | 2362 { |
| 2360 return overlapBoundsIncludeChildren() ? boundingBoxForCompositing() : fragme
ntsBoundingBox(this); | 2363 return overlapBoundsIncludeChildren() ? boundingBoxForCompositing() : fragme
ntsBoundingBox(this); |
| 2361 } | 2364 } |
| 2362 | 2365 |
| 2363 static void expandRectForReflectionAndStackingChildren(const RenderLayer* ancest
orLayer, RenderLayer::CalculateBoundsOptions options, LayoutRect& result) | 2366 static void expandRectForReflectionAndStackingChildren(const Layer* ancestorLaye
r, Layer::CalculateBoundsOptions options, LayoutRect& result) |
| 2364 { | 2367 { |
| 2365 if (ancestorLayer->reflectionInfo() && !ancestorLayer->reflectionInfo()->ref
lectionLayer()->hasCompositedLayerMapping()) | 2368 if (ancestorLayer->reflectionInfo() && !ancestorLayer->reflectionInfo()->ref
lectionLayer()->hasCompositedLayerMapping()) |
| 2366 result.unite(ancestorLayer->reflectionInfo()->reflectionLayer()->boundin
gBoxForCompositing(ancestorLayer)); | 2369 result.unite(ancestorLayer->reflectionInfo()->reflectionLayer()->boundin
gBoxForCompositing(ancestorLayer)); |
| 2367 | 2370 |
| 2368 ASSERT(ancestorLayer->stackingNode()->isStackingContext() || !ancestorLayer-
>stackingNode()->hasPositiveZOrderList()); | 2371 ASSERT(ancestorLayer->stackingNode()->isStackingContext() || !ancestorLayer-
>stackingNode()->hasPositiveZOrderList()); |
| 2369 | 2372 |
| 2370 #if ENABLE(ASSERT) | 2373 #if ENABLE(ASSERT) |
| 2371 LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(ancestorL
ayer)->stackingNode()); | 2374 LayerListMutationDetector mutationChecker(const_cast<Layer*>(ancestorLayer)-
>stackingNode()); |
| 2372 #endif | 2375 #endif |
| 2373 | 2376 |
| 2374 RenderLayerStackingNodeIterator iterator(*ancestorLayer->stackingNode(), All
Children); | 2377 LayerStackingNodeIterator iterator(*ancestorLayer->stackingNode(), AllChildr
en); |
| 2375 while (RenderLayerStackingNode* node = iterator.next()) { | 2378 while (LayerStackingNode* node = iterator.next()) { |
| 2376 // Here we exclude both directly composited layers and squashing layers | 2379 // Here we exclude both directly composited layers and squashing layers |
| 2377 // because those RenderLayers don't paint into the graphics layer | 2380 // because those Layers don't paint into the graphics layer |
| 2378 // for this RenderLayer. For example, the bounds of squashed RenderLayer
s | 2381 // for this Layer. For example, the bounds of squashed Layers |
| 2379 // will be included in the computation of the appropriate squashing | 2382 // will be included in the computation of the appropriate squashing |
| 2380 // GraphicsLayer. | 2383 // GraphicsLayer. |
| 2381 if (options != RenderLayer::ApplyBoundsChickenEggHacks && node->layer()-
>compositingState() != NotComposited) | 2384 if (options != Layer::ApplyBoundsChickenEggHacks && node->layer()->compo
sitingState() != NotComposited) |
| 2382 continue; | 2385 continue; |
| 2383 result.unite(node->layer()->boundingBoxForCompositing(ancestorLayer, opt
ions)); | 2386 result.unite(node->layer()->boundingBoxForCompositing(ancestorLayer, opt
ions)); |
| 2384 } | 2387 } |
| 2385 } | 2388 } |
| 2386 | 2389 |
| 2387 LayoutRect RenderLayer::physicalBoundingBoxIncludingReflectionAndStackingChildre
n(const RenderLayer* ancestorLayer, const LayoutPoint& offsetFromRoot) const | 2390 LayoutRect Layer::physicalBoundingBoxIncludingReflectionAndStackingChildren(cons
t Layer* ancestorLayer, const LayoutPoint& offsetFromRoot) const |
| 2388 { | 2391 { |
| 2389 LayoutPoint origin; | 2392 LayoutPoint origin; |
| 2390 LayoutRect result = physicalBoundingBox(ancestorLayer, &origin); | 2393 LayoutRect result = physicalBoundingBox(ancestorLayer, &origin); |
| 2391 | 2394 |
| 2392 const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded(); | 2395 const_cast<Layer*>(this)->stackingNode()->updateLayerListsIfNeeded(); |
| 2393 | 2396 |
| 2394 expandRectForReflectionAndStackingChildren(this, DoNotApplyBoundsChickenEggH
acks, result); | 2397 expandRectForReflectionAndStackingChildren(this, DoNotApplyBoundsChickenEggH
acks, result); |
| 2395 | 2398 |
| 2396 result.moveBy(offsetFromRoot); | 2399 result.moveBy(offsetFromRoot); |
| 2397 return result; | 2400 return result; |
| 2398 } | 2401 } |
| 2399 | 2402 |
| 2400 LayoutRect RenderLayer::boundingBoxForCompositing(const RenderLayer* ancestorLay
er, CalculateBoundsOptions options) const | 2403 LayoutRect Layer::boundingBoxForCompositing(const Layer* ancestorLayer, Calculat
eBoundsOptions options) const |
| 2401 { | 2404 { |
| 2402 if (!isSelfPaintingLayer()) | 2405 if (!isSelfPaintingLayer()) |
| 2403 return LayoutRect(); | 2406 return LayoutRect(); |
| 2404 | 2407 |
| 2405 if (!ancestorLayer) | 2408 if (!ancestorLayer) |
| 2406 ancestorLayer = this; | 2409 ancestorLayer = this; |
| 2407 | 2410 |
| 2408 // FIXME: This could be improved to do a check like hasVisibleNonCompositing
DescendantLayers() (bug 92580). | 2411 // FIXME: This could be improved to do a check like hasVisibleNonCompositing
DescendantLayers() (bug 92580). |
| 2409 if (this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant()
) | 2412 if (this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant()
) |
| 2410 return LayoutRect(); | 2413 return LayoutRect(); |
| 2411 | 2414 |
| 2412 // The root layer is always just the size of the document. | 2415 // The root layer is always just the size of the document. |
| 2413 if (isRootLayer()) | 2416 if (isRootLayer()) |
| 2414 return m_renderer->view()->unscaledDocumentRect(); | 2417 return m_renderer->view()->unscaledDocumentRect(); |
| 2415 | 2418 |
| 2416 // The layer created for the RenderFlowThread is just a helper for painting
and hit-testing, | 2419 // The layer created for the RenderFlowThread is just a helper for painting
and hit-testing, |
| 2417 // and should not contribute to the bounding box. The RenderMultiColumnSets
will contribute | 2420 // and should not contribute to the bounding box. The RenderMultiColumnSets
will contribute |
| 2418 // the correct size for the rendered content of the multicol container. | 2421 // the correct size for the rendered content of the multicol container. |
| 2419 if (useRegionBasedColumns() && renderer()->isRenderFlowThread()) | 2422 if (useRegionBasedColumns() && renderer()->isRenderFlowThread()) |
| 2420 return LayoutRect(); | 2423 return LayoutRect(); |
| 2421 | 2424 |
| 2422 LayoutRect result = clipper().localClipRect(); | 2425 LayoutRect result = clipper().localClipRect(); |
| 2423 if (result == LayoutRect::infiniteIntRect()) { | 2426 if (result == LayoutRect::infiniteIntRect()) { |
| 2424 LayoutPoint origin; | 2427 LayoutPoint origin; |
| 2425 result = physicalBoundingBox(ancestorLayer, &origin); | 2428 result = physicalBoundingBox(ancestorLayer, &origin); |
| 2426 | 2429 |
| 2427 const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded
(); | 2430 const_cast<Layer*>(this)->stackingNode()->updateLayerListsIfNeeded(); |
| 2428 | 2431 |
| 2429 // Reflections are implemented with RenderLayers that hang off of the re
flected layer. However, | 2432 // Reflections are implemented with Layers that hang off of the reflecte
d layer. However, |
| 2430 // the reflection layer subtree does not include the subtree of the pare
nt RenderLayer, so | 2433 // the reflection layer subtree does not include the subtree of the pare
nt Layer, so |
| 2431 // a recursive computation of stacking children yields no results. This
breaks cases when there are stacking | 2434 // a recursive computation of stacking children yields no results. This
breaks cases when there are stacking |
| 2432 // children of the parent, that need to be included in reflected composi
ted bounds. | 2435 // children of the parent, that need to be included in reflected composi
ted bounds. |
| 2433 // Fix this by including composited bounds of stacking children of the r
eflected RenderLayer. | 2436 // Fix this by including composited bounds of stacking children of the r
eflected Layer. |
| 2434 if (hasCompositedLayerMapping() && parent() && parent()->reflectionInfo(
) && parent()->reflectionInfo()->reflectionLayer() == this) | 2437 if (hasCompositedLayerMapping() && parent() && parent()->reflectionInfo(
) && parent()->reflectionInfo()->reflectionLayer() == this) |
| 2435 expandRectForReflectionAndStackingChildren(parent(), options, result
); | 2438 expandRectForReflectionAndStackingChildren(parent(), options, result
); |
| 2436 else | 2439 else |
| 2437 expandRectForReflectionAndStackingChildren(this, options, result); | 2440 expandRectForReflectionAndStackingChildren(this, options, result); |
| 2438 | 2441 |
| 2439 // FIXME: We can optimize the size of the composited layers, by not enla
rging | 2442 // FIXME: We can optimize the size of the composited layers, by not enla
rging |
| 2440 // filtered areas with the outsets if we know that the filter is going t
o render in hardware. | 2443 // filtered areas with the outsets if we know that the filter is going t
o render in hardware. |
| 2441 // https://bugs.webkit.org/show_bug.cgi?id=81239 | 2444 // https://bugs.webkit.org/show_bug.cgi?id=81239 |
| 2442 result.expand(m_renderer->style()->filterOutsets()); | 2445 result.expand(m_renderer->style()->filterOutsets()); |
| 2443 } | 2446 } |
| 2444 | 2447 |
| 2445 if (paintsWithTransform(PaintBehaviorNormal) || (options == ApplyBoundsChick
enEggHacks && transform())) | 2448 if (paintsWithTransform(PaintBehaviorNormal) || (options == ApplyBoundsChick
enEggHacks && transform())) |
| 2446 result = transform()->mapRect(result); | 2449 result = transform()->mapRect(result); |
| 2447 | 2450 |
| 2448 if (enclosingPaginationLayer()) { | 2451 if (enclosingPaginationLayer()) { |
| 2449 convertFromFlowThreadToVisualBoundingBoxInAncestor(this, ancestorLayer,
result); | 2452 convertFromFlowThreadToVisualBoundingBoxInAncestor(this, ancestorLayer,
result); |
| 2450 return result; | 2453 return result; |
| 2451 } | 2454 } |
| 2452 LayoutPoint delta; | 2455 LayoutPoint delta; |
| 2453 convertToLayerCoords(ancestorLayer, delta); | 2456 convertToLayerCoords(ancestorLayer, delta); |
| 2454 result.moveBy(delta); | 2457 result.moveBy(delta); |
| 2455 return result; | 2458 return result; |
| 2456 } | 2459 } |
| 2457 | 2460 |
| 2458 CompositingState RenderLayer::compositingState() const | 2461 CompositingState Layer::compositingState() const |
| 2459 { | 2462 { |
| 2460 ASSERT(isAllowedToQueryCompositingState()); | 2463 ASSERT(isAllowedToQueryCompositingState()); |
| 2461 | 2464 |
| 2462 // This is computed procedurally so there is no redundant state variable tha
t | 2465 // This is computed procedurally so there is no redundant state variable tha
t |
| 2463 // can get out of sync from the real actual compositing state. | 2466 // can get out of sync from the real actual compositing state. |
| 2464 | 2467 |
| 2465 if (m_groupedMapping) { | 2468 if (m_groupedMapping) { |
| 2466 ASSERT(!m_compositedLayerMapping); | 2469 ASSERT(!m_compositedLayerMapping); |
| 2467 return PaintsIntoGroupedBacking; | 2470 return PaintsIntoGroupedBacking; |
| 2468 } | 2471 } |
| 2469 | 2472 |
| 2470 if (!m_compositedLayerMapping) | 2473 if (!m_compositedLayerMapping) |
| 2471 return NotComposited; | 2474 return NotComposited; |
| 2472 | 2475 |
| 2473 return PaintsIntoOwnBacking; | 2476 return PaintsIntoOwnBacking; |
| 2474 } | 2477 } |
| 2475 | 2478 |
| 2476 bool RenderLayer::isAllowedToQueryCompositingState() const | 2479 bool Layer::isAllowedToQueryCompositingState() const |
| 2477 { | 2480 { |
| 2478 if (gCompositingQueryMode == CompositingQueriesAreAllowed) | 2481 if (gCompositingQueryMode == CompositingQueriesAreAllowed) |
| 2479 return true; | 2482 return true; |
| 2480 return renderer()->document().lifecycle().state() >= DocumentLifecycle::InCo
mpositingUpdate; | 2483 return renderer()->document().lifecycle().state() >= DocumentLifecycle::InCo
mpositingUpdate; |
| 2481 } | 2484 } |
| 2482 | 2485 |
| 2483 CompositedLayerMapping* RenderLayer::compositedLayerMapping() const | 2486 CompositedLayerMapping* Layer::compositedLayerMapping() const |
| 2484 { | 2487 { |
| 2485 ASSERT(isAllowedToQueryCompositingState()); | 2488 ASSERT(isAllowedToQueryCompositingState()); |
| 2486 return m_compositedLayerMapping.get(); | 2489 return m_compositedLayerMapping.get(); |
| 2487 } | 2490 } |
| 2488 | 2491 |
| 2489 GraphicsLayer* RenderLayer::graphicsLayerBacking() const | 2492 GraphicsLayer* Layer::graphicsLayerBacking() const |
| 2490 { | 2493 { |
| 2491 switch (compositingState()) { | 2494 switch (compositingState()) { |
| 2492 case NotComposited: | 2495 case NotComposited: |
| 2493 return 0; | 2496 return 0; |
| 2494 case PaintsIntoGroupedBacking: | 2497 case PaintsIntoGroupedBacking: |
| 2495 return groupedMapping()->squashingLayer(); | 2498 return groupedMapping()->squashingLayer(); |
| 2496 default: | 2499 default: |
| 2497 return compositedLayerMapping()->mainGraphicsLayer(); | 2500 return compositedLayerMapping()->mainGraphicsLayer(); |
| 2498 } | 2501 } |
| 2499 } | 2502 } |
| 2500 | 2503 |
| 2501 GraphicsLayer* RenderLayer::graphicsLayerBackingForScrolling() const | 2504 GraphicsLayer* Layer::graphicsLayerBackingForScrolling() const |
| 2502 { | 2505 { |
| 2503 switch (compositingState()) { | 2506 switch (compositingState()) { |
| 2504 case NotComposited: | 2507 case NotComposited: |
| 2505 return 0; | 2508 return 0; |
| 2506 case PaintsIntoGroupedBacking: | 2509 case PaintsIntoGroupedBacking: |
| 2507 return groupedMapping()->squashingLayer(); | 2510 return groupedMapping()->squashingLayer(); |
| 2508 default: | 2511 default: |
| 2509 return compositedLayerMapping()->scrollingContentsLayer() ? compositedLa
yerMapping()->scrollingContentsLayer() : compositedLayerMapping()->mainGraphicsL
ayer(); | 2512 return compositedLayerMapping()->scrollingContentsLayer() ? compositedLa
yerMapping()->scrollingContentsLayer() : compositedLayerMapping()->mainGraphicsL
ayer(); |
| 2510 } | 2513 } |
| 2511 } | 2514 } |
| 2512 | 2515 |
| 2513 void RenderLayer::ensureCompositedLayerMapping() | 2516 void Layer::ensureCompositedLayerMapping() |
| 2514 { | 2517 { |
| 2515 if (m_compositedLayerMapping) | 2518 if (m_compositedLayerMapping) |
| 2516 return; | 2519 return; |
| 2517 | 2520 |
| 2518 m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(*this)); | 2521 m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(*this)); |
| 2519 m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSub
tree); | 2522 m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSub
tree); |
| 2520 | 2523 |
| 2521 updateOrRemoveFilterEffectRenderer(); | 2524 updateOrRemoveFilterEffectRenderer(); |
| 2522 } | 2525 } |
| 2523 | 2526 |
| 2524 void RenderLayer::clearCompositedLayerMapping(bool layerBeingDestroyed) | 2527 void Layer::clearCompositedLayerMapping(bool layerBeingDestroyed) |
| 2525 { | 2528 { |
| 2526 if (!layerBeingDestroyed) { | 2529 if (!layerBeingDestroyed) { |
| 2527 // We need to make sure our decendants get a geometry update. In princip
le, | 2530 // We need to make sure our decendants get a geometry update. In princip
le, |
| 2528 // we could call setNeedsGraphicsLayerUpdate on our children, but that w
ould | 2531 // we could call setNeedsGraphicsLayerUpdate on our children, but that w
ould |
| 2529 // require walking the z-order lists to find them. Instead, we over-inva
lidate | 2532 // require walking the z-order lists to find them. Instead, we over-inva
lidate |
| 2530 // by marking our parent as needing a geometry update. | 2533 // by marking our parent as needing a geometry update. |
| 2531 if (RenderLayer* compositingParent = enclosingLayerWithCompositedLayerMa
pping(ExcludeSelf)) | 2534 if (Layer* compositingParent = enclosingLayerWithCompositedLayerMapping(
ExcludeSelf)) |
| 2532 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUp
date(GraphicsLayerUpdateSubtree); | 2535 compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUp
date(GraphicsLayerUpdateSubtree); |
| 2533 } | 2536 } |
| 2534 | 2537 |
| 2535 m_compositedLayerMapping.clear(); | 2538 m_compositedLayerMapping.clear(); |
| 2536 | 2539 |
| 2537 if (!layerBeingDestroyed) | 2540 if (!layerBeingDestroyed) |
| 2538 updateOrRemoveFilterEffectRenderer(); | 2541 updateOrRemoveFilterEffectRenderer(); |
| 2539 } | 2542 } |
| 2540 | 2543 |
| 2541 void RenderLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, bool
layerBeingDestroyed) | 2544 void Layer::setGroupedMapping(CompositedLayerMapping* groupedMapping, bool layer
BeingDestroyed) |
| 2542 { | 2545 { |
| 2543 if (groupedMapping == m_groupedMapping) | 2546 if (groupedMapping == m_groupedMapping) |
| 2544 return; | 2547 return; |
| 2545 | 2548 |
| 2546 if (!layerBeingDestroyed && m_groupedMapping) { | 2549 if (!layerBeingDestroyed && m_groupedMapping) { |
| 2547 m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree
); | 2550 m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree
); |
| 2548 m_groupedMapping->removeRenderLayerFromSquashingGraphicsLayer(this); | 2551 m_groupedMapping->removeLayerFromSquashingGraphicsLayer(this); |
| 2549 } | 2552 } |
| 2550 m_groupedMapping = groupedMapping; | 2553 m_groupedMapping = groupedMapping; |
| 2551 if (!layerBeingDestroyed && m_groupedMapping) | 2554 if (!layerBeingDestroyed && m_groupedMapping) |
| 2552 m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree
); | 2555 m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree
); |
| 2553 } | 2556 } |
| 2554 | 2557 |
| 2555 bool RenderLayer::hasCompositedMask() const | 2558 bool Layer::hasCompositedMask() const |
| 2556 { | 2559 { |
| 2557 return m_compositedLayerMapping && m_compositedLayerMapping->hasMaskLayer(); | 2560 return m_compositedLayerMapping && m_compositedLayerMapping->hasMaskLayer(); |
| 2558 } | 2561 } |
| 2559 | 2562 |
| 2560 bool RenderLayer::hasCompositedClippingMask() const | 2563 bool Layer::hasCompositedClippingMask() const |
| 2561 { | 2564 { |
| 2562 return m_compositedLayerMapping && m_compositedLayerMapping->hasChildClippin
gMaskLayer(); | 2565 return m_compositedLayerMapping && m_compositedLayerMapping->hasChildClippin
gMaskLayer(); |
| 2563 } | 2566 } |
| 2564 | 2567 |
| 2565 bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const | 2568 bool Layer::paintsWithTransform(PaintBehavior paintBehavior) const |
| 2566 { | 2569 { |
| 2567 return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayer
s) || compositingState() != PaintsIntoOwnBacking); | 2570 return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayer
s) || compositingState() != PaintsIntoOwnBacking); |
| 2568 } | 2571 } |
| 2569 | 2572 |
| 2570 bool RenderLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect)
const | 2573 bool Layer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const |
| 2571 { | 2574 { |
| 2572 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) | 2575 if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant()) |
| 2573 return false; | 2576 return false; |
| 2574 | 2577 |
| 2575 if (paintsWithTransparency(PaintBehaviorNormal)) | 2578 if (paintsWithTransparency(PaintBehaviorNormal)) |
| 2576 return false; | 2579 return false; |
| 2577 | 2580 |
| 2578 // We can't use hasVisibleContent(), because that will be true if our render
er is hidden, but some child | 2581 // We can't use hasVisibleContent(), because that will be true if our render
er is hidden, but some child |
| 2579 // is visible and that child doesn't cover the entire rect. | 2582 // is visible and that child doesn't cover the entire rect. |
| 2580 if (renderer()->style()->visibility() != VISIBLE) | 2583 if (renderer()->style()->visibility() != VISIBLE) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2599 return true; | 2602 return true; |
| 2600 | 2603 |
| 2601 // We can't consult child layers if we clip, since they might cover | 2604 // We can't consult child layers if we clip, since they might cover |
| 2602 // parts of the rect that are clipped out. | 2605 // parts of the rect that are clipped out. |
| 2603 if (renderer()->hasOverflowClip()) | 2606 if (renderer()->hasOverflowClip()) |
| 2604 return false; | 2607 return false; |
| 2605 | 2608 |
| 2606 return childBackgroundIsKnownToBeOpaqueInRect(localRect); | 2609 return childBackgroundIsKnownToBeOpaqueInRect(localRect); |
| 2607 } | 2610 } |
| 2608 | 2611 |
| 2609 bool RenderLayer::childBackgroundIsKnownToBeOpaqueInRect(const LayoutRect& local
Rect) const | 2612 bool Layer::childBackgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect)
const |
| 2610 { | 2613 { |
| 2611 RenderLayerStackingNodeReverseIterator revertseIterator(*m_stackingNode, Pos
itiveZOrderChildren | NormalFlowChildren | NegativeZOrderChildren); | 2614 LayerStackingNodeReverseIterator revertseIterator(*m_stackingNode, PositiveZ
OrderChildren | NormalFlowChildren | NegativeZOrderChildren); |
| 2612 while (RenderLayerStackingNode* child = revertseIterator.next()) { | 2615 while (LayerStackingNode* child = revertseIterator.next()) { |
| 2613 const RenderLayer* childLayer = child->layer(); | 2616 const Layer* childLayer = child->layer(); |
| 2614 // Stop at composited paint boundaries. | 2617 // Stop at composited paint boundaries. |
| 2615 if (childLayer->isPaintInvalidationContainer()) | 2618 if (childLayer->isPaintInvalidationContainer()) |
| 2616 continue; | 2619 continue; |
| 2617 | 2620 |
| 2618 if (!childLayer->canUseConvertToLayerCoords()) | 2621 if (!childLayer->canUseConvertToLayerCoords()) |
| 2619 continue; | 2622 continue; |
| 2620 | 2623 |
| 2621 LayoutPoint childOffset; | 2624 LayoutPoint childOffset; |
| 2622 LayoutRect childLocalRect(localRect); | 2625 LayoutRect childLocalRect(localRect); |
| 2623 childLayer->convertToLayerCoords(this, childOffset); | 2626 childLayer->convertToLayerCoords(this, childOffset); |
| 2624 childLocalRect.moveBy(-childOffset); | 2627 childLocalRect.moveBy(-childOffset); |
| 2625 | 2628 |
| 2626 if (childLayer->backgroundIsKnownToBeOpaqueInRect(childLocalRect)) | 2629 if (childLayer->backgroundIsKnownToBeOpaqueInRect(childLocalRect)) |
| 2627 return true; | 2630 return true; |
| 2628 } | 2631 } |
| 2629 return false; | 2632 return false; |
| 2630 } | 2633 } |
| 2631 | 2634 |
| 2632 bool RenderLayer::shouldBeSelfPaintingLayer() const | 2635 bool Layer::shouldBeSelfPaintingLayer() const |
| 2633 { | 2636 { |
| 2634 if (renderer()->isRenderPart() && toRenderPart(renderer())->requiresAccelera
tedCompositing()) | 2637 if (renderer()->isRenderPart() && toRenderPart(renderer())->requiresAccelera
tedCompositing()) |
| 2635 return true; | 2638 return true; |
| 2636 return m_layerType == NormalLayer | 2639 return m_layerType == NormalLayer |
| 2637 || (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars()) | 2640 || (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars()) |
| 2638 || needsCompositedScrolling(); | 2641 || needsCompositedScrolling(); |
| 2639 } | 2642 } |
| 2640 | 2643 |
| 2641 void RenderLayer::updateSelfPaintingLayer() | 2644 void Layer::updateSelfPaintingLayer() |
| 2642 { | 2645 { |
| 2643 bool isSelfPaintingLayer = shouldBeSelfPaintingLayer(); | 2646 bool isSelfPaintingLayer = shouldBeSelfPaintingLayer(); |
| 2644 if (this->isSelfPaintingLayer() == isSelfPaintingLayer) | 2647 if (this->isSelfPaintingLayer() == isSelfPaintingLayer) |
| 2645 return; | 2648 return; |
| 2646 | 2649 |
| 2647 m_isSelfPaintingLayer = isSelfPaintingLayer; | 2650 m_isSelfPaintingLayer = isSelfPaintingLayer; |
| 2648 | 2651 |
| 2649 if (parent()) | 2652 if (parent()) |
| 2650 parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); | 2653 parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus(); |
| 2651 } | 2654 } |
| 2652 | 2655 |
| 2653 bool RenderLayer::hasNonEmptyChildRenderers() const | 2656 bool Layer::hasNonEmptyChildRenderers() const |
| 2654 { | 2657 { |
| 2655 // Some HTML can cause whitespace text nodes to have renderers, like: | 2658 // Some HTML can cause whitespace text nodes to have renderers, like: |
| 2656 // <div> | 2659 // <div> |
| 2657 // <img src=...> | 2660 // <img src=...> |
| 2658 // </div> | 2661 // </div> |
| 2659 // so test for 0x0 RenderTexts here | 2662 // so test for 0x0 RenderTexts here |
| 2660 for (RenderObject* child = renderer()->slowFirstChild(); child; child = chil
d->nextSibling()) { | 2663 for (RenderObject* child = renderer()->slowFirstChild(); child; child = chil
d->nextSibling()) { |
| 2661 if (!child->hasLayer()) { | 2664 if (!child->hasLayer()) { |
| 2662 if (child->isRenderInline() || !child->isBox()) | 2665 if (child->isRenderInline() || !child->isBox()) |
| 2663 return true; | 2666 return true; |
| 2664 | 2667 |
| 2665 if (!toRenderBox(child)->size().isEmpty()) | 2668 if (!toRenderBox(child)->size().isEmpty()) |
| 2666 return true; | 2669 return true; |
| 2667 } | 2670 } |
| 2668 } | 2671 } |
| 2669 return false; | 2672 return false; |
| 2670 } | 2673 } |
| 2671 | 2674 |
| 2672 bool RenderLayer::hasBoxDecorationsOrBackground() const | 2675 bool Layer::hasBoxDecorationsOrBackground() const |
| 2673 { | 2676 { |
| 2674 return renderer()->style()->hasBoxDecorations() || renderer()->style()->hasB
ackground(); | 2677 return renderer()->style()->hasBoxDecorations() || renderer()->style()->hasB
ackground(); |
| 2675 } | 2678 } |
| 2676 | 2679 |
| 2677 bool RenderLayer::hasVisibleBoxDecorations() const | 2680 bool Layer::hasVisibleBoxDecorations() const |
| 2678 { | 2681 { |
| 2679 if (!hasVisibleContent()) | 2682 if (!hasVisibleContent()) |
| 2680 return false; | 2683 return false; |
| 2681 | 2684 |
| 2682 return hasBoxDecorationsOrBackground() || hasOverflowControls(); | 2685 return hasBoxDecorationsOrBackground() || hasOverflowControls(); |
| 2683 } | 2686 } |
| 2684 | 2687 |
| 2685 void RenderLayer::updateFilters(const RenderStyle* oldStyle, const RenderStyle*
newStyle) | 2688 void Layer::updateFilters(const RenderStyle* oldStyle, const RenderStyle* newSty
le) |
| 2686 { | 2689 { |
| 2687 if (!newStyle->hasFilter() && (!oldStyle || !oldStyle->hasFilter())) | 2690 if (!newStyle->hasFilter() && (!oldStyle || !oldStyle->hasFilter())) |
| 2688 return; | 2691 return; |
| 2689 | 2692 |
| 2690 updateOrRemoveFilterClients(); | 2693 updateOrRemoveFilterClients(); |
| 2691 updateOrRemoveFilterEffectRenderer(); | 2694 updateOrRemoveFilterEffectRenderer(); |
| 2692 } | 2695 } |
| 2693 | 2696 |
| 2694 bool RenderLayer::attemptDirectCompositingUpdate(StyleDifference diff, const Ren
derStyle* oldStyle) | 2697 bool Layer::attemptDirectCompositingUpdate(StyleDifference diff, const RenderSty
le* oldStyle) |
| 2695 { | 2698 { |
| 2696 CompositingReasons oldPotentialCompositingReasonsFromStyle = m_potentialComp
ositingReasonsFromStyle; | 2699 CompositingReasons oldPotentialCompositingReasonsFromStyle = m_potentialComp
ositingReasonsFromStyle; |
| 2697 compositor()->updatePotentialCompositingReasonsFromStyle(this); | 2700 compositor()->updatePotentialCompositingReasonsFromStyle(this); |
| 2698 | 2701 |
| 2699 // This function implements an optimization for transforms and opacity. | 2702 // This function implements an optimization for transforms and opacity. |
| 2700 // A common pattern is for a touchmove handler to update the transform | 2703 // A common pattern is for a touchmove handler to update the transform |
| 2701 // and/or an opacity of an element every frame while the user moves their | 2704 // and/or an opacity of an element every frame while the user moves their |
| 2702 // finger across the screen. The conditions below recognize when the | 2705 // finger across the screen. The conditions below recognize when the |
| 2703 // compositing state is set up to receive a direct transform or opacity | 2706 // compositing state is set up to receive a direct transform or opacity |
| 2704 // update. | 2707 // update. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2725 | 2728 |
| 2726 // To cut off almost all the work in the compositing update for | 2729 // To cut off almost all the work in the compositing update for |
| 2727 // this case, we treat inline transforms has having assumed overlap | 2730 // this case, we treat inline transforms has having assumed overlap |
| 2728 // (similar to how we treat animated transforms). Notice that we read | 2731 // (similar to how we treat animated transforms). Notice that we read |
| 2729 // CompositingReasonInlineTransform from the m_compositingReasons, which | 2732 // CompositingReasonInlineTransform from the m_compositingReasons, which |
| 2730 // means that the inline transform actually triggered assumed overlap in | 2733 // means that the inline transform actually triggered assumed overlap in |
| 2731 // the overlap map. | 2734 // the overlap map. |
| 2732 if (diff.transformChanged() && !(m_compositingReasons & CompositingReasonInl
ineTransform)) | 2735 if (diff.transformChanged() && !(m_compositingReasons & CompositingReasonInl
ineTransform)) |
| 2733 return false; | 2736 return false; |
| 2734 | 2737 |
| 2735 // We composite transparent RenderLayers differently from non-transparent | 2738 // We composite transparent Layers differently from non-transparent |
| 2736 // RenderLayers even when the non-transparent RenderLayers are already a | 2739 // Layers even when the non-transparent Layers are already a |
| 2737 // stacking context. | 2740 // stacking context. |
| 2738 if (diff.opacityChanged() && m_renderer->style()->hasOpacity() != oldStyle->
hasOpacity()) | 2741 if (diff.opacityChanged() && m_renderer->style()->hasOpacity() != oldStyle->
hasOpacity()) |
| 2739 return false; | 2742 return false; |
| 2740 | 2743 |
| 2741 updateTransform(oldStyle, renderer()->style()); | 2744 updateTransform(oldStyle, renderer()->style()); |
| 2742 | 2745 |
| 2743 // FIXME: Consider introducing a smaller graphics layer update scope | 2746 // FIXME: Consider introducing a smaller graphics layer update scope |
| 2744 // that just handles transforms and opacity. GraphicsLayerUpdateLocal | 2747 // that just handles transforms and opacity. GraphicsLayerUpdateLocal |
| 2745 // will also program bounds, clips, and many other properties that could | 2748 // will also program bounds, clips, and many other properties that could |
| 2746 // not possibly have changed. | 2749 // not possibly have changed. |
| 2747 m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLoc
al); | 2750 m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLoc
al); |
| 2748 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterGeometryChange
); | 2751 compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterGeometryChange
); |
| 2749 return true; | 2752 return true; |
| 2750 } | 2753 } |
| 2751 | 2754 |
| 2752 void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle
) | 2755 void Layer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle) |
| 2753 { | 2756 { |
| 2754 if (attemptDirectCompositingUpdate(diff, oldStyle)) | 2757 if (attemptDirectCompositingUpdate(diff, oldStyle)) |
| 2755 return; | 2758 return; |
| 2756 | 2759 |
| 2757 m_stackingNode->updateIsNormalFlowOnly(); | 2760 m_stackingNode->updateIsNormalFlowOnly(); |
| 2758 m_stackingNode->updateStackingNodesAfterStyleChange(oldStyle); | 2761 m_stackingNode->updateStackingNodesAfterStyleChange(oldStyle); |
| 2759 | 2762 |
| 2760 if (m_scrollableArea) | 2763 if (m_scrollableArea) |
| 2761 m_scrollableArea->updateAfterStyleChange(oldStyle); | 2764 m_scrollableArea->updateAfterStyleChange(oldStyle); |
| 2762 | 2765 |
| 2763 // Overlay scrollbars can make this layer self-painting so we need | 2766 // Overlay scrollbars can make this layer self-painting so we need |
| 2764 // to recompute the bit once scrollbars have been updated. | 2767 // to recompute the bit once scrollbars have been updated. |
| 2765 updateSelfPaintingLayer(); | 2768 updateSelfPaintingLayer(); |
| 2766 | 2769 |
| 2767 if (!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)) { | 2770 if (!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)) { |
| 2768 ASSERT(!oldStyle || diff.needsFullLayout()); | 2771 ASSERT(!oldStyle || diff.needsFullLayout()); |
| 2769 updateReflectionInfo(oldStyle); | 2772 updateReflectionInfo(oldStyle); |
| 2770 } | 2773 } |
| 2771 | 2774 |
| 2772 updateDescendantDependentFlags(); | 2775 updateDescendantDependentFlags(); |
| 2773 | 2776 |
| 2774 updateTransform(oldStyle, renderer()->style()); | 2777 updateTransform(oldStyle, renderer()->style()); |
| 2775 updateFilters(oldStyle, renderer()->style()); | 2778 updateFilters(oldStyle, renderer()->style()); |
| 2776 | 2779 |
| 2777 setNeedsCompositingInputsUpdate(); | 2780 setNeedsCompositingInputsUpdate(); |
| 2778 } | 2781 } |
| 2779 | 2782 |
| 2780 bool RenderLayer::scrollsOverflow() const | 2783 bool Layer::scrollsOverflow() const |
| 2781 { | 2784 { |
| 2782 if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea()) | 2785 if (LayerScrollableArea* scrollableArea = this->scrollableArea()) |
| 2783 return scrollableArea->scrollsOverflow(); | 2786 return scrollableArea->scrollsOverflow(); |
| 2784 | 2787 |
| 2785 return false; | 2788 return false; |
| 2786 } | 2789 } |
| 2787 | 2790 |
| 2788 FilterOperations RenderLayer::computeFilterOperations(const RenderStyle* style) | 2791 FilterOperations Layer::computeFilterOperations(const RenderStyle* style) |
| 2789 { | 2792 { |
| 2790 const FilterOperations& filters = style->filter(); | 2793 const FilterOperations& filters = style->filter(); |
| 2791 if (filters.hasReferenceFilter()) { | 2794 if (filters.hasReferenceFilter()) { |
| 2792 for (size_t i = 0; i < filters.size(); ++i) { | 2795 for (size_t i = 0; i < filters.size(); ++i) { |
| 2793 FilterOperation* filterOperation = filters.operations().at(i).get(); | 2796 FilterOperation* filterOperation = filters.operations().at(i).get(); |
| 2794 if (filterOperation->type() != FilterOperation::REFERENCE) | 2797 if (filterOperation->type() != FilterOperation::REFERENCE) |
| 2795 continue; | 2798 continue; |
| 2796 ReferenceFilterOperation* referenceOperation = toReferenceFilterOper
ation(filterOperation); | 2799 ReferenceFilterOperation* referenceOperation = toReferenceFilterOper
ation(filterOperation); |
| 2797 // FIXME: Cache the ReferenceFilter if it didn't change. | 2800 // FIXME: Cache the ReferenceFilter if it didn't change. |
| 2798 RefPtrWillBeRawPtr<ReferenceFilter> referenceFilter = ReferenceFilte
r::create(style->effectiveZoom()); | 2801 RefPtrWillBeRawPtr<ReferenceFilter> referenceFilter = ReferenceFilte
r::create(style->effectiveZoom()); |
| 2799 referenceFilter->setLastEffect(ReferenceFilterBuilder::build(referen
ceFilter.get(), renderer(), referenceFilter->sourceGraphic(), | 2802 referenceFilter->setLastEffect(ReferenceFilterBuilder::build(referen
ceFilter.get(), renderer(), referenceFilter->sourceGraphic(), |
| 2800 referenceOperation)); | 2803 referenceOperation)); |
| 2801 referenceOperation->setFilter(referenceFilter.release()); | 2804 referenceOperation->setFilter(referenceFilter.release()); |
| 2802 } | 2805 } |
| 2803 } | 2806 } |
| 2804 | 2807 |
| 2805 return filters; | 2808 return filters; |
| 2806 } | 2809 } |
| 2807 | 2810 |
| 2808 void RenderLayer::updateOrRemoveFilterClients() | 2811 void Layer::updateOrRemoveFilterClients() |
| 2809 { | 2812 { |
| 2810 if (!hasFilter()) { | 2813 if (!hasFilter()) { |
| 2811 removeFilterInfoIfNeeded(); | 2814 removeFilterInfoIfNeeded(); |
| 2812 return; | 2815 return; |
| 2813 } | 2816 } |
| 2814 | 2817 |
| 2815 if (renderer()->style()->filter().hasReferenceFilter()) | 2818 if (renderer()->style()->filter().hasReferenceFilter()) |
| 2816 ensureFilterInfo()->updateReferenceFilterClients(renderer()->style()->fi
lter()); | 2819 ensureFilterInfo()->updateReferenceFilterClients(renderer()->style()->fi
lter()); |
| 2817 else if (hasFilterInfo()) | 2820 else if (hasFilterInfo()) |
| 2818 filterInfo()->removeReferenceFilterClients(); | 2821 filterInfo()->removeReferenceFilterClients(); |
| 2819 } | 2822 } |
| 2820 | 2823 |
| 2821 void RenderLayer::updateOrRemoveFilterEffectRenderer() | 2824 void Layer::updateOrRemoveFilterEffectRenderer() |
| 2822 { | 2825 { |
| 2823 // FilterEffectRenderer is only used to render the filters in software mode, | 2826 // FilterEffectRenderer is only used to render the filters in software mode, |
| 2824 // so we always need to run updateOrRemoveFilterEffectRenderer after the com
posited | 2827 // so we always need to run updateOrRemoveFilterEffectRenderer after the com
posited |
| 2825 // mode might have changed for this layer. | 2828 // mode might have changed for this layer. |
| 2826 if (!paintsWithFilters()) { | 2829 if (!paintsWithFilters()) { |
| 2827 // Don't delete the whole filter info here, because we might use it | 2830 // Don't delete the whole filter info here, because we might use it |
| 2828 // for loading CSS shader files. | 2831 // for loading CSS shader files. |
| 2829 if (RenderLayerFilterInfo* filterInfo = this->filterInfo()) | 2832 if (LayerFilterInfo* filterInfo = this->filterInfo()) |
| 2830 filterInfo->setRenderer(nullptr); | 2833 filterInfo->setRenderer(nullptr); |
| 2831 | 2834 |
| 2832 return; | 2835 return; |
| 2833 } | 2836 } |
| 2834 | 2837 |
| 2835 RenderLayerFilterInfo* filterInfo = ensureFilterInfo(); | 2838 LayerFilterInfo* filterInfo = ensureFilterInfo(); |
| 2836 if (!filterInfo->renderer()) { | 2839 if (!filterInfo->renderer()) { |
| 2837 RefPtrWillBeRawPtr<FilterEffectRenderer> filterRenderer = FilterEffectRe
nderer::create(); | 2840 RefPtrWillBeRawPtr<FilterEffectRenderer> filterRenderer = FilterEffectRe
nderer::create(); |
| 2838 filterInfo->setRenderer(filterRenderer.release()); | 2841 filterInfo->setRenderer(filterRenderer.release()); |
| 2839 } | 2842 } |
| 2840 | 2843 |
| 2841 // If the filter fails to build, remove it from the layer. It will still att
empt to | 2844 // If the filter fails to build, remove it from the layer. It will still att
empt to |
| 2842 // go through regular processing (e.g. compositing), but never apply anythin
g. | 2845 // go through regular processing (e.g. compositing), but never apply anythin
g. |
| 2843 if (!filterInfo->renderer()->build(renderer(), computeFilterOperations(rende
rer()->style()))) | 2846 if (!filterInfo->renderer()->build(renderer(), computeFilterOperations(rende
rer()->style()))) |
| 2844 filterInfo->setRenderer(nullptr); | 2847 filterInfo->setRenderer(nullptr); |
| 2845 } | 2848 } |
| 2846 | 2849 |
| 2847 void RenderLayer::filterNeedsPaintInvalidation() | 2850 void Layer::filterNeedsPaintInvalidation() |
| 2848 { | 2851 { |
| 2849 { | 2852 { |
| 2850 DeprecatedScheduleStyleRecalcDuringLayout marker(renderer()->document().
lifecycle()); | 2853 DeprecatedScheduleStyleRecalcDuringLayout marker(renderer()->document().
lifecycle()); |
| 2851 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a styl
e recalc, which | 2854 // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a styl
e recalc, which |
| 2852 // is a problem because this function can be called while performing lay
out. | 2855 // is a problem because this function can be called while performing lay
out. |
| 2853 // Presumably this represents an illegal data flow of layout or composit
ing | 2856 // Presumably this represents an illegal data flow of layout or composit
ing |
| 2854 // information into the style system. | 2857 // information into the style system. |
| 2855 toElement(renderer()->node())->scheduleSVGFilterLayerUpdateHack(); | 2858 toElement(renderer()->node())->scheduleSVGFilterLayerUpdateHack(); |
| 2856 } | 2859 } |
| 2857 | 2860 |
| 2858 renderer()->setShouldDoFullPaintInvalidation(); | 2861 renderer()->setShouldDoFullPaintInvalidation(); |
| 2859 } | 2862 } |
| 2860 | 2863 |
| 2861 void RenderLayer::addLayerHitTestRects(LayerHitTestRects& rects) const | 2864 void Layer::addLayerHitTestRects(LayerHitTestRects& rects) const |
| 2862 { | 2865 { |
| 2863 computeSelfHitTestRects(rects); | 2866 computeSelfHitTestRects(rects); |
| 2864 for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) | 2867 for (Layer* child = firstChild(); child; child = child->nextSibling()) |
| 2865 child->addLayerHitTestRects(rects); | 2868 child->addLayerHitTestRects(rects); |
| 2866 } | 2869 } |
| 2867 | 2870 |
| 2868 void RenderLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const | 2871 void Layer::computeSelfHitTestRects(LayerHitTestRects& rects) const |
| 2869 { | 2872 { |
| 2870 if (!size().isEmpty()) { | 2873 if (!size().isEmpty()) { |
| 2871 Vector<LayoutRect> rect; | 2874 Vector<LayoutRect> rect; |
| 2872 | 2875 |
| 2873 if (renderBox() && renderBox()->scrollsOverflow()) { | 2876 if (renderBox() && renderBox()->scrollsOverflow()) { |
| 2874 // For scrolling layers, rects are taken to be in the space of the c
ontents. | 2877 // For scrolling layers, rects are taken to be in the space of the c
ontents. |
| 2875 // We need to include the bounding box of the layer in the space of
its parent | 2878 // We need to include the bounding box of the layer in the space of
its parent |
| 2876 // (eg. for border / scroll bars) and if it's composited then the en
tire contents | 2879 // (eg. for border / scroll bars) and if it's composited then the en
tire contents |
| 2877 // as well as they may be on another composited layer. Skip reportin
g contents | 2880 // as well as they may be on another composited layer. Skip reportin
g contents |
| 2878 // for non-composited layers as they'll get projected to the same la
yer as the | 2881 // for non-composited layers as they'll get projected to the same la
yer as the |
| 2879 // bounding box. | 2882 // bounding box. |
| 2880 if (compositingState() != NotComposited) | 2883 if (compositingState() != NotComposited) |
| 2881 rect.append(m_scrollableArea->overflowRect()); | 2884 rect.append(m_scrollableArea->overflowRect()); |
| 2882 | 2885 |
| 2883 rects.set(this, rect); | 2886 rects.set(this, rect); |
| 2884 if (const RenderLayer* parentLayer = parent()) { | 2887 if (const Layer* parentLayer = parent()) { |
| 2885 LayerHitTestRects::iterator iter = rects.find(parentLayer); | 2888 LayerHitTestRects::iterator iter = rects.find(parentLayer); |
| 2886 if (iter == rects.end()) { | 2889 if (iter == rects.end()) { |
| 2887 rects.add(parentLayer, Vector<LayoutRect>()).storedValue->va
lue.append(physicalBoundingBox(parentLayer)); | 2890 rects.add(parentLayer, Vector<LayoutRect>()).storedValue->va
lue.append(physicalBoundingBox(parentLayer)); |
| 2888 } else { | 2891 } else { |
| 2889 iter->value.append(physicalBoundingBox(parentLayer)); | 2892 iter->value.append(physicalBoundingBox(parentLayer)); |
| 2890 } | 2893 } |
| 2891 } | 2894 } |
| 2892 } else { | 2895 } else { |
| 2893 rect.append(logicalBoundingBox()); | 2896 rect.append(logicalBoundingBox()); |
| 2894 rects.set(this, rect); | 2897 rects.set(this, rect); |
| 2895 } | 2898 } |
| 2896 } | 2899 } |
| 2897 } | 2900 } |
| 2898 | 2901 |
| 2899 void RenderLayer::setShouldDoFullPaintInvalidationIncludingNonCompositingDescend
ants() | 2902 void Layer::setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants() |
| 2900 { | 2903 { |
| 2901 renderer()->setShouldDoFullPaintInvalidation(); | 2904 renderer()->setShouldDoFullPaintInvalidation(); |
| 2902 | 2905 |
| 2903 // Disable for reading compositingState() in isPaintInvalidationContainer()
below. | 2906 // Disable for reading compositingState() in isPaintInvalidationContainer()
below. |
| 2904 DisableCompositingQueryAsserts disabler; | 2907 DisableCompositingQueryAsserts disabler; |
| 2905 | 2908 |
| 2906 for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
{ | 2909 for (Layer* child = firstChild(); child; child = child->nextSibling()) { |
| 2907 if (!child->isPaintInvalidationContainer()) | 2910 if (!child->isPaintInvalidationContainer()) |
| 2908 child->setShouldDoFullPaintInvalidationIncludingNonCompositingDescen
dants(); | 2911 child->setShouldDoFullPaintInvalidationIncludingNonCompositingDescen
dants(); |
| 2909 } | 2912 } |
| 2910 } | 2913 } |
| 2911 | 2914 |
| 2912 DisableCompositingQueryAsserts::DisableCompositingQueryAsserts() | 2915 DisableCompositingQueryAsserts::DisableCompositingQueryAsserts() |
| 2913 : m_disabler(gCompositingQueryMode, CompositingQueriesAreAllowed) { } | 2916 : m_disabler(gCompositingQueryMode, CompositingQueriesAreAllowed) { } |
| 2914 | 2917 |
| 2915 } // namespace blink | 2918 } // namespace blink |
| 2916 | 2919 |
| 2917 #ifndef NDEBUG | 2920 #ifndef NDEBUG |
| 2918 void showLayerTree(const blink::RenderLayer* layer) | 2921 void showLayerTree(const blink::Layer* layer) |
| 2919 { | 2922 { |
| 2920 if (!layer) | 2923 if (!layer) |
| 2921 return; | 2924 return; |
| 2922 | 2925 |
| 2923 if (blink::LocalFrame* frame = layer->renderer()->frame()) { | 2926 if (blink::LocalFrame* frame = layer->renderer()->frame()) { |
| 2924 WTF::String output = externalRepresentation(frame, blink::LayoutAsTextSh
owAllLayers | blink::LayoutAsTextShowLayerNesting | blink::LayoutAsTextShowCompo
sitedLayers | blink::LayoutAsTextShowAddresses | blink::LayoutAsTextShowIDAndCla
ss | blink::LayoutAsTextDontUpdateLayout | blink::LayoutAsTextShowLayoutState); | 2927 WTF::String output = externalRepresentation(frame, blink::LayoutAsTextSh
owAllLayers | blink::LayoutAsTextShowLayerNesting | blink::LayoutAsTextShowCompo
sitedLayers | blink::LayoutAsTextShowAddresses | blink::LayoutAsTextShowIDAndCla
ss | blink::LayoutAsTextDontUpdateLayout | blink::LayoutAsTextShowLayoutState); |
| 2925 fprintf(stderr, "%s\n", output.utf8().data()); | 2928 fprintf(stderr, "%s\n", output.utf8().data()); |
| 2926 } | 2929 } |
| 2927 } | 2930 } |
| 2928 | 2931 |
| 2929 void showLayerTree(const blink::RenderObject* renderer) | 2932 void showLayerTree(const blink::RenderObject* renderer) |
| 2930 { | 2933 { |
| 2931 if (!renderer) | 2934 if (!renderer) |
| 2932 return; | 2935 return; |
| 2933 showLayerTree(renderer->enclosingLayer()); | 2936 showLayerTree(renderer->enclosingLayer()); |
| 2934 } | 2937 } |
| 2935 #endif | 2938 #endif |
| OLD | NEW |