@@ -24,11 +24,10 @@ use profiler::{Profiler, BackendProfileCounters};
24
24
use profiler:: { GpuProfileTag , RendererProfileTimers , RendererProfileCounters } ;
25
25
use render_backend:: RenderBackend ;
26
26
use std:: cmp;
27
- use std:: collections:: hash_map:: Entry ;
28
27
use std:: collections:: HashMap ;
29
28
use std:: f32;
30
29
use std:: hash:: BuildHasherDefault ;
31
- use std:: { mem, slice } ;
30
+ use std:: mem;
32
31
use std:: path:: PathBuf ;
33
32
use std:: sync:: { Arc , Mutex } ;
34
33
use std:: sync:: mpsc:: { channel, Receiver , Sender } ;
@@ -39,7 +38,7 @@ use tiling::{RenderTarget, ClearTile};
39
38
use time:: precise_time_ns;
40
39
use util:: TransformedRectKind ;
41
40
use webrender_traits:: { ColorF , Epoch , FlushNotifier , PipelineId , RenderNotifier , RenderDispatcher } ;
42
- use webrender_traits:: { ImageFormat , RenderApiSender , RendererKind } ;
41
+ use webrender_traits:: { ExternalImageId , ImageFormat , RenderApiSender , RendererKind } ;
43
42
44
43
pub const MAX_VERTEX_TEXTURE_WIDTH : usize = 1024 ;
45
44
@@ -63,13 +62,6 @@ const GPU_TAG_PRIM_BORDER: GpuProfileTag = GpuProfileTag { label: "Border", colo
63
62
const GPU_TAG_PRIM_CACHE_IMAGE : GpuProfileTag = GpuProfileTag { label : "CacheImage" , color : debug_colors:: SILVER } ;
64
63
const GPU_TAG_BLUR : GpuProfileTag = GpuProfileTag { label : "Blur" , color : debug_colors:: VIOLET } ;
65
64
66
- /// Internal details regarding external textures that the
67
- /// renderer knows about.
68
- struct ExternalTexture {
69
- timestamp : u64 ,
70
- texture_id : TextureId ,
71
- }
72
-
73
65
#[ derive( Debug , Copy , Clone , PartialEq ) ]
74
66
pub enum BlendMode {
75
67
None ,
@@ -416,7 +408,7 @@ pub struct Renderer {
416
408
external_image_handler : Option < Box < ExternalImageHandler > > ,
417
409
418
410
/// Map of external image IDs to native textures.
419
- external_images : HashMap < ExternalImageId , ExternalTexture , BuildHasherDefault < FnvHasher > > ,
411
+ external_images : HashMap < ExternalImageId , TextureId , BuildHasherDefault < FnvHasher > > ,
420
412
}
421
413
422
414
impl Renderer {
@@ -822,10 +814,9 @@ impl Renderer {
822
814
& SourceTexture :: Invalid => TextureId :: invalid ( ) ,
823
815
& SourceTexture :: WebGL ( id) => TextureId :: new ( id) ,
824
816
& SourceTexture :: External ( ref key) => {
825
- self . external_images
826
- . get ( key)
827
- . expect ( "BUG: External image should be resolved by now!" )
828
- . texture_id
817
+ * self . external_images
818
+ . get ( key)
819
+ . expect ( "BUG: External image should be resolved by now!" )
829
820
}
830
821
& SourceTexture :: TextureCache ( index) => {
831
822
self . cache_texture_id_map [ index. 0 ]
@@ -1353,9 +1344,7 @@ impl Renderer {
1353
1344
self . device . set_blend ( false ) ;
1354
1345
}
1355
1346
1356
- fn draw_tile_frame ( & mut self ,
1357
- frame : & mut Frame ,
1358
- framebuffer_size : & Size2D < u32 > ) {
1347
+ fn update_deferred_resolves ( & mut self , frame : & mut Frame ) {
1359
1348
// The first thing we do is run through any pending deferred
1360
1349
// resolves, and use a callback to get the UV rect for this
1361
1350
// custom item. Then we patch the resource_rects structure
@@ -1366,89 +1355,40 @@ impl Renderer {
1366
1355
. expect ( "Found external image, but no handler set!" ) ;
1367
1356
1368
1357
for deferred_resolve in & frame. deferred_resolves {
1369
- // First, check if we need to update this external image.
1370
- // If we haven't got this image previously, or if the
1371
- // version of the image has changed, then we will ask
1372
- // for the image and upload it to the GPU.
1373
1358
let props = & deferred_resolve. image_properties ;
1374
1359
let external_id = props. external_id
1375
1360
. expect ( "BUG: Deferred resolves must be external images!" ) ;
1376
1361
let image = handler. get ( external_id) ;
1377
- let texture_id = match self . external_images . entry ( external_id) {
1378
- Entry :: Occupied ( mut entry) => {
1379
- let current_info = entry. get_mut ( ) ;
1380
- if image. timestamp != current_info. timestamp {
1381
- current_info. timestamp = image. timestamp ;
1382
- Some ( current_info. texture_id )
1383
- } else {
1384
- None
1385
- }
1386
- }
1387
- Entry :: Vacant ( entry) => {
1388
- let texture_id = match image. data {
1389
- ExternalImageData :: Buffer ( ..) => {
1390
- // For a custom user buffer, allocate a native texture.
1391
- let texture_id = self . device
1392
- . create_texture_ids ( 1 , TextureTarget :: Default ) [ 0 ] ;
1393
- self . device . init_texture ( texture_id,
1394
- props. width ,
1395
- props. height ,
1396
- props. format ,
1397
- TextureFilter :: Linear ,
1398
- RenderTargetMode :: None ,
1399
- None ) ;
1400
- texture_id
1401
- }
1402
- ExternalImageData :: Native ( texture_id) => {
1403
- // User has supplied a native texture, so
1404
- // just use it!
1405
- TextureId :: new ( texture_id)
1406
- }
1407
- } ;
1408
1362
1409
- entry. insert ( ExternalTexture {
1410
- texture_id : texture_id,
1411
- timestamp : image. timestamp ,
1412
- } ) ;
1413
-
1414
- Some ( texture_id)
1415
- }
1363
+ let texture_id = match image. source {
1364
+ ExternalImageSource :: NativeTexture ( texture_id) => TextureId :: new ( texture_id) ,
1416
1365
} ;
1417
1366
1418
- if let Some ( texture_id) = texture_id {
1419
- let resource_rect_index = deferred_resolve. resource_address . 0 as usize ;
1420
- let resource_rect = & mut frame. gpu_resource_rects [ resource_rect_index] ;
1421
- resource_rect. uv0 = Point2D :: new ( image. u0 , image. v0 ) ;
1422
- resource_rect. uv1 = Point2D :: new ( image. u1 , image. v1 ) ;
1423
-
1424
- // If user supplied a CPU data pointer, upload it to the
1425
- // GPU now.
1426
- match image. data {
1427
- ExternalImageData :: Buffer ( ptr, len) => {
1428
- let data = unsafe {
1429
- slice:: from_raw_parts ( ptr, len)
1430
- } ;
1431
-
1432
- // TODO(gw): This is not going to be the most efficient way to
1433
- // upload an external image on each platform. But it works for
1434
- // now and we can profile and optimize later.
1435
- self . device . update_texture ( texture_id,
1436
- 0 ,
1437
- 0 ,
1438
- props. width ,
1439
- props. height ,
1440
- props. stride ,
1441
- data) ;
1442
-
1443
- // The data is uploaded to the GPU now, so client is
1444
- // able to release this image.
1445
- handler. release ( external_id)
1446
- }
1447
- ExternalImageData :: Native ( ..) => { }
1448
- }
1449
- }
1367
+ self . external_images . insert ( external_id, texture_id) ;
1368
+ let resource_rect_index = deferred_resolve. resource_address . 0 as usize ;
1369
+ let resource_rect = & mut frame. gpu_resource_rects [ resource_rect_index] ;
1370
+ resource_rect. uv0 = Point2D :: new ( image. u0 , image. v0 ) ;
1371
+ resource_rect. uv1 = Point2D :: new ( image. u1 , image. v1 ) ;
1450
1372
}
1451
1373
}
1374
+ }
1375
+
1376
+ fn release_external_textures ( & mut self ) {
1377
+ if !self . external_images . is_empty ( ) {
1378
+ let handler = self . external_image_handler
1379
+ . as_mut ( )
1380
+ . expect ( "Found external image, but no handler set!" ) ;
1381
+
1382
+ for ( external_id, _) in self . external_images . drain ( ) {
1383
+ handler. release ( external_id) ;
1384
+ }
1385
+ }
1386
+ }
1387
+
1388
+ fn draw_tile_frame ( & mut self ,
1389
+ frame : & mut Frame ,
1390
+ framebuffer_size : & Size2D < u32 > ) {
1391
+ self . update_deferred_resolves ( frame) ;
1452
1392
1453
1393
// Some tests use a restricted viewport smaller than the main screen size.
1454
1394
// Ensure we clear the framebuffer in these tests.
@@ -1560,6 +1500,8 @@ impl Renderer {
1560
1500
max_prim_items,
1561
1501
& projection) ;
1562
1502
}
1503
+
1504
+ self . release_external_textures ( ) ;
1563
1505
}
1564
1506
1565
1507
pub fn debug_renderer < ' a > ( & ' a mut self ) -> & ' a mut DebugRenderer {
@@ -1575,9 +1517,10 @@ impl Renderer {
1575
1517
}
1576
1518
}
1577
1519
1578
- pub enum ExternalImageData {
1579
- Buffer ( * const u8 , usize ) ,
1580
- Native ( u32 ) , // Is a gl::GLuint texture handle
1520
+ pub enum ExternalImageSource {
1521
+ // TODO(gw): Work out the API for raw buffers.
1522
+ //RawData(*const u8, usize),
1523
+ NativeTexture ( u32 ) , // Is a gl::GLuint texture handle
1581
1524
}
1582
1525
1583
1526
/// The data that an external client should provide about
@@ -1590,12 +1533,11 @@ pub enum ExternalImageData {
1590
1533
/// will know to re-upload the image data to the GPU.
1591
1534
/// Note that the UV coords are supplied in texel-space!
1592
1535
pub struct ExternalImage {
1593
- pub timestamp : u64 ,
1594
1536
pub u0 : f32 ,
1595
1537
pub v0 : f32 ,
1596
1538
pub u1 : f32 ,
1597
1539
pub v1 : f32 ,
1598
- pub data : ExternalImageData ,
1540
+ pub source : ExternalImageSource ,
1599
1541
}
1600
1542
1601
1543
/// Interface that an application can implement
0 commit comments