1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/base/nsDisplayList.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,3413 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * vim: set ts=2 sw=2 et tw=78: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.9 + */ 1.10 + 1.11 +/* 1.12 + * structures that represent things to be painted (ordered in z-order), 1.13 + * used during painting and hit testing 1.14 + */ 1.15 + 1.16 +#ifndef NSDISPLAYLIST_H_ 1.17 +#define NSDISPLAYLIST_H_ 1.18 + 1.19 +#include "mozilla/Attributes.h" 1.20 +#include "nsCOMPtr.h" 1.21 +#include "nsIFrame.h" 1.22 +#include "nsPoint.h" 1.23 +#include "nsRect.h" 1.24 +#include "nsCaret.h" 1.25 +#include "plarena.h" 1.26 +#include "nsRegion.h" 1.27 +#include "FrameLayerBuilder.h" 1.28 +#include "nsLayoutUtils.h" 1.29 +#include "nsDisplayListInvalidation.h" 1.30 +#include "DisplayListClipState.h" 1.31 + 1.32 +#include <stdint.h> 1.33 + 1.34 +#include <stdlib.h> 1.35 +#include <algorithm> 1.36 + 1.37 +class nsIContent; 1.38 +class nsRenderingContext; 1.39 +class nsDisplayTableItem; 1.40 +class nsISelection; 1.41 +class nsDisplayLayerEventRegions; 1.42 + 1.43 +namespace mozilla { 1.44 +namespace layers { 1.45 +class Layer; 1.46 +class ImageLayer; 1.47 +class ImageContainer; 1.48 +} //namepsace 1.49 +} //namepsace 1.50 + 1.51 +/* 1.52 + * An nsIFrame can have many different visual parts. For example an image frame 1.53 + * can have a background, border, and outline, the image itself, and a 1.54 + * translucent selection overlay. In general these parts can be drawn at 1.55 + * discontiguous z-levels; see CSS2.1 appendix E: 1.56 + * http://www.w3.org/TR/CSS21/zindex.html 1.57 + * 1.58 + * We construct a display list for a frame tree that contains one item 1.59 + * for each visual part. The display list is itself a tree since some items 1.60 + * are containers for other items; however, its structure does not match 1.61 + * the structure of its source frame tree. The display list items are sorted 1.62 + * by z-order. A display list can be used to paint the frames, to determine 1.63 + * which frame is the target of a mouse event, and to determine what areas 1.64 + * need to be repainted when scrolling. The display lists built for each task 1.65 + * may be different for efficiency; in particular some frames need special 1.66 + * display list items only for event handling, and do not create these items 1.67 + * when the display list will be used for painting (the common case). For 1.68 + * example, when painting we avoid creating nsDisplayBackground items for 1.69 + * frames that don't display a visible background, but for event handling 1.70 + * we need those backgrounds because they are not transparent to events. 1.71 + * 1.72 + * We could avoid constructing an explicit display list by traversing the 1.73 + * frame tree multiple times in clever ways. However, reifying the display list 1.74 + * reduces code complexity and reduces the number of times each frame must be 1.75 + * traversed to one, which seems to be good for performance. It also means 1.76 + * we can share code for painting, event handling and scroll analysis. 1.77 + * 1.78 + * Display lists are short-lived; content and frame trees cannot change 1.79 + * between a display list being created and destroyed. Display lists should 1.80 + * not be created during reflow because the frame tree may be in an 1.81 + * inconsistent state (e.g., a frame's stored overflow-area may not include 1.82 + * the bounds of all its children). However, it should be fine to create 1.83 + * a display list while a reflow is pending, before it starts. 1.84 + * 1.85 + * A display list covers the "extended" frame tree; the display list for a frame 1.86 + * tree containing FRAME/IFRAME elements can include frames from the subdocuments. 1.87 + * 1.88 + * Display item's coordinates are relative to their nearest reference frame ancestor. 1.89 + * Both the display root and any frame with a transform act as a reference frame 1.90 + * for their frame subtrees. 1.91 + */ 1.92 + 1.93 +// All types are defined in nsDisplayItemTypes.h 1.94 +#ifdef MOZ_DUMP_PAINTING 1.95 +#define NS_DISPLAY_DECL_NAME(n, e) \ 1.96 + virtual const char* Name() { return n; } \ 1.97 + virtual Type GetType() { return e; } 1.98 +#else 1.99 +#define NS_DISPLAY_DECL_NAME(n, e) \ 1.100 + virtual Type GetType() { return e; } 1.101 +#endif 1.102 + 1.103 +/** 1.104 + * This manages a display list and is passed as a parameter to 1.105 + * nsIFrame::BuildDisplayList. 1.106 + * It contains the parameters that don't change from frame to frame and manages 1.107 + * the display list memory using a PLArena. It also establishes the reference 1.108 + * coordinate system for all display list items. Some of the parameters are 1.109 + * available from the prescontext/presshell, but we copy them into the builder 1.110 + * for faster/more convenient access. 1.111 + */ 1.112 +class nsDisplayListBuilder { 1.113 +public: 1.114 + typedef mozilla::FramePropertyDescriptor FramePropertyDescriptor; 1.115 + typedef mozilla::FrameLayerBuilder FrameLayerBuilder; 1.116 + typedef mozilla::DisplayItemClip DisplayItemClip; 1.117 + typedef mozilla::DisplayListClipState DisplayListClipState; 1.118 + typedef nsIWidget::ThemeGeometry ThemeGeometry; 1.119 + typedef mozilla::layers::Layer Layer; 1.120 + typedef mozilla::layers::FrameMetrics::ViewID ViewID; 1.121 + 1.122 + /** 1.123 + * @param aReferenceFrame the frame at the root of the subtree; its origin 1.124 + * is the origin of the reference coordinate system for this display list 1.125 + * @param aIsForEvents true if we're creating this list in order to 1.126 + * determine which frame is under the mouse position 1.127 + * @param aBuildCaret whether or not we should include the caret in any 1.128 + * display lists that we make. 1.129 + */ 1.130 + enum Mode { 1.131 + PAINTING, 1.132 + EVENT_DELIVERY, 1.133 + PLUGIN_GEOMETRY, 1.134 + IMAGE_VISIBILITY, 1.135 + OTHER 1.136 + }; 1.137 + nsDisplayListBuilder(nsIFrame* aReferenceFrame, Mode aMode, bool aBuildCaret); 1.138 + ~nsDisplayListBuilder(); 1.139 + 1.140 + void SetWillComputePluginGeometry(bool aWillComputePluginGeometry) 1.141 + { 1.142 + mWillComputePluginGeometry = aWillComputePluginGeometry; 1.143 + } 1.144 + void SetForPluginGeometry() 1.145 + { 1.146 + NS_ASSERTION(mMode == PAINTING, "Can only switch from PAINTING to PLUGIN_GEOMETRY"); 1.147 + NS_ASSERTION(mWillComputePluginGeometry, "Should have signalled this in advance"); 1.148 + mMode = PLUGIN_GEOMETRY; 1.149 + } 1.150 + 1.151 + /** 1.152 + * @return true if the display is being built in order to determine which 1.153 + * frame is under the mouse position. 1.154 + */ 1.155 + bool IsForEventDelivery() { return mMode == EVENT_DELIVERY; } 1.156 + /** 1.157 + * Be careful with this. The display list will be built in PAINTING mode 1.158 + * first and then switched to PLUGIN_GEOMETRY before a second call to 1.159 + * ComputeVisibility. 1.160 + * @return true if the display list is being built to compute geometry 1.161 + * for plugins. 1.162 + */ 1.163 + bool IsForPluginGeometry() { return mMode == PLUGIN_GEOMETRY; } 1.164 + /** 1.165 + * @return true if the display list is being built for painting. 1.166 + */ 1.167 + bool IsForPainting() { return mMode == PAINTING; } 1.168 + /** 1.169 + * @return true if the display list is being built for determining image 1.170 + * visibility. 1.171 + */ 1.172 + bool IsForImageVisibility() { return mMode == IMAGE_VISIBILITY; } 1.173 + bool WillComputePluginGeometry() { return mWillComputePluginGeometry; } 1.174 + /** 1.175 + * @return true if "painting is suppressed" during page load and we 1.176 + * should paint only the background of the document. 1.177 + */ 1.178 + bool IsBackgroundOnly() { 1.179 + NS_ASSERTION(mPresShellStates.Length() > 0, 1.180 + "don't call this if we're not in a presshell"); 1.181 + return CurrentPresShellState()->mIsBackgroundOnly; 1.182 + } 1.183 + /** 1.184 + * @return true if the currently active BuildDisplayList call is being 1.185 + * applied to a frame at the root of a pseudo stacking context. A pseudo 1.186 + * stacking context is either a real stacking context or basically what 1.187 + * CSS2.1 appendix E refers to with "treat the element as if it created 1.188 + * a new stacking context 1.189 + */ 1.190 + bool IsAtRootOfPseudoStackingContext() { return mIsAtRootOfPseudoStackingContext; } 1.191 + 1.192 + /** 1.193 + * @return the selection that painting should be restricted to (or nullptr 1.194 + * in the normal unrestricted case) 1.195 + */ 1.196 + nsISelection* GetBoundingSelection() { return mBoundingSelection; } 1.197 + 1.198 + /** 1.199 + * @return the root of given frame's (sub)tree, whose origin 1.200 + * establishes the coordinate system for the child display items. 1.201 + */ 1.202 + const nsIFrame* FindReferenceFrameFor(const nsIFrame *aFrame) 1.203 + { 1.204 + if (aFrame == mCachedOffsetFrame) { 1.205 + return mCachedReferenceFrame; 1.206 + } 1.207 + for (const nsIFrame* f = aFrame; f; f = nsLayoutUtils::GetCrossDocParentFrame(f)) 1.208 + { 1.209 + if (f == mReferenceFrame || f->IsTransformed()) { 1.210 + mCachedOffsetFrame = aFrame; 1.211 + mCachedReferenceFrame = f; 1.212 + mCachedOffset = aFrame->GetOffsetToCrossDoc(f); 1.213 + return f; 1.214 + } 1.215 + } 1.216 + mCachedOffsetFrame = aFrame; 1.217 + mCachedReferenceFrame = mReferenceFrame; 1.218 + mCachedOffset = aFrame->GetOffsetToCrossDoc(mReferenceFrame); 1.219 + return mReferenceFrame; 1.220 + } 1.221 + 1.222 + /** 1.223 + * @return the root of the display list's frame (sub)tree, whose origin 1.224 + * establishes the coordinate system for the display list 1.225 + */ 1.226 + nsIFrame* RootReferenceFrame() 1.227 + { 1.228 + return mReferenceFrame; 1.229 + } 1.230 + 1.231 + /** 1.232 + * @return a point pt such that adding pt to a coordinate relative to aFrame 1.233 + * makes it relative to ReferenceFrame(), i.e., returns 1.234 + * aFrame->GetOffsetToCrossDoc(ReferenceFrame()). The returned point is in 1.235 + * the appunits of aFrame. It may be optimized to be faster than 1.236 + * aFrame->GetOffsetToCrossDoc(ReferenceFrame()) (but currently isn't). 1.237 + */ 1.238 + const nsPoint& ToReferenceFrame(const nsIFrame* aFrame) { 1.239 + if (aFrame != mCachedOffsetFrame) { 1.240 + FindReferenceFrameFor(aFrame); 1.241 + } 1.242 + return mCachedOffset; 1.243 + } 1.244 + /** 1.245 + * When building the display list, the scrollframe aFrame will be "ignored" 1.246 + * for the purposes of clipping, and its scrollbars will be hidden. We use 1.247 + * this to allow RenderOffscreen to render a whole document without beign 1.248 + * clipped by the viewport or drawing the viewport scrollbars. 1.249 + */ 1.250 + void SetIgnoreScrollFrame(nsIFrame* aFrame) { mIgnoreScrollFrame = aFrame; } 1.251 + /** 1.252 + * Get the scrollframe to ignore, if any. 1.253 + */ 1.254 + nsIFrame* GetIgnoreScrollFrame() { return mIgnoreScrollFrame; } 1.255 + /** 1.256 + * Get the ViewID of the nearest scrolling ancestor frame. 1.257 + */ 1.258 + ViewID GetCurrentScrollParentId() const { return mCurrentScrollParentId; } 1.259 + /** 1.260 + * Calling this setter makes us include all out-of-flow descendant 1.261 + * frames in the display list, wherever they may be positioned (even 1.262 + * outside the dirty rects). 1.263 + */ 1.264 + void SetIncludeAllOutOfFlows() { mIncludeAllOutOfFlows = true; } 1.265 + bool GetIncludeAllOutOfFlows() const { return mIncludeAllOutOfFlows; } 1.266 + /** 1.267 + * Calling this setter makes us exclude all leaf frames that aren't 1.268 + * selected. 1.269 + */ 1.270 + void SetSelectedFramesOnly() { mSelectedFramesOnly = true; } 1.271 + bool GetSelectedFramesOnly() { return mSelectedFramesOnly; } 1.272 + /** 1.273 + * Calling this setter makes us compute accurate visible regions at the cost 1.274 + * of performance if regions get very complex. 1.275 + */ 1.276 + void SetAccurateVisibleRegions() { mAccurateVisibleRegions = true; } 1.277 + bool GetAccurateVisibleRegions() { return mAccurateVisibleRegions; } 1.278 + /** 1.279 + * Allows callers to selectively override the regular paint suppression checks, 1.280 + * so that methods like GetFrameForPoint work when painting is suppressed. 1.281 + */ 1.282 + void IgnorePaintSuppression() { mIgnoreSuppression = true; } 1.283 + /** 1.284 + * @return Returns if this builder will ignore paint suppression. 1.285 + */ 1.286 + bool IsIgnoringPaintSuppression() { return mIgnoreSuppression; } 1.287 + /** 1.288 + * @return Returns if this builder had to ignore painting suppression on some 1.289 + * document when building the display list. 1.290 + */ 1.291 + bool GetHadToIgnorePaintSuppression() { return mHadToIgnoreSuppression; } 1.292 + /** 1.293 + * Call this if we're doing normal painting to the window. 1.294 + */ 1.295 + void SetPaintingToWindow(bool aToWindow) { mIsPaintingToWindow = aToWindow; } 1.296 + bool IsPaintingToWindow() const { return mIsPaintingToWindow; } 1.297 + /** 1.298 + * Call this to prevent descending into subdocuments. 1.299 + */ 1.300 + void SetDescendIntoSubdocuments(bool aDescend) { mDescendIntoSubdocuments = aDescend; } 1.301 + bool GetDescendIntoSubdocuments() { return mDescendIntoSubdocuments; } 1.302 + 1.303 + /** 1.304 + * Returns true if merging and flattening of display lists should be 1.305 + * performed while computing visibility. 1.306 + */ 1.307 + bool AllowMergingAndFlattening() { return mAllowMergingAndFlattening; } 1.308 + void SetAllowMergingAndFlattening(bool aAllow) { mAllowMergingAndFlattening = aAllow; } 1.309 + 1.310 + nsDisplayLayerEventRegions* GetLayerEventRegions() { return mLayerEventRegions; } 1.311 + void SetLayerEventRegions(nsDisplayLayerEventRegions* aItem) 1.312 + { 1.313 + mLayerEventRegions = aItem; 1.314 + } 1.315 + bool IsBuildingLayerEventRegions() 1.316 + { 1.317 + // Disable for now. 1.318 + return false; 1.319 + // return mMode == PAINTING; 1.320 + } 1.321 + 1.322 + bool GetAncestorHasTouchEventHandler() { return mAncestorHasTouchEventHandler; } 1.323 + void SetAncestorHasTouchEventHandler(bool aValue) 1.324 + { 1.325 + mAncestorHasTouchEventHandler = aValue; 1.326 + } 1.327 + 1.328 + bool HaveScrollableDisplayPort() const { return mHaveScrollableDisplayPort; } 1.329 + void SetHaveScrollableDisplayPort() { mHaveScrollableDisplayPort = true; } 1.330 + 1.331 + bool SetIsCompositingCheap(bool aCompositingCheap) { 1.332 + bool temp = mIsCompositingCheap; 1.333 + mIsCompositingCheap = aCompositingCheap; 1.334 + return temp; 1.335 + } 1.336 + bool IsCompositingCheap() const { return mIsCompositingCheap; } 1.337 + /** 1.338 + * Display the caret if needed. 1.339 + */ 1.340 + void DisplayCaret(nsIFrame* aFrame, const nsRect& aDirtyRect, 1.341 + nsDisplayList* aList) { 1.342 + nsIFrame* frame = GetCaretFrame(); 1.343 + if (aFrame == frame) { 1.344 + frame->DisplayCaret(this, aDirtyRect, aList); 1.345 + } 1.346 + } 1.347 + /** 1.348 + * Get the frame that the caret is supposed to draw in. 1.349 + * If the caret is currently invisible, this will be null. 1.350 + */ 1.351 + nsIFrame* GetCaretFrame() { 1.352 + return CurrentPresShellState()->mCaretFrame; 1.353 + } 1.354 + /** 1.355 + * Get the caret associated with the current presshell. 1.356 + */ 1.357 + nsCaret* GetCaret(); 1.358 + /** 1.359 + * Notify the display list builder that we're entering a presshell. 1.360 + * aReferenceFrame should be a frame in the new presshell and aDirtyRect 1.361 + * should be the current dirty rect in aReferenceFrame's coordinate space. 1.362 + */ 1.363 + void EnterPresShell(nsIFrame* aReferenceFrame, const nsRect& aDirtyRect); 1.364 + /** 1.365 + * For print-preview documents, we sometimes need to build display items for 1.366 + * the same frames multiple times in the same presentation, with different 1.367 + * clipping. Between each such batch of items, call 1.368 + * ResetMarkedFramesForDisplayList to make sure that the results of 1.369 + * MarkFramesForDisplayList do not carry over between batches. 1.370 + */ 1.371 + void ResetMarkedFramesForDisplayList(); 1.372 + /** 1.373 + * Notify the display list builder that we're leaving a presshell. 1.374 + */ 1.375 + void LeavePresShell(nsIFrame* aReferenceFrame, const nsRect& aDirtyRect); 1.376 + 1.377 + /** 1.378 + * Returns true if we're currently building a display list that's 1.379 + * directly or indirectly under an nsDisplayTransform. 1.380 + */ 1.381 + bool IsInTransform() const { return mInTransform; } 1.382 + /** 1.383 + * Indicate whether or not we're directly or indirectly under and 1.384 + * nsDisplayTransform or SVG foreignObject. 1.385 + */ 1.386 + void SetInTransform(bool aInTransform) { mInTransform = aInTransform; } 1.387 + 1.388 + /** 1.389 + * Returns true if we're currently building display items that are in 1.390 + * true fixed position subtree. 1.391 + */ 1.392 + bool IsInFixedPos() const { return mInFixedPos; } 1.393 + 1.394 + /** 1.395 + * @return true if images have been set to decode synchronously. 1.396 + */ 1.397 + bool ShouldSyncDecodeImages() { return mSyncDecodeImages; } 1.398 + 1.399 + /** 1.400 + * Indicates whether we should synchronously decode images. If true, we decode 1.401 + * and draw whatever image data has been loaded. If false, we just draw 1.402 + * whatever has already been decoded. 1.403 + */ 1.404 + void SetSyncDecodeImages(bool aSyncDecodeImages) { 1.405 + mSyncDecodeImages = aSyncDecodeImages; 1.406 + } 1.407 + 1.408 + /** 1.409 + * Helper method to generate background painting flags based on the 1.410 + * information available in the display list builder. Currently only 1.411 + * accounts for mSyncDecodeImages. 1.412 + */ 1.413 + uint32_t GetBackgroundPaintFlags(); 1.414 + 1.415 + /** 1.416 + * Subtracts aRegion from *aVisibleRegion. We avoid letting 1.417 + * aVisibleRegion become overcomplex by simplifying it if necessary --- 1.418 + * unless mAccurateVisibleRegions is set, in which case we let it 1.419 + * get arbitrarily complex. 1.420 + */ 1.421 + void SubtractFromVisibleRegion(nsRegion* aVisibleRegion, 1.422 + const nsRegion& aRegion); 1.423 + 1.424 + /** 1.425 + * Mark the frames in aFrames to be displayed if they intersect aDirtyRect 1.426 + * (which is relative to aDirtyFrame). If the frames have placeholders 1.427 + * that might not be displayed, we mark the placeholders and their ancestors 1.428 + * to ensure that display list construction descends into them 1.429 + * anyway. nsDisplayListBuilder will take care of unmarking them when it is 1.430 + * destroyed. 1.431 + */ 1.432 + void MarkFramesForDisplayList(nsIFrame* aDirtyFrame, 1.433 + const nsFrameList& aFrames, 1.434 + const nsRect& aDirtyRect); 1.435 + /** 1.436 + * Mark all child frames that Preserve3D() as needing display. 1.437 + * Because these frames include transforms set on their parent, dirty rects 1.438 + * for intermediate frames may be empty, yet child frames could still be visible. 1.439 + */ 1.440 + void MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect); 1.441 + 1.442 + /** 1.443 + * Get the area of the final transparent region. 1.444 + */ 1.445 + const nsRegion* GetFinalTransparentRegion() { return mFinalTransparentRegion; } 1.446 + /** 1.447 + * Record the area of the final transparent region after all visibility 1.448 + * calculations were performed. 1.449 + */ 1.450 + void SetFinalTransparentRegion(const nsRegion& aFinalTransparentRegion) 1.451 + { 1.452 + mFinalTransparentRegion = &aFinalTransparentRegion; 1.453 + } 1.454 + 1.455 + const nsTArray<ThemeGeometry>& GetThemeGeometries() { return mThemeGeometries; } 1.456 + 1.457 + /** 1.458 + * Returns true if we need to descend into this frame when building 1.459 + * the display list, even though it doesn't intersect the dirty 1.460 + * rect, because it may have out-of-flows that do so. 1.461 + */ 1.462 + bool ShouldDescendIntoFrame(nsIFrame* aFrame) const { 1.463 + return 1.464 + (aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) || 1.465 + GetIncludeAllOutOfFlows(); 1.466 + } 1.467 + 1.468 + /** 1.469 + * Notifies the builder that a particular themed widget exists 1.470 + * at the given rectangle within the currently built display list. 1.471 + * For certain appearance values (currently only 1.472 + * NS_THEME_MOZ_MAC_UNIFIED_TOOLBAR, NS_THEME_TOOLBAR and 1.473 + * NS_THEME_WINDOW_TITLEBAR) this gets called during every display list 1.474 + * construction, for every themed widget of the right type within the 1.475 + * display list, except for themed widgets which are transformed or have 1.476 + * effects applied to them (e.g. CSS opacity or filters). 1.477 + * 1.478 + * @param aWidgetType the -moz-appearance value for the themed widget 1.479 + * @param aRect the device-pixel rect relative to the widget's displayRoot 1.480 + * for the themed widget 1.481 + */ 1.482 + void RegisterThemeGeometry(uint8_t aWidgetType, 1.483 + const nsIntRect& aRect) { 1.484 + if (mIsPaintingToWindow && mPresShellStates.Length() == 1) { 1.485 + ThemeGeometry geometry(aWidgetType, aRect); 1.486 + mThemeGeometries.AppendElement(geometry); 1.487 + } 1.488 + } 1.489 + 1.490 + /** 1.491 + * Allocate memory in our arena. It will only be freed when this display list 1.492 + * builder is destroyed. This memory holds nsDisplayItems. nsDisplayItem 1.493 + * destructors are called as soon as the item is no longer used. 1.494 + */ 1.495 + void* Allocate(size_t aSize); 1.496 + 1.497 + /** 1.498 + * Allocate a new DisplayListClip in the arena. Will be cleaned up 1.499 + * automatically when the arena goes away. 1.500 + */ 1.501 + const DisplayItemClip* AllocateDisplayItemClip(const DisplayItemClip& aOriginal); 1.502 + 1.503 + /** 1.504 + * Transfer off main thread animations to the layer. May be called 1.505 + * with aBuilder and aItem both null, but only if the caller has 1.506 + * already checked that off main thread animations should be sent to 1.507 + * the layer. When they are both null, the animations are added to 1.508 + * the layer as pending animations. 1.509 + */ 1.510 + static void AddAnimationsAndTransitionsToLayer(Layer* aLayer, 1.511 + nsDisplayListBuilder* aBuilder, 1.512 + nsDisplayItem* aItem, 1.513 + nsIFrame* aFrame, 1.514 + nsCSSProperty aProperty); 1.515 + /** 1.516 + * A helper class to temporarily set the value of 1.517 + * mIsAtRootOfPseudoStackingContext, and temporarily 1.518 + * update mCachedOffsetFrame/mCachedOffset from a frame to its child. 1.519 + * Also saves and restores mClipState. 1.520 + */ 1.521 + class AutoBuildingDisplayList; 1.522 + friend class AutoBuildingDisplayList; 1.523 + class AutoBuildingDisplayList { 1.524 + public: 1.525 + AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, bool aIsRoot) 1.526 + : mBuilder(aBuilder), 1.527 + mPrevCachedOffsetFrame(aBuilder->mCachedOffsetFrame), 1.528 + mPrevCachedReferenceFrame(aBuilder->mCachedReferenceFrame), 1.529 + mPrevLayerEventRegions(aBuilder->mLayerEventRegions), 1.530 + mPrevCachedOffset(aBuilder->mCachedOffset), 1.531 + mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext), 1.532 + mPrevAncestorHasTouchEventHandler(aBuilder->mAncestorHasTouchEventHandler) 1.533 + { 1.534 + aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot; 1.535 + } 1.536 + AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, 1.537 + nsIFrame* aForChild, bool aIsRoot) 1.538 + : mBuilder(aBuilder), 1.539 + mPrevCachedOffsetFrame(aBuilder->mCachedOffsetFrame), 1.540 + mPrevCachedReferenceFrame(aBuilder->mCachedReferenceFrame), 1.541 + mPrevLayerEventRegions(aBuilder->mLayerEventRegions), 1.542 + mPrevCachedOffset(aBuilder->mCachedOffset), 1.543 + mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext), 1.544 + mPrevAncestorHasTouchEventHandler(aBuilder->mAncestorHasTouchEventHandler) 1.545 + { 1.546 + if (aForChild->IsTransformed()) { 1.547 + aBuilder->mCachedOffset = nsPoint(); 1.548 + aBuilder->mCachedReferenceFrame = aForChild; 1.549 + } else if (mPrevCachedOffsetFrame == aForChild->GetParent()) { 1.550 + aBuilder->mCachedOffset += aForChild->GetPosition(); 1.551 + } else { 1.552 + aBuilder->mCachedOffset = aBuilder->ToReferenceFrame(aForChild); 1.553 + } 1.554 + aBuilder->mCachedOffsetFrame = aForChild; 1.555 + aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot; 1.556 + } 1.557 + ~AutoBuildingDisplayList() { 1.558 + mBuilder->mCachedOffsetFrame = mPrevCachedOffsetFrame; 1.559 + mBuilder->mCachedReferenceFrame = mPrevCachedReferenceFrame; 1.560 + mBuilder->mLayerEventRegions = mPrevLayerEventRegions; 1.561 + mBuilder->mCachedOffset = mPrevCachedOffset; 1.562 + mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext; 1.563 + mBuilder->mAncestorHasTouchEventHandler = mPrevAncestorHasTouchEventHandler; 1.564 + } 1.565 + private: 1.566 + nsDisplayListBuilder* mBuilder; 1.567 + const nsIFrame* mPrevCachedOffsetFrame; 1.568 + const nsIFrame* mPrevCachedReferenceFrame; 1.569 + nsDisplayLayerEventRegions* mPrevLayerEventRegions; 1.570 + nsPoint mPrevCachedOffset; 1.571 + bool mPrevIsAtRootOfPseudoStackingContext; 1.572 + bool mPrevAncestorHasTouchEventHandler; 1.573 + }; 1.574 + 1.575 + /** 1.576 + * A helper class to temporarily set the value of mInTransform. 1.577 + */ 1.578 + class AutoInTransformSetter; 1.579 + friend class AutoInTransformSetter; 1.580 + class AutoInTransformSetter { 1.581 + public: 1.582 + AutoInTransformSetter(nsDisplayListBuilder* aBuilder, bool aInTransform) 1.583 + : mBuilder(aBuilder), mOldValue(aBuilder->mInTransform) { 1.584 + aBuilder->mInTransform = aInTransform; 1.585 + } 1.586 + ~AutoInTransformSetter() { 1.587 + mBuilder->mInTransform = mOldValue; 1.588 + } 1.589 + private: 1.590 + nsDisplayListBuilder* mBuilder; 1.591 + bool mOldValue; 1.592 + }; 1.593 + 1.594 + /** 1.595 + * A helper class to temporarily set the value of mInFixedPos. 1.596 + */ 1.597 + class AutoInFixedPosSetter; 1.598 + friend class AutoInFixedPosSetter; 1.599 + class AutoInFixedPosSetter { 1.600 + public: 1.601 + AutoInFixedPosSetter(nsDisplayListBuilder* aBuilder, bool aInFixedPos) 1.602 + : mBuilder(aBuilder), mOldValue(aBuilder->mInFixedPos) { 1.603 + aBuilder->mInFixedPos = aInFixedPos; 1.604 + } 1.605 + ~AutoInFixedPosSetter() { 1.606 + mBuilder->mInFixedPos = mOldValue; 1.607 + } 1.608 + private: 1.609 + nsDisplayListBuilder* mBuilder; 1.610 + bool mOldValue; 1.611 + }; 1.612 + 1.613 + /** 1.614 + * A helper class to temporarily set the value of mCurrentScrollParentId. 1.615 + */ 1.616 + class AutoCurrentScrollParentIdSetter; 1.617 + friend class AutoCurrentScrollParentIdSetter; 1.618 + class AutoCurrentScrollParentIdSetter { 1.619 + public: 1.620 + AutoCurrentScrollParentIdSetter(nsDisplayListBuilder* aBuilder, ViewID aScrollId) 1.621 + : mBuilder(aBuilder), mOldValue(aBuilder->mCurrentScrollParentId) { 1.622 + aBuilder->mCurrentScrollParentId = aScrollId; 1.623 + } 1.624 + ~AutoCurrentScrollParentIdSetter() { 1.625 + mBuilder->mCurrentScrollParentId = mOldValue; 1.626 + } 1.627 + private: 1.628 + nsDisplayListBuilder* mBuilder; 1.629 + ViewID mOldValue; 1.630 + }; 1.631 + 1.632 + // Helpers for tables 1.633 + nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; } 1.634 + void SetCurrentTableItem(nsDisplayTableItem* aTableItem) { mCurrentTableItem = aTableItem; } 1.635 + 1.636 + struct OutOfFlowDisplayData { 1.637 + OutOfFlowDisplayData(const DisplayItemClip& aContainingBlockClip, 1.638 + const nsRect &aDirtyRect) 1.639 + : mContainingBlockClip(aContainingBlockClip) 1.640 + , mDirtyRect(aDirtyRect) 1.641 + {} 1.642 + OutOfFlowDisplayData(const nsRect &aDirtyRect) 1.643 + : mDirtyRect(aDirtyRect) 1.644 + {} 1.645 + DisplayItemClip mContainingBlockClip; 1.646 + nsRect mDirtyRect; 1.647 + }; 1.648 + static void DestroyOutOfFlowDisplayData(void* aPropertyValue) 1.649 + { 1.650 + delete static_cast<OutOfFlowDisplayData*>(aPropertyValue); 1.651 + } 1.652 + 1.653 + NS_DECLARE_FRAME_PROPERTY(OutOfFlowDisplayDataProperty, DestroyOutOfFlowDisplayData) 1.654 + NS_DECLARE_FRAME_PROPERTY(Preserve3DDirtyRectProperty, nsIFrame::DestroyRect) 1.655 + 1.656 + nsPresContext* CurrentPresContext() { 1.657 + return CurrentPresShellState()->mPresShell->GetPresContext(); 1.658 + } 1.659 + 1.660 + /** 1.661 + * Accumulates the bounds of box frames that have moz-appearance 1.662 + * -moz-win-exclude-glass style. Used in setting glass margins on 1.663 + * Windows. 1.664 + */ 1.665 + void AddExcludedGlassRegion(nsRect &bounds) { 1.666 + mExcludedGlassRegion.Or(mExcludedGlassRegion, bounds); 1.667 + } 1.668 + const nsRegion& GetExcludedGlassRegion() { 1.669 + return mExcludedGlassRegion; 1.670 + } 1.671 + void SetGlassDisplayItem(nsDisplayItem* aItem) { 1.672 + if (mGlassDisplayItem) { 1.673 + // Web pages or extensions could trigger this by using 1.674 + // -moz-appearance:win-borderless-glass etc on their own elements. 1.675 + // Keep the first one, since that will be the background of the root 1.676 + // window 1.677 + NS_WARNING("Multiple glass backgrounds found?"); 1.678 + } else { 1.679 + mGlassDisplayItem = aItem; 1.680 + } 1.681 + } 1.682 + bool NeedToForceTransparentSurfaceForItem(nsDisplayItem* aItem) { 1.683 + return aItem == mGlassDisplayItem; 1.684 + } 1.685 + 1.686 + void SetContainsPluginItem() { mContainsPluginItem = true; } 1.687 + bool ContainsPluginItem() { return mContainsPluginItem; } 1.688 + 1.689 + /** 1.690 + * mContainsBlendMode is true if we processed a display item that 1.691 + * has a blend mode attached. We do this so we can insert a 1.692 + * nsDisplayBlendContainer in the parent stacking context. 1.693 + */ 1.694 + void SetContainsBlendMode(bool aContainsBlendMode) { mContainsBlendMode = aContainsBlendMode; } 1.695 + bool ContainsBlendMode() const { return mContainsBlendMode; } 1.696 + 1.697 + DisplayListClipState& ClipState() { return mClipState; } 1.698 + 1.699 +private: 1.700 + void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame, 1.701 + const nsRect& aDirtyRect); 1.702 + 1.703 + struct PresShellState { 1.704 + nsIPresShell* mPresShell; 1.705 + nsIFrame* mCaretFrame; 1.706 + uint32_t mFirstFrameMarkedForDisplay; 1.707 + bool mIsBackgroundOnly; 1.708 + }; 1.709 + PresShellState* CurrentPresShellState() { 1.710 + NS_ASSERTION(mPresShellStates.Length() > 0, 1.711 + "Someone forgot to enter a presshell"); 1.712 + return &mPresShellStates[mPresShellStates.Length() - 1]; 1.713 + } 1.714 + 1.715 + nsIFrame* mReferenceFrame; 1.716 + nsIFrame* mIgnoreScrollFrame; 1.717 + nsDisplayLayerEventRegions* mLayerEventRegions; 1.718 + PLArenaPool mPool; 1.719 + nsCOMPtr<nsISelection> mBoundingSelection; 1.720 + nsAutoTArray<PresShellState,8> mPresShellStates; 1.721 + nsAutoTArray<nsIFrame*,100> mFramesMarkedForDisplay; 1.722 + nsAutoTArray<ThemeGeometry,2> mThemeGeometries; 1.723 + nsDisplayTableItem* mCurrentTableItem; 1.724 + DisplayListClipState mClipState; 1.725 + const nsRegion* mFinalTransparentRegion; 1.726 + // When mCachedOffsetFrame is non-null, mCachedOffset is the offset from 1.727 + // mCachedOffsetFrame to mReferenceFrame. 1.728 + const nsIFrame* mCachedOffsetFrame; 1.729 + const nsIFrame* mCachedReferenceFrame; 1.730 + nsPoint mCachedOffset; 1.731 + nsRegion mExcludedGlassRegion; 1.732 + // The display item for the Windows window glass background, if any 1.733 + nsDisplayItem* mGlassDisplayItem; 1.734 + nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy; 1.735 + Mode mMode; 1.736 + ViewID mCurrentScrollParentId; 1.737 + bool mBuildCaret; 1.738 + bool mIgnoreSuppression; 1.739 + bool mHadToIgnoreSuppression; 1.740 + bool mIsAtRootOfPseudoStackingContext; 1.741 + bool mIncludeAllOutOfFlows; 1.742 + bool mDescendIntoSubdocuments; 1.743 + bool mSelectedFramesOnly; 1.744 + bool mAccurateVisibleRegions; 1.745 + bool mAllowMergingAndFlattening; 1.746 + bool mWillComputePluginGeometry; 1.747 + // True when we're building a display list that's directly or indirectly 1.748 + // under an nsDisplayTransform 1.749 + bool mInTransform; 1.750 + bool mInFixedPos; 1.751 + bool mSyncDecodeImages; 1.752 + bool mIsPaintingToWindow; 1.753 + bool mIsCompositingCheap; 1.754 + bool mContainsPluginItem; 1.755 + bool mContainsBlendMode; 1.756 + bool mAncestorHasTouchEventHandler; 1.757 + // True when the first async-scrollable scroll frame for which we build a 1.758 + // display list has a display port. An async-scrollable scroll frame is one 1.759 + // which WantsAsyncScroll(). 1.760 + bool mHaveScrollableDisplayPort; 1.761 +}; 1.762 + 1.763 +class nsDisplayItem; 1.764 +class nsDisplayList; 1.765 +/** 1.766 + * nsDisplayItems are put in singly-linked lists rooted in an nsDisplayList. 1.767 + * nsDisplayItemLink holds the link. The lists are linked from lowest to 1.768 + * highest in z-order. 1.769 + */ 1.770 +class nsDisplayItemLink { 1.771 + // This is never instantiated directly, so no need to count constructors and 1.772 + // destructors. 1.773 +protected: 1.774 + nsDisplayItemLink() : mAbove(nullptr) {} 1.775 + nsDisplayItem* mAbove; 1.776 + 1.777 + friend class nsDisplayList; 1.778 +}; 1.779 + 1.780 +/** 1.781 + * This is the unit of rendering and event testing. Each instance of this 1.782 + * class represents an entity that can be drawn on the screen, e.g., a 1.783 + * frame's CSS background, or a frame's text string. 1.784 + * 1.785 + * nsDisplayListItems can be containers --- i.e., they can perform hit testing 1.786 + * and painting by recursively traversing a list of child items. 1.787 + * 1.788 + * These are arena-allocated during display list construction. A typical 1.789 + * subclass would just have a frame pointer, so its object would be just three 1.790 + * pointers (vtable, next-item, frame). 1.791 + * 1.792 + * Display items belong to a list at all times (except temporarily as they 1.793 + * move from one list to another). 1.794 + */ 1.795 +class nsDisplayItem : public nsDisplayItemLink { 1.796 +public: 1.797 + typedef mozilla::ContainerLayerParameters ContainerLayerParameters; 1.798 + typedef mozilla::DisplayItemClip DisplayItemClip; 1.799 + typedef mozilla::layers::FrameMetrics::ViewID ViewID; 1.800 + typedef mozilla::layers::Layer Layer; 1.801 + typedef mozilla::layers::LayerManager LayerManager; 1.802 + typedef mozilla::LayerState LayerState; 1.803 + 1.804 + // This is never instantiated directly (it has pure virtual methods), so no 1.805 + // need to count constructors and destructors. 1.806 + nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) 1.807 + : mFrame(aFrame) 1.808 + , mClip(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder)) 1.809 + , mInFixedPos(aBuilder->IsInFixedPos()) 1.810 +#ifdef MOZ_DUMP_PAINTING 1.811 + , mPainted(false) 1.812 +#endif 1.813 + { 1.814 + mReferenceFrame = aBuilder->FindReferenceFrameFor(aFrame); 1.815 + mToReferenceFrame = aBuilder->ToReferenceFrame(aFrame); 1.816 + } 1.817 + nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.818 + const nsIFrame* aReferenceFrame, 1.819 + const nsPoint& aToReferenceFrame) 1.820 + : mFrame(aFrame) 1.821 + , mClip(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder)) 1.822 + , mReferenceFrame(aReferenceFrame) 1.823 + , mToReferenceFrame(aToReferenceFrame) 1.824 + , mInFixedPos(aBuilder->IsInFixedPos()) 1.825 +#ifdef MOZ_DUMP_PAINTING 1.826 + , mPainted(false) 1.827 +#endif 1.828 + { 1.829 + } 1.830 + /** 1.831 + * This constructor is only used in rare cases when we need to construct 1.832 + * temporary items. 1.833 + */ 1.834 + nsDisplayItem(nsIFrame* aFrame) 1.835 + : mFrame(aFrame) 1.836 + , mClip(nullptr) 1.837 + , mReferenceFrame(nullptr) 1.838 + , mInFixedPos(false) 1.839 +#ifdef MOZ_DUMP_PAINTING 1.840 + , mPainted(false) 1.841 +#endif 1.842 + { 1.843 + } 1.844 + virtual ~nsDisplayItem() {} 1.845 + 1.846 + void* operator new(size_t aSize, 1.847 + nsDisplayListBuilder* aBuilder) CPP_THROW_NEW { 1.848 + return aBuilder->Allocate(aSize); 1.849 + } 1.850 + 1.851 +// Contains all the type integers for each display list item type 1.852 +#include "nsDisplayItemTypes.h" 1.853 + 1.854 + struct HitTestState { 1.855 + typedef nsTArray<ViewID> ShadowArray; 1.856 + 1.857 + HitTestState(ShadowArray* aShadows = nullptr) 1.858 + : mShadows(aShadows) { 1.859 + } 1.860 + 1.861 + ~HitTestState() { 1.862 + NS_ASSERTION(mItemBuffer.Length() == 0, 1.863 + "mItemBuffer should have been cleared"); 1.864 + } 1.865 + 1.866 + nsAutoTArray<nsDisplayItem*, 100> mItemBuffer; 1.867 + 1.868 + // It is sometimes useful to hit test for frames that are not in this 1.869 + // process. Display items may append IDs into this array if it is 1.870 + // non-null. 1.871 + ShadowArray* mShadows; 1.872 + }; 1.873 + 1.874 + /** 1.875 + * Some consecutive items should be rendered together as a unit, e.g., 1.876 + * outlines for the same element. For this, we need a way for items to 1.877 + * identify their type. We use the type for other purposes too. 1.878 + */ 1.879 + virtual Type GetType() = 0; 1.880 + /** 1.881 + * Pairing this with the GetUnderlyingFrame() pointer gives a key that 1.882 + * uniquely identifies this display item in the display item tree. 1.883 + * XXX check ScrollLayerWrapper/nsOptionEventGrabberWrapper/nsXULEventRedirectorWrapper 1.884 + */ 1.885 + virtual uint32_t GetPerFrameKey() { return uint32_t(GetType()); } 1.886 + /** 1.887 + * This is called after we've constructed a display list for event handling. 1.888 + * When this is called, we've already ensured that aRect intersects the 1.889 + * item's bounds and that clipping has been taking into account. 1.890 + * 1.891 + * @param aRect the point or rect being tested, relative to the reference 1.892 + * frame. If the width and height are both 1 app unit, it indicates we're 1.893 + * hit testing a point, not a rect. 1.894 + * @param aState must point to a HitTestState. If you don't have one, 1.895 + * just create one with the default constructor and pass it in. 1.896 + * @param aOutFrames each item appends the frame(s) in this display item that 1.897 + * the rect is considered over (if any) to aOutFrames. 1.898 + */ 1.899 + virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, 1.900 + HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {} 1.901 + /** 1.902 + * @return the frame that this display item is based on. This is used to sort 1.903 + * items by z-index and content order and for some other uses. Never 1.904 + * returns null. 1.905 + */ 1.906 + inline nsIFrame* Frame() const { return mFrame; } 1.907 + /** 1.908 + * Compute the used z-index of our frame; returns zero for elements to which 1.909 + * z-index does not apply, and for z-index:auto. 1.910 + * @note This can be overridden, @see nsDisplayWrapList::SetOverrideZIndex. 1.911 + */ 1.912 + virtual int32_t ZIndex() const; 1.913 + /** 1.914 + * The default bounds is the frame border rect. 1.915 + * @param aSnap *aSnap is set to true if the returned rect will be 1.916 + * snapped to nearest device pixel edges during actual drawing. 1.917 + * It might be set to false and snap anyway, so code computing the set of 1.918 + * pixels affected by this display item needs to round outwards to pixel 1.919 + * boundaries when *aSnap is set to false. 1.920 + * This does not take the item's clipping into account. 1.921 + * @return a rectangle relative to aBuilder->ReferenceFrame() that 1.922 + * contains the area drawn by this display item 1.923 + */ 1.924 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) 1.925 + { 1.926 + *aSnap = false; 1.927 + return nsRect(ToReferenceFrame(), Frame()->GetSize()); 1.928 + } 1.929 + /** 1.930 + * Returns the result of GetBounds intersected with the item's clip. 1.931 + * The intersection is approximate since rounded corners are not taking into 1.932 + * account. 1.933 + */ 1.934 + nsRect GetClippedBounds(nsDisplayListBuilder* aBuilder); 1.935 + nsRect GetBorderRect() { 1.936 + return nsRect(ToReferenceFrame(), Frame()->GetSize()); 1.937 + } 1.938 + nsRect GetPaddingRect() { 1.939 + return Frame()->GetPaddingRectRelativeToSelf() + ToReferenceFrame(); 1.940 + } 1.941 + nsRect GetContentRect() { 1.942 + return Frame()->GetContentRectRelativeToSelf() + ToReferenceFrame(); 1.943 + } 1.944 + 1.945 + /** 1.946 + * Checks if the frame(s) owning this display item have been marked as invalid, 1.947 + * and needing repainting. 1.948 + */ 1.949 + virtual bool IsInvalid(nsRect& aRect) { 1.950 + bool result = mFrame ? mFrame->IsInvalid(aRect) : false; 1.951 + aRect += ToReferenceFrame(); 1.952 + return result; 1.953 + } 1.954 + 1.955 + /** 1.956 + * Creates and initializes an nsDisplayItemGeometry object that retains the current 1.957 + * areas covered by this display item. These need to retain enough information 1.958 + * such that they can be compared against a future nsDisplayItem of the same type, 1.959 + * and determine if repainting needs to happen. 1.960 + * 1.961 + * Subclasses wishing to store more information need to override both this 1.962 + * and ComputeInvalidationRegion, as well as implementing an nsDisplayItemGeometry 1.963 + * subclass. 1.964 + * 1.965 + * The default implementation tracks both the display item bounds, and the frame's 1.966 + * border rect. 1.967 + */ 1.968 + virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) 1.969 + { 1.970 + return new nsDisplayItemGenericGeometry(this, aBuilder); 1.971 + } 1.972 + 1.973 + /** 1.974 + * Compares an nsDisplayItemGeometry object from a previous paint against the 1.975 + * current item. Computes if the geometry of the item has changed, and the 1.976 + * invalidation area required for correct repainting. 1.977 + * 1.978 + * The existing geometry will have been created from a display item with a 1.979 + * matching GetPerFrameKey()/mFrame pair to the current item. 1.980 + * 1.981 + * The default implementation compares the display item bounds, and the frame's 1.982 + * border rect, and invalidates the entire bounds if either rect changes. 1.983 + * 1.984 + * @param aGeometry The geometry of the matching display item from the 1.985 + * previous paint. 1.986 + * @param aInvalidRegion Output param, the region to invalidate, or 1.987 + * unchanged if none. 1.988 + */ 1.989 + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, 1.990 + const nsDisplayItemGeometry* aGeometry, 1.991 + nsRegion* aInvalidRegion) 1.992 + { 1.993 + const nsDisplayItemGenericGeometry* geometry = static_cast<const nsDisplayItemGenericGeometry*>(aGeometry); 1.994 + bool snap; 1.995 + if (!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder, &snap)) || 1.996 + !geometry->mBorderRect.IsEqualInterior(GetBorderRect())) { 1.997 + aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds); 1.998 + } 1.999 + } 1.1000 + 1.1001 + /** 1.1002 + * An alternative default implementation of ComputeInvalidationRegion, 1.1003 + * that instead invalidates only the changed area between the two items. 1.1004 + */ 1.1005 + void ComputeInvalidationRegionDifference(nsDisplayListBuilder* aBuilder, 1.1006 + const nsDisplayItemBoundsGeometry* aGeometry, 1.1007 + nsRegion* aInvalidRegion) 1.1008 + { 1.1009 + bool snap; 1.1010 + nsRect bounds = GetBounds(aBuilder, &snap); 1.1011 + 1.1012 + if (!aGeometry->mBounds.IsEqualInterior(bounds)) { 1.1013 + nscoord radii[8]; 1.1014 + if (aGeometry->mHasRoundedCorners || 1.1015 + Frame()->GetBorderRadii(radii)) { 1.1016 + aInvalidRegion->Or(aGeometry->mBounds, bounds); 1.1017 + } else { 1.1018 + aInvalidRegion->Xor(aGeometry->mBounds, bounds); 1.1019 + } 1.1020 + } 1.1021 + } 1.1022 + 1.1023 + /** 1.1024 + * For display items types that just draw a background we use this function 1.1025 + * to do any invalidation that might be needed if we are asked to sync decode 1.1026 + * images. 1.1027 + */ 1.1028 + void AddInvalidRegionForSyncDecodeBackgroundImages( 1.1029 + nsDisplayListBuilder* aBuilder, 1.1030 + const nsDisplayItemGeometry* aGeometry, 1.1031 + nsRegion* aInvalidRegion); 1.1032 + 1.1033 + /** 1.1034 + * Called when the area rendered by this display item has changed (been 1.1035 + * invalidated or changed geometry) since the last paint. This includes 1.1036 + * when the display item was not rendered at all in the last paint. 1.1037 + * It does NOT get called when a display item was being rendered and no 1.1038 + * longer is, because generally that means there is no display item to 1.1039 + * call this method on. 1.1040 + */ 1.1041 + virtual void NotifyRenderingChanged() {} 1.1042 + 1.1043 + /** 1.1044 + * @param aSnap set to true if the edges of the rectangles of the opaque 1.1045 + * region would be snapped to device pixels when drawing 1.1046 + * @return a region of the item that is opaque --- that is, every pixel 1.1047 + * that is visible (according to ComputeVisibility) is painted with an opaque 1.1048 + * color. This is useful for determining when one piece 1.1049 + * of content completely obscures another so that we can do occlusion 1.1050 + * culling. 1.1051 + * This does not take clipping into account. 1.1052 + */ 1.1053 + virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, 1.1054 + bool* aSnap) 1.1055 + { 1.1056 + *aSnap = false; 1.1057 + return nsRegion(); 1.1058 + } 1.1059 + /** 1.1060 + * If this returns true, then aColor is set to the uniform color 1.1061 + * @return true if the item is guaranteed to paint every pixel in its 1.1062 + * bounds with the same (possibly translucent) color 1.1063 + */ 1.1064 + virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { return false; } 1.1065 + /** 1.1066 + * @return false if the painting performed by the item is invariant 1.1067 + * when the item's underlying frame is moved relative to aFrame. 1.1068 + * In other words, if you render the item at locations P and P', the rendering 1.1069 + * only differs by the translation. 1.1070 + * It return true for all wrapped lists. 1.1071 + */ 1.1072 + virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, 1.1073 + nsIFrame* aFrame) 1.1074 + { return false; } 1.1075 + /** 1.1076 + * @return true if the contents of this item are rendered fixed relative 1.1077 + * to the nearest viewport. 1.1078 + */ 1.1079 + virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) 1.1080 + { return false; } 1.1081 + 1.1082 + /** 1.1083 + * Returns true if all layers that can be active should be forced to be 1.1084 + * active. Requires setting the pref layers.force-active=true. 1.1085 + */ 1.1086 + static bool ForceActiveLayers(); 1.1087 + 1.1088 + /** 1.1089 + * Returns the maximum number of layers that should be created 1.1090 + * or -1 for no limit. Requires setting the pref layers.max-acitve. 1.1091 + */ 1.1092 + static int32_t MaxActiveLayers(); 1.1093 + 1.1094 + /** 1.1095 + * @return LAYER_NONE if BuildLayer will return null. In this case 1.1096 + * there is no layer for the item, and Paint should be called instead 1.1097 + * to paint the content using Thebes. 1.1098 + * Return LAYER_INACTIVE if there is a layer --- BuildLayer will 1.1099 + * not return null (unless there's an error) --- but the layer contents 1.1100 + * are not changing frequently. In this case it makes sense to composite 1.1101 + * the layer into a ThebesLayer with other content, so we don't have to 1.1102 + * recomposite it every time we paint. 1.1103 + * Note: GetLayerState is only allowed to return LAYER_INACTIVE if all 1.1104 + * descendant display items returned LAYER_INACTIVE or LAYER_NONE. Also, 1.1105 + * all descendant display item frames must have an active scrolled root 1.1106 + * that's either the same as this item's frame's active scrolled root, or 1.1107 + * a descendant of this item's frame. This ensures that the entire 1.1108 + * set of display items can be collapsed onto a single ThebesLayer. 1.1109 + * Return LAYER_ACTIVE if the layer is active, that is, its contents are 1.1110 + * changing frequently. In this case it makes sense to keep the layer 1.1111 + * as a separate buffer in VRAM and composite it into the destination 1.1112 + * every time we paint. 1.1113 + * 1.1114 + * Users of GetLayerState should check ForceActiveLayers() and if it returns 1.1115 + * true, change a returned value of LAYER_INACTIVE to LAYER_ACTIVE. 1.1116 + */ 1.1117 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.1118 + LayerManager* aManager, 1.1119 + const ContainerLayerParameters& aParameters) 1.1120 + { return mozilla::LAYER_NONE; } 1.1121 + /** 1.1122 + * Return true to indicate the layer should be constructed even if it's 1.1123 + * completely invisible. 1.1124 + */ 1.1125 + virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) 1.1126 + { return false; } 1.1127 + /** 1.1128 + * Actually paint this item to some rendering context. 1.1129 + * Content outside mVisibleRect need not be painted. 1.1130 + * aCtx must be set up as for nsDisplayList::Paint. 1.1131 + */ 1.1132 + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) {} 1.1133 + 1.1134 +#ifdef MOZ_DUMP_PAINTING 1.1135 + /** 1.1136 + * Mark this display item as being painted via FrameLayerBuilder::DrawThebesLayer. 1.1137 + */ 1.1138 + bool Painted() { return mPainted; } 1.1139 + 1.1140 + /** 1.1141 + * Check if this display item has been painted. 1.1142 + */ 1.1143 + void SetPainted() { mPainted = true; } 1.1144 +#endif 1.1145 + 1.1146 + /** 1.1147 + * Get the layer drawn by this display item. Call this only if 1.1148 + * GetLayerState() returns something other than LAYER_NONE. 1.1149 + * If GetLayerState returned LAYER_NONE then Paint will be called 1.1150 + * instead. 1.1151 + * This is called while aManager is in the construction phase. 1.1152 + * 1.1153 + * The caller (nsDisplayList) is responsible for setting the visible 1.1154 + * region of the layer. 1.1155 + * 1.1156 + * @param aContainerParameters should be passed to 1.1157 + * FrameLayerBuilder::BuildContainerLayerFor if a ContainerLayer is 1.1158 + * constructed. 1.1159 + */ 1.1160 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.1161 + LayerManager* aManager, 1.1162 + const ContainerLayerParameters& aContainerParameters) 1.1163 + { return nullptr; } 1.1164 + 1.1165 + /** 1.1166 + * On entry, aVisibleRegion contains the region (relative to ReferenceFrame()) 1.1167 + * which may be visible. If the display item opaquely covers an area, it 1.1168 + * can remove that area from aVisibleRegion before returning. 1.1169 + * nsDisplayList::ComputeVisibility automatically subtracts the region 1.1170 + * returned by GetOpaqueRegion, and automatically removes items whose bounds 1.1171 + * do not intersect the visible area, so implementations of 1.1172 + * nsDisplayItem::ComputeVisibility do not need to do these things. 1.1173 + * nsDisplayList::ComputeVisibility will already have set mVisibleRect on 1.1174 + * this item to the intersection of *aVisibleRegion and this item's bounds. 1.1175 + * We rely on that, so this should only be called by 1.1176 + * nsDisplayList::ComputeVisibility or nsDisplayItem::RecomputeVisibility. 1.1177 + * aAllowVisibleRegionExpansion is a rect where we are allowed to 1.1178 + * expand the visible region and is only used for making sure the 1.1179 + * background behind a plugin is visible. 1.1180 + * This method needs to be idempotent. 1.1181 + * 1.1182 + * @return true if the item is visible, false if no part of the item 1.1183 + * is visible. 1.1184 + */ 1.1185 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.1186 + nsRegion* aVisibleRegion, 1.1187 + const nsRect& aAllowVisibleRegionExpansion) 1.1188 + { return !mVisibleRect.IsEmpty(); } 1.1189 + 1.1190 + /** 1.1191 + * Try to merge with the other item (which is below us in the display 1.1192 + * list). This gets used by nsDisplayClip to coalesce clipping operations 1.1193 + * (optimization), by nsDisplayOpacity to merge rendering for the same 1.1194 + * content element into a single opacity group (correctness), and will be 1.1195 + * used by nsDisplayOutline to merge multiple outlines for the same element 1.1196 + * (also for correctness). 1.1197 + * @return true if the merge was successful and the other item should be deleted 1.1198 + */ 1.1199 + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) { 1.1200 + return false; 1.1201 + } 1.1202 + 1.1203 + /** 1.1204 + * Appends the underlying frames of all display items that have been 1.1205 + * merged into this one (excluding this item's own underlying frame) 1.1206 + * to aFrames. 1.1207 + */ 1.1208 + virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) {} 1.1209 + 1.1210 + /** 1.1211 + * During the visibility computation and after TryMerge, display lists may 1.1212 + * return true here to flatten themselves away, removing them. This 1.1213 + * flattening is distinctly different from FlattenTo, which occurs before 1.1214 + * items are merged together. 1.1215 + */ 1.1216 + virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) { 1.1217 + return false; 1.1218 + } 1.1219 + 1.1220 + /** 1.1221 + * If this has a child list where the children are in the same coordinate 1.1222 + * system as this item (i.e., they have the same reference frame), 1.1223 + * return the list. 1.1224 + */ 1.1225 + virtual nsDisplayList* GetSameCoordinateSystemChildren() { return nullptr; } 1.1226 + virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) {} 1.1227 + 1.1228 + /** 1.1229 + * If this has a child list, return it, even if the children are in 1.1230 + * a different coordinate system to this item. 1.1231 + */ 1.1232 + virtual nsDisplayList* GetChildren() { return nullptr; } 1.1233 + 1.1234 + /** 1.1235 + * Returns the visible rect. Should only be called after ComputeVisibility 1.1236 + * has happened. 1.1237 + */ 1.1238 + const nsRect& GetVisibleRect() { return mVisibleRect; } 1.1239 + 1.1240 + /** 1.1241 + * Stores the given opacity value to be applied when drawing. Returns 1.1242 + * false if this isn't supported for this display item. 1.1243 + */ 1.1244 + virtual bool ApplyOpacity(nsDisplayListBuilder* aBuilder, 1.1245 + float aOpacity, 1.1246 + const DisplayItemClip* aClip) { 1.1247 + return false; 1.1248 + } 1.1249 + 1.1250 +#ifdef MOZ_DUMP_PAINTING 1.1251 + /** 1.1252 + * For debugging and stuff 1.1253 + */ 1.1254 + virtual const char* Name() = 0; 1.1255 + 1.1256 + virtual void WriteDebugInfo(nsACString& aTo) {} 1.1257 +#endif 1.1258 + 1.1259 + nsDisplayItem* GetAbove() { return mAbove; } 1.1260 + 1.1261 + /** 1.1262 + * Like ComputeVisibility, but does the work that nsDisplayList 1.1263 + * does per-item: 1.1264 + * -- Intersects GetBounds with aVisibleRegion and puts the result 1.1265 + * in mVisibleRect 1.1266 + * -- Subtracts bounds from aVisibleRegion if the item is opaque 1.1267 + */ 1.1268 + bool RecomputeVisibility(nsDisplayListBuilder* aBuilder, 1.1269 + nsRegion* aVisibleRegion); 1.1270 + 1.1271 + /** 1.1272 + * Returns the result of aBuilder->ToReferenceFrame(GetUnderlyingFrame()) 1.1273 + */ 1.1274 + const nsPoint& ToReferenceFrame() const { 1.1275 + NS_ASSERTION(mFrame, "No frame?"); 1.1276 + return mToReferenceFrame; 1.1277 + } 1.1278 + /** 1.1279 + * @return the root of the display list's frame (sub)tree, whose origin 1.1280 + * establishes the coordinate system for the display list 1.1281 + */ 1.1282 + const nsIFrame* ReferenceFrame() const { return mReferenceFrame; } 1.1283 + 1.1284 + /** 1.1285 + * Returns the reference frame for display item children of this item. 1.1286 + */ 1.1287 + virtual const nsIFrame* ReferenceFrameForChildren() const { return mReferenceFrame; } 1.1288 + 1.1289 + /** 1.1290 + * Checks if this display item (or any children) contains content that might 1.1291 + * be rendered with component alpha (e.g. subpixel antialiasing). Returns the 1.1292 + * bounds of the area that needs component alpha, or an empty rect if nothing 1.1293 + * in the item does. 1.1294 + */ 1.1295 + virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) { return nsRect(); } 1.1296 + 1.1297 + /** 1.1298 + * Disable usage of component alpha. Currently only relevant for items that have text. 1.1299 + */ 1.1300 + virtual void DisableComponentAlpha() {} 1.1301 + 1.1302 + /** 1.1303 + * Check if we can add async animations to the layer for this display item. 1.1304 + */ 1.1305 + virtual bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) { 1.1306 + return false; 1.1307 + } 1.1308 + 1.1309 + virtual bool SupportsOptimizingToImage() { return false; } 1.1310 + 1.1311 + const DisplayItemClip& GetClip() 1.1312 + { 1.1313 + return mClip ? *mClip : DisplayItemClip::NoClip(); 1.1314 + } 1.1315 + void SetClip(nsDisplayListBuilder* aBuilder, const DisplayItemClip& aClip) 1.1316 + { 1.1317 + if (!aClip.HasClip()) { 1.1318 + mClip = nullptr; 1.1319 + return; 1.1320 + } 1.1321 + mClip = aBuilder->AllocateDisplayItemClip(aClip); 1.1322 + } 1.1323 + 1.1324 + void IntersectClip(nsDisplayListBuilder* aBuilder, const DisplayItemClip& aClip) 1.1325 + { 1.1326 + if (mClip) { 1.1327 + DisplayItemClip temp = *mClip; 1.1328 + temp.IntersectWith(aClip); 1.1329 + SetClip(aBuilder, temp); 1.1330 + } else { 1.1331 + SetClip(aBuilder, aClip); 1.1332 + } 1.1333 + } 1.1334 + 1.1335 + // If we return false here it means that if this item creates a layer then 1.1336 + // ProcessDisplayItems will not set the visible region on the layer. The item 1.1337 + // should set the visible region, usually in BuildContainerLayer. 1.1338 + virtual bool SetVisibleRegionOnLayer() { return true; } 1.1339 + 1.1340 + bool IsInFixedPos() { return mInFixedPos; } 1.1341 + 1.1342 +protected: 1.1343 + friend class nsDisplayList; 1.1344 + 1.1345 + nsDisplayItem() { mAbove = nullptr; } 1.1346 + 1.1347 + nsIFrame* mFrame; 1.1348 + const DisplayItemClip* mClip; 1.1349 + // Result of FindReferenceFrameFor(mFrame), if mFrame is non-null 1.1350 + const nsIFrame* mReferenceFrame; 1.1351 + // Result of ToReferenceFrame(mFrame), if mFrame is non-null 1.1352 + nsPoint mToReferenceFrame; 1.1353 + // This is the rectangle that needs to be painted. 1.1354 + // nsDisplayList::ComputeVisibility sets this to the visible region 1.1355 + // of the item by intersecting the current visible region with the bounds 1.1356 + // of the item. Paint implementations can use this to limit their drawing. 1.1357 + // Guaranteed to be contained in GetBounds(). 1.1358 + nsRect mVisibleRect; 1.1359 + bool mInFixedPos; 1.1360 +#ifdef MOZ_DUMP_PAINTING 1.1361 + // True if this frame has been painted. 1.1362 + bool mPainted; 1.1363 +#endif 1.1364 +}; 1.1365 + 1.1366 +/** 1.1367 + * Manages a singly-linked list of display list items. 1.1368 + * 1.1369 + * mSentinel is the sentinel list value, the first value in the null-terminated 1.1370 + * linked list of items. mTop is the last item in the list (whose 'above' 1.1371 + * pointer is null). This class has no virtual methods. So list objects are just 1.1372 + * two pointers. 1.1373 + * 1.1374 + * Stepping upward through this list is very fast. Stepping downward is very 1.1375 + * slow so we don't support it. The methods that need to step downward 1.1376 + * (HitTest(), ComputeVisibility()) internally build a temporary array of all 1.1377 + * the items while they do the downward traversal, so overall they're still 1.1378 + * linear time. We have optimized for efficient AppendToTop() of both 1.1379 + * items and lists, with minimal codesize. AppendToBottom() is efficient too. 1.1380 + */ 1.1381 +class nsDisplayList { 1.1382 +public: 1.1383 + typedef mozilla::layers::Layer Layer; 1.1384 + typedef mozilla::layers::LayerManager LayerManager; 1.1385 + typedef mozilla::layers::ThebesLayer ThebesLayer; 1.1386 + 1.1387 + /** 1.1388 + * Create an empty list. 1.1389 + */ 1.1390 + nsDisplayList() : 1.1391 + mIsOpaque(false) 1.1392 + { 1.1393 + mTop = &mSentinel; 1.1394 + mSentinel.mAbove = nullptr; 1.1395 +#if defined(DEBUG) || defined(MOZ_DUMP_PAINTING) 1.1396 + mDidComputeVisibility = false; 1.1397 +#endif 1.1398 + } 1.1399 + ~nsDisplayList() { 1.1400 + if (mSentinel.mAbove) { 1.1401 + NS_WARNING("Nonempty list left over?"); 1.1402 + } 1.1403 + DeleteAll(); 1.1404 + } 1.1405 + 1.1406 + /** 1.1407 + * Append an item to the top of the list. The item must not currently 1.1408 + * be in a list and cannot be null. 1.1409 + */ 1.1410 + void AppendToTop(nsDisplayItem* aItem) { 1.1411 + NS_ASSERTION(aItem, "No item to append!"); 1.1412 + NS_ASSERTION(!aItem->mAbove, "Already in a list!"); 1.1413 + mTop->mAbove = aItem; 1.1414 + mTop = aItem; 1.1415 + } 1.1416 + 1.1417 + /** 1.1418 + * Append a new item to the top of the list. If the item is null we return 1.1419 + * NS_ERROR_OUT_OF_MEMORY. The intended usage is AppendNewToTop(new ...); 1.1420 + */ 1.1421 + void AppendNewToTop(nsDisplayItem* aItem) { 1.1422 + if (aItem) { 1.1423 + AppendToTop(aItem); 1.1424 + } 1.1425 + } 1.1426 + 1.1427 + /** 1.1428 + * Append a new item to the bottom of the list. If the item is null we return 1.1429 + * NS_ERROR_OUT_OF_MEMORY. The intended usage is AppendNewToBottom(new ...); 1.1430 + */ 1.1431 + void AppendNewToBottom(nsDisplayItem* aItem) { 1.1432 + if (aItem) { 1.1433 + AppendToBottom(aItem); 1.1434 + } 1.1435 + } 1.1436 + 1.1437 + /** 1.1438 + * Append a new item to the bottom of the list. The item must be non-null 1.1439 + * and not already in a list. 1.1440 + */ 1.1441 + void AppendToBottom(nsDisplayItem* aItem) { 1.1442 + NS_ASSERTION(aItem, "No item to append!"); 1.1443 + NS_ASSERTION(!aItem->mAbove, "Already in a list!"); 1.1444 + aItem->mAbove = mSentinel.mAbove; 1.1445 + mSentinel.mAbove = aItem; 1.1446 + if (mTop == &mSentinel) { 1.1447 + mTop = aItem; 1.1448 + } 1.1449 + } 1.1450 + 1.1451 + /** 1.1452 + * Removes all items from aList and appends them to the top of this list 1.1453 + */ 1.1454 + void AppendToTop(nsDisplayList* aList) { 1.1455 + if (aList->mSentinel.mAbove) { 1.1456 + mTop->mAbove = aList->mSentinel.mAbove; 1.1457 + mTop = aList->mTop; 1.1458 + aList->mTop = &aList->mSentinel; 1.1459 + aList->mSentinel.mAbove = nullptr; 1.1460 + } 1.1461 + } 1.1462 + 1.1463 + /** 1.1464 + * Removes all items from aList and prepends them to the bottom of this list 1.1465 + */ 1.1466 + void AppendToBottom(nsDisplayList* aList) { 1.1467 + if (aList->mSentinel.mAbove) { 1.1468 + aList->mTop->mAbove = mSentinel.mAbove; 1.1469 + mSentinel.mAbove = aList->mSentinel.mAbove; 1.1470 + if (mTop == &mSentinel) { 1.1471 + mTop = aList->mTop; 1.1472 + } 1.1473 + 1.1474 + aList->mTop = &aList->mSentinel; 1.1475 + aList->mSentinel.mAbove = nullptr; 1.1476 + } 1.1477 + } 1.1478 + 1.1479 + /** 1.1480 + * Remove an item from the bottom of the list and return it. 1.1481 + */ 1.1482 + nsDisplayItem* RemoveBottom(); 1.1483 + 1.1484 + /** 1.1485 + * Remove all items from the list and call their destructors. 1.1486 + */ 1.1487 + void DeleteAll(); 1.1488 + 1.1489 + /** 1.1490 + * @return the item at the top of the list, or null if the list is empty 1.1491 + */ 1.1492 + nsDisplayItem* GetTop() const { 1.1493 + return mTop != &mSentinel ? static_cast<nsDisplayItem*>(mTop) : nullptr; 1.1494 + } 1.1495 + /** 1.1496 + * @return the item at the bottom of the list, or null if the list is empty 1.1497 + */ 1.1498 + nsDisplayItem* GetBottom() const { return mSentinel.mAbove; } 1.1499 + bool IsEmpty() const { return mTop == &mSentinel; } 1.1500 + 1.1501 + /** 1.1502 + * This is *linear time*! 1.1503 + * @return the number of items in the list 1.1504 + */ 1.1505 + uint32_t Count() const; 1.1506 + /** 1.1507 + * Stable sort the list by the z-order of GetUnderlyingFrame() on 1.1508 + * each item. 'auto' is counted as zero. Content order is used as the 1.1509 + * secondary order. 1.1510 + * @param aCommonAncestor a common ancestor of all the content elements 1.1511 + * associated with the display items, for speeding up tree order 1.1512 + * checks, or nullptr if not known; it's only a hint, if it is not an 1.1513 + * ancestor of some elements, then we lose performance but not correctness 1.1514 + */ 1.1515 + void SortByZOrder(nsDisplayListBuilder* aBuilder, nsIContent* aCommonAncestor); 1.1516 + /** 1.1517 + * Stable sort the list by the tree order of the content of 1.1518 + * GetUnderlyingFrame() on each item. z-index is ignored. 1.1519 + * @param aCommonAncestor a common ancestor of all the content elements 1.1520 + * associated with the display items, for speeding up tree order 1.1521 + * checks, or nullptr if not known; it's only a hint, if it is not an 1.1522 + * ancestor of some elements, then we lose performance but not correctness 1.1523 + */ 1.1524 + void SortByContentOrder(nsDisplayListBuilder* aBuilder, nsIContent* aCommonAncestor); 1.1525 + 1.1526 + /** 1.1527 + * Generic stable sort. Take care, because some of the items might be nsDisplayLists 1.1528 + * themselves. 1.1529 + * aCmp(item1, item2) should return true if item1 <= item2. We sort the items 1.1530 + * into increasing order. 1.1531 + */ 1.1532 + typedef bool (* SortLEQ)(nsDisplayItem* aItem1, nsDisplayItem* aItem2, 1.1533 + void* aClosure); 1.1534 + void Sort(nsDisplayListBuilder* aBuilder, SortLEQ aCmp, void* aClosure); 1.1535 + 1.1536 + /** 1.1537 + * Compute visiblity for the items in the list. 1.1538 + * We put this logic here so it can be shared by top-level 1.1539 + * painting and also display items that maintain child lists. 1.1540 + * This is also a good place to put ComputeVisibility-related logic 1.1541 + * that must be applied to every display item. In particular, this 1.1542 + * sets mVisibleRect on each display item. 1.1543 + * This sets mIsOpaque if the entire visible area of this list has 1.1544 + * been removed from aVisibleRegion when we return. 1.1545 + * This does not remove any items from the list, so we can recompute 1.1546 + * visiblity with different regions later (see 1.1547 + * FrameLayerBuilder::DrawThebesLayer). 1.1548 + * This method needs to be idempotent. 1.1549 + * 1.1550 + * @param aVisibleRegion the area that is visible, relative to the 1.1551 + * reference frame; on return, this contains the area visible under the list. 1.1552 + * I.e., opaque contents of this list are subtracted from aVisibleRegion. 1.1553 + * @param aListVisibleBounds must be equal to the bounds of the intersection 1.1554 + * of aVisibleRegion and GetBounds() for this list. 1.1555 + * @param aDisplayPortFrame If the item for which this list corresponds is 1.1556 + * within a displayport, the scroll frame for which that display port 1.1557 + * applies. For root scroll frames, you can pass the the root frame instead. 1.1558 + * @return true if any item in the list is visible. 1.1559 + */ 1.1560 + bool ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder, 1.1561 + nsRegion* aVisibleRegion, 1.1562 + const nsRect& aListVisibleBounds, 1.1563 + const nsRect& aAllowVisibleRegionExpansion, 1.1564 + nsIFrame* aDisplayPortFrame = nullptr); 1.1565 + 1.1566 + /** 1.1567 + * As ComputeVisibilityForSublist, but computes visibility for a root 1.1568 + * list (a list that does not belong to an nsDisplayItem). 1.1569 + * This method needs to be idempotent. 1.1570 + * 1.1571 + * @param aVisibleRegion the area that is visible 1.1572 + * @param aDisplayPortFrame The root scroll frame, if a displayport is set 1.1573 + */ 1.1574 + bool ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder, 1.1575 + nsRegion* aVisibleRegion, 1.1576 + nsIFrame* aDisplayPortFrame = nullptr); 1.1577 + 1.1578 + /** 1.1579 + * Returns true if the visible region output from ComputeVisiblity was 1.1580 + * empty, i.e. everything visible in this list is opaque. 1.1581 + */ 1.1582 + bool IsOpaque() const { 1.1583 + NS_ASSERTION(mDidComputeVisibility, "Need to have called ComputeVisibility"); 1.1584 + return mIsOpaque; 1.1585 + } 1.1586 + 1.1587 + /** 1.1588 + * Returns true if during ComputeVisibility any display item 1.1589 + * set the surface to be transparent. 1.1590 + */ 1.1591 + bool NeedsTransparentSurface() const { 1.1592 + NS_ASSERTION(mDidComputeVisibility, "Need to have called ComputeVisibility"); 1.1593 + return mForceTransparentSurface; 1.1594 + } 1.1595 + /** 1.1596 + * Paint the list to the rendering context. We assume that (0,0) in aCtx 1.1597 + * corresponds to the origin of the reference frame. For best results, 1.1598 + * aCtx's current transform should make (0,0) pixel-aligned. The 1.1599 + * rectangle in aDirtyRect is painted, which *must* be contained in the 1.1600 + * dirty rect used to construct the display list. 1.1601 + * 1.1602 + * If aFlags contains PAINT_USE_WIDGET_LAYERS and 1.1603 + * ShouldUseWidgetLayerManager() is set, then we will paint using 1.1604 + * the reference frame's widget's layer manager (and ctx may be null), 1.1605 + * otherwise we will use a temporary BasicLayerManager and ctx must 1.1606 + * not be null. 1.1607 + * 1.1608 + * If PAINT_FLUSH_LAYERS is set, we'll force a completely new layer 1.1609 + * tree to be created for this paint *and* the next paint. 1.1610 + * 1.1611 + * If PAINT_EXISTING_TRANSACTION is set, the reference frame's widget's 1.1612 + * layer manager has already had BeginTransaction() called on it and 1.1613 + * we should not call it again. 1.1614 + * 1.1615 + * If PAINT_COMPRESSED is set, the FrameLayerBuilder should be set to compressed mode 1.1616 + * to avoid short cut optimizations. 1.1617 + * 1.1618 + * ComputeVisibility must be called before Paint. 1.1619 + * 1.1620 + * This must only be called on the root display list of the display list 1.1621 + * tree. 1.1622 + */ 1.1623 + enum { 1.1624 + PAINT_DEFAULT = 0, 1.1625 + PAINT_USE_WIDGET_LAYERS = 0x01, 1.1626 + PAINT_FLUSH_LAYERS = 0x02, 1.1627 + PAINT_EXISTING_TRANSACTION = 0x04, 1.1628 + PAINT_NO_COMPOSITE = 0x08, 1.1629 + PAINT_COMPRESSED = 0x10 1.1630 + }; 1.1631 + void PaintRoot(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx, 1.1632 + uint32_t aFlags) const; 1.1633 + /** 1.1634 + * Like PaintRoot, but used for internal display sublists. 1.1635 + * aForFrame is the frame that the list is associated with. 1.1636 + */ 1.1637 + void PaintForFrame(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx, 1.1638 + nsIFrame* aForFrame, uint32_t aFlags) const; 1.1639 + /** 1.1640 + * Get the bounds. Takes the union of the bounds of all children. 1.1641 + */ 1.1642 + nsRect GetBounds(nsDisplayListBuilder* aBuilder) const; 1.1643 + /** 1.1644 + * Find the topmost display item that returns a non-null frame, and return 1.1645 + * the frame. 1.1646 + */ 1.1647 + void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, 1.1648 + nsDisplayItem::HitTestState* aState, 1.1649 + nsTArray<nsIFrame*> *aOutFrames) const; 1.1650 + 1.1651 +#if defined(DEBUG) || defined(MOZ_DUMP_PAINTING) 1.1652 + bool DidComputeVisibility() const { return mDidComputeVisibility; } 1.1653 +#endif 1.1654 + 1.1655 + nsRect GetVisibleRect() const { return mVisibleRect; } 1.1656 + 1.1657 +private: 1.1658 + // This class is only used on stack, so we don't have to worry about leaking 1.1659 + // it. Don't let us be heap-allocated! 1.1660 + void* operator new(size_t sz) CPP_THROW_NEW; 1.1661 + 1.1662 + // Utility function used to massage the list during ComputeVisibility. 1.1663 + void FlattenTo(nsTArray<nsDisplayItem*>* aElements); 1.1664 + 1.1665 + nsDisplayItemLink mSentinel; 1.1666 + nsDisplayItemLink* mTop; 1.1667 + 1.1668 + // This is set by ComputeVisibility 1.1669 + nsRect mVisibleRect; 1.1670 + // This is set to true by ComputeVisibility if the final visible region 1.1671 + // is empty (i.e. everything that was visible is covered by some 1.1672 + // opaque content in this list). 1.1673 + bool mIsOpaque; 1.1674 + // This is set to true by ComputeVisibility if any display item in this 1.1675 + // list needs to force the surface containing this list to be transparent. 1.1676 + bool mForceTransparentSurface; 1.1677 +#if defined(DEBUG) || defined(MOZ_DUMP_PAINTING) 1.1678 + bool mDidComputeVisibility; 1.1679 +#endif 1.1680 +}; 1.1681 + 1.1682 +/** 1.1683 + * This is passed as a parameter to nsIFrame::BuildDisplayList. That method 1.1684 + * will put any generated items onto the appropriate list given here. It's 1.1685 + * basically just a collection with one list for each separate stacking layer. 1.1686 + * The lists themselves are external to this object and thus can be shared 1.1687 + * with others. Some of the list pointers may even refer to the same list. 1.1688 + */ 1.1689 +class nsDisplayListSet { 1.1690 +public: 1.1691 + /** 1.1692 + * @return a list where one should place the border and/or background for 1.1693 + * this frame (everything from steps 1 and 2 of CSS 2.1 appendix E) 1.1694 + */ 1.1695 + nsDisplayList* BorderBackground() const { return mBorderBackground; } 1.1696 + /** 1.1697 + * @return a list where one should place the borders and/or backgrounds for 1.1698 + * block-level in-flow descendants (step 4 of CSS 2.1 appendix E) 1.1699 + */ 1.1700 + nsDisplayList* BlockBorderBackgrounds() const { return mBlockBorderBackgrounds; } 1.1701 + /** 1.1702 + * @return a list where one should place descendant floats (step 5 of 1.1703 + * CSS 2.1 appendix E) 1.1704 + */ 1.1705 + nsDisplayList* Floats() const { return mFloats; } 1.1706 + /** 1.1707 + * @return a list where one should place the (pseudo) stacking contexts 1.1708 + * for descendants of this frame (everything from steps 3, 7 and 8 1.1709 + * of CSS 2.1 appendix E) 1.1710 + */ 1.1711 + nsDisplayList* PositionedDescendants() const { return mPositioned; } 1.1712 + /** 1.1713 + * @return a list where one should place the outlines 1.1714 + * for this frame and its descendants (step 9 of CSS 2.1 appendix E) 1.1715 + */ 1.1716 + nsDisplayList* Outlines() const { return mOutlines; } 1.1717 + /** 1.1718 + * @return a list where one should place all other content 1.1719 + */ 1.1720 + nsDisplayList* Content() const { return mContent; } 1.1721 + 1.1722 + nsDisplayListSet(nsDisplayList* aBorderBackground, 1.1723 + nsDisplayList* aBlockBorderBackgrounds, 1.1724 + nsDisplayList* aFloats, 1.1725 + nsDisplayList* aContent, 1.1726 + nsDisplayList* aPositionedDescendants, 1.1727 + nsDisplayList* aOutlines) : 1.1728 + mBorderBackground(aBorderBackground), 1.1729 + mBlockBorderBackgrounds(aBlockBorderBackgrounds), 1.1730 + mFloats(aFloats), 1.1731 + mContent(aContent), 1.1732 + mPositioned(aPositionedDescendants), 1.1733 + mOutlines(aOutlines) { 1.1734 + } 1.1735 + 1.1736 + /** 1.1737 + * A copy constructor that lets the caller override the BorderBackground 1.1738 + * list. 1.1739 + */ 1.1740 + nsDisplayListSet(const nsDisplayListSet& aLists, 1.1741 + nsDisplayList* aBorderBackground) : 1.1742 + mBorderBackground(aBorderBackground), 1.1743 + mBlockBorderBackgrounds(aLists.BlockBorderBackgrounds()), 1.1744 + mFloats(aLists.Floats()), 1.1745 + mContent(aLists.Content()), 1.1746 + mPositioned(aLists.PositionedDescendants()), 1.1747 + mOutlines(aLists.Outlines()) { 1.1748 + } 1.1749 + 1.1750 + /** 1.1751 + * Move all display items in our lists to top of the corresponding lists in the 1.1752 + * destination. 1.1753 + */ 1.1754 + void MoveTo(const nsDisplayListSet& aDestination) const; 1.1755 + 1.1756 +private: 1.1757 + // This class is only used on stack, so we don't have to worry about leaking 1.1758 + // it. Don't let us be heap-allocated! 1.1759 + void* operator new(size_t sz) CPP_THROW_NEW; 1.1760 + 1.1761 +protected: 1.1762 + nsDisplayList* mBorderBackground; 1.1763 + nsDisplayList* mBlockBorderBackgrounds; 1.1764 + nsDisplayList* mFloats; 1.1765 + nsDisplayList* mContent; 1.1766 + nsDisplayList* mPositioned; 1.1767 + nsDisplayList* mOutlines; 1.1768 +}; 1.1769 + 1.1770 +/** 1.1771 + * A specialization of nsDisplayListSet where the lists are actually internal 1.1772 + * to the object, and all distinct. 1.1773 + */ 1.1774 +struct nsDisplayListCollection : public nsDisplayListSet { 1.1775 + nsDisplayListCollection() : 1.1776 + nsDisplayListSet(&mLists[0], &mLists[1], &mLists[2], &mLists[3], &mLists[4], 1.1777 + &mLists[5]) {} 1.1778 + nsDisplayListCollection(nsDisplayList* aBorderBackground) : 1.1779 + nsDisplayListSet(aBorderBackground, &mLists[1], &mLists[2], &mLists[3], &mLists[4], 1.1780 + &mLists[5]) {} 1.1781 + 1.1782 + /** 1.1783 + * Sort all lists by content order. 1.1784 + */ 1.1785 + void SortAllByContentOrder(nsDisplayListBuilder* aBuilder, nsIContent* aCommonAncestor) { 1.1786 + for (int32_t i = 0; i < 6; ++i) { 1.1787 + mLists[i].SortByContentOrder(aBuilder, aCommonAncestor); 1.1788 + } 1.1789 + } 1.1790 + 1.1791 +private: 1.1792 + // This class is only used on stack, so we don't have to worry about leaking 1.1793 + // it. Don't let us be heap-allocated! 1.1794 + void* operator new(size_t sz) CPP_THROW_NEW; 1.1795 + 1.1796 + nsDisplayList mLists[6]; 1.1797 +}; 1.1798 + 1.1799 + 1.1800 +class nsDisplayImageContainer : public nsDisplayItem { 1.1801 +public: 1.1802 + typedef mozilla::layers::ImageContainer ImageContainer; 1.1803 + typedef mozilla::layers::ImageLayer ImageLayer; 1.1804 + 1.1805 + nsDisplayImageContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) 1.1806 + : nsDisplayItem(aBuilder, aFrame) 1.1807 + {} 1.1808 + 1.1809 + virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager, 1.1810 + nsDisplayListBuilder* aBuilder) = 0; 1.1811 + virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) = 0; 1.1812 + 1.1813 + virtual bool SupportsOptimizingToImage() MOZ_OVERRIDE { return true; } 1.1814 +}; 1.1815 + 1.1816 +/** 1.1817 + * Use this class to implement not-very-frequently-used display items 1.1818 + * that are not opaque, do not receive events, and are bounded by a frame's 1.1819 + * border-rect. 1.1820 + * 1.1821 + * This should not be used for display items which are created frequently, 1.1822 + * because each item is one or two pointers bigger than an item from a 1.1823 + * custom display item class could be, and fractionally slower. However it does 1.1824 + * save code size. We use this for infrequently-used item types. 1.1825 + */ 1.1826 +class nsDisplayGeneric : public nsDisplayItem { 1.1827 +public: 1.1828 + typedef void (* PaintCallback)(nsIFrame* aFrame, nsRenderingContext* aCtx, 1.1829 + const nsRect& aDirtyRect, nsPoint aFramePt); 1.1830 + 1.1831 + nsDisplayGeneric(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.1832 + PaintCallback aPaint, const char* aName, Type aType) 1.1833 + : nsDisplayItem(aBuilder, aFrame), mPaint(aPaint) 1.1834 +#ifdef MOZ_DUMP_PAINTING 1.1835 + , mName(aName) 1.1836 +#endif 1.1837 + , mType(aType) 1.1838 + { 1.1839 + MOZ_COUNT_CTOR(nsDisplayGeneric); 1.1840 + } 1.1841 +#ifdef NS_BUILD_REFCNT_LOGGING 1.1842 + virtual ~nsDisplayGeneric() { 1.1843 + MOZ_COUNT_DTOR(nsDisplayGeneric); 1.1844 + } 1.1845 +#endif 1.1846 + 1.1847 + virtual void Paint(nsDisplayListBuilder* aBuilder, 1.1848 + nsRenderingContext* aCtx) MOZ_OVERRIDE { 1.1849 + mPaint(mFrame, aCtx, mVisibleRect, ToReferenceFrame()); 1.1850 + } 1.1851 + NS_DISPLAY_DECL_NAME(mName, mType) 1.1852 + 1.1853 + virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE { 1.1854 + if (mType == nsDisplayItem::TYPE_HEADER_FOOTER) { 1.1855 + bool snap; 1.1856 + return GetBounds(aBuilder, &snap); 1.1857 + } 1.1858 + return nsRect(); 1.1859 + } 1.1860 + 1.1861 +protected: 1.1862 + PaintCallback mPaint; 1.1863 +#ifdef MOZ_DUMP_PAINTING 1.1864 + const char* mName; 1.1865 +#endif 1.1866 + Type mType; 1.1867 +}; 1.1868 + 1.1869 +/** 1.1870 + * Generic display item that can contain overflow. Use this in lieu of 1.1871 + * nsDisplayGeneric if you have a frame that should use the visual overflow 1.1872 + * rect of its frame when drawing items, instead of the frame's bounds. 1.1873 + */ 1.1874 +class nsDisplayGenericOverflow : public nsDisplayGeneric { 1.1875 + public: 1.1876 + nsDisplayGenericOverflow(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.1877 + PaintCallback aPaint, const char* aName, Type aType) 1.1878 + : nsDisplayGeneric(aBuilder, aFrame, aPaint, aName, aType) 1.1879 + { 1.1880 + MOZ_COUNT_CTOR(nsDisplayGenericOverflow); 1.1881 + } 1.1882 + #ifdef NS_BUILD_REFCNT_LOGGING 1.1883 + virtual ~nsDisplayGenericOverflow() { 1.1884 + MOZ_COUNT_DTOR(nsDisplayGenericOverflow); 1.1885 + } 1.1886 + #endif 1.1887 + 1.1888 + /** 1.1889 + * Returns the frame's visual overflow rect instead of the frame's bounds. 1.1890 + */ 1.1891 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, 1.1892 + bool* aSnap) MOZ_OVERRIDE 1.1893 + { 1.1894 + *aSnap = false; 1.1895 + return Frame()->GetVisualOverflowRect() + ToReferenceFrame(); 1.1896 + } 1.1897 +}; 1.1898 + 1.1899 +#if defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF) 1.1900 +/** 1.1901 + * This class implements painting of reflow counts. Ideally, we would simply 1.1902 + * make all the frame names be those returned by nsFrame::GetFrameName 1.1903 + * (except that tosses in the content tag name!) and support only one color 1.1904 + * and eliminate this class altogether in favor of nsDisplayGeneric, but for 1.1905 + * the time being we can't pass args to a PaintCallback, so just have a 1.1906 + * separate class to do the right thing. Sadly, this alsmo means we need to 1.1907 + * hack all leaf frame classes to handle this. 1.1908 + * 1.1909 + * XXXbz the color thing is a bit of a mess, but 0 basically means "not set" 1.1910 + * here... I could switch it all to nscolor, but why bother? 1.1911 + */ 1.1912 +class nsDisplayReflowCount : public nsDisplayItem { 1.1913 +public: 1.1914 + nsDisplayReflowCount(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.1915 + const char* aFrameName, 1.1916 + uint32_t aColor = 0) 1.1917 + : nsDisplayItem(aBuilder, aFrame), 1.1918 + mFrameName(aFrameName), 1.1919 + mColor(aColor) 1.1920 + { 1.1921 + MOZ_COUNT_CTOR(nsDisplayReflowCount); 1.1922 + } 1.1923 +#ifdef NS_BUILD_REFCNT_LOGGING 1.1924 + virtual ~nsDisplayReflowCount() { 1.1925 + MOZ_COUNT_DTOR(nsDisplayReflowCount); 1.1926 + } 1.1927 +#endif 1.1928 + 1.1929 + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE { 1.1930 + mFrame->PresContext()->PresShell()->PaintCount(mFrameName, aCtx, 1.1931 + mFrame->PresContext(), 1.1932 + mFrame, ToReferenceFrame(), 1.1933 + mColor); 1.1934 + } 1.1935 + NS_DISPLAY_DECL_NAME("nsDisplayReflowCount", TYPE_REFLOW_COUNT) 1.1936 +protected: 1.1937 + const char* mFrameName; 1.1938 + nscolor mColor; 1.1939 +}; 1.1940 + 1.1941 +#define DO_GLOBAL_REFLOW_COUNT_DSP(_name) \ 1.1942 + PR_BEGIN_MACRO \ 1.1943 + if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() && \ 1.1944 + PresContext()->PresShell()->IsPaintingFrameCounts()) { \ 1.1945 + aLists.Outlines()->AppendNewToTop( \ 1.1946 + new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name)); \ 1.1947 + } \ 1.1948 + PR_END_MACRO 1.1949 + 1.1950 +#define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color) \ 1.1951 + PR_BEGIN_MACRO \ 1.1952 + if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() && \ 1.1953 + PresContext()->PresShell()->IsPaintingFrameCounts()) { \ 1.1954 + aLists.Outlines()->AppendNewToTop( \ 1.1955 + new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name, _color)); \ 1.1956 + } \ 1.1957 + PR_END_MACRO 1.1958 + 1.1959 +/* 1.1960 + Macro to be used for classes that don't actually implement BuildDisplayList 1.1961 + */ 1.1962 +#define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super) \ 1.1963 + void BuildDisplayList(nsDisplayListBuilder* aBuilder, \ 1.1964 + const nsRect& aDirtyRect, \ 1.1965 + const nsDisplayListSet& aLists) { \ 1.1966 + DO_GLOBAL_REFLOW_COUNT_DSP(#_class); \ 1.1967 + _super::BuildDisplayList(aBuilder, aDirtyRect, aLists); \ 1.1968 + } 1.1969 + 1.1970 +#else // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF 1.1971 + 1.1972 +#define DO_GLOBAL_REFLOW_COUNT_DSP(_name) 1.1973 +#define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color) 1.1974 +#define DECL_DO_GLOBAL_REFLOW_COUNT_DSP(_class, _super) 1.1975 + 1.1976 +#endif // MOZ_REFLOW_PERF_DSP && MOZ_REFLOW_PERF 1.1977 + 1.1978 +class nsDisplayCaret : public nsDisplayItem { 1.1979 +public: 1.1980 + nsDisplayCaret(nsDisplayListBuilder* aBuilder, nsIFrame* aCaretFrame, 1.1981 + nsCaret *aCaret) 1.1982 + : nsDisplayItem(aBuilder, aCaretFrame), mCaret(aCaret) { 1.1983 + MOZ_COUNT_CTOR(nsDisplayCaret); 1.1984 + } 1.1985 +#ifdef NS_BUILD_REFCNT_LOGGING 1.1986 + virtual ~nsDisplayCaret() { 1.1987 + MOZ_COUNT_DTOR(nsDisplayCaret); 1.1988 + } 1.1989 +#endif 1.1990 + 1.1991 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE { 1.1992 + *aSnap = false; 1.1993 + // The caret returns a rect in the coordinates of mFrame. 1.1994 + return mCaret->GetCaretRect() + ToReferenceFrame(); 1.1995 + } 1.1996 + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; 1.1997 + NS_DISPLAY_DECL_NAME("Caret", TYPE_CARET) 1.1998 +protected: 1.1999 + nsRefPtr<nsCaret> mCaret; 1.2000 +}; 1.2001 + 1.2002 +/** 1.2003 + * The standard display item to paint the CSS borders of a frame. 1.2004 + */ 1.2005 +class nsDisplayBorder : public nsDisplayItem { 1.2006 +public: 1.2007 + nsDisplayBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) : 1.2008 + nsDisplayItem(aBuilder, aFrame) 1.2009 + { 1.2010 + MOZ_COUNT_CTOR(nsDisplayBorder); 1.2011 + } 1.2012 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2013 + virtual ~nsDisplayBorder() { 1.2014 + MOZ_COUNT_DTOR(nsDisplayBorder); 1.2015 + } 1.2016 +#endif 1.2017 + 1.2018 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; 1.2019 + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; 1.2020 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.2021 + nsRegion* aVisibleRegion, 1.2022 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.2023 + NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER) 1.2024 + 1.2025 + virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; 1.2026 + 1.2027 + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, 1.2028 + const nsDisplayItemGeometry* aGeometry, 1.2029 + nsRegion* aInvalidRegion) MOZ_OVERRIDE; 1.2030 + 1.2031 +protected: 1.2032 + nsRect CalculateBounds(const nsStyleBorder& aStyleBorder); 1.2033 +}; 1.2034 + 1.2035 +/** 1.2036 + * A simple display item that just renders a solid color across the 1.2037 + * specified bounds. For canvas frames (in the CSS sense) we split off the 1.2038 + * drawing of the background color into this class (from nsDisplayBackground 1.2039 + * via nsDisplayCanvasBackground). This is done so that we can always draw a 1.2040 + * background color to avoid ugly flashes of white when we can't draw a full 1.2041 + * frame tree (ie when a page is loading). The bounds can differ from the 1.2042 + * frame's bounds -- this is needed when a frame/iframe is loading and there 1.2043 + * is not yet a frame tree to go in the frame/iframe so we use the subdoc 1.2044 + * frame of the parent document as a standin. 1.2045 + */ 1.2046 +class nsDisplaySolidColor : public nsDisplayItem { 1.2047 +public: 1.2048 + nsDisplaySolidColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2049 + const nsRect& aBounds, nscolor aColor) 1.2050 + : nsDisplayItem(aBuilder, aFrame), mBounds(aBounds), mColor(aColor) 1.2051 + { 1.2052 + NS_ASSERTION(NS_GET_A(aColor) > 0, "Don't create invisible nsDisplaySolidColors!"); 1.2053 + MOZ_COUNT_CTOR(nsDisplaySolidColor); 1.2054 + } 1.2055 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2056 + virtual ~nsDisplaySolidColor() { 1.2057 + MOZ_COUNT_DTOR(nsDisplaySolidColor); 1.2058 + } 1.2059 +#endif 1.2060 + 1.2061 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; 1.2062 + 1.2063 + virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, 1.2064 + bool* aSnap) MOZ_OVERRIDE { 1.2065 + *aSnap = false; 1.2066 + nsRegion result; 1.2067 + if (NS_GET_A(mColor) == 255) { 1.2068 + result = GetBounds(aBuilder, aSnap); 1.2069 + } 1.2070 + return result; 1.2071 + } 1.2072 + 1.2073 + virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE 1.2074 + { 1.2075 + *aColor = mColor; 1.2076 + return true; 1.2077 + } 1.2078 + 1.2079 + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; 1.2080 + 1.2081 + virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE 1.2082 + { 1.2083 + return new nsDisplaySolidColorGeometry(this, aBuilder, mColor); 1.2084 + } 1.2085 + 1.2086 + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, 1.2087 + const nsDisplayItemGeometry* aGeometry, 1.2088 + nsRegion* aInvalidRegion) MOZ_OVERRIDE 1.2089 + { 1.2090 + const nsDisplaySolidColorGeometry* geometry = 1.2091 + static_cast<const nsDisplaySolidColorGeometry*>(aGeometry); 1.2092 + if (mColor != geometry->mColor) { 1.2093 + bool dummy; 1.2094 + aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &dummy)); 1.2095 + return; 1.2096 + } 1.2097 + ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion); 1.2098 + } 1.2099 + 1.2100 +#ifdef MOZ_DUMP_PAINTING 1.2101 + virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE; 1.2102 +#endif 1.2103 + 1.2104 + NS_DISPLAY_DECL_NAME("SolidColor", TYPE_SOLID_COLOR) 1.2105 + 1.2106 +private: 1.2107 + nsRect mBounds; 1.2108 + nscolor mColor; 1.2109 +}; 1.2110 + 1.2111 +/** 1.2112 + * A display item to paint one background-image for a frame. Each background 1.2113 + * image layer gets its own nsDisplayBackgroundImage. 1.2114 + */ 1.2115 +class nsDisplayBackgroundImage : public nsDisplayImageContainer { 1.2116 +public: 1.2117 + /** 1.2118 + * aLayer signifies which background layer this item represents. 1.2119 + * aIsThemed should be the value of aFrame->IsThemed. 1.2120 + * aBackgroundStyle should be the result of 1.2121 + * nsCSSRendering::FindBackground, or null if FindBackground returned false. 1.2122 + */ 1.2123 + nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2124 + uint32_t aLayer, 1.2125 + const nsStyleBackground* aBackgroundStyle); 1.2126 + virtual ~nsDisplayBackgroundImage(); 1.2127 + 1.2128 + // This will create and append new items for all the layers of the 1.2129 + // background. Returns whether we appended a themed background. 1.2130 + static bool AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuilder, 1.2131 + nsIFrame* aFrame, 1.2132 + nsDisplayList* aList); 1.2133 + 1.2134 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.2135 + LayerManager* aManager, 1.2136 + const ContainerLayerParameters& aParameters) MOZ_OVERRIDE; 1.2137 + 1.2138 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.2139 + LayerManager* aManager, 1.2140 + const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE; 1.2141 + 1.2142 + virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, 1.2143 + HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE; 1.2144 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.2145 + nsRegion* aVisibleRegion, 1.2146 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.2147 + virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, 1.2148 + bool* aSnap) MOZ_OVERRIDE; 1.2149 + virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, 1.2150 + nsIFrame* aFrame) MOZ_OVERRIDE; 1.2151 + virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE; 1.2152 + /** 1.2153 + * GetBounds() returns the background painting area. 1.2154 + */ 1.2155 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; 1.2156 + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; 1.2157 + virtual uint32_t GetPerFrameKey() MOZ_OVERRIDE; 1.2158 + NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND) 1.2159 + 1.2160 + /** 1.2161 + * Return the background positioning area. 1.2162 + * (GetBounds() returns the background painting area.) 1.2163 + * Can be called only when mBackgroundStyle is non-null. 1.2164 + */ 1.2165 + nsRect GetPositioningArea(); 1.2166 + 1.2167 + /** 1.2168 + * Returns true if existing rendered pixels of this display item may need 1.2169 + * to be redrawn if the positioning area size changes but its position does 1.2170 + * not. 1.2171 + * If false, only the changed painting area needs to be redrawn when the 1.2172 + * positioning area size changes but its position does not. 1.2173 + */ 1.2174 + bool RenderingMightDependOnPositioningAreaSizeChange(); 1.2175 + 1.2176 + virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE 1.2177 + { 1.2178 + return new nsDisplayBackgroundGeometry(this, aBuilder); 1.2179 + } 1.2180 + 1.2181 + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, 1.2182 + const nsDisplayItemGeometry* aGeometry, 1.2183 + nsRegion* aInvalidRegion) MOZ_OVERRIDE; 1.2184 + 1.2185 + virtual already_AddRefed<ImageContainer> GetContainer(LayerManager* aManager, 1.2186 + nsDisplayListBuilder *aBuilder) MOZ_OVERRIDE; 1.2187 + virtual void ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset) MOZ_OVERRIDE; 1.2188 + 1.2189 + static nsRegion GetInsideClipRegion(nsDisplayItem* aItem, nsPresContext* aPresContext, uint8_t aClip, 1.2190 + const nsRect& aRect, bool* aSnap); 1.2191 + 1.2192 +protected: 1.2193 + typedef class mozilla::layers::ImageContainer ImageContainer; 1.2194 + typedef class mozilla::layers::ImageLayer ImageLayer; 1.2195 + 1.2196 + bool TryOptimizeToImageLayer(LayerManager* aManager, nsDisplayListBuilder* aBuilder); 1.2197 + bool IsSingleFixedPositionImage(nsDisplayListBuilder* aBuilder, 1.2198 + const nsRect& aClipRect, 1.2199 + gfxRect* aDestRect); 1.2200 + nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder); 1.2201 + 1.2202 + void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx, 1.2203 + const nsRect& aBounds, nsRect* aClipRect); 1.2204 + 1.2205 + // Cache the result of nsCSSRendering::FindBackground. Always null if 1.2206 + // mIsThemed is true or if FindBackground returned false. 1.2207 + const nsStyleBackground* mBackgroundStyle; 1.2208 + /* If this background can be a simple image layer, we store the format here. */ 1.2209 + nsRefPtr<ImageContainer> mImageContainer; 1.2210 + gfxRect mDestRect; 1.2211 + /* Bounds of this display item */ 1.2212 + nsRect mBounds; 1.2213 + uint32_t mLayer; 1.2214 +}; 1.2215 + 1.2216 + 1.2217 +/** 1.2218 + * A display item to paint the native theme background for a frame. 1.2219 + */ 1.2220 +class nsDisplayThemedBackground : public nsDisplayItem { 1.2221 +public: 1.2222 + nsDisplayThemedBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame); 1.2223 + virtual ~nsDisplayThemedBackground(); 1.2224 + 1.2225 + virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, 1.2226 + HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE; 1.2227 + virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, 1.2228 + bool* aSnap) MOZ_OVERRIDE; 1.2229 + virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE; 1.2230 + /** 1.2231 + * GetBounds() returns the background painting area. 1.2232 + */ 1.2233 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; 1.2234 + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; 1.2235 + NS_DISPLAY_DECL_NAME("ThemedBackground", TYPE_THEMED_BACKGROUND) 1.2236 + 1.2237 + /** 1.2238 + * Return the background positioning area. 1.2239 + * (GetBounds() returns the background painting area.) 1.2240 + * Can be called only when mBackgroundStyle is non-null. 1.2241 + */ 1.2242 + nsRect GetPositioningArea(); 1.2243 + 1.2244 + /** 1.2245 + * Return whether our frame's document does not have the state 1.2246 + * NS_DOCUMENT_STATE_WINDOW_INACTIVE. 1.2247 + */ 1.2248 + bool IsWindowActive(); 1.2249 + 1.2250 + virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE 1.2251 + { 1.2252 + return new nsDisplayThemedBackgroundGeometry(this, aBuilder); 1.2253 + } 1.2254 + 1.2255 + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, 1.2256 + const nsDisplayItemGeometry* aGeometry, 1.2257 + nsRegion* aInvalidRegion) MOZ_OVERRIDE; 1.2258 + 1.2259 +#ifdef MOZ_DUMP_PAINTING 1.2260 + virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE; 1.2261 +#endif 1.2262 +protected: 1.2263 + nsRect GetBoundsInternal(); 1.2264 + 1.2265 + void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx, 1.2266 + const nsRect& aBounds, nsRect* aClipRect); 1.2267 + 1.2268 + nsRect mBounds; 1.2269 + nsITheme::Transparency mThemeTransparency; 1.2270 + uint8_t mAppearance; 1.2271 +}; 1.2272 + 1.2273 +class nsDisplayBackgroundColor : public nsDisplayItem 1.2274 +{ 1.2275 +public: 1.2276 + nsDisplayBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2277 + const nsStyleBackground* aBackgroundStyle, 1.2278 + nscolor aColor) 1.2279 + : nsDisplayItem(aBuilder, aFrame) 1.2280 + , mBackgroundStyle(aBackgroundStyle) 1.2281 + , mColor(aColor) 1.2282 + { } 1.2283 + 1.2284 + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; 1.2285 + 1.2286 + virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, 1.2287 + bool* aSnap) MOZ_OVERRIDE; 1.2288 + virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE; 1.2289 + virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, 1.2290 + HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE; 1.2291 + 1.2292 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE 1.2293 + { 1.2294 + *aSnap = true; 1.2295 + return nsRect(ToReferenceFrame(), Frame()->GetSize()); 1.2296 + } 1.2297 + 1.2298 + virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE 1.2299 + { 1.2300 + return new nsDisplayItemBoundsGeometry(this, aBuilder); 1.2301 + } 1.2302 + 1.2303 + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, 1.2304 + const nsDisplayItemGeometry* aGeometry, 1.2305 + nsRegion* aInvalidRegion) MOZ_OVERRIDE 1.2306 + { 1.2307 + const nsDisplayItemBoundsGeometry* geometry = static_cast<const nsDisplayItemBoundsGeometry*>(aGeometry); 1.2308 + ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion); 1.2309 + } 1.2310 + 1.2311 + NS_DISPLAY_DECL_NAME("BackgroundColor", TYPE_BACKGROUND_COLOR) 1.2312 +#ifdef MOZ_DUMP_PAINTING 1.2313 + virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE; 1.2314 +#endif 1.2315 + 1.2316 +protected: 1.2317 + const nsStyleBackground* mBackgroundStyle; 1.2318 + nscolor mColor; 1.2319 +}; 1.2320 + 1.2321 +/** 1.2322 + * The standard display item to paint the outer CSS box-shadows of a frame. 1.2323 + */ 1.2324 +class nsDisplayBoxShadowOuter : public nsDisplayItem { 1.2325 +public: 1.2326 + nsDisplayBoxShadowOuter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) 1.2327 + : nsDisplayItem(aBuilder, aFrame) 1.2328 + , mOpacity(1.0) { 1.2329 + MOZ_COUNT_CTOR(nsDisplayBoxShadowOuter); 1.2330 + mBounds = GetBoundsInternal(); 1.2331 + } 1.2332 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2333 + virtual ~nsDisplayBoxShadowOuter() { 1.2334 + MOZ_COUNT_DTOR(nsDisplayBoxShadowOuter); 1.2335 + } 1.2336 +#endif 1.2337 + 1.2338 + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; 1.2339 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; 1.2340 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.2341 + nsRegion* aVisibleRegion, 1.2342 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.2343 + NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER) 1.2344 + 1.2345 + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, 1.2346 + const nsDisplayItemGeometry* aGeometry, 1.2347 + nsRegion* aInvalidRegion) MOZ_OVERRIDE; 1.2348 + 1.2349 + virtual bool ApplyOpacity(nsDisplayListBuilder* aBuilder, 1.2350 + float aOpacity, 1.2351 + const DisplayItemClip* aClip) MOZ_OVERRIDE 1.2352 + { 1.2353 + mOpacity = aOpacity; 1.2354 + if (aClip) { 1.2355 + IntersectClip(aBuilder, *aClip); 1.2356 + } 1.2357 + return true; 1.2358 + } 1.2359 + 1.2360 + nsRect GetBoundsInternal(); 1.2361 + 1.2362 +private: 1.2363 + nsRegion mVisibleRegion; 1.2364 + nsRect mBounds; 1.2365 + float mOpacity; 1.2366 +}; 1.2367 + 1.2368 +/** 1.2369 + * The standard display item to paint the inner CSS box-shadows of a frame. 1.2370 + */ 1.2371 +class nsDisplayBoxShadowInner : public nsDisplayItem { 1.2372 +public: 1.2373 + nsDisplayBoxShadowInner(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) 1.2374 + : nsDisplayItem(aBuilder, aFrame) { 1.2375 + MOZ_COUNT_CTOR(nsDisplayBoxShadowInner); 1.2376 + } 1.2377 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2378 + virtual ~nsDisplayBoxShadowInner() { 1.2379 + MOZ_COUNT_DTOR(nsDisplayBoxShadowInner); 1.2380 + } 1.2381 +#endif 1.2382 + 1.2383 + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; 1.2384 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.2385 + nsRegion* aVisibleRegion, 1.2386 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.2387 + NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER) 1.2388 + 1.2389 + virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE 1.2390 + { 1.2391 + return new nsDisplayBoxShadowInnerGeometry(this, aBuilder); 1.2392 + } 1.2393 + 1.2394 + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, 1.2395 + const nsDisplayItemGeometry* aGeometry, 1.2396 + nsRegion* aInvalidRegion) MOZ_OVERRIDE 1.2397 + { 1.2398 + const nsDisplayBoxShadowInnerGeometry* geometry = static_cast<const nsDisplayBoxShadowInnerGeometry*>(aGeometry); 1.2399 + if (!geometry->mPaddingRect.IsEqualInterior(GetPaddingRect())) { 1.2400 + // nsDisplayBoxShadowInner is based around the padding rect, but it can 1.2401 + // touch pixels outside of this. We should invalidate the entire bounds. 1.2402 + bool snap; 1.2403 + aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &snap)); 1.2404 + } 1.2405 + } 1.2406 + 1.2407 +private: 1.2408 + nsRegion mVisibleRegion; 1.2409 +}; 1.2410 + 1.2411 +/** 1.2412 + * The standard display item to paint the CSS outline of a frame. 1.2413 + */ 1.2414 +class nsDisplayOutline : public nsDisplayItem { 1.2415 +public: 1.2416 + nsDisplayOutline(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) : 1.2417 + nsDisplayItem(aBuilder, aFrame) { 1.2418 + MOZ_COUNT_CTOR(nsDisplayOutline); 1.2419 + } 1.2420 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2421 + virtual ~nsDisplayOutline() { 1.2422 + MOZ_COUNT_DTOR(nsDisplayOutline); 1.2423 + } 1.2424 +#endif 1.2425 + 1.2426 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; 1.2427 + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; 1.2428 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.2429 + nsRegion* aVisibleRegion, 1.2430 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.2431 + NS_DISPLAY_DECL_NAME("Outline", TYPE_OUTLINE) 1.2432 +}; 1.2433 + 1.2434 +/** 1.2435 + * A class that lets you receive events within the frame bounds but never paints. 1.2436 + */ 1.2437 +class nsDisplayEventReceiver : public nsDisplayItem { 1.2438 +public: 1.2439 + nsDisplayEventReceiver(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) 1.2440 + : nsDisplayItem(aBuilder, aFrame) { 1.2441 + MOZ_COUNT_CTOR(nsDisplayEventReceiver); 1.2442 + } 1.2443 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2444 + virtual ~nsDisplayEventReceiver() { 1.2445 + MOZ_COUNT_DTOR(nsDisplayEventReceiver); 1.2446 + } 1.2447 +#endif 1.2448 + 1.2449 + virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, 1.2450 + HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE; 1.2451 + NS_DISPLAY_DECL_NAME("EventReceiver", TYPE_EVENT_RECEIVER) 1.2452 +}; 1.2453 + 1.2454 +/** 1.2455 + * A display item that tracks event-sensitive regions which will be set 1.2456 + * on the ContainerLayer that eventually contains this item. 1.2457 + * 1.2458 + * One of these is created for each stacking context and pseudo-stacking-context. 1.2459 + * It accumulates regions for event targets contributed by the border-boxes of 1.2460 + * frames in its (pseudo) stacking context. A nsDisplayLayerEventRegions 1.2461 + * eventually contributes its regions to the ThebesLayer it is placed in by 1.2462 + * FrameLayerBuilder. (We don't create a display item for every frame that 1.2463 + * could be an event target (i.e. almost all frames), because that would be 1.2464 + * high overhead.) 1.2465 + * 1.2466 + * We always make leaf layers other than ThebesLayers transparent to events. 1.2467 + * For example, an event targeting a canvas or video will actually target the 1.2468 + * background of that element, which is logically in the ThebesLayer behind the 1.2469 + * CanvasFrame or ImageFrame. We only need to create a 1.2470 + * nsDisplayLayerEventRegions when an element's background could be in front 1.2471 + * of a lower z-order element with its own layer. 1.2472 + */ 1.2473 +class nsDisplayLayerEventRegions MOZ_FINAL : public nsDisplayItem { 1.2474 +public: 1.2475 + nsDisplayLayerEventRegions(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) 1.2476 + : nsDisplayItem(aBuilder, aFrame) 1.2477 + { 1.2478 + MOZ_COUNT_CTOR(nsDisplayEventReceiver); 1.2479 + AddFrame(aBuilder, aFrame); 1.2480 + } 1.2481 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2482 + virtual ~nsDisplayLayerEventRegions() { 1.2483 + MOZ_COUNT_DTOR(nsDisplayEventReceiver); 1.2484 + } 1.2485 +#endif 1.2486 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE 1.2487 + { 1.2488 + *aSnap = false; 1.2489 + return mHitRegion.GetBounds().Union(mMaybeHitRegion.GetBounds()); 1.2490 + } 1.2491 + 1.2492 + NS_DISPLAY_DECL_NAME("LayerEventRegions", TYPE_LAYER_EVENT_REGIONS) 1.2493 + 1.2494 + // Indicate that aFrame's border-box contributes to the event regions for 1.2495 + // this layer. aFrame must have the same reference frame as mFrame. 1.2496 + void AddFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame); 1.2497 + 1.2498 + const nsRegion& HitRegion() { return mHitRegion; } 1.2499 + const nsRegion& MaybeHitRegion() { return mMaybeHitRegion; } 1.2500 + const nsRegion& DispatchToContentHitRegion() { return mDispatchToContentHitRegion; } 1.2501 + 1.2502 +private: 1.2503 + // Relative to aFrame's reference frame. 1.2504 + // These are the points that are definitely in the hit region. 1.2505 + nsRegion mHitRegion; 1.2506 + // These are points that may or may not be in the hit region. Only main-thread 1.2507 + // event handling can tell for sure (e.g. because complex shapes are present). 1.2508 + nsRegion mMaybeHitRegion; 1.2509 + // These are points that need to be dispatched to the content thread for 1.2510 + // resolution. Always contained in the union of mHitRegion and mMaybeHitRegion. 1.2511 + nsRegion mDispatchToContentHitRegion; 1.2512 +}; 1.2513 + 1.2514 +/** 1.2515 + * A class that lets you wrap a display list as a display item. 1.2516 + * 1.2517 + * GetUnderlyingFrame() is troublesome for wrapped lists because if the wrapped 1.2518 + * list has many items, it's not clear which one has the 'underlying frame'. 1.2519 + * Thus we force the creator to specify what the underlying frame is. The 1.2520 + * underlying frame should be the root of a stacking context, because sorting 1.2521 + * a list containing this item will not get at the children. 1.2522 + * 1.2523 + * In some cases (e.g., clipping) we want to wrap a list but we don't have a 1.2524 + * particular underlying frame that is a stacking context root. In that case 1.2525 + * we allow the frame to be nullptr. Callers to GetUnderlyingFrame must 1.2526 + * detect and handle this case. 1.2527 + */ 1.2528 +class nsDisplayWrapList : public nsDisplayItem { 1.2529 + // This is never instantiated directly, so no need to count constructors and 1.2530 + // destructors. 1.2531 + 1.2532 +public: 1.2533 + /** 1.2534 + * Takes all the items from aList and puts them in our list. 1.2535 + */ 1.2536 + nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2537 + nsDisplayList* aList); 1.2538 + nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2539 + nsDisplayItem* aItem); 1.2540 + nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2541 + nsDisplayItem* aItem, const nsIFrame* aReferenceFrame, const nsPoint& aToReferenceFrame); 1.2542 + nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) 1.2543 + : nsDisplayItem(aBuilder, aFrame), mOverrideZIndex(0) {} 1.2544 + virtual ~nsDisplayWrapList(); 1.2545 + /** 1.2546 + * Call this if the wrapped list is changed. 1.2547 + */ 1.2548 + virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE 1.2549 + { 1.2550 + mBounds = mList.GetBounds(aBuilder); 1.2551 + } 1.2552 + virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, 1.2553 + HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE; 1.2554 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; 1.2555 + virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, 1.2556 + bool* aSnap) MOZ_OVERRIDE; 1.2557 + virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE; 1.2558 + virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder, 1.2559 + nsIFrame* aFrame) MOZ_OVERRIDE; 1.2560 + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; 1.2561 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.2562 + nsRegion* aVisibleRegion, 1.2563 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.2564 + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE { 1.2565 + NS_WARNING("This list should already have been flattened!!!"); 1.2566 + return false; 1.2567 + } 1.2568 + virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) MOZ_OVERRIDE 1.2569 + { 1.2570 + aFrames->AppendElements(mMergedFrames); 1.2571 + } 1.2572 + virtual bool IsInvalid(nsRect& aRect) MOZ_OVERRIDE 1.2573 + { 1.2574 + if (mFrame->IsInvalid(aRect) && aRect.IsEmpty()) { 1.2575 + return true; 1.2576 + } 1.2577 + nsRect temp; 1.2578 + for (uint32_t i = 0; i < mMergedFrames.Length(); i++) { 1.2579 + if (mMergedFrames[i]->IsInvalid(temp) && temp.IsEmpty()) { 1.2580 + aRect.SetEmpty(); 1.2581 + return true; 1.2582 + } 1.2583 + aRect = aRect.Union(temp); 1.2584 + } 1.2585 + aRect += ToReferenceFrame(); 1.2586 + return !aRect.IsEmpty(); 1.2587 + } 1.2588 + NS_DISPLAY_DECL_NAME("WrapList", TYPE_WRAP_LIST) 1.2589 + 1.2590 + virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; 1.2591 + 1.2592 + virtual nsDisplayList* GetSameCoordinateSystemChildren() MOZ_OVERRIDE 1.2593 + { 1.2594 + NS_ASSERTION(mList.IsEmpty() || !ReferenceFrame() || 1.2595 + !mList.GetBottom()->ReferenceFrame() || 1.2596 + mList.GetBottom()->ReferenceFrame() == ReferenceFrame(), 1.2597 + "Children must have same reference frame"); 1.2598 + return &mList; 1.2599 + } 1.2600 + virtual nsDisplayList* GetChildren() MOZ_OVERRIDE { return &mList; } 1.2601 + 1.2602 + virtual int32_t ZIndex() const MOZ_OVERRIDE 1.2603 + { 1.2604 + return (mOverrideZIndex > 0) ? mOverrideZIndex : nsDisplayItem::ZIndex(); 1.2605 + } 1.2606 + 1.2607 + void SetOverrideZIndex(int32_t aZIndex) 1.2608 + { 1.2609 + mOverrideZIndex = aZIndex; 1.2610 + } 1.2611 + 1.2612 + /** 1.2613 + * This creates a copy of this item, but wrapping aItem instead of 1.2614 + * our existing list. Only gets called if this item returned nullptr 1.2615 + * for GetUnderlyingFrame(). aItem is guaranteed to return non-null from 1.2616 + * GetUnderlyingFrame(). 1.2617 + */ 1.2618 + virtual nsDisplayWrapList* WrapWithClone(nsDisplayListBuilder* aBuilder, 1.2619 + nsDisplayItem* aItem) { 1.2620 + NS_NOTREACHED("We never returned nullptr for GetUnderlyingFrame!"); 1.2621 + return nullptr; 1.2622 + } 1.2623 + 1.2624 +protected: 1.2625 + nsDisplayWrapList() {} 1.2626 + 1.2627 + void MergeFrom(nsDisplayWrapList* aOther) 1.2628 + { 1.2629 + mList.AppendToBottom(&aOther->mList); 1.2630 + mBounds.UnionRect(mBounds, aOther->mBounds); 1.2631 + } 1.2632 + void MergeFromTrackingMergedFrames(nsDisplayWrapList* aOther) 1.2633 + { 1.2634 + MergeFrom(aOther); 1.2635 + mMergedFrames.AppendElement(aOther->mFrame); 1.2636 + mMergedFrames.MoveElementsFrom(aOther->mMergedFrames); 1.2637 + } 1.2638 + 1.2639 + nsDisplayList mList; 1.2640 + // The frames from items that have been merged into this item, excluding 1.2641 + // this item's own frame. 1.2642 + nsTArray<nsIFrame*> mMergedFrames; 1.2643 + nsRect mBounds; 1.2644 + // Overrides the ZIndex of our frame if > 0. 1.2645 + int32_t mOverrideZIndex; 1.2646 +}; 1.2647 + 1.2648 +/** 1.2649 + * We call WrapDisplayList on the in-flow lists: BorderBackground(), 1.2650 + * BlockBorderBackgrounds() and Content(). 1.2651 + * We call WrapDisplayItem on each item of Outlines(), PositionedDescendants(), 1.2652 + * and Floats(). This is done to support special wrapping processing for frames 1.2653 + * that may not be in-flow descendants of the current frame. 1.2654 + */ 1.2655 +class nsDisplayWrapper { 1.2656 +public: 1.2657 + // This is never instantiated directly (it has pure virtual methods), so no 1.2658 + // need to count constructors and destructors. 1.2659 + 1.2660 + virtual bool WrapBorderBackground() { return true; } 1.2661 + virtual nsDisplayItem* WrapList(nsDisplayListBuilder* aBuilder, 1.2662 + nsIFrame* aFrame, nsDisplayList* aList) = 0; 1.2663 + virtual nsDisplayItem* WrapItem(nsDisplayListBuilder* aBuilder, 1.2664 + nsDisplayItem* aItem) = 0; 1.2665 + 1.2666 + nsresult WrapLists(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2667 + const nsDisplayListSet& aIn, const nsDisplayListSet& aOut); 1.2668 + nsresult WrapListsInPlace(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2669 + const nsDisplayListSet& aLists); 1.2670 +protected: 1.2671 + nsDisplayWrapper() {} 1.2672 +}; 1.2673 + 1.2674 +/** 1.2675 + * The standard display item to paint a stacking context with translucency 1.2676 + * set by the stacking context root frame's 'opacity' style. 1.2677 + */ 1.2678 +class nsDisplayOpacity : public nsDisplayWrapList { 1.2679 +public: 1.2680 + nsDisplayOpacity(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2681 + nsDisplayList* aList); 1.2682 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2683 + virtual ~nsDisplayOpacity(); 1.2684 +#endif 1.2685 + 1.2686 + virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, 1.2687 + bool* aSnap) MOZ_OVERRIDE; 1.2688 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.2689 + LayerManager* aManager, 1.2690 + const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE; 1.2691 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.2692 + LayerManager* aManager, 1.2693 + const ContainerLayerParameters& aParameters) MOZ_OVERRIDE; 1.2694 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.2695 + nsRegion* aVisibleRegion, 1.2696 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.2697 + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE; 1.2698 + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, 1.2699 + const nsDisplayItemGeometry* aGeometry, 1.2700 + nsRegion* aInvalidRegion) MOZ_OVERRIDE 1.2701 + { 1.2702 + // We don't need to compute an invalidation region since we have LayerTreeInvalidation 1.2703 + } 1.2704 + virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; 1.2705 + bool NeedsActiveLayer(); 1.2706 + NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY) 1.2707 +#ifdef MOZ_DUMP_PAINTING 1.2708 + virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE; 1.2709 +#endif 1.2710 + 1.2711 + bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; 1.2712 +}; 1.2713 + 1.2714 +class nsDisplayMixBlendMode : public nsDisplayWrapList { 1.2715 +public: 1.2716 + nsDisplayMixBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2717 + nsDisplayList* aList, uint32_t aFlags = 0); 1.2718 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2719 + virtual ~nsDisplayMixBlendMode(); 1.2720 +#endif 1.2721 + 1.2722 + nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, 1.2723 + bool* aSnap) MOZ_OVERRIDE; 1.2724 + 1.2725 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.2726 + LayerManager* aManager, 1.2727 + const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE; 1.2728 + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, 1.2729 + const nsDisplayItemGeometry* aGeometry, 1.2730 + nsRegion* aInvalidRegion) MOZ_OVERRIDE 1.2731 + { 1.2732 + // We don't need to compute an invalidation region since we have LayerTreeInvalidation 1.2733 + } 1.2734 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.2735 + LayerManager* aManager, 1.2736 + const ContainerLayerParameters& aParameters) MOZ_OVERRIDE 1.2737 + { 1.2738 + return mozilla::LAYER_INACTIVE; 1.2739 + } 1.2740 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.2741 + nsRegion* aVisibleRegion, 1.2742 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.2743 + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE; 1.2744 + NS_DISPLAY_DECL_NAME("MixBlendMode", TYPE_MIX_BLEND_MODE) 1.2745 +}; 1.2746 + 1.2747 +class nsDisplayBlendContainer : public nsDisplayWrapList { 1.2748 +public: 1.2749 + nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2750 + nsDisplayList* aList, uint32_t aFlags = 0); 1.2751 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2752 + virtual ~nsDisplayBlendContainer(); 1.2753 +#endif 1.2754 + 1.2755 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.2756 + LayerManager* aManager, 1.2757 + const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE; 1.2758 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.2759 + LayerManager* aManager, 1.2760 + const ContainerLayerParameters& aParameters) MOZ_OVERRIDE 1.2761 + { 1.2762 + return mozilla::LAYER_INACTIVE; 1.2763 + } 1.2764 + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE; 1.2765 + NS_DISPLAY_DECL_NAME("BlendContainer", TYPE_BLEND_CONTAINER) 1.2766 +}; 1.2767 + 1.2768 +/** 1.2769 + * A display item that has no purpose but to ensure its contents get 1.2770 + * their own layer. 1.2771 + */ 1.2772 +class nsDisplayOwnLayer : public nsDisplayWrapList { 1.2773 +public: 1.2774 + 1.2775 + /** 1.2776 + * nsDisplayOwnLayer constructor flags 1.2777 + */ 1.2778 + enum { 1.2779 + GENERATE_SUBDOC_INVALIDATIONS = 0x01, 1.2780 + VERTICAL_SCROLLBAR = 0x02, 1.2781 + HORIZONTAL_SCROLLBAR = 0x04, 1.2782 + GENERATE_SCROLLABLE_LAYER = 0x08 1.2783 + }; 1.2784 + 1.2785 + /** 1.2786 + * @param aFlags GENERATE_SUBDOC_INVALIDATIONS : 1.2787 + * Add UserData to the created ContainerLayer, so that invalidations 1.2788 + * for this layer are send to our nsPresContext. 1.2789 + * GENERATE_SCROLLABLE_LAYER : only valid on nsDisplaySubDocument (and 1.2790 + * subclasses), indicates this layer is to be a scrollable layer, so call 1.2791 + * RecordFrameMetrics, etc. 1.2792 + * @param aScrollTarget when VERTICAL_SCROLLBAR or HORIZONTAL_SCROLLBAR 1.2793 + * is set in the flags, this parameter should be the ViewID of the 1.2794 + * scrollable content this scrollbar is for. 1.2795 + */ 1.2796 + nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2797 + nsDisplayList* aList, uint32_t aFlags = 0, 1.2798 + ViewID aScrollTarget = mozilla::layers::FrameMetrics::NULL_SCROLL_ID); 1.2799 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2800 + virtual ~nsDisplayOwnLayer(); 1.2801 +#endif 1.2802 + 1.2803 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.2804 + LayerManager* aManager, 1.2805 + const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE; 1.2806 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.2807 + LayerManager* aManager, 1.2808 + const ContainerLayerParameters& aParameters) MOZ_OVERRIDE 1.2809 + { 1.2810 + return mozilla::LAYER_ACTIVE_FORCE; 1.2811 + } 1.2812 + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE 1.2813 + { 1.2814 + // Don't allow merging, each sublist must have its own layer 1.2815 + return false; 1.2816 + } 1.2817 + uint32_t GetFlags() { return mFlags; } 1.2818 + NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER) 1.2819 +protected: 1.2820 + uint32_t mFlags; 1.2821 + ViewID mScrollTarget; 1.2822 +}; 1.2823 + 1.2824 +/** 1.2825 + * A display item for subdocuments. This is more or less the same as nsDisplayOwnLayer, 1.2826 + * except that it always populates the FrameMetrics instance on the ContainerLayer it 1.2827 + * builds. 1.2828 + */ 1.2829 +class nsDisplaySubDocument : public nsDisplayOwnLayer { 1.2830 +public: 1.2831 + nsDisplaySubDocument(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2832 + nsDisplayList* aList, uint32_t aFlags); 1.2833 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2834 + virtual ~nsDisplaySubDocument(); 1.2835 +#endif 1.2836 + 1.2837 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.2838 + LayerManager* aManager, 1.2839 + const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE; 1.2840 + 1.2841 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; 1.2842 + 1.2843 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.2844 + nsRegion* aVisibleRegion, 1.2845 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.2846 + 1.2847 + virtual bool SetVisibleRegionOnLayer() MOZ_OVERRIDE { return !(mFlags & GENERATE_SCROLLABLE_LAYER); } 1.2848 + 1.2849 + virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; 1.2850 + 1.2851 + virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; 1.2852 + 1.2853 + NS_DISPLAY_DECL_NAME("SubDocument", TYPE_SUBDOCUMENT) 1.2854 +protected: 1.2855 + ViewID mScrollParentId; 1.2856 +}; 1.2857 + 1.2858 +/** 1.2859 + * A display item for subdocuments to capture the resolution from the presShell 1.2860 + * and ensure that it gets applied to all the right elements. This item creates 1.2861 + * a container layer. 1.2862 + */ 1.2863 +class nsDisplayResolution : public nsDisplaySubDocument { 1.2864 +public: 1.2865 + nsDisplayResolution(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2866 + nsDisplayList* aList, uint32_t aFlags); 1.2867 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2868 + virtual ~nsDisplayResolution(); 1.2869 +#endif 1.2870 + 1.2871 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.2872 + LayerManager* aManager, 1.2873 + const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE; 1.2874 + NS_DISPLAY_DECL_NAME("Resolution", TYPE_RESOLUTION) 1.2875 +}; 1.2876 + 1.2877 +/** 1.2878 + * A display item used to represent sticky position elements. The contents 1.2879 + * gets its own layer and creates a stacking context, and the layer will have 1.2880 + * position-related metadata set on it. 1.2881 + */ 1.2882 +class nsDisplayStickyPosition : public nsDisplayOwnLayer { 1.2883 +public: 1.2884 + nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.2885 + nsDisplayList* aList); 1.2886 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2887 + virtual ~nsDisplayStickyPosition(); 1.2888 +#endif 1.2889 + 1.2890 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.2891 + LayerManager* aManager, 1.2892 + const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE; 1.2893 + NS_DISPLAY_DECL_NAME("StickyPosition", TYPE_STICKY_POSITION) 1.2894 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.2895 + LayerManager* aManager, 1.2896 + const ContainerLayerParameters& aParameters) MOZ_OVERRIDE 1.2897 + { 1.2898 + return mozilla::LAYER_ACTIVE; 1.2899 + } 1.2900 + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE; 1.2901 +}; 1.2902 + 1.2903 +/** 1.2904 + * This potentially creates a layer for the given list of items, whose 1.2905 + * visibility is determined by the displayport for the given frame instead of 1.2906 + * what is passed in to ComputeVisibility. 1.2907 + * 1.2908 + * Here in content, we can use this to render more content than is actually 1.2909 + * visible. Then, the compositing process can manipulate the generated layer 1.2910 + * through transformations so that asynchronous scrolling can be implemented. 1.2911 + * 1.2912 + * Note that setting the displayport will not change any hit testing! The 1.2913 + * content process will know nothing about what the user is actually seeing, 1.2914 + * so it can only do hit testing for what is supposed to be the visible region. 1.2915 + * 1.2916 + * It is possible for scroll boxes to have content that can be both above and 1.2917 + * below content outside of the scroll box. We cannot create layers for these 1.2918 + * cases. This is accomplished by wrapping display items with 1.2919 + * nsDisplayScrollLayers. nsDisplayScrollLayers with the same scroll frame will 1.2920 + * be merged together. If more than one nsDisplayScrollLayer exists after 1.2921 + * merging, all nsDisplayScrollLayers will be flattened out so that no new 1.2922 + * layer is created at all. 1.2923 + */ 1.2924 +class nsDisplayScrollLayer : public nsDisplayWrapList 1.2925 +{ 1.2926 +public: 1.2927 + /** 1.2928 + * @param aScrolledFrame This will determine what the displayport is. It should be 1.2929 + * the root content frame of the scrolled area. Note 1.2930 + * that nsDisplayScrollLayer will expect for 1.2931 + * ScrollLayerCount to be defined on aScrolledFrame. 1.2932 + * @param aScrollFrame The viewport frame you see this content through. 1.2933 + */ 1.2934 + nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, nsDisplayList* aList, 1.2935 + nsIFrame* aForFrame, nsIFrame* aScrolledFrame, 1.2936 + nsIFrame* aScrollFrame); 1.2937 + nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, 1.2938 + nsIFrame* aForFrame, nsIFrame* aScrolledFrame, 1.2939 + nsIFrame* aScrollFrame); 1.2940 + nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder, 1.2941 + nsIFrame* aForFrame, nsIFrame* aScrolledFrame, 1.2942 + nsIFrame* aScrollFrame); 1.2943 + NS_DISPLAY_DECL_NAME("ScrollLayer", TYPE_SCROLL_LAYER) 1.2944 + 1.2945 +#ifdef NS_BUILD_REFCNT_LOGGING 1.2946 + virtual ~nsDisplayScrollLayer(); 1.2947 +#endif 1.2948 + 1.2949 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; 1.2950 + 1.2951 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.2952 + LayerManager* aManager, 1.2953 + const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE; 1.2954 + 1.2955 + virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; 1.2956 + 1.2957 + virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, 1.2958 + bool* aSnap) MOZ_OVERRIDE { 1.2959 + *aSnap = false; 1.2960 + return nsRegion(); 1.2961 + } 1.2962 + 1.2963 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.2964 + nsRegion* aVisibleRegion, 1.2965 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.2966 + 1.2967 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.2968 + LayerManager* aManager, 1.2969 + const ContainerLayerParameters& aParameters) MOZ_OVERRIDE; 1.2970 + 1.2971 + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, 1.2972 + nsDisplayItem* aItem) MOZ_OVERRIDE; 1.2973 + 1.2974 + virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; 1.2975 + 1.2976 + // Get the number of nsDisplayScrollLayers for a scroll frame. Note that this 1.2977 + // number does not include nsDisplayScrollInfoLayers. If this number is not 1 1.2978 + // after merging, all the nsDisplayScrollLayers should flatten away. 1.2979 + intptr_t GetScrollLayerCount(); 1.2980 + 1.2981 + virtual nsIFrame* GetScrollFrame() { return mScrollFrame; } 1.2982 + virtual nsIFrame* GetScrolledFrame() { return mScrolledFrame; } 1.2983 + 1.2984 + virtual bool SetVisibleRegionOnLayer() MOZ_OVERRIDE { return false; } 1.2985 + 1.2986 +#ifdef MOZ_DUMP_PAINTING 1.2987 + virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE; 1.2988 +#endif 1.2989 + 1.2990 +protected: 1.2991 + nsIFrame* mScrollFrame; 1.2992 + nsIFrame* mScrolledFrame; 1.2993 + ViewID mScrollParentId; 1.2994 +}; 1.2995 + 1.2996 +/** 1.2997 + * Like nsDisplayScrollLayer, but only has metadata on the scroll frame. This 1.2998 + * creates a layer that has no Thebes child layer, but still allows the 1.2999 + * compositor process to know of the scroll frame's existence. 1.3000 + * 1.3001 + * After visibility computation, nsDisplayScrollInfoLayers should only exist if 1.3002 + * nsDisplayScrollLayers were all flattened away. 1.3003 + * 1.3004 + * Important!! Add info layers to the bottom of the list so they are only 1.3005 + * considered after the others have flattened out! 1.3006 + */ 1.3007 +class nsDisplayScrollInfoLayer : public nsDisplayScrollLayer 1.3008 +{ 1.3009 +public: 1.3010 + nsDisplayScrollInfoLayer(nsDisplayListBuilder* aBuilder, 1.3011 + nsIFrame* aScrolledFrame, nsIFrame* aScrollFrame); 1.3012 + NS_DISPLAY_DECL_NAME("ScrollInfoLayer", TYPE_SCROLL_INFO_LAYER) 1.3013 + 1.3014 + virtual ~nsDisplayScrollInfoLayer(); 1.3015 + 1.3016 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; 1.3017 + 1.3018 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.3019 + LayerManager* aManager, 1.3020 + const ContainerLayerParameters& aParameters) MOZ_OVERRIDE; 1.3021 + virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE 1.3022 + { return true; } 1.3023 + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, 1.3024 + nsDisplayItem* aItem) MOZ_OVERRIDE; 1.3025 + 1.3026 + virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; 1.3027 +}; 1.3028 + 1.3029 +/** 1.3030 + * nsDisplayZoom is used for subdocuments that have a different full zoom than 1.3031 + * their parent documents. This item creates a container layer. 1.3032 + */ 1.3033 +class nsDisplayZoom : public nsDisplaySubDocument { 1.3034 +public: 1.3035 + /** 1.3036 + * @param aFrame is the root frame of the subdocument. 1.3037 + * @param aList contains the display items for the subdocument. 1.3038 + * @param aAPD is the app units per dev pixel ratio of the subdocument. 1.3039 + * @param aParentAPD is the app units per dev pixel ratio of the parent 1.3040 + * document. 1.3041 + * @param aFlags GENERATE_SUBDOC_INVALIDATIONS : 1.3042 + * Add UserData to the created ContainerLayer, so that invalidations 1.3043 + * for this layer are send to our nsPresContext. 1.3044 + */ 1.3045 + nsDisplayZoom(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.3046 + nsDisplayList* aList, 1.3047 + int32_t aAPD, int32_t aParentAPD, 1.3048 + uint32_t aFlags = 0); 1.3049 +#ifdef NS_BUILD_REFCNT_LOGGING 1.3050 + virtual ~nsDisplayZoom(); 1.3051 +#endif 1.3052 + 1.3053 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE; 1.3054 + virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE; 1.3055 + virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, 1.3056 + HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE; 1.3057 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.3058 + nsRegion* aVisibleRegion, 1.3059 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.3060 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.3061 + LayerManager* aManager, 1.3062 + const ContainerLayerParameters& aParameters) MOZ_OVERRIDE 1.3063 + { 1.3064 + return mozilla::LAYER_ACTIVE; 1.3065 + } 1.3066 + NS_DISPLAY_DECL_NAME("Zoom", TYPE_ZOOM) 1.3067 + 1.3068 + // Get the app units per dev pixel ratio of the child document. 1.3069 + int32_t GetChildAppUnitsPerDevPixel() { return mAPD; } 1.3070 + // Get the app units per dev pixel ratio of the parent document. 1.3071 + int32_t GetParentAppUnitsPerDevPixel() { return mParentAPD; } 1.3072 + 1.3073 +private: 1.3074 + int32_t mAPD, mParentAPD; 1.3075 +}; 1.3076 + 1.3077 +/** 1.3078 + * A display item to paint a stacking context with effects 1.3079 + * set by the stacking context root frame's style. 1.3080 + */ 1.3081 +class nsDisplaySVGEffects : public nsDisplayWrapList { 1.3082 +public: 1.3083 + nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, 1.3084 + nsDisplayList* aList); 1.3085 +#ifdef NS_BUILD_REFCNT_LOGGING 1.3086 + virtual ~nsDisplaySVGEffects(); 1.3087 +#endif 1.3088 + 1.3089 + virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, 1.3090 + bool* aSnap) MOZ_OVERRIDE; 1.3091 + virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, 1.3092 + HitTestState* aState, 1.3093 + nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE; 1.3094 + virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, 1.3095 + bool* aSnap) MOZ_OVERRIDE { 1.3096 + *aSnap = false; 1.3097 + return mEffectsBounds + ToReferenceFrame(); 1.3098 + } 1.3099 + virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder, 1.3100 + nsRegion* aVisibleRegion, 1.3101 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.3102 + virtual bool TryMerge(nsDisplayListBuilder* aBuilder, 1.3103 + nsDisplayItem* aItem) MOZ_OVERRIDE; 1.3104 + NS_DISPLAY_DECL_NAME("SVGEffects", TYPE_SVG_EFFECTS) 1.3105 + 1.3106 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.3107 + LayerManager* aManager, 1.3108 + const ContainerLayerParameters& aParameters) MOZ_OVERRIDE; 1.3109 + 1.3110 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.3111 + LayerManager* aManager, 1.3112 + const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE; 1.3113 + 1.3114 + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, 1.3115 + const nsDisplayItemGeometry* aGeometry, 1.3116 + nsRegion* aInvalidRegion) MOZ_OVERRIDE 1.3117 + { 1.3118 + // We don't need to compute an invalidation region since we have LayerTreeInvalidation 1.3119 + } 1.3120 + 1.3121 + void PaintAsLayer(nsDisplayListBuilder* aBuilder, 1.3122 + nsRenderingContext* aCtx, 1.3123 + LayerManager* aManager); 1.3124 + 1.3125 +#ifdef MOZ_DUMP_PAINTING 1.3126 + void PrintEffects(nsACString& aTo); 1.3127 +#endif 1.3128 + 1.3129 +private: 1.3130 + // relative to mFrame 1.3131 + nsRect mEffectsBounds; 1.3132 +}; 1.3133 + 1.3134 +/* A display item that applies a transformation to all of its descendant 1.3135 + * elements. This wrapper should only be used if there is a transform applied 1.3136 + * to the root element. 1.3137 + * 1.3138 + * The reason that a "bounds" rect is involved in transform calculations is 1.3139 + * because CSS-transforms allow percentage values for the x and y components 1.3140 + * of <translation-value>s, where percentages are percentages of the element's 1.3141 + * border box. 1.3142 + * 1.3143 + * INVARIANT: The wrapped frame is transformed or we supplied a transform getter 1.3144 + * function. 1.3145 + * INVARIANT: The wrapped frame is non-null. 1.3146 + */ 1.3147 +class nsDisplayTransform: public nsDisplayItem 1.3148 +{ 1.3149 +public: 1.3150 + /** 1.3151 + * Returns a matrix (in pixels) for the current frame. The matrix should be relative to 1.3152 + * the current frame's coordinate space. 1.3153 + * 1.3154 + * @param aFrame The frame to compute the transform for. 1.3155 + * @param aAppUnitsPerPixel The number of app units per graphics unit. 1.3156 + */ 1.3157 + typedef gfx3DMatrix (* ComputeTransformFunction)(nsIFrame* aFrame, float aAppUnitsPerPixel); 1.3158 + 1.3159 + /* Constructor accepts a display list, empties it, and wraps it up. It also 1.3160 + * ferries the underlying frame to the nsDisplayItem constructor. 1.3161 + */ 1.3162 + nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame, 1.3163 + nsDisplayList *aList, uint32_t aIndex = 0); 1.3164 + nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame, 1.3165 + nsDisplayItem *aItem, uint32_t aIndex = 0); 1.3166 + nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame, 1.3167 + nsDisplayList *aList, ComputeTransformFunction aTransformGetter, uint32_t aIndex = 0); 1.3168 + 1.3169 +#ifdef NS_BUILD_REFCNT_LOGGING 1.3170 + virtual ~nsDisplayTransform() 1.3171 + { 1.3172 + MOZ_COUNT_DTOR(nsDisplayTransform); 1.3173 + } 1.3174 +#endif 1.3175 + 1.3176 + NS_DISPLAY_DECL_NAME("nsDisplayTransform", TYPE_TRANSFORM) 1.3177 + 1.3178 + virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE 1.3179 + { 1.3180 + if (mStoredList.GetComponentAlphaBounds(aBuilder).IsEmpty()) 1.3181 + return nsRect(); 1.3182 + bool snap; 1.3183 + return GetBounds(aBuilder, &snap); 1.3184 + } 1.3185 + 1.3186 + virtual nsDisplayList* GetChildren() MOZ_OVERRIDE { return mStoredList.GetChildren(); } 1.3187 + 1.3188 + virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect, 1.3189 + HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE; 1.3190 + virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap) MOZ_OVERRIDE; 1.3191 + virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder *aBuilder, 1.3192 + bool* aSnap) MOZ_OVERRIDE; 1.3193 + virtual bool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor) MOZ_OVERRIDE; 1.3194 + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, 1.3195 + LayerManager* aManager, 1.3196 + const ContainerLayerParameters& aParameters) MOZ_OVERRIDE; 1.3197 + virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder, 1.3198 + LayerManager* aManager, 1.3199 + const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE; 1.3200 + virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; 1.3201 + virtual bool ComputeVisibility(nsDisplayListBuilder *aBuilder, 1.3202 + nsRegion *aVisibleRegion, 1.3203 + const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE; 1.3204 + virtual bool TryMerge(nsDisplayListBuilder *aBuilder, nsDisplayItem *aItem) MOZ_OVERRIDE; 1.3205 + 1.3206 + virtual uint32_t GetPerFrameKey() MOZ_OVERRIDE { return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); } 1.3207 + 1.3208 + virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder, 1.3209 + const nsDisplayItemGeometry* aGeometry, 1.3210 + nsRegion* aInvalidRegion) MOZ_OVERRIDE 1.3211 + { 1.3212 + // We don't need to compute an invalidation region since we have LayerTreeInvalidation 1.3213 + } 1.3214 + 1.3215 + virtual const nsIFrame* ReferenceFrameForChildren() const MOZ_OVERRIDE { 1.3216 + // If we were created using a transform-getter, then we don't 1.3217 + // belong to a transformed frame, and aren't a reference frame 1.3218 + // for our children. 1.3219 + if (!mTransformGetter) { 1.3220 + return mFrame; 1.3221 + } 1.3222 + return nsDisplayItem::ReferenceFrameForChildren(); 1.3223 + } 1.3224 + 1.3225 + enum { 1.3226 + INDEX_MAX = UINT32_MAX >> nsDisplayItem::TYPE_BITS 1.3227 + }; 1.3228 + 1.3229 + const gfx3DMatrix& GetTransform(); 1.3230 + 1.3231 + float GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsPoint& aPoint); 1.3232 + 1.3233 + /** 1.3234 + * TransformRect takes in as parameters a rectangle (in aFrame's coordinate 1.3235 + * space) and returns the smallest rectangle (in aFrame's coordinate space) 1.3236 + * containing the transformed image of that rectangle. That is, it takes 1.3237 + * the four corners of the rectangle, transforms them according to the 1.3238 + * matrix associated with the specified frame, then returns the smallest 1.3239 + * rectangle containing the four transformed points. 1.3240 + * 1.3241 + * @param untransformedBounds The rectangle (in app units) to transform. 1.3242 + * @param aFrame The frame whose transformation should be applied. This 1.3243 + * function raises an assertion if aFrame is null or doesn't have a 1.3244 + * transform applied to it. 1.3245 + * @param aOrigin The origin of the transform relative to aFrame's local 1.3246 + * coordinate space. 1.3247 + * @param aBoundsOverride (optional) Rather than using the frame's computed 1.3248 + * bounding rect as frame bounds, use this rectangle instead. Pass 1.3249 + * nullptr (or nothing at all) to use the default. 1.3250 + */ 1.3251 + static nsRect TransformRect(const nsRect &aUntransformedBounds, 1.3252 + const nsIFrame* aFrame, 1.3253 + const nsPoint &aOrigin, 1.3254 + const nsRect* aBoundsOverride = nullptr); 1.3255 + 1.3256 + static nsRect TransformRectOut(const nsRect &aUntransformedBounds, 1.3257 + const nsIFrame* aFrame, 1.3258 + const nsPoint &aOrigin, 1.3259 + const nsRect* aBoundsOverride = nullptr); 1.3260 + 1.3261 + /* UntransformRect is like TransformRect, except that it inverts the 1.3262 + * transform. 1.3263 + */ 1.3264 + static bool UntransformRect(const nsRect &aTransformedBounds, 1.3265 + const nsRect &aChildBounds, 1.3266 + const nsIFrame* aFrame, 1.3267 + const nsPoint &aOrigin, 1.3268 + nsRect *aOutRect); 1.3269 + 1.3270 + bool UntransformVisibleRect(nsDisplayListBuilder* aBuilder, 1.3271 + nsRect* aOutRect); 1.3272 + 1.3273 + static gfxPoint3D GetDeltaToTransformOrigin(const nsIFrame* aFrame, 1.3274 + float aAppUnitsPerPixel, 1.3275 + const nsRect* aBoundsOverride); 1.3276 + 1.3277 + static gfxPoint3D GetDeltaToPerspectiveOrigin(const nsIFrame* aFrame, 1.3278 + float aAppUnitsPerPixel); 1.3279 + 1.3280 + /** 1.3281 + * Returns the bounds of a frame as defined for resolving percentage 1.3282 + * <translation-value>s in CSS transforms. If 1.3283 + * UNIFIED_CONTINUATIONS is not defined, this is simply the frame's bounding 1.3284 + * rectangle, translated to the origin. Otherwise, returns the smallest 1.3285 + * rectangle containing a frame and all of its continuations. For example, 1.3286 + * if there is a <span> element with several continuations split over 1.3287 + * several lines, this function will return the rectangle containing all of 1.3288 + * those continuations. This rectangle is relative to the origin of the 1.3289 + * frame's local coordinate space. 1.3290 + * 1.3291 + * @param aFrame The frame to get the bounding rect for. 1.3292 + * @return The frame's bounding rect, as described above. 1.3293 + */ 1.3294 + static nsRect GetFrameBoundsForTransform(const nsIFrame* aFrame); 1.3295 + 1.3296 + struct FrameTransformProperties 1.3297 + { 1.3298 + FrameTransformProperties(const nsIFrame* aFrame, 1.3299 + float aAppUnitsPerPixel, 1.3300 + const nsRect* aBoundsOverride); 1.3301 + FrameTransformProperties(nsCSSValueSharedList* aTransformList, 1.3302 + const gfxPoint3D& aToTransformOrigin, 1.3303 + const gfxPoint3D& aToPerspectiveOrigin, 1.3304 + nscoord aChildPerspective) 1.3305 + : mFrame(nullptr) 1.3306 + , mTransformList(aTransformList) 1.3307 + , mToTransformOrigin(aToTransformOrigin) 1.3308 + , mToPerspectiveOrigin(aToPerspectiveOrigin) 1.3309 + , mChildPerspective(aChildPerspective) 1.3310 + {} 1.3311 + 1.3312 + const nsIFrame* mFrame; 1.3313 + nsRefPtr<nsCSSValueSharedList> mTransformList; 1.3314 + const gfxPoint3D mToTransformOrigin; 1.3315 + const gfxPoint3D mToPerspectiveOrigin; 1.3316 + nscoord mChildPerspective; 1.3317 + }; 1.3318 + 1.3319 + /** 1.3320 + * Given a frame with the -moz-transform property or an SVG transform, 1.3321 + * returns the transformation matrix for that frame. 1.3322 + * 1.3323 + * @param aFrame The frame to get the matrix from. 1.3324 + * @param aOrigin Relative to which point this transform should be applied. 1.3325 + * @param aAppUnitsPerPixel The number of app units per graphics unit. 1.3326 + * @param aBoundsOverride [optional] If this is nullptr (the default), the 1.3327 + * computation will use the value of GetFrameBoundsForTransform(aFrame) 1.3328 + * for the frame's bounding rectangle. Otherwise, it will use the 1.3329 + * value of aBoundsOverride. This is mostly for internal use and in 1.3330 + * most cases you will not need to specify a value. 1.3331 + */ 1.3332 + static gfx3DMatrix GetResultingTransformMatrix(const nsIFrame* aFrame, 1.3333 + const nsPoint& aOrigin, 1.3334 + float aAppUnitsPerPixel, 1.3335 + const nsRect* aBoundsOverride = nullptr, 1.3336 + nsIFrame** aOutAncestor = nullptr); 1.3337 + static gfx3DMatrix GetResultingTransformMatrix(const FrameTransformProperties& aProperties, 1.3338 + const nsPoint& aOrigin, 1.3339 + float aAppUnitsPerPixel, 1.3340 + const nsRect* aBoundsOverride = nullptr, 1.3341 + nsIFrame** aOutAncestor = nullptr); 1.3342 + /** 1.3343 + * Return true when we should try to prerender the entire contents of the 1.3344 + * transformed frame even when it's not completely visible (yet). 1.3345 + */ 1.3346 + static bool ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder, 1.3347 + nsIFrame* aFrame, 1.3348 + bool aLogAnimations = false); 1.3349 + bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE; 1.3350 + 1.3351 + virtual bool SetVisibleRegionOnLayer() MOZ_OVERRIDE { return false; } 1.3352 + 1.3353 +private: 1.3354 + static gfx3DMatrix GetResultingTransformMatrixInternal(const FrameTransformProperties& aProperties, 1.3355 + const nsPoint& aOrigin, 1.3356 + float aAppUnitsPerPixel, 1.3357 + const nsRect* aBoundsOverride, 1.3358 + nsIFrame** aOutAncestor); 1.3359 + 1.3360 + nsDisplayWrapList mStoredList; 1.3361 + gfx3DMatrix mTransform; 1.3362 + ComputeTransformFunction mTransformGetter; 1.3363 + uint32_t mIndex; 1.3364 +}; 1.3365 + 1.3366 +/** 1.3367 + * This class adds basic support for limiting the rendering to the part inside 1.3368 + * the specified edges. It's a base class for the display item classes that 1.3369 + * does the actual work. The two members, mLeftEdge and mRightEdge, are 1.3370 + * relative to the edges of the frame's scrollable overflow rectangle and is 1.3371 + * the amount to suppress on each side. 1.3372 + * 1.3373 + * Setting none, both or only one edge is allowed. 1.3374 + * The values must be non-negative. 1.3375 + * The default value for both edges is zero, which means everything is painted. 1.3376 + */ 1.3377 +class nsCharClipDisplayItem : public nsDisplayItem { 1.3378 +public: 1.3379 + nsCharClipDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) 1.3380 + : nsDisplayItem(aBuilder, aFrame), mLeftEdge(0), mRightEdge(0) {} 1.3381 + 1.3382 + nsCharClipDisplayItem(nsIFrame* aFrame) 1.3383 + : nsDisplayItem(aFrame) {} 1.3384 + 1.3385 + struct ClipEdges { 1.3386 + ClipEdges(const nsDisplayItem& aItem, 1.3387 + nscoord aLeftEdge, nscoord aRightEdge) { 1.3388 + nsRect r = aItem.Frame()->GetScrollableOverflowRect() + 1.3389 + aItem.ToReferenceFrame(); 1.3390 + mX = aLeftEdge > 0 ? r.x + aLeftEdge : nscoord_MIN; 1.3391 + mXMost = aRightEdge > 0 ? std::max(r.XMost() - aRightEdge, mX) : nscoord_MAX; 1.3392 + } 1.3393 + void Intersect(nscoord* aX, nscoord* aWidth) const { 1.3394 + nscoord xmost1 = *aX + *aWidth; 1.3395 + *aX = std::max(*aX, mX); 1.3396 + *aWidth = std::max(std::min(xmost1, mXMost) - *aX, 0); 1.3397 + } 1.3398 + nscoord mX; 1.3399 + nscoord mXMost; 1.3400 + }; 1.3401 + 1.3402 + ClipEdges Edges() const { return ClipEdges(*this, mLeftEdge, mRightEdge); } 1.3403 + 1.3404 + static nsCharClipDisplayItem* CheckCast(nsDisplayItem* aItem) { 1.3405 + nsDisplayItem::Type t = aItem->GetType(); 1.3406 + return (t == nsDisplayItem::TYPE_TEXT || 1.3407 + t == nsDisplayItem::TYPE_TEXT_DECORATION || 1.3408 + t == nsDisplayItem::TYPE_TEXT_SHADOW) 1.3409 + ? static_cast<nsCharClipDisplayItem*>(aItem) : nullptr; 1.3410 + } 1.3411 + 1.3412 + nscoord mLeftEdge; // length from the left side 1.3413 + nscoord mRightEdge; // length from the right side 1.3414 +}; 1.3415 + 1.3416 +#endif /*NSDISPLAYLIST_H_*/