Bumping manifests a=b2g-bump
[gecko.git] / layout / base / nsDisplayList.h
blobd93199150637fd8f2880af48b07a54f65175f951
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=2 sw=2 et tw=78:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 */
8 /*
9 * structures that represent things to be painted (ordered in z-order),
10 * used during painting and hit testing
13 #ifndef NSDISPLAYLIST_H_
14 #define NSDISPLAYLIST_H_
16 #include "mozilla/Attributes.h"
17 #include "nsCOMPtr.h"
18 #include "nsContainerFrame.h"
19 #include "nsPoint.h"
20 #include "nsRect.h"
21 #include "plarena.h"
22 #include "Layers.h"
23 #include "nsRegion.h"
24 #include "nsDisplayListInvalidation.h"
25 #include "DisplayListClipState.h"
26 #include "LayerState.h"
27 #include "FrameMetrics.h"
28 #include "mozilla/UniquePtr.h"
30 #include <stdint.h>
32 #include <stdlib.h>
33 #include <algorithm>
35 class nsIContent;
36 class nsRenderingContext;
37 class nsDisplayTableItem;
38 class nsISelection;
39 class nsDisplayLayerEventRegions;
40 class nsCaret;
42 namespace mozilla {
43 class FrameLayerBuilder;
44 namespace layers {
45 class Layer;
46 class ImageLayer;
47 class ImageContainer;
48 } //namespace
49 } //namespace
51 // A set of blend modes, that never includes OP_OVER (since it's
52 // considered the default, rather than a specific blend mode).
53 typedef mozilla::EnumSet<mozilla::gfx::CompositionOp> BlendModeSet;
56 * An nsIFrame can have many different visual parts. For example an image frame
57 * can have a background, border, and outline, the image itself, and a
58 * translucent selection overlay. In general these parts can be drawn at
59 * discontiguous z-levels; see CSS2.1 appendix E:
60 * http://www.w3.org/TR/CSS21/zindex.html
62 * We construct a display list for a frame tree that contains one item
63 * for each visual part. The display list is itself a tree since some items
64 * are containers for other items; however, its structure does not match
65 * the structure of its source frame tree. The display list items are sorted
66 * by z-order. A display list can be used to paint the frames, to determine
67 * which frame is the target of a mouse event, and to determine what areas
68 * need to be repainted when scrolling. The display lists built for each task
69 * may be different for efficiency; in particular some frames need special
70 * display list items only for event handling, and do not create these items
71 * when the display list will be used for painting (the common case). For
72 * example, when painting we avoid creating nsDisplayBackground items for
73 * frames that don't display a visible background, but for event handling
74 * we need those backgrounds because they are not transparent to events.
76 * We could avoid constructing an explicit display list by traversing the
77 * frame tree multiple times in clever ways. However, reifying the display list
78 * reduces code complexity and reduces the number of times each frame must be
79 * traversed to one, which seems to be good for performance. It also means
80 * we can share code for painting, event handling and scroll analysis.
82 * Display lists are short-lived; content and frame trees cannot change
83 * between a display list being created and destroyed. Display lists should
84 * not be created during reflow because the frame tree may be in an
85 * inconsistent state (e.g., a frame's stored overflow-area may not include
86 * the bounds of all its children). However, it should be fine to create
87 * a display list while a reflow is pending, before it starts.
89 * A display list covers the "extended" frame tree; the display list for a frame
90 * tree containing FRAME/IFRAME elements can include frames from the subdocuments.
92 * Display item's coordinates are relative to their nearest reference frame ancestor.
93 * Both the display root and any frame with a transform act as a reference frame
94 * for their frame subtrees.
97 // All types are defined in nsDisplayItemTypes.h
98 #ifdef MOZ_DUMP_PAINTING
99 #define NS_DISPLAY_DECL_NAME(n, e) \
100 virtual const char* Name() { return n; } \
101 virtual Type GetType() { return e; }
102 #else
103 #define NS_DISPLAY_DECL_NAME(n, e) \
104 virtual Type GetType() { return e; }
105 #endif
108 * This manages a display list and is passed as a parameter to
109 * nsIFrame::BuildDisplayList.
110 * It contains the parameters that don't change from frame to frame and manages
111 * the display list memory using a PLArena. It also establishes the reference
112 * coordinate system for all display list items. Some of the parameters are
113 * available from the prescontext/presshell, but we copy them into the builder
114 * for faster/more convenient access.
116 class nsDisplayListBuilder {
117 public:
118 typedef mozilla::FramePropertyDescriptor FramePropertyDescriptor;
119 typedef mozilla::FrameLayerBuilder FrameLayerBuilder;
120 typedef mozilla::DisplayItemClip DisplayItemClip;
121 typedef mozilla::DisplayListClipState DisplayListClipState;
122 typedef nsIWidget::ThemeGeometry ThemeGeometry;
123 typedef mozilla::layers::Layer Layer;
124 typedef mozilla::layers::FrameMetrics FrameMetrics;
125 typedef mozilla::layers::FrameMetrics::ViewID ViewID;
128 * @param aReferenceFrame the frame at the root of the subtree; its origin
129 * is the origin of the reference coordinate system for this display list
130 * @param aIsForEvents true if we're creating this list in order to
131 * determine which frame is under the mouse position
132 * @param aBuildCaret whether or not we should include the caret in any
133 * display lists that we make.
135 enum Mode {
136 PAINTING,
137 EVENT_DELIVERY,
138 PLUGIN_GEOMETRY,
139 IMAGE_VISIBILITY,
140 OTHER
142 nsDisplayListBuilder(nsIFrame* aReferenceFrame, Mode aMode, bool aBuildCaret);
143 ~nsDisplayListBuilder();
145 void SetWillComputePluginGeometry(bool aWillComputePluginGeometry)
147 mWillComputePluginGeometry = aWillComputePluginGeometry;
149 void SetForPluginGeometry()
151 NS_ASSERTION(mMode == PAINTING, "Can only switch from PAINTING to PLUGIN_GEOMETRY");
152 NS_ASSERTION(mWillComputePluginGeometry, "Should have signalled this in advance");
153 mMode = PLUGIN_GEOMETRY;
157 * @return true if the display is being built in order to determine which
158 * frame is under the mouse position.
160 bool IsForEventDelivery() { return mMode == EVENT_DELIVERY; }
162 * Be careful with this. The display list will be built in PAINTING mode
163 * first and then switched to PLUGIN_GEOMETRY before a second call to
164 * ComputeVisibility.
165 * @return true if the display list is being built to compute geometry
166 * for plugins.
168 bool IsForPluginGeometry() { return mMode == PLUGIN_GEOMETRY; }
170 * @return true if the display list is being built for painting.
172 bool IsForPainting() { return mMode == PAINTING; }
174 * @return true if the display list is being built for determining image
175 * visibility.
177 bool IsForImageVisibility() { return mMode == IMAGE_VISIBILITY; }
178 bool WillComputePluginGeometry() { return mWillComputePluginGeometry; }
180 * @return true if "painting is suppressed" during page load and we
181 * should paint only the background of the document.
183 bool IsBackgroundOnly() {
184 NS_ASSERTION(mPresShellStates.Length() > 0,
185 "don't call this if we're not in a presshell");
186 return CurrentPresShellState()->mIsBackgroundOnly;
189 * @return true if the currently active BuildDisplayList call is being
190 * applied to a frame at the root of a pseudo stacking context. A pseudo
191 * stacking context is either a real stacking context or basically what
192 * CSS2.1 appendix E refers to with "treat the element as if it created
193 * a new stacking context
195 bool IsAtRootOfPseudoStackingContext() { return mIsAtRootOfPseudoStackingContext; }
198 * @return the selection that painting should be restricted to (or nullptr
199 * in the normal unrestricted case)
201 nsISelection* GetBoundingSelection() { return mBoundingSelection; }
204 * @return the root of given frame's (sub)tree, whose origin
205 * establishes the coordinate system for the child display items.
207 const nsIFrame* FindReferenceFrameFor(const nsIFrame *aFrame,
208 nsPoint* aOffset = nullptr);
211 * @return the root of the display list's frame (sub)tree, whose origin
212 * establishes the coordinate system for the display list
214 nsIFrame* RootReferenceFrame()
216 return mReferenceFrame;
220 * @return a point pt such that adding pt to a coordinate relative to aFrame
221 * makes it relative to ReferenceFrame(), i.e., returns
222 * aFrame->GetOffsetToCrossDoc(ReferenceFrame()). The returned point is in
223 * the appunits of aFrame.
225 const nsPoint ToReferenceFrame(const nsIFrame* aFrame) {
226 nsPoint result;
227 FindReferenceFrameFor(aFrame, &result);
228 return result;
231 * When building the display list, the scrollframe aFrame will be "ignored"
232 * for the purposes of clipping, and its scrollbars will be hidden. We use
233 * this to allow RenderOffscreen to render a whole document without beign
234 * clipped by the viewport or drawing the viewport scrollbars.
236 void SetIgnoreScrollFrame(nsIFrame* aFrame) { mIgnoreScrollFrame = aFrame; }
238 * Get the scrollframe to ignore, if any.
240 nsIFrame* GetIgnoreScrollFrame() { return mIgnoreScrollFrame; }
242 * Get the ViewID of the nearest scrolling ancestor frame.
244 ViewID GetCurrentScrollParentId() const { return mCurrentScrollParentId; }
246 * Get the ViewID and the scrollbar flags corresponding to the scrollbar for
247 * which we are building display items at the moment.
249 void GetScrollbarInfo(ViewID* aOutScrollbarTarget, uint32_t* aOutScrollbarFlags)
251 *aOutScrollbarTarget = mCurrentScrollbarTarget;
252 *aOutScrollbarFlags = mCurrentScrollbarFlags;
255 * Calling this setter makes us include all out-of-flow descendant
256 * frames in the display list, wherever they may be positioned (even
257 * outside the dirty rects).
259 void SetIncludeAllOutOfFlows() { mIncludeAllOutOfFlows = true; }
260 bool GetIncludeAllOutOfFlows() const { return mIncludeAllOutOfFlows; }
262 * Calling this setter makes us exclude all leaf frames that aren't
263 * selected.
265 void SetSelectedFramesOnly() { mSelectedFramesOnly = true; }
266 bool GetSelectedFramesOnly() { return mSelectedFramesOnly; }
268 * Calling this setter makes us compute accurate visible regions at the cost
269 * of performance if regions get very complex.
271 void SetAccurateVisibleRegions() { mAccurateVisibleRegions = true; }
272 bool GetAccurateVisibleRegions() { return mAccurateVisibleRegions; }
274 * Allows callers to selectively override the regular paint suppression checks,
275 * so that methods like GetFrameForPoint work when painting is suppressed.
277 void IgnorePaintSuppression() { mIgnoreSuppression = true; }
279 * @return Returns if this builder will ignore paint suppression.
281 bool IsIgnoringPaintSuppression() { return mIgnoreSuppression; }
283 * @return Returns if this builder had to ignore painting suppression on some
284 * document when building the display list.
286 bool GetHadToIgnorePaintSuppression() { return mHadToIgnoreSuppression; }
288 * Call this if we're doing normal painting to the window.
290 void SetPaintingToWindow(bool aToWindow) { mIsPaintingToWindow = aToWindow; }
291 bool IsPaintingToWindow() const { return mIsPaintingToWindow; }
293 * Call this to prevent descending into subdocuments.
295 void SetDescendIntoSubdocuments(bool aDescend) { mDescendIntoSubdocuments = aDescend; }
296 bool GetDescendIntoSubdocuments() { return mDescendIntoSubdocuments; }
299 * Get dirty rect relative to current frame (the frame that we're calling
300 * BuildDisplayList on right now).
302 const nsRect& GetDirtyRect() { return mDirtyRect; }
303 const nsIFrame* GetCurrentFrame() { return mCurrentFrame; }
304 const nsIFrame* GetCurrentReferenceFrame() { return mCurrentReferenceFrame; }
305 const nsPoint& GetCurrentFrameOffsetToReferenceFrame() { return mCurrentOffsetToReferenceFrame; }
308 * Returns true if merging and flattening of display lists should be
309 * performed while computing visibility.
311 bool AllowMergingAndFlattening() { return mAllowMergingAndFlattening; }
312 void SetAllowMergingAndFlattening(bool aAllow) { mAllowMergingAndFlattening = aAllow; }
314 nsDisplayLayerEventRegions* GetLayerEventRegions() { return mLayerEventRegions; }
315 void SetLayerEventRegions(nsDisplayLayerEventRegions* aItem)
317 mLayerEventRegions = aItem;
319 bool IsBuildingLayerEventRegions()
321 // Disable for now.
322 return false;
323 // return mMode == PAINTING;
326 bool GetAncestorHasTouchEventHandler() { return mAncestorHasTouchEventHandler; }
327 void SetAncestorHasTouchEventHandler(bool aValue)
329 mAncestorHasTouchEventHandler = aValue;
332 bool HaveScrollableDisplayPort() const { return mHaveScrollableDisplayPort; }
333 void SetHaveScrollableDisplayPort() { mHaveScrollableDisplayPort = true; }
335 bool SetIsCompositingCheap(bool aCompositingCheap) {
336 bool temp = mIsCompositingCheap;
337 mIsCompositingCheap = aCompositingCheap;
338 return temp;
340 bool IsCompositingCheap() const { return mIsCompositingCheap; }
342 * Display the caret if needed.
344 void DisplayCaret(nsIFrame* aFrame, const nsRect& aDirtyRect,
345 nsDisplayList* aList) {
346 nsIFrame* frame = GetCaretFrame();
347 if (aFrame == frame) {
348 frame->DisplayCaret(this, aDirtyRect, aList);
352 * Get the frame that the caret is supposed to draw in.
353 * If the caret is currently invisible, this will be null.
355 nsIFrame* GetCaretFrame() {
356 return CurrentPresShellState()->mCaretFrame;
359 * Get the rectangle we're supposed to draw the caret into.
361 const nsRect& GetCaretRect() {
362 return CurrentPresShellState()->mCaretRect;
365 * Get the caret associated with the current presshell.
367 nsCaret* GetCaret();
369 * Notify the display list builder that we're entering a presshell.
370 * aReferenceFrame should be a frame in the new presshell and aDirtyRect
371 * should be the current dirty rect in aReferenceFrame's coordinate space.
373 void EnterPresShell(nsIFrame* aReferenceFrame, const nsRect& aDirtyRect);
375 * For print-preview documents, we sometimes need to build display items for
376 * the same frames multiple times in the same presentation, with different
377 * clipping. Between each such batch of items, call
378 * ResetMarkedFramesForDisplayList to make sure that the results of
379 * MarkFramesForDisplayList do not carry over between batches.
381 void ResetMarkedFramesForDisplayList();
383 * Notify the display list builder that we're leaving a presshell.
385 void LeavePresShell(nsIFrame* aReferenceFrame, const nsRect& aDirtyRect);
388 * Returns true if we're currently building a display list that's
389 * directly or indirectly under an nsDisplayTransform.
391 bool IsInTransform() const { return mInTransform; }
393 * Indicate whether or not we're directly or indirectly under and
394 * nsDisplayTransform or SVG foreignObject.
396 void SetInTransform(bool aInTransform) { mInTransform = aInTransform; }
399 * @return true if images have been set to decode synchronously.
401 bool ShouldSyncDecodeImages() { return mSyncDecodeImages; }
404 * Indicates whether we should synchronously decode images. If true, we decode
405 * and draw whatever image data has been loaded. If false, we just draw
406 * whatever has already been decoded.
408 void SetSyncDecodeImages(bool aSyncDecodeImages) {
409 mSyncDecodeImages = aSyncDecodeImages;
413 * Helper method to generate background painting flags based on the
414 * information available in the display list builder. Currently only
415 * accounts for mSyncDecodeImages.
417 uint32_t GetBackgroundPaintFlags();
420 * Subtracts aRegion from *aVisibleRegion. We avoid letting
421 * aVisibleRegion become overcomplex by simplifying it if necessary ---
422 * unless mAccurateVisibleRegions is set, in which case we let it
423 * get arbitrarily complex.
425 void SubtractFromVisibleRegion(nsRegion* aVisibleRegion,
426 const nsRegion& aRegion);
429 * Mark the frames in aFrames to be displayed if they intersect aDirtyRect
430 * (which is relative to aDirtyFrame). If the frames have placeholders
431 * that might not be displayed, we mark the placeholders and their ancestors
432 * to ensure that display list construction descends into them
433 * anyway. nsDisplayListBuilder will take care of unmarking them when it is
434 * destroyed.
436 void MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
437 const nsFrameList& aFrames,
438 const nsRect& aDirtyRect);
440 * Mark all child frames that Preserve3D() as needing display.
441 * Because these frames include transforms set on their parent, dirty rects
442 * for intermediate frames may be empty, yet child frames could still be visible.
444 void MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect);
446 const nsTArray<ThemeGeometry>& GetThemeGeometries() { return mThemeGeometries; }
449 * Returns true if we need to descend into this frame when building
450 * the display list, even though it doesn't intersect the dirty
451 * rect, because it may have out-of-flows that do so.
453 bool ShouldDescendIntoFrame(nsIFrame* aFrame) const {
454 return
455 (aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) ||
456 GetIncludeAllOutOfFlows();
460 * Notifies the builder that a particular themed widget exists
461 * at the given rectangle within the currently built display list.
462 * For certain appearance values (currently only
463 * NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR, NS_THEME_TOOLBAR and
464 * NS_THEME_WINDOW_TITLEBAR) this gets called during every display list
465 * construction, for every themed widget of the right type within the
466 * display list, except for themed widgets which are transformed or have
467 * effects applied to them (e.g. CSS opacity or filters).
469 * @param aWidgetType the -moz-appearance value for the themed widget
470 * @param aRect the device-pixel rect relative to the widget's displayRoot
471 * for the themed widget
473 void RegisterThemeGeometry(uint8_t aWidgetType,
474 const nsIntRect& aRect) {
475 if (mIsPaintingToWindow && mPresShellStates.Length() == 1) {
476 ThemeGeometry geometry(aWidgetType, aRect);
477 mThemeGeometries.AppendElement(geometry);
482 * Allocate memory in our arena. It will only be freed when this display list
483 * builder is destroyed. This memory holds nsDisplayItems. nsDisplayItem
484 * destructors are called as soon as the item is no longer used.
486 void* Allocate(size_t aSize);
489 * Allocate a new DisplayListClip in the arena. Will be cleaned up
490 * automatically when the arena goes away.
492 const DisplayItemClip* AllocateDisplayItemClip(const DisplayItemClip& aOriginal);
495 * Transfer off main thread animations to the layer. May be called
496 * with aBuilder and aItem both null, but only if the caller has
497 * already checked that off main thread animations should be sent to
498 * the layer. When they are both null, the animations are added to
499 * the layer as pending animations.
501 static void AddAnimationsAndTransitionsToLayer(Layer* aLayer,
502 nsDisplayListBuilder* aBuilder,
503 nsDisplayItem* aItem,
504 nsIFrame* aFrame,
505 nsCSSProperty aProperty);
507 * A helper class to temporarily set the value of
508 * mIsAtRootOfPseudoStackingContext, and temporarily
509 * set mCurrentFrame and related state. Also temporarily sets mDirtyRect.
510 * aDirtyRect is relative to aForChild.
512 class AutoBuildingDisplayList;
513 friend class AutoBuildingDisplayList;
514 class AutoBuildingDisplayList {
515 public:
516 AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder,
517 nsIFrame* aForChild,
518 const nsRect& aDirtyRect, bool aIsRoot)
519 : mBuilder(aBuilder),
520 mPrevFrame(aBuilder->mCurrentFrame),
521 mPrevReferenceFrame(aBuilder->mCurrentReferenceFrame),
522 mPrevLayerEventRegions(aBuilder->mLayerEventRegions),
523 mPrevOffset(aBuilder->mCurrentOffsetToReferenceFrame),
524 mPrevDirtyRect(aBuilder->mDirtyRect),
525 mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext),
526 mPrevAncestorHasTouchEventHandler(aBuilder->mAncestorHasTouchEventHandler)
528 if (aForChild->IsTransformed()) {
529 aBuilder->mCurrentOffsetToReferenceFrame = nsPoint();
530 aBuilder->mCurrentReferenceFrame = aForChild;
531 } else if (aBuilder->mCurrentFrame == aForChild->GetParent()) {
532 aBuilder->mCurrentOffsetToReferenceFrame += aForChild->GetPosition();
533 } else {
534 aBuilder->mCurrentReferenceFrame =
535 aBuilder->FindReferenceFrameFor(aForChild,
536 &aBuilder->mCurrentOffsetToReferenceFrame);
538 aBuilder->mCurrentFrame = aForChild;
539 aBuilder->mDirtyRect = aDirtyRect;
540 aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
542 void SetDirtyRect(const nsRect& aRect) {
543 mBuilder->mDirtyRect = aRect;
545 void SetReferenceFrameAndCurrentOffset(const nsIFrame* aFrame, const nsPoint& aOffset) {
546 mBuilder->mCurrentReferenceFrame = aFrame;
547 mBuilder->mCurrentOffsetToReferenceFrame = aOffset;
549 ~AutoBuildingDisplayList() {
550 mBuilder->mCurrentFrame = mPrevFrame;
551 mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame;
552 mBuilder->mLayerEventRegions = mPrevLayerEventRegions;
553 mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset;
554 mBuilder->mDirtyRect = mPrevDirtyRect;
555 mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext;
556 mBuilder->mAncestorHasTouchEventHandler = mPrevAncestorHasTouchEventHandler;
558 private:
559 nsDisplayListBuilder* mBuilder;
560 const nsIFrame* mPrevFrame;
561 const nsIFrame* mPrevReferenceFrame;
562 nsDisplayLayerEventRegions* mPrevLayerEventRegions;
563 nsPoint mPrevOffset;
564 nsRect mPrevDirtyRect;
565 bool mPrevIsAtRootOfPseudoStackingContext;
566 bool mPrevAncestorHasTouchEventHandler;
570 * A helper class to temporarily set the value of mInTransform.
572 class AutoInTransformSetter;
573 friend class AutoInTransformSetter;
574 class AutoInTransformSetter {
575 public:
576 AutoInTransformSetter(nsDisplayListBuilder* aBuilder, bool aInTransform)
577 : mBuilder(aBuilder), mOldValue(aBuilder->mInTransform) {
578 aBuilder->mInTransform = aInTransform;
580 ~AutoInTransformSetter() {
581 mBuilder->mInTransform = mOldValue;
583 private:
584 nsDisplayListBuilder* mBuilder;
585 bool mOldValue;
589 * A helper class to temporarily set the value of mCurrentScrollParentId.
591 class AutoCurrentScrollParentIdSetter;
592 friend class AutoCurrentScrollParentIdSetter;
593 class AutoCurrentScrollParentIdSetter {
594 public:
595 AutoCurrentScrollParentIdSetter(nsDisplayListBuilder* aBuilder, ViewID aScrollId)
596 : mBuilder(aBuilder), mOldValue(aBuilder->mCurrentScrollParentId) {
597 aBuilder->mCurrentScrollParentId = aScrollId;
599 ~AutoCurrentScrollParentIdSetter() {
600 mBuilder->mCurrentScrollParentId = mOldValue;
602 private:
603 nsDisplayListBuilder* mBuilder;
604 ViewID mOldValue;
608 * A helper class to temporarily set the value of mCurrentScrollbarTarget
609 * and mCurrentScrollbarFlags.
611 class AutoCurrentScrollbarInfoSetter;
612 friend class AutoCurrentScrollbarInfoSetter;
613 class AutoCurrentScrollbarInfoSetter {
614 public:
615 AutoCurrentScrollbarInfoSetter(nsDisplayListBuilder* aBuilder, ViewID aScrollTargetID,
616 uint32_t aScrollbarFlags)
617 : mBuilder(aBuilder) {
618 aBuilder->mCurrentScrollbarTarget = aScrollTargetID;
619 aBuilder->mCurrentScrollbarFlags = aScrollbarFlags;
621 ~AutoCurrentScrollbarInfoSetter() {
622 // No need to restore old values because scrollbars cannot be nested.
623 mBuilder->mCurrentScrollbarTarget = FrameMetrics::NULL_SCROLL_ID;
624 mBuilder->mCurrentScrollbarFlags = 0;
626 private:
627 nsDisplayListBuilder* mBuilder;
630 // Helpers for tables
631 nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; }
632 void SetCurrentTableItem(nsDisplayTableItem* aTableItem) { mCurrentTableItem = aTableItem; }
634 struct OutOfFlowDisplayData {
635 OutOfFlowDisplayData(const DisplayItemClip& aContainingBlockClip,
636 const nsRect &aDirtyRect)
637 : mContainingBlockClip(aContainingBlockClip)
638 , mDirtyRect(aDirtyRect)
640 explicit OutOfFlowDisplayData(const nsRect &aDirtyRect)
641 : mDirtyRect(aDirtyRect)
643 DisplayItemClip mContainingBlockClip;
644 nsRect mDirtyRect;
646 static void DestroyOutOfFlowDisplayData(void* aPropertyValue)
648 delete static_cast<OutOfFlowDisplayData*>(aPropertyValue);
651 NS_DECLARE_FRAME_PROPERTY(OutOfFlowDisplayDataProperty, DestroyOutOfFlowDisplayData)
652 NS_DECLARE_FRAME_PROPERTY(Preserve3DDirtyRectProperty, nsIFrame::DestroyRect)
654 nsPresContext* CurrentPresContext() {
655 return CurrentPresShellState()->mPresShell->GetPresContext();
659 * Accumulates the bounds of box frames that have moz-appearance
660 * -moz-win-exclude-glass style. Used in setting glass margins on
661 * Windows.
663 * We set the window opaque region (from which glass margins are computed)
664 * to the intersection of the glass region specified here and the opaque
665 * region computed during painting. So the excluded glass region actually
666 * *limits* the extent of the opaque area reported to Windows. We limit it
667 * so that changes to the computed opaque region (which can vary based on
668 * region optimizations and the placement of UI elements) outside the
669 * -moz-win-exclude-glass area don't affect the glass margins reported to
670 * Windows; changing those margins willy-nilly can cause the Windows 7 glass
671 * haze effect to jump around disconcertingly.
673 void AddWindowExcludeGlassRegion(const nsRegion& bounds) {
674 mWindowExcludeGlassRegion.Or(mWindowExcludeGlassRegion, bounds);
676 const nsRegion& GetWindowExcludeGlassRegion() {
677 return mWindowExcludeGlassRegion;
680 * Accumulates opaque stuff into the window opaque region.
682 void AddWindowOpaqueRegion(const nsRegion& bounds) {
683 mWindowOpaqueRegion.Or(mWindowOpaqueRegion, bounds);
686 * Returns the window opaque region built so far. This may be incomplete
687 * since the opaque region is built during layer construction.
689 const nsRegion& GetWindowOpaqueRegion() {
690 return mWindowOpaqueRegion;
692 void SetGlassDisplayItem(nsDisplayItem* aItem) {
693 if (mGlassDisplayItem) {
694 // Web pages or extensions could trigger this by using
695 // -moz-appearance:win-borderless-glass etc on their own elements.
696 // Keep the first one, since that will be the background of the root
697 // window
698 NS_WARNING("Multiple glass backgrounds found?");
699 } else {
700 mGlassDisplayItem = aItem;
703 bool NeedToForceTransparentSurfaceForItem(nsDisplayItem* aItem);
705 void SetContainsPluginItem() { mContainsPluginItem = true; }
706 bool ContainsPluginItem() { return mContainsPluginItem; }
709 * mContainsBlendMode is true if we processed a display item that
710 * has a blend mode attached. We do this so we can insert a
711 * nsDisplayBlendContainer in the parent stacking context.
713 void SetContainsBlendMode(uint8_t aBlendMode);
714 void SetContainsBlendModes(const BlendModeSet& aModes) {
715 mContainedBlendModes = aModes;
717 bool ContainsBlendMode() const { return !mContainedBlendModes.isEmpty(); }
718 BlendModeSet& ContainedBlendModes() {
719 return mContainedBlendModes;
722 DisplayListClipState& ClipState() { return mClipState; }
724 private:
725 void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame,
726 const nsRect& aDirtyRect);
728 struct PresShellState {
729 nsIPresShell* mPresShell;
730 nsIFrame* mCaretFrame;
731 nsRect mCaretRect;
732 nsRect mPrevDirtyRect;
733 uint32_t mFirstFrameMarkedForDisplay;
734 bool mIsBackgroundOnly;
736 PresShellState* CurrentPresShellState() {
737 NS_ASSERTION(mPresShellStates.Length() > 0,
738 "Someone forgot to enter a presshell");
739 return &mPresShellStates[mPresShellStates.Length() - 1];
742 nsIFrame* mReferenceFrame;
743 nsIFrame* mIgnoreScrollFrame;
744 nsDisplayLayerEventRegions* mLayerEventRegions;
745 PLArenaPool mPool;
746 nsCOMPtr<nsISelection> mBoundingSelection;
747 nsAutoTArray<PresShellState,8> mPresShellStates;
748 nsAutoTArray<nsIFrame*,100> mFramesMarkedForDisplay;
749 nsAutoTArray<ThemeGeometry,2> mThemeGeometries;
750 nsDisplayTableItem* mCurrentTableItem;
751 DisplayListClipState mClipState;
752 // mCurrentFrame is the frame that we're currently calling (or about to call)
753 // BuildDisplayList on.
754 const nsIFrame* mCurrentFrame;
755 // The reference frame for mCurrentFrame.
756 const nsIFrame* mCurrentReferenceFrame;
757 // The offset from mCurrentFrame to mCurrentReferenceFrame.
758 nsPoint mCurrentOffsetToReferenceFrame;
759 // Relative to mCurrentFrame.
760 nsRect mDirtyRect;
761 nsRegion mWindowExcludeGlassRegion;
762 nsRegion mWindowOpaqueRegion;
763 // The display item for the Windows window glass background, if any
764 nsDisplayItem* mGlassDisplayItem;
765 nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;
766 Mode mMode;
767 ViewID mCurrentScrollParentId;
768 ViewID mCurrentScrollbarTarget;
769 uint32_t mCurrentScrollbarFlags;
770 BlendModeSet mContainedBlendModes;
771 bool mBuildCaret;
772 bool mIgnoreSuppression;
773 bool mHadToIgnoreSuppression;
774 bool mIsAtRootOfPseudoStackingContext;
775 bool mIncludeAllOutOfFlows;
776 bool mDescendIntoSubdocuments;
777 bool mSelectedFramesOnly;
778 bool mAccurateVisibleRegions;
779 bool mAllowMergingAndFlattening;
780 bool mWillComputePluginGeometry;
781 // True when we're building a display list that's directly or indirectly
782 // under an nsDisplayTransform
783 bool mInTransform;
784 bool mSyncDecodeImages;
785 bool mIsPaintingToWindow;
786 bool mIsCompositingCheap;
787 bool mContainsPluginItem;
788 bool mAncestorHasTouchEventHandler;
789 // True when the first async-scrollable scroll frame for which we build a
790 // display list has a display port. An async-scrollable scroll frame is one
791 // which WantsAsyncScroll().
792 bool mHaveScrollableDisplayPort;
795 class nsDisplayItem;
796 class nsDisplayList;
798 * nsDisplayItems are put in singly-linked lists rooted in an nsDisplayList.
799 * nsDisplayItemLink holds the link. The lists are linked from lowest to
800 * highest in z-order.
802 class nsDisplayItemLink {
803 // This is never instantiated directly, so no need to count constructors and
804 // destructors.
805 protected:
806 nsDisplayItemLink() : mAbove(nullptr) {}
807 nsDisplayItem* mAbove;
809 friend class nsDisplayList;
813 * This is the unit of rendering and event testing. Each instance of this
814 * class represents an entity that can be drawn on the screen, e.g., a
815 * frame's CSS background, or a frame's text string.
817 * nsDisplayListItems can be containers --- i.e., they can perform hit testing
818 * and painting by recursively traversing a list of child items.
820 * These are arena-allocated during display list construction. A typical
821 * subclass would just have a frame pointer, so its object would be just three
822 * pointers (vtable, next-item, frame).
824 * Display items belong to a list at all times (except temporarily as they
825 * move from one list to another).
827 class nsDisplayItem : public nsDisplayItemLink {
828 public:
829 typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
830 typedef mozilla::DisplayItemClip DisplayItemClip;
831 typedef mozilla::layers::FrameMetrics FrameMetrics;
832 typedef mozilla::layers::FrameMetrics::ViewID ViewID;
833 typedef mozilla::layers::Layer Layer;
834 typedef mozilla::layers::LayerManager LayerManager;
835 typedef mozilla::LayerState LayerState;
837 // This is never instantiated directly (it has pure virtual methods), so no
838 // need to count constructors and destructors.
839 nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
841 * This constructor is only used in rare cases when we need to construct
842 * temporary items.
844 explicit nsDisplayItem(nsIFrame* aFrame)
845 : mFrame(aFrame)
846 , mClip(nullptr)
847 , mReferenceFrame(nullptr)
848 #ifdef MOZ_DUMP_PAINTING
849 , mPainted(false)
850 #endif
853 virtual ~nsDisplayItem() {}
855 void* operator new(size_t aSize,
856 nsDisplayListBuilder* aBuilder) CPP_THROW_NEW {
857 return aBuilder->Allocate(aSize);
860 // Contains all the type integers for each display list item type
861 #include "nsDisplayItemTypes.h"
863 struct HitTestState {
864 explicit HitTestState() {}
866 ~HitTestState() {
867 NS_ASSERTION(mItemBuffer.Length() == 0,
868 "mItemBuffer should have been cleared");
871 nsAutoTArray<nsDisplayItem*, 100> mItemBuffer;
875 * Some consecutive items should be rendered together as a unit, e.g.,
876 * outlines for the same element. For this, we need a way for items to
877 * identify their type. We use the type for other purposes too.
879 virtual Type GetType() = 0;
881 * Pairing this with the GetUnderlyingFrame() pointer gives a key that
882 * uniquely identifies this display item in the display item tree.
883 * XXX check ScrollLayerWrapper/nsOptionEventGrabberWrapper/nsXULEventRedirectorWrapper
885 virtual uint32_t GetPerFrameKey() { return uint32_t(GetType()); }
887 * This is called after we've constructed a display list for event handling.
888 * When this is called, we've already ensured that aRect intersects the
889 * item's bounds and that clipping has been taking into account.
891 * @param aRect the point or rect being tested, relative to the reference
892 * frame. If the width and height are both 1 app unit, it indicates we're
893 * hit testing a point, not a rect.
894 * @param aState must point to a HitTestState. If you don't have one,
895 * just create one with the default constructor and pass it in.
896 * @param aOutFrames each item appends the frame(s) in this display item that
897 * the rect is considered over (if any) to aOutFrames.
899 virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
900 HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {}
902 * @return the frame that this display item is based on. This is used to sort
903 * items by z-index and content order and for some other uses. Never
904 * returns null.
906 inline nsIFrame* Frame() const { return mFrame; }
908 * Compute the used z-index of our frame; returns zero for elements to which
909 * z-index does not apply, and for z-index:auto.
910 * @note This can be overridden, @see nsDisplayWrapList::SetOverrideZIndex.
912 virtual int32_t ZIndex() const;
914 * The default bounds is the frame border rect.
915 * @param aSnap *aSnap is set to true if the returned rect will be
916 * snapped to nearest device pixel edges during actual drawing.
917 * It might be set to false and snap anyway, so code computing the set of
918 * pixels affected by this display item needs to round outwards to pixel
919 * boundaries when *aSnap is set to false.
920 * This does not take the item's clipping into account.
921 * @return a rectangle relative to aBuilder->ReferenceFrame() that
922 * contains the area drawn by this display item
924 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
926 *aSnap = false;
927 return nsRect(ToReferenceFrame(), Frame()->GetSize());
930 * Returns true if nothing will be rendered inside aRect, false if uncertain.
931 * aRect is assumed to be contained in this item's bounds.
933 virtual bool IsInvisibleInRect(const nsRect& aRect)
935 return false;
938 * Returns the result of GetBounds intersected with the item's clip.
939 * The intersection is approximate since rounded corners are not taking into
940 * account.
942 nsRect GetClippedBounds(nsDisplayListBuilder* aBuilder);
943 nsRect GetBorderRect() {
944 return nsRect(ToReferenceFrame(), Frame()->GetSize());
946 nsRect GetPaddingRect() {
947 return Frame()->GetPaddingRectRelativeToSelf() + ToReferenceFrame();
949 nsRect GetContentRect() {
950 return Frame()->GetContentRectRelativeToSelf() + ToReferenceFrame();
954 * Checks if the frame(s) owning this display item have been marked as invalid,
955 * and needing repainting.
957 virtual bool IsInvalid(nsRect& aRect) {
958 bool result = mFrame ? mFrame->IsInvalid(aRect) : false;
959 aRect += ToReferenceFrame();
960 return result;
964 * Creates and initializes an nsDisplayItemGeometry object that retains the current
965 * areas covered by this display item. These need to retain enough information
966 * such that they can be compared against a future nsDisplayItem of the same type,
967 * and determine if repainting needs to happen.
969 * Subclasses wishing to store more information need to override both this
970 * and ComputeInvalidationRegion, as well as implementing an nsDisplayItemGeometry
971 * subclass.
973 * The default implementation tracks both the display item bounds, and the frame's
974 * border rect.
976 virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
978 return new nsDisplayItemGenericGeometry(this, aBuilder);
982 * Compares an nsDisplayItemGeometry object from a previous paint against the
983 * current item. Computes if the geometry of the item has changed, and the
984 * invalidation area required for correct repainting.
986 * The existing geometry will have been created from a display item with a
987 * matching GetPerFrameKey()/mFrame pair to the current item.
989 * The default implementation compares the display item bounds, and the frame's
990 * border rect, and invalidates the entire bounds if either rect changes.
992 * @param aGeometry The geometry of the matching display item from the
993 * previous paint.
994 * @param aInvalidRegion Output param, the region to invalidate, or
995 * unchanged if none.
997 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
998 const nsDisplayItemGeometry* aGeometry,
999 nsRegion* aInvalidRegion)
1001 const nsDisplayItemGenericGeometry* geometry = static_cast<const nsDisplayItemGenericGeometry*>(aGeometry);
1002 bool snap;
1003 if (!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder, &snap)) ||
1004 !geometry->mBorderRect.IsEqualInterior(GetBorderRect())) {
1005 aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds);
1010 * An alternative default implementation of ComputeInvalidationRegion,
1011 * that instead invalidates only the changed area between the two items.
1013 void ComputeInvalidationRegionDifference(nsDisplayListBuilder* aBuilder,
1014 const nsDisplayItemBoundsGeometry* aGeometry,
1015 nsRegion* aInvalidRegion)
1017 bool snap;
1018 nsRect bounds = GetBounds(aBuilder, &snap);
1020 if (!aGeometry->mBounds.IsEqualInterior(bounds)) {
1021 nscoord radii[8];
1022 if (aGeometry->mHasRoundedCorners ||
1023 Frame()->GetBorderRadii(radii)) {
1024 aInvalidRegion->Or(aGeometry->mBounds, bounds);
1025 } else {
1026 aInvalidRegion->Xor(aGeometry->mBounds, bounds);
1032 * For display items types that just draw a background we use this function
1033 * to do any invalidation that might be needed if we are asked to sync decode
1034 * images.
1036 void AddInvalidRegionForSyncDecodeBackgroundImages(
1037 nsDisplayListBuilder* aBuilder,
1038 const nsDisplayItemGeometry* aGeometry,
1039 nsRegion* aInvalidRegion);
1042 * Called when the area rendered by this display item has changed (been
1043 * invalidated or changed geometry) since the last paint. This includes
1044 * when the display item was not rendered at all in the last paint.
1045 * It does NOT get called when a display item was being rendered and no
1046 * longer is, because generally that means there is no display item to
1047 * call this method on.
1049 virtual void NotifyRenderingChanged() {}
1052 * @param aSnap set to true if the edges of the rectangles of the opaque
1053 * region would be snapped to device pixels when drawing
1054 * @return a region of the item that is opaque --- that is, every pixel
1055 * that is visible is painted with an opaque
1056 * color. This is useful for determining when one piece
1057 * of content completely obscures another so that we can do occlusion
1058 * culling.
1059 * This does not take clipping into account.
1061 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
1062 bool* aSnap)
1064 *aSnap = false;
1065 return nsRegion();
1068 * If this returns true, then aColor is set to the uniform color
1069 * @return true if the item is guaranteed to paint every pixel in its
1070 * bounds with the same (possibly translucent) color
1072 virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { return false; }
1074 * @return true if the contents of this item are rendered fixed relative
1075 * to the nearest viewport.
1077 virtual bool ShouldFixToViewport(LayerManager* aManager)
1078 { return false; }
1080 virtual bool ClearsBackground()
1081 { return false; }
1084 * Returns true if all layers that can be active should be forced to be
1085 * active. Requires setting the pref layers.force-active=true.
1087 static bool ForceActiveLayers();
1090 * Returns the maximum number of layers that should be created
1091 * or -1 for no limit. Requires setting the pref layers.max-acitve.
1093 static int32_t MaxActiveLayers();
1096 * @return LAYER_NONE if BuildLayer will return null. In this case
1097 * there is no layer for the item, and Paint should be called instead
1098 * to paint the content using Thebes.
1099 * Return LAYER_INACTIVE if there is a layer --- BuildLayer will
1100 * not return null (unless there's an error) --- but the layer contents
1101 * are not changing frequently. In this case it makes sense to composite
1102 * the layer into a ThebesLayer with other content, so we don't have to
1103 * recomposite it every time we paint.
1104 * Note: GetLayerState is only allowed to return LAYER_INACTIVE if all
1105 * descendant display items returned LAYER_INACTIVE or LAYER_NONE. Also,
1106 * all descendant display item frames must have an active scrolled root
1107 * that's either the same as this item's frame's active scrolled root, or
1108 * a descendant of this item's frame. This ensures that the entire
1109 * set of display items can be collapsed onto a single ThebesLayer.
1110 * Return LAYER_ACTIVE if the layer is active, that is, its contents are
1111 * changing frequently. In this case it makes sense to keep the layer
1112 * as a separate buffer in VRAM and composite it into the destination
1113 * every time we paint.
1115 * Users of GetLayerState should check ForceActiveLayers() and if it returns
1116 * true, change a returned value of LAYER_INACTIVE to LAYER_ACTIVE.
1118 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
1119 LayerManager* aManager,
1120 const ContainerLayerParameters& aParameters)
1121 { return mozilla::LAYER_NONE; }
1123 * Return true to indicate the layer should be constructed even if it's
1124 * completely invisible.
1126 virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder)
1127 { return false; }
1129 * Actually paint this item to some rendering context.
1130 * Content outside mVisibleRect need not be painted.
1131 * aCtx must be set up as for nsDisplayList::Paint.
1133 virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) {}
1135 #ifdef MOZ_DUMP_PAINTING
1137 * Mark this display item as being painted via FrameLayerBuilder::DrawThebesLayer.
1139 bool Painted() { return mPainted; }
1142 * Check if this display item has been painted.
1144 void SetPainted() { mPainted = true; }
1145 #endif
1148 * Get the layer drawn by this display item. Call this only if
1149 * GetLayerState() returns something other than LAYER_NONE.
1150 * If GetLayerState returned LAYER_NONE then Paint will be called
1151 * instead.
1152 * This is called while aManager is in the construction phase.
1154 * The caller (nsDisplayList) is responsible for setting the visible
1155 * region of the layer.
1157 * @param aContainerParameters should be passed to
1158 * FrameLayerBuilder::BuildContainerLayerFor if a ContainerLayer is
1159 * constructed.
1161 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
1162 LayerManager* aManager,
1163 const ContainerLayerParameters& aContainerParameters)
1164 { return nullptr; }
1167 * On entry, aVisibleRegion contains the region (relative to ReferenceFrame())
1168 * which may be visible. If the display item opaquely covers an area, it
1169 * can remove that area from aVisibleRegion before returning.
1170 * nsDisplayList::ComputeVisibility automatically subtracts the region
1171 * returned by GetOpaqueRegion, and automatically removes items whose bounds
1172 * do not intersect the visible area, so implementations of
1173 * nsDisplayItem::ComputeVisibility do not need to do these things.
1174 * nsDisplayList::ComputeVisibility will already have set mVisibleRect on
1175 * this item to the intersection of *aVisibleRegion and this item's bounds.
1176 * We rely on that, so this should only be called by
1177 * nsDisplayList::ComputeVisibility or nsDisplayItem::RecomputeVisibility.
1178 * aAllowVisibleRegionExpansion is a rect where we are allowed to
1179 * expand the visible region and is only used for making sure the
1180 * background behind a plugin is visible.
1181 * This method needs to be idempotent.
1183 * @return true if the item is visible, false if no part of the item
1184 * is visible.
1186 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
1187 nsRegion* aVisibleRegion);
1190 * Try to merge with the other item (which is below us in the display
1191 * list). This gets used by nsDisplayClip to coalesce clipping operations
1192 * (optimization), by nsDisplayOpacity to merge rendering for the same
1193 * content element into a single opacity group (correctness), and will be
1194 * used by nsDisplayOutline to merge multiple outlines for the same element
1195 * (also for correctness).
1196 * @return true if the merge was successful and the other item should be deleted
1198 virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) {
1199 return false;
1203 * Appends the underlying frames of all display items that have been
1204 * merged into this one (excluding this item's own underlying frame)
1205 * to aFrames.
1207 virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) {}
1210 * During the visibility computation and after TryMerge, display lists may
1211 * return true here to flatten themselves away, removing them. This
1212 * flattening is distinctly different from FlattenTo, which occurs before
1213 * items are merged together.
1215 virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) {
1216 return false;
1220 * If this has a child list where the children are in the same coordinate
1221 * system as this item (i.e., they have the same reference frame),
1222 * return the list.
1224 virtual nsDisplayList* GetSameCoordinateSystemChildren() { return nullptr; }
1225 virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) {}
1228 * If this has a child list, return it, even if the children are in
1229 * a different coordinate system to this item.
1231 virtual nsDisplayList* GetChildren() { return nullptr; }
1234 * Returns the visible rect.
1236 const nsRect& GetVisibleRect() const { return mVisibleRect; }
1239 * Returns the visible rect for the children, relative to their
1240 * reference frame. Can be different from mVisibleRect for nsDisplayTransform,
1241 * since the reference frame for the children is different from the reference
1242 * frame for the item itself.
1244 virtual const nsRect& GetVisibleRectForChildren() const { return mVisibleRect; }
1247 * Stores the given opacity value to be applied when drawing. Returns
1248 * false if this isn't supported for this display item.
1250 virtual bool ApplyOpacity(nsDisplayListBuilder* aBuilder,
1251 float aOpacity,
1252 const DisplayItemClip* aClip) {
1253 return false;
1256 #ifdef MOZ_DUMP_PAINTING
1258 * For debugging and stuff
1260 virtual const char* Name() = 0;
1262 virtual void WriteDebugInfo(nsACString& aTo) {}
1263 #endif
1265 nsDisplayItem* GetAbove() { return mAbove; }
1268 * Like ComputeVisibility, but does the work that nsDisplayList
1269 * does per-item:
1270 * -- Intersects GetBounds with aVisibleRegion and puts the result
1271 * in mVisibleRect
1272 * -- Subtracts bounds from aVisibleRegion if the item is opaque
1274 bool RecomputeVisibility(nsDisplayListBuilder* aBuilder,
1275 nsRegion* aVisibleRegion);
1278 * Returns the result of aBuilder->ToReferenceFrame(GetUnderlyingFrame())
1280 const nsPoint& ToReferenceFrame() const {
1281 NS_ASSERTION(mFrame, "No frame?");
1282 return mToReferenceFrame;
1285 * @return the root of the display list's frame (sub)tree, whose origin
1286 * establishes the coordinate system for the display list
1288 const nsIFrame* ReferenceFrame() const { return mReferenceFrame; }
1291 * Returns the reference frame for display item children of this item.
1293 virtual const nsIFrame* ReferenceFrameForChildren() const { return mReferenceFrame; }
1296 * Checks if this display item (or any children) contains content that might
1297 * be rendered with component alpha (e.g. subpixel antialiasing). Returns the
1298 * bounds of the area that needs component alpha, or an empty rect if nothing
1299 * in the item does.
1301 virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) { return nsRect(); }
1304 * Disable usage of component alpha. Currently only relevant for items that have text.
1306 virtual void DisableComponentAlpha() {}
1309 * Check if we can add async animations to the layer for this display item.
1311 virtual bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) {
1312 return false;
1315 virtual bool SupportsOptimizingToImage() { return false; }
1317 const DisplayItemClip& GetClip()
1319 return mClip ? *mClip : DisplayItemClip::NoClip();
1321 void SetClip(nsDisplayListBuilder* aBuilder, const DisplayItemClip& aClip)
1323 if (!aClip.HasClip()) {
1324 mClip = nullptr;
1325 return;
1327 mClip = aBuilder->AllocateDisplayItemClip(aClip);
1330 void IntersectClip(nsDisplayListBuilder* aBuilder, const DisplayItemClip& aClip)
1332 if (mClip) {
1333 DisplayItemClip temp = *mClip;
1334 temp.IntersectWith(aClip);
1335 SetClip(aBuilder, temp);
1336 } else {
1337 SetClip(aBuilder, aClip);
1341 protected:
1342 friend class nsDisplayList;
1344 nsDisplayItem() { mAbove = nullptr; }
1346 nsIFrame* mFrame;
1347 const DisplayItemClip* mClip;
1348 // Result of FindReferenceFrameFor(mFrame), if mFrame is non-null
1349 const nsIFrame* mReferenceFrame;
1350 // Result of ToReferenceFrame(mFrame), if mFrame is non-null
1351 nsPoint mToReferenceFrame;
1352 // This is the rectangle that needs to be painted.
1353 // Display item construction sets this to the dirty rect.
1354 // nsDisplayList::ComputeVisibility sets this to the visible region
1355 // of the item by intersecting the current visible region with the bounds
1356 // of the item. Paint implementations can use this to limit their drawing.
1357 // Guaranteed to be contained in GetBounds().
1358 nsRect mVisibleRect;
1359 #ifdef MOZ_DUMP_PAINTING
1360 // True if this frame has been painted.
1361 bool mPainted;
1362 #endif
1366 * Manages a singly-linked list of display list items.
1368 * mSentinel is the sentinel list value, the first value in the null-terminated
1369 * linked list of items. mTop is the last item in the list (whose 'above'
1370 * pointer is null). This class has no virtual methods. So list objects are just
1371 * two pointers.
1373 * Stepping upward through this list is very fast. Stepping downward is very
1374 * slow so we don't support it. The methods that need to step downward
1375 * (HitTest(), ComputeVisibility()) internally build a temporary array of all
1376 * the items while they do the downward traversal, so overall they're still
1377 * linear time. We have optimized for efficient AppendToTop() of both
1378 * items and lists, with minimal codesize. AppendToBottom() is efficient too.
1380 class nsDisplayList {
1381 public:
1382 typedef mozilla::layers::Layer Layer;
1383 typedef mozilla::layers::LayerManager LayerManager;
1384 typedef mozilla::layers::ThebesLayer ThebesLayer;
1387 * Create an empty list.
1389 nsDisplayList()
1390 : mIsOpaque(false)
1391 , mForceTransparentSurface(false)
1393 mTop = &mSentinel;
1394 mSentinel.mAbove = nullptr;
1396 ~nsDisplayList() {
1397 if (mSentinel.mAbove) {
1398 NS_WARNING("Nonempty list left over?");
1400 DeleteAll();
1404 * Append an item to the top of the list. The item must not currently
1405 * be in a list and cannot be null.
1407 void AppendToTop(nsDisplayItem* aItem) {
1408 NS_ASSERTION(aItem, "No item to append!");
1409 NS_ASSERTION(!aItem->mAbove, "Already in a list!");
1410 mTop->mAbove = aItem;
1411 mTop = aItem;
1415 * Append a new item to the top of the list. If the item is null we return
1416 * NS_ERROR_OUT_OF_MEMORY. The intended usage is AppendNewToTop(new ...);
1418 void AppendNewToTop(nsDisplayItem* aItem) {
1419 if (aItem) {
1420 AppendToTop(aItem);
1425 * Append a new item to the bottom of the list. If the item is null we return
1426 * NS_ERROR_OUT_OF_MEMORY. The intended usage is AppendNewToBottom(new ...);
1428 void AppendNewToBottom(nsDisplayItem* aItem) {
1429 if (aItem) {
1430 AppendToBottom(aItem);
1435 * Append a new item to the bottom of the list. The item must be non-null
1436 * and not already in a list.
1438 void AppendToBottom(nsDisplayItem* aItem) {
1439 NS_ASSERTION(aItem, "No item to append!");
1440 NS_ASSERTION(!aItem->mAbove, "Already in a list!");
1441 aItem->mAbove = mSentinel.mAbove;
1442 mSentinel.mAbove = aItem;
1443 if (mTop == &mSentinel) {
1444 mTop = aItem;
1449 * Removes all items from aList and appends them to the top of this list
1451 void AppendToTop(nsDisplayList* aList) {
1452 if (aList->mSentinel.mAbove) {
1453 mTop->mAbove = aList->mSentinel.mAbove;
1454 mTop = aList->mTop;
1455 aList->mTop = &aList->mSentinel;
1456 aList->mSentinel.mAbove = nullptr;
1461 * Removes all items from aList and prepends them to the bottom of this list
1463 void AppendToBottom(nsDisplayList* aList) {
1464 if (aList->mSentinel.mAbove) {
1465 aList->mTop->mAbove = mSentinel.mAbove;
1466 mSentinel.mAbove = aList->mSentinel.mAbove;
1467 if (mTop == &mSentinel) {
1468 mTop = aList->mTop;
1471 aList->mTop = &aList->mSentinel;
1472 aList->mSentinel.mAbove = nullptr;
1477 * Remove an item from the bottom of the list and return it.
1479 nsDisplayItem* RemoveBottom();
1482 * Remove all items from the list and call their destructors.
1484 void DeleteAll();
1487 * @return the item at the top of the list, or null if the list is empty
1489 nsDisplayItem* GetTop() const {
1490 return mTop != &mSentinel ? static_cast<nsDisplayItem*>(mTop) : nullptr;
1493 * @return the item at the bottom of the list, or null if the list is empty
1495 nsDisplayItem* GetBottom() const { return mSentinel.mAbove; }
1496 bool IsEmpty() const { return mTop == &mSentinel; }
1499 * This is *linear time*!
1500 * @return the number of items in the list
1502 uint32_t Count() const;
1504 * Stable sort the list by the z-order of GetUnderlyingFrame() on
1505 * each item. 'auto' is counted as zero. Content order is used as the
1506 * secondary order.
1507 * @param aCommonAncestor a common ancestor of all the content elements
1508 * associated with the display items, for speeding up tree order
1509 * checks, or nullptr if not known; it's only a hint, if it is not an
1510 * ancestor of some elements, then we lose performance but not correctness
1512 void SortByZOrder(nsDisplayListBuilder* aBuilder, nsIContent* aCommonAncestor);
1514 * Stable sort the list by the tree order of the content of
1515 * GetUnderlyingFrame() on each item. z-index is ignored.
1516 * @param aCommonAncestor a common ancestor of all the content elements
1517 * associated with the display items, for speeding up tree order
1518 * checks, or nullptr if not known; it's only a hint, if it is not an
1519 * ancestor of some elements, then we lose performance but not correctness
1521 void SortByContentOrder(nsDisplayListBuilder* aBuilder, nsIContent* aCommonAncestor);
1524 * Generic stable sort. Take care, because some of the items might be nsDisplayLists
1525 * themselves.
1526 * aCmp(item1, item2) should return true if item1 <= item2. We sort the items
1527 * into increasing order.
1529 typedef bool (* SortLEQ)(nsDisplayItem* aItem1, nsDisplayItem* aItem2,
1530 void* aClosure);
1531 void Sort(nsDisplayListBuilder* aBuilder, SortLEQ aCmp, void* aClosure);
1534 * Compute visiblity for the items in the list.
1535 * We put this logic here so it can be shared by top-level
1536 * painting and also display items that maintain child lists.
1537 * This is also a good place to put ComputeVisibility-related logic
1538 * that must be applied to every display item. In particular, this
1539 * sets mVisibleRect on each display item.
1540 * This sets mIsOpaque if the entire visible area of this list has
1541 * been removed from aVisibleRegion when we return.
1542 * This does not remove any items from the list, so we can recompute
1543 * visiblity with different regions later (see
1544 * FrameLayerBuilder::DrawThebesLayer).
1545 * This method needs to be idempotent.
1547 * @param aVisibleRegion the area that is visible, relative to the
1548 * reference frame; on return, this contains the area visible under the list.
1549 * I.e., opaque contents of this list are subtracted from aVisibleRegion.
1550 * @param aListVisibleBounds must be equal to the bounds of the intersection
1551 * of aVisibleRegion and GetBounds() for this list.
1552 * @param aDisplayPortFrame If the item for which this list corresponds is
1553 * within a displayport, the scroll frame for which that display port
1554 * applies. For root scroll frames, you can pass the the root frame instead.
1555 * @return true if any item in the list is visible.
1557 bool ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
1558 nsRegion* aVisibleRegion,
1559 const nsRect& aListVisibleBounds,
1560 nsIFrame* aDisplayPortFrame = nullptr);
1563 * As ComputeVisibilityForSublist, but computes visibility for a root
1564 * list (a list that does not belong to an nsDisplayItem).
1565 * This method needs to be idempotent.
1567 * @param aVisibleRegion the area that is visible
1568 * @param aDisplayPortFrame The root scroll frame, if a displayport is set
1570 bool ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
1571 nsRegion* aVisibleRegion,
1572 nsIFrame* aDisplayPortFrame = nullptr);
1575 * Returns true if the visible region output from ComputeVisiblity was
1576 * empty, i.e. everything visible in this list is opaque.
1578 bool IsOpaque() const {
1579 return mIsOpaque;
1583 * Returns true if any display item requires the surface to be transparent.
1585 bool NeedsTransparentSurface() const {
1586 return mForceTransparentSurface;
1589 * Paint the list to the rendering context. We assume that (0,0) in aCtx
1590 * corresponds to the origin of the reference frame. For best results,
1591 * aCtx's current transform should make (0,0) pixel-aligned. The
1592 * rectangle in aDirtyRect is painted, which *must* be contained in the
1593 * dirty rect used to construct the display list.
1595 * If aFlags contains PAINT_USE_WIDGET_LAYERS and
1596 * ShouldUseWidgetLayerManager() is set, then we will paint using
1597 * the reference frame's widget's layer manager (and ctx may be null),
1598 * otherwise we will use a temporary BasicLayerManager and ctx must
1599 * not be null.
1601 * If PAINT_FLUSH_LAYERS is set, we'll force a completely new layer
1602 * tree to be created for this paint *and* the next paint.
1604 * If PAINT_EXISTING_TRANSACTION is set, the reference frame's widget's
1605 * layer manager has already had BeginTransaction() called on it and
1606 * we should not call it again.
1608 * If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to compressed mode
1609 * to avoid short cut optimizations.
1611 * ComputeVisibility must be called before Paint.
1613 * This must only be called on the root display list of the display list
1614 * tree.
1616 enum {
1617 PAINT_DEFAULT = 0,
1618 PAINT_USE_WIDGET_LAYERS = 0x01,
1619 PAINT_FLUSH_LAYERS = 0x02,
1620 PAINT_EXISTING_TRANSACTION = 0x04,
1621 PAINT_NO_COMPOSITE = 0x08,
1622 PAINT_COMPRESSED = 0x10
1624 void PaintRoot(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
1625 uint32_t aFlags);
1627 * Like PaintRoot, but used for internal display sublists.
1628 * aForFrame is the frame that the list is associated with.
1630 void PaintForFrame(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
1631 nsIFrame* aForFrame, uint32_t aFlags);
1633 * Get the bounds. Takes the union of the bounds of all children.
1634 * The result is not cached.
1636 nsRect GetBounds(nsDisplayListBuilder* aBuilder) const;
1638 * Find the topmost display item that returns a non-null frame, and return
1639 * the frame.
1641 void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
1642 nsDisplayItem::HitTestState* aState,
1643 nsTArray<nsIFrame*> *aOutFrames) const;
1645 * Compute the union of the visible rects of the items in the list. The
1646 * result is not cached.
1648 nsRect GetVisibleRect() const;
1650 void SetIsOpaque()
1652 mIsOpaque = true;
1654 void SetNeedsTransparentSurface()
1656 mForceTransparentSurface = true;
1659 private:
1660 // This class is only used on stack, so we don't have to worry about leaking
1661 // it. Don't let us be heap-allocated!
1662 void* operator new(size_t sz) CPP_THROW_NEW;
1664 nsDisplayItemLink mSentinel;
1665 nsDisplayItemLink* mTop;
1667 // This is set by ComputeVisibility
1668 nsRect mVisibleRect;
1669 // This is set to true by FrameLayerBuilder if the final visible region
1670 // is empty (i.e. everything that was visible is covered by some
1671 // opaque content in this list).
1672 bool mIsOpaque;
1673 // This is set to true by FrameLayerBuilder if any display item in this
1674 // list needs to force the surface containing this list to be transparent.
1675 bool mForceTransparentSurface;
1679 * This is passed as a parameter to nsIFrame::BuildDisplayList. That method
1680 * will put any generated items onto the appropriate list given here. It's
1681 * basically just a collection with one list for each separate stacking layer.
1682 * The lists themselves are external to this object and thus can be shared
1683 * with others. Some of the list pointers may even refer to the same list.
1685 class nsDisplayListSet {
1686 public:
1688 * @return a list where one should place the border and/or background for
1689 * this frame (everything from steps 1 and 2 of CSS 2.1 appendix E)
1691 nsDisplayList* BorderBackground() const { return mBorderBackground; }
1693 * @return a list where one should place the borders and/or backgrounds for
1694 * block-level in-flow descendants (step 4 of CSS 2.1 appendix E)
1696 nsDisplayList* BlockBorderBackgrounds() const { return mBlockBorderBackgrounds; }
1698 * @return a list where one should place descendant floats (step 5 of
1699 * CSS 2.1 appendix E)
1701 nsDisplayList* Floats() const { return mFloats; }
1703 * @return a list where one should place the (pseudo) stacking contexts
1704 * for descendants of this frame (everything from steps 3, 7 and 8
1705 * of CSS 2.1 appendix E)
1707 nsDisplayList* PositionedDescendants() const { return mPositioned; }
1709 * @return a list where one should place the outlines
1710 * for this frame and its descendants (step 9 of CSS 2.1 appendix E)
1712 nsDisplayList* Outlines() const { return mOutlines; }
1714 * @return a list where one should place all other content
1716 nsDisplayList* Content() const { return mContent; }
1718 nsDisplayListSet(nsDisplayList* aBorderBackground,
1719 nsDisplayList* aBlockBorderBackgrounds,
1720 nsDisplayList* aFloats,
1721 nsDisplayList* aContent,
1722 nsDisplayList* aPositionedDescendants,
1723 nsDisplayList* aOutlines) :
1724 mBorderBackground(aBorderBackground),
1725 mBlockBorderBackgrounds(aBlockBorderBackgrounds),
1726 mFloats(aFloats),
1727 mContent(aContent),
1728 mPositioned(aPositionedDescendants),
1729 mOutlines(aOutlines) {
1733 * A copy constructor that lets the caller override the BorderBackground
1734 * list.
1736 nsDisplayListSet(const nsDisplayListSet& aLists,
1737 nsDisplayList* aBorderBackground) :
1738 mBorderBackground(aBorderBackground),
1739 mBlockBorderBackgrounds(aLists.BlockBorderBackgrounds()),
1740 mFloats(aLists.Floats()),
1741 mContent(aLists.Content()),
1742 mPositioned(aLists.PositionedDescendants()),
1743 mOutlines(aLists.Outlines()) {
1747 * Move all display items in our lists to top of the corresponding lists in the
1748 * destination.
1750 void MoveTo(const nsDisplayListSet& aDestination) const;
1752 private:
1753 // This class is only used on stack, so we don't have to worry about leaking
1754 // it. Don't let us be heap-allocated!
1755 void* operator new(size_t sz) CPP_THROW_NEW;
1757 protected:
1758 nsDisplayList* mBorderBackground;
1759 nsDisplayList* mBlockBorderBackgrounds;
1760 nsDisplayList* mFloats;
1761 nsDisplayList* mContent;
1762 nsDisplayList* mPositioned;
1763 nsDisplayList* mOutlines;
1767 * A specialization of nsDisplayListSet where the lists are actually internal
1768 * to the object, and all distinct.
1770 struct nsDisplayListCollection : public nsDisplayListSet {
1771 nsDisplayListCollection() :
1772 nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4],
1773 &mLists[5]) {}
1774 explicit nsDisplayListCollection(nsDisplayList* aBorderBackground) :
1775 nsDisplayListSet(aBorderBackground, &mLists[1], &mLists[2], &mLists[3], &mLists[4],
1776 &mLists[5]) {}
1779 * Sort all lists by content order.
1781 void SortAllByContentOrder(nsDisplayListBuilder* aBuilder, nsIContent* aCommonAncestor) {
1782 for (int32_t i = 0; i < 6; ++i) {
1783 mLists[i].SortByContentOrder(aBuilder, aCommonAncestor);
1787 private:
1788 // This class is only used on stack, so we don't have to worry about leaking
1789 // it. Don't let us be heap-allocated!
1790 void* operator new(size_t sz) CPP_THROW_NEW;
1792 nsDisplayList mLists[6];
1796 class nsDisplayImageContainer : public nsDisplayItem {
1797 public:
1798 typedef mozilla::layers::ImageContainer ImageContainer;
1799 typedef mozilla::layers::ImageLayer ImageLayer;
1801 nsDisplayImageContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
1802 : nsDisplayItem(aBuilder, aFrame)
1805 virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
1806 nsDisplayListBuilder* aBuilder) = 0;
1807 virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) = 0;
1809 virtual bool SupportsOptimizingToImage() MOZ_OVERRIDE { return true; }
1813 * Use this class to implement not-very-frequently-used display items
1814 * that are not opaque, do not receive events, and are bounded by a frame's
1815 * border-rect.
1817 * This should not be used for display items which are created frequently,
1818 * because each item is one or two pointers bigger than an item from a
1819 * custom display item class could be, and fractionally slower. However it does
1820 * save code size. We use this for infrequently-used item types.
1822 class nsDisplayGeneric : public nsDisplayItem {
1823 public:
1824 typedef void (* PaintCallback)(nsIFrame* aFrame, nsRenderingContext* aCtx,
1825 const nsRect& aDirtyRect, nsPoint aFramePt);
1827 nsDisplayGeneric(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
1828 PaintCallback aPaint, const char* aName, Type aType)
1829 : nsDisplayItem(aBuilder, aFrame), mPaint(aPaint)
1830 #ifdef MOZ_DUMP_PAINTING
1831 , mName(aName)
1832 #endif
1833 , mType(aType)
1835 MOZ_COUNT_CTOR(nsDisplayGeneric);
1837 #ifdef NS_BUILD_REFCNT_LOGGING
1838 virtual ~nsDisplayGeneric() {
1839 MOZ_COUNT_DTOR(nsDisplayGeneric);
1841 #endif
1843 virtual void Paint(nsDisplayListBuilder* aBuilder,
1844 nsRenderingContext* aCtx) MOZ_OVERRIDE {
1845 mPaint(mFrame, aCtx, mVisibleRect, ToReferenceFrame());
1847 NS_DISPLAY_DECL_NAME(mName, mType)
1849 virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE {
1850 if (mType == nsDisplayItem::TYPE_HEADER_FOOTER) {
1851 bool snap;
1852 return GetBounds(aBuilder, &snap);
1854 return nsRect();
1857 protected:
1858 PaintCallback mPaint;
1859 #ifdef MOZ_DUMP_PAINTING
1860 const char* mName;
1861 #endif
1862 Type mType;
1866 * Generic display item that can contain overflow. Use this in lieu of
1867 * nsDisplayGeneric if you have a frame that should use the visual overflow
1868 * rect of its frame when drawing items, instead of the frame's bounds.
1870 class nsDisplayGenericOverflow : public nsDisplayGeneric {
1871 public:
1872 nsDisplayGenericOverflow(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
1873 PaintCallback aPaint, const char* aName, Type aType)
1874 : nsDisplayGeneric(aBuilder, aFrame, aPaint, aName, aType)
1876 MOZ_COUNT_CTOR(nsDisplayGenericOverflow);
1878 #ifdef NS_BUILD_REFCNT_LOGGING
1879 virtual ~nsDisplayGenericOverflow() {
1880 MOZ_COUNT_DTOR(nsDisplayGenericOverflow);
1882 #endif
1885 * Returns the frame's visual overflow rect instead of the frame's bounds.
1887 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
1888 bool* aSnap) MOZ_OVERRIDE
1890 *aSnap = false;
1891 return Frame()->GetVisualOverflowRect() + ToReferenceFrame();
1895 #if defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF)
1897 * This class implements painting of reflow counts. Ideally, we would simply
1898 * make all the frame names be those returned by nsFrame::GetFrameName
1899 * (except that tosses in the content tag name!) and support only one color
1900 * and eliminate this class altogether in favor of nsDisplayGeneric, but for
1901 * the time being we can't pass args to a PaintCallback, so just have a
1902 * separate class to do the right thing. Sadly, this alsmo means we need to
1903 * hack all leaf frame classes to handle this.
1905 * XXXbz the color thing is a bit of a mess, but 0 basically means "not set"
1906 * here... I could switch it all to nscolor, but why bother?
1908 class nsDisplayReflowCount : public nsDisplayItem {
1909 public:
1910 nsDisplayReflowCount(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
1911 const char* aFrameName,
1912 uint32_t aColor = 0)
1913 : nsDisplayItem(aBuilder, aFrame),
1914 mFrameName(aFrameName),
1915 mColor(aColor)
1917 MOZ_COUNT_CTOR(nsDisplayReflowCount);
1919 #ifdef NS_BUILD_REFCNT_LOGGING
1920 virtual ~nsDisplayReflowCount() {
1921 MOZ_COUNT_DTOR(nsDisplayReflowCount);
1923 #endif
1925 virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE {
1926 mFrame->PresContext()->PresShell()->PaintCount(mFrameName, aCtx,
1927 mFrame->PresContext(),
1928 mFrame, ToReferenceFrame(),
1929 mColor);
1931 NS_DISPLAY_DECL_NAME("nsDisplayReflowCount", TYPE_REFLOW_COUNT)
1932 protected:
1933 const char* mFrameName;
1934 nscolor mColor;
1937 #define DO_GLOBAL_REFLOW_COUNT_DSP(_name) \
1938 PR_BEGIN_MACRO \
1939 if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() && \
1940 PresContext()->PresShell()->IsPaintingFrameCounts()) { \
1941 aLists.Outlines()->AppendNewToTop( \
1942 new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name)); \
1944 PR_END_MACRO
1946 #define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color) \
1947 PR_BEGIN_MACRO \
1948 if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() && \
1949 PresContext()->PresShell()->IsPaintingFrameCounts()) { \
1950 aLists.Outlines()->AppendNewToTop( \
1951 new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name, _color)); \
1953 PR_END_MACRO
1956 Macro to be used for classes that don't actually implement BuildDisplayList
1958 #define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super) \
1959 void BuildDisplayList(nsDisplayListBuilder* aBuilder, \
1960 const nsRect& aDirtyRect, \
1961 const nsDisplayListSet& aLists) { \
1962 DO_GLOBAL_REFLOW_COUNT_DSP(#_class); \
1963 _super::BuildDisplayList(aBuilder, aDirtyRect, aLists); \
1966 #else // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF
1968 #define DO_GLOBAL_REFLOW_COUNT_DSP(_name)
1969 #define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color)
1970 #define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super)
1972 #endif // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF
1974 class nsDisplayCaret : public nsDisplayItem {
1975 public:
1976 nsDisplayCaret(nsDisplayListBuilder* aBuilder, nsIFrame* aCaretFrame);
1977 #ifdef NS_BUILD_REFCNT_LOGGING
1978 virtual ~nsDisplayCaret();
1979 #endif
1981 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
1982 virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
1983 NS_DISPLAY_DECL_NAME("Caret", TYPE_CARET)
1984 protected:
1985 nsRefPtr<nsCaret> mCaret;
1986 nsRect mBounds;
1990 * The standard display item to paint the CSS borders of a frame.
1992 class nsDisplayBorder : public nsDisplayItem {
1993 public:
1994 nsDisplayBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) :
1995 nsDisplayItem(aBuilder, aFrame)
1997 MOZ_COUNT_CTOR(nsDisplayBorder);
1999 #ifdef NS_BUILD_REFCNT_LOGGING
2000 virtual ~nsDisplayBorder() {
2001 MOZ_COUNT_DTOR(nsDisplayBorder);
2003 #endif
2005 virtual bool IsInvisibleInRect(const nsRect& aRect) MOZ_OVERRIDE;
2006 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
2007 virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
2008 NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
2010 virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
2012 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
2013 const nsDisplayItemGeometry* aGeometry,
2014 nsRegion* aInvalidRegion) MOZ_OVERRIDE;
2016 protected:
2017 nsRect CalculateBounds(const nsStyleBorder& aStyleBorder);
2021 * A simple display item that just renders a solid color across the
2022 * specified bounds. For canvas frames (in the CSS sense) we split off the
2023 * drawing of the background color into this class (from nsDisplayBackground
2024 * via nsDisplayCanvasBackground). This is done so that we can always draw a
2025 * background color to avoid ugly flashes of white when we can't draw a full
2026 * frame tree (ie when a page is loading). The bounds can differ from the
2027 * frame's bounds -- this is needed when a frame/iframe is loading and there
2028 * is not yet a frame tree to go in the frame/iframe so we use the subdoc
2029 * frame of the parent document as a standin.
2031 class nsDisplaySolidColor : public nsDisplayItem {
2032 public:
2033 nsDisplaySolidColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2034 const nsRect& aBounds, nscolor aColor)
2035 : nsDisplayItem(aBuilder, aFrame), mBounds(aBounds), mColor(aColor)
2037 NS_ASSERTION(NS_GET_A(aColor) > 0, "Don't create invisible nsDisplaySolidColors!");
2038 MOZ_COUNT_CTOR(nsDisplaySolidColor);
2040 #ifdef NS_BUILD_REFCNT_LOGGING
2041 virtual ~nsDisplaySolidColor() {
2042 MOZ_COUNT_DTOR(nsDisplaySolidColor);
2044 #endif
2046 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
2048 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
2049 bool* aSnap) MOZ_OVERRIDE {
2050 *aSnap = false;
2051 nsRegion result;
2052 if (NS_GET_A(mColor) == 255) {
2053 result = GetBounds(aBuilder, aSnap);
2055 return result;
2058 virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE
2060 *aColor = mColor;
2061 return true;
2064 virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
2066 virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
2068 return new nsDisplaySolidColorGeometry(this, aBuilder, mColor);
2071 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
2072 const nsDisplayItemGeometry* aGeometry,
2073 nsRegion* aInvalidRegion) MOZ_OVERRIDE
2075 const nsDisplaySolidColorGeometry* geometry =
2076 static_cast<const nsDisplaySolidColorGeometry*>(aGeometry);
2077 if (mColor != geometry->mColor) {
2078 bool dummy;
2079 aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &dummy));
2080 return;
2082 ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
2085 #ifdef MOZ_DUMP_PAINTING
2086 virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
2087 #endif
2089 NS_DISPLAY_DECL_NAME("SolidColor", TYPE_SOLID_COLOR)
2091 private:
2092 nsRect mBounds;
2093 nscolor mColor;
2097 * A display item to paint one background-image for a frame. Each background
2098 * image layer gets its own nsDisplayBackgroundImage.
2100 class nsDisplayBackgroundImage : public nsDisplayImageContainer {
2101 public:
2103 * aLayer signifies which background layer this item represents.
2104 * aIsThemed should be the value of aFrame->IsThemed.
2105 * aBackgroundStyle should be the result of
2106 * nsCSSRendering::FindBackground, or null if FindBackground returned false.
2108 nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2109 uint32_t aLayer,
2110 const nsStyleBackground* aBackgroundStyle);
2111 virtual ~nsDisplayBackgroundImage();
2113 // This will create and append new items for all the layers of the
2114 // background. Returns whether we appended a themed background.
2115 static bool AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuilder,
2116 nsIFrame* aFrame,
2117 nsDisplayList* aList);
2119 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
2120 LayerManager* aManager,
2121 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
2123 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
2124 LayerManager* aManager,
2125 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
2127 virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
2128 HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
2129 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
2130 nsRegion* aVisibleRegion) MOZ_OVERRIDE;
2131 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
2132 bool* aSnap) MOZ_OVERRIDE;
2133 virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE;
2135 * GetBounds() returns the background painting area.
2137 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
2138 virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
2139 virtual uint32_t GetPerFrameKey() MOZ_OVERRIDE;
2140 NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
2143 * Return the background positioning area.
2144 * (GetBounds() returns the background painting area.)
2145 * Can be called only when mBackgroundStyle is non-null.
2147 nsRect GetPositioningArea();
2150 * Returns true if existing rendered pixels of this display item may need
2151 * to be redrawn if the positioning area size changes but its position does
2152 * not.
2153 * If false, only the changed painting area needs to be redrawn when the
2154 * positioning area size changes but its position does not.
2156 bool RenderingMightDependOnPositioningAreaSizeChange();
2158 virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
2160 return new nsDisplayBackgroundGeometry(this, aBuilder);
2163 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
2164 const nsDisplayItemGeometry* aGeometry,
2165 nsRegion* aInvalidRegion) MOZ_OVERRIDE;
2167 virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager,
2168 nsDisplayListBuilder *aBuilder) MOZ_OVERRIDE;
2169 virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) MOZ_OVERRIDE;
2171 static nsRegion GetInsideClipRegion(nsDisplayItem* aItem, nsPresContext* aPresContext, uint8_t aClip,
2172 const nsRect& aRect, bool* aSnap);
2174 virtual bool ShouldFixToViewport(LayerManager* aManager) MOZ_OVERRIDE;
2176 protected:
2177 typedef class mozilla::layers::ImageContainer ImageContainer;
2178 typedef class mozilla::layers::ImageLayer ImageLayer;
2180 bool TryOptimizeToImageLayer(LayerManager* aManager, nsDisplayListBuilder* aBuilder);
2181 bool IsSingleFixedPositionImage(nsDisplayListBuilder* aBuilder,
2182 const nsRect& aClipRect,
2183 gfxRect* aDestRect);
2184 nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder);
2186 void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
2187 const nsRect& aBounds, nsRect* aClipRect);
2189 // Cache the result of nsCSSRendering::FindBackground. Always null if
2190 // mIsThemed is true or if FindBackground returned false.
2191 const nsStyleBackground* mBackgroundStyle;
2192 /* If this background can be a simple image layer, we store the format here. */
2193 nsRefPtr<ImageContainer> mImageContainer;
2194 gfxRect mDestRect;
2195 /* Bounds of this display item */
2196 nsRect mBounds;
2197 uint32_t mLayer;
2202 * A display item to paint the native theme background for a frame.
2204 class nsDisplayThemedBackground : public nsDisplayItem {
2205 public:
2206 nsDisplayThemedBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
2207 virtual ~nsDisplayThemedBackground();
2209 virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
2210 HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
2211 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
2212 bool* aSnap) MOZ_OVERRIDE;
2213 virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE;
2215 * GetBounds() returns the background painting area.
2217 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
2218 virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
2219 NS_DISPLAY_DECL_NAME("ThemedBackground", TYPE_THEMED_BACKGROUND)
2222 * Return the background positioning area.
2223 * (GetBounds() returns the background painting area.)
2224 * Can be called only when mBackgroundStyle is non-null.
2226 nsRect GetPositioningArea();
2229 * Return whether our frame's document does not have the state
2230 * NS_DOCUMENT_STATE_WINDOW_INACTIVE.
2232 bool IsWindowActive();
2234 virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
2236 return new nsDisplayThemedBackgroundGeometry(this, aBuilder);
2239 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
2240 const nsDisplayItemGeometry* aGeometry,
2241 nsRegion* aInvalidRegion) MOZ_OVERRIDE;
2243 #ifdef MOZ_DUMP_PAINTING
2244 virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
2245 #endif
2246 protected:
2247 nsRect GetBoundsInternal();
2249 void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
2250 const nsRect& aBounds, nsRect* aClipRect);
2252 nsRect mBounds;
2253 nsITheme::Transparency mThemeTransparency;
2254 uint8_t mAppearance;
2257 class nsDisplayBackgroundColor : public nsDisplayItem
2259 public:
2260 nsDisplayBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2261 const nsStyleBackground* aBackgroundStyle,
2262 nscolor aColor)
2263 : nsDisplayItem(aBuilder, aFrame)
2264 , mBackgroundStyle(aBackgroundStyle)
2265 , mColor(gfxRGBA(aColor))
2268 virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
2270 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
2271 bool* aSnap) MOZ_OVERRIDE;
2272 virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE;
2273 virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
2274 HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
2276 virtual bool ApplyOpacity(nsDisplayListBuilder* aBuilder,
2277 float aOpacity,
2278 const DisplayItemClip* aClip) MOZ_OVERRIDE;
2280 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE
2282 *aSnap = true;
2283 return nsRect(ToReferenceFrame(), Frame()->GetSize());
2286 virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
2288 return new nsDisplaySolidColorGeometry(this, aBuilder,
2289 NS_RGBA_FROM_GFXRGBA(mColor));
2292 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
2293 const nsDisplayItemGeometry* aGeometry,
2294 nsRegion* aInvalidRegion) MOZ_OVERRIDE
2296 const nsDisplaySolidColorGeometry* geometry = static_cast<const nsDisplaySolidColorGeometry*>(aGeometry);
2297 if (NS_RGBA_FROM_GFXRGBA(mColor) != geometry->mColor) {
2298 bool dummy;
2299 aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &dummy));
2300 return;
2302 ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
2305 NS_DISPLAY_DECL_NAME("BackgroundColor", TYPE_BACKGROUND_COLOR)
2306 #ifdef MOZ_DUMP_PAINTING
2307 virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
2308 #endif
2310 protected:
2311 const nsStyleBackground* mBackgroundStyle;
2312 gfxRGBA mColor;
2315 class nsDisplayClearBackground : public nsDisplayItem
2317 public:
2318 nsDisplayClearBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
2319 : nsDisplayItem(aBuilder, aFrame)
2322 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE
2324 *aSnap = true;
2325 return nsRect(ToReferenceFrame(), Frame()->GetSize());
2328 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
2329 bool* aSnap) MOZ_OVERRIDE {
2330 *aSnap = false;
2331 return GetBounds(aBuilder, aSnap);
2334 virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE
2336 *aColor = NS_RGBA(0, 0, 0, 0);
2337 return true;
2340 virtual bool ClearsBackground() MOZ_OVERRIDE
2342 return true;
2345 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
2346 LayerManager* aManager,
2347 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
2349 return mozilla::LAYER_ACTIVE_FORCE;
2352 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
2353 LayerManager* aManager,
2354 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
2356 NS_DISPLAY_DECL_NAME("ClearBackground", TYPE_CLEAR_BACKGROUND)
2360 * The standard display item to paint the outer CSS box-shadows of a frame.
2362 class nsDisplayBoxShadowOuter MOZ_FINAL : public nsDisplayItem {
2363 public:
2364 nsDisplayBoxShadowOuter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
2365 : nsDisplayItem(aBuilder, aFrame)
2366 , mOpacity(1.0) {
2367 MOZ_COUNT_CTOR(nsDisplayBoxShadowOuter);
2368 mBounds = GetBoundsInternal();
2370 #ifdef NS_BUILD_REFCNT_LOGGING
2371 virtual ~nsDisplayBoxShadowOuter() {
2372 MOZ_COUNT_DTOR(nsDisplayBoxShadowOuter);
2374 #endif
2376 virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
2377 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
2378 virtual bool IsInvisibleInRect(const nsRect& aRect) MOZ_OVERRIDE;
2379 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
2380 nsRegion* aVisibleRegion) MOZ_OVERRIDE;
2381 NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER)
2383 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
2384 const nsDisplayItemGeometry* aGeometry,
2385 nsRegion* aInvalidRegion) MOZ_OVERRIDE;
2387 virtual bool ApplyOpacity(nsDisplayListBuilder* aBuilder,
2388 float aOpacity,
2389 const DisplayItemClip* aClip) MOZ_OVERRIDE
2391 mOpacity = aOpacity;
2392 if (aClip) {
2393 IntersectClip(aBuilder, *aClip);
2395 return true;
2398 virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
2400 return new nsDisplayBoxShadowOuterGeometry(this, aBuilder, mOpacity);
2403 nsRect GetBoundsInternal();
2405 private:
2406 nsRegion mVisibleRegion;
2407 nsRect mBounds;
2408 float mOpacity;
2412 * The standard display item to paint the inner CSS box-shadows of a frame.
2414 class nsDisplayBoxShadowInner : public nsDisplayItem {
2415 public:
2416 nsDisplayBoxShadowInner(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
2417 : nsDisplayItem(aBuilder, aFrame) {
2418 MOZ_COUNT_CTOR(nsDisplayBoxShadowInner);
2420 #ifdef NS_BUILD_REFCNT_LOGGING
2421 virtual ~nsDisplayBoxShadowInner() {
2422 MOZ_COUNT_DTOR(nsDisplayBoxShadowInner);
2424 #endif
2426 virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
2427 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
2428 nsRegion* aVisibleRegion) MOZ_OVERRIDE;
2429 NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER)
2431 virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
2433 return new nsDisplayBoxShadowInnerGeometry(this, aBuilder);
2436 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
2437 const nsDisplayItemGeometry* aGeometry,
2438 nsRegion* aInvalidRegion) MOZ_OVERRIDE
2440 const nsDisplayBoxShadowInnerGeometry* geometry = static_cast<const nsDisplayBoxShadowInnerGeometry*>(aGeometry);
2441 if (!geometry->mPaddingRect.IsEqualInterior(GetPaddingRect())) {
2442 // nsDisplayBoxShadowInner is based around the padding rect, but it can
2443 // touch pixels outside of this. We should invalidate the entire bounds.
2444 bool snap;
2445 aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &snap));
2449 private:
2450 nsRegion mVisibleRegion;
2454 * The standard display item to paint the CSS outline of a frame.
2456 class nsDisplayOutline : public nsDisplayItem {
2457 public:
2458 nsDisplayOutline(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) :
2459 nsDisplayItem(aBuilder, aFrame) {
2460 MOZ_COUNT_CTOR(nsDisplayOutline);
2462 #ifdef NS_BUILD_REFCNT_LOGGING
2463 virtual ~nsDisplayOutline() {
2464 MOZ_COUNT_DTOR(nsDisplayOutline);
2466 #endif
2468 virtual bool IsInvisibleInRect(const nsRect& aRect) MOZ_OVERRIDE;
2469 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
2470 virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
2471 NS_DISPLAY_DECL_NAME("Outline", TYPE_OUTLINE)
2475 * A class that lets you receive events within the frame bounds but never paints.
2477 class nsDisplayEventReceiver : public nsDisplayItem {
2478 public:
2479 nsDisplayEventReceiver(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
2480 : nsDisplayItem(aBuilder, aFrame) {
2481 MOZ_COUNT_CTOR(nsDisplayEventReceiver);
2483 #ifdef NS_BUILD_REFCNT_LOGGING
2484 virtual ~nsDisplayEventReceiver() {
2485 MOZ_COUNT_DTOR(nsDisplayEventReceiver);
2487 #endif
2489 virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
2490 HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
2491 NS_DISPLAY_DECL_NAME("EventReceiver", TYPE_EVENT_RECEIVER)
2495 * A display item that tracks event-sensitive regions which will be set
2496 * on the ContainerLayer that eventually contains this item.
2498 * One of these is created for each stacking context and pseudo-stacking-context.
2499 * It accumulates regions for event targets contributed by the border-boxes of
2500 * frames in its (pseudo) stacking context. A nsDisplayLayerEventRegions
2501 * eventually contributes its regions to the ThebesLayer it is placed in by
2502 * FrameLayerBuilder. (We don't create a display item for every frame that
2503 * could be an event target (i.e. almost all frames), because that would be
2504 * high overhead.)
2506 * We always make leaf layers other than ThebesLayers transparent to events.
2507 * For example, an event targeting a canvas or video will actually target the
2508 * background of that element, which is logically in the ThebesLayer behind the
2509 * CanvasFrame or ImageFrame. We only need to create a
2510 * nsDisplayLayerEventRegions when an element's background could be in front
2511 * of a lower z-order element with its own layer.
2513 class nsDisplayLayerEventRegions MOZ_FINAL : public nsDisplayItem {
2514 public:
2515 nsDisplayLayerEventRegions(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
2516 : nsDisplayItem(aBuilder, aFrame)
2518 MOZ_COUNT_CTOR(nsDisplayEventReceiver);
2519 AddFrame(aBuilder, aFrame);
2521 #ifdef NS_BUILD_REFCNT_LOGGING
2522 virtual ~nsDisplayLayerEventRegions() {
2523 MOZ_COUNT_DTOR(nsDisplayEventReceiver);
2525 #endif
2526 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE
2528 *aSnap = false;
2529 return mHitRegion.GetBounds().Union(mMaybeHitRegion.GetBounds());
2532 NS_DISPLAY_DECL_NAME("LayerEventRegions", TYPE_LAYER_EVENT_REGIONS)
2534 // Indicate that aFrame's border-box contributes to the event regions for
2535 // this layer. aFrame must have the same reference frame as mFrame.
2536 void AddFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
2538 const nsRegion& HitRegion() { return mHitRegion; }
2539 const nsRegion& MaybeHitRegion() { return mMaybeHitRegion; }
2540 const nsRegion& DispatchToContentHitRegion() { return mDispatchToContentHitRegion; }
2542 private:
2543 // Relative to aFrame's reference frame.
2544 // These are the points that are definitely in the hit region.
2545 nsRegion mHitRegion;
2546 // These are points that may or may not be in the hit region. Only main-thread
2547 // event handling can tell for sure (e.g. because complex shapes are present).
2548 nsRegion mMaybeHitRegion;
2549 // These are points that need to be dispatched to the content thread for
2550 // resolution. Always contained in the union of mHitRegion and mMaybeHitRegion.
2551 nsRegion mDispatchToContentHitRegion;
2555 * A class that lets you wrap a display list as a display item.
2557 * GetUnderlyingFrame() is troublesome for wrapped lists because if the wrapped
2558 * list has many items, it's not clear which one has the 'underlying frame'.
2559 * Thus we force the creator to specify what the underlying frame is. The
2560 * underlying frame should be the root of a stacking context, because sorting
2561 * a list containing this item will not get at the children.
2563 * In some cases (e.g., clipping) we want to wrap a list but we don't have a
2564 * particular underlying frame that is a stacking context root. In that case
2565 * we allow the frame to be nullptr. Callers to GetUnderlyingFrame must
2566 * detect and handle this case.
2568 class nsDisplayWrapList : public nsDisplayItem {
2569 public:
2571 * Takes all the items from aList and puts them in our list.
2573 nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2574 nsDisplayList* aList);
2575 nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2576 nsDisplayItem* aItem);
2577 nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
2578 : nsDisplayItem(aBuilder, aFrame), mOverrideZIndex(0), mHasZIndexOverride(false)
2580 MOZ_COUNT_CTOR(nsDisplayWrapList);
2582 virtual ~nsDisplayWrapList();
2584 * Call this if the wrapped list is changed.
2586 virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
2588 mBounds = mList.GetBounds(aBuilder);
2590 virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
2591 HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
2592 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
2593 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
2594 bool* aSnap) MOZ_OVERRIDE;
2595 virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE;
2596 virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
2597 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
2598 nsRegion* aVisibleRegion) MOZ_OVERRIDE;
2599 virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE {
2600 return false;
2602 virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) MOZ_OVERRIDE
2604 aFrames->AppendElements(mMergedFrames);
2606 virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) {
2607 return true;
2609 virtual bool IsInvalid(nsRect& aRect) MOZ_OVERRIDE
2611 if (mFrame->IsInvalid(aRect) && aRect.IsEmpty()) {
2612 return true;
2614 nsRect temp;
2615 for (uint32_t i = 0; i < mMergedFrames.Length(); i++) {
2616 if (mMergedFrames[i]->IsInvalid(temp) && temp.IsEmpty()) {
2617 aRect.SetEmpty();
2618 return true;
2620 aRect = aRect.Union(temp);
2622 aRect += ToReferenceFrame();
2623 return !aRect.IsEmpty();
2625 NS_DISPLAY_DECL_NAME("WrapList", TYPE_WRAP_LIST)
2627 virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
2629 virtual nsDisplayList* GetSameCoordinateSystemChildren() MOZ_OVERRIDE
2631 NS_ASSERTION(mList.IsEmpty() || !ReferenceFrame() ||
2632 !mList.GetBottom()->ReferenceFrame() ||
2633 mList.GetBottom()->ReferenceFrame() == ReferenceFrame(),
2634 "Children must have same reference frame");
2635 return &mList;
2637 virtual nsDisplayList* GetChildren() MOZ_OVERRIDE { return &mList; }
2639 virtual int32_t ZIndex() const MOZ_OVERRIDE
2641 return (mHasZIndexOverride) ? mOverrideZIndex : nsDisplayItem::ZIndex();
2644 void SetOverrideZIndex(int32_t aZIndex)
2646 mHasZIndexOverride = true;
2647 mOverrideZIndex = aZIndex;
2650 void SetVisibleRect(const nsRect& aRect);
2653 * This creates a copy of this item, but wrapping aItem instead of
2654 * our existing list. Only gets called if this item returned nullptr
2655 * for GetUnderlyingFrame(). aItem is guaranteed to return non-null from
2656 * GetUnderlyingFrame().
2658 virtual nsDisplayWrapList* WrapWithClone(nsDisplayListBuilder* aBuilder,
2659 nsDisplayItem* aItem) {
2660 NS_NOTREACHED("We never returned nullptr for GetUnderlyingFrame!");
2661 return nullptr;
2664 protected:
2665 nsDisplayWrapList() {}
2667 void MergeFromTrackingMergedFrames(nsDisplayWrapList* aOther)
2669 mList.AppendToBottom(&aOther->mList);
2670 mBounds.UnionRect(mBounds, aOther->mBounds);
2671 mVisibleRect.UnionRect(mVisibleRect, aOther->mVisibleRect);
2672 mMergedFrames.AppendElement(aOther->mFrame);
2673 mMergedFrames.MoveElementsFrom(aOther->mMergedFrames);
2676 nsDisplayList mList;
2677 // The frames from items that have been merged into this item, excluding
2678 // this item's own frame.
2679 nsTArray<nsIFrame*> mMergedFrames;
2680 nsRect mBounds;
2681 int32_t mOverrideZIndex;
2682 bool mHasZIndexOverride;
2686 * We call WrapDisplayList on the in-flow lists: BorderBackground(),
2687 * BlockBorderBackgrounds() and Content().
2688 * We call WrapDisplayItem on each item of Outlines(), PositionedDescendants(),
2689 * and Floats(). This is done to support special wrapping processing for frames
2690 * that may not be in-flow descendants of the current frame.
2692 class nsDisplayWrapper {
2693 public:
2694 // This is never instantiated directly (it has pure virtual methods), so no
2695 // need to count constructors and destructors.
2697 virtual bool WrapBorderBackground() { return true; }
2698 virtual nsDisplayItem* WrapList(nsDisplayListBuilder* aBuilder,
2699 nsIFrame* aFrame, nsDisplayList* aList) = 0;
2700 virtual nsDisplayItem* WrapItem(nsDisplayListBuilder* aBuilder,
2701 nsDisplayItem* aItem) = 0;
2703 nsresult WrapLists(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2704 const nsDisplayListSet& aIn, const nsDisplayListSet& aOut);
2705 nsresult WrapListsInPlace(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2706 const nsDisplayListSet& aLists);
2707 protected:
2708 nsDisplayWrapper() {}
2712 * The standard display item to paint a stacking context with translucency
2713 * set by the stacking context root frame's 'opacity' style.
2715 class nsDisplayOpacity : public nsDisplayWrapList {
2716 public:
2717 nsDisplayOpacity(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2718 nsDisplayList* aList);
2719 #ifdef NS_BUILD_REFCNT_LOGGING
2720 virtual ~nsDisplayOpacity();
2721 #endif
2723 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
2724 bool* aSnap) MOZ_OVERRIDE;
2725 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
2726 LayerManager* aManager,
2727 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
2728 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
2729 LayerManager* aManager,
2730 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
2731 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
2732 nsRegion* aVisibleRegion) MOZ_OVERRIDE;
2733 virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
2734 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
2735 const nsDisplayItemGeometry* aGeometry,
2736 nsRegion* aInvalidRegion) MOZ_OVERRIDE
2738 // We don't need to compute an invalidation region since we have LayerTreeInvalidation
2740 virtual bool ApplyOpacity(nsDisplayListBuilder* aBuilder,
2741 float aOpacity,
2742 const DisplayItemClip* aClip) MOZ_OVERRIDE;
2743 virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
2744 bool NeedsActiveLayer();
2745 NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
2746 #ifdef MOZ_DUMP_PAINTING
2747 virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
2748 #endif
2750 bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
2752 private:
2753 float mOpacity;
2756 class nsDisplayMixBlendMode : public nsDisplayWrapList {
2757 public:
2758 nsDisplayMixBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2759 nsDisplayList* aList, uint32_t aFlags = 0);
2760 #ifdef NS_BUILD_REFCNT_LOGGING
2761 virtual ~nsDisplayMixBlendMode();
2762 #endif
2764 nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
2765 bool* aSnap) MOZ_OVERRIDE;
2767 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
2768 LayerManager* aManager,
2769 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
2770 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
2771 const nsDisplayItemGeometry* aGeometry,
2772 nsRegion* aInvalidRegion) MOZ_OVERRIDE
2774 // We don't need to compute an invalidation region since we have LayerTreeInvalidation
2776 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
2777 LayerManager* aManager,
2778 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
2779 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
2780 nsRegion* aVisibleRegion) MOZ_OVERRIDE;
2781 virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
2782 virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE {
2783 return false;
2785 NS_DISPLAY_DECL_NAME("MixBlendMode", TYPE_MIX_BLEND_MODE)
2788 class nsDisplayBlendContainer : public nsDisplayWrapList {
2789 public:
2790 nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2791 nsDisplayList* aList,
2792 BlendModeSet& aContainedBlendModes);
2793 nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2794 nsDisplayList* aList);
2795 #ifdef NS_BUILD_REFCNT_LOGGING
2796 virtual ~nsDisplayBlendContainer();
2797 #endif
2799 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
2800 LayerManager* aManager,
2801 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
2802 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
2803 LayerManager* aManager,
2804 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
2806 if (mCanBeActive && aManager->SupportsMixBlendModes(mContainedBlendModes)) {
2807 return mozilla::LAYER_ACTIVE;
2809 return mozilla::LAYER_INACTIVE;
2811 virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
2812 virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE {
2813 return false;
2815 NS_DISPLAY_DECL_NAME("BlendContainer", TYPE_BLEND_CONTAINER)
2817 private:
2818 // The set of all blend modes used by nsDisplayMixBlendMode descendents of this container.
2819 BlendModeSet mContainedBlendModes;
2820 // If this is true, then we should make the layer active if all contained blend
2821 // modes can be supported by the current layer manager.
2822 bool mCanBeActive;
2826 * A display item that has no purpose but to ensure its contents get
2827 * their own layer.
2829 class nsDisplayOwnLayer : public nsDisplayWrapList {
2830 public:
2833 * nsDisplayOwnLayer constructor flags
2835 enum {
2836 GENERATE_SUBDOC_INVALIDATIONS = 0x01,
2837 VERTICAL_SCROLLBAR = 0x02,
2838 HORIZONTAL_SCROLLBAR = 0x04,
2839 GENERATE_SCROLLABLE_LAYER = 0x08
2843 * @param aFlags GENERATE_SUBDOC_INVALIDATIONS :
2844 * Add UserData to the created ContainerLayer, so that invalidations
2845 * for this layer are send to our nsPresContext.
2846 * GENERATE_SCROLLABLE_LAYER : only valid on nsDisplaySubDocument (and
2847 * subclasses), indicates this layer is to be a scrollable layer, so call
2848 * RecordFrameMetrics, etc.
2849 * @param aScrollTarget when VERTICAL_SCROLLBAR or HORIZONTAL_SCROLLBAR
2850 * is set in the flags, this parameter should be the ViewID of the
2851 * scrollable content this scrollbar is for.
2853 nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2854 nsDisplayList* aList, uint32_t aFlags = 0,
2855 ViewID aScrollTarget = mozilla::layers::FrameMetrics::NULL_SCROLL_ID);
2856 #ifdef NS_BUILD_REFCNT_LOGGING
2857 virtual ~nsDisplayOwnLayer();
2858 #endif
2860 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
2861 LayerManager* aManager,
2862 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
2863 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
2864 LayerManager* aManager,
2865 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
2867 return mozilla::LAYER_ACTIVE_FORCE;
2869 virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE
2871 // Don't allow merging, each sublist must have its own layer
2872 return false;
2874 virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE {
2875 return false;
2877 uint32_t GetFlags() { return mFlags; }
2878 NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
2879 protected:
2880 uint32_t mFlags;
2881 ViewID mScrollTarget;
2885 * A display item for subdocuments. This is more or less the same as nsDisplayOwnLayer,
2886 * except that it always populates the FrameMetrics instance on the ContainerLayer it
2887 * builds.
2889 class nsDisplaySubDocument : public nsDisplayOwnLayer {
2890 public:
2891 nsDisplaySubDocument(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2892 nsDisplayList* aList, uint32_t aFlags);
2893 #ifdef NS_BUILD_REFCNT_LOGGING
2894 virtual ~nsDisplaySubDocument();
2895 #endif
2897 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
2898 LayerManager* aManager,
2899 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
2901 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
2903 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
2904 nsRegion* aVisibleRegion) MOZ_OVERRIDE;
2906 virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
2908 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
2910 NS_DISPLAY_DECL_NAME("SubDocument", TYPE_SUBDOCUMENT)
2912 mozilla::UniquePtr<FrameMetrics> ComputeFrameMetrics(Layer* aLayer,
2913 const ContainerLayerParameters& aContainerParameters);
2915 protected:
2916 ViewID mScrollParentId;
2920 * A display item for subdocuments to capture the resolution from the presShell
2921 * and ensure that it gets applied to all the right elements. This item creates
2922 * a container layer.
2924 class nsDisplayResolution : public nsDisplaySubDocument {
2925 public:
2926 nsDisplayResolution(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2927 nsDisplayList* aList, uint32_t aFlags);
2928 #ifdef NS_BUILD_REFCNT_LOGGING
2929 virtual ~nsDisplayResolution();
2930 #endif
2932 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
2933 LayerManager* aManager,
2934 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
2935 NS_DISPLAY_DECL_NAME("Resolution", TYPE_RESOLUTION)
2939 * A display item used to represent sticky position elements. The contents
2940 * gets its own layer and creates a stacking context, and the layer will have
2941 * position-related metadata set on it.
2943 class nsDisplayStickyPosition : public nsDisplayOwnLayer {
2944 public:
2945 nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
2946 nsDisplayList* aList);
2947 #ifdef NS_BUILD_REFCNT_LOGGING
2948 virtual ~nsDisplayStickyPosition();
2949 #endif
2951 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
2952 LayerManager* aManager,
2953 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
2954 NS_DISPLAY_DECL_NAME("StickyPosition", TYPE_STICKY_POSITION)
2955 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
2956 LayerManager* aManager,
2957 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
2959 return mozilla::LAYER_ACTIVE;
2961 virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
2965 * This potentially creates a layer for the given list of items, whose
2966 * visibility is determined by the displayport for the given frame instead of
2967 * normal visibility computation.
2969 * Here in content, we can use this to render more content than is actually
2970 * visible. Then, the compositing process can manipulate the generated layer
2971 * through transformations so that asynchronous scrolling can be implemented.
2973 * Note that setting the displayport will not change any hit testing! The
2974 * content process will know nothing about what the user is actually seeing,
2975 * so it can only do hit testing for what is supposed to be the visible region.
2977 * It is possible for scroll boxes to have content that can be both above and
2978 * below content outside of the scroll box. We cannot create layers for these
2979 * cases. This is accomplished by wrapping display items with
2980 * nsDisplayScrollLayers. nsDisplayScrollLayers with the same scroll frame will
2981 * be merged together. If more than one nsDisplayScrollLayer exists after
2982 * merging, all nsDisplayScrollLayers will be flattened out so that no new
2983 * layer is created at all.
2985 class nsDisplayScrollLayer : public nsDisplayWrapList
2987 public:
2989 * @param aScrolledFrame This will determine what the displayport is. It should be
2990 * the root content frame of the scrolled area. Note
2991 * that nsDisplayScrollLayer will expect for
2992 * ScrollLayerCount to be defined on aScrolledFrame.
2993 * @param aScrollFrame The viewport frame you see this content through.
2995 nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
2996 nsIFrame* aForFrame, nsIFrame* aScrolledFrame,
2997 nsIFrame* aScrollFrame);
2998 nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
2999 nsIFrame* aForFrame, nsIFrame* aScrolledFrame,
3000 nsIFrame* aScrollFrame);
3001 nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
3002 nsIFrame* aForFrame, nsIFrame* aScrolledFrame,
3003 nsIFrame* aScrollFrame);
3004 NS_DISPLAY_DECL_NAME("ScrollLayer", TYPE_SCROLL_LAYER)
3006 #ifdef NS_BUILD_REFCNT_LOGGING
3007 virtual ~nsDisplayScrollLayer();
3008 #endif
3010 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
3012 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
3013 LayerManager* aManager,
3014 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
3016 virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
3018 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
3019 bool* aSnap) MOZ_OVERRIDE {
3020 *aSnap = false;
3021 return nsRegion();
3024 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
3025 nsRegion* aVisibleRegion) MOZ_OVERRIDE;
3027 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
3028 LayerManager* aManager,
3029 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
3031 virtual bool TryMerge(nsDisplayListBuilder* aBuilder,
3032 nsDisplayItem* aItem) MOZ_OVERRIDE;
3034 virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
3036 // Get the number of nsDisplayScrollLayers for a scroll frame. Note that this
3037 // number does not include nsDisplayScrollInfoLayers. If this number is not 1
3038 // after merging, all the nsDisplayScrollLayers should flatten away.
3039 intptr_t GetScrollLayerCount();
3041 virtual nsIFrame* GetScrollFrame() { return mScrollFrame; }
3042 virtual nsIFrame* GetScrolledFrame() { return mScrolledFrame; }
3044 #ifdef MOZ_DUMP_PAINTING
3045 virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
3046 #endif
3048 bool IsDisplayPortOpaque() { return mDisplayPortContentsOpaque; }
3050 static FrameMetrics ComputeFrameMetrics(nsIFrame* aForFrame,
3051 nsIFrame* aScrollFrame,
3052 const nsIFrame* aReferenceFrame,
3053 Layer* aLayer,
3054 ViewID aScrollParentId,
3055 const nsRect& aViewport,
3056 bool aForceNullScrollId,
3057 bool aIsRoot,
3058 const ContainerLayerParameters& aContainerParameters);
3060 mozilla::UniquePtr<FrameMetrics> ComputeFrameMetrics(Layer* aLayer,
3061 const ContainerLayerParameters& aContainerParameters);
3063 protected:
3064 nsRect GetScrolledContentRectToDraw(nsDisplayListBuilder* aBuilder,
3065 nsRect* aDisplayPort);
3067 nsIFrame* mScrollFrame;
3068 nsIFrame* mScrolledFrame;
3069 ViewID mScrollParentId;
3070 bool mDisplayPortContentsOpaque;
3074 * Like nsDisplayScrollLayer, but only has metadata on the scroll frame. This
3075 * creates a layer that has no Thebes child layer, but still allows the
3076 * compositor process to know of the scroll frame's existence.
3078 * After visibility computation, nsDisplayScrollInfoLayers should only exist if
3079 * nsDisplayScrollLayers were all flattened away.
3081 * Important!! Add info layers to the bottom of the list so they are only
3082 * considered after the others have flattened out!
3084 class nsDisplayScrollInfoLayer : public nsDisplayScrollLayer
3086 public:
3087 nsDisplayScrollInfoLayer(nsDisplayListBuilder* aBuilder,
3088 nsIFrame* aScrolledFrame, nsIFrame* aScrollFrame);
3089 NS_DISPLAY_DECL_NAME("ScrollInfoLayer", TYPE_SCROLL_INFO_LAYER)
3091 virtual ~nsDisplayScrollInfoLayer();
3093 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
3095 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
3096 LayerManager* aManager,
3097 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
3098 virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
3099 { return true; }
3100 virtual bool TryMerge(nsDisplayListBuilder* aBuilder,
3101 nsDisplayItem* aItem) MOZ_OVERRIDE;
3103 virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
3107 * nsDisplayZoom is used for subdocuments that have a different full zoom than
3108 * their parent documents. This item creates a container layer.
3110 class nsDisplayZoom : public nsDisplaySubDocument {
3111 public:
3113 * @param aFrame is the root frame of the subdocument.
3114 * @param aList contains the display items for the subdocument.
3115 * @param aAPD is the app units per dev pixel ratio of the subdocument.
3116 * @param aParentAPD is the app units per dev pixel ratio of the parent
3117 * document.
3118 * @param aFlags GENERATE_SUBDOC_INVALIDATIONS :
3119 * Add UserData to the created ContainerLayer, so that invalidations
3120 * for this layer are send to our nsPresContext.
3122 nsDisplayZoom(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
3123 nsDisplayList* aList,
3124 int32_t aAPD, int32_t aParentAPD,
3125 uint32_t aFlags = 0);
3126 #ifdef NS_BUILD_REFCNT_LOGGING
3127 virtual ~nsDisplayZoom();
3128 #endif
3130 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
3131 virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
3132 virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
3133 HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
3134 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
3135 nsRegion* aVisibleRegion) MOZ_OVERRIDE;
3136 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
3137 LayerManager* aManager,
3138 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
3140 return mozilla::LAYER_ACTIVE;
3142 NS_DISPLAY_DECL_NAME("Zoom", TYPE_ZOOM)
3144 // Get the app units per dev pixel ratio of the child document.
3145 int32_t GetChildAppUnitsPerDevPixel() { return mAPD; }
3146 // Get the app units per dev pixel ratio of the parent document.
3147 int32_t GetParentAppUnitsPerDevPixel() { return mParentAPD; }
3149 private:
3150 int32_t mAPD, mParentAPD;
3154 * A display item to paint a stacking context with effects
3155 * set by the stacking context root frame's style.
3157 class nsDisplaySVGEffects : public nsDisplayWrapList {
3158 public:
3159 nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
3160 nsDisplayList* aList);
3161 #ifdef NS_BUILD_REFCNT_LOGGING
3162 virtual ~nsDisplaySVGEffects();
3163 #endif
3165 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
3166 bool* aSnap) MOZ_OVERRIDE;
3167 virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
3168 HitTestState* aState,
3169 nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
3170 virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
3171 bool* aSnap) MOZ_OVERRIDE {
3172 *aSnap = false;
3173 return mEffectsBounds + ToReferenceFrame();
3175 virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
3176 nsRegion* aVisibleRegion) MOZ_OVERRIDE;
3177 virtual bool TryMerge(nsDisplayListBuilder* aBuilder,
3178 nsDisplayItem* aItem) MOZ_OVERRIDE;
3179 virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE {
3180 return false;
3182 NS_DISPLAY_DECL_NAME("SVGEffects", TYPE_SVG_EFFECTS)
3184 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
3185 LayerManager* aManager,
3186 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
3188 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
3189 LayerManager* aManager,
3190 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
3192 gfxRect BBoxInUserSpace() const;
3193 gfxPoint UserSpaceOffset() const;
3195 virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
3197 return new nsDisplaySVGEffectsGeometry(this, aBuilder);
3199 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
3200 const nsDisplayItemGeometry* aGeometry,
3201 nsRegion* aInvalidRegion) MOZ_OVERRIDE;
3203 void PaintAsLayer(nsDisplayListBuilder* aBuilder,
3204 nsRenderingContext* aCtx,
3205 LayerManager* aManager);
3207 #ifdef MOZ_DUMP_PAINTING
3208 void PrintEffects(nsACString& aTo);
3209 #endif
3211 private:
3212 // relative to mFrame
3213 nsRect mEffectsBounds;
3216 /* A display item that applies a transformation to all of its descendant
3217 * elements. This wrapper should only be used if there is a transform applied
3218 * to the root element.
3220 * The reason that a "bounds" rect is involved in transform calculations is
3221 * because CSS-transforms allow percentage values for the x and y components
3222 * of <translation-value>s, where percentages are percentages of the element's
3223 * border box.
3225 * INVARIANT: The wrapped frame is transformed or we supplied a transform getter
3226 * function.
3227 * INVARIANT: The wrapped frame is non-null.
3229 class nsDisplayTransform: public nsDisplayItem
3231 typedef mozilla::gfx::Matrix4x4 Matrix4x4;
3232 typedef mozilla::gfx::Point3D Point3D;
3233 public:
3235 * Returns a matrix (in pixels) for the current frame. The matrix should be relative to
3236 * the current frame's coordinate space.
3238 * @param aFrame The frame to compute the transform for.
3239 * @param aAppUnitsPerPixel The number of app units per graphics unit.
3241 typedef Matrix4x4 (* ComputeTransformFunction)(nsIFrame* aFrame, float aAppUnitsPerPixel);
3243 /* Constructor accepts a display list, empties it, and wraps it up. It also
3244 * ferries the underlying frame to the nsDisplayItem constructor.
3246 nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
3247 nsDisplayList *aList, const nsRect& aChildrenVisibleRect,
3248 uint32_t aIndex = 0);
3249 nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
3250 nsDisplayItem *aItem, const nsRect& aChildrenVisibleRect,
3251 uint32_t aIndex = 0);
3252 nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
3253 nsDisplayList *aList, const nsRect& aChildrenVisibleRect,
3254 ComputeTransformFunction aTransformGetter, uint32_t aIndex = 0);
3256 #ifdef NS_BUILD_REFCNT_LOGGING
3257 virtual ~nsDisplayTransform()
3259 MOZ_COUNT_DTOR(nsDisplayTransform);
3261 #endif
3263 NS_DISPLAY_DECL_NAME("nsDisplayTransform", TYPE_TRANSFORM)
3265 virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
3267 if (mStoredList.GetComponentAlphaBounds(aBuilder).IsEmpty())
3268 return nsRect();
3269 bool snap;
3270 return GetBounds(aBuilder, &snap);
3273 virtual nsDisplayList* GetChildren() MOZ_OVERRIDE { return mStoredList.GetChildren(); }
3275 virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect,
3276 HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
3277 virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap) MOZ_OVERRIDE;
3278 virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
3279 bool* aSnap) MOZ_OVERRIDE;
3280 virtual bool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor) MOZ_OVERRIDE;
3281 virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
3282 LayerManager* aManager,
3283 const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
3284 virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
3285 LayerManager* aManager,
3286 const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
3287 virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
3288 virtual bool ComputeVisibility(nsDisplayListBuilder *aBuilder,
3289 nsRegion *aVisibleRegion) MOZ_OVERRIDE;
3290 virtual bool TryMerge(nsDisplayListBuilder *aBuilder, nsDisplayItem *aItem) MOZ_OVERRIDE;
3292 virtual uint32_t GetPerFrameKey() MOZ_OVERRIDE { return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); }
3294 virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
3295 const nsDisplayItemGeometry* aGeometry,
3296 nsRegion* aInvalidRegion) MOZ_OVERRIDE
3298 // We don't need to compute an invalidation region since we have LayerTreeInvalidation
3301 virtual const nsIFrame* ReferenceFrameForChildren() const MOZ_OVERRIDE {
3302 // If we were created using a transform-getter, then we don't
3303 // belong to a transformed frame, and aren't a reference frame
3304 // for our children.
3305 if (!mTransformGetter) {
3306 return mFrame;
3308 return nsDisplayItem::ReferenceFrameForChildren();
3311 virtual const nsRect& GetVisibleRectForChildren() const MOZ_OVERRIDE
3313 return mChildrenVisibleRect;
3316 enum {
3317 INDEX_MAX = UINT32_MAX >> nsDisplayItem::TYPE_BITS
3320 const Matrix4x4& GetTransform();
3322 float GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsPoint& aPoint);
3325 * TransformRect takes in as parameters a rectangle (in aFrame's coordinate
3326 * space) and returns the smallest rectangle (in aFrame's coordinate space)
3327 * containing the transformed image of that rectangle. That is, it takes
3328 * the four corners of the rectangle, transforms them according to the
3329 * matrix associated with the specified frame, then returns the smallest
3330 * rectangle containing the four transformed points.
3332 * @param untransformedBounds The rectangle (in app units) to transform.
3333 * @param aFrame The frame whose transformation should be applied. This
3334 * function raises an assertion if aFrame is null or doesn't have a
3335 * transform applied to it.
3336 * @param aOrigin The origin of the transform relative to aFrame's local
3337 * coordinate space.
3338 * @param aBoundsOverride (optional) Rather than using the frame's computed
3339 * bounding rect as frame bounds, use this rectangle instead. Pass
3340 * nullptr (or nothing at all) to use the default.
3342 static nsRect TransformRect(const nsRect &aUntransformedBounds,
3343 const nsIFrame* aFrame,
3344 const nsPoint &aOrigin,
3345 const nsRect* aBoundsOverride = nullptr);
3347 static nsRect TransformRectOut(const nsRect &aUntransformedBounds,
3348 const nsIFrame* aFrame,
3349 const nsPoint &aOrigin,
3350 const nsRect* aBoundsOverride = nullptr);
3352 /* UntransformRect is like TransformRect, except that it inverts the
3353 * transform.
3355 static bool UntransformRect(const nsRect &aTransformedBounds,
3356 const nsRect &aChildBounds,
3357 const nsIFrame* aFrame,
3358 const nsPoint &aOrigin,
3359 nsRect *aOutRect);
3361 bool UntransformVisibleRect(nsDisplayListBuilder* aBuilder,
3362 nsRect* aOutRect);
3364 static Point3D GetDeltaToTransformOrigin(const nsIFrame* aFrame,
3365 float aAppUnitsPerPixel,
3366 const nsRect* aBoundsOverride);
3368 static Point3D GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame,
3369 float aAppUnitsPerPixel);
3372 * Returns the bounds of a frame as defined for resolving percentage
3373 * <translation-value>s in CSS transforms. If
3374 * UNIFIED_CONTINUATIONS is not defined, this is simply the frame's bounding
3375 * rectangle, translated to the origin. Otherwise, returns the smallest
3376 * rectangle containing a frame and all of its continuations. For example,
3377 * if there is a <span> element with several continuations split over
3378 * several lines, this function will return the rectangle containing all of
3379 * those continuations. This rectangle is relative to the origin of the
3380 * frame's local coordinate space.
3382 * @param aFrame The frame to get the bounding rect for.
3383 * @return The frame's bounding rect, as described above.
3385 static nsRect GetFrameBoundsForTransform(const nsIFrame* aFrame);
3387 struct FrameTransformProperties
3389 FrameTransformProperties(const nsIFrame* aFrame,
3390 float aAppUnitsPerPixel,
3391 const nsRect* aBoundsOverride);
3392 FrameTransformProperties(nsCSSValueSharedList* aTransformList,
3393 const Point3D& aToTransformOrigin,
3394 const Point3D& aToPerspectiveOrigin,
3395 nscoord aChildPerspective)
3396 : mFrame(nullptr)
3397 , mTransformList(aTransformList)
3398 , mToTransformOrigin(aToTransformOrigin)
3399 , mToPerspectiveOrigin(aToPerspectiveOrigin)
3400 , mChildPerspective(aChildPerspective)
3403 const nsIFrame* mFrame;
3404 nsRefPtr<nsCSSValueSharedList> mTransformList;
3405 const Point3D mToTransformOrigin;
3406 const Point3D mToPerspectiveOrigin;
3407 nscoord mChildPerspective;
3411 * Given a frame with the -moz-transform property or an SVG transform,
3412 * returns the transformation matrix for that frame.
3414 * @param aFrame The frame to get the matrix from.
3415 * @param aOrigin Relative to which point this transform should be applied.
3416 * @param aAppUnitsPerPixel The number of app units per graphics unit.
3417 * @param aBoundsOverride [optional] If this is nullptr (the default), the
3418 * computation will use the value of GetFrameBoundsForTransform(aFrame)
3419 * for the frame's bounding rectangle. Otherwise, it will use the
3420 * value of aBoundsOverride. This is mostly for internal use and in
3421 * most cases you will not need to specify a value.
3422 * @param aOffsetByOrigin If true, the resulting matrix will be translated
3423 * by aOrigin. This translation is applied *before* the CSS transform.
3425 static gfx3DMatrix GetResultingTransformMatrix(const nsIFrame* aFrame,
3426 const nsPoint& aOrigin,
3427 float aAppUnitsPerPixel,
3428 const nsRect* aBoundsOverride = nullptr,
3429 nsIFrame** aOutAncestor = nullptr,
3430 bool aOffsetByOrigin = false);
3431 static gfx3DMatrix GetResultingTransformMatrix(const FrameTransformProperties& aProperties,
3432 const nsPoint& aOrigin,
3433 float aAppUnitsPerPixel,
3434 const nsRect* aBoundsOverride = nullptr,
3435 nsIFrame** aOutAncestor = nullptr);
3437 * Return true when we should try to prerender the entire contents of the
3438 * transformed frame even when it's not completely visible (yet).
3440 static bool ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
3441 nsIFrame* aFrame,
3442 bool aLogAnimations = false);
3443 bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
3445 bool ShouldPrerender() const { return mPrerender; }
3447 #ifdef MOZ_DUMP_PAINTING
3448 virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE;
3449 #endif
3451 private:
3452 void SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder);
3453 void Init(nsDisplayListBuilder* aBuilder);
3455 static gfx3DMatrix GetResultingTransformMatrixInternal(const FrameTransformProperties& aProperties,
3456 const nsPoint& aOrigin,
3457 float aAppUnitsPerPixel,
3458 const nsRect* aBoundsOverride,
3459 nsIFrame** aOutAncestor,
3460 bool aOffsetByOrigin);
3462 nsDisplayWrapList mStoredList;
3463 Matrix4x4 mTransform;
3464 ComputeTransformFunction mTransformGetter;
3465 nsRect mChildrenVisibleRect;
3466 uint32_t mIndex;
3467 bool mPrerender;
3471 * This class adds basic support for limiting the rendering to the part inside
3472 * the specified edges. It's a base class for the display item classes that
3473 * does the actual work. The two members, mLeftEdge and mRightEdge, are
3474 * relative to the edges of the frame's scrollable overflow rectangle and is
3475 * the amount to suppress on each side.
3477 * Setting none, both or only one edge is allowed.
3478 * The values must be non-negative.
3479 * The default value for both edges is zero, which means everything is painted.
3481 class nsCharClipDisplayItem : public nsDisplayItem {
3482 public:
3483 nsCharClipDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
3484 : nsDisplayItem(aBuilder, aFrame), mLeftEdge(0), mRightEdge(0) {}
3486 explicit nsCharClipDisplayItem(nsIFrame* aFrame)
3487 : nsDisplayItem(aFrame) {}
3489 struct ClipEdges {
3490 ClipEdges(const nsDisplayItem& aItem,
3491 nscoord aLeftEdge, nscoord aRightEdge) {
3492 nsRect r = aItem.Frame()->GetScrollableOverflowRect() +
3493 aItem.ToReferenceFrame();
3494 mX = aLeftEdge > 0 ? r.x + aLeftEdge : nscoord_MIN;
3495 mXMost = aRightEdge > 0 ? std::max(r.XMost() - aRightEdge, mX) : nscoord_MAX;
3497 void Intersect(nscoord* aX, nscoord* aWidth) const {
3498 nscoord xmost1 = *aX + *aWidth;
3499 *aX = std::max(*aX, mX);
3500 *aWidth = std::max(std::min(xmost1, mXMost) - *aX, 0);
3502 nscoord mX;
3503 nscoord mXMost;
3506 ClipEdges Edges() const { return ClipEdges(*this, mLeftEdge, mRightEdge); }
3508 static nsCharClipDisplayItem* CheckCast(nsDisplayItem* aItem) {
3509 nsDisplayItem::Type t = aItem->GetType();
3510 return (t == nsDisplayItem::TYPE_TEXT ||
3511 t == nsDisplayItem::TYPE_TEXT_DECORATION ||
3512 t == nsDisplayItem::TYPE_TEXT_SHADOW)
3513 ? static_cast<nsCharClipDisplayItem*>(aItem) : nullptr;
3516 nscoord mLeftEdge; // length from the left side
3517 nscoord mRightEdge; // length from the right side
3520 #endif /*NSDISPLAYLIST_H_*/