no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / gfx / webrender_bindings / WebRenderTypes.h
blob3216a0afd61d56312e038b1f936025f03e291271
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::LayoutPoint ToLayoutPoint(
318 const mozilla::LayoutDevicePoint& point) {
319 wr::LayoutPoint p;
320 p.x = point.x;
321 p.y = point.y;
322 return p;
325 static inline wr::LayoutPoint ToLayoutPoint(
326 const mozilla::LayoutDeviceIntPoint& point) {
327 return ToLayoutPoint(LayoutDevicePoint(point));
330 static inline wr::WorldPoint ToWorldPoint(const mozilla::ScreenPoint& point) {
331 wr::WorldPoint p;
332 p.x = point.x;
333 p.y = point.y;
334 return p;
337 static inline wr::LayoutVector2D ToLayoutVector2D(
338 const mozilla::LayoutDevicePoint& point) {
339 wr::LayoutVector2D p;
340 p.x = point.x;
341 p.y = point.y;
342 return p;
345 static inline wr::LayoutVector2D ToLayoutVector2D(
346 const mozilla::LayoutDeviceIntPoint& point) {
347 return ToLayoutVector2D(LayoutDevicePoint(point));
350 static inline wr::LayoutRect ToLayoutRect(
351 const mozilla::LayoutDeviceRect& rect) {
352 wr::LayoutRect r;
353 r.min.x = rect.X();
354 r.min.y = rect.Y();
355 r.max.x = rect.X() + rect.Width();
356 r.max.y = rect.Y() + rect.Height();
357 return r;
360 static inline wr::LayoutRect ToLayoutRect(const gfx::Rect& 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::DeviceIntRect ToDeviceIntRect(
370 const mozilla::ImageIntRect& rect) {
371 wr::DeviceIntRect r;
372 r.min.x = rect.X();
373 r.min.y = rect.Y();
374 r.max.x = rect.X() + rect.Width();
375 r.max.y = rect.Y() + rect.Height();
376 return r;
379 // TODO: should be const LayoutDeviceIntRect instead of ImageIntRect
380 static inline wr::LayoutIntRect ToLayoutIntRect(
381 const mozilla::ImageIntRect& rect) {
382 wr::LayoutIntRect r;
383 r.min.x = rect.X();
384 r.min.y = rect.Y();
385 r.max.x = rect.X() + rect.Width();
386 r.max.y = rect.Y() + rect.Height();
387 return r;
390 static inline wr::LayoutRect ToLayoutRect(
391 const mozilla::LayoutDeviceIntRect& rect) {
392 return ToLayoutRect(IntRectToRect(rect));
395 static inline wr::LayoutRect IntersectLayoutRect(const wr::LayoutRect& aRect,
396 const wr::LayoutRect& aOther) {
397 wr::LayoutRect r;
398 r.min.x = std::max(aRect.min.x, aOther.min.x);
399 r.min.y = std::max(aRect.min.y, aOther.min.y);
400 r.max.x = std::min(aRect.max.x, aOther.max.x);
401 r.max.y = std::min(aRect.max.y, aOther.max.y);
403 if (r.max.x < r.min.x || r.max.y < r.min.y) {
404 r.max.x = r.min.x;
405 r.max.y = r.min.y;
407 return r;
410 static inline wr::LayoutSize ToLayoutSize(
411 const mozilla::LayoutDeviceSize& size) {
412 wr::LayoutSize ls;
413 ls.width = size.width;
414 ls.height = size.height;
415 return ls;
418 static inline wr::ComplexClipRegion ToComplexClipRegion(
419 const gfx::RoundedRect& rect) {
420 wr::ComplexClipRegion ret;
421 ret.rect = ToLayoutRect(rect.rect);
422 ret.radii.top_left = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(
423 rect.corners.radii[mozilla::eCornerTopLeft]));
424 ret.radii.top_right = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(
425 rect.corners.radii[mozilla::eCornerTopRight]));
426 ret.radii.bottom_left = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(
427 rect.corners.radii[mozilla::eCornerBottomLeft]));
428 ret.radii.bottom_right = ToLayoutSize(LayoutDeviceSize::FromUnknownSize(
429 rect.corners.radii[mozilla::eCornerBottomRight]));
430 ret.mode = wr::ClipMode::Clip;
431 return ret;
434 static inline wr::ComplexClipRegion SimpleRadii(const wr::LayoutRect& aRect,
435 float aRadii) {
436 wr::ComplexClipRegion ret;
437 wr::LayoutSize radii{aRadii, aRadii};
438 ret.rect = aRect;
439 ret.radii.top_left = radii;
440 ret.radii.top_right = radii;
441 ret.radii.bottom_left = radii;
442 ret.radii.bottom_right = radii;
443 ret.mode = wr::ClipMode::Clip;
444 return ret;
447 static inline wr::LayoutSize ToLayoutSize(
448 const mozilla::LayoutDeviceIntSize& size) {
449 return ToLayoutSize(LayoutDeviceSize(size));
452 template <class S, class T>
453 static inline wr::LayoutTransform ToLayoutTransform(
454 const gfx::Matrix4x4Typed<S, T>& m) {
455 wr::LayoutTransform transform;
456 transform.m11 = m._11;
457 transform.m12 = m._12;
458 transform.m13 = m._13;
459 transform.m14 = m._14;
460 transform.m21 = m._21;
461 transform.m22 = m._22;
462 transform.m23 = m._23;
463 transform.m24 = m._24;
464 transform.m31 = m._31;
465 transform.m32 = m._32;
466 transform.m33 = m._33;
467 transform.m34 = m._34;
468 transform.m41 = m._41;
469 transform.m42 = m._42;
470 transform.m43 = m._43;
471 transform.m44 = m._44;
472 return transform;
475 wr::BorderStyle ToBorderStyle(StyleBorderStyle style);
477 static inline wr::BorderSide ToBorderSide(const gfx::DeviceColor& color,
478 StyleBorderStyle style) {
479 wr::BorderSide bs;
480 bs.color = ToColorF(color);
481 bs.style = ToBorderStyle(style);
482 return bs;
485 static inline wr::BorderRadius EmptyBorderRadius() {
486 wr::BorderRadius br;
487 PodZero(&br);
488 return br;
491 static inline wr::BorderRadius ToBorderRadius(
492 const LayoutDeviceSize& topLeft, const LayoutDeviceSize& topRight,
493 const LayoutDeviceSize& bottomLeft, const LayoutDeviceSize& bottomRight) {
494 wr::BorderRadius br;
495 br.top_left = ToLayoutSize(topLeft);
496 br.top_right = ToLayoutSize(topRight);
497 br.bottom_left = ToLayoutSize(bottomLeft);
498 br.bottom_right = ToLayoutSize(bottomRight);
499 return br;
502 static inline wr::BorderRadius ToBorderRadius(
503 const gfx::RectCornerRadii& aRadii) {
504 return ToBorderRadius(LayoutDeviceSize::FromUnknownSize(aRadii[0]),
505 LayoutDeviceSize::FromUnknownSize(aRadii[1]),
506 LayoutDeviceSize::FromUnknownSize(aRadii[3]),
507 LayoutDeviceSize::FromUnknownSize(aRadii[2]));
510 static inline wr::ComplexClipRegion ToComplexClipRegion(
511 const nsRect& aRect, const nscoord* aRadii, int32_t aAppUnitsPerDevPixel) {
512 wr::ComplexClipRegion ret;
513 ret.rect =
514 ToLayoutRect(LayoutDeviceRect::FromAppUnits(aRect, aAppUnitsPerDevPixel));
515 ret.radii = ToBorderRadius(
516 LayoutDeviceSize::FromAppUnits(
517 nsSize(aRadii[eCornerTopLeftX], aRadii[eCornerTopLeftY]),
518 aAppUnitsPerDevPixel),
519 LayoutDeviceSize::FromAppUnits(
520 nsSize(aRadii[eCornerTopRightX], aRadii[eCornerTopRightY]),
521 aAppUnitsPerDevPixel),
522 LayoutDeviceSize::FromAppUnits(
523 nsSize(aRadii[eCornerBottomLeftX], aRadii[eCornerBottomLeftY]),
524 aAppUnitsPerDevPixel),
525 LayoutDeviceSize::FromAppUnits(
526 nsSize(aRadii[eCornerBottomRightX], aRadii[eCornerBottomRightY]),
527 aAppUnitsPerDevPixel));
528 ret.mode = ClipMode::Clip;
529 return ret;
532 static inline wr::LayoutSideOffsets ToBorderWidths(float top, float right,
533 float bottom, float left) {
534 wr::LayoutSideOffsets bw;
535 bw.top = top;
536 bw.right = right;
537 bw.bottom = bottom;
538 bw.left = left;
539 return bw;
542 static inline wr::DeviceIntSideOffsets ToDeviceIntSideOffsets(int32_t top,
543 int32_t right,
544 int32_t bottom,
545 int32_t left) {
546 wr::DeviceIntSideOffsets offset;
547 offset.top = top;
548 offset.right = right;
549 offset.bottom = bottom;
550 offset.left = left;
551 return offset;
554 static inline wr::LayoutSideOffsets ToLayoutSideOffsets(float top, float right,
555 float bottom,
556 float left) {
557 wr::LayoutSideOffsets offset;
558 offset.top = top;
559 offset.right = right;
560 offset.bottom = bottom;
561 offset.left = left;
562 return offset;
565 wr::RepeatMode ToRepeatMode(StyleBorderImageRepeat);
567 template <class S, class T>
568 static inline wr::WrTransformProperty ToWrTransformProperty(
569 uint64_t id, const gfx::Matrix4x4Typed<S, T>& transform) {
570 wr::WrTransformProperty prop;
571 prop.id = id;
572 prop.value = ToLayoutTransform(transform);
573 return prop;
576 static inline wr::WrOpacityProperty ToWrOpacityProperty(uint64_t id,
577 const float opacity) {
578 wr::WrOpacityProperty prop;
579 prop.id = id;
580 prop.value = opacity;
581 return prop;
584 static inline wr::WrColorProperty ToWrColorProperty(
585 uint64_t id, const gfx::DeviceColor& color) {
586 wr::WrColorProperty prop;
587 prop.id = id;
588 prop.value = ToColorF(color);
589 return prop;
592 // Whenever possible, use wr::ExternalImageId instead of manipulating uint64_t.
593 inline uint64_t AsUint64(const ExternalImageId& aId) {
594 return static_cast<uint64_t>(aId._0);
597 static inline ExternalImageId ToExternalImageId(uint64_t aID) {
598 ExternalImageId Id;
599 Id._0 = aID;
600 return Id;
603 static inline wr::WrExternalImage RawDataToWrExternalImage(const uint8_t* aBuff,
604 size_t size) {
605 return wr::WrExternalImage{
606 wr::WrExternalImageType::RawData, 0, 0.0f, 0.0f, 0.0f, 0.0f, aBuff, size};
609 static inline wr::WrExternalImage NativeTextureToWrExternalImage(
610 uint32_t aHandle, float u0, float v0, float u1, float v1) {
611 return wr::WrExternalImage{wr::WrExternalImageType::NativeTexture,
612 aHandle,
617 nullptr,
621 static inline wr::WrExternalImage InvalidToWrExternalImage() {
622 return wr::WrExternalImage{
623 wr::WrExternalImageType::Invalid, 0, 0, 0, 0, 0, nullptr, 0};
626 inline wr::ByteSlice RangeToByteSlice(mozilla::Range<uint8_t> aRange) {
627 return wr::ByteSlice{aRange.begin().get(), aRange.length()};
630 inline mozilla::Range<const uint8_t> ByteSliceToRange(wr::ByteSlice aWrSlice) {
631 return mozilla::Range<const uint8_t>(aWrSlice.buffer, aWrSlice.len);
634 inline mozilla::Range<uint8_t> MutByteSliceToRange(wr::MutByteSlice aWrSlice) {
635 return mozilla::Range<uint8_t>(aWrSlice.buffer, aWrSlice.len);
638 void Assign_WrVecU8(wr::WrVecU8& aVec, mozilla::ipc::ByteBuf&& aOther);
640 template <typename T>
641 struct Vec;
643 template <>
644 struct Vec<uint8_t> final {
645 wr::WrVecU8 inner;
646 Vec() { SetEmpty(); }
647 Vec(Vec&) = delete;
648 Vec(Vec&& src) {
649 inner = src.inner;
650 src.SetEmpty();
653 explicit Vec(mozilla::ipc::ByteBuf&& aSrc) {
654 Assign_WrVecU8(inner, std::move(aSrc));
657 Vec& operator=(Vec&& src) {
658 inner = src.inner;
659 src.SetEmpty();
660 return *this;
663 wr::WrVecU8 Extract() {
664 wr::WrVecU8 ret = inner;
665 SetEmpty();
666 return ret;
669 void SetEmpty() {
670 inner.data = (uint8_t*)1;
671 inner.capacity = 0;
672 inner.length = 0;
675 uint8_t* Data() { return inner.data; }
677 size_t Length() { return inner.length; }
679 size_t Capacity() { return inner.capacity; }
681 Range<uint8_t> GetRange() { return Range<uint8_t>(Data(), Length()); }
683 void PushBytes(Range<uint8_t> aBytes) {
684 wr_vec_u8_push_bytes(&inner, RangeToByteSlice(aBytes));
687 void Reserve(size_t aLength) { wr_vec_u8_reserve(&inner, aLength); }
689 ~Vec() {
690 if (inner.data) {
691 wr_vec_u8_free(inner);
696 struct ByteBuffer {
697 ByteBuffer(size_t aLength, uint8_t* aData)
698 : mLength(aLength), mData(aData), mOwned(false) {}
700 // XXX: this is a bit of hack that assumes
701 // the allocators are the same
702 explicit ByteBuffer(VecU8&& vec) {
703 if (vec.inner.capacity) {
704 mLength = vec.inner.length;
705 mData = vec.inner.data;
706 vec.inner.data = nullptr;
707 vec.inner.capacity = 0;
708 mOwned = true;
709 } else {
710 mOwned = false;
711 mData = nullptr;
712 mLength = 0;
716 ByteBuffer(ByteBuffer&& aFrom)
717 : mLength(aFrom.mLength), mData(aFrom.mData), mOwned(aFrom.mOwned) {
718 aFrom.mLength = 0;
719 aFrom.mData = nullptr;
720 aFrom.mOwned = false;
723 ByteBuffer(ByteBuffer& aFrom)
724 : mLength(aFrom.mLength), mData(aFrom.mData), mOwned(aFrom.mOwned) {
725 aFrom.mLength = 0;
726 aFrom.mData = nullptr;
727 aFrom.mOwned = false;
730 ByteBuffer() : mLength(0), mData(nullptr), mOwned(false) {}
732 bool Allocate(size_t aLength) {
733 MOZ_ASSERT(mData == nullptr);
734 mData = (uint8_t*)malloc(aLength);
735 if (!mData) {
736 return false;
738 mLength = aLength;
739 mOwned = true;
740 return true;
743 ~ByteBuffer() {
744 if (mData && mOwned) {
745 free(mData);
749 const Range<uint8_t> AsSlice() const {
750 return Range<uint8_t>(mData, mLength);
753 Range<uint8_t> AsSlice() { return Range<uint8_t>(mData, mLength); }
755 bool operator==(const ByteBuffer& other) const {
756 return mLength == other.mLength && !(memcmp(mData, other.mData, mLength));
759 size_t mLength;
760 uint8_t* mData;
761 bool mOwned;
764 struct BuiltDisplayList {
765 wr::VecU8 dl_items;
766 wr::VecU8 dl_cache;
767 wr::VecU8 dl_spatial_tree;
768 wr::BuiltDisplayListDescriptor dl_desc;
771 // Corresponds to a clip id for a clip chain in webrender. Similar to
772 // WrClipId but a separate struct so we don't get them mixed up in C++.
773 struct WrClipChainId {
774 uint64_t id;
776 bool operator==(const WrClipChainId& other) const { return id == other.id; }
778 static WrClipChainId Empty() {
779 WrClipChainId id = {0};
780 return id;
784 WrSpatialId RootScrollNode();
785 WrSpaceAndClipChain RootScrollNodeWithChain();
786 WrSpaceAndClipChain InvalidScrollNodeWithChain();
788 enum class WebRenderError : int8_t {
789 INITIALIZE = 0,
790 MAKE_CURRENT,
791 RENDER,
792 NEW_SURFACE,
793 BEGIN_DRAW,
794 VIDEO_OVERLAY,
795 VIDEO_HW_OVERLAY,
796 VIDEO_SW_OVERLAY,
797 EXCESSIVE_RESETS,
799 Sentinel /* this must be last for serialization purposes. */
802 static inline wr::WrYuvColorSpace ToWrYuvColorSpace(
803 gfx::YUVColorSpace aYUVColorSpace) {
804 switch (aYUVColorSpace) {
805 case gfx::YUVColorSpace::BT601:
806 return wr::WrYuvColorSpace::Rec601;
807 case gfx::YUVColorSpace::BT709:
808 return wr::WrYuvColorSpace::Rec709;
809 case gfx::YUVColorSpace::BT2020:
810 return wr::WrYuvColorSpace::Rec2020;
811 case gfx::YUVColorSpace::Identity:
812 return wr::WrYuvColorSpace::Identity;
813 default:
814 MOZ_ASSERT_UNREACHABLE("Tried to convert invalid YUVColorSpace.");
816 return wr::WrYuvColorSpace::Rec601;
819 // TODO: Use YUVRangedColorSpace instead of assuming ColorRange::LIMITED.
820 static inline wr::YuvRangedColorSpace ToWrYuvRangedColorSpace(
821 gfx::YUVRangedColorSpace aFrom) {
822 switch (aFrom) {
823 case gfx::YUVRangedColorSpace::BT601_Narrow:
824 return wr::YuvRangedColorSpace::Rec601Narrow;
825 case gfx::YUVRangedColorSpace::BT601_Full:
826 return wr::YuvRangedColorSpace::Rec601Full;
827 case gfx::YUVRangedColorSpace::BT709_Narrow:
828 return wr::YuvRangedColorSpace::Rec709Narrow;
829 case gfx::YUVRangedColorSpace::BT709_Full:
830 return wr::YuvRangedColorSpace::Rec709Full;
831 case gfx::YUVRangedColorSpace::BT2020_Narrow:
832 return wr::YuvRangedColorSpace::Rec2020Narrow;
833 case gfx::YUVRangedColorSpace::BT2020_Full:
834 return wr::YuvRangedColorSpace::Rec2020Full;
835 case gfx::YUVRangedColorSpace::GbrIdentity:
836 break;
837 default:
838 MOZ_ASSERT_UNREACHABLE("Tried to convert invalid YUVColorSpace.");
839 break;
841 return wr::YuvRangedColorSpace::GbrIdentity;
844 static inline wr::WrColorDepth ToWrColorDepth(gfx::ColorDepth aColorDepth) {
845 switch (aColorDepth) {
846 case gfx::ColorDepth::COLOR_8:
847 return wr::WrColorDepth::Color8;
848 case gfx::ColorDepth::COLOR_10:
849 return wr::WrColorDepth::Color10;
850 case gfx::ColorDepth::COLOR_12:
851 return wr::WrColorDepth::Color12;
852 case gfx::ColorDepth::COLOR_16:
853 return wr::WrColorDepth::Color16;
854 default:
855 MOZ_ASSERT_UNREACHABLE("Tried to convert invalid color depth value.");
857 return wr::WrColorDepth::Color8;
860 static inline wr::WrColorRange ToWrColorRange(gfx::ColorRange aColorRange) {
861 switch (aColorRange) {
862 case gfx::ColorRange::LIMITED:
863 return wr::WrColorRange::Limited;
864 case gfx::ColorRange::FULL:
865 return wr::WrColorRange::Full;
866 default:
867 MOZ_ASSERT_UNREACHABLE("Tried to convert invalid color range value.");
868 return wr ::WrColorRange::Limited;
872 static inline wr::SyntheticItalics DegreesToSyntheticItalics(float aDegrees) {
873 wr::SyntheticItalics synthetic_italics;
874 synthetic_italics.angle =
875 int16_t(std::min(std::max(aDegrees, -89.0f), 89.0f) * 256.0f);
876 return synthetic_italics;
879 static inline wr::WindowSizeMode ToWrWindowSizeMode(nsSizeMode aSizeMode) {
880 switch (aSizeMode) {
881 case nsSizeMode_Normal:
882 return wr::WindowSizeMode::Normal;
883 case nsSizeMode_Minimized:
884 return wr::WindowSizeMode::Minimized;
885 case nsSizeMode_Maximized:
886 return wr::WindowSizeMode::Maximized;
887 case nsSizeMode_Fullscreen:
888 return wr::WindowSizeMode::Fullscreen;
889 default:
890 MOZ_ASSERT_UNREACHABLE("Tried to convert invalid size mode.");
891 return wr::WindowSizeMode::Invalid;
895 static inline wr::APZScrollGeneration ToWrAPZScrollGeneration(
896 const mozilla::APZScrollGeneration& aGeneration) {
897 return wr::APZScrollGeneration(aGeneration.Raw());
900 static inline wr::HasScrollLinkedEffect ToWrHasScrollLinkedEffect(
901 bool aHasScrollLinkedEffect) {
902 return aHasScrollLinkedEffect ? wr::HasScrollLinkedEffect::Yes
903 : wr::HasScrollLinkedEffect::No;
906 enum class ExternalImageSource : uint8_t { Unknown = 0, SharedSurfaces, Last };
908 } // namespace wr
909 } // namespace mozilla
911 namespace std {
912 template <>
913 struct hash<mozilla::wr::WrSpatialId> {
914 std::size_t operator()(mozilla::wr::WrSpatialId const& aKey) const noexcept {
915 return std::hash<size_t>{}(aKey.id);
918 } // namespace std
920 #endif /* GFX_WEBRENDERTYPES_H */