Ticket #8706: DXAOptimisations3

File DXAOptimisations3, 9.7 KB (added by SF/robinwatts, 14 years ago)

Third version of the DXA changes

Line 
1Index: graphics/dxa_player.cpp
2===================================================================
3--- graphics/dxa_player.cpp (revision 27747)
4+++ graphics/dxa_player.cpp (working copy)
5@@ -42,6 +42,12 @@
6 _scaledBuffer = 0;
7 _drawBuffer = 0;
8
9+ _inBuffer = 0;
10+ _inBufferSize = 0;
11+
12+ _decompBuffer = 0;
13+ _decompBufferSize = 0;
14+
15 _width = 0;
16 _height = 0;
17
18@@ -53,6 +59,12 @@
19 _frameTicks = 0;
20
21 _scaleMode = S_NONE;
22+
23+ _d_stream.zalloc = (alloc_func)0;
24+ _d_stream.zfree = (free_func)0;
25+ _d_stream.opaque = (voidpf)0;
26+
27+ _continuousCompression = false;
28 }
29
30 DXAPlayer::~DXAPlayer() {
31@@ -88,6 +100,8 @@
32
33 Common::File *file = new Common::File();
34 if (!file->open(filename)) {
35+fprintf(stderr, "file open failed: %s\n", filename);
36+fflush(stderr);
37 return 0;
38 }
39
40@@ -126,9 +140,13 @@
41 _curHeight = _height;
42 }
43
44+fprintf(stderr, "flags 0x0%x framesCount %d width %d height %d rate %d ticks %d\n", flags, _framesCount, _width, _height, _framesPerSec, _frameTicks);
45+fflush(stderr);
46+
47 debug(2, "flags 0x0%x framesCount %d width %d height %d rate %d ticks %d", flags, _framesCount, _width, _height, _framesPerSec, _frameTicks);
48
49 _frameSize = _width * _height;
50+ _decompBufferSize = _frameSize;
51 _frameBuffer1 = (uint8 *)malloc(_frameSize);
52 _frameBuffer2 = (uint8 *)malloc(_frameSize);
53 if (!_frameBuffer1 || !_frameBuffer2)
54@@ -143,6 +161,8 @@
55
56 _frameNum = 0;
57 _frameSkipped = 0;
58+fprintf(stderr, "init done\n");
59+fflush(stderr);
60
61 return true;
62 }
63@@ -157,6 +177,11 @@
64 free(_frameBuffer1);
65 free(_frameBuffer2);
66 free(_scaledBuffer);
67+ free(_inBuffer);
68+ free(_decompBuffer);
69+ if (_continuousCompression) {
70+ inflateEnd(&_d_stream);
71+ }
72 }
73
74 void DXAPlayer::copyFrameToBuffer(byte *dst, uint x, uint y, uint pitch) {
75@@ -175,23 +200,17 @@
76
77 void DXAPlayer::decodeZlib(byte *data, int size, int totalSize) {
78 #ifdef USE_ZLIB
79- byte *temp = (byte *)malloc(size);
80- if (temp) {
81- memcpy(temp, data, size);
82-
83- z_stream d_stream;
84- d_stream.zalloc = (alloc_func)0;
85- d_stream.zfree = (free_func)0;
86- d_stream.opaque = (voidpf)0;
87- d_stream.next_in = temp;
88- d_stream.avail_in = size;
89- d_stream.total_in = size;
90- d_stream.next_out = data;
91- d_stream.avail_out = totalSize;
92- inflateInit(&d_stream);
93- inflate(&d_stream, Z_FINISH);
94- inflateEnd(&d_stream);
95- free(temp);
96+ _d_stream.next_in = _inBuffer;
97+ _d_stream.avail_in = size;
98+ _d_stream.total_in = size;
99+ _d_stream.next_out = data;
100+ _d_stream.avail_out = totalSize;
101+ if (_continuousCompression) {
102+ inflate(&_d_stream, Z_SYNC_FLUSH);
103+ } else {
104+ inflateInit(&_d_stream);
105+ inflate(&_d_stream, Z_FINISH);
106+ inflateEnd(&_d_stream);
107 }
108 #endif
109 }
110@@ -199,20 +218,24 @@
111 #define BLOCKW 4
112 #define BLOCKH 4
113
114-void DXAPlayer::decode12(byte *data, int size, int totalSize) {
115+void DXAPlayer::decode12(int size) {
116 #ifdef USE_ZLIB
117+ if (_decompBuffer == NULL) {
118+ _decompBuffer = (byte *)malloc(_decompBufferSize);
119+ if (_decompBuffer == NULL)
120+ error("Error allocating decomp buffer (size %d)", _decompBufferSize);
121+ }
122 /* decompress the input data */
123- decodeZlib(data, size, totalSize);
124+ decodeZlib(_decompBuffer, size, _decompBufferSize);
125
126- byte *dat = data;
127- byte *frame2 = (byte *)malloc(totalSize);
128+ byte *dat = _decompBuffer;
129
130- memcpy(frame2, _frameBuffer1, totalSize);
131+ memcpy(_frameBuffer2, _frameBuffer1, _frameSize);
132
133 for (int by = 0; by < _height; by += BLOCKH) {
134 for (int bx = 0; bx < _width; bx += BLOCKW) {
135 byte type = *dat++;
136- byte *b2 = frame2 + bx + by * _width;
137+ byte *b2 = _frameBuffer1 + bx + by * _width;
138
139 switch (type) {
140 case 0:
141@@ -276,7 +299,7 @@
142 int my = mbyte & 0x07;
143 if (mbyte & 0x08)
144 my = -my;
145- byte *b1 = _frameBuffer1 + (bx+mx) + (by+my) * _width;
146+ byte *b1 = _frameBuffer2 + (bx+mx) + (by+my) * _width;
147 for (int yc = 0; yc < BLOCKH; yc++) {
148 memcpy(b2, b1, BLOCKW);
149 b1 += _width;
150@@ -291,30 +314,32 @@
151 }
152 }
153 }
154-
155- memcpy(data, frame2, totalSize);
156- free(frame2);
157 #endif
158 }
159
160-void DXAPlayer::decode13(byte *data, int size, int totalSize) {
161+void DXAPlayer::decode13(int size) {
162 #ifdef USE_ZLIB
163 uint8 *codeBuf, *dataBuf, *motBuf, *maskBuf;
164
165+ if (_decompBuffer == NULL) {
166+ _decompBuffer = (byte *)malloc(_decompBufferSize);
167+ if (_decompBuffer == NULL)
168+ error("Error allocating decomp buffer (size %d)", _decompBufferSize);
169+ }
170+
171 /* decompress the input data */
172- decodeZlib(data, size, totalSize);
173+ decodeZlib(_decompBuffer, size, _decompBufferSize);
174
175- uint8 *frame2 = (uint8*)malloc(totalSize);
176- memcpy(frame2, _frameBuffer1, totalSize);
177+ memcpy(_frameBuffer2, _frameBuffer1, _frameSize);
178
179 int codeSize = _width * _curHeight / 16;
180 int dataSize, motSize, maskSize;
181
182- dataSize = READ_BE_UINT32(&data[0]);
183- motSize = READ_BE_UINT32(&data[4]);
184- maskSize = READ_BE_UINT32(&data[8]);
185+ dataSize = READ_BE_UINT32(&_decompBuffer[0]);
186+ motSize = READ_BE_UINT32(&_decompBuffer[4]);
187+ maskSize = READ_BE_UINT32(&_decompBuffer[8]);
188
189- codeBuf = &data[12];
190+ codeBuf = &_decompBuffer[12];
191 dataBuf = &codeBuf[codeSize];
192 motBuf = &dataBuf[dataSize];
193 maskBuf = &motBuf[motSize];
194@@ -322,7 +347,7 @@
195 for (int by = 0; by < _curHeight; by += BLOCKH) {
196 for (int bx = 0; bx < _width; bx += BLOCKW) {
197 uint8 type = *codeBuf++;
198- uint8 *b2 = (uint8*)frame2 + bx + by * _width;
199+ uint8 *b2 = (uint8*)_frameBuffer1 + bx + by * _width;
200
201 switch (type) {
202 case 0:
203@@ -373,7 +398,7 @@
204 if (mbyte & 0x08)
205 my = -my;
206
207- uint8 *b1 = (uint8*)_frameBuffer1 + (bx+mx) + (by+my) * _width;
208+ uint8 *b1 = (uint8*)_frameBuffer2 + (bx+mx) + (by+my) * _width;
209 for (int yc = 0; yc < BLOCKH; yc++) {
210 memcpy(b2, b1, BLOCKW);
211 b1 += _width;
212@@ -389,7 +414,7 @@
213
214 for (int subBlock = 0; subBlock < 4; subBlock++) {
215 int sx = bx + subX[subBlock], sy = by + subY[subBlock];
216- b2 = (uint8*)frame2 + sx + sy * _width;
217+ b2 = (uint8*)_frameBuffer1 + sx + sy * _width;
218 switch (subMask & 0xC0) {
219 // 00: skip
220 case 0x00:
221@@ -417,7 +442,7 @@
222 if (mbyte & 0x08)
223 my = -my;
224
225- uint8 *b1 = (uint8*)_frameBuffer1 + (sx+mx) + (sy+my) * _width;
226+ uint8 *b1 = (uint8*)_frameBuffer2 + (sx+mx) + (sy+my) * _width;
227 for (int yc = 0; yc < BLOCKH / 2; yc++) {
228 memcpy(b2, b1, BLOCKW / 2);
229 b1 += _width;
230@@ -476,16 +501,48 @@
231 }
232 }
233 }
234-
235- memcpy(data, frame2, totalSize);
236- free(frame2);
237 #endif
238 }
239
240 void DXAPlayer::decodeNextFrame() {
241 uint32 tag;
242
243+ fprintf(stderr, "DNF\n");
244+ fflush(stderr);
245 tag = _fd->readUint32BE();
246+ fprintf(stderr, "DNF %x\n", tag);
247+ fflush(stderr);
248+ if (tag == MKID_BE('MAXD')) {
249+ // This tag specifies the maximum decompression buffer size
250+ // we will require (this should only occur once in a file,
251+ // at the start, and decreases our previous estimate, which
252+ // is _frameSize).
253+ uint32 size = _fd->readUint32BE();
254+
255+ fprintf(stderr, "MAXD %x\n", size);
256+ fflush(stderr);
257+
258+ // This should never happen, but cope in case
259+ if ((_decompBuffer != NULL) && (size > _decompBufferSize)) {
260+ free(_decompBuffer);
261+ _decompBuffer = NULL;
262+ }
263+ _decompBufferSize = size;
264+
265+ // Read the next tag
266+ tag = _fd->readUint32BE();
267+ }
268+ if (tag == MKID_BE('ZCNT')) {
269+ // This tag specifies that we are using continuous
270+ // compression - i.e. that the compression context is not
271+ // restarted between frames.
272+ _continuousCompression = true;
273+ fprintf(stderr, "ZCNT\n");
274+ fflush(stderr);
275+ inflateInit(&_d_stream);
276+ // Read the next tag
277+ tag = _fd->readUint32BE();
278+ }
279 if (tag == MKID_BE('CMAP')) {
280 byte rgb[768];
281
282@@ -498,25 +555,37 @@
283 byte type = _fd->readByte();
284 uint32 size = _fd->readUint32BE();
285
286- _fd->read(_frameBuffer2, size);
287+ if ((_inBuffer == NULL) || (_inBufferSize < size)) {
288+ free(_inBuffer);
289+ _inBuffer = (byte *)malloc(size);
290+ if (_inBuffer == NULL)
291+ error("Error allocating input buffer (size %d)", size);
292+ _inBufferSize = size;
293+ }
294
295+fprintf(stderr, "size=%d type=%d\n", size, type);
296+fflush(stderr);
297+
298+ _fd->read(_inBuffer, size);
299+
300 switch (type) {
301 case 2:
302+ decodeZlib(_frameBuffer1, size, _frameSize);
303+ break;
304 case 3:
305 decodeZlib(_frameBuffer2, size, _frameSize);
306 break;
307 case 12:
308- decode12(_frameBuffer2, size, _frameSize);
309+ decode12(size);
310 break;
311 case 13:
312- decode13(_frameBuffer2, size, _frameSize);
313+ decode13(size);
314 break;
315 default:
316 error("decodeFrame: Unknown compression type %d", type);
317 }
318- if (type == 2 || type == 4 || type == 12 || type == 13) {
319- memcpy(_frameBuffer1, _frameBuffer2, _frameSize);
320- } else {
321+
322+ if (type != 2 && type != 12 && type != 13) {
323 for (int j = 0; j < _curHeight; ++j) {
324 for (int i = 0; i < _width; ++i) {
325 const int offs = j * _width + i;
326Index: graphics/dxa_player.h
327===================================================================
328--- graphics/dxa_player.h (revision 27747)
329+++ graphics/dxa_player.h (working copy)
330@@ -29,6 +29,10 @@
331 #include "common/scummsys.h"
332 #include "common/file.h"
333
334+#ifdef USE_ZLIB
335+#include <zlib.h>
336+#endif
337+
338 namespace Common {
339 class File;
340 }
341@@ -47,6 +51,10 @@
342 byte *_frameBuffer2;
343 byte *_scaledBuffer;
344 byte *_drawBuffer;
345+ byte *_inBuffer;
346+ uint32 _inBufferSize;
347+ byte *_decompBuffer;
348+ uint32 _decompBufferSize;
349 uint16 _width;
350 uint16 _height, _curHeight;
351 uint16 _framesCount;
352@@ -56,6 +64,10 @@
353 uint16 _frameSkipped;
354 uint32 _frameTicks;
355 ScaleMode _scaleMode;
356+ bool _continuousCompression;
357+#ifdef USE_ZLIB
358+ z_stream _d_stream;
359+#endif
360
361 public:
362 DXAPlayer();
363@@ -121,10 +133,10 @@
364 void decodeNextFrame();
365
366 void decodeZlib(byte *data, int size, int totalSize);
367- void decode12(byte *data, int size, int totalSize);
368- void decode13(byte *data, int size, int totalSize);
369+ void decode12(int size);
370+ void decode13(int size);
371 };
372-
373+
374 } // End of namespace Graphics
375
376 #endif