1
1
using System ;
2
2
using System . Collections ;
3
- using System . Collections . Generic ;
4
3
using System . IO ;
5
4
using RSG ;
6
- using Unity . UIWidgets . async ;
7
5
using Unity . UIWidgets . foundation ;
8
6
using UnityEngine ;
9
7
@@ -18,34 +16,48 @@ public class FrameData {
18
16
public GifDecoder . GifFrame gifFrame ;
19
17
}
20
18
21
- readonly List < Promise < FrameData > > _frames ;
19
+ volatile byte [ ] _bytes ;
22
20
volatile int _width ;
23
21
volatile int _height ;
24
22
volatile int _frameCount ;
25
23
volatile int _repetitionCount ;
26
24
volatile bool _isDone ;
27
25
volatile int _frameIndex ;
28
26
volatile Texture2D _texture ;
29
- readonly UIWidgetsCoroutine _coroutine ;
27
+ volatile FrameData _frameData ;
28
+ volatile Image _image ;
29
+ IEnumerator _coroutine ;
30
30
31
31
public GifCodec ( byte [ ] bytes ) {
32
32
D . assert ( bytes != null ) ;
33
33
D . assert ( isGif ( bytes ) ) ;
34
34
35
- this . _frames = new List < Promise < FrameData > > ( ) ;
36
- this . _width = 0 ;
37
- this . _height = 0 ;
38
35
this . _frameCount = 0 ;
39
36
this . _repetitionCount = 0 ;
40
37
this . _isDone = false ;
41
38
this . _frameIndex = 0 ;
39
+ this . _bytes = bytes ;
40
+ this . _coroutine = this . _startDecoding ( ) ;
41
+ this . _init ( ) ;
42
+ this . _texture = new Texture2D ( this . _width , this . _height , TextureFormat . BGRA32 , false ) ;
43
+ this . _texture . hideFlags = HideFlags . HideAndDontSave ;
44
+ this . _image = new Image ( this . _texture ) ;
45
+ }
46
+
47
+ void _init ( ) {
48
+ var bytesStream = new MemoryStream ( this . _bytes ) ;
42
49
43
- this . _coroutine = Window . instance . startBackgroundCoroutine (
44
- this . _startDecoding ( bytes , Window . instance ) ) ;
50
+ var gifDecoder = new GifDecoder ( ) ;
51
+ if ( gifDecoder . read ( bytesStream ) != GifDecoder . STATUS_OK ) {
52
+ throw new Exception ( "Failed to decode gif." ) ;
53
+ }
54
+
55
+ this . _width = gifDecoder . frameWidth ;
56
+ this . _height = gifDecoder . frameHeight ;
45
57
}
46
58
47
- IEnumerator _startDecoding ( byte [ ] bytes , Window window ) {
48
- var bytesStream = new MemoryStream ( bytes ) ;
59
+ IEnumerator _startDecoding ( ) {
60
+ var bytesStream = new MemoryStream ( this . _bytes ) ;
49
61
50
62
var gifDecoder = new GifDecoder ( ) ;
51
63
if ( gifDecoder . read ( bytesStream ) != GifDecoder . STATUS_OK ) {
@@ -57,8 +69,6 @@ IEnumerator _startDecoding(byte[] bytes, Window window) {
57
69
58
70
int i = 0 ;
59
71
while ( true ) {
60
- yield return null ;
61
-
62
72
if ( gifDecoder . nextFrame ( ) != GifDecoder . STATUS_OK ) {
63
73
throw new Exception ( "Failed to decode gif." ) ;
64
74
}
@@ -68,25 +78,14 @@ IEnumerator _startDecoding(byte[] bytes, Window window) {
68
78
}
69
79
70
80
var frameData = new FrameData {
71
- gifFrame = gifDecoder . currentFrame ,
81
+ gifFrame = gifDecoder . currentFrame
72
82
} ;
73
83
74
- Promise < FrameData > frame ;
75
-
76
- lock ( this . _frames ) {
77
- if ( i < this . _frames . Count ) {
78
- }
79
- else {
80
- D . assert ( this . _frames . Count == i ) ;
81
- this . _frames . Add ( new Promise < FrameData > ( ) ) ;
82
- }
83
-
84
- frame = this . _frames [ i ] ;
85
- }
86
-
87
- window . runInMain ( ( ) => { frame . Resolve ( frameData ) ; } ) ;
84
+ this . _frameData = frameData ;
88
85
89
86
i ++ ;
87
+
88
+ yield return null ;
90
89
}
91
90
92
91
D . assert ( gifDecoder . frameCount == i ) ;
@@ -107,54 +106,28 @@ public int repetitionCount {
107
106
void _nextFrame ( ) {
108
107
this . _frameIndex ++ ;
109
108
109
+ this . _coroutine . MoveNext ( ) ;
110
+
110
111
if ( this . _isDone && this . _frameIndex >= this . _frameCount ) {
111
112
this . _frameIndex = 0 ;
113
+ this . _isDone = false ;
114
+ this . _coroutine = this . _startDecoding ( ) ;
115
+ this . _coroutine . MoveNext ( ) ;
112
116
}
113
117
}
114
118
115
119
public IPromise < FrameInfo > getNextFrame ( ) {
116
- Promise < FrameData > frame ;
117
-
118
- lock ( this . _frames ) {
119
- if ( this . _frameIndex == this . _frames . Count ) {
120
- this . _frames . Add ( new Promise < FrameData > ( ) ) ;
121
- }
122
- else {
123
- D . assert ( this . _frameIndex < this . _frames . Count ) ;
124
- }
125
-
126
- frame = this . _frames [ this . _frameIndex ] ;
127
- }
128
-
129
-
130
- return frame . Then ( frameData => {
131
- this . _nextFrame ( ) ;
132
-
133
- if ( this . _texture == null ) {
134
- this . _texture = new Texture2D ( this . _width , this . _height , TextureFormat . BGRA32 , false ) ;
135
- this . _texture . hideFlags = HideFlags . HideAndDontSave ;
136
- }
137
-
138
- var tex = this . _texture ;
139
- tex . LoadRawTextureData ( frameData . gifFrame . bytes ) ;
140
- tex . Apply ( ) ;
141
-
142
- if ( frameData . frameInfo != null ) {
143
- return frameData . frameInfo ;
144
- }
145
-
146
- frameData . frameInfo = new FrameInfo {
147
- image = new Image ( tex ) ,
148
- duration = TimeSpan . FromMilliseconds ( frameData . gifFrame . delay )
149
- } ;
150
- // frameData.gifFrame = null; // dispose gifFrame
151
-
152
- return frameData . frameInfo ;
153
- } ) ;
120
+ this . _nextFrame ( ) ;
121
+ this . _texture . LoadRawTextureData ( this . _frameData . gifFrame . bytes ) ;
122
+ this . _texture . Apply ( ) ;
123
+ this . _frameData . frameInfo = new FrameInfo ( ) {
124
+ image = this . _image ,
125
+ duration = TimeSpan . FromMilliseconds ( this . _frameData . gifFrame . delay )
126
+ } ;
127
+ return Promise < FrameInfo > . Resolved ( this . _frameData . frameInfo ) ;
154
128
}
155
129
156
130
public void Dispose ( ) {
157
- this . _coroutine . stop ( ) ;
158
131
}
159
132
}
160
133
}
0 commit comments