Update WR (removal of RGB8, which isn't supported on some hardware).

Instead, we convert any source RGB8 images into RGBx (with
an opaque alpha channel).
This commit is contained in:
Glenn Watson 2018-01-08 08:18:52 +10:00
parent 8e226fe9ff
commit 3f2ebfa422
3 changed files with 33 additions and 42 deletions

4
Cargo.lock generated
View file

@ -3567,7 +3567,7 @@ dependencies = [
[[package]] [[package]]
name = "webrender" name = "webrender"
version = "0.56.1" version = "0.56.1"
source = "git+https://github.com/servo/webrender#92959212d069eace3cf1c5f939458108de4432b5" source = "git+https://github.com/servo/webrender#a21197eb1e427730c7bec6eec07bc6cc352d452e"
dependencies = [ dependencies = [
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3595,7 +3595,7 @@ dependencies = [
[[package]] [[package]]
name = "webrender_api" name = "webrender_api"
version = "0.56.1" version = "0.56.1"
source = "git+https://github.com/servo/webrender#92959212d069eace3cf1c5f939458108de4432b5" source = "git+https://github.com/servo/webrender#a21197eb1e427730c7bec6eec07bc6cc352d452e"
dependencies = [ dependencies = [
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -487,7 +487,7 @@ impl<VR: WebVRRenderHandler + 'static, OB: WebGLThreadObserver> WebGLThread<VR,
width: size.width as u32, width: size.width as u32,
height: size.height as u32, height: size.height as u32,
stride: None, stride: None,
format: if alpha { webrender_api::ImageFormat::BGRA8 } else { webrender_api::ImageFormat::RGB8 }, format: webrender_api::ImageFormat::BGRA8,
offset: 0, offset: 0,
is_opaque: !alpha, is_opaque: !alpha,
} }

View file

@ -34,16 +34,6 @@ use webrender_api;
// Helper functions. // Helper functions.
// ====================================================================== // ======================================================================
fn convert_format(format: PixelFormat) -> webrender_api::ImageFormat {
match format {
PixelFormat::K8 | PixelFormat::KA8 => {
panic!("Not support by webrender yet");
}
PixelFormat::RGB8 => webrender_api::ImageFormat::RGB8,
PixelFormat::BGRA8 => webrender_api::ImageFormat::BGRA8,
}
}
fn decode_bytes_sync(key: LoadKey, bytes: &[u8]) -> DecoderMsg { fn decode_bytes_sync(key: LoadKey, bytes: &[u8]) -> DecoderMsg {
let image = load_from_memory(bytes); let image = load_from_memory(bytes);
DecoderMsg { DecoderMsg {
@ -63,19 +53,35 @@ fn get_placeholder_image(webrender_api: &webrender_api::RenderApi, path: &PathBu
fn set_webrender_image_key(webrender_api: &webrender_api::RenderApi, image: &mut Image) { fn set_webrender_image_key(webrender_api: &webrender_api::RenderApi, image: &mut Image) {
if image.id.is_some() { return; } if image.id.is_some() { return; }
let format = convert_format(image.format);
let mut bytes = Vec::new(); let mut bytes = Vec::new();
let is_opaque = match image.format {
PixelFormat::BGRA8 => {
bytes.extend_from_slice(&*image.bytes); bytes.extend_from_slice(&*image.bytes);
if format == webrender_api::ImageFormat::BGRA8 { premultiply(bytes.as_mut_slice())
premultiply(bytes.as_mut_slice());
} }
PixelFormat::RGB8 => {
for bgr in image.bytes.chunks(3) {
bytes.extend_from_slice(&[
bgr[2],
bgr[1],
bgr[0],
0xff
]);
}
true
}
PixelFormat::K8 | PixelFormat::KA8 => {
panic!("Not support by webrender yet");
}
};
let descriptor = webrender_api::ImageDescriptor { let descriptor = webrender_api::ImageDescriptor {
width: image.width, width: image.width,
height: image.height, height: image.height,
stride: None, stride: None,
format: format, format: webrender_api::ImageFormat::BGRA8,
offset: 0, offset: 0,
is_opaque: is_image_opaque(format, &bytes), is_opaque,
}; };
let data = webrender_api::ImageData::new(bytes); let data = webrender_api::ImageData::new(bytes);
let image_key = webrender_api.generate_image_key(); let image_key = webrender_api.generate_image_key();
@ -85,28 +91,10 @@ fn set_webrender_image_key(webrender_api: &webrender_api::RenderApi, image: &mut
image.id = Some(image_key); image.id = Some(image_key);
} }
// TODO(gw): This is a port of the old is_image_opaque code from WR. // Returns true if the image was found to be
// Consider using SIMD to speed this up if it shows in profiles. // completely opaque.
fn is_image_opaque(format: webrender_api::ImageFormat, bytes: &[u8]) -> bool { fn premultiply(data: &mut [u8]) -> bool {
match format {
webrender_api::ImageFormat::BGRA8 => {
let mut is_opaque = true; let mut is_opaque = true;
for i in 0..(bytes.len() / 4) {
if bytes[i * 4 + 3] != 255 {
is_opaque = false;
break;
}
}
is_opaque
}
webrender_api::ImageFormat::RGB8 => true,
webrender_api::ImageFormat::RG8 => true,
webrender_api::ImageFormat::A8 => false,
webrender_api::ImageFormat::Invalid | webrender_api::ImageFormat::RGBAF32 => unreachable!(),
}
}
fn premultiply(data: &mut [u8]) {
let length = data.len(); let length = data.len();
let mut i = 0; let mut i = 0;
@ -121,7 +109,10 @@ fn premultiply(data: &mut [u8]) {
data[i + 2] = (r * a / 255) as u8; data[i + 2] = (r * a / 255) as u8;
i += 4; i += 4;
is_opaque = is_opaque && a == 255;
} }
is_opaque
} }
// ====================================================================== // ======================================================================