Skip to content
This repository was archived by the owner on Jul 10, 2023. It is now read-only.

Commit 3cb5df4

Browse files
author
bors-servo
committed
Auto merge of #232 - jdm:egl_linux, r=glennw
Support EGL on non-Android Linux. Rebase and squash of #220. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.svg" height="40" alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/rust-layers/232) <!-- Reviewable:end -->
2 parents a68ac95 + 274ba0a commit 3cb5df4

File tree

6 files changed

+219
-22
lines changed

6 files changed

+219
-22
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ addons:
77
packages:
88
- libxxf86vm-dev
99
- libosmesa6-dev
10+
- libgles2-mesa-dev
1011
before_install:
1112
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
1213
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get update; fi

Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22

33
name = "layers"
4-
version = "0.2.3"
4+
version = "0.2.4"
55
authors = ["The Servo Project Developers"]
66
license = "MIT/Apache-2.0"
77

@@ -33,19 +33,23 @@ io-surface = "0.2.0"
3333

3434
[target.i686-unknown-linux-gnu.dependencies]
3535
glx = "0.1.0"
36+
servo-egl = "0.2"
3637
x11 = { version = "2.3.0", features = ["xlib"] }
3738

3839
[target.x86_64-unknown-linux-gnu.dependencies]
3940
glx = "0.1.0"
41+
servo-egl = "0.2"
4042
x11 = { version = "2.3.0", features = ["xlib"] }
4143

4244
[target.arm-unknown-linux-gnueabihf.dependencies]
4345
glx = "0.1.0"
46+
servo-egl = "0.2"
4447
x11 = { version = "2.3.0", features = ["xlib"] }
4548

4649
[target.aarch64-unknown-linux-gnu.dependencies]
4750
glx = "0.1.0"
51+
servo-egl = "0.2"
4852
x11 = { version = "2.3.0", features = ["xlib"] }
4953

5054
[target.arm-linux-androideabi.dependencies]
51-
servo-egl = "0.2"
55+
servo-egl = "0.2"

src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ extern crate x11;
4040
#[cfg(target_os="linux")]
4141
extern crate glx;
4242

43-
#[cfg(target_os="android")]
43+
#[cfg(any(target_os = "linux", target_os = "android"))]
4444
extern crate egl;
4545

4646
pub mod color;
@@ -65,10 +65,13 @@ pub mod platform {
6565
pub mod android {
6666
pub mod surface;
6767
}
68+
#[cfg(any(target_os="android",target_os="linux"))]
69+
pub mod egl {
70+
pub mod surface;
71+
}
6872
#[cfg(target_os="windows")]
6973
pub mod windows {
7074
pub mod surface;
7175
}
7276
pub mod surface;
7377
}
74-

src/platform/egl/surface.rs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// Copyright 2015 The Servo Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution.
3+
//
4+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7+
// option. This file may not be copied, modified, or distributed
8+
// except according to those terms.
9+
10+
//! Implementation of cross-process surfaces implementing EGL surface.
11+
12+
use texturegl::Texture;
13+
14+
use egl::eglext::EGLImageKHR;
15+
use euclid::size::Size2D;
16+
use gleam::gl::{TEXTURE_2D, TexImage2D, UNSIGNED_BYTE};
17+
use skia::gl_context::GLContext;
18+
use skia::gl_rasterization_context::GLRasterizationContext;
19+
use std::iter::repeat;
20+
use std::os::raw::c_void;
21+
use std::sync::Arc;
22+
use std::vec::Vec;
23+
24+
use gleam::gl;
25+
26+
#[cfg(target_os = "linux")]
27+
const GL_FORMAT_BGRA: gl::GLuint = gl::BGRA;
28+
29+
#[cfg(any(target_os = "android", target_os = "gonk"))]
30+
const GL_FORMAT_BGRA: gl::GLuint = gl::BGRA_EXT;
31+
32+
#[cfg(target_os="linux")]
33+
pub use platform::linux::surface::NativeDisplay;
34+
35+
#[cfg(target_os="android")]
36+
pub use platform::android::surface::NativeDisplay;
37+
38+
pub struct EGLImageNativeSurface {
39+
/// An EGLImage for the case of GPU rendering.
40+
image: Option<EGLImageKHR>,
41+
42+
/// A heap-allocated bitmap for the case of CPU rendering.
43+
bitmap: Option<Vec<u8>>,
44+
45+
/// Whether this pixmap will leak if the destructor runs. This is for debugging purposes.
46+
will_leak: bool,
47+
48+
/// The size of this surface.
49+
pub size: Size2D<i32>,
50+
}
51+
52+
unsafe impl Send for EGLImageNativeSurface {}
53+
54+
impl EGLImageNativeSurface {
55+
pub fn new(_: &NativeDisplay, size: Size2D<i32>) -> EGLImageNativeSurface {
56+
let len = size.width * size.height * 4;
57+
let bitmap: Vec<u8> = repeat(0).take(len as usize).collect();
58+
59+
EGLImageNativeSurface {
60+
image: None,
61+
bitmap: Some(bitmap),
62+
will_leak: true,
63+
size: size,
64+
}
65+
}
66+
67+
/// This may only be called on the compositor side.
68+
pub fn bind_to_texture(&self, _: &NativeDisplay, texture: &Texture) {
69+
let _bound = texture.bind();
70+
match self.image {
71+
None => match self.bitmap {
72+
Some(ref bitmap) => {
73+
let data = bitmap.as_ptr() as *const c_void;
74+
unsafe {
75+
TexImage2D(TEXTURE_2D,
76+
0,
77+
GL_FORMAT_BGRA as i32,
78+
self.size.width as i32,
79+
self.size.height as i32,
80+
0,
81+
GL_FORMAT_BGRA as u32,
82+
UNSIGNED_BYTE,
83+
data);
84+
}
85+
}
86+
None => {
87+
debug!("Cannot bind the buffer(CPU rendering), there is no bitmap");
88+
}
89+
},
90+
Some(_image_khr) => {
91+
panic!("TODO: Support GPU rasterizer path on EGL");
92+
}
93+
}
94+
}
95+
96+
/// This may only be called on the painting side.
97+
pub fn upload(&mut self, _: &NativeDisplay, data: &[u8]) {
98+
match self.bitmap {
99+
Some(ref mut bitmap) => {
100+
bitmap.clear();
101+
bitmap.extend_from_slice(data);
102+
}
103+
None => {
104+
debug!("Cannot upload the buffer(CPU rendering), there is no bitmap");
105+
}
106+
}
107+
}
108+
109+
pub fn get_id(&self) -> isize {
110+
match self.image {
111+
None => 0,
112+
Some(image_khr) => image_khr as isize,
113+
}
114+
}
115+
116+
pub fn destroy(&mut self, _graphics_context: &NativeDisplay) {
117+
if self.image.is_some() {
118+
panic!("TODO: Support GPU rendering path on Android");
119+
}
120+
self.mark_wont_leak()
121+
}
122+
123+
pub fn mark_will_leak(&mut self) {
124+
self.will_leak = true
125+
}
126+
127+
pub fn mark_wont_leak(&mut self) {
128+
self.will_leak = false
129+
}
130+
131+
pub fn gl_rasterization_context(&mut self,
132+
_gl_context: Arc<GLContext>)
133+
-> Option<GLRasterizationContext> {
134+
panic!("TODO: Support GL context on EGL");
135+
}
136+
}

src/platform/linux/surface.rs

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
1212
#![allow(non_snake_case)]
1313

14+
//TODO: Linking EGL here is probably wrong - should it be done in gleam / glutin etc?
15+
#[link(name = "EGL")]
16+
extern {}
17+
1418
use texturegl::Texture;
1519

1620
use euclid::size::Size2D;
@@ -26,6 +30,8 @@ use std::str;
2630
use std::sync::Arc;
2731
use x11::xlib;
2832

33+
use egl::egl::{EGLDisplay, GetCurrentDisplay};
34+
2935
/// The display, visual info, and framebuffer configuration. This is needed in order to bind to a
3036
/// texture on the compositor side. This holds only a *weak* reference to the display and does not
3137
/// close it.
@@ -34,12 +40,25 @@ use x11::xlib;
3440
/// to fix because the Display is given to us by the native windowing system, but we should fix it
3541
/// someday.
3642
/// FIXME(pcwalton): Mark nonsendable.
43+
3744
#[derive(Copy, Clone)]
38-
pub struct NativeDisplay {
45+
pub struct GLXDisplayInfo {
3946
pub display: *mut xlib::Display,
4047
visual_info: *mut xlib::XVisualInfo,
4148
framebuffer_configuration: Option<glx::types::GLXFBConfig>,
4249
}
50+
#[derive(Copy, Clone)]
51+
pub struct EGLDisplayInfo {
52+
pub display: EGLDisplay,
53+
}
54+
55+
#[derive(Copy, Clone)]
56+
pub enum NativeDisplay {
57+
EGL(EGLDisplayInfo),
58+
GLX(GLXDisplayInfo),
59+
}
60+
61+
4362

4463
unsafe impl Send for NativeDisplay {}
4564

@@ -50,11 +69,11 @@ impl NativeDisplay {
5069
let (compositor_visual_info, frambuffer_configuration) =
5170
NativeDisplay::compositor_visual_info(display);
5271

53-
NativeDisplay {
72+
NativeDisplay::GLX(GLXDisplayInfo {
5473
display: display,
5574
visual_info: compositor_visual_info,
5675
framebuffer_configuration: frambuffer_configuration,
57-
}
76+
})
5877
}
5978

6079
/// Chooses the compositor visual info using the same algorithm that the compositor uses.
@@ -141,11 +160,22 @@ impl NativeDisplay {
141160
}
142161

143162
pub fn platform_display_data(&self) -> PlatformDisplayData {
144-
PlatformDisplayData {
145-
display: self.display,
146-
visual_info: self.visual_info,
163+
match *self {
164+
NativeDisplay::GLX(info) => {
165+
PlatformDisplayData {
166+
display: info.display,
167+
visual_info: info.visual_info,
168+
}
169+
}
170+
NativeDisplay::EGL(_) => unreachable!(),
147171
}
148172
}
173+
174+
pub fn new_egl_display() -> NativeDisplay {
175+
NativeDisplay::EGL(EGLDisplayInfo {
176+
display: GetCurrentDisplay()
177+
})
178+
}
149179
}
150180

151181
#[derive(RustcDecodable, RustcEncodable)]
@@ -170,7 +200,7 @@ impl Drop for PixmapNativeSurface {
170200
}
171201

172202
impl PixmapNativeSurface {
173-
pub fn new(display: &NativeDisplay, size: Size2D<i32>) -> PixmapNativeSurface {
203+
pub fn new(display: &GLXDisplayInfo, size: Size2D<i32>) -> PixmapNativeSurface {
174204
unsafe {
175205
// Create the pixmap.
176206
let screen = xlib::XDefaultScreen(display.display);
@@ -197,6 +227,11 @@ impl PixmapNativeSurface {
197227
//
198228
// FIXME(pcwalton): RAII for exception safety?
199229
unsafe {
230+
let display = match display {
231+
&NativeDisplay::GLX(info) => info,
232+
&NativeDisplay::EGL(_) => unreachable!(),
233+
};
234+
200235
let pixmap_attributes = [
201236
glx::TEXTURE_TARGET_EXT as i32, glx::TEXTURE_2D_EXT as i32,
202237
glx::TEXTURE_FORMAT_EXT as i32, glx::TEXTURE_FORMAT_RGBA_EXT as i32,
@@ -228,6 +263,11 @@ impl PixmapNativeSurface {
228263
/// This may only be called on the painting side.
229264
pub fn upload(&mut self, display: &NativeDisplay, data: &[u8]) {
230265
unsafe {
266+
let display = match display {
267+
&NativeDisplay::GLX(info) => info,
268+
&NativeDisplay::EGL(_) => unreachable!(),
269+
};
270+
231271
let image = xlib::XCreateImage(display.display,
232272
(*display.visual_info).visual,
233273
32,
@@ -259,6 +299,11 @@ impl PixmapNativeSurface {
259299

260300
pub fn destroy(&mut self, display: &NativeDisplay) {
261301
unsafe {
302+
let display = match display {
303+
&NativeDisplay::GLX(info) => info,
304+
&NativeDisplay::EGL(_) => unreachable!(),
305+
};
306+
262307
assert!(self.pixmap != 0);
263308
xlib::XFreePixmap(display.display, self.pixmap);
264309
self.mark_wont_leak()

0 commit comments

Comments
 (0)