@@ -2,6 +2,8 @@ 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 ;
5
7
use parking_lot:: RwLock ;
6
8
use std:: collections:: HashMap ;
7
9
use std:: sync:: Arc ;
@@ -62,9 +64,9 @@ impl TextureRegistry {
62
64
texture_id : TextureId ,
63
65
_size : ( usize , usize ) ,
64
66
) ->Option < ExternalTextureFrame > {
65
- let textures =self . textures . read ( ) ;
67
+ let mut textures =self . textures . write ( ) ;
66
68
textures
67
- . get ( & texture_id)
69
+ . get_mut ( & texture_id)
68
70
. map ( |texture| texture. get_texture_frame ( ) )
69
71
}
70
72
@@ -99,7 +101,7 @@ impl FlutterTexture {
99
101
self . texture . mark_frame_available ( ) ;
100
102
}
101
103
102
- fn get_texture_frame ( & self ) ->ExternalTextureFrame {
104
+ fn get_texture_frame ( & mut self ) ->ExternalTextureFrame {
103
105
self . gl . get_texture_frame ( )
104
106
}
105
107
}
@@ -112,51 +114,64 @@ impl Drop for FlutterTexture {
112
114
}
113
115
114
116
pub trait GlTexture : Send +Sync {
115
- fn get_texture_frame ( & self ) ->ExternalTextureFrame ;
117
+ fn get_texture_frame ( & mut self ) ->ExternalTextureFrame ;
116
118
}
117
119
118
120
#[ cfg( feature ="image" ) ]
119
121
#[ derive( Clone ) ]
120
- pub struct RgbaTexture ( Arc < RwLock < RgbaImage > > ) ;
122
+ pub struct RgbaTexture {
123
+ data : Arc < Mutex < Option < RgbaImage > > > ,
124
+ id : u32 ,
125
+ }
121
126
122
127
#[ cfg( feature ="image" ) ]
123
128
impl RgbaTexture {
124
129
pub fn new ( img : RgbaImage ) ->Self {
125
- Self ( Arc :: new ( RwLock :: new ( img) ) )
130
+ Self {
131
+ data : Arc :: new ( Mutex :: new ( Some ( img) ) ) ,
132
+ id : 0 ,
133
+ }
126
134
}
127
135
128
136
pub fn post_frame_rgba ( & mut self , img : RgbaImage ) {
129
- * self . 0 . write ( ) = img;
137
+ * self . data . lock ( ) =Some ( img) ;
130
138
}
131
139
}
132
140
133
141
#[ cfg( feature ="image" ) ]
134
142
impl GlTexture for RgbaTexture {
135
- fn get_texture_frame ( & self ) ->ExternalTextureFrame {
136
- let mut id: u32 =0 ;
137
- let img =self . 0 . read ( ) ;
138
- let ( width, height) = img. dimensions ( ) ;
143
+ fn get_texture_frame ( & mut self ) ->ExternalTextureFrame {
144
+ if let Some ( img) =self . data . lock ( ) . take ( ) {
145
+ let ( width, height) = img. dimensions ( ) ;
146
+ unsafe {
147
+ gl:: GenTextures ( 1 , & mut self . id as * mut _ ) ;
148
+ gl:: BindTexture ( gl:: TEXTURE_2D , self . id ) ;
149
+ gl:: PixelStorei ( gl:: UNPACK_ALIGNMENT , 1 ) ;
150
+ gl:: TexParameteri ( gl:: TEXTURE_2D , gl:: TEXTURE_MIN_FILTER , gl:: LINEAR as _ ) ;
151
+ gl:: TexParameteri ( gl:: TEXTURE_2D , gl:: TEXTURE_MAG_FILTER , gl:: LINEAR as _ ) ;
152
+ gl:: TexImage2D (
153
+ gl:: TEXTURE_2D ,
154
+ 0 , // mipmap level
155
+ gl:: RGBA as _ , // internal format of the texture
156
+ widthas _ ,
157
+ heightas _ ,
158
+ 0 , // border, must be 0
159
+ gl:: RGBA , // format of the pixel data
160
+ gl:: UNSIGNED_BYTE , // data type of the pixel data
161
+ ( & img) . as_ptr ( ) as * const _ , // pixel data
162
+ ) ;
163
+ log:: debug!( "created gl texture with id {}" , self . id) ;
164
+ }
165
+ }
166
+ ExternalTextureFrame :: new ( gl:: TEXTURE_2D , self . id , gl:: RGBA8 , ||{ } )
167
+ }
168
+ }
169
+
170
+ #[ cfg( feature ="image" ) ]
171
+ impl Drop for RgbaTexture {
172
+ fn drop ( & mut self ) {
139
173
unsafe {
140
- gl:: GenTextures ( 1 , & mut idas * mut _ ) ;
141
- gl:: BindTexture ( gl:: TEXTURE_2D , id) ;
142
- gl:: PixelStorei ( gl:: UNPACK_ALIGNMENT , 1 ) ;
143
- gl:: TexParameteri ( gl:: TEXTURE_2D , gl:: TEXTURE_MIN_FILTER , gl:: LINEAR as _ ) ;
144
- gl:: TexParameteri ( gl:: TEXTURE_2D , gl:: TEXTURE_MAG_FILTER , gl:: LINEAR as _ ) ;
145
- gl:: TexImage2D (
146
- gl:: TEXTURE_2D ,
147
- 0 , // mipmap level
148
- gl:: RGBA as _ , // internal format of the texture
149
- widthas _ ,
150
- heightas _ ,
151
- 0 , // border, must be 0
152
- gl:: RGBA , // format of the pixel data
153
- gl:: UNSIGNED_BYTE , // data type of the pixel data
154
- ( & img) . as_ptr ( ) as * const _ , // pixel data
155
- ) ;
174
+ gl:: DeleteTextures ( 1 , & self . id as * const _ ) ;
156
175
}
157
- log:: debug!( "created gl texture with id {}" , id) ;
158
- ExternalTextureFrame :: new ( gl:: TEXTURE_2D , id, gl:: RGBA8 , move ||unsafe {
159
- gl:: DeleteTextures ( 1 , & idas * const _ ) ;
160
- } )
161
176
}
162
177
}