Bug 1675375 Part 7: Update expectations in helper_hittest_clippath.html. r=botond
[gecko.git] / layout / painting / nsDisplayListInvalidation.h
blob382b5ff038d0ad9d60b30e441805b0dac161b7a0
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef NSDISPLAYLISTINVALIDATION_H_
8 #define NSDISPLAYLISTINVALIDATION_H_
10 #include "mozilla/Attributes.h"
11 #include "FrameLayerBuilder.h"
12 #include "nsRect.h"
13 #include "nsColor.h"
14 #include "gfxRect.h"
15 #include "mozilla/gfx/MatrixFwd.h"
17 class nsDisplayBackgroundImage;
18 class nsCharClipDisplayItem;
19 class nsDisplayItem;
20 class nsDisplayListBuilder;
21 class nsDisplayTableItem;
22 class nsDisplayThemedBackground;
23 class nsDisplayEffectsBase;
24 class nsDisplayMasksAndClipPaths;
25 class nsDisplayFilters;
27 namespace mozilla {
28 namespace gfx {
29 struct sRGBColor;
31 } // namespace mozilla
33 /**
34 * This stores the geometry of an nsDisplayItem, and the area
35 * that will be affected when painting the item.
37 * It is used to retain information about display items so they
38 * can be compared against new display items in the next paint.
40 class nsDisplayItemGeometry {
41 public:
42 nsDisplayItemGeometry(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder);
43 virtual ~nsDisplayItemGeometry();
45 /**
46 * Compute the area required to be invalidated if this
47 * display item is removed.
49 const nsRect& ComputeInvalidationRegion() { return mBounds; }
51 /**
52 * Shifts all retained areas of the nsDisplayItemGeometry by the given offset.
54 * This is used to compensate for scrolling, since the destination buffer
55 * can scroll without requiring a full repaint.
57 * @param aOffset Offset to shift by.
59 virtual void MoveBy(const nsPoint& aOffset) { mBounds.MoveBy(aOffset); }
61 virtual bool InvalidateForSyncDecodeImages() const { return false; }
63 /**
64 * Bounds of the display item
66 nsRect mBounds;
69 /**
70 * A default geometry implementation, used by nsDisplayItem. Retains
71 * and compares the bounds, and border rect.
73 * This should be sufficient for the majority of display items.
75 class nsDisplayItemGenericGeometry : public nsDisplayItemGeometry {
76 public:
77 nsDisplayItemGenericGeometry(nsDisplayItem* aItem,
78 nsDisplayListBuilder* aBuilder);
80 void MoveBy(const nsPoint& aOffset) override;
82 nsRect mBorderRect;
85 bool ShouldSyncDecodeImages(nsDisplayListBuilder* aBuilder);
87 /**
88 * nsImageGeometryMixin is a mixin for geometry items that draw images.
89 * Geometry items that include this mixin can track drawing results and use
90 * that information to inform invalidation decisions.
92 * This mixin uses CRTP; its template parameter should be the type of the class
93 * that is inheriting from it. See nsDisplayItemGenericImageGeometry for an
94 * example.
96 template <typename T>
97 class nsImageGeometryMixin {
98 public:
99 nsImageGeometryMixin(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder)
100 : mLastDrawResult(mozilla::image::ImgDrawResult::NOT_READY),
101 mWaitingForPaint(false) {
102 // Transfer state from the previous version of this geometry item.
103 auto lastGeometry = static_cast<T*>(
104 mozilla::FrameLayerBuilder::GetMostRecentGeometry(aItem));
105 if (lastGeometry) {
106 mLastDrawResult = lastGeometry->mLastDrawResult;
107 mWaitingForPaint = lastGeometry->mWaitingForPaint;
110 // If our display item is going to invalidate to trigger sync decoding of
111 // images, mark ourselves as waiting for a paint. If we actually get
112 // painted, UpdateDrawResult will get called, and we'll clear the flag.
113 if (ShouldSyncDecodeImages(aBuilder) &&
114 ShouldInvalidateToSyncDecodeImages()) {
115 mWaitingForPaint = true;
119 static void UpdateDrawResult(nsDisplayItem* aItem,
120 mozilla::image::ImgDrawResult aResult) {
121 MOZ_ASSERT(aResult != mozilla::image::ImgDrawResult::NOT_SUPPORTED,
122 "ImgDrawResult::NOT_SUPPORTED should be handled already!");
124 auto lastGeometry = static_cast<T*>(
125 mozilla::FrameLayerBuilder::GetMostRecentGeometry(aItem));
126 if (lastGeometry) {
127 lastGeometry->mLastDrawResult = aResult;
128 lastGeometry->mWaitingForPaint = false;
132 bool ShouldInvalidateToSyncDecodeImages() const {
133 if (mWaitingForPaint) {
134 // We previously invalidated for sync decoding and haven't gotten painted
135 // since them. This suggests that our display item is completely occluded
136 // and there's no point in invalidating again - and because the reftest
137 // harness takes a new snapshot every time we invalidate, doing so might
138 // lead to an invalidation loop if we're in a reftest.
139 return false;
142 if (mLastDrawResult == mozilla::image::ImgDrawResult::SUCCESS ||
143 mLastDrawResult == mozilla::image::ImgDrawResult::BAD_IMAGE) {
144 return false;
147 return true;
150 private:
151 mozilla::image::ImgDrawResult mLastDrawResult;
152 bool mWaitingForPaint;
156 * nsDisplayItemGenericImageGeometry is a generic geometry item class that
157 * includes nsImageGeometryMixin.
159 * This should be sufficient for most display items that draw images.
161 class nsDisplayItemGenericImageGeometry
162 : public nsDisplayItemGenericGeometry,
163 public nsImageGeometryMixin<nsDisplayItemGenericImageGeometry> {
164 public:
165 nsDisplayItemGenericImageGeometry(nsDisplayItem* aItem,
166 nsDisplayListBuilder* aBuilder)
167 : nsDisplayItemGenericGeometry(aItem, aBuilder),
168 nsImageGeometryMixin(aItem, aBuilder) {}
170 bool InvalidateForSyncDecodeImages() const override {
171 return ShouldInvalidateToSyncDecodeImages();
175 class nsDisplayItemBoundsGeometry : public nsDisplayItemGeometry {
176 public:
177 nsDisplayItemBoundsGeometry(nsDisplayItem* aItem,
178 nsDisplayListBuilder* aBuilder);
180 bool mHasRoundedCorners;
183 class nsDisplayBorderGeometry
184 : public nsDisplayItemGeometry,
185 public nsImageGeometryMixin<nsDisplayBorderGeometry> {
186 public:
187 nsDisplayBorderGeometry(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder);
189 bool InvalidateForSyncDecodeImages() const override {
190 return ShouldInvalidateToSyncDecodeImages();
194 class nsDisplayBackgroundGeometry
195 : public nsDisplayItemGeometry,
196 public nsImageGeometryMixin<nsDisplayBackgroundGeometry> {
197 public:
198 nsDisplayBackgroundGeometry(nsDisplayBackgroundImage* aItem,
199 nsDisplayListBuilder* aBuilder);
201 void MoveBy(const nsPoint& aOffset) override;
203 bool InvalidateForSyncDecodeImages() const override {
204 return ShouldInvalidateToSyncDecodeImages();
207 nsRect mPositioningArea;
208 nsRect mDestRect;
211 class nsDisplayThemedBackgroundGeometry : public nsDisplayItemGeometry {
212 public:
213 nsDisplayThemedBackgroundGeometry(nsDisplayThemedBackground* aItem,
214 nsDisplayListBuilder* aBuilder);
216 void MoveBy(const nsPoint& aOffset) override;
218 nsRect mPositioningArea;
219 bool mWindowIsActive;
222 class nsDisplayTreeBodyGeometry
223 : public nsDisplayItemGenericGeometry,
224 public nsImageGeometryMixin<nsDisplayTreeBodyGeometry> {
225 public:
226 nsDisplayTreeBodyGeometry(nsDisplayItem* aItem,
227 nsDisplayListBuilder* aBuilder,
228 bool aWindowIsActive)
229 : nsDisplayItemGenericGeometry(aItem, aBuilder),
230 nsImageGeometryMixin(aItem, aBuilder),
231 mWindowIsActive(aWindowIsActive) {}
233 bool InvalidateForSyncDecodeImages() const override {
234 return ShouldInvalidateToSyncDecodeImages();
237 bool mWindowIsActive = false;
240 class nsDisplayBoxShadowInnerGeometry : public nsDisplayItemGeometry {
241 public:
242 nsDisplayBoxShadowInnerGeometry(nsDisplayItem* aItem,
243 nsDisplayListBuilder* aBuilder);
245 void MoveBy(const nsPoint& aOffset) override;
247 nsRect mPaddingRect;
250 class nsDisplayBoxShadowOuterGeometry : public nsDisplayItemGenericGeometry {
251 public:
252 nsDisplayBoxShadowOuterGeometry(nsDisplayItem* aItem,
253 nsDisplayListBuilder* aBuilder,
254 float aOpacity);
256 float mOpacity;
259 class nsDisplaySolidColorGeometry : public nsDisplayItemBoundsGeometry {
260 public:
261 nsDisplaySolidColorGeometry(nsDisplayItem* aItem,
262 nsDisplayListBuilder* aBuilder, nscolor aColor)
263 : nsDisplayItemBoundsGeometry(aItem, aBuilder), mColor(aColor) {}
265 nscolor mColor;
268 class nsDisplaySolidColorRegionGeometry : public nsDisplayItemBoundsGeometry {
269 public:
270 nsDisplaySolidColorRegionGeometry(nsDisplayItem* aItem,
271 nsDisplayListBuilder* aBuilder,
272 const nsRegion& aRegion,
273 mozilla::gfx::sRGBColor aColor)
274 : nsDisplayItemBoundsGeometry(aItem, aBuilder),
275 mRegion(aRegion),
276 mColor(aColor) {}
278 void MoveBy(const nsPoint& aOffset) override;
280 nsRegion mRegion;
281 mozilla::gfx::sRGBColor mColor;
284 class nsDisplaySVGEffectGeometry : public nsDisplayItemGeometry {
285 public:
286 nsDisplaySVGEffectGeometry(nsDisplayEffectsBase* aItem,
287 nsDisplayListBuilder* aBuilder);
289 void MoveBy(const nsPoint& aOffset) override;
291 gfxRect mBBox;
292 gfxPoint mUserSpaceOffset;
293 nsPoint mFrameOffsetToReferenceFrame;
294 float mOpacity;
295 bool mHandleOpacity;
298 class nsDisplayMasksAndClipPathsGeometry
299 : public nsDisplaySVGEffectGeometry,
300 public nsImageGeometryMixin<nsDisplayMasksAndClipPathsGeometry> {
301 public:
302 nsDisplayMasksAndClipPathsGeometry(nsDisplayMasksAndClipPaths* aItem,
303 nsDisplayListBuilder* aBuilder);
305 bool InvalidateForSyncDecodeImages() const override {
306 return ShouldInvalidateToSyncDecodeImages();
309 nsTArray<nsRect> mDestRects;
312 class nsDisplayFiltersGeometry
313 : public nsDisplaySVGEffectGeometry,
314 public nsImageGeometryMixin<nsDisplayFiltersGeometry> {
315 public:
316 nsDisplayFiltersGeometry(nsDisplayFilters* aItem,
317 nsDisplayListBuilder* aBuilder);
319 bool InvalidateForSyncDecodeImages() const override {
320 return ShouldInvalidateToSyncDecodeImages();
324 class nsDisplayTableItemGeometry
325 : public nsDisplayItemGenericGeometry,
326 public nsImageGeometryMixin<nsDisplayTableItemGeometry> {
327 public:
328 nsDisplayTableItemGeometry(nsDisplayTableItem* aItem,
329 nsDisplayListBuilder* aBuilder,
330 const nsPoint& aFrameOffsetToViewport);
332 bool InvalidateForSyncDecodeImages() const override {
333 return ShouldInvalidateToSyncDecodeImages();
336 nsPoint mFrameOffsetToViewport;
339 class nsDisplayOpacityGeometry : public nsDisplayItemGenericGeometry {
340 public:
341 nsDisplayOpacityGeometry(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder,
342 float aOpacity)
343 : nsDisplayItemGenericGeometry(aItem, aBuilder), mOpacity(aOpacity) {}
345 float mOpacity;
348 class nsDisplayTransformGeometry : public nsDisplayItemGeometry {
349 public:
350 nsDisplayTransformGeometry(nsDisplayItem* aItem,
351 nsDisplayListBuilder* aBuilder,
352 const mozilla::gfx::Matrix4x4Flagged& aTransform,
353 int32_t aAppUnitsPerDevPixel)
354 : nsDisplayItemGeometry(aItem, aBuilder),
355 mTransform(aTransform),
356 mAppUnitsPerDevPixel(aAppUnitsPerDevPixel) {}
358 void MoveBy(const nsPoint& aOffset) override {
359 nsDisplayItemGeometry::MoveBy(aOffset);
360 mTransform.PostTranslate(
361 NSAppUnitsToFloatPixels(aOffset.x, mAppUnitsPerDevPixel),
362 NSAppUnitsToFloatPixels(aOffset.y, mAppUnitsPerDevPixel), 0.0f);
365 mozilla::gfx::Matrix4x4Flagged mTransform;
366 int32_t mAppUnitsPerDevPixel;
369 #endif /*NSDISPLAYLISTINVALIDATION_H_*/