Source code

Revision control

Other Tools

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/. */
6
7
#ifndef GFX_LAYERSTYPES_H
8
#define GFX_LAYERSTYPES_H
9
10
#include <stdint.h> // for uint32_t
11
12
#include "Units.h"
13
#include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
14
#include "mozilla/gfx/Point.h" // for IntPoint
15
#include "mozilla/Maybe.h"
16
#include "mozilla/TimeStamp.h" // for TimeStamp
17
#include "mozilla/TypedEnumBits.h"
18
#include "nsRegion.h"
19
20
#include <stdio.h> // FILE
21
#include "mozilla/Logging.h" // for PR_LOG
22
23
#ifndef MOZ_LAYERS_HAVE_LOG
24
# define MOZ_LAYERS_HAVE_LOG
25
#endif
26
#define MOZ_LAYERS_LOG(_args) \
27
MOZ_LOG(LayerManager::GetLog(), LogLevel::Debug, _args)
28
#define MOZ_LAYERS_LOG_IF_SHADOWABLE(layer, _args) \
29
do { \
30
if (layer->AsShadowableLayer()) { \
31
MOZ_LOG(LayerManager::GetLog(), LogLevel::Debug, _args); \
32
} \
33
} while (0)
34
35
#define INVALID_OVERLAY -1
36
37
//#define ENABLE_FRAME_LATENCY_LOG
38
39
namespace IPC {
40
template <typename T>
41
struct ParamTraits;
42
} // namespace IPC
43
44
namespace mozilla {
45
46
enum class StyleBorderStyle : uint8_t;
47
48
namespace layers {
49
50
class TextureHost;
51
52
#undef NONE
53
#undef OPAQUE
54
55
struct LayersId {
56
uint64_t mId = 0;
57
58
bool IsValid() const { return mId != 0; }
59
60
// Allow explicit cast to a uint64_t for now
61
explicit operator uint64_t() const { return mId; }
62
63
// Implement some operators so this class can be used as a key in
64
// stdlib classes.
65
bool operator<(const LayersId& aOther) const { return mId < aOther.mId; }
66
67
bool operator==(const LayersId& aOther) const { return mId == aOther.mId; }
68
69
bool operator!=(const LayersId& aOther) const { return !(*this == aOther); }
70
71
// Helper struct that allow this class to be used as a key in
72
// std::unordered_map like so:
73
// std::unordered_map<LayersId, ValueType, LayersId::HashFn> myMap;
74
struct HashFn {
75
std::size_t operator()(const LayersId& aKey) const {
76
return std::hash<uint64_t>{}(aKey.mId);
77
}
78
};
79
};
80
81
template <typename T>
82
struct BaseTransactionId {
83
uint64_t mId = 0;
84
85
bool IsValid() const { return mId != 0; }
86
87
[[nodiscard]] BaseTransactionId<T> Next() const {
88
return BaseTransactionId<T>{mId + 1};
89
}
90
91
[[nodiscard]] BaseTransactionId<T> Prev() const {
92
return BaseTransactionId<T>{mId - 1};
93
}
94
95
int64_t operator-(const BaseTransactionId<T>& aOther) const {
96
return mId - aOther.mId;
97
}
98
99
// Allow explicit cast to a uint64_t for now
100
explicit operator uint64_t() const { return mId; }
101
102
bool operator<(const BaseTransactionId<T>& aOther) const {
103
return mId < aOther.mId;
104
}
105
106
bool operator<=(const BaseTransactionId<T>& aOther) const {
107
return mId <= aOther.mId;
108
}
109
110
bool operator>(const BaseTransactionId<T>& aOther) const {
111
return mId > aOther.mId;
112
}
113
114
bool operator>=(const BaseTransactionId<T>& aOther) const {
115
return mId >= aOther.mId;
116
}
117
118
bool operator==(const BaseTransactionId<T>& aOther) const {
119
return mId == aOther.mId;
120
}
121
};
122
123
class TransactionIdType {};
124
typedef BaseTransactionId<TransactionIdType> TransactionId;
125
126
struct LayersObserverEpoch {
127
uint64_t mId;
128
129
[[nodiscard]] LayersObserverEpoch Next() const {
130
return LayersObserverEpoch{mId + 1};
131
}
132
133
bool operator<=(const LayersObserverEpoch& aOther) const {
134
return mId <= aOther.mId;
135
}
136
137
bool operator>=(const LayersObserverEpoch& aOther) const {
138
return mId >= aOther.mId;
139
}
140
141
bool operator==(const LayersObserverEpoch& aOther) const {
142
return mId == aOther.mId;
143
}
144
145
bool operator!=(const LayersObserverEpoch& aOther) const {
146
return mId != aOther.mId;
147
}
148
};
149
150
enum class LayersBackend : int8_t {
151
LAYERS_NONE = 0,
152
LAYERS_BASIC,
153
LAYERS_OPENGL,
154
LAYERS_D3D11,
155
LAYERS_CLIENT,
156
LAYERS_WR,
157
LAYERS_LAST
158
};
159
160
const char* GetLayersBackendName(LayersBackend aBackend);
161
162
enum class TextureType : int8_t {
163
Unknown = 0,
164
D3D11,
165
DIB,
166
X11,
167
MacIOSurface,
168
AndroidNativeWindow,
169
WaylandDMABUF,
170
Last
171
};
172
173
enum class BufferMode : int8_t { BUFFER_NONE, BUFFERED };
174
175
enum class DrawRegionClip : int8_t { DRAW, NONE };
176
177
enum class SurfaceMode : int8_t {
178
SURFACE_NONE = 0,
179
SURFACE_OPAQUE,
180
SURFACE_SINGLE_CHANNEL_ALPHA,
181
SURFACE_COMPONENT_ALPHA
182
};
183
184
// clang-format off
185
MOZ_DEFINE_ENUM_CLASS_WITH_BASE(
186
ScaleMode, int8_t, (
187
SCALE_NONE,
188
STRETCH
189
// Unimplemented - PRESERVE_ASPECT_RATIO_CONTAIN
190
));
191
// clang-format on
192
193
struct EventRegions {
194
// The hit region for a layer contains all areas on the layer that are
195
// sensitive to events. This region is an over-approximation and may
196
// contain regions that are not actually sensitive, but any such regions
197
// will be included in the mDispatchToContentHitRegion.
198
nsIntRegion mHitRegion;
199
// The mDispatchToContentHitRegion for a layer contains all areas for
200
// which the main-thread must be consulted before responding to events.
201
// This region will be a subregion of mHitRegion.
202
nsIntRegion mDispatchToContentHitRegion;
203
204
// The following regions represent the touch-action areas of this layer.
205
// All of these regions are approximations to the true region, but any
206
// variance between the approximation and the true region is guaranteed
207
// to be included in the mDispatchToContentHitRegion.
208
nsIntRegion mNoActionRegion;
209
nsIntRegion mHorizontalPanRegion;
210
nsIntRegion mVerticalPanRegion;
211
212
// Set to true if events targeting the dispatch-to-content region
213
// require target confirmation.
214
// See CompositorHitTestFlags::eRequiresTargetConfirmation.
215
// We don't bother tracking a separate region for this (which would
216
// be a sub-region of the dispatch-to-content region), because the added
217
// overhead of region computations is not worth it, and because
218
// EventRegions are going to be deprecated anyways.
219
bool mDTCRequiresTargetConfirmation;
220
221
EventRegions() : mDTCRequiresTargetConfirmation(false) {}
222
223
explicit EventRegions(nsIntRegion aHitRegion)
224
: mHitRegion(aHitRegion), mDTCRequiresTargetConfirmation(false) {}
225
226
// This constructor takes the maybe-hit region and uses it to update the
227
// hit region and dispatch-to-content region. It is useful from converting
228
// from the display item representation to the layer representation.
229
EventRegions(const nsIntRegion& aHitRegion,
230
const nsIntRegion& aMaybeHitRegion,
231
const nsIntRegion& aDispatchToContentRegion,
232
const nsIntRegion& aNoActionRegion,
233
const nsIntRegion& aHorizontalPanRegion,
234
const nsIntRegion& aVerticalPanRegion,
235
bool aDTCRequiresTargetConfirmation);
236
237
bool operator==(const EventRegions& aRegions) const {
238
return mHitRegion == aRegions.mHitRegion &&
239
mDispatchToContentHitRegion ==
240
aRegions.mDispatchToContentHitRegion &&
241
mNoActionRegion == aRegions.mNoActionRegion &&
242
mHorizontalPanRegion == aRegions.mHorizontalPanRegion &&
243
mVerticalPanRegion == aRegions.mVerticalPanRegion &&
244
mDTCRequiresTargetConfirmation ==
245
aRegions.mDTCRequiresTargetConfirmation;
246
}
247
bool operator!=(const EventRegions& aRegions) const {
248
return !(*this == aRegions);
249
}
250
251
void ApplyTranslationAndScale(float aXTrans, float aYTrans, float aXScale,
252
float aYScale) {
253
mHitRegion.ScaleRoundOut(aXScale, aYScale);
254
mDispatchToContentHitRegion.ScaleRoundOut(aXScale, aYScale);
255
mNoActionRegion.ScaleRoundOut(aXScale, aYScale);
256
mHorizontalPanRegion.ScaleRoundOut(aXScale, aYScale);
257
mVerticalPanRegion.ScaleRoundOut(aXScale, aYScale);
258
259
mHitRegion.MoveBy(aXTrans, aYTrans);
260
mDispatchToContentHitRegion.MoveBy(aXTrans, aYTrans);
261
mNoActionRegion.MoveBy(aXTrans, aYTrans);
262
mHorizontalPanRegion.MoveBy(aXTrans, aYTrans);
263
mVerticalPanRegion.MoveBy(aXTrans, aYTrans);
264
}
265
266
void Transform(const gfx::Matrix4x4& aTransform) {
267
mHitRegion.Transform(aTransform);
268
mDispatchToContentHitRegion.Transform(aTransform);
269
mNoActionRegion.Transform(aTransform);
270
mHorizontalPanRegion.Transform(aTransform);
271
mVerticalPanRegion.Transform(aTransform);
272
}
273
274
void OrWith(const EventRegions& aOther) {
275
mHitRegion.OrWith(aOther.mHitRegion);
276
mDispatchToContentHitRegion.OrWith(aOther.mDispatchToContentHitRegion);
277
// See the comment in nsDisplayList::AddFrame, where the touch action
278
// regions are handled. The same thing applies here.
279
bool alreadyHadRegions = !mNoActionRegion.IsEmpty() ||
280
!mHorizontalPanRegion.IsEmpty() ||
281
!mVerticalPanRegion.IsEmpty();
282
mNoActionRegion.OrWith(aOther.mNoActionRegion);
283
mHorizontalPanRegion.OrWith(aOther.mHorizontalPanRegion);
284
mVerticalPanRegion.OrWith(aOther.mVerticalPanRegion);
285
if (alreadyHadRegions) {
286
nsIntRegion combinedActionRegions;
287
combinedActionRegions.Or(mHorizontalPanRegion, mVerticalPanRegion);
288
combinedActionRegions.OrWith(mNoActionRegion);
289
mDispatchToContentHitRegion.OrWith(combinedActionRegions);
290
}
291
mDTCRequiresTargetConfirmation |= aOther.mDTCRequiresTargetConfirmation;
292
}
293
294
bool IsEmpty() const {
295
return mHitRegion.IsEmpty() && mDispatchToContentHitRegion.IsEmpty() &&
296
mNoActionRegion.IsEmpty() && mHorizontalPanRegion.IsEmpty() &&
297
mVerticalPanRegion.IsEmpty();
298
}
299
300
void SetEmpty() {
301
mHitRegion.SetEmpty();
302
mDispatchToContentHitRegion.SetEmpty();
303
mNoActionRegion.SetEmpty();
304
mHorizontalPanRegion.SetEmpty();
305
mVerticalPanRegion.SetEmpty();
306
}
307
308
nsCString ToString() const {
309
nsCString result = mHitRegion.ToString();
310
result.AppendLiteral(";dispatchToContent=");
311
result.Append(mDispatchToContentHitRegion.ToString());
312
return result;
313
}
314
};
315
316
// Bit flags that go on a RefLayer and override the
317
// event regions in the entire subtree below. This is needed for propagating
318
// various flags across processes since the child-process layout code doesn't
319
// know about parent-process listeners or CSS rules.
320
enum EventRegionsOverride {
321
// The default, no flags set
322
NoOverride = 0,
323
// Treat all hit regions in the subtree as dispatch-to-content
324
ForceDispatchToContent = (1 << 0),
325
// Treat all hit regions in the subtree as empty
326
ForceEmptyHitRegion = (1 << 1),
327
// OR union of all valid bit flags, for use in BitFlagsEnumSerializer
328
ALL_BITS = (1 << 2) - 1
329
};
330
331
MOZ_ALWAYS_INLINE EventRegionsOverride operator|(EventRegionsOverride a,
332
EventRegionsOverride b) {
333
return (EventRegionsOverride)((int)a | (int)b);
334
}
335
336
MOZ_ALWAYS_INLINE EventRegionsOverride& operator|=(EventRegionsOverride& a,
337
EventRegionsOverride b) {
338
a = a | b;
339
return a;
340
}
341
342
// Flags used as an argument to functions that dump textures.
343
enum TextureDumpMode {
344
Compress, // dump texture with LZ4 compression
345
DoNotCompress // dump texture uncompressed
346
};
347
348
typedef uint32_t TouchBehaviorFlags;
349
350
// Some specialized typedefs of Matrix4x4Typed.
351
typedef gfx::Matrix4x4Typed<LayerPixel, CSSTransformedLayerPixel>
352
CSSTransformMatrix;
353
// Several different async transforms can contribute to a layer's transform
354
// (specifically, an async animation can contribute a transform, and each APZC
355
// that scrolls a layer can contribute async scroll/zoom and overscroll
356
// transforms).
357
// To try to model this with typed units, we represent individual async
358
// transforms as ParentLayer -> ParentLayer transforms (aliased as
359
// AsyncTransformComponentMatrix), and we represent the product of all of them
360
// as a CSSTransformLayer -> ParentLayer transform (aliased as
361
// AsyncTransformMatrix). To create an AsyncTransformMatrix from component
362
// matrices, a ViewAs operation is needed. A MultipleAsyncTransforms
363
// PixelCastJustification is provided for this purpose.
364
typedef gfx::Matrix4x4Typed<ParentLayerPixel, ParentLayerPixel>
365
AsyncTransformComponentMatrix;
366
typedef gfx::Matrix4x4Typed<CSSTransformedLayerPixel, ParentLayerPixel>
367
AsyncTransformMatrix;
368
369
typedef Array<gfx::DeviceColor, 4> BorderColors;
370
typedef Array<LayerSize, 4> BorderCorners;
371
typedef Array<LayerCoord, 4> BorderWidths;
372
typedef Array<StyleBorderStyle, 4> BorderStyles;
373
374
typedef Maybe<LayerRect> MaybeLayerRect;
375
376
// This is used to communicate Layers across IPC channels. The Handle is valid
377
// for layers in the same PLayerTransaction. Handles are created by
378
// ClientLayerManager, and are cached in LayerTransactionParent on first use.
379
class LayerHandle final {
380
friend struct IPC::ParamTraits<mozilla::layers::LayerHandle>;
381
382
public:
383
LayerHandle() : mHandle(0) {}
384
LayerHandle(const LayerHandle& aOther) = default;
385
explicit LayerHandle(uint64_t aHandle) : mHandle(aHandle) {}
386
bool IsValid() const { return mHandle != 0; }
387
explicit operator bool() const { return IsValid(); }
388
bool operator==(const LayerHandle& aOther) const {
389
return mHandle == aOther.mHandle;
390
}
391
uint64_t Value() const { return mHandle; }
392
393
private:
394
uint64_t mHandle;
395
};
396
397
// This is used to communicate Compositables across IPC channels. The Handle is
398
// valid for layers in the same PLayerTransaction or PImageBridge. Handles are
399
// created by ClientLayerManager or ImageBridgeChild, and are cached in the
400
// parent side on first use.
401
class CompositableHandle final {
402
friend struct IPC::ParamTraits<mozilla::layers::CompositableHandle>;
403
404
public:
405
CompositableHandle() : mHandle(0) {}
406
CompositableHandle(const CompositableHandle& aOther) = default;
407
explicit CompositableHandle(uint64_t aHandle) : mHandle(aHandle) {}
408
bool IsValid() const { return mHandle != 0; }
409
explicit operator bool() const { return IsValid(); }
410
bool operator==(const CompositableHandle& aOther) const {
411
return mHandle == aOther.mHandle;
412
}
413
uint64_t Value() const { return mHandle; }
414
415
private:
416
uint64_t mHandle;
417
};
418
419
// clang-format off
420
MOZ_DEFINE_ENUM_CLASS_WITH_BASE(ScrollDirection, uint32_t, (
421
eVertical,
422
eHorizontal
423
));
424
425
MOZ_DEFINE_ENUM_CLASS_WITH_BASE(CompositionPayloadType, uint8_t, (
426
/**
427
* A |CompositionPayload| with this type indicates a key press happened
428
* before composition and will be used to determine latency between key press
429
* and presentation in |mozilla::Telemetry::KEYPRESS_PRESENT_LATENCY|
430
*/
431
eKeyPress,
432
433
/**
434
* A |CompositionPayload| with this type indicates that an APZ scroll event
435
* occurred that will be included in the composition.
436
*/
437
eAPZScroll,
438
439
/**
440
* A |CompositionPayload| with this type indicates that an APZ pinch-to-zoom
441
* event occurred that will be included in the composition.
442
*/
443
eAPZPinchZoom,
444
445
/**
446
* A |CompositionPayload| with this type indicates that content was painted
447
* that will be included in the composition.
448
*/
449
eContentPaint
450
));
451
// clang-format on
452
453
struct CompositionPayload {
454
bool operator==(const CompositionPayload& aOther) const {
455
return mType == aOther.mType && mTimeStamp == aOther.mTimeStamp;
456
}
457
/* The type of payload that is in this composition */
458
CompositionPayloadType mType;
459
/* When this payload was generated */
460
TimeStamp mTimeStamp;
461
};
462
463
} // namespace layers
464
} // namespace mozilla
465
466
#endif /* GFX_LAYERSTYPES_H */