@@ -1316,57 +1316,80 @@ impl Renderer {
1316
1316
let props = & deferred_resolve. image_properties ;
1317
1317
let external_id = props. external_id
1318
1318
. expect ( "BUG: Deferred resolves must be external images!" ) ;
1319
- let image_info = handler. lock_image ( external_id) ;
1319
+ let image = handler. get ( external_id) ;
1320
1320
let texture_id = match self . external_images . entry ( external_id) {
1321
1321
Entry :: Occupied ( mut entry) => {
1322
1322
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 ;
1325
1325
Some ( current_info. texture_id )
1326
1326
} else {
1327
1327
None
1328
1328
}
1329
1329
}
1330
1330
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
+
1340
1352
entry. insert ( ExternalTexture {
1341
1353
texture_id : texture_id,
1342
- timestamp : image_info . timestamp ,
1354
+ timestamp : image . timestamp ,
1343
1355
} ) ;
1356
+
1344
1357
Some ( texture_id)
1345
1358
}
1346
1359
} ;
1347
1360
1348
1361
if let Some ( texture_id) = texture_id {
1349
1362
let resource_rect_index = deferred_resolve. resource_address . 0 as usize ;
1350
1363
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
+ }
1368
1392
}
1369
- handler. unlock_image ( external_id) ;
1370
1393
}
1371
1394
}
1372
1395
@@ -1499,6 +1522,11 @@ impl Renderer {
1499
1522
}
1500
1523
}
1501
1524
1525
+ pub enum ExternalImageData {
1526
+ Buffer ( * const u8 , usize ) ,
1527
+ Native ( u32 ) , // Is a gl::GLuint texture handle
1528
+ }
1529
+
1502
1530
/// The data that an external client should provide about
1503
1531
/// an external image. The timestamp is used to test if
1504
1532
/// the renderer should upload new texture data this
@@ -1514,15 +1542,14 @@ pub struct ExternalImage {
1514
1542
pub v0 : f32 ,
1515
1543
pub u1 : f32 ,
1516
1544
pub v1 : f32 ,
1517
- pub data : * const u8 ,
1518
- pub len : usize ,
1545
+ pub data : ExternalImageData ,
1519
1546
}
1520
1547
1521
1548
/// Interface that an application can implement
1522
1549
/// to support providing external image buffers.
1523
1550
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 ) ;
1526
1553
}
1527
1554
1528
1555
#[ derive( Clone , Debug ) ]
0 commit comments