mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
imagebitmap: Use snapshot::Snapshot as bitmap data (#37131)
Replace the holder of actual pixel data of the ImageBitmap interface ([[BitmapData]] slot) from Vec<u8> to snapshot::Snapshot (image bitmap with metadata). https://html.spec.whatwg.org/multipage/#the-imagebitmap-interface It will allow to have all required information (e.g. size, pixel format, alpha mode) for further drawing processing to/from canvas2D output bitmap. Testing: No required tests Fixes: https://github.com/servo/servo/issues/34112 Signed-off-by: Andrei Volykhin <andrei.volykhin@gmail.com>
This commit is contained in:
parent
d76b4a14df
commit
86b3b16b4c
7 changed files with 50 additions and 47 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -1209,6 +1209,7 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"servo_malloc_size_of",
|
"servo_malloc_size_of",
|
||||||
"servo_url",
|
"servo_url",
|
||||||
|
"snapshot",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
@ -7117,8 +7118,10 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"euclid",
|
"euclid",
|
||||||
"ipc-channel",
|
"ipc-channel",
|
||||||
|
"malloc_size_of_derive",
|
||||||
"pixels",
|
"pixels",
|
||||||
"serde",
|
"serde",
|
||||||
|
"servo_malloc_size_of",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -2983,9 +2983,7 @@ impl GlobalScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(snapshot) = canvas.get_image_data() {
|
if let Some(snapshot) = canvas.get_image_data() {
|
||||||
let size = snapshot.size().cast();
|
let image_bitmap = ImageBitmap::new(self, snapshot, can_gc);
|
||||||
let image_bitmap = ImageBitmap::new(self, size.width, size.height, can_gc);
|
|
||||||
image_bitmap.set_bitmap_data(snapshot.to_vec());
|
|
||||||
image_bitmap.set_origin_clean(canvas.origin_is_clean());
|
image_bitmap.set_origin_clean(canvas.origin_is_clean());
|
||||||
p.resolve_native(&(image_bitmap), can_gc);
|
p.resolve_native(&(image_bitmap), can_gc);
|
||||||
}
|
}
|
||||||
|
@ -2999,9 +2997,7 @@ impl GlobalScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(snapshot) = canvas.get_image_data() {
|
if let Some(snapshot) = canvas.get_image_data() {
|
||||||
let size = snapshot.size().cast();
|
let image_bitmap = ImageBitmap::new(self, snapshot, can_gc);
|
||||||
let image_bitmap = ImageBitmap::new(self, size.width, size.height, can_gc);
|
|
||||||
image_bitmap.set_bitmap_data(snapshot.to_vec());
|
|
||||||
image_bitmap.set_origin_clean(canvas.origin_is_clean());
|
image_bitmap.set_origin_clean(canvas.origin_is_clean());
|
||||||
p.resolve_native(&(image_bitmap), can_gc);
|
p.resolve_native(&(image_bitmap), can_gc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::{Cell, Ref};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::vec::Vec;
|
|
||||||
|
|
||||||
use base::id::{ImageBitmapId, ImageBitmapIndex};
|
use base::id::{ImageBitmapId, ImageBitmapIndex};
|
||||||
use constellation_traits::SerializableImageBitmap;
|
use constellation_traits::SerializableImageBitmap;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use snapshot::Snapshot;
|
||||||
|
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::ImageBitmapMethods;
|
use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::ImageBitmapMethods;
|
||||||
|
@ -23,41 +23,39 @@ use crate::script_runtime::CanGc;
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub(crate) struct ImageBitmap {
|
pub(crate) struct ImageBitmap {
|
||||||
reflector_: Reflector,
|
reflector_: Reflector,
|
||||||
width: u32,
|
|
||||||
height: u32,
|
|
||||||
/// The actual pixel data of the bitmap
|
/// The actual pixel data of the bitmap
|
||||||
///
|
///
|
||||||
/// If this is `None`, then the bitmap data has been released by calling
|
/// If this is `None`, then the bitmap data has been released by calling
|
||||||
/// [`close`](https://html.spec.whatwg.org/multipage/#dom-imagebitmap-close)
|
/// [`close`](https://html.spec.whatwg.org/multipage/#dom-imagebitmap-close)
|
||||||
bitmap_data: DomRefCell<Option<Vec<u8>>>,
|
#[no_trace]
|
||||||
|
bitmap_data: DomRefCell<Option<Snapshot>>,
|
||||||
origin_clean: Cell<bool>,
|
origin_clean: Cell<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImageBitmap {
|
impl ImageBitmap {
|
||||||
fn new_inherited(width: u32, height: u32) -> ImageBitmap {
|
fn new_inherited(bitmap_data: Snapshot) -> ImageBitmap {
|
||||||
ImageBitmap {
|
ImageBitmap {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
width,
|
bitmap_data: DomRefCell::new(Some(bitmap_data)),
|
||||||
height,
|
|
||||||
bitmap_data: DomRefCell::new(Some(vec![])),
|
|
||||||
origin_clean: Cell::new(true),
|
origin_clean: Cell::new(true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
global: &GlobalScope,
|
global: &GlobalScope,
|
||||||
width: u32,
|
bitmap_data: Snapshot,
|
||||||
height: u32,
|
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) -> DomRoot<ImageBitmap> {
|
) -> DomRoot<ImageBitmap> {
|
||||||
//assigning to a variable the return object of new_inherited
|
reflect_dom_object(
|
||||||
let imagebitmap = Box::new(ImageBitmap::new_inherited(width, height));
|
Box::new(ImageBitmap::new_inherited(bitmap_data)),
|
||||||
|
global,
|
||||||
reflect_dom_object(imagebitmap, global, can_gc)
|
can_gc,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_bitmap_data(&self, data: Vec<u8>) {
|
#[allow(dead_code)]
|
||||||
*self.bitmap_data.borrow_mut() = Some(data);
|
pub(crate) fn bitmap_data(&self) -> Ref<Option<Snapshot>> {
|
||||||
|
self.bitmap_data.borrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn origin_is_clean(&self) -> bool {
|
pub(crate) fn origin_is_clean(&self) -> bool {
|
||||||
|
@ -94,8 +92,6 @@ impl Serializable for ImageBitmap {
|
||||||
|
|
||||||
// Step 2. Set serialized.[[BitmapData]] to a copy of value's bitmap data.
|
// Step 2. Set serialized.[[BitmapData]] to a copy of value's bitmap data.
|
||||||
let serialized = SerializableImageBitmap {
|
let serialized = SerializableImageBitmap {
|
||||||
width: self.width,
|
|
||||||
height: self.height,
|
|
||||||
bitmap_data: self.bitmap_data.borrow().clone().unwrap(),
|
bitmap_data: self.bitmap_data.borrow().clone().unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -108,12 +104,8 @@ impl Serializable for ImageBitmap {
|
||||||
serialized: Self::Data,
|
serialized: Self::Data,
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) -> Result<DomRoot<Self>, ()> {
|
) -> Result<DomRoot<Self>, ()> {
|
||||||
let image_bitmap = ImageBitmap::new(owner, serialized.width, serialized.height, can_gc);
|
|
||||||
|
|
||||||
// Step 1. Set value's bitmap data to serialized.[[BitmapData]].
|
// Step 1. Set value's bitmap data to serialized.[[BitmapData]].
|
||||||
image_bitmap.set_bitmap_data(serialized.bitmap_data);
|
Ok(ImageBitmap::new(owner, serialized.bitmap_data, can_gc))
|
||||||
|
|
||||||
Ok(image_bitmap)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialized_storage<'a>(
|
fn serialized_storage<'a>(
|
||||||
|
@ -153,8 +145,6 @@ impl Transferable for ImageBitmap {
|
||||||
// Step 2. Set dataHolder.[[BitmapData]] to value's bitmap data.
|
// Step 2. Set dataHolder.[[BitmapData]] to value's bitmap data.
|
||||||
// Step 3. Unset value's bitmap data.
|
// Step 3. Unset value's bitmap data.
|
||||||
let serialized = SerializableImageBitmap {
|
let serialized = SerializableImageBitmap {
|
||||||
width: self.width,
|
|
||||||
height: self.height,
|
|
||||||
bitmap_data: self.bitmap_data.borrow_mut().take().unwrap(),
|
bitmap_data: self.bitmap_data.borrow_mut().take().unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -167,13 +157,12 @@ impl Transferable for ImageBitmap {
|
||||||
_: ImageBitmapId,
|
_: ImageBitmapId,
|
||||||
serialized: SerializableImageBitmap,
|
serialized: SerializableImageBitmap,
|
||||||
) -> Result<DomRoot<Self>, ()> {
|
) -> Result<DomRoot<Self>, ()> {
|
||||||
let image_bitmap =
|
|
||||||
ImageBitmap::new(owner, serialized.width, serialized.height, CanGc::note());
|
|
||||||
|
|
||||||
// Step 1. Set value's bitmap data to serialized.[[BitmapData]].
|
// Step 1. Set value's bitmap data to serialized.[[BitmapData]].
|
||||||
image_bitmap.set_bitmap_data(serialized.bitmap_data);
|
Ok(ImageBitmap::new(
|
||||||
|
owner,
|
||||||
Ok(image_bitmap)
|
serialized.bitmap_data,
|
||||||
|
CanGc::note(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialized_storage<'a>(
|
fn serialized_storage<'a>(
|
||||||
|
@ -195,7 +184,13 @@ impl ImageBitmapMethods<crate::DomTypeHolder> for ImageBitmap {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2. Return this's height, in CSS pixels.
|
// Step 2. Return this's height, in CSS pixels.
|
||||||
self.height
|
self.bitmap_data
|
||||||
|
.borrow()
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.size()
|
||||||
|
.cast()
|
||||||
|
.height
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#dom-imagebitmap-width>
|
/// <https://html.spec.whatwg.org/multipage/#dom-imagebitmap-width>
|
||||||
|
@ -206,7 +201,13 @@ impl ImageBitmapMethods<crate::DomTypeHolder> for ImageBitmap {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2. Return this's width, in CSS pixels.
|
// Step 2. Return this's width, in CSS pixels.
|
||||||
self.width
|
self.bitmap_data
|
||||||
|
.borrow()
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.size()
|
||||||
|
.cast()
|
||||||
|
.width
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#dom-imagebitmap-close>
|
/// <https://html.spec.whatwg.org/multipage/#dom-imagebitmap-close>
|
||||||
|
|
|
@ -31,6 +31,7 @@ net_traits = { workspace = true }
|
||||||
profile_traits = { workspace = true }
|
profile_traits = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
servo_url = { path = "../../url" }
|
servo_url = { path = "../../url" }
|
||||||
|
snapshot = { workspace = true }
|
||||||
strum = { workspace = true }
|
strum = { workspace = true }
|
||||||
strum_macros = { workspace = true }
|
strum_macros = { workspace = true }
|
||||||
uuid = { workspace = true }
|
uuid = { workspace = true }
|
||||||
|
|
|
@ -16,6 +16,7 @@ use malloc_size_of_derive::MallocSizeOf;
|
||||||
use net_traits::filemanager_thread::RelativePos;
|
use net_traits::filemanager_thread::RelativePos;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use servo_url::ImmutableOrigin;
|
use servo_url::ImmutableOrigin;
|
||||||
|
use snapshot::Snapshot;
|
||||||
use strum::EnumIter;
|
use strum::EnumIter;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@ -321,9 +322,7 @@ impl BroadcastClone for DomException {
|
||||||
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
||||||
/// A serializable version of the ImageBitmap interface.
|
/// A serializable version of the ImageBitmap interface.
|
||||||
pub struct SerializableImageBitmap {
|
pub struct SerializableImageBitmap {
|
||||||
pub width: u32,
|
pub bitmap_data: Snapshot,
|
||||||
pub height: u32,
|
|
||||||
pub bitmap_data: Vec<u8>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BroadcastClone for SerializableImageBitmap {
|
impl BroadcastClone for SerializableImageBitmap {
|
||||||
|
|
|
@ -15,5 +15,7 @@ path = "lib.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
euclid = { workspace = true }
|
euclid = { workspace = true }
|
||||||
ipc-channel = { workspace = true }
|
ipc-channel = { workspace = true }
|
||||||
|
malloc_size_of = { workspace = true }
|
||||||
|
malloc_size_of_derive = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
pixels = { path = "../../pixels" }
|
pixels = { path = "../../pixels" }
|
||||||
|
|
|
@ -6,17 +6,18 @@ use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
use euclid::default::Size2D;
|
use euclid::default::Size2D;
|
||||||
use ipc_channel::ipc::IpcSharedMemory;
|
use ipc_channel::ipc::IpcSharedMemory;
|
||||||
|
use malloc_size_of_derive::MallocSizeOf;
|
||||||
use pixels::Multiply;
|
use pixels::Multiply;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
|
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
|
||||||
pub enum PixelFormat {
|
pub enum PixelFormat {
|
||||||
#[default]
|
#[default]
|
||||||
RGBA,
|
RGBA,
|
||||||
BGRA,
|
BGRA,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
|
||||||
pub enum AlphaMode {
|
pub enum AlphaMode {
|
||||||
/// Internal data is opaque (alpha is cleared to 1)
|
/// Internal data is opaque (alpha is cleared to 1)
|
||||||
Opaque,
|
Opaque,
|
||||||
|
@ -48,7 +49,7 @@ impl AlphaMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
||||||
pub enum Data {
|
pub enum Data {
|
||||||
// TODO: https://github.com/servo/servo/issues/36594
|
// TODO: https://github.com/servo/servo/issues/36594
|
||||||
//IPC(IpcSharedMemory),
|
//IPC(IpcSharedMemory),
|
||||||
|
@ -84,7 +85,7 @@ pub type IpcSnapshot = Snapshot<IpcSharedMemory>;
|
||||||
///
|
///
|
||||||
/// Inspired by snapshot for concept in WebGPU spec:
|
/// Inspired by snapshot for concept in WebGPU spec:
|
||||||
/// <https://gpuweb.github.io/gpuweb/#abstract-opdef-get-a-copy-of-the-image-contents-of-a-context>
|
/// <https://gpuweb.github.io/gpuweb/#abstract-opdef-get-a-copy-of-the-image-contents-of-a-context>
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
|
||||||
pub struct Snapshot<T = Data> {
|
pub struct Snapshot<T = Data> {
|
||||||
size: Size2D<u64>,
|
size: Size2D<u64>,
|
||||||
/// internal data (can be any format it will be converted on use if needed)
|
/// internal data (can be any format it will be converted on use if needed)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue