Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(312)

Side by Side Diff: Source/core/rendering/RenderView.h

Issue 335963002: Change LayoutState to be stack-allocated (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix assert Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698