@@ -2,150 +2,86 @@ use crate::ffi::{ExternalTexture, ExternalTextureFrame, TextureId};
2
2
use crate :: FlutterEngine ;
3
3
#[ cfg( feature ="image" ) ]
4
4
use image:: RgbaImage ;
5
- #[ cfg( feature ="image" ) ]
6
- use parking_lot:: Mutex ;
7
5
use parking_lot:: RwLock ;
8
6
use std:: collections:: HashMap ;
9
- use std:: sync:: Arc ;
10
-
11
- pub struct Texture {
12
- texture_id : TextureId ,
13
- registry : TextureRegistry ,
14
- }
15
-
16
- impl Texture {
17
- pub fn id ( & self ) ->TextureId {
18
- self . texture_id
19
- }
20
-
21
- pub fn mark_frame_available ( & self ) {
22
- self . registry . mark_frame_available ( self . texture_id )
23
- }
24
- }
25
-
26
- impl Drop for Texture {
27
- fn drop ( & mut self ) {
28
- log:: trace!( "dropping Texture" ) ;
29
- self . registry . drop_texture ( self . texture_id ) ;
30
- }
31
- }
7
+ use std:: sync:: { Arc , Barrier } ;
8
+ use std:: sync:: atomic:: { AtomicU32 , Ordering } ;
32
9
33
10
#[ derive( Clone , Default ) ]
34
11
pub struct TextureRegistry {
35
- textures : Arc < RwLock < HashMap < TextureId , FlutterTexture > > > ,
12
+ textures : Arc < RwLock < HashMap < TextureId , u32 > > > ,
36
13
}
37
14
38
15
impl TextureRegistry {
39
- pub fn new ( ) -> Self {
40
- Default :: default ( )
16
+ pub fn register ( & self , texture_id : TextureId , glid : u32 ) {
17
+ self . textures . write ( ) . insert ( texture_id , glid ) ;
41
18
}
42
19
43
- pub fn create_texture ( & self , engine : & FlutterEngine , gl : Box < dyn GlTexture > ) ->Texture {
44
- let texture =ExternalTexture :: new ( engine. engine_ptr ( ) ) ;
45
- let texture_id = texture. id ( ) ;
46
- let texture =FlutterTexture :: new ( texture, gl) ;
47
- self . textures . write ( ) . insert ( texture_id, texture) ;
48
-
49
- let textures =self . textures . clone ( ) ;
50
- engine. run_on_platform_thread ( move |_engine|{
51
- if let Some ( texture) = textures. read ( ) . get ( & texture_id) {
52
- texture. register ( ) ;
53
- }
54
- } ) ;
55
-
56
- Texture {
57
- texture_id,
58
- registry : self . clone ( ) ,
59
- }
60
- }
61
-
62
- pub ( crate ) fn get_texture_frame (
63
- & self ,
64
- texture_id : TextureId ,
65
- _size : ( usize , usize ) ,
66
- ) ->Option < ExternalTextureFrame > {
67
- let mut textures =self . textures . write ( ) ;
68
- textures
69
- . get_mut ( & texture_id)
70
- . map ( |texture| texture. get_texture_frame ( ) )
71
- }
72
-
73
- fn mark_frame_available ( & self , texture_id : TextureId ) {
20
+ pub fn get_texture_frame ( & self , texture_id : TextureId , _size : ( usize , usize ) ) ->Option < ExternalTextureFrame > {
74
21
let textures =self . textures . read ( ) ;
75
- if let Some ( texture) = textures. get ( & texture_id) {
76
- texture. mark_frame_available ( ) ;
22
+ if let Some ( glid) = textures. get ( & texture_id) {
23
+ log:: trace!( "returning external texture frame with glid {}" , glid) ;
24
+ return Some ( ExternalTextureFrame :: new ( gl:: TEXTURE_2D , * glid, gl:: RGBA8 , ||{ } ) )
77
25
}
78
- }
79
-
80
- fn drop_texture ( & self , texture_id : TextureId ) {
81
- let mut textures =self . textures . write ( ) ;
82
- textures. remove ( & texture_id) ;
26
+ None
83
27
}
84
28
}
85
29
86
- struct FlutterTexture {
30
+ pub struct Texture {
31
+ engine : FlutterEngine ,
87
32
texture : ExternalTexture ,
88
- gl : Box < dyn GlTexture > ,
89
- }
90
-
91
- impl FlutterTexture {
92
- fn new ( texture : ExternalTexture , gl : Box < dyn GlTexture > ) ->Self {
93
- Self { texture, gl}
94
- }
95
-
96
- fn register ( & self ) {
97
- self . texture . register ( ) ;
98
- }
99
-
100
- fn mark_frame_available ( & self ) {
101
- self . texture . mark_frame_available ( ) ;
102
- }
103
-
104
- fn get_texture_frame ( & mut self ) ->ExternalTextureFrame {
105
- self . gl . get_texture_frame ( )
106
- }
107
- }
108
-
109
- impl Drop for FlutterTexture {
110
- fn drop ( & mut self ) {
111
- log:: trace!( "dropping FlutterTexture" ) ;
112
- self . texture . unregister ( ) ;
113
- }
114
- }
115
-
116
- pub trait GlTexture : Send +Sync {
117
- fn get_texture_frame ( & mut self ) ->ExternalTextureFrame ;
33
+ glid : Arc < AtomicU32 > ,
118
34
}
119
35
120
- #[ cfg( feature ="image" ) ]
121
- #[ derive( Clone ) ]
122
- pub struct RgbaTexture {
123
- data : Arc < Mutex < Option < RgbaImage > > > ,
124
- id : u32 ,
125
- }
36
+ impl Texture {
37
+ pub ( crate ) fn new ( engine : FlutterEngine ) ->Self {
38
+ let texture =ExternalTexture :: new ( engine. engine_ptr ( ) ) ;
39
+ let texture2 = texture. clone ( ) ;
40
+ let glid =Arc :: new ( AtomicU32 :: new ( 0 ) ) ;
41
+ let glid2 = glid. clone ( ) ;
42
+ let barrier =Arc :: new ( Barrier :: new ( 2 ) ) ;
43
+ let barrier2 = barrier. clone ( ) ;
44
+ engine. run_on_render_thread ( move |engine|{
45
+ let mut id: u32 =0 ;
46
+ unsafe {
47
+ gl:: GenTextures ( 1 , & mut idas * mut _ ) ;
48
+ }
49
+ glid2. store ( id, Ordering :: SeqCst ) ;
50
+ engine. inner . texture_registry . register ( texture2. id ( ) , id) ;
51
+ barrier2. wait ( ) ;
126
52
127
- #[ cfg( feature ="image" ) ]
128
- impl RgbaTexture {
129
- pub fn new ( img : RgbaImage ) ->Self {
53
+ engine. run_on_platform_thread ( move |_engine|{
54
+ texture2. register ( ) ;
55
+ } ) ;
56
+ } ) ;
57
+ barrier. wait ( ) ;
130
58
Self {
131
- data : Arc :: new ( Mutex :: new ( Some ( img) ) ) ,
132
- id : 0 ,
59
+ engine, texture, glid
133
60
}
134
61
}
135
62
136
- pub fn post_frame_rgba ( & mut self , img : RgbaImage ) {
137
- * self . data . lock ( ) =Some ( img) ;
63
+ pub fn id ( & self ) ->TextureId {
64
+ self . texture . id ( )
65
+ }
66
+
67
+ pub fn post_frame < F : FnOnce ( ) +Send +' static > ( & self , render : F ) {
68
+ let glid =self . glid . load ( Ordering :: SeqCst ) ;
69
+ let texture =self . texture . clone ( ) ;
70
+ self . engine . run_on_render_thread ( move |engine|{
71
+ log:: trace!( "bound texture with glid {}" , glid) ;
72
+ unsafe { gl:: BindTexture ( gl:: TEXTURE_2D , glid) } ;
73
+ render ( ) ;
74
+ engine. run_on_platform_thread ( move |_engine|{
75
+ texture. mark_frame_available ( ) ;
76
+ } ) ;
77
+ } ) ;
138
78
}
139
- }
140
79
141
- #[ cfg( feature ="image" ) ]
142
- impl GlTexture for RgbaTexture {
143
- fn get_texture_frame ( & mut self ) ->ExternalTextureFrame {
144
- if let Some ( img) =self . data . lock ( ) . take ( ) {
80
+ #[ cfg( feature ="image" ) ]
81
+ pub fn post_frame_rgba ( & self , img : RgbaImage ) {
82
+ self . post_frame ( move ||{
145
83
let ( width, height) = img. dimensions ( ) ;
146
84
unsafe {
147
- gl:: GenTextures ( 1 , & mut self . id as * mut _ ) ;
148
- gl:: BindTexture ( gl:: TEXTURE_2D , self . id ) ;
149
85
gl:: PixelStorei ( gl:: UNPACK_ALIGNMENT , 1 ) ;
150
86
gl:: TexParameteri ( gl:: TEXTURE_2D , gl:: TEXTURE_MIN_FILTER , gl:: LINEAR as _ ) ;
151
87
gl:: TexParameteri ( gl:: TEXTURE_2D , gl:: TEXTURE_MAG_FILTER , gl:: LINEAR as _ ) ;
@@ -160,18 +96,23 @@ impl GlTexture for RgbaTexture {
160
96
gl:: UNSIGNED_BYTE , // data type of the pixel data
161
97
( & img) . as_ptr ( ) as * const _ , // pixel data
162
98
) ;
163
- log:: debug!( "created gl texture with id {}" , self . id) ;
164
99
}
165
- }
166
- ExternalTextureFrame :: new ( gl:: TEXTURE_2D , self . id , gl:: RGBA8 , ||{ } )
100
+ } ) ;
167
101
}
168
102
}
169
103
170
- #[ cfg( feature ="image" ) ]
171
- impl Drop for RgbaTexture {
104
+ impl Drop for Texture {
172
105
fn drop ( & mut self ) {
173
- unsafe {
174
- gl:: DeleteTextures ( 1 , & self . id as * const _ ) ;
175
- }
106
+ let id =self . glid . load ( Ordering :: SeqCst ) ;
107
+ log:: trace!( "dropping Texture with id {}" , id) ;
108
+ let texture =self . texture . clone ( ) ;
109
+ self . engine . run_on_platform_thread ( move |_engine|{
110
+ texture. unregister ( ) ;
111
+ } ) ;
112
+ self . engine . run_on_render_thread ( move |_engine|{
113
+ unsafe {
114
+ gl:: DeleteTextures ( 1 , & idas * const _ ) ;
115
+ }
116
+ } ) ;
176
117
}
177
118
}