[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-dev] Optimization to jpeg decoding
From: |
dolphinling |
Subject: |
[Gnash-dev] Optimization to jpeg decoding |
Date: |
Wed, 26 Nov 2008 20:32:03 -0500 |
User-agent: |
Thunderbird 2.0.0.18 (X11/20081105) |
Hitachi's animation The Hard Drive is the New Bling (Bling_Final.swf, available
from e.g. http://dagobah.biz/flash/Bling_Final.swf) plays slowly in gnash. It
contains a small number of very large jpegs (up to 3422x2516 px), and a profile
shows that there are over 8 million calls to JpegImageInput::getWidth, nearly 2%
of the total cpu time (in a debug build with video and audio output disabled).
All but 32 of those 8 million calls are from ImageInput::readSWFJpeg3. This
patch simply stores the result of getWidth within readSWFJpeg3.
This has not been run through make check--I don't have all the packages for
that. It has been tested on Bling_Final.swf, though, and works fine.
Jpeg decoding as a whole takes up just barely under 50% of the total time
(again, debug build run with -r0 so no output) so there may be other
improvements that could be made in the area. In fact,
boost::scoped_array<unsigned char>::operator[] is called nearly 25 million times
from readSWFJpeg3, for 5.67% of the run time, but I don't see a trivial way to
eliminate those calls like with getWidth.
Any comments or questions of course welcome.
--
dolphinling
<http://dolphinling.net/>
=== modified file 'libbase/GnashImage.cpp'
--- libbase/GnashImage.cpp 2008-10-27 16:05:13 +0000
+++ libbase/GnashImage.cpp 2008-11-27 00:42:16 +0000
@@ -20,7 +20,7 @@
// Based on the public domain work of Thatcher Ulrich <address@hidden> 2002
#include <cstring>
-#include <memory> // for auto_ptr
+#include <memory> // for auto_ptr
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
@@ -140,7 +140,7 @@
assert(x < _width);
assert(y < _height);
- boost::uint8_t* data = scanline(y) + 4 * x;
+ boost::uint8_t* data = scanline(y) + 4 * x;
data[0] = r;
data[1] = g;
@@ -301,18 +301,23 @@
assert(j_in.get());
j_in->read();
+
+ // For large images, getWidth can be called millions of times, so cache it
+ // here. Cache getHeight for symmetry.
+ const size_t j_in_width = j_in->getWidth();
+ const size_t j_in_height = j_in->getHeight();
- im.reset(new ImageRGBA(j_in->getWidth(), j_in->getHeight()));
+ im.reset(new ImageRGBA(j_in_width, j_in_height));
boost::scoped_array<boost::uint8_t> line (
- new boost::uint8_t[3 * j_in->getWidth()]);
+ new boost::uint8_t[3 * j_in_width]);
- for (size_t y = 0; y < j_in->getHeight(); y++)
+ for (size_t y = 0; y < j_in_height; y++)
{
j_in->readScanline(line.get());
- boost::uint8_t* data = im->scanline(y);
- for (size_t x = 0; x < j_in->getWidth(); x++)
+ boost::uint8_t* data = im->scanline(y);
+ for (size_t x = 0; x < j_in_width; x++)
{
data[4*x+0] = line[3*x+0];
data[4*x+1] = line[3*x+1];
- [Gnash-dev] Optimization to jpeg decoding,
dolphinling <=