LayersTypes.h (17514B)
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 <iosfwd> // for ostream 11 #include <stdint.h> // for uint32_t 12 #include <stdio.h> // FILE 13 #include <tuple> 14 15 #include "Units.h" 16 #include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM_CLASS_WITH_BASE 17 #include "mozilla/Maybe.h" 18 #include "mozilla/TimeStamp.h" // for TimeStamp 19 #include "nsRegion.h" 20 #include "mozilla/EnumSet.h" 21 22 #ifndef MOZ_LAYERS_HAVE_LOG 23 # define MOZ_LAYERS_HAVE_LOG 24 #endif 25 #define MOZ_LAYERS_LOG(_args) \ 26 MOZ_LOG(LayerManager::GetLog(), LogLevel::Debug, _args) 27 #define MOZ_LAYERS_LOG_IF_SHADOWABLE(layer, _args) 28 29 #define INVALID_OVERLAY -1 30 31 // #define ENABLE_FRAME_LATENCY_LOG 32 33 namespace IPC { 34 template <typename T> 35 struct ParamTraits; 36 } // namespace IPC 37 38 namespace mozilla { 39 40 enum class StyleBorderStyle : uint8_t; 41 42 namespace layers { 43 44 class TextureHost; 45 46 #undef NONE 47 #undef OPAQUE 48 49 struct LayersId final { 50 uint64_t mId = 0; 51 52 auto MutTiedFields() { return std::tie(mId); } 53 54 bool IsValid() const { return mId != 0; } 55 56 // Allow explicit cast to a uint64_t for now 57 explicit operator uint64_t() const { return mId; } 58 59 // Implement some operators so this class can be used as a key in 60 // stdlib classes. 61 bool operator<(const LayersId& aOther) const { return mId < aOther.mId; } 62 63 bool operator==(const LayersId& aOther) const { return mId == aOther.mId; } 64 65 bool operator!=(const LayersId& aOther) const { return !(*this == aOther); } 66 67 friend std::ostream& operator<<(std::ostream& aStream, const LayersId& aId); 68 69 // Helper struct that allow this class to be used as a key in 70 // std::unordered_map like so: 71 // std::unordered_map<LayersId, ValueType, LayersId::HashFn> myMap; 72 struct HashFn { 73 std::size_t operator()(const LayersId& aKey) const { 74 return std::hash<uint64_t>{}(aKey.mId); 75 } 76 }; 77 }; 78 79 template <typename T> 80 struct BaseTransactionId final { 81 uint64_t mId = 0; 82 83 auto MutTiedFields() { return std::tie(mId); } 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 bool operator!=(const BaseTransactionId<T>& aOther) const { 123 return mId != aOther.mId; 124 } 125 }; 126 127 class TransactionIdType {}; 128 typedef BaseTransactionId<TransactionIdType> TransactionId; 129 130 // CompositionOpportunityId is a counter that goes up every time we have an 131 // opportunity to composite. It increments even on no-op composites (if nothing 132 // has changed) and while compositing is paused. It does not skip values if a 133 // composite is delayed. It is meaningful per window. 134 // This counter is used to differentiate intentionally-skipped video frames from 135 // unintentionally-skipped video frames: If CompositionOpportunityIds are 136 // observed by the video in +1 increments, then the video was onscreen the 137 // entire time and compositing was not paused. But if gaps in 138 // CompositionOpportunityIds are observed, that must mean that the video was not 139 // considered during some composition opportunities, because compositing was 140 // paused or because the video was not part of the on-screen scene. 141 class CompositionOpportunityType {}; 142 typedef BaseTransactionId<CompositionOpportunityType> CompositionOpportunityId; 143 144 /// We make different decisions about resource allocation sizes in WebRender 145 /// depending on whether we are going to render web pages or simpler 146 /// content in the window. 147 enum class WindowKind : int8_t { MAIN = 0, SECONDARY, LAST }; 148 149 enum class LayersBackend : int8_t { LAYERS_NONE = 0, LAYERS_WR, LAYERS_LAST }; 150 151 enum class WebRenderBackend : int8_t { HARDWARE = 0, SOFTWARE, LAST }; 152 153 enum class WebRenderCompositor : int8_t { 154 DRAW = 0, 155 DIRECT_COMPOSITION, 156 CORE_ANIMATION, 157 SOFTWARE, 158 D3D11, 159 OPENGL, 160 WAYLAND, 161 LAST 162 }; 163 164 const char* GetLayersBackendName(LayersBackend aBackend); 165 166 enum class TextureType : int8_t { 167 Unknown = 0, 168 D3D11, 169 MacIOSurface, 170 AndroidNativeWindow, 171 AndroidHardwareBuffer, 172 DMABUF, 173 EGLImage, 174 Last 175 }; 176 177 enum class DrawRegionClip : int8_t { DRAW, NONE }; 178 179 enum class SurfaceMode : int8_t { 180 SURFACE_NONE = 0, 181 SURFACE_OPAQUE, 182 SURFACE_SINGLE_CHANNEL_ALPHA, 183 SURFACE_COMPONENT_ALPHA 184 }; 185 186 // clang-format off 187 MOZ_DEFINE_ENUM_CLASS_WITH_BASE( 188 ScaleMode, int8_t, ( 189 SCALE_NONE, 190 STRETCH 191 // Unimplemented - PRESERVE_ASPECT_RATIO_CONTAIN 192 )); 193 // clang-format on 194 195 // Bit flags that go on a RefLayer and override the 196 // event regions in the entire subtree below. This is needed for propagating 197 // various flags across processes since the child-process layout code doesn't 198 // know about parent-process listeners or CSS rules. 199 enum EventRegionsOverride { 200 // The default, no flags set 201 NoOverride = 0, 202 // Treat all hit regions in the subtree as dispatch-to-content 203 ForceDispatchToContent = (1 << 0), 204 // Treat all hit regions in the subtree as empty 205 ForceEmptyHitRegion = (1 << 1), 206 // OR union of all valid bit flags, for use in BitFlagsEnumSerializer 207 ALL_BITS = (1 << 2) - 1 208 }; 209 210 MOZ_ALWAYS_INLINE EventRegionsOverride operator|(EventRegionsOverride a, 211 EventRegionsOverride b) { 212 return (EventRegionsOverride)((int)a | (int)b); 213 } 214 215 MOZ_ALWAYS_INLINE EventRegionsOverride& operator|=(EventRegionsOverride& a, 216 EventRegionsOverride b) { 217 a = a | b; 218 return a; 219 } 220 221 // Flags used as an argument to functions that dump textures. 222 enum TextureDumpMode { 223 Compress, // dump texture with LZ4 compression 224 DoNotCompress // dump texture uncompressed 225 }; 226 227 // Corresponding bit masks for allowed touch behaviors 228 // are defined in AllowedTouchBehavior 229 typedef uint32_t TouchBehaviorFlags; 230 231 // Some specialized typedefs of Matrix4x4Typed. 232 typedef gfx::Matrix4x4Typed<LayerPixel, CSSTransformedLayerPixel> 233 CSSTransformMatrix; 234 // Several different async transforms can contribute to a layer's transform 235 // (specifically, an async animation can contribute a transform, and each APZC 236 // that scrolls a layer can contribute async scroll/zoom and overscroll 237 // transforms). 238 // To try to model this with typed units, we represent individual async 239 // transforms as ParentLayer -> ParentLayer transforms (aliased as 240 // AsyncTransformComponentMatrix), and we represent the product of all of them 241 // as a CSSTransformLayer -> ParentLayer transform (aliased as 242 // AsyncTransformMatrix). To create an AsyncTransformMatrix from component 243 // matrices, a ViewAs operation is needed. A MultipleAsyncTransforms 244 // PixelCastJustification is provided for this purpose. 245 typedef gfx::Matrix4x4Typed<ParentLayerPixel, ParentLayerPixel> 246 AsyncTransformComponentMatrix; 247 typedef gfx::Matrix4x4Typed<CSSTransformedLayerPixel, ParentLayerPixel> 248 AsyncTransformMatrix; 249 250 typedef Array<gfx::DeviceColor, 4> BorderColors; 251 typedef Array<LayerSize, 4> BorderCorners; 252 typedef Array<LayerCoord, 4> BorderWidths; 253 typedef Array<StyleBorderStyle, 4> BorderStyles; 254 255 typedef Maybe<LayerRect> MaybeLayerRect; 256 257 // This is used to communicate Layers across IPC channels. The Handle is valid 258 // for layers in the same PLayerTransaction. Handles are created by 259 // ClientLayerManager, and are cached in LayerTransactionParent on first use. 260 class LayerHandle final { 261 friend struct IPC::ParamTraits<mozilla::layers::LayerHandle>; 262 263 public: 264 LayerHandle() : mHandle(0) {} 265 LayerHandle(const LayerHandle& aOther) = default; 266 explicit LayerHandle(uint64_t aHandle) : mHandle(aHandle) {} 267 bool IsValid() const { return mHandle != 0; } 268 explicit operator bool() const { return IsValid(); } 269 bool operator==(const LayerHandle& aOther) const { 270 return mHandle == aOther.mHandle; 271 } 272 uint64_t Value() const { return mHandle; } 273 274 private: 275 uint64_t mHandle; 276 }; 277 278 // This is used to communicate Compositables across IPC channels. The Handle is 279 // valid for layers in the same PLayerTransaction or PImageBridge. Handles are 280 // created by ClientLayerManager or ImageBridgeChild, and are cached in the 281 // parent side on first use. 282 class CompositableHandle final { 283 friend struct IPC::ParamTraits<mozilla::layers::CompositableHandle>; 284 285 public: 286 static CompositableHandle GetNext(); 287 288 CompositableHandle() : mHandle(0) {} 289 CompositableHandle(const CompositableHandle& aOther) = default; 290 explicit CompositableHandle(uint64_t aHandle) : mHandle(aHandle) {} 291 bool IsValid() const { return mHandle != 0; } 292 explicit operator bool() const { return IsValid(); } 293 explicit operator uint64_t() const { return mHandle; } 294 bool operator==(const CompositableHandle& aOther) const { 295 return mHandle == aOther.mHandle; 296 } 297 bool operator!=(const CompositableHandle& aOther) const { 298 return !(*this == aOther); 299 } 300 uint64_t Value() const { return mHandle; } 301 302 private: 303 uint64_t mHandle; 304 }; 305 306 enum class CompositableHandleOwner : uint8_t { 307 WebRenderBridge, 308 ImageBridge, 309 }; 310 311 struct RemoteTextureId { 312 uint64_t mId = 0; 313 314 auto MutTiedFields() { return std::tie(mId); } 315 316 static RemoteTextureId GetNext(); 317 318 static constexpr RemoteTextureId Max() { return RemoteTextureId{UINT64_MAX}; } 319 320 bool IsValid() const { return mId != 0; } 321 322 // Allow explicit cast to a uint64_t for now 323 explicit operator uint64_t() const { return mId; } 324 325 // Implement some operators so this class can be used as a key in 326 // stdlib classes. 327 bool operator<(const RemoteTextureId& aOther) const { 328 return mId < aOther.mId; 329 } 330 331 bool operator>(const RemoteTextureId& aOther) const { 332 return mId > aOther.mId; 333 } 334 335 bool operator==(const RemoteTextureId& aOther) const { 336 return mId == aOther.mId; 337 } 338 339 bool operator!=(const RemoteTextureId& aOther) const { 340 return !(*this == aOther); 341 } 342 343 bool operator>=(const RemoteTextureId& aOther) const { 344 return mId >= aOther.mId; 345 } 346 347 // Helper struct that allow this class to be used as a key in 348 // std::unordered_map like so: 349 // std::unordered_map<RemoteTextureId, ValueType, RemoteTextureId::HashFn> 350 // myMap; 351 struct HashFn { 352 std::size_t operator()(const RemoteTextureId aKey) const { 353 return std::hash<uint64_t>{}(aKey.mId); 354 } 355 }; 356 }; 357 358 struct RemoteTextureOwnerId { 359 uint64_t mId = 0; 360 361 auto MutTiedFields() { return std::tie(mId); } 362 363 static RemoteTextureOwnerId GetNext(); 364 365 bool IsValid() const { return mId != 0; } 366 367 // Allow explicit cast to a uint64_t for now 368 explicit operator uint64_t() const { return mId; } 369 370 // Implement some operators so this class can be used as a key in 371 // stdlib classes. 372 bool operator<(const RemoteTextureOwnerId& aOther) const { 373 return mId < aOther.mId; 374 } 375 376 bool operator==(const RemoteTextureOwnerId& aOther) const { 377 return mId == aOther.mId; 378 } 379 380 bool operator!=(const RemoteTextureOwnerId& aOther) const { 381 return !(*this == aOther); 382 } 383 384 // Helper struct that allow this class to be used as a key in 385 // std::unordered_map like so: 386 // std::unordered_map<RemoteTextureOwnerId, ValueType, 387 // RemoteTextureOwnerId::HashFn> myMap; 388 struct HashFn { 389 std::size_t operator()(const RemoteTextureOwnerId aKey) const { 390 return std::hash<uint64_t>{}(aKey.mId); 391 } 392 }; 393 }; 394 395 struct SurfaceDescriptorRemoteDecoderId { 396 uint64_t mId = 0; 397 398 auto MutTiedFields() { return std::tie(mId); } 399 400 static SurfaceDescriptorRemoteDecoderId GetNext(); 401 402 bool IsValid() const { return mId != 0; } 403 404 // Allow explicit cast to a uint64_t for now 405 explicit operator uint64_t() const { return mId; } 406 407 // Implement some operators so this class can be used as a key in 408 // stdlib classes. 409 bool operator<(const SurfaceDescriptorRemoteDecoderId& aOther) const { 410 return mId < aOther.mId; 411 } 412 413 bool operator==(const SurfaceDescriptorRemoteDecoderId& aOther) const { 414 return mId == aOther.mId; 415 } 416 417 bool operator!=(const SurfaceDescriptorRemoteDecoderId& aOther) const { 418 return !(*this == aOther); 419 } 420 421 // Helper struct that allow this class to be used as a key in 422 // std::unordered_map like so: 423 // std::unordered_map<SurfaceDescriptorRemoteDecoderId, ValueType, 424 // SurfaceDescriptorRemoteDecoderId::HashFn> myMap; 425 struct HashFn { 426 std::size_t operator()(const SurfaceDescriptorRemoteDecoderId aKey) const { 427 return std::hash<uint64_t>{}(aKey.mId); 428 } 429 }; 430 }; 431 432 typedef uint32_t RemoteTextureTxnType; 433 typedef uint64_t RemoteTextureTxnId; 434 435 // TextureId allocated in GPU process 436 struct GpuProcessTextureId { 437 uint64_t mId = 0; 438 439 static GpuProcessTextureId GetNext(); 440 441 bool IsValid() const { return mId != 0; } 442 443 // Allow explicit cast to a uint64_t for now 444 explicit operator uint64_t() const { return mId; } 445 446 bool operator==(const GpuProcessTextureId& aOther) const { 447 return mId == aOther.mId; 448 } 449 450 bool operator!=(const GpuProcessTextureId& aOther) const { 451 return !(*this == aOther); 452 } 453 454 // Helper struct that allow this class to be used as a key in 455 // std::unordered_map like so: 456 // std::unordered_map<GpuProcessTextureId, ValueType, 457 // GpuProcessTextureId::HashFn> myMap; 458 struct HashFn { 459 std::size_t operator()(const GpuProcessTextureId aKey) const { 460 return std::hash<uint64_t>{}(aKey.mId); 461 } 462 }; 463 }; 464 465 // FencesHolderId allocated in GPU process 466 struct CompositeProcessFencesHolderId { 467 uint64_t mId = 0; 468 469 static CompositeProcessFencesHolderId GetNext(); 470 471 bool IsValid() const { return mId != 0; } 472 473 // Allow explicit cast to a uint64_t for now 474 explicit operator uint64_t() const { return mId; } 475 476 bool operator==(const CompositeProcessFencesHolderId& aOther) const { 477 return mId == aOther.mId; 478 } 479 480 bool operator!=(const CompositeProcessFencesHolderId& aOther) const { 481 return !(*this == aOther); 482 } 483 484 // Helper struct that allow this class to be used as a key in 485 // std::unordered_map like so: 486 // std::unordered_map<GpuProcessQueryId, ValueType, 487 // GpuProcessQueryId::HashFn> myMap; 488 struct HashFn { 489 std::size_t operator()(const CompositeProcessFencesHolderId aKey) const { 490 return std::hash<uint64_t>{}(aKey.mId); 491 } 492 }; 493 }; 494 495 // clang-format off 496 MOZ_DEFINE_ENUM_CLASS_WITH_BASE(ScrollDirection, uint8_t, ( 497 eVertical, 498 eHorizontal 499 )); 500 501 std::ostream& operator<<(std::ostream& os, ScrollDirection aDirection); 502 503 using ScrollDirections = EnumSet<ScrollDirection, uint8_t>; 504 505 constexpr ScrollDirections EitherScrollDirection(ScrollDirection::eVertical,ScrollDirection::eHorizontal); 506 constexpr ScrollDirections HorizontalScrollDirection(ScrollDirection::eHorizontal); 507 constexpr ScrollDirections VerticalScrollDirection(ScrollDirection::eVertical); 508 509 // Return the scroll directions which have a nonzero component in |aDelta|. 510 template <typename Point> 511 ScrollDirections DirectionsInDelta(const Point& aDelta) { 512 ScrollDirections result; 513 if (aDelta.x != 0) { 514 result += ScrollDirection::eHorizontal; 515 } 516 if (aDelta.y != 0) { 517 result += ScrollDirection::eVertical; 518 } 519 return result; 520 } 521 522 MOZ_DEFINE_ENUM_CLASS_WITH_BASE(CompositionPayloadType, uint8_t, ( 523 /** 524 * A |CompositionPayload| with this type indicates a key press happened 525 * before composition and will be used to determine latency between key press 526 * and presentation in |mozilla::Telemetry::KEYPRESS_PRESENT_LATENCY| 527 */ 528 eKeyPress, 529 530 /** 531 * A |CompositionPayload| with this type indicates that an APZ scroll event 532 * occurred that will be included in the composition. 533 */ 534 eAPZScroll, 535 536 /** 537 * A |CompositionPayload| with this type indicates that an APZ pinch-to-zoom 538 * event occurred that will be included in the composition. 539 */ 540 eAPZPinchZoom, 541 542 /** 543 * A |CompositionPayload| with this type indicates that content was painted 544 * that will be included in the composition. 545 */ 546 eContentPaint, 547 548 /** 549 * A |CompositionPayload| with this type indicates a mouse up (which caused 550 * a click to happen) happened before composition and will be used to determine latency 551 * between mouse up and presentation in 552 * |mozilla::Telemetry::MOUSEUP_FOLLOWED_BY_CLICK_PRESENT_LATENCY| 553 */ 554 eMouseUpFollowedByClick 555 )); 556 // clang-format on 557 558 extern const char* kCompositionPayloadTypeNames[kCompositionPayloadTypeCount]; 559 560 struct CompositionPayload { 561 bool operator==(const CompositionPayload& aOther) const { 562 return mType == aOther.mType && mTimeStamp == aOther.mTimeStamp; 563 } 564 /* The type of payload that is in this composition */ 565 CompositionPayloadType mType; 566 /* When this payload was generated */ 567 TimeStamp mTimeStamp; 568 }; 569 570 } // namespace layers 571 } // namespace mozilla 572 573 #endif /* GFX_LAYERSTYPES_H */