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