Bug 1833753 [wpt PR 40065] - Allow newly-added test to also pass when mutation events...
[gecko.git] / gfx / webrender_bindings / WebRenderTypes.h
blobff2c64aefa5092643eebad48694f5a955b110c6f
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 GFX_WEBRENDERTYPES_H
8 #define GFX_WEBRENDERTYPES_H
10 #include "ImageTypes.h"
11 #include "mozilla/webrender/webrender_ffi.h"
12 #include "mozilla/EnumSet.h"
13 #include "mozilla/Maybe.h"
14 #include "mozilla/gfx/Matrix.h"
15 #include "mozilla/gfx/Types.h"
16 #include "mozilla/gfx/Tools.h"
17 #include "mozilla/gfx/Rect.h"
18 #include "mozilla/layers/LayersTypes.h"
19 #include "mozilla/PodOperations.h"
20 #include "mozilla/Range.h"
21 #include "mozilla/ScrollGeneration.h"
22 #include "Units.h"
23 #include "nsIWidgetListener.h"
25 namespace mozilla {
27 enum class StyleBorderStyle : uint8_t;
28 enum class StyleBorderImageRepeat : uint8_t;
29 enum class StyleImageRendering : uint8_t;
31 namespace ipc {
32 class ByteBuf;
33 } // namespace ipc
35 namespace wr {
37 // Using uintptr_t in C++ code for "size" types seems weird, so let's use a
38 // better-sounding typedef. The name comes from the fact that we generally
39 // have to deal with uintptr_t because that's what rust's usize maps to.
40 typedef uintptr_t usize;
42 typedef wr::WrWindowId WindowId;
43 typedef wr::WrRemovedPipeline RemovedPipeline;
45 class RenderedFrameIdType {};
46 typedef layers::BaseTransactionId<RenderedFrameIdType> RenderedFrameId;
48 typedef mozilla::Maybe<mozilla::wr::IdNamespace> MaybeIdNamespace;
49 typedef mozilla::Maybe<mozilla::wr::ImageMask> MaybeImageMask;
50 typedef Maybe<ExternalImageId> MaybeExternalImageId;
52 typedef Maybe<FontInstanceOptions> MaybeFontInstanceOptions;
53 typedef Maybe<FontInstancePlatformOptions> MaybeFontInstancePlatformOptions;
55 struct ExternalImageKeyPair {
56 ImageKey key;
57 ExternalImageId id;
60 /* Generate a brand new window id and return it. */
61 WindowId NewWindowId();
63 inline bool WindowSizeSanityCheck(int32_t aWidth, int32_t aHeight) {
64 if (aWidth < 0 || aWidth > wr::MAX_RENDER_TASK_SIZE || aHeight < 0 ||
65 aHeight > wr::MAX_RENDER_TASK_SIZE) {
66 return false;
68 return true;
71 inline DebugFlags NewDebugFlags(uint32_t aFlags) { return {aFlags}; }
73 inline Maybe<wr::ImageFormat> SurfaceFormatToImageFormat(
74 gfx::SurfaceFormat aFormat) {
75 switch (aFormat) {
76 case gfx::SurfaceFormat::R8G8B8X8:
77 // WebRender not support RGBX8. Assert here.
78 MOZ_ASSERT(false);
79 return Nothing();
80 case gfx::SurfaceFormat::R8G8B8A8:
81 return Some(wr::ImageFormat::RGBA8);
82 case gfx::SurfaceFormat::B8G8R8X8:
83 // TODO: WebRender will have a BGRA + opaque flag for this but does not
84 // have it yet (cf. issue #732).
85 case gfx::SurfaceFormat::B8G8R8A8:
86 return Some(wr::ImageFormat::BGRA8);
87 case gfx::SurfaceFormat::A8:
88 return Some(wr::ImageFormat::R8);
89 case gfx::SurfaceFormat::A16:
90 return Some(wr::ImageFormat::R16);
91 case gfx::SurfaceFormat::R8G8:
92 return Some(wr::ImageFormat::RG8);
93 case gfx::SurfaceFormat::R16G16:
94 return Some(wr::ImageFormat::RG16);
95 case gfx::SurfaceFormat::UNKNOWN:
96 default:
97 return Nothing();
101 inline gfx::SurfaceFormat ImageFormatToSurfaceFormat(ImageFormat aFormat) {
102 switch (aFormat) {
103 case ImageFormat::BGRA8:
104 return gfx::SurfaceFormat::B8G8R8A8;
105 case ImageFormat::R8:
106 return gfx::SurfaceFormat::A8;
107 case ImageFormat::R16:
108 return gfx::SurfaceFormat::A16;
109 default:
110 return gfx::SurfaceFormat::UNKNOWN;
114 // This extra piece of data is used to differentiate when spatial nodes that are
115 // created by Gecko that have the same mFrame and PerFrameKey. This currently
116 // only occurs with sticky display list items that are also zoomable, which
117 // results in Gecko creating both a sticky spatial node, and then a property
118 // animated reference frame for APZ
119 enum class SpatialKeyKind : uint32_t {
120 Transform,
121 Perspective,
122 Scroll,
123 Sticky,
124 ImagePipeline,
125 APZ,
128 // Construct a unique, persistent spatial key based on the frame tree pointer,
129 // per-frame key and a spatial key kind. For now, this covers all the ways Gecko
130 // creates spatial nodes. In future, we may need to be more clever with the
131 // SpatialKeyKind.
132 inline wr::SpatialTreeItemKey SpatialKey(uint64_t aFrame, uint32_t aPerFrameKey,
133 SpatialKeyKind aKind) {
134 return wr::SpatialTreeItemKey{
135 aFrame, uint64_t(aPerFrameKey) | (uint64_t(aKind) << 32)};
138 struct ImageDescriptor : public wr::WrImageDescriptor {
139 // We need a default constructor for ipdl serialization.
140 ImageDescriptor() {
141 format = (ImageFormat)0;
142 width = 0;
143 height = 0;
144 stride = 0;
145 opacity = OpacityType::HasAlphaChannel;
146 prefer_compositor_surface = false;
149 ImageDescriptor(const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat,
150 bool aPreferCompositorSurface = false) {
151 format = wr::SurfaceFormatToImageFormat(aFormat).valueOr((ImageFormat)0);
152 width = aSize.width;
153 height = aSize.height;
154 stride = 0;
155 opacity = gfx::IsOpaque(aFormat) ? OpacityType::Opaque
156 : OpacityType::HasAlphaChannel;
157 prefer_compositor_surface = aPreferCompositorSurface;
160 ImageDescriptor(const gfx::IntSize& aSize, uint32_t aByteStride,
161 gfx::SurfaceFormat aFormat,
162 bool aPreferCompositorSurface = false) {
163 format = wr::SurfaceFormatToImageFormat(aFormat).valueOr((ImageFormat)0);
164 width = aSize.width;
165 height = aSize.height;
166 stride = aByteStride;
167 opacity = gfx::IsOpaque(aFormat) ? OpacityType::Opaque
168 : OpacityType::HasAlphaChannel;
169 prefer_compositor_surface = aPreferCompositorSurface;
172 ImageDescriptor(const gfx::IntSize& aSize, uint32_t aByteStride,
173 gfx::SurfaceFormat aFormat, OpacityType aOpacity,
174 bool aPreferCompositorSurface = false) {
175 format = wr::SurfaceFormatToImageFormat(aFormat).valueOr((ImageFormat)0);
176 width = aSize.width;
177 height = aSize.height;
178 stride = aByteStride;
179 opacity = aOpacity;
180 prefer_compositor_surface = aPreferCompositorSurface;
184 inline uint64_t AsUint64(const NativeSurfaceId& aId) {
185 return static_cast<uint64_t>(aId._0);
188 // Whenever possible, use wr::WindowId instead of manipulating uint64_t.
189 inline uint64_t AsUint64(const WindowId& aId) {
190 return static_cast<uint64_t>(aId.mHandle);
193 // Whenever possible, use wr::ImageKey instead of manipulating uint64_t.
194 inline uint64_t AsUint64(const ImageKey& aId) {
195 return (static_cast<uint64_t>(aId.mNamespace.mHandle) << 32) +
196 static_cast<uint64_t>(aId.mHandle);
199 inline ImageKey AsImageKey(const uint64_t& aId) {
200 ImageKey imageKey;
201 imageKey.mNamespace.mHandle = aId >> 32;
202 imageKey.mHandle = aId;
203 return imageKey;
206 // Whenever possible, use wr::FontKey instead of manipulating uint64_t.
207 inline uint64_t AsUint64(const FontKey& aId) {
208 return (static_cast<uint64_t>(aId.mNamespace.mHandle) << 32) +
209 static_cast<uint64_t>(aId.mHandle);
212 inline FontKey AsFontKey(const uint64_t& aId) {
213 FontKey fontKey;
214 fontKey.mNamespace.mHandle = aId >> 32;
215 fontKey.mHandle = aId;
216 return fontKey;
219 // Whenever possible, use wr::FontInstanceKey instead of manipulating uint64_t.
220 inline uint64_t AsUint64(const FontInstanceKey& aId) {
221 return (static_cast<uint64_t>(aId.mNamespace.mHandle) << 32) +
222 static_cast<uint64_t>(aId.mHandle);
225 inline FontInstanceKey AsFontInstanceKey(const uint64_t& aId) {
226 FontInstanceKey instanceKey;
227 instanceKey.mNamespace.mHandle = aId >> 32;
228 instanceKey.mHandle = aId;
229 return instanceKey;
232 // Whenever possible, use wr::PipelineId instead of manipulating uint64_t.
233 inline uint64_t AsUint64(const PipelineId& aId) {
234 return (static_cast<uint64_t>(aId.mNamespace) << 32) +
235 static_cast<uint64_t>(aId.mHandle);
238 inline PipelineId AsPipelineId(const uint64_t& aId) {
239 PipelineId pipeline;
240 pipeline.mNamespace = aId >> 32;
241 pipeline.mHandle = aId;
242 return pipeline;
245 inline mozilla::layers::LayersId AsLayersId(const PipelineId& aId) {
246 return mozilla::layers::LayersId{AsUint64(aId)};
249 inline PipelineId AsPipelineId(const mozilla::layers::LayersId& aId) {
250 return AsPipelineId(uint64_t(aId));
253 ImageRendering ToImageRendering(StyleImageRendering);
255 static inline FontRenderMode ToFontRenderMode(gfx::AntialiasMode aMode,
256 bool aPermitSubpixelAA = true) {
257 switch (aMode) {
258 case gfx::AntialiasMode::NONE:
259 return FontRenderMode::Mono;
260 case gfx::AntialiasMode::GRAY:
261 return FontRenderMode::Alpha;
262 case gfx::AntialiasMode::SUBPIXEL:
263 default:
264 return aPermitSubpixelAA ? FontRenderMode::Subpixel
265 : FontRenderMode::Alpha;
269 static inline MixBlendMode ToMixBlendMode(gfx::CompositionOp compositionOp) {
270 switch (compositionOp) {
271 case gfx::CompositionOp::OP_MULTIPLY:
272 return MixBlendMode::Multiply;
273 case gfx::CompositionOp::OP_SCREEN:
274 return MixBlendMode::Screen;
275 case gfx::CompositionOp::OP_OVERLAY:
276 return MixBlendMode::Overlay;
277 case gfx::CompositionOp::OP_DARKEN:
278 return MixBlendMode::Darken;
279 case gfx::CompositionOp::OP_LIGHTEN:
280 return MixBlendMode::Lighten;
281 case gfx::CompositionOp::OP_COLOR_DODGE:
282 return MixBlendMode::ColorDodge;
283 case gfx::CompositionOp::OP_COLOR_BURN:
284 return MixBlendMode::ColorBurn;
285 case gfx::CompositionOp::OP_HARD_LIGHT:
286 return MixBlendMode::HardLight;
287 case gfx::CompositionOp::OP_SOFT_LIGHT:
288 return MixBlendMode::SoftLight;
289 case gfx::CompositionOp::OP_DIFFERENCE:
290 return MixBlendMode::Difference;
291 case gfx::CompositionOp::OP_EXCLUSION:
292 return MixBlendMode::Exclusion;
293 case gfx::CompositionOp::OP_HUE:
294 return MixBlendMode::Hue;
295 case gfx::CompositionOp::OP_SATURATION:
296 return MixBlendMode::Saturation;
297 case gfx::CompositionOp::OP_COLOR:
298 return MixBlendMode::Color;
299 case gfx::CompositionOp::OP_LUMINOSITY:
300 return MixBlendMode::Luminosity;
301 case gfx::CompositionOp::OP_ADD:
302 return MixBlendMode::PlusLighter;
303 default:
304 return MixBlendMode::Normal;
308 static inline wr::ColorF ToColorF(const gfx::DeviceColor& color) {
309 wr::ColorF c;
310 c.r = color.r;
311 c.g = color.g;
312 c.b = color.b;
313 c.a = color.a;
314 return c;
317 static inline wr::ColorU ToColorU(const gfx::DeviceColor& color) {
318 wr::ColorU c;
319 c.r = uint8_t(color.r * 255.0f);
320 c.g = uint8_t(color.g * 255.0f);
321 c.b = uint8_t(color.b * 255.0f);
322 c.a = uint8_t(color.a * 255.0f);
323 return c;
326 static inline wr::LayoutPoint ToLayoutPoint(
327 const mozilla::LayoutDevicePoint& point) {
328 wr::LayoutPoint p;
329 p.x = point.x;
330 p.y = point.y;
331 return p;
334 static inline wr::LayoutPoint ToLayoutPoint(
335 const mozilla::LayoutDeviceIntPoint& point) {
336 return ToLayoutPoint(LayoutDevicePoint(point));
339 static inline wr::WorldPoint ToWorldPoint(const mozilla::ScreenPoint& point) {
340 wr::WorldPoint p;
341 p.x = point.x;
342 p.y = point.y;
343 return p;
346 static inline wr::LayoutVector2D ToLayoutVector2D(
347 const mozilla::LayoutDevicePoint& point) {
348 wr::LayoutVector2D p;
349 p.x = point.x;
350 p.y = point.y;
351 return p;
354 static inline wr::LayoutVector2D ToLayoutVector2D(
355 const mozilla::LayoutDeviceIntPoint& point) {
356 return ToLayoutVector2D(LayoutDevicePoint(point));
359 static inline wr::LayoutRect ToLayoutRect(
360 const mozilla::LayoutDeviceRect& rect) {
361 wr::LayoutRect r;
362 r.min.x = rect.X();
363 r.min.y = rect.Y();
364 r.max.x = rect.X() + rect.Width();
365 r.max.y = rect.Y() + rect.Height();
366 return r;
369 static inline wr::LayoutRect ToLayoutRect(const gfx::Rect& rect) {
370 wr::LayoutRect r;
371 r.min.x = rect.X();
372 r.min.y = rect.Y();
373 r.max.x = rect.X() + rect.Width();
374 r.max.y = rect.Y() + rect.Height();
375 return r;
378 static inline wr::DeviceIntRect ToDeviceIntRect(
379 const mozilla::ImageIntRect& rect) {
380 wr::DeviceIntRect r;
381 r.min.x = rect.X();
382 r.min.y = rect.Y();
383 r.max.x = rect.X() + rect.Width();
384 r.max.y = rect.Y() + rect.Height();
385 return r;
388 // TODO: should be const LayoutDeviceIntRect instead of ImageIntRect
389 static inline wr::LayoutIntRect ToLayoutIntRect(
390 const mozilla::ImageIntRect& rect) {
391 wr::LayoutIntRect r;
392 r.min.x = rect.X();
393 r.min.y = rect.Y();
394 r.max.x = rect.X() + rect.Width();
395 r.max.y = rect.Y() + rect.Height();
396 return r;
399 static inline wr::LayoutRect ToLayoutRect(
400 const mozilla::LayoutDeviceIntRect& rect) {
401 return ToLayoutRect(IntRectToRect(rect));
404 static inline wr::LayoutRect IntersectLayoutRect(const wr::LayoutRect& aRect,
405 const wr::LayoutRect& aOther) {
406 wr::LayoutRect r;
407 r.min.x = std::max(aRect.min.x, aOther.min.x);
408 r.min.y = std::max(aRect.min.y, aOther.min.y);
409 r.max.x = std::min(aRect.max.x, aOther.max.x);
410 r.max.y = std::min(aRect.max.y, aOther.max.y);
412 if (r.max.x < r.min.x || r.max.y < r.min.y) {
413 r.max.x = r.min.x;
414 r.max.y = r.min.y;
416 return r;
419 static inline wr::LayoutSize ToLayoutSize(
420 const mozilla::LayoutDeviceSize& size) {
421 wr::LayoutSize ls;
422 ls.width = size.width;
423 ls.height = size.height;
424 return ls;
427 static inline wr::ComplexClipRegion ToComplexClipRegion(
428 const gfx::RoundedRect& rect) {
429 wr::ComplexClipRegion ret;
430 ret.rect = ToLayoutRect(rect.rect);
431 ret.radii.top_left = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(
432 rect.corners.radii[mozilla::eCornerTopLeft]));
433 ret.radii.top_right = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(
434 rect.corners.radii[mozilla::eCornerTopRight]));
435 ret.radii.bottom_left = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(
436 rect.corners.radii[mozilla::eCornerBottomLeft]));
437 ret.radii.bottom_right = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(
438 rect.corners.radii[mozilla::eCornerBottomRight]));
439 ret.mode = wr::ClipMode::Clip;
440 return ret;
443 static inline wr::ComplexClipRegion SimpleRadii(const wr::LayoutRect& aRect,
444 float aRadii) {
445 wr::ComplexClipRegion ret;
446 wr::LayoutSize radii{aRadii, aRadii};
447 ret.rect = aRect;
448 ret.radii.top_left = radii;
449 ret.radii.top_right = radii;
450 ret.radii.bottom_left = radii;
451 ret.radii.bottom_right = radii;
452 ret.mode = wr::ClipMode::Clip;
453 return ret;
456 static inline wr::LayoutSize ToLayoutSize(
457 const mozilla::LayoutDeviceIntSize& size) {
458 return ToLayoutSize(LayoutDeviceSize(size));
461 template <class S, class T>
462 static inline wr::LayoutTransform ToLayoutTransform(
463 const gfx::Matrix4x4Typed<S, T>& m) {
464 wr::LayoutTransform transform;
465 transform.m11 = m._11;
466 transform.m12 = m._12;
467 transform.m13 = m._13;
468 transform.m14 = m._14;
469 transform.m21 = m._21;
470 transform.m22 = m._22;
471 transform.m23 = m._23;
472 transform.m24 = m._24;
473 transform.m31 = m._31;
474 transform.m32 = m._32;
475 transform.m33 = m._33;
476 transform.m34 = m._34;
477 transform.m41 = m._41;
478 transform.m42 = m._42;
479 transform.m43 = m._43;
480 transform.m44 = m._44;
481 return transform;
484 wr::BorderStyle ToBorderStyle(StyleBorderStyle style);
486 static inline wr::BorderSide ToBorderSide(const gfx::DeviceColor& color,
487 StyleBorderStyle style) {
488 wr::BorderSide bs;
489 bs.color = ToColorF(color);
490 bs.style = ToBorderStyle(style);
491 return bs;
494 static inline wr::BorderRadius EmptyBorderRadius() {
495 wr::BorderRadius br;
496 PodZero(&br);
497 return br;
500 static inline wr::BorderRadius ToBorderRadius(
501 const LayoutDeviceSize& topLeft, const LayoutDeviceSize& topRight,
502 const LayoutDeviceSize& bottomLeft, const LayoutDeviceSize& bottomRight) {
503 wr::BorderRadius br;
504 br.top_left = ToLayoutSize(topLeft);
505 br.top_right = ToLayoutSize(topRight);
506 br.bottom_left = ToLayoutSize(bottomLeft);
507 br.bottom_right = ToLayoutSize(bottomRight);
508 return br;
511 static inline wr::BorderRadius ToBorderRadius(
512 const gfx::RectCornerRadii& aRadii) {
513 return ToBorderRadius(LayoutDeviceSize::FromUnknownSize(aRadii[0]),
514 LayoutDeviceSize::FromUnknownSize(aRadii[1]),
515 LayoutDeviceSize::FromUnknownSize(aRadii[3]),
516 LayoutDeviceSize::FromUnknownSize(aRadii[2]));
519 static inline wr::ComplexClipRegion ToComplexClipRegion(
520 const nsRect& aRect, const nscoord* aRadii, int32_t aAppUnitsPerDevPixel) {
521 wr::ComplexClipRegion ret;
522 ret.rect =
523 ToLayoutRect(LayoutDeviceRect::FromAppUnits(aRect, aAppUnitsPerDevPixel));
524 ret.radii = ToBorderRadius(
525 LayoutDeviceSize::FromAppUnits(
526 nsSize(aRadii[eCornerTopLeftX], aRadii[eCornerTopLeftY]),
527 aAppUnitsPerDevPixel),
528 LayoutDeviceSize::FromAppUnits(
529 nsSize(aRadii[eCornerTopRightX], aRadii[eCornerTopRightY]),
530 aAppUnitsPerDevPixel),
531 LayoutDeviceSize::FromAppUnits(
532 nsSize(aRadii[eCornerBottomLeftX], aRadii[eCornerBottomLeftY]),
533 aAppUnitsPerDevPixel),
534 LayoutDeviceSize::FromAppUnits(
535 nsSize(aRadii[eCornerBottomRightX], aRadii[eCornerBottomRightY]),
536 aAppUnitsPerDevPixel));
537 ret.mode = ClipMode::Clip;
538 return ret;
541 static inline wr::LayoutSideOffsets ToBorderWidths(float top, float right,
542 float bottom, float left) {
543 wr::LayoutSideOffsets bw;
544 bw.top = top;
545 bw.right = right;
546 bw.bottom = bottom;
547 bw.left = left;
548 return bw;
551 static inline wr::DeviceIntSideOffsets ToDeviceIntSideOffsets(int32_t top,
552 int32_t right,
553 int32_t bottom,
554 int32_t left) {
555 wr::DeviceIntSideOffsets offset;
556 offset.top = top;
557 offset.right = right;
558 offset.bottom = bottom;
559 offset.left = left;
560 return offset;
563 static inline wr::LayoutSideOffsets ToLayoutSideOffsets(float top, float right,
564 float bottom,
565 float left) {
566 wr::LayoutSideOffsets offset;
567 offset.top = top;
568 offset.right = right;
569 offset.bottom = bottom;
570 offset.left = left;
571 return offset;
574 wr::RepeatMode ToRepeatMode(StyleBorderImageRepeat);
576 template <class S, class T>
577 static inline wr::WrTransformProperty ToWrTransformProperty(
578 uint64_t id, const gfx::Matrix4x4Typed<S, T>& transform) {
579 wr::WrTransformProperty prop;
580 prop.id = id;
581 prop.value = ToLayoutTransform(transform);
582 return prop;
585 static inline wr::WrOpacityProperty ToWrOpacityProperty(uint64_t id,
586 const float opacity) {
587 wr::WrOpacityProperty prop;
588 prop.id = id;
589 prop.value = opacity;
590 return prop;
593 static inline wr::WrColorProperty ToWrColorProperty(
594 uint64_t id, const gfx::DeviceColor& color) {
595 wr::WrColorProperty prop;
596 prop.id = id;
597 prop.value = ToColorF(color);
598 return prop;
601 // Whenever possible, use wr::ExternalImageId instead of manipulating uint64_t.
602 inline uint64_t AsUint64(const ExternalImageId& aId) {
603 return static_cast<uint64_t>(aId._0);
606 static inline ExternalImageId ToExternalImageId(uint64_t aID) {
607 ExternalImageId Id;
608 Id._0 = aID;
609 return Id;
612 static inline wr::WrExternalImage RawDataToWrExternalImage(const uint8_t* aBuff,
613 size_t size) {
614 return wr::WrExternalImage{
615 wr::WrExternalImageType::RawData, 0, 0.0f, 0.0f, 0.0f, 0.0f, aBuff, size};
618 static inline wr::WrExternalImage NativeTextureToWrExternalImage(
619 uint32_t aHandle, float u0, float v0, float u1, float v1) {
620 return wr::WrExternalImage{wr::WrExternalImageType::NativeTexture,
621 aHandle,
626 nullptr,
630 static inline wr::WrExternalImage InvalidToWrExternalImage() {
631 return wr::WrExternalImage{
632 wr::WrExternalImageType::Invalid, 0, 0, 0, 0, 0, nullptr, 0};
635 inline wr::ByteSlice RangeToByteSlice(mozilla::Range<uint8_t> aRange) {
636 return wr::ByteSlice{aRange.begin().get(), aRange.length()};
639 inline mozilla::Range<const uint8_t> ByteSliceToRange(wr::ByteSlice aWrSlice) {
640 return mozilla::Range<const uint8_t>(aWrSlice.buffer, aWrSlice.len);
643 inline mozilla::Range<uint8_t> MutByteSliceToRange(wr::MutByteSlice aWrSlice) {
644 return mozilla::Range<uint8_t>(aWrSlice.buffer, aWrSlice.len);
647 void Assign_WrVecU8(wr::WrVecU8& aVec, mozilla::ipc::ByteBuf&& aOther);
649 template <typename T>
650 struct Vec;
652 template <>
653 struct Vec<uint8_t> final {
654 wr::WrVecU8 inner;
655 Vec() { SetEmpty(); }
656 Vec(Vec&) = delete;
657 Vec(Vec&& src) {
658 inner = src.inner;
659 src.SetEmpty();
662 explicit Vec(mozilla::ipc::ByteBuf&& aSrc) {
663 Assign_WrVecU8(inner, std::move(aSrc));
666 Vec& operator=(Vec&& src) {
667 inner = src.inner;
668 src.SetEmpty();
669 return *this;
672 wr::WrVecU8 Extract() {
673 wr::WrVecU8 ret = inner;
674 SetEmpty();
675 return ret;
678 void SetEmpty() {
679 inner.data = (uint8_t*)1;
680 inner.capacity = 0;
681 inner.length = 0;
684 uint8_t* Data() { return inner.data; }
686 size_t Length() { return inner.length; }
688 size_t Capacity() { return inner.capacity; }
690 Range<uint8_t> GetRange() { return Range<uint8_t>(Data(), Length()); }
692 void PushBytes(Range<uint8_t> aBytes) {
693 wr_vec_u8_push_bytes(&inner, RangeToByteSlice(aBytes));
696 void Reserve(size_t aLength) { wr_vec_u8_reserve(&inner, aLength); }
698 ~Vec() {
699 if (inner.data) {
700 wr_vec_u8_free(inner);
705 struct ByteBuffer {
706 ByteBuffer(size_t aLength, uint8_t* aData)
707 : mLength(aLength), mData(aData), mOwned(false) {}
709 // XXX: this is a bit of hack that assumes
710 // the allocators are the same
711 explicit ByteBuffer(VecU8&& vec) {
712 if (vec.inner.capacity) {
713 mLength = vec.inner.length;
714 mData = vec.inner.data;
715 vec.inner.data = nullptr;
716 vec.inner.capacity = 0;
717 mOwned = true;
718 } else {
719 mOwned = false;
720 mData = nullptr;
721 mLength = 0;
725 ByteBuffer(ByteBuffer&& aFrom)
726 : mLength(aFrom.mLength), mData(aFrom.mData), mOwned(aFrom.mOwned) {
727 aFrom.mLength = 0;
728 aFrom.mData = nullptr;
729 aFrom.mOwned = false;
732 ByteBuffer(ByteBuffer& aFrom)
733 : mLength(aFrom.mLength), mData(aFrom.mData), mOwned(aFrom.mOwned) {
734 aFrom.mLength = 0;
735 aFrom.mData = nullptr;
736 aFrom.mOwned = false;
739 ByteBuffer() : mLength(0), mData(nullptr), mOwned(false) {}
741 bool Allocate(size_t aLength) {
742 MOZ_ASSERT(mData == nullptr);
743 mData = (uint8_t*)malloc(aLength);
744 if (!mData) {
745 return false;
747 mLength = aLength;
748 mOwned = true;
749 return true;
752 ~ByteBuffer() {
753 if (mData && mOwned) {
754 free(mData);
758 const Range<uint8_t> AsSlice() const {
759 return Range<uint8_t>(mData, mLength);
762 Range<uint8_t> AsSlice() { return Range<uint8_t>(mData, mLength); }
764 bool operator==(const ByteBuffer& other) const {
765 return mLength == other.mLength && !(memcmp(mData, other.mData, mLength));
768 size_t mLength;
769 uint8_t* mData;
770 bool mOwned;
773 struct BuiltDisplayList {
774 wr::VecU8 dl_items;
775 wr::VecU8 dl_cache;
776 wr::VecU8 dl_spatial_tree;
777 wr::BuiltDisplayListDescriptor dl_desc;
780 // Corresponds to a clip id for a clip chain in webrender. Similar to
781 // WrClipId but a separate struct so we don't get them mixed up in C++.
782 struct WrClipChainId {
783 uint64_t id;
785 bool operator==(const WrClipChainId& other) const { return id == other.id; }
787 static WrClipChainId Empty() {
788 WrClipChainId id = {0};
789 return id;
793 WrSpatialId RootScrollNode();
794 WrSpaceAndClipChain RootScrollNodeWithChain();
795 WrSpaceAndClipChain InvalidScrollNodeWithChain();
797 enum class WebRenderError : int8_t {
798 INITIALIZE = 0,
799 MAKE_CURRENT,
800 RENDER,
801 NEW_SURFACE,
802 BEGIN_DRAW,
803 VIDEO_OVERLAY,
804 EXCESSIVE_RESETS,
806 Sentinel /* this must be last for serialization purposes. */
809 static inline wr::WrYuvColorSpace ToWrYuvColorSpace(
810 gfx::YUVColorSpace aYUVColorSpace) {
811 switch (aYUVColorSpace) {
812 case gfx::YUVColorSpace::BT601:
813 return wr::WrYuvColorSpace::Rec601;
814 case gfx::YUVColorSpace::BT709:
815 return wr::WrYuvColorSpace::Rec709;
816 case gfx::YUVColorSpace::BT2020:
817 return wr::WrYuvColorSpace::Rec2020;
818 case gfx::YUVColorSpace::Identity:
819 return wr::WrYuvColorSpace::Identity;
820 default:
821 MOZ_ASSERT_UNREACHABLE("Tried to convert invalid YUVColorSpace.");
823 return wr::WrYuvColorSpace::Rec601;
826 // TODO: Use YUVRangedColorSpace instead of assuming ColorRange::LIMITED.
827 static inline wr::YuvRangedColorSpace ToWrYuvRangedColorSpace(
828 gfx::YUVRangedColorSpace aFrom) {
829 switch (aFrom) {
830 case gfx::YUVRangedColorSpace::BT601_Narrow:
831 return wr::YuvRangedColorSpace::Rec601Narrow;
832 case gfx::YUVRangedColorSpace::BT601_Full:
833 return wr::YuvRangedColorSpace::Rec601Full;
834 case gfx::YUVRangedColorSpace::BT709_Narrow:
835 return wr::YuvRangedColorSpace::Rec709Narrow;
836 case gfx::YUVRangedColorSpace::BT709_Full:
837 return wr::YuvRangedColorSpace::Rec709Full;
838 case gfx::YUVRangedColorSpace::BT2020_Narrow:
839 return wr::YuvRangedColorSpace::Rec2020Narrow;
840 case gfx::YUVRangedColorSpace::BT2020_Full:
841 return wr::YuvRangedColorSpace::Rec2020Full;
842 case gfx::YUVRangedColorSpace::GbrIdentity:
843 break;
844 default:
845 MOZ_ASSERT_UNREACHABLE("Tried to convert invalid YUVColorSpace.");
846 break;
848 return wr::YuvRangedColorSpace::GbrIdentity;
851 static inline wr::WrColorDepth ToWrColorDepth(gfx::ColorDepth aColorDepth) {
852 switch (aColorDepth) {
853 case gfx::ColorDepth::COLOR_8:
854 return wr::WrColorDepth::Color8;
855 case gfx::ColorDepth::COLOR_10:
856 return wr::WrColorDepth::Color10;
857 case gfx::ColorDepth::COLOR_12:
858 return wr::WrColorDepth::Color12;
859 case gfx::ColorDepth::COLOR_16:
860 return wr::WrColorDepth::Color16;
861 default:
862 MOZ_ASSERT_UNREACHABLE("Tried to convert invalid color depth value.");
864 return wr::WrColorDepth::Color8;
867 static inline wr::WrColorRange ToWrColorRange(gfx::ColorRange aColorRange) {
868 switch (aColorRange) {
869 case gfx::ColorRange::LIMITED:
870 return wr::WrColorRange::Limited;
871 case gfx::ColorRange::FULL:
872 return wr::WrColorRange::Full;
873 default:
874 MOZ_ASSERT_UNREACHABLE("Tried to convert invalid color range value.");
875 return wr ::WrColorRange::Limited;
879 static inline wr::SyntheticItalics DegreesToSyntheticItalics(float aDegrees) {
880 wr::SyntheticItalics synthetic_italics;
881 synthetic_italics.angle =
882 int16_t(std::min(std::max(aDegrees, -89.0f), 89.0f) * 256.0f);
883 return synthetic_italics;
886 static inline wr::WindowSizeMode ToWrWindowSizeMode(nsSizeMode aSizeMode) {
887 switch (aSizeMode) {
888 case nsSizeMode_Normal:
889 return wr::WindowSizeMode::Normal;
890 case nsSizeMode_Minimized:
891 return wr::WindowSizeMode::Minimized;
892 case nsSizeMode_Maximized:
893 return wr::WindowSizeMode::Maximized;
894 case nsSizeMode_Fullscreen:
895 return wr::WindowSizeMode::Fullscreen;
896 default:
897 MOZ_ASSERT_UNREACHABLE("Tried to convert invalid size mode.");
898 return wr::WindowSizeMode::Invalid;
902 static inline wr::APZScrollGeneration ToWrAPZScrollGeneration(
903 const mozilla::APZScrollGeneration& aGeneration) {
904 return wr::APZScrollGeneration(aGeneration.Raw());
907 static inline wr::HasScrollLinkedEffect ToWrHasScrollLinkedEffect(
908 bool aHasScrollLinkedEffect) {
909 return aHasScrollLinkedEffect ? wr::HasScrollLinkedEffect::Yes
910 : wr::HasScrollLinkedEffect::No;
913 } // namespace wr
914 } // namespace mozilla
916 namespace std {
917 template <>
918 struct hash<mozilla::wr::WrSpatialId> {
919 std::size_t operator()(mozilla::wr::WrSpatialId const& aKey) const noexcept {
920 return std::hash<size_t>{}(aKey.id);
923 } // namespace std
925 #endif /* GFX_WEBRENDERTYPES_H */