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/webglrenderingcontext.rs | |
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/webglrenderingcontext.rs')
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 33 |
1 files changed, 33 insertions, 0 deletions
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 { |