Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / platform / graphics / paint / DisplayItem.h
blob1615455d7c720edbcaf936084ce820cdfd9d9018
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef DisplayItem_h
6 #define DisplayItem_h
8 #include "platform/PlatformExport.h"
9 #include "platform/graphics/ContiguousContainer.h"
10 #include "platform/graphics/paint/DisplayItemClient.h"
11 #include "wtf/Assertions.h"
12 #include "wtf/PassOwnPtr.h"
14 #ifndef NDEBUG
15 #include "wtf/text/StringBuilder.h"
16 #include "wtf/text/WTFString.h"
17 #endif
20 namespace blink {
22 class GraphicsContext;
23 class WebDisplayItemList;
25 class PLATFORM_EXPORT DisplayItem {
26 public:
27 enum {
28 // Must be kept in sync with core/paint/PaintPhase.h.
29 PaintPhaseMax = 12,
32 // A display item type uniquely identifies a display item of a client.
33 // Some display item types can be categorized using the following directives:
34 // - In enum Type:
35 // - enum value <Category>First;
36 // - enum values of the category, first of which should equal <Category>First;
37 // (for ease of maintenance, the values should be in alphabetic order)
38 // - enum value <Category>Last which should be equal to the last of the enum values of the category
39 // - DEFINE_CATEGORY_METHODS(<Category>) to define is<Category>Type(Type) and is<Category>() methods.
41 // A category or subset of a category can contain types each of which corresponds to a PaintPhase:
42 // - In enum Type:
43 // - enum value <Category>[<Subset>]PaintPhaseFirst;
44 // - enum value <Category>[<Subset>]PaintPhaseLast = <Category>[<Subset>]PaintPhaseFirst + PaintPhaseMax;
45 // - DEFINE_PAINT_PHASE_CONVERSION_METHOD(<Category>[<Subset>]) to define
46 // paintPhaseTo<Category>[<Subset>]Type(PaintPhase) method.
48 // A category can be derived from another category, containing types each of which corresponds to a
49 // value of the latter category:
50 // - In enum Type:
51 // - enum value <Category>First;
52 // - enum value <Category>Last = <Category>First + <BaseCategory>Last - <BaseCategory>First;
53 // - DEFINE_CONVERSION_METHODS(<Category>, <category>, <BaseCategory>, <baseCategory>) to define methods to
54 // convert types between the categories;
55 enum Type {
56 DrawingFirst,
57 DrawingPaintPhaseFirst = DrawingFirst,
58 DrawingPaintPhaseLast = DrawingFirst + PaintPhaseMax,
59 BoxDecorationBackground,
60 Caret,
61 ColumnRules,
62 DebugRedFill,
63 DragImage,
64 SVGImage,
65 LinkHighlight,
66 PageOverlay,
67 PageWidgetDelegateBackgroundFallback,
68 PopupContainerBorder,
69 PopupListBoxBackground,
70 PopupListBoxRow,
71 PrintedContentBackground,
72 PrintedContentLineBoundary,
73 PrintedContentPDFURLRect,
74 Resizer,
75 SVGClip,
76 SVGFilter,
77 SVGMask,
78 ScrollbarBackButtonEnd,
79 ScrollbarBackButtonStart,
80 ScrollbarBackground,
81 ScrollbarBackTrack,
82 ScrollbarCorner,
83 ScrollbarForwardButtonEnd,
84 ScrollbarForwardButtonStart,
85 ScrollbarForwardTrack,
86 ScrollbarHorizontal, // For ScrollbarThemeMacNonOverlayAPI only.
87 ScrollbarThumb,
88 ScrollbarTickmarks,
89 ScrollbarTrackBackground,
90 ScrollbarVertical, // For ScrollbarThemeMacNonOverlayAPI only.
91 SelectionGap,
92 SelectionTint,
93 TableCellBackgroundFromContainers,
94 TableCellBackgroundFromSelfPaintingRow,
95 // Table collapsed borders can be painted together (e.g., left & top) but there are at most 4 phases of collapsed
96 // border painting for a single cell. To disambiguate these phases of collapsed border painting, a mask is used.
97 // TableCollapsedBorderBase can be larger than TableCollapsedBorderUnalignedBase to ensure the base lower bits are 0's.
98 TableCollapsedBorderUnalignedBase,
99 TableCollapsedBorderBase = (((TableCollapsedBorderUnalignedBase - 1) >> 4) + 1) << 4,
100 TableCollapsedBorderLast = TableCollapsedBorderBase + 0x0f,
101 VideoBitmap,
102 WebPlugin,
103 WebFont,
104 DrawingLast = WebFont,
106 CachedDrawingFirst,
107 CachedDrawingLast = CachedDrawingFirst + DrawingLast - DrawingFirst,
109 ClipFirst,
110 ClipBoxPaintPhaseFirst = ClipFirst,
111 ClipBoxPaintPhaseLast = ClipBoxPaintPhaseFirst + PaintPhaseMax,
112 ClipColumnBoundsPaintPhaseFirst,
113 ClipColumnBoundsPaintPhaseLast = ClipColumnBoundsPaintPhaseFirst + PaintPhaseMax,
114 ClipLayerFragmentPaintPhaseFirst,
115 ClipLayerFragmentPaintPhaseLast = ClipLayerFragmentPaintPhaseFirst + PaintPhaseMax,
116 ClipFileUploadControlRect,
117 ClipFrameToVisibleContentRect,
118 ClipFrameScrollbars,
119 ClipLayerBackground,
120 ClipLayerColumnBounds,
121 ClipLayerFilter,
122 ClipLayerForeground,
123 ClipLayerParent,
124 ClipLayerOverflowControls,
125 ClipNodeImage,
126 ClipPopupListBoxFrame,
127 ClipSelectionImage,
128 PageWidgetDelegateClip,
129 ClipPrintedPage,
130 ClipLast = ClipPrintedPage,
132 EndClipFirst,
133 EndClipLast = EndClipFirst + ClipLast - ClipFirst,
135 FloatClipFirst,
136 FloatClipPaintPhaseFirst = FloatClipFirst,
137 FloatClipPaintPhaseLast = FloatClipFirst + PaintPhaseMax,
138 FloatClipLast = FloatClipPaintPhaseLast,
139 EndFloatClipFirst,
140 EndFloatClipLast = EndFloatClipFirst + FloatClipLast - FloatClipFirst,
142 ScrollFirst,
143 ScrollPaintPhaseFirst = ScrollFirst,
144 ScrollPaintPhaseLast = ScrollPaintPhaseFirst + PaintPhaseMax,
145 ScrollLast = ScrollPaintPhaseLast,
146 EndScrollFirst,
147 EndScrollLast = EndScrollFirst + ScrollLast - ScrollFirst,
149 Transform3DFirst,
150 Transform3DElementTransform = Transform3DFirst,
151 Transform3DLast = Transform3DElementTransform,
152 EndTransform3DFirst,
153 EndTransform3DLast = EndTransform3DFirst + Transform3DLast - Transform3DFirst,
155 BeginFilter,
156 EndFilter,
157 BeginCompositing,
158 EndCompositing,
159 BeginTransform,
160 EndTransform,
161 BeginClipPath,
162 EndClipPath,
163 BeginFixedPosition,
164 EndFixedPosition,
165 BeginFixedPositionContainer,
166 EndFixedPositionContainer,
168 BeginSubsequence,
169 EndSubsequence,
170 CachedSubsequence,
172 UninitializedType,
173 TypeLast = UninitializedType
176 static_assert(TableCollapsedBorderBase >= TableCollapsedBorderUnalignedBase, "TableCollapsedBorder types overlap with other types");
177 static_assert((TableCollapsedBorderBase & 0xf) == 0, "The lowest 4 bits of TableCollapsedBorderBase should be zero");
178 // Bits or'ed onto TableCollapsedBorderBase to generate a real table collapsed border type.
179 enum TableCollspaedBorderSides {
180 TableCollapsedBorderTop = 1 << 0,
181 TableCollapsedBorderRight = 1 << 1,
182 TableCollapsedBorderBottom = 1 << 2,
183 TableCollapsedBorderLeft = 1 << 3,
186 DisplayItem(const DisplayItemClientWrapper& client, Type type, size_t derivedSize)
187 : m_client(client.displayItemClient())
188 , m_scope(0)
189 , m_type(type)
190 , m_derivedSize(derivedSize)
191 , m_skippedCache(false)
192 #ifndef NDEBUG
193 , m_clientDebugString(client.debugName())
194 #endif
196 // derivedSize must fit in m_derivedSize.
197 // If it doesn't, enlarge m_derivedSize and fix this assert.
198 ASSERT_WITH_SECURITY_IMPLICATION(derivedSize < (1 << 8));
199 ASSERT_WITH_SECURITY_IMPLICATION(derivedSize >= sizeof(*this));
202 virtual ~DisplayItem() { }
204 // Ids are for matching new DisplayItems with existing DisplayItems.
205 struct Id {
206 Id(const DisplayItemClient client, const Type type, const unsigned scope)
207 : client(client)
208 , type(type)
209 , scope(scope) { }
211 bool matches(const DisplayItem& item) const
213 // We should always convert to non-cached types before matching.
214 ASSERT(!isCachedType(item.m_type));
215 ASSERT(!isCachedType(type));
216 return client == item.m_client
217 && type == item.m_type
218 && scope == item.m_scope;
221 const DisplayItemClient client;
222 const Type type;
223 const unsigned scope;
226 // Convert cached type to non-cached type (e.g., Type::CachedSVGImage -> Type::SVGImage).
227 static Type nonCachedType(Type type)
229 if (isCachedDrawingType(type))
230 return cachedDrawingTypeToDrawingType(type);
231 if (type == CachedSubsequence)
232 return BeginSubsequence;
233 return type;
236 // Return the Id with cached type converted to non-cached type.
237 Id nonCachedId() const
239 return Id(m_client, nonCachedType(m_type), m_scope);
242 virtual void replay(GraphicsContext&) { }
244 DisplayItemClient client() const { return m_client; }
245 Type type() const { return m_type; }
247 void setScope(unsigned scope) { m_scope = scope; }
248 unsigned scope() { return m_scope; }
250 // Size of this object in memory, used to move it with memcpy.
251 // This is not sizeof(*this), because it needs to account for the size of
252 // the derived class (i.e. runtime type). Derived classes are expected to
253 // supply this to the DisplayItem constructor.
254 size_t derivedSize() const { return m_derivedSize; }
256 // For DisplayItemList only. Painters should use DisplayItemCacheSkipper instead.
257 void setSkippedCache() { m_skippedCache = true; }
258 bool skippedCache() const { return m_skippedCache; }
260 virtual void appendToWebDisplayItemList(WebDisplayItemList*) const { }
262 // See comments of enum Type for usage of the following macros.
263 #define DEFINE_CATEGORY_METHODS(Category) \
264 static bool is##Category##Type(Type type) { return type >= Category##First && type <= Category##Last; } \
265 bool is##Category() const { return is##Category##Type(type()); }
267 #define DEFINE_CONVERSION_METHODS(Category1, category1, Category2, category2) \
268 static Type category1##TypeTo##Category2##Type(Type type) \
270 static_assert(Category1##Last - Category1##First == Category2##Last - Category2##First, \
271 "Categories " #Category1 " and " #Category2 " should have same number of enum values. See comments of DisplayItem::Type"); \
272 ASSERT(is##Category1##Type(type)); \
273 return static_cast<Type>(type - Category1##First + Category2##First); \
275 static Type category2##TypeTo##Category1##Type(Type type) \
277 ASSERT(is##Category2##Type(type)); \
278 return static_cast<Type>(type - Category2##First + Category1##First); \
281 #define DEFINE_PAIRED_CATEGORY_METHODS(Category, category) \
282 DEFINE_CATEGORY_METHODS(Category) \
283 DEFINE_CATEGORY_METHODS(End##Category) \
284 DEFINE_CONVERSION_METHODS(Category, category, End##Category, end##Category)
286 #define DEFINE_PAINT_PHASE_CONVERSION_METHOD(Category) \
287 static Type paintPhaseTo##Category##Type(int paintPhase) \
289 static_assert(Category##PaintPhaseLast - Category##PaintPhaseFirst == PaintPhaseMax, \
290 "Invalid paint-phase-based category " #Category ". See comments of DisplayItem::Type"); \
291 return static_cast<Type>(paintPhase + Category##PaintPhaseFirst); \
294 DEFINE_CATEGORY_METHODS(Drawing)
295 DEFINE_PAINT_PHASE_CONVERSION_METHOD(Drawing)
296 DEFINE_CATEGORY_METHODS(CachedDrawing)
297 DEFINE_CONVERSION_METHODS(Drawing, drawing, CachedDrawing, cachedDrawing)
299 DEFINE_PAIRED_CATEGORY_METHODS(Clip, clip)
300 DEFINE_PAINT_PHASE_CONVERSION_METHOD(ClipLayerFragment)
301 DEFINE_PAINT_PHASE_CONVERSION_METHOD(ClipBox)
302 DEFINE_PAINT_PHASE_CONVERSION_METHOD(ClipColumnBounds)
304 DEFINE_PAIRED_CATEGORY_METHODS(FloatClip, floatClip)
305 DEFINE_PAINT_PHASE_CONVERSION_METHOD(FloatClip)
307 DEFINE_PAIRED_CATEGORY_METHODS(Scroll, scroll)
308 DEFINE_PAINT_PHASE_CONVERSION_METHOD(Scroll)
310 DEFINE_PAIRED_CATEGORY_METHODS(Transform3D, transform3D);
312 static bool isCachedType(Type type) { return isCachedDrawingType(type) || type == CachedSubsequence; }
313 bool isCached() const { return isCachedType(m_type); }
314 static bool isCacheableType(Type type) { return isDrawingType(type) || type == BeginSubsequence; }
315 bool isCacheable() const { return !skippedCache() && isCacheableType(m_type); }
317 virtual bool isBegin() const { return false; }
318 virtual bool isEnd() const { return false; }
320 #if ENABLE(ASSERT)
321 virtual bool isEndAndPairedWith(DisplayItem::Type otherType) const { return false; }
322 virtual bool equals(const DisplayItem& other) const
324 return m_client == other.m_client
325 && m_scope == other.m_scope
326 && m_type == other.m_type
327 && m_derivedSize == other.m_derivedSize
328 && m_skippedCache == other.m_skippedCache;
330 #endif
332 virtual bool drawsContent() const { return false; }
334 bool isValid() const { return m_client; }
336 #ifndef NDEBUG
337 static WTF::String typeAsDebugString(DisplayItem::Type);
338 const WTF::String& clientDebugString() const { return m_clientDebugString; }
339 void setClientDebugString(const WTF::String& s) { m_clientDebugString = s; }
340 WTF::String asDebugString() const;
341 virtual void dumpPropertiesAsDebugString(WTF::StringBuilder&) const;
342 #endif
344 private:
345 // The default DisplayItem constructor is only used by
346 // ContiguousContainer::appendByMoving where an invalid DisplaItem is
347 // constructed at the source location.
348 template <typename T, unsigned alignment> friend class ContiguousContainer;
350 DisplayItem()
351 : m_client(nullptr)
352 , m_scope(0)
353 , m_type(UninitializedType)
354 , m_derivedSize(sizeof(*this))
355 , m_skippedCache(false)
358 const DisplayItemClient m_client;
359 unsigned m_scope;
360 static_assert(TypeLast < (1 << 16), "DisplayItem::Type should fit in 16 bits");
361 const Type m_type : 16;
362 const unsigned m_derivedSize : 8; // size of the actual derived class
363 unsigned m_skippedCache : 1;
365 #ifndef NDEBUG
366 WTF::String m_clientDebugString;
367 #endif
370 class PLATFORM_EXPORT PairedBeginDisplayItem : public DisplayItem {
371 protected:
372 PairedBeginDisplayItem(const DisplayItemClientWrapper& client, Type type, size_t derivedSize) : DisplayItem(client, type, derivedSize) { }
374 private:
375 bool isBegin() const final { return true; }
378 class PLATFORM_EXPORT PairedEndDisplayItem : public DisplayItem {
379 protected:
380 PairedEndDisplayItem(const DisplayItemClientWrapper& client, Type type, size_t derivedSize) : DisplayItem(client, type, derivedSize) { }
382 #if ENABLE(ASSERT)
383 bool isEndAndPairedWith(DisplayItem::Type otherType) const override = 0;
384 #endif
386 private:
387 bool isEnd() const final { return true; }
390 } // namespace blink
392 #endif // DisplayItem_h