diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2018-03-24 00:18:28 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-24 00:18:28 -0400 |
commit | 72f326b22bfa9dfae30941883979fd9f3090d044 (patch) | |
tree | ff9899af648934f5a142bcc17397fe9c0969c6dd /components/script/dom | |
parent | 5a432eaad33f36591f62c3d2671ffd9956be3594 (diff) | |
parent | a77d35b60c5e9b01f868daff510fbb7e44ca1bbc (diff) | |
download | servo-72f326b22bfa9dfae30941883979fd9f3090d044.tar.gz servo-72f326b22bfa9dfae30941883979fd9f3090d044.zip |
Auto merge of #20400 - servo:webgl, r=emilio
Implement HTMLCanvasElement.toDataURL for WebGL canvas (fixes #19147)
<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20400)
<!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/htmlcanvaselement.rs | 13 | ||||
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 33 |
2 files changed, 45 insertions, 1 deletions
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index c866664cbcf..b1bea124a7b 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -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. diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index d9d993e5b21..204426f8063 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -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 { |