aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorAnthony Ramine <n.oxyde@gmail.com>2018-10-08 13:49:58 +0200
committerAnthony Ramine <n.oxyde@gmail.com>2018-10-09 14:57:02 +0200
commit6c469b90b1ae34bddcb7da19eacfa6ad4467cf35 (patch)
tree1746b4cef5b9710368c7c86b360906a417e0a78f /components/script/dom
parent05ef233097e17c3cdd0000f434d1592e8e26ff54 (diff)
downloadservo-6c469b90b1ae34bddcb7da19eacfa6ad4467cf35.tar.gz
servo-6c469b90b1ae34bddcb7da19eacfa6ad4467cf35.zip
Share some code between 2D canvas and WebGL
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs24
-rw-r--r--components/script/dom/htmlcanvaselement.rs4
-rw-r--r--components/script/dom/webglrenderingcontext.rs63
3 files changed, 27 insertions, 64 deletions
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index 2617f9e7ed5..dacabcccce5 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -1168,7 +1168,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
// FIXME(nox): This is probably wrong when this is a context for an
// offscreen canvas.
let canvas_size = self.canvas.as_ref().map_or(Size2D::zero(), |c| c.get_size());
- let read_rect = match clip(origin, size, canvas_size) {
+ let read_rect = match pixels::clip(origin, size, canvas_size) {
Some(rect) => rect,
None => {
// All the pixels are outside the canvas surface.
@@ -1220,7 +1220,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
Point2D::new(dirty_x, dirty_y),
Size2D::new(dirty_width, dirty_height),
);
- let src_rect = match clip(src_origin, src_size, imagedata_size) {
+ let src_rect = match pixels::clip(src_origin, src_size, imagedata_size) {
Some(rect) => rect,
None => return,
};
@@ -1230,7 +1230,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
);
// By clipping to the canvas surface, we avoid sending any pixel
// that would fall outside it.
- let dst_rect = match clip(dst_origin, src_rect.size, canvas_size) {
+ let dst_rect = match pixels::clip(dst_origin, src_rect.size, canvas_size) {
Some(rect) => rect,
None => return,
};
@@ -1537,21 +1537,3 @@ fn adjust_size_sign(
}
(origin, size.to_u32())
}
-
-fn clip(
- mut origin: Point2D<i32>,
- mut size: Size2D<u32>,
- surface: Size2D<u32>,
-) -> Option<Rect<u32>> {
- if origin.x < 0 {
- size.width = size.width.saturating_sub(-origin.x as u32);
- origin.x = 0;
- }
- if origin.y < 0 {
- size.height = size.height.saturating_sub(-origin.y as u32);
- origin.y = 0;
- }
- Rect::new(origin.to_u32(), size)
- .intersection(&Rect::from_size(surface))
- .filter(|rect| !rect.is_empty())
-}
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs
index 5cc28fcf461..8f572336573 100644
--- a/components/script/dom/htmlcanvaselement.rs
+++ b/components/script/dom/htmlcanvaselement.rs
@@ -368,13 +368,13 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement {
context.get_rect(Rect::from_size(self.get_size()))
},
Some(CanvasContext::WebGL(ref context)) => {
- match context.get_image_data(self.Width(), self.Height()) {
+ match context.get_image_data(self.get_size()) {
Some(data) => data,
None => return Ok(USVString("data:,".into())),
}
},
Some(CanvasContext::WebGL2(ref context)) => {
- match context.base_context().get_image_data(self.Width(), self.Height()) {
+ match context.base_context().get_image_data(self.get_size()) {
Some(data) => data,
None => return Ok(USVString("data:,".into())),
}
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 4e3658fa524..bfccd5e6f68 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -52,7 +52,7 @@ use dom::webgluniformlocation::WebGLUniformLocation;
use dom::webglvertexarrayobjectoes::WebGLVertexArrayObjectOES;
use dom::window::Window;
use dom_struct::dom_struct;
-use euclid::Size2D;
+use euclid::{Point2D, Rect, Size2D};
use half::f16;
use ipc_channel::ipc;
use js::jsapi::{JSContext, JSObject, Type};
@@ -1070,7 +1070,7 @@ impl WebGLRenderingContext {
// 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, width: u32, height: u32) -> Option<Vec<u8>> {
+ pub fn get_image_data(&self, mut size: Size2D<u32>) -> Option<Vec<u8>> {
handle_potential_webgl_error!(self, self.validate_framebuffer(), return None);
let (fb_width, fb_height) = handle_potential_webgl_error!(
@@ -1078,15 +1078,12 @@ impl WebGLRenderingContext {
self.get_current_framebuffer_size().ok_or(InvalidOperation),
return None
);
- let width = cmp::min(width, fb_width as u32);
- let height = cmp::min(height, fb_height as u32);
+ size.width = cmp::min(size.width, fb_width as u32);
+ size.height = cmp::min(size.height, fb_height as u32);
let (sender, receiver) = ipc::bytes_channel().unwrap();
self.send_command(WebGLCommand::ReadPixels(
- 0,
- 0,
- width as i32,
- height as i32,
+ Rect::from_size(size),
constants::RGBA,
constants::UNSIGNED_BYTE,
sender,
@@ -2879,45 +2876,29 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
return self.webgl_error(InvalidOperation);
}
- let mut src_x = x;
- let mut src_y = y;
- let mut src_width = width;
- let mut src_height = height;
- let mut dest_offset = 0;
-
- if src_x < 0 {
- if src_width <= -src_x {
- return;
- }
- dest_offset += bytes_per_pixel * -src_x;
- src_width += src_x;
- src_x = 0;
- }
- if src_y < 0 {
- if src_height <= -src_y {
- return;
- }
- dest_offset += row_len * -src_y;
- src_height += src_y;
- src_y = 0;
- }
+ let src_origin = Point2D::new(x, y);
+ let src_size = Size2D::new(width as u32, height as u32);
+ let fb_size = Size2D::new(fb_width as u32, fb_height as u32);
+ let src_rect = match pixels::clip(src_origin, src_size, fb_size) {
+ Some(rect) => rect,
+ None => return,
+ };
- if src_x + src_width > fb_width {
- src_width = fb_width - src_x;
+ let mut dest_offset = 0;
+ if x < 0 {
+ dest_offset += -x * bytes_per_pixel;
}
- if src_y + src_height > fb_height {
- src_height = fb_height - src_y;
+ if y < 0 {
+ dest_offset += -y * row_len;
}
let (sender, receiver) = ipc::bytes_channel().unwrap();
- self.send_command(WebGLCommand::ReadPixels(
- src_x, src_y, src_width, src_height, format, pixel_type, sender,
- ));
-
+ self.send_command(WebGLCommand::ReadPixels(src_rect, format, pixel_type, sender));
let src = receiver.recv().unwrap();
- let src_row_len = (src_width * bytes_per_pixel) as usize;
- for i in 0..src_height {
- let dest_start = (dest_offset + i * dest_stride) as usize;
+
+ let src_row_len = src_rect.size.width as usize * bytes_per_pixel as usize;
+ for i in 0..src_rect.size.height {
+ let dest_start = dest_offset as usize + i as usize * dest_stride as usize;
let dest_end = dest_start + src_row_len;
let src_start = i as usize * src_row_len;
let src_end = src_start + src_row_len;