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 | |
130 void pushLayoutState(RenderObject&); | |
131 | |
132 void popLayoutState() | |
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
. | 129 // Returns true if layoutState should be used for its cached offset and clip
. |
143 bool layoutStateEnabled() const { return m_layoutStateDisableCount == 0 && m
_layoutState; } | 130 bool layoutStateCachedOffsetsEnabled() const { return m_layoutState && m_lay
outState->cachedOffsetsEnabled(); } |
144 LayoutState* layoutState() const { return m_layoutState; } | 131 LayoutState* layoutState() const { return m_layoutState; } |
145 | 132 |
146 bool canUseLayoutStateForContainer(const RenderObject* repaintContainer) con
st | 133 bool canMapUsingLayoutStateForContainer(const RenderObject* repaintContainer
) const |
147 { | 134 { |
148 // FIXME: LayoutState should be enabled for other repaint containers tha
n the RenderView. crbug.com/363834 | 135 // FIXME: LayoutState should be enabled for other repaint containers tha
n the RenderView. crbug.com/363834 |
149 return layoutStateEnabled() && (repaintContainer == this); | 136 return layoutStateCachedOffsetsEnabled() && (repaintContainer == this); |
150 } | 137 } |
151 | 138 |
152 virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&) OVERRID
E; | 139 virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&) OVERRID
E; |
153 | 140 |
154 LayoutUnit pageLogicalHeight() const { return m_pageLogicalHeight; } | 141 LayoutUnit pageLogicalHeight() const { return m_pageLogicalHeight; } |
155 void setPageLogicalHeight(LayoutUnit height) | 142 void setPageLogicalHeight(LayoutUnit height) |
156 { | 143 { |
157 if (m_pageLogicalHeight != height) { | 144 if (m_pageLogicalHeight != height) { |
158 m_pageLogicalHeight = height; | 145 m_pageLogicalHeight = height; |
159 m_pageLogicalHeightChanged = true; | 146 m_pageLogicalHeightChanged = true; |
(...skipping 28 matching lines...) Expand all Loading... |
188 // rewrite the counter and quotes code. | 175 // rewrite the counter and quotes code. |
189 void addRenderCounter() { m_renderCounterCount++; } | 176 void addRenderCounter() { m_renderCounterCount++; } |
190 void removeRenderCounter() { ASSERT(m_renderCounterCount > 0); m_renderCount
erCount--; } | 177 void removeRenderCounter() { ASSERT(m_renderCounterCount > 0); m_renderCount
erCount--; } |
191 bool hasRenderCounters() { return m_renderCounterCount; } | 178 bool hasRenderCounters() { return m_renderCounterCount; } |
192 | 179 |
193 virtual bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect)
const OVERRIDE; | 180 virtual bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect)
const OVERRIDE; |
194 | 181 |
195 double layoutViewportWidth() const; | 182 double layoutViewportWidth() const; |
196 double layoutViewportHeight() const; | 183 double layoutViewportHeight() const; |
197 | 184 |
198 // Suspends the LayoutState optimization. Used under transforms that cannot
be represented by | 185 void pushLayoutState(LayoutState&); |
199 // LayoutState (common in SVG) and when manipulating the render tree during
layout in ways | 186 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: | 187 private: |
207 virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContai
ner, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed =
0) const OVERRIDE; | 188 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; | 189 virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObj
ect* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE; |
209 virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) c
onst OVERRIDE; | 190 virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) c
onst OVERRIDE; |
210 virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint&
layerOffset) const OVERRIDE; | 191 virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint&
layerOffset) const OVERRIDE; |
211 | 192 |
212 virtual void invalidateTreeAfterLayout(const RenderLayerModelObject& paintIn
validationContainer) OVERRIDE FINAL; | 193 virtual void invalidateTreeAfterLayout(const RenderLayerModelObject& paintIn
validationContainer) OVERRIDE FINAL; |
213 | 194 |
214 bool shouldRepaint(const LayoutRect&) const; | 195 bool shouldRepaint(const LayoutRect&) const; |
215 | 196 |
216 bool rootFillsViewportBackground(RenderBox* rootBox) const; | 197 bool rootFillsViewportBackground(RenderBox* rootBox) const; |
217 | 198 |
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(); | 199 void layoutContent(); |
232 #ifndef NDEBUG | 200 #ifndef NDEBUG |
233 void checkLayoutState(); | 201 void checkLayoutState(); |
234 #endif | 202 #endif |
235 | 203 |
236 void positionDialog(RenderBox*); | 204 void positionDialog(RenderBox*); |
237 void positionDialogs(); | 205 void positionDialogs(); |
238 | 206 |
239 void pushLayoutStateForCurrentFlowThread(const RenderObject&); | |
240 void popLayoutStateForCurrentFlowThread(); | |
241 | |
242 friend class LayoutStateMaintainer; | |
243 friend class ForceHorriblySlowRectMapping; | 207 friend class ForceHorriblySlowRectMapping; |
244 friend class RootLayoutStateScope; | |
245 | 208 |
246 bool shouldUsePrintingLayout() const; | 209 bool shouldUsePrintingLayout() const; |
247 | 210 |
248 RenderObject* backgroundRenderer() const; | 211 RenderObject* backgroundRenderer() const; |
249 | 212 |
250 FrameView* m_frameView; | 213 FrameView* m_frameView; |
251 | 214 |
252 RenderObject* m_selectionStart; | 215 RenderObject* m_selectionStart; |
253 RenderObject* m_selectionEnd; | 216 RenderObject* m_selectionEnd; |
254 | 217 |
255 int m_selectionStartPos; | 218 int m_selectionStartPos; |
256 int m_selectionEndPos; | 219 int m_selectionEndPos; |
257 | 220 |
258 LayoutUnit m_pageLogicalHeight; | 221 LayoutUnit m_pageLogicalHeight; |
259 bool m_pageLogicalHeightChanged; | 222 bool m_pageLogicalHeightChanged; |
260 LayoutState* m_layoutState; | 223 LayoutState* m_layoutState; |
261 unsigned m_layoutStateDisableCount; | |
262 OwnPtr<RenderLayerCompositor> m_compositor; | 224 OwnPtr<RenderLayerCompositor> m_compositor; |
263 OwnPtr<FlowThreadController> m_flowThreadController; | 225 OwnPtr<FlowThreadController> m_flowThreadController; |
264 RefPtr<IntervalArena> m_intervalArena; | 226 RefPtr<IntervalArena> m_intervalArena; |
265 | 227 |
266 RenderQuote* m_renderQuoteHead; | 228 RenderQuote* m_renderQuoteHead; |
267 unsigned m_renderCounterCount; | 229 unsigned m_renderCounterCount; |
268 }; | 230 }; |
269 | 231 |
270 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderView, isRenderView()); | 232 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderView, isRenderView()); |
271 | 233 |
272 class RootLayoutStateScope { | 234 // Suspends the LayoutState cached offset and clipRect optimization. Used under
transforms |
273 public: | 235 // that cannot be represented by LayoutState (common in SVG) and when manipulati
ng the render |
274 explicit RootLayoutStateScope(RenderObject& obj) | 236 // tree during layout in ways that can trigger repaint of a non-child (e.g. when
a list item |
275 : m_view(*obj.view()) | 237 // 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()) | 238 // 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 { | 239 class ForceHorriblySlowRectMapping { |
370 WTF_MAKE_NONCOPYABLE(ForceHorriblySlowRectMapping); | 240 WTF_MAKE_NONCOPYABLE(ForceHorriblySlowRectMapping); |
371 public: | 241 public: |
372 ForceHorriblySlowRectMapping(const RenderObject& root) | 242 ForceHorriblySlowRectMapping(const RenderObject& root) |
373 : m_view(*root.view()) | 243 : m_view(*root.view()) |
| 244 , m_didDisable(m_view.layoutState() && m_view.layoutState()->cachedOffse
tsEnabled()) |
374 { | 245 { |
375 m_view.disableLayoutState(); | 246 if (m_view.layoutState()) |
| 247 m_view.layoutState()->m_cachedOffsetsEnabled = false; |
| 248 #if ASSERT_ENABLED |
| 249 m_layoutState = m_view.layoutState(); |
| 250 #endif |
376 } | 251 } |
377 | 252 |
378 ~ForceHorriblySlowRectMapping() | 253 ~ForceHorriblySlowRectMapping() |
379 { | 254 { |
380 m_view.enableLayoutState(); | 255 ASSERT(m_view.layoutState() == m_layoutState); |
| 256 if (m_didDisable) |
| 257 m_view.layoutState()->m_cachedOffsetsEnabled = true; |
381 } | 258 } |
382 private: | 259 private: |
383 RenderView& m_view; | 260 RenderView& m_view; |
| 261 bool m_didDisable; |
| 262 #if ASSERT_ENABLED |
| 263 LayoutState* m_layoutState; |
| 264 #endif |
384 }; | 265 }; |
385 | 266 |
386 } // namespace WebCore | 267 } // namespace WebCore |
387 | 268 |
388 #endif // RenderView_h | 269 #endif // RenderView_h |
OLD | NEW |