Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bleeding in FxR by adding Padding support to ServoSurface #23002

Merged
merged 1 commit into from Mar 26, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Add transparent padding around ServoSurface

  • Loading branch information
paulrouget committed Mar 25, 2019
commit 8f2390fdff4921697e16094c92c80c960e2f9f75
@@ -42,8 +42,7 @@ use style_traits::viewport::ViewportConstraints;
use style_traits::{CSSPixel, DevicePixel, PinchZoomFactor};
use time::{now, precise_time_ns, precise_time_s};
use webrender_api::{
self, DeviceIntPoint, DevicePoint, FramebufferIntRect, FramebufferIntSize, HitTestFlags,
HitTestResult,
self, DeviceIntPoint, DevicePoint, FramebufferIntSize, HitTestFlags, HitTestResult,
};
use webrender_api::{LayoutVector2D, ScrollLocation};
use webvr_traits::WebVRMainThreadHeartbeat;
@@ -578,16 +577,9 @@ impl<Window: WindowMethods> IOCompositor<Window> {
fn send_window_size(&self, size_type: WindowSizeType) {
let dppx = self.page_zoom * self.embedder_coordinates.hidpi_factor;

let flipped_viewport = {
let fb_height = self.embedder_coordinates.framebuffer.height;
let mut view = self.embedder_coordinates.viewport.clone();
view.origin.y = fb_height - view.origin.y - view.size.height;
FramebufferIntRect::from_untyped(&view.to_untyped())
};

self.webrender_api.set_document_view(
self.webrender_document,
flipped_viewport,
self.embedder_coordinates.get_flipped_viewport(),
self.embedder_coordinates.hidpi_factor.get(),
);

@@ -1214,8 +1206,19 @@ impl<Window: WindowMethods> IOCompositor<Window> {
&self.embedder_coordinates.framebuffer.to_untyped(),
);

self.window.gl().clear_color(1.0, 1.0, 1.0, 0.0);
self.window.gl().clear_color(0.0, 0.0, 0.0, 0.0);
self.window.gl().clear(gleam::gl::COLOR_BUFFER_BIT);
let viewport = self.embedder_coordinates.get_flipped_viewport();
self.window.gl().scissor(
viewport.origin.x,
viewport.origin.y,
viewport.size.width,
viewport.size.height,
);
self.window.gl().clear_color(1.0, 1.0, 1.0, 1.0);
self.window.gl().enable(gleam::gl::SCISSOR_TEST);
self.window.gl().clear(gleam::gl::COLOR_BUFFER_BIT);
self.window.gl().disable(gleam::gl::SCISSOR_TEST);

// Paint the scene.
// TODO(gw): Take notice of any errors the renderer returns!
@@ -18,7 +18,8 @@ use std::fmt::{Debug, Error, Formatter};
use std::rc::Rc;
use style_traits::DevicePixel;
use webrender_api::{
DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePoint, FramebufferIntSize, ScrollLocation,
DeviceIntPoint, DeviceIntRect, DeviceIntSize, DevicePoint, FramebufferIntRect,
FramebufferIntSize, ScrollLocation,
};
use webvr::VRServiceManager;
use webvr_traits::WebVRMainThreadHeartbeat;
@@ -173,3 +174,12 @@ pub struct EmbedderCoordinates {
/// Coordinates of the document within the framebuffer.
pub viewport: DeviceIntRect,
}

impl EmbedderCoordinates {
pub fn get_flipped_viewport(&self) -> FramebufferIntRect {
let fb_height = self.framebuffer.height;
let mut view = self.viewport.clone();
view.origin.y = fb_height - view.origin.y - view.size.height;
FramebufferIntRect::from_untyped(&view.to_untyped())
}
}
@@ -16,7 +16,8 @@ use servo::webrender_api::DevicePixel;
use servo::webrender_api::DevicePoint;
use servo::webrender_api::LayoutPixel;
use simpleservo::{
self, deinit, gl_glue, EventLoopWaker, HostTrait, InitOptions, MouseButton, ServoGlue, SERVO,
self, deinit, gl_glue, Coordinates, EventLoopWaker, HostTrait, InitOptions, MouseButton,
ServoGlue, SERVO,
};
use smallvec::SmallVec;
use std::cell::Cell;
@@ -114,14 +115,21 @@ pub unsafe extern "C" fn init_servo(
let gl = gl_glue::egl::init().expect("EGL initialization failure");

let url = CStr::from_ptr(url).to_str().unwrap_or("about:blank");
let coordinates = Coordinates::new(
0,
0,
width as i32,
height as i32,
width as i32,
height as i32,
);
let opts = InitOptions {
args: None,
url: Some(url.to_string()),
width: width,
height: height,
density: hidpi,
enable_subpixel_text_antialiasing: false,
vr_pointer: None,
coordinates,
};
let wakeup = Box::new(EventLoopWakerInstance);
let shut_down_complete = Rc::new(Cell::new(false));
@@ -14,16 +14,17 @@ use servo::compositing::windowing::{
};
use servo::embedder_traits::resources::{self, Resource, ResourceReaderMethods};
use servo::embedder_traits::EmbedderMsg;
use servo::euclid::{TypedPoint2D, TypedScale, TypedSize2D, TypedVector2D};
use servo::euclid::{TypedPoint2D, TypedRect, TypedScale, TypedSize2D, TypedVector2D};
use servo::keyboard_types::{Key, KeyState, KeyboardEvent};
use servo::msg::constellation_msg::TraversalDirection;
use servo::script_traits::{TouchEventType, TouchId};
use servo::servo_config::opts;
use servo::servo_config::{pref, set_pref};
use servo::servo_url::ServoUrl;
use servo::webrender_api::{DevicePixel, FramebufferPixel, ScrollLocation};
use servo::webvr::{VRExternalShmemPtr, VRMainThreadHeartbeat, VRServiceManager};
use servo::{self, gl, webrender_api, BrowserId, Servo};
use std::cell::{Cell, RefCell};
use servo::{self, gl, BrowserId, Servo};
use std::cell::RefCell;
use std::mem;
use std::os::raw::c_void;
use std::path::PathBuf;
@@ -41,13 +42,34 @@ pub use servo::embedder_traits::EventLoopWaker;
pub struct InitOptions {
pub args: Option<String>,
pub url: Option<String>,
pub width: u32,
pub height: u32,
pub coordinates: Coordinates,
pub density: f32,
pub vr_pointer: Option<*mut c_void>,
pub enable_subpixel_text_antialiasing: bool,
}

#[derive(Clone, Debug)]
pub struct Coordinates {
pub viewport: TypedRect<i32, DevicePixel>,
pub framebuffer: TypedSize2D<i32, FramebufferPixel>,
}

impl Coordinates {
pub fn new(
x: i32,
y: i32,
width: i32,
height: i32,
fb_width: i32,
fb_height: i32,
) -> Coordinates {
Coordinates {
viewport: TypedRect::new(TypedPoint2D::new(x, y), TypedSize2D::new(width, height)),
framebuffer: TypedSize2D::new(fb_width, fb_height),
}
}
}

/// Callbacks. Implemented by embedder. Called by Servo.
pub trait HostTrait {
/// Will be called from the thread used for the init call.
@@ -150,8 +172,7 @@ pub fn init(
let callbacks = Rc::new(ServoCallbacks {
gl: gl.clone(),
host_callbacks: callbacks,
width: Cell::new(init_opts.width),
height: Cell::new(init_opts.height),
coordinates: RefCell::new(init_opts.coordinates),
density: init_opts.density,
vr_pointer: init_opts.vr_pointer,
waker,
@@ -270,10 +291,9 @@ impl ServoGlue {
}

/// Let Servo know that the window has been resized.
pub fn resize(&mut self, width: u32, height: u32) -> Result<(), &'static str> {
pub fn resize(&mut self, coordinates: Coordinates) -> Result<(), &'static str> {
info!("resize");
self.callbacks.width.set(width);
self.callbacks.height.set(height);
*self.callbacks.coordinates.borrow_mut() = coordinates;
self.process_event(WindowEvent::Resize)
}

@@ -282,7 +302,7 @@ impl ServoGlue {
/// dx/dy are scroll deltas.
pub fn scroll_start(&mut self, dx: f32, dy: f32, x: i32, y: i32) -> Result<(), &'static str> {
let delta = TypedVector2D::new(dx, dy);
let scroll_location = webrender_api::ScrollLocation::Delta(delta);
let scroll_location = ScrollLocation::Delta(delta);
let event = WindowEvent::Scroll(
scroll_location,
TypedPoint2D::new(x, y),
@@ -296,7 +316,7 @@ impl ServoGlue {
/// dx/dy are scroll deltas.
pub fn scroll(&mut self, dx: f32, dy: f32, x: i32, y: i32) -> Result<(), &'static str> {
let delta = TypedVector2D::new(dx, dy);
let scroll_location = webrender_api::ScrollLocation::Delta(delta);
let scroll_location = ScrollLocation::Delta(delta);
let event = WindowEvent::Scroll(
scroll_location,
TypedPoint2D::new(x, y),
@@ -310,7 +330,7 @@ impl ServoGlue {
/// dx/dy are scroll deltas.
pub fn scroll_end(&mut self, dx: f32, dy: f32, x: i32, y: i32) -> Result<(), &'static str> {
let delta = TypedVector2D::new(dx, dy);
let scroll_location = webrender_api::ScrollLocation::Delta(delta);
let scroll_location = ScrollLocation::Delta(delta);
let event =
WindowEvent::Scroll(scroll_location, TypedPoint2D::new(x, y), TouchEventType::Up);
self.process_event(event)
@@ -529,8 +549,7 @@ struct ServoCallbacks {
waker: Box<dyn EventLoopWaker>,
gl: Rc<dyn gl::Gl>,
host_callbacks: Box<dyn HostTrait>,
width: Cell<u32>,
height: Cell<u32>,
coordinates: RefCell<Coordinates>,
density: f32,
vr_pointer: Option<*mut c_void>,
}
@@ -564,15 +583,13 @@ impl WindowMethods for ServoCallbacks {
}

fn get_coordinates(&self) -> EmbedderCoordinates {
let fb_size = TypedSize2D::new(self.width.get() as i32, self.height.get() as i32);
let pixel_size = TypedSize2D::new(self.width.get() as i32, self.height.get() as i32);
let viewport = webrender_api::DeviceIntRect::new(TypedPoint2D::zero(), pixel_size);
let coords = self.coordinates.borrow();
EmbedderCoordinates {
viewport,
framebuffer: fb_size,
window: (pixel_size, TypedPoint2D::new(0, 0)),
screen: pixel_size,
screen_avail: pixel_size,
viewport: coords.viewport,
framebuffer: coords.framebuffer,
window: (coords.viewport.size, TypedPoint2D::new(0, 0)),
screen: coords.viewport.size,
screen_avail: coords.viewport.size,
hidpi_factor: TypedScale::new(self.density),
}
}
@@ -6,7 +6,9 @@
extern crate log;

use env_logger;
use simpleservo::{self, gl_glue, EventLoopWaker, HostTrait, InitOptions, ServoGlue, SERVO};
use simpleservo::{
self, gl_glue, Coordinates, EventLoopWaker, HostTrait, InitOptions, ServoGlue, SERVO,
};
use std::ffi::{CStr, CString};
use std::mem;
use std::os::raw::{c_char, c_void};
@@ -48,8 +50,8 @@ pub struct CHostCallbacks {
pub struct CInitOptions {
pub args: *const c_char,
pub url: *const c_char,
pub width: u32,
pub height: u32,
pub width: i32,
pub height: i32,
pub density: f32,
pub vr_pointer: *mut c_void,
pub enable_subpixel_text_antialiasing: bool,
@@ -79,11 +81,12 @@ fn init(
let url = unsafe { CStr::from_ptr(opts.url) };
let url = url.to_str().map(|s| s.to_string()).ok();

let coordinates = Coordinates::new(0, 0, opts.width, opts.height, opts.width, opts.height);

let opts = InitOptions {
args,
url,
width: opts.width,
height: opts.height,
coordinates,
density: opts.density,
vr_pointer: if opts.vr_pointer.is_null() {
None
@@ -140,9 +143,12 @@ pub extern "C" fn set_batch_mode(batch: bool) {
}

#[no_mangle]
pub extern "C" fn resize(width: u32, height: u32) {
pub extern "C" fn resize(width: i32, height: i32) {
debug!("resize {}/{}", width, height);
call(|s| s.resize(width, height));
call(|s| {
let coordinates = Coordinates::new(0, 0, width, height, width, height);
s.resize(coordinates)
});
}

#[no_mangle]
@@ -13,7 +13,9 @@ use jni::sys::{jboolean, jfloat, jint, jstring, JNI_TRUE};
use jni::{errors, JNIEnv, JavaVM};
use libc::{dup2, pipe, read};
use log::Level;
use simpleservo::{self, gl_glue, EventLoopWaker, HostTrait, InitOptions, ServoGlue, SERVO};
use simpleservo::{
self, gl_glue, Coordinates, EventLoopWaker, HostTrait, InitOptions, ServoGlue, SERVO,
};
use std::os::raw::{c_char, c_int, c_void};
use std::sync::Arc;
use std::thread;
@@ -129,14 +131,13 @@ pub fn Java_org_mozilla_servoview_JNIServo_deinit(_env: JNIEnv, _class: JClass)
}

#[no_mangle]
pub fn Java_org_mozilla_servoview_JNIServo_resize(
env: JNIEnv,
_: JClass,
width: jint,
height: jint,
) {
debug!("resize {}/{}", width, height);
call(&env, |s| s.resize(width as u32, height as u32));
pub fn Java_org_mozilla_servoview_JNIServo_resize(env: JNIEnv, _: JClass, coordinates: JObject) {
let coords = jni_coords_to_rust_coords(&env, coordinates);
debug!("resize {:#?}", coords);
match coords {
Ok(coords) => call(&env, |s| s.resize(coords.clone())),
Err(error) => throw(&env, &error),
}
}

#[no_mangle]
@@ -587,6 +588,28 @@ fn new_string(env: &JNIEnv, s: &str) -> Result<jstring, jstring> {
}
}

fn jni_coords_to_rust_coords(env: &JNIEnv, obj: JObject) -> Result<Coordinates, String> {
let x = get_non_null_field(env, obj, "x", "I")?
.i()
.map_err(|_| "x not an int")? as i32;
let y = get_non_null_field(env, obj, "y", "I")?
.i()
.map_err(|_| "y not an int")? as i32;
let width = get_non_null_field(env, obj, "width", "I")?
.i()
.map_err(|_| "width not an int")? as i32;
let height = get_non_null_field(env, obj, "height", "I")?
.i()
.map_err(|_| "height not an int")? as i32;
let fb_width = get_non_null_field(env, obj, "fb_width", "I")?
.i()
.map_err(|_| "fb_width not an int")? as i32;
let fb_height = get_non_null_field(env, obj, "fb_height", "I")?
.i()
.map_err(|_| "fb_height not an int")? as i32;
Ok(Coordinates::new(x, y, width, height, fb_width, fb_height))
}

fn get_field<'a>(
env: &'a JNIEnv,
obj: JObject,
@@ -638,12 +661,6 @@ fn get_options(env: &JNIEnv, opts: JObject) -> Result<(InitOptions, bool, Option
let args = get_string(env, opts, "args")?;
let url = get_string(env, opts, "url")?;
let log_str = get_string(env, opts, "logStr")?;
let width = get_non_null_field(env, opts, "width", "I")?
.i()
.map_err(|_| "width not an int")? as u32;
let height = get_non_null_field(env, opts, "height", "I")?
.i()
.map_err(|_| "height not an int")? as u32;
let density = get_non_null_field(env, opts, "density", "F")?
.f()
.map_err(|_| "densitiy not a float")? as f32;
@@ -657,11 +674,19 @@ fn get_options(env: &JNIEnv, opts: JObject) -> Result<(InitOptions, bool, Option
let vr_pointer = get_non_null_field(env, opts, "VRExternalContext", "J")?
.j()
.map_err(|_| "VRExternalContext is not a long")? as *mut c_void;
let coordinates = get_non_null_field(
env,
opts,
"coordinates",
"Lorg/mozilla/servoview/JNIServo$ServoCoordinates;",
)?
.l()
.map_err(|_| "coordinates is not an object")?;
let coordinates = jni_coords_to_rust_coords(&env, coordinates)?;
let opts = InitOptions {
args,
url,
width,
height,
coordinates,
density,
enable_subpixel_text_antialiasing,
vr_pointer: if vr_pointer.is_null() {
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.