1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #![deny(missing_docs)]
6 
7 use euclid::{size2, Rect, num::Zero};
8 use peek_poke::PeekPoke;
9 use std::ops::{Add, Sub};
10 use std::sync::Arc;
11 // local imports
12 use crate::api::{IdNamespace, PipelineId, TileSize};
13 use crate::display_item::ImageRendering;
14 use crate::font::{FontInstanceKey, FontInstanceData, FontKey, FontTemplate};
15 use crate::units::*;
16 
17 /// The default tile size for blob images and regular images larger than
18 /// the maximum texture size.
19 pub const DEFAULT_TILE_SIZE: TileSize = 512;
20 
21 /// An opaque identifier describing an image registered with WebRender.
22 /// This is used as a handle to reference images, and is used as the
23 /// hash map key for the actual image storage in the `ResourceCache`.
24 #[repr(C)]
25 #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
26 pub struct ImageKey(pub IdNamespace, pub u32);
27 
28 impl Default for ImageKey {
default() -> Self29     fn default() -> Self {
30         ImageKey::DUMMY
31     }
32 }
33 
34 impl ImageKey {
35     /// Placeholder Image key, used to represent None.
36     pub const DUMMY: Self = ImageKey(IdNamespace(0), 0);
37 
38     /// Mints a new ImageKey. The given ID must be unique.
new(namespace: IdNamespace, key: u32) -> Self39     pub fn new(namespace: IdNamespace, key: u32) -> Self {
40         ImageKey(namespace, key)
41     }
42 }
43 
44 /// An opaque identifier describing a blob image registered with WebRender.
45 /// This is used as a handle to reference blob images, and can be used as an
46 /// image in display items.
47 #[repr(C)]
48 #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
49 pub struct BlobImageKey(pub ImageKey);
50 
51 impl BlobImageKey {
52     /// Interpret this blob image as an image for a display item.
as_image(self) -> ImageKey53     pub fn as_image(self) -> ImageKey {
54         self.0
55     }
56 }
57 
58 /// An arbitrary identifier for an external image provided by the
59 /// application. It must be a unique identifier for each external
60 /// image.
61 #[repr(C)]
62 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
63 pub struct ExternalImageId(pub u64);
64 
65 /// The source for an external image.
66 pub enum ExternalImageSource<'a> {
67     /// A raw pixel buffer.
68     RawData(&'a [u8]),
69     /// A gl::GLuint texture handle.
70     NativeTexture(u32),
71     /// An invalid source.
72     Invalid,
73 }
74 
75 /// The data that an external client should provide about
76 /// an external image. For instance, if providing video frames,
77 /// the application could call wr.render() whenever a new
78 /// video frame is ready. Note that the UV coords are supplied
79 /// in texel-space!
80 pub struct ExternalImage<'a> {
81     /// UV coordinates for the image.
82     pub uv: TexelRect,
83     /// The source for this image's contents.
84     pub source: ExternalImageSource<'a>,
85 }
86 
87 /// The interfaces that an application can implement to support providing
88 /// external image buffers.
89 /// When the application passes an external image to WR, it should keep that
90 /// external image life time. People could check the epoch id in RenderNotifier
91 /// at the client side to make sure that the external image is not used by WR.
92 /// Then, do the clean up for that external image.
93 pub trait ExternalImageHandler {
94     /// Lock the external image. Then, WR could start to read the image content.
95     /// The WR client should not change the image content until the unlock()
96     /// call. Provide ImageRendering for NativeTexture external images.
lock(&mut self, key: ExternalImageId, channel_index: u8, rendering: ImageRendering) -> ExternalImage97     fn lock(&mut self, key: ExternalImageId, channel_index: u8, rendering: ImageRendering) -> ExternalImage;
98     /// Unlock the external image. WR should not read the image content
99     /// after this call.
unlock(&mut self, key: ExternalImageId, channel_index: u8)100     fn unlock(&mut self, key: ExternalImageId, channel_index: u8);
101 }
102 
103 /// Allows callers to receive a texture with the contents of a specific
104 /// pipeline copied to it.
105 pub trait OutputImageHandler {
106     /// Return the native texture handle and the size of the texture.
lock(&mut self, pipeline_id: PipelineId) -> Option<(u32, FramebufferIntSize)>107     fn lock(&mut self, pipeline_id: PipelineId) -> Option<(u32, FramebufferIntSize)>;
108     /// Unlock will only be called if the lock() call succeeds, when WR has issued
109     /// the GL commands to copy the output to the texture handle.
unlock(&mut self, pipeline_id: PipelineId)110     fn unlock(&mut self, pipeline_id: PipelineId);
111 }
112 
113 /// Specifies the type of texture target in driver terms.
114 #[repr(u8)]
115 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
116 pub enum TextureTarget {
117     /// Standard texture. This maps to GL_TEXTURE_2D in OpenGL.
118     Default = 0,
119     /// Array texture. This maps to GL_TEXTURE_2D_ARRAY in OpenGL. See
120     /// https://www.khronos.org/opengl/wiki/Array_Texture for background
121     /// on Array textures.
122     Array = 1,
123     /// Rectangle texture. This maps to GL_TEXTURE_RECTANGLE in OpenGL. This
124     /// is similar to a standard texture, with a few subtle differences
125     /// (no mipmaps, non-power-of-two dimensions, different coordinate space)
126     /// that make it useful for representing the kinds of textures we use
127     /// in WebRender. See https://www.khronos.org/opengl/wiki/Rectangle_Texture
128     /// for background on Rectangle textures.
129     Rect = 2,
130     /// External texture. This maps to GL_TEXTURE_EXTERNAL_OES in OpenGL, which
131     /// is an extension. This is used for image formats that OpenGL doesn't
132     /// understand, particularly YUV. See
133     /// https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external.txt
134     External = 3,
135 }
136 
137 /// Storage format identifier for externally-managed images.
138 #[repr(u8)]
139 #[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
140 pub enum ExternalImageType {
141     /// The image is texture-backed.
142     TextureHandle(TextureTarget),
143     /// The image is heap-allocated by the embedding.
144     Buffer,
145 }
146 
147 /// Descriptor for external image resources. See `ImageData`.
148 #[repr(C)]
149 #[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, Serialize, Deserialize)]
150 pub struct ExternalImageData {
151     /// The identifier of this external image, provided by the embedding.
152     pub id: ExternalImageId,
153     /// For multi-plane images (i.e. YUV), indicates the plane of the
154     /// original image that this struct represents. 0 for single-plane images.
155     pub channel_index: u8,
156     /// Storage format identifier.
157     pub image_type: ExternalImageType,
158 }
159 
160 /// Specifies the format of a series of pixels, in driver terms.
161 #[repr(u8)]
162 #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
163 pub enum ImageFormat {
164     /// One-channel, byte storage. The "red" doesn't map to the color
165     /// red per se, and is just the way that OpenGL has historically referred
166     /// to single-channel buffers.
167     R8 = 1,
168     /// One-channel, short storage
169     R16 = 2,
170     /// Four channels, byte storage.
171     BGRA8 = 3,
172     /// Four channels, float storage.
173     RGBAF32 = 4,
174     /// Two-channels, byte storage. Similar to `R8`, this just means
175     /// "two channels" rather than "red and green".
176     RG8 = 5,
177     /// Two-channels, byte storage. Similar to `R16`, this just means
178     /// "two channels" rather than "red and green".
179     RG16 = 6,
180 
181     /// Four channels, signed integer storage.
182     RGBAI32 = 7,
183     /// Four channels, byte storage.
184     RGBA8 = 8,
185 }
186 
187 impl ImageFormat {
188     /// Returns the number of bytes per pixel for the given format.
bytes_per_pixel(self) -> i32189     pub fn bytes_per_pixel(self) -> i32 {
190         match self {
191             ImageFormat::R8 => 1,
192             ImageFormat::R16 => 2,
193             ImageFormat::BGRA8 => 4,
194             ImageFormat::RGBAF32 => 16,
195             ImageFormat::RG8 => 2,
196             ImageFormat::RG16 => 4,
197             ImageFormat::RGBAI32 => 16,
198             ImageFormat::RGBA8 => 4,
199         }
200     }
201 }
202 
203 /// Specifies the color depth of an image. Currently only used for YUV images.
204 #[repr(u8)]
205 #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
206 pub enum ColorDepth {
207     /// 8 bits image (most common)
208     Color8,
209     /// 10 bits image
210     Color10,
211     /// 12 bits image
212     Color12,
213     /// 16 bits image
214     Color16,
215 }
216 
217 impl Default for ColorDepth {
default() -> Self218     fn default() -> Self {
219         ColorDepth::Color8
220     }
221 }
222 
223 impl ColorDepth {
224     /// Return the numerical bit depth value for the type.
bit_depth(self) -> u32225     pub fn bit_depth(self) -> u32 {
226         match self {
227             ColorDepth::Color8 => 8,
228             ColorDepth::Color10 => 10,
229             ColorDepth::Color12 => 12,
230             ColorDepth::Color16 => 16,
231         }
232     }
233     /// 10 and 12 bits images are encoded using 16 bits integer, we need to
234     /// rescale the 10 or 12 bits value to extend to 16 bits.
rescaling_factor(self) -> f32235     pub fn rescaling_factor(self) -> f32 {
236         match self {
237             ColorDepth::Color8 => 1.0,
238             ColorDepth::Color10 => 64.0,
239             ColorDepth::Color12 => 16.0,
240             ColorDepth::Color16 => 1.0,
241         }
242     }
243 }
244 
245 bitflags! {
246     /// Various flags that are part of an image descriptor.
247     #[derive(Deserialize, Serialize)]
248     pub struct ImageDescriptorFlags: u32 {
249         /// Whether this image is opaque, or has an alpha channel. Avoiding blending
250         /// for opaque surfaces is an important optimization.
251         const IS_OPAQUE = 1;
252         /// Whether to allow the driver to automatically generate mipmaps. If images
253         /// are already downscaled appropriately, mipmap generation can be wasted
254         /// work, and cause performance problems on some cards/drivers.
255         ///
256         /// See https://github.com/servo/webrender/pull/2555/
257         const ALLOW_MIPMAPS = 2;
258     }
259 }
260 
261 /// Metadata (but not storage) describing an image In WebRender.
262 #[derive(Copy, Clone, Debug, Deserialize, PartialEq, Serialize)]
263 pub struct ImageDescriptor {
264     /// Format of the image data.
265     pub format: ImageFormat,
266     /// Width and length of the image data, in pixels.
267     pub size: DeviceIntSize,
268     /// The number of bytes from the start of one row to the next. If non-None,
269     /// `compute_stride` will return this value, otherwise it returns
270     /// `width * bpp`. Different source of images have different alignment
271     /// constraints for rows, so the stride isn't always equal to width * bpp.
272     pub stride: Option<i32>,
273     /// Offset in bytes of the first pixel of this image in its backing buffer.
274     /// This is used for tiling, wherein WebRender extracts chunks of input images
275     /// in order to cache, manipulate, and render them individually. This offset
276     /// tells the texture upload machinery where to find the bytes to upload for
277     /// this tile. Non-tiled images generally set this to zero.
278     pub offset: i32,
279     /// Various bool flags related to this descriptor.
280     pub flags: ImageDescriptorFlags,
281 }
282 
283 impl ImageDescriptor {
284     /// Mints a new ImageDescriptor.
new( width: i32, height: i32, format: ImageFormat, flags: ImageDescriptorFlags, ) -> Self285     pub fn new(
286         width: i32,
287         height: i32,
288         format: ImageFormat,
289         flags: ImageDescriptorFlags,
290     ) -> Self {
291         ImageDescriptor {
292             size: size2(width, height),
293             format,
294             stride: None,
295             offset: 0,
296             flags,
297         }
298     }
299 
300     /// Returns the stride, either via an explicit stride stashed on the object
301     /// or by the default computation.
compute_stride(&self) -> i32302     pub fn compute_stride(&self) -> i32 {
303         self.stride.unwrap_or(self.size.width * self.format.bytes_per_pixel())
304     }
305 
306     /// Computes the total size of the image, in bytes.
compute_total_size(&self) -> i32307     pub fn compute_total_size(&self) -> i32 {
308         self.compute_stride() * self.size.height
309     }
310 
311     /// Computes the bounding rectangle for the image, rooted at (0, 0).
full_rect(&self) -> DeviceIntRect312     pub fn full_rect(&self) -> DeviceIntRect {
313         DeviceIntRect::new(
314             DeviceIntPoint::zero(),
315             self.size,
316         )
317     }
318 
319     /// Returns true if this descriptor is opaque
is_opaque(&self) -> bool320     pub fn is_opaque(&self) -> bool {
321         self.flags.contains(ImageDescriptorFlags::IS_OPAQUE)
322     }
323 
324     /// Returns true if this descriptor allows mipmaps
allow_mipmaps(&self) -> bool325     pub fn allow_mipmaps(&self) -> bool {
326         self.flags.contains(ImageDescriptorFlags::ALLOW_MIPMAPS)
327     }
328 }
329 
330 /// Represents the backing store of an arbitrary series of pixels for display by
331 /// WebRender. This storage can take several forms.
332 #[derive(Clone, Debug, Serialize, Deserialize)]
333 pub enum ImageData {
334     /// A simple series of bytes, provided by the embedding and owned by WebRender.
335     /// The format is stored out-of-band, currently in ImageDescriptor.
336     Raw(#[serde(with = "serde_image_data_raw")] Arc<Vec<u8>>),
337     /// An image owned by the embedding, and referenced by WebRender. This may
338     /// take the form of a texture or a heap-allocated buffer.
339     External(ExternalImageData),
340 }
341 
342 mod serde_image_data_raw {
343     extern crate serde_bytes;
344 
345     use std::sync::Arc;
346     use serde::{Deserializer, Serializer};
347 
serialize<S: Serializer>(bytes: &Arc<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error>348     pub fn serialize<S: Serializer>(bytes: &Arc<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error> {
349         serde_bytes::serialize(bytes.as_slice(), serializer)
350     }
351 
deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Arc<Vec<u8>>, D::Error>352     pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Arc<Vec<u8>>, D::Error> {
353         serde_bytes::deserialize(deserializer).map(Arc::new)
354     }
355 }
356 
357 impl ImageData {
358     /// Mints a new raw ImageData, taking ownership of the bytes.
new(bytes: Vec<u8>) -> Self359     pub fn new(bytes: Vec<u8>) -> Self {
360         ImageData::Raw(Arc::new(bytes))
361     }
362 
363     /// Mints a new raw ImageData from Arc-ed bytes.
new_shared(bytes: Arc<Vec<u8>>) -> Self364     pub fn new_shared(bytes: Arc<Vec<u8>>) -> Self {
365         ImageData::Raw(bytes)
366     }
367 }
368 
369 /// The resources exposed by the resource cache available for use by the blob rasterizer.
370 pub trait BlobImageResources {
371     /// Returns the `FontTemplate` for the given key.
get_font_data(&self, key: FontKey) -> &FontTemplate372     fn get_font_data(&self, key: FontKey) -> &FontTemplate;
373     /// Returns the `FontInstanceData` for the given key, if found.
get_font_instance_data(&self, key: FontInstanceKey) -> Option<FontInstanceData>374     fn get_font_instance_data(&self, key: FontInstanceKey) -> Option<FontInstanceData>;
375 }
376 
377 /// A handler on the render backend that can create rasterizer objects which will
378 /// be sent to the scene builder thread to execute the rasterization.
379 ///
380 /// The handler is responsible for collecting resources, managing/updating blob commands
381 /// and creating the rasterizer objects, but isn't expected to do any rasterization itself.
382 pub trait BlobImageHandler: Send {
383     /// Creates a snapshot of the current state of blob images in the handler.
create_blob_rasterizer(&mut self) -> Box<dyn AsyncBlobImageRasterizer>384     fn create_blob_rasterizer(&mut self) -> Box<dyn AsyncBlobImageRasterizer>;
385 
386     /// Creates an empty blob handler of the same type.
387     ///
388     /// This is used to allow creating new API endpoints with blob handlers installed on them.
create_similar(&self) -> Box<dyn BlobImageHandler>389     fn create_similar(&self) -> Box<dyn BlobImageHandler>;
390 
391     /// A hook to let the blob image handler update any state related to resources that
392     /// are not bundled in the blob recording itself.
prepare_resources( &mut self, services: &dyn BlobImageResources, requests: &[BlobImageParams], )393     fn prepare_resources(
394         &mut self,
395         services: &dyn BlobImageResources,
396         requests: &[BlobImageParams],
397     );
398 
399     /// Register a blob image.
add(&mut self, key: BlobImageKey, data: Arc<BlobImageData>, visible_rect: &DeviceIntRect, tile_size: TileSize)400     fn add(&mut self, key: BlobImageKey, data: Arc<BlobImageData>, visible_rect: &DeviceIntRect,
401            tile_size: TileSize);
402 
403     /// Update an already registered blob image.
update(&mut self, key: BlobImageKey, data: Arc<BlobImageData>, visible_rect: &DeviceIntRect, dirty_rect: &BlobDirtyRect)404     fn update(&mut self, key: BlobImageKey, data: Arc<BlobImageData>, visible_rect: &DeviceIntRect,
405               dirty_rect: &BlobDirtyRect);
406 
407     /// Delete an already registered blob image.
delete(&mut self, key: BlobImageKey)408     fn delete(&mut self, key: BlobImageKey);
409 
410     /// A hook to let the handler clean up any state related to a font which the resource
411     /// cache is about to delete.
delete_font(&mut self, key: FontKey)412     fn delete_font(&mut self, key: FontKey);
413 
414     /// A hook to let the handler clean up any state related to a font instance which the
415     /// resource cache is about to delete.
delete_font_instance(&mut self, key: FontInstanceKey)416     fn delete_font_instance(&mut self, key: FontInstanceKey);
417 
418     /// A hook to let the handler clean up any state related a given namespace before the
419     /// resource cache deletes them.
clear_namespace(&mut self, namespace: IdNamespace)420     fn clear_namespace(&mut self, namespace: IdNamespace);
421 
422     /// Whether to allow rendering blobs on multiple threads.
enable_multithreading(&mut self, enable: bool)423     fn enable_multithreading(&mut self, enable: bool);
424 }
425 
426 /// A group of rasterization requests to execute synchronously on the scene builder thread.
427 pub trait AsyncBlobImageRasterizer : Send {
428     /// Rasterize the requests.
429     ///
430     /// Gecko uses te priority hint to schedule work in a way that minimizes the risk
431     /// of high priority work being blocked by (or enqued behind) low priority work.
rasterize( &mut self, requests: &[BlobImageParams], low_priority: bool ) -> Vec<(BlobImageRequest, BlobImageResult)>432     fn rasterize(
433         &mut self,
434         requests: &[BlobImageParams],
435         low_priority: bool
436     ) -> Vec<(BlobImageRequest, BlobImageResult)>;
437 }
438 
439 
440 /// Input parameters for the BlobImageRasterizer.
441 #[derive(Copy, Clone, Debug)]
442 pub struct BlobImageParams {
443     /// A key that identifies the blob image rasterization request.
444     pub request: BlobImageRequest,
445     /// Description of the format of the blob's output image.
446     pub descriptor: BlobImageDescriptor,
447     /// An optional sub-rectangle of the image to avoid re-rasterizing
448     /// the entire image when only a portion is updated.
449     ///
450     /// If set to None the entire image is rasterized.
451     pub dirty_rect: BlobDirtyRect,
452 }
453 
454 /// The possible states of a Dirty rect.
455 ///
456 /// This exists because people kept getting confused with `Option<Rect>`.
457 #[derive(Debug, Serialize, Deserialize)]
458 pub enum DirtyRect<T: Copy, U> {
459     /// Everything is Dirty, equivalent to Partial(image_bounds)
460     All,
461     /// Some specific amount is dirty
462     Partial(Rect<T, U>)
463 }
464 
465 impl<T, U> DirtyRect<T, U>
466 where
467     T: Copy + Clone
468         + PartialOrd + PartialEq
469         + Add<T, Output = T>
470         + Sub<T, Output = T>
471         + Zero
472 {
473     /// Creates an empty DirtyRect (indicating nothing is invalid)
empty() -> Self474     pub fn empty() -> Self {
475         DirtyRect::Partial(Rect::zero())
476     }
477 
478     /// Returns whether the dirty rect is empty
is_empty(&self) -> bool479     pub fn is_empty(&self) -> bool {
480         match self {
481             DirtyRect::All => false,
482             DirtyRect::Partial(rect) => rect.is_empty(),
483         }
484     }
485 
486     /// Replaces self with the empty rect and returns the old value.
replace_with_empty(&mut self) -> Self487     pub fn replace_with_empty(&mut self) -> Self {
488         ::std::mem::replace(self, DirtyRect::empty())
489     }
490 
491     /// Maps over the contents of Partial.
map<F>(self, func: F) -> Self where F: FnOnce(Rect<T, U>) -> Rect<T, U>,492     pub fn map<F>(self, func: F) -> Self
493         where F: FnOnce(Rect<T, U>) -> Rect<T, U>,
494     {
495         use crate::DirtyRect::*;
496 
497         match self {
498             All        => All,
499             Partial(rect) => Partial(func(rect)),
500         }
501     }
502 
503     /// Unions the dirty rects.
union(&self, other: &Self) -> Self504     pub fn union(&self, other: &Self) -> Self {
505         use crate::DirtyRect::*;
506 
507         match (*self, *other) {
508             (All, _) | (_, All)        => All,
509             (Partial(rect1), Partial(rect2)) => Partial(rect1.union(&rect2)),
510         }
511     }
512 
513     /// Intersects the dirty rects.
intersection(&self, other: &Self) -> Self514     pub fn intersection(&self, other: &Self) -> Self {
515         use crate::DirtyRect::*;
516 
517         match (*self, *other) {
518             (All, rect) | (rect, All)  => rect,
519             (Partial(rect1), Partial(rect2)) => Partial(rect1.intersection(&rect2)
520                                                                    .unwrap_or_else(Rect::zero))
521         }
522     }
523 
524     /// Converts the dirty rect into a subrect of the given one via intersection.
to_subrect_of(&self, rect: &Rect<T, U>) -> Rect<T, U>525     pub fn to_subrect_of(&self, rect: &Rect<T, U>) -> Rect<T, U> {
526         use crate::DirtyRect::*;
527 
528         match *self {
529             All              => *rect,
530             Partial(dirty_rect) => dirty_rect.intersection(rect)
531                                                .unwrap_or_else(Rect::zero),
532         }
533     }
534 }
535 
536 impl<T: Copy, U> Copy for DirtyRect<T, U> {}
537 impl<T: Copy, U> Clone for DirtyRect<T, U> {
clone(&self) -> Self538     fn clone(&self) -> Self { *self }
539 }
540 
541 impl<T: Copy, U> From<Rect<T, U>> for DirtyRect<T, U> {
from(rect: Rect<T, U>) -> Self542     fn from(rect: Rect<T, U>) -> Self {
543         DirtyRect::Partial(rect)
544     }
545 }
546 
547 /// Backing store for blob image command streams.
548 pub type BlobImageData = Vec<u8>;
549 
550 /// Result type for blob raserization.
551 pub type BlobImageResult = Result<RasterizedBlobImage, BlobImageError>;
552 
553 /// Metadata (but not storage) for a blob image.
554 #[repr(C)]
555 #[derive(Copy, Clone, Debug)]
556 pub struct BlobImageDescriptor {
557     /// Surface of the image or tile to render in the same coordinate space as
558     /// the drawing commands.
559     pub rect: LayoutIntRect,
560     /// Format for the data in the backing store.
561     pub format: ImageFormat,
562 }
563 
564 /// Representation of a rasterized blob image. This is obtained by passing
565 /// `BlobImageData` to the embedding via the rasterization callback.
566 pub struct RasterizedBlobImage {
567     /// The rectangle that was rasterized in device pixels, relative to the
568     /// image or tile.
569     pub rasterized_rect: DeviceIntRect,
570     /// Backing store. The format is stored out of band in `BlobImageDescriptor`.
571     pub data: Arc<Vec<u8>>,
572 }
573 
574 /// Error code for when blob rasterization failed.
575 #[derive(Clone, Debug)]
576 pub enum BlobImageError {
577     /// Out of memory.
578     Oom,
579     /// Other failure, embedding-specified.
580     Other(String),
581 }
582 
583 
584 
585 /// A key identifying blob image rasterization work requested from the blob
586 /// image rasterizer.
587 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
588 pub struct BlobImageRequest {
589     /// Unique handle to the image.
590     pub key: BlobImageKey,
591     /// Tiling offset in number of tiles.
592     pub tile: TileOffset,
593 }
594