Skip to content

Commit 373a7a9

Browse files
committed
Add support for providing a native GL texture as external image.
1 parent 307553d commit 373a7a9

File tree

3 files changed

+69
-41
lines changed

3 files changed

+69
-41
lines changed

sample/src/main.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use euclid::{Size2D, Point2D, Rect, Matrix4D};
88
use gleam::gl;
99
use std::path::PathBuf;
1010
use std::ffi::CStr;
11-
use webrender::{ExternalImage, ExternalImageHandler};
11+
use webrender::{ExternalImage, ExternalImageData, ExternalImageHandler};
1212
use webrender_traits::{AuxiliaryListsBuilder, ColorF, Epoch, GlyphInstance, ExternalImageId};
1313
use webrender_traits::{ImageData, ImageFormat, PipelineId, RendererKind, ImageRendering};
1414
use std::fs::File;
@@ -72,7 +72,7 @@ impl ImageHandler {
7272
}
7373

7474
impl ExternalImageHandler for ImageHandler {
75-
fn lock_image(&mut self, _: ExternalImageId) -> ExternalImage {
75+
fn get(&mut self, _: ExternalImageId) -> ExternalImage {
7676
self.frame += 1;
7777

7878
if self.frame == 10 {
@@ -88,12 +88,13 @@ impl ExternalImageHandler for ImageHandler {
8888
v0: 0.0,
8989
u1: 2.0,
9090
v1: 2.0,
91-
data: self.data.as_ptr(),
92-
len: self.data.len(),
91+
data: ExternalImageData::Buffer(self.data.as_ptr(),
92+
self.data.len())
9393
}
9494
}
9595

96-
fn unlock_image(&mut self, _: ExternalImageId) {
96+
fn release(&mut self, _: ExternalImageId) {
97+
9798
}
9899
}
99100

webrender/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,5 @@ extern crate offscreen_gl_context;
120120
extern crate byteorder;
121121
extern crate rayon;
122122

123-
pub use renderer::{ExternalImage, ExternalImageHandler};
123+
pub use renderer::{ExternalImage, ExternalImageData, ExternalImageHandler};
124124
pub use renderer::{Renderer, RendererOptions};

webrender/src/renderer.rs

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,57 +1316,80 @@ impl Renderer {
13161316
let props = &deferred_resolve.image_properties;
13171317
let external_id = props.external_id
13181318
.expect("BUG: Deferred resolves must be external images!");
1319-
let image_info = handler.lock_image(external_id);
1319+
let image = handler.get(external_id);
13201320
let texture_id = match self.external_images.entry(external_id) {
13211321
Entry::Occupied(mut entry) => {
13221322
let current_info = entry.get_mut();
1323-
if image_info.timestamp != current_info.timestamp {
1324-
current_info.timestamp = image_info.timestamp;
1323+
if image.timestamp != current_info.timestamp {
1324+
current_info.timestamp = image.timestamp;
13251325
Some(current_info.texture_id)
13261326
} else {
13271327
None
13281328
}
13291329
}
13301330
Entry::Vacant(entry) => {
1331-
let texture_id = self.device
1332-
.create_texture_ids(1, TextureTarget::Default)[0];
1333-
self.device.init_texture(texture_id,
1334-
props.width,
1335-
props.height,
1336-
props.format,
1337-
TextureFilter::Linear,
1338-
RenderTargetMode::None,
1339-
None);
1331+
let texture_id = match image.data {
1332+
ExternalImageData::Buffer(..) => {
1333+
// For a custom user buffer, allocate a native texture.
1334+
let texture_id = self.device
1335+
.create_texture_ids(1, TextureTarget::Default)[0];
1336+
self.device.init_texture(texture_id,
1337+
props.width,
1338+
props.height,
1339+
props.format,
1340+
TextureFilter::Linear,
1341+
RenderTargetMode::None,
1342+
None);
1343+
texture_id
1344+
}
1345+
ExternalImageData::Native(texture_id) => {
1346+
// User has supplied a native texture, so
1347+
// just use it!
1348+
TextureId::new(texture_id)
1349+
}
1350+
};
1351+
13401352
entry.insert(ExternalTexture {
13411353
texture_id: texture_id,
1342-
timestamp: image_info.timestamp,
1354+
timestamp: image.timestamp,
13431355
});
1356+
13441357
Some(texture_id)
13451358
}
13461359
};
13471360

13481361
if let Some(texture_id) = texture_id {
13491362
let resource_rect_index = deferred_resolve.resource_address.0 as usize;
13501363
let resource_rect = &mut frame.gpu_resource_rects[resource_rect_index];
1351-
resource_rect.uv0 = Point2D::new(image_info.u0, image_info.v0);
1352-
resource_rect.uv1 = Point2D::new(image_info.u1, image_info.v1);
1353-
1354-
let data = unsafe {
1355-
slice::from_raw_parts(image_info.data, image_info.len)
1356-
};
1357-
1358-
// TODO(gw): This is not going to be the most efficient way to
1359-
// upload an external image on each platform. But it works for
1360-
// now and we can profile and optimize later.
1361-
self.device.update_texture(texture_id,
1362-
0,
1363-
0,
1364-
props.width,
1365-
props.height,
1366-
props.stride,
1367-
data);
1364+
resource_rect.uv0 = Point2D::new(image.u0, image.v0);
1365+
resource_rect.uv1 = Point2D::new(image.u1, image.v1);
1366+
1367+
// If user supplied a CPU data pointer, upload it to the
1368+
// GPU now.
1369+
match image.data {
1370+
ExternalImageData::Buffer(ptr, len) => {
1371+
let data = unsafe {
1372+
slice::from_raw_parts(ptr, len)
1373+
};
1374+
1375+
// TODO(gw): This is not going to be the most efficient way to
1376+
// upload an external image on each platform. But it works for
1377+
// now and we can profile and optimize later.
1378+
self.device.update_texture(texture_id,
1379+
0,
1380+
0,
1381+
props.width,
1382+
props.height,
1383+
props.stride,
1384+
data);
1385+
1386+
// The data is uploaded to the GPU now, so client is
1387+
// able to release this image.
1388+
handler.release(external_id)
1389+
}
1390+
ExternalImageData::Native(..) => {}
1391+
}
13681392
}
1369-
handler.unlock_image(external_id);
13701393
}
13711394
}
13721395

@@ -1499,6 +1522,11 @@ impl Renderer {
14991522
}
15001523
}
15011524

1525+
pub enum ExternalImageData {
1526+
Buffer(*const u8, usize),
1527+
Native(u32), // Is a gl::GLuint texture handle
1528+
}
1529+
15021530
/// The data that an external client should provide about
15031531
/// an external image. The timestamp is used to test if
15041532
/// the renderer should upload new texture data this
@@ -1514,15 +1542,14 @@ pub struct ExternalImage {
15141542
pub v0: f32,
15151543
pub u1: f32,
15161544
pub v1: f32,
1517-
pub data: *const u8,
1518-
pub len: usize,
1545+
pub data: ExternalImageData,
15191546
}
15201547

15211548
/// Interface that an application can implement
15221549
/// to support providing external image buffers.
15231550
pub trait ExternalImageHandler {
1524-
fn lock_image(&mut self, key: ExternalImageId) -> ExternalImage;
1525-
fn unlock_image(&mut self, key: ExternalImageId);
1551+
fn get(&mut self, key: ExternalImageId) -> ExternalImage;
1552+
fn release(&mut self, key: ExternalImageId);
15261553
}
15271554

15281555
#[derive(Clone, Debug)]

0 commit comments

Comments
 (0)