Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2006 Apple Computer, Inc. | 3 * Copyright (C) 2006 Apple Computer, Inc. |
| 4 * | 4 * |
| 5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
| 6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
| 7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
| 8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
| 9 * | 9 * |
| 10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 ASSERT(!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()); | 119 ASSERT(!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()); |
| 120 if (!m_layoutState) | 120 if (!m_layoutState) |
| 121 return false; | 121 return false; |
| 122 return (delta.width() == m_layoutState->layoutDelta().width() || m_layou tState->layoutDeltaXSaturated()) && (delta.height() == m_layoutState->layoutDelt a().height() || m_layoutState->layoutDeltaYSaturated()); | 122 return (delta.width() == m_layoutState->layoutDelta().width() || m_layou tState->layoutDeltaXSaturated()) && (delta.height() == m_layoutState->layoutDelt a().height() || m_layoutState->layoutDeltaYSaturated()); |
| 123 } | 123 } |
| 124 #endif | 124 #endif |
| 125 | 125 |
| 126 bool shouldDoFullRepaintForNextLayout() const; | 126 bool shouldDoFullRepaintForNextLayout() const; |
| 127 bool doingFullRepaint() const { return m_frameView->needsFullPaintInvalidati on(); } | 127 bool doingFullRepaint() const { return m_frameView->needsFullPaintInvalidati on(); } |
| 128 | 128 |
| 129 // Subtree push | 129 // Returns true if layoutState should be used for its cached offset and clip . |
| 130 void pushLayoutState(RenderObject&); | 130 bool layoutStateCachedOffsetsEnabled() const { return m_layoutState && m_lay outState->cachedOffsetsEnabled(); } |
| 131 LayoutState* layoutState() const { return m_layoutState; } | |
| 132 void setLayoutState(LayoutState* layoutState) { m_layoutState = layoutState; } | |
| 131 | 133 |
| 132 void popLayoutState() | 134 bool canMapUsingLayoutStateForContainer(const RenderObject* repaintContainer ) const |
| 133 { | |
| 134 LayoutState* state = m_layoutState; | |
| 135 m_layoutState = state->next(); | |
| 136 delete state; | |
| 137 popLayoutStateForCurrentFlowThread(); | |
| 138 } | |
| 139 | |
| 140 bool shouldDisableLayoutStateForSubtree(RenderObject&) const; | |
| 141 | |
| 142 // Returns true if layoutState should be used for its cached offset and clip . | |
| 143 bool layoutStateEnabled() const { return m_layoutStateDisableCount == 0 && m _layoutState; } | |
| 144 LayoutState* layoutState() const { return m_layoutState; } | |
| 145 | |
| 146 bool canUseLayoutStateForContainer(const RenderObject* repaintContainer) con st | |
| 147 { | 135 { |
| 148 // FIXME: LayoutState should be enabled for other repaint containers tha n the RenderView. crbug.com/363834 | 136 // FIXME: LayoutState should be enabled for other repaint containers tha n the RenderView. crbug.com/363834 |
| 149 return layoutStateEnabled() && (repaintContainer == this); | 137 return layoutStateCachedOffsetsEnabled() && (repaintContainer == this); |
| 150 } | 138 } |
| 151 | 139 |
| 152 virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&) OVERRID E; | 140 virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&) OVERRID E; |
| 153 | 141 |
| 154 LayoutUnit pageLogicalHeight() const { return m_pageLogicalHeight; } | 142 LayoutUnit pageLogicalHeight() const { return m_pageLogicalHeight; } |
| 155 void setPageLogicalHeight(LayoutUnit height) | 143 void setPageLogicalHeight(LayoutUnit height) |
| 156 { | 144 { |
| 157 if (m_pageLogicalHeight != height) { | 145 if (m_pageLogicalHeight != height) { |
| 158 m_pageLogicalHeight = height; | 146 m_pageLogicalHeight = height; |
| 159 m_pageLogicalHeightChanged = true; | 147 m_pageLogicalHeightChanged = true; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 188 // rewrite the counter and quotes code. | 176 // rewrite the counter and quotes code. |
| 189 void addRenderCounter() { m_renderCounterCount++; } | 177 void addRenderCounter() { m_renderCounterCount++; } |
| 190 void removeRenderCounter() { ASSERT(m_renderCounterCount > 0); m_renderCount erCount--; } | 178 void removeRenderCounter() { ASSERT(m_renderCounterCount > 0); m_renderCount erCount--; } |
| 191 bool hasRenderCounters() { return m_renderCounterCount; } | 179 bool hasRenderCounters() { return m_renderCounterCount; } |
| 192 | 180 |
| 193 virtual bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const OVERRIDE; | 181 virtual bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const OVERRIDE; |
| 194 | 182 |
| 195 double layoutViewportWidth() const; | 183 double layoutViewportWidth() const; |
| 196 double layoutViewportHeight() const; | 184 double layoutViewportHeight() const; |
| 197 | 185 |
| 198 // Suspends the LayoutState optimization. Used under transforms that cannot be represented by | 186 void pushLayoutState(LayoutState&); |
| 199 // LayoutState (common in SVG) and when manipulating the render tree during layout in ways | 187 void popLayoutState(); |
| 200 // that can trigger repaint of a non-child (e.g. when a list item moves its list marker around). | |
| 201 // Note that even when disabled, LayoutState is still used to store layoutDe lta. | |
| 202 // These functions may only be accessed by LayoutStateMaintainer or LayoutSt ateDisabler. | |
| 203 void disableLayoutState() { m_layoutStateDisableCount++; } | |
| 204 void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutSt ateDisableCount--; } | |
| 205 | |
| 206 private: | 188 private: |
| 207 virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContai ner, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE; | 189 virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContai ner, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE; |
| 208 virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObj ect* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; | 190 virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObj ect* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; |
| 209 virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) c onst OVERRIDE; | 191 virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) c onst OVERRIDE; |
| 210 virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const OVERRIDE; | 192 virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const OVERRIDE; |
| 211 | 193 |
| 212 virtual void invalidateTreeAfterLayout(const RenderLayerModelObject& paintIn validationContainer) OVERRIDE FINAL; | 194 virtual void invalidateTreeAfterLayout(const RenderLayerModelObject& paintIn validationContainer) OVERRIDE FINAL; |
| 213 | 195 |
| 214 bool shouldRepaint(const LayoutRect&) const; | 196 bool shouldRepaint(const LayoutRect&) const; |
| 215 | 197 |
| 216 bool rootFillsViewportBackground(RenderBox* rootBox) const; | 198 bool rootFillsViewportBackground(RenderBox* rootBox) const; |
| 217 | 199 |
| 218 // These functions may only be accessed by LayoutStateMaintainer. | |
| 219 bool pushLayoutState(RenderBox& renderer, const LayoutSize& offset, LayoutUn it pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0) | |
| 220 { | |
| 221 // We push LayoutState even if layoutState is disabled because it stores layoutDelta too. | |
| 222 if ((!doingFullRepaint() || (RuntimeEnabledFeatures::repaintAfterLayoutE nabled() && layoutStateEnabled())) || m_layoutState->isPaginated() || renderer.h asColumns() || renderer.flowThreadContainingBlock() | |
| 223 ) { | |
| 224 pushLayoutStateForCurrentFlowThread(renderer); | |
| 225 m_layoutState = new LayoutState(m_layoutState, renderer, offset, pag eHeight, pageHeightChanged, colInfo); | |
| 226 return true; | |
| 227 } | |
| 228 return false; | |
| 229 } | |
| 230 | |
| 231 void layoutContent(); | 200 void layoutContent(); |
| 232 #ifndef NDEBUG | 201 #ifndef NDEBUG |
| 233 void checkLayoutState(); | 202 void checkLayoutState(); |
| 234 #endif | 203 #endif |
| 235 | 204 |
| 236 void positionDialog(RenderBox*); | 205 void positionDialog(RenderBox*); |
| 237 void positionDialogs(); | 206 void positionDialogs(); |
| 238 | 207 |
| 239 void pushLayoutStateForCurrentFlowThread(const RenderObject&); | |
| 240 void popLayoutStateForCurrentFlowThread(); | |
| 241 | |
| 242 friend class LayoutStateMaintainer; | |
| 243 friend class ForceHorriblySlowRectMapping; | 208 friend class ForceHorriblySlowRectMapping; |
| 244 friend class RootLayoutStateScope; | |
| 245 | 209 |
| 246 bool shouldUsePrintingLayout() const; | 210 bool shouldUsePrintingLayout() const; |
| 247 | 211 |
| 248 RenderObject* backgroundRenderer() const; | 212 RenderObject* backgroundRenderer() const; |
| 249 | 213 |
| 250 FrameView* m_frameView; | 214 FrameView* m_frameView; |
| 251 | 215 |
| 252 RenderObject* m_selectionStart; | 216 RenderObject* m_selectionStart; |
| 253 RenderObject* m_selectionEnd; | 217 RenderObject* m_selectionEnd; |
| 254 | 218 |
| 255 int m_selectionStartPos; | 219 int m_selectionStartPos; |
| 256 int m_selectionEndPos; | 220 int m_selectionEndPos; |
| 257 | 221 |
| 258 LayoutUnit m_pageLogicalHeight; | 222 LayoutUnit m_pageLogicalHeight; |
| 259 bool m_pageLogicalHeightChanged; | 223 bool m_pageLogicalHeightChanged; |
| 260 LayoutState* m_layoutState; | 224 LayoutState* m_layoutState; |
| 261 unsigned m_layoutStateDisableCount; | |
| 262 OwnPtr<RenderLayerCompositor> m_compositor; | 225 OwnPtr<RenderLayerCompositor> m_compositor; |
| 263 OwnPtr<FlowThreadController> m_flowThreadController; | 226 OwnPtr<FlowThreadController> m_flowThreadController; |
| 264 RefPtr<IntervalArena> m_intervalArena; | 227 RefPtr<IntervalArena> m_intervalArena; |
| 265 | 228 |
| 266 RenderQuote* m_renderQuoteHead; | 229 RenderQuote* m_renderQuoteHead; |
| 267 unsigned m_renderCounterCount; | 230 unsigned m_renderCounterCount; |
| 268 }; | 231 }; |
| 269 | 232 |
| 270 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderView, isRenderView()); | 233 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderView, isRenderView()); |
| 271 | 234 |
| 272 class RootLayoutStateScope { | 235 // Suspends the LayoutState cached offset and clipRect optimization. Used under transforms |
| 273 public: | 236 // that cannot be represented by LayoutState (common in SVG) and when manipulati ng the render |
| 274 explicit RootLayoutStateScope(RenderObject& obj) | 237 // tree during layout in ways that can trigger repaint of a non-child (e.g. when a list item |
| 275 : m_view(*obj.view()) | 238 // moves its list marker around). Note that even when disabled, LayoutState is s till used to |
| 276 , m_rootLayoutState(m_view.pageLogicalHeight(), m_view.pageLogicalHeight Changed()) | 239 // store layoutDelta. |
| 277 , m_isRenderView(obj.isRenderView()) | |
| 278 { | |
| 279 // If the invalidation root isn't the renderView we have to make sure it | |
| 280 // gets added correctly to LayoutState otherwise we'll lose the margins that | |
| 281 // are set in the ancestors of the roots. | |
| 282 if (m_isRenderView) { | |
| 283 ASSERT(!m_view.m_layoutState); | |
| 284 m_view.m_layoutState = &m_rootLayoutState; | |
| 285 } else { | |
| 286 m_view.pushLayoutState(obj); | |
| 287 } | |
| 288 } | |
| 289 | |
| 290 ~RootLayoutStateScope() | |
| 291 { | |
| 292 if (m_isRenderView) { | |
| 293 ASSERT(m_view.m_layoutState == &m_rootLayoutState); | |
| 294 m_view.m_layoutState = 0; | |
| 295 } else { | |
| 296 m_view.popLayoutState(); | |
| 297 } | |
| 298 } | |
| 299 private: | |
| 300 RenderView& m_view; | |
| 301 LayoutState m_rootLayoutState; | |
| 302 bool m_isRenderView; | |
| 303 }; | |
| 304 | |
| 305 // Stack-based class to assist with LayoutState push/pop | |
| 306 class LayoutStateMaintainer { | |
| 307 WTF_MAKE_NONCOPYABLE(LayoutStateMaintainer); | |
| 308 public: | |
| 309 // ctor to push now | |
| 310 explicit LayoutStateMaintainer(RenderBox& root, const LayoutSize& offset, La youtUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0 ) | |
| 311 : m_view(*root.view()) | |
| 312 , m_disabled(root.shouldDisableLayoutState()) | |
| 313 , m_didStart(false) | |
| 314 , m_didEnd(false) | |
| 315 , m_didCreateLayoutState(false) | |
| 316 { | |
| 317 push(root, offset, pageHeight, pageHeightChanged, colInfo); | |
| 318 } | |
| 319 | |
| 320 // ctor to maybe push later | |
| 321 explicit LayoutStateMaintainer(RenderBox& root) | |
| 322 : m_view(*root.view()) | |
| 323 , m_disabled(false) | |
| 324 , m_didStart(false) | |
| 325 , m_didEnd(false) | |
| 326 , m_didCreateLayoutState(false) | |
| 327 { | |
| 328 } | |
| 329 | |
| 330 ~LayoutStateMaintainer() | |
| 331 { | |
| 332 if (m_didStart) | |
| 333 pop(); | |
| 334 ASSERT(m_didStart == m_didEnd); // if this fires, it means that someon e did a push(), but forgot to pop(). | |
| 335 } | |
| 336 | |
| 337 void push(RenderBox& root, const LayoutSize& offset, LayoutUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0) | |
| 338 { | |
| 339 ASSERT(!m_didStart); | |
| 340 // We push state even if disabled, because we still need to store layout Delta | |
| 341 m_didCreateLayoutState = m_view.pushLayoutState(root, offset, pageHeight , pageHeightChanged, colInfo); | |
| 342 if (m_disabled && m_didCreateLayoutState) | |
| 343 m_view.disableLayoutState(); | |
| 344 m_didStart = true; | |
| 345 } | |
| 346 | |
| 347 bool didPush() const { return m_didStart; } | |
| 348 | |
| 349 private: | |
| 350 void pop() | |
| 351 { | |
| 352 ASSERT(m_didStart && !m_didEnd); | |
| 353 if (m_didCreateLayoutState) { | |
| 354 m_view.popLayoutState(); | |
| 355 if (m_disabled) | |
| 356 m_view.enableLayoutState(); | |
| 357 } | |
| 358 | |
| 359 m_didEnd = true; | |
| 360 } | |
| 361 | |
| 362 RenderView& m_view; | |
| 363 bool m_disabled : 1; // true if the offset and clip part of layoutSta te is disabled | |
| 364 bool m_didStart : 1; // true if we did a push or disable | |
| 365 bool m_didEnd : 1; // true if we popped or re-enabled | |
| 366 bool m_didCreateLayoutState : 1; // true if we actually made a layout state. | |
| 367 }; | |
| 368 | |
| 369 class ForceHorriblySlowRectMapping { | 240 class ForceHorriblySlowRectMapping { |
| 370 WTF_MAKE_NONCOPYABLE(ForceHorriblySlowRectMapping); | 241 WTF_MAKE_NONCOPYABLE(ForceHorriblySlowRectMapping); |
| 371 public: | 242 public: |
| 372 ForceHorriblySlowRectMapping(const RenderObject& root) | 243 ForceHorriblySlowRectMapping(const RenderObject& root) |
| 373 : m_view(*root.view()) | 244 : m_didDisable(false) |
|
esprehn
2014/06/13 23:25:26
m_didDisable(m_view.layoutState() && m_view.layout
leviw_travelin_and_unemployed
2014/06/13 23:46:16
Sure.
| |
| 245 , m_view(*root.view()) | |
| 374 { | 246 { |
| 375 m_view.disableLayoutState(); | 247 if (m_view.layoutState()) { |
| 248 m_didDisable = m_view.layoutState()->cachedOffsetsEnabled(); | |
|
esprehn
2014/06/13 23:25:26
Why does cachedOffsetEnabled map to m_didDisable?
| |
| 249 m_view.layoutState()->m_cachedOffsetsEnabled = false; | |
|
esprehn
2014/06/13 23:25:26
This is weird to reaching into the LayotuState wit
| |
| 250 } | |
| 251 #if !ASSERT_DISABLED | |
|
esprehn
2014/06/13 23:25:26
This can't land, abarth removed ASSERT_DISABLED. I
| |
| 252 m_layoutState = m_view.layoutState(); | |
| 253 #endif | |
| 376 } | 254 } |
| 377 | 255 |
| 378 ~ForceHorriblySlowRectMapping() | 256 ~ForceHorriblySlowRectMapping() |
| 379 { | 257 { |
| 380 m_view.enableLayoutState(); | 258 ASSERT(m_view.layoutState() == m_layoutState); |
| 259 if (m_didDisable) | |
| 260 m_view.layoutState()->m_cachedOffsetsEnabled = true; | |
|
esprehn
2014/06/13 23:25:26
So cachedOffsetsEnabled means layoutStateEnabled?
leviw_travelin_and_unemployed
2014/06/13 23:46:16
Yes, but there is no more layoutStateEnabled. Layo
| |
| 381 } | 261 } |
| 382 private: | 262 private: |
| 263 bool m_didDisable; | |
| 383 RenderView& m_view; | 264 RenderView& m_view; |
| 265 #if !ASSERT_DISABLED | |
| 266 LayoutState* m_layoutState; | |
| 267 #endif | |
| 384 }; | 268 }; |
| 385 | 269 |
| 386 } // namespace WebCore | 270 } // namespace WebCore |
| 387 | 271 |
| 388 #endif // RenderView_h | 272 #endif // RenderView_h |
| OLD | NEW |