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

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 push function to match old behavior... 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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698