зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #20400 - Implement HTMLCanvasElement.toDataURL for WebGL canvas (fixes #19147) (from servo:webgl); r=emilio
Source-Repo: https://github.com/servo/servo Source-Revision: 72f326b22bfa9dfae30941883979fd9f3090d044 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 9118aa2e1d2e5022092fa4134dc9c85785d62aaf
This commit is contained in:
Родитель
76d07ca4c5
Коммит
b341652060
|
@ -345,11 +345,22 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement {
|
|||
Finite::wrap(self.Height() as f64))?;
|
||||
image_data.get_data_array()
|
||||
}
|
||||
Some(CanvasContext::WebGL(ref context)) => {
|
||||
match context.get_image_data(self.Width(), self.Height()) {
|
||||
Some(data) => data,
|
||||
None => return Ok("data:,".into()),
|
||||
}
|
||||
}
|
||||
Some(CanvasContext::WebGL2(ref context)) => {
|
||||
match context.base_context().get_image_data(self.Width(), self.Height()) {
|
||||
Some(data) => data,
|
||||
None => return Ok("data:,".into()),
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// Each pixel is fully-transparent black.
|
||||
vec![0; (self.Width() * self.Height() * 4) as usize]
|
||||
}
|
||||
_ => return Err(Error::NotSupported) // WebGL
|
||||
};
|
||||
|
||||
// Only handle image/png for now.
|
||||
|
|
|
@ -57,6 +57,7 @@ use offscreen_gl_context::{GLContextAttributes, GLLimits};
|
|||
use script_layout_interface::HTMLCanvasDataSource;
|
||||
use servo_config::prefs::PREFS;
|
||||
use std::cell::{Cell, Ref};
|
||||
use std::cmp;
|
||||
use std::iter::FromIterator;
|
||||
use std::ptr::NonNull;
|
||||
use webrender_api;
|
||||
|
@ -1151,6 +1152,38 @@ impl WebGLRenderingContext {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used by HTMLCanvasElement.toDataURL
|
||||
//
|
||||
// This emits errors quite liberally, but the spec says that this operation
|
||||
// can fail and that it is UB what happens in that case.
|
||||
//
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#2.2
|
||||
pub fn get_image_data(&self, mut width: u32, mut height: u32) -> Option<Vec<u8>> {
|
||||
if !self.validate_framebuffer_complete() {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some((fb_width, fb_height)) = self.get_current_framebuffer_size() {
|
||||
width = cmp::min(width, fb_width as u32);
|
||||
height = cmp::min(height, fb_height as u32);
|
||||
} else {
|
||||
self.webgl_error(InvalidOperation);
|
||||
return None;
|
||||
}
|
||||
|
||||
let (sender, receiver) = webgl_channel().unwrap();
|
||||
self.send_command(WebGLCommand::ReadPixels(
|
||||
0,
|
||||
0,
|
||||
width as i32,
|
||||
height as i32,
|
||||
constants::RGBA,
|
||||
constants::UNSIGNED_BYTE,
|
||||
sender,
|
||||
));
|
||||
Some(receiver.recv().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for WebGLRenderingContext {
|
||||
|
|
Загрузка…
Ссылка в новой задаче