summaryrefslogtreecommitdiffstats
path: root/webkit/port/platform
diff options
context:
space:
mode:
authordglazkov@google.com <dglazkov@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-16 02:13:24 +0000
committerdglazkov@google.com <dglazkov@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-12-16 02:13:24 +0000
commit5b0d9165de0e8c5652d731bb83e72a3d39d4d066 (patch)
treead34ccba3e9999e27f126ee4bc7064dd0e354b40 /webkit/port/platform
parent381e299978874f38b6c9af4afdac1f9d05bb4a29 (diff)
downloadchromium_src-5b0d9165de0e8c5652d731bb83e72a3d39d4d066.zip
chromium_src-5b0d9165de0e8c5652d731bb83e72a3d39d4d066.tar.gz
chromium_src-5b0d9165de0e8c5652d731bb83e72a3d39d4d066.tar.bz2
WebKit Merge 39143:39309, Part 8 (port side)
Review URL: http://codereview.chromium.org/14140 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@7040 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port/platform')
-rw-r--r--webkit/port/platform/graphics/skia/BitmapImageSingleFrameSkia.h2
-rw-r--r--webkit/port/platform/graphics/skia/ImageSourceSkia.cpp20
-rw-r--r--webkit/port/platform/image-decoders/ImageDecoder.h16
-rw-r--r--webkit/port/platform/image-decoders/gif/GIFImageDecoder.cpp50
-rw-r--r--webkit/port/platform/image-decoders/gif/GIFImageDecoder.h2
-rw-r--r--webkit/port/platform/image-decoders/gif/GIFImageReader.h4
6 files changed, 85 insertions, 9 deletions
diff --git a/webkit/port/platform/graphics/skia/BitmapImageSingleFrameSkia.h b/webkit/port/platform/graphics/skia/BitmapImageSingleFrameSkia.h
index 2ec3fbd..74ac230 100644
--- a/webkit/port/platform/graphics/skia/BitmapImageSingleFrameSkia.h
+++ b/webkit/port/platform/graphics/skia/BitmapImageSingleFrameSkia.h
@@ -33,7 +33,7 @@ public:
}
// Do nothing, as we only have the one representation of data (decoded).
- virtual void destroyDecodedData(bool, bool preserveNearbyFrames = false) { }
+ virtual void destroyDecodedData(bool destroyAll = true) { }
virtual unsigned decodedSize() const
{
diff --git a/webkit/port/platform/graphics/skia/ImageSourceSkia.cpp b/webkit/port/platform/graphics/skia/ImageSourceSkia.cpp
index 95a335d..af5bb82 100644
--- a/webkit/port/platform/graphics/skia/ImageSourceSkia.cpp
+++ b/webkit/port/platform/graphics/skia/ImageSourceSkia.cpp
@@ -92,13 +92,19 @@ ImageSource::ImageSource()
ImageSource::~ImageSource()
{
- clear();
+ clear(true);
}
-void ImageSource::clear()
+void ImageSource::clear(bool destroyAll, size_t clearBeforeFrame)
{
- delete m_decoder;
- m_decoder = 0;
+ if (destroyAll) {
+ delete m_decoder;
+ m_decoder = 0;
+ return;
+ }
+
+ if (m_decoder)
+ m_decoder->clearFrameBufferCache(clearBeforeFrame);
}
bool ImageSource::initialized() const
@@ -229,4 +235,10 @@ void ImageSourceSkia::setData(SharedBuffer* data,
ImageSource::setData(data, allDataReceived);
}
+String ImageSource::filenameExtension() const
+{
+ // TODO(pkasting): Implement me!
+ return String();
+}
+
}
diff --git a/webkit/port/platform/image-decoders/ImageDecoder.h b/webkit/port/platform/image-decoders/ImageDecoder.h
index c4b6e20..f13c055 100644
--- a/webkit/port/platform/image-decoders/ImageDecoder.h
+++ b/webkit/port/platform/image-decoders/ImageDecoder.h
@@ -119,6 +119,14 @@ public:
return *this;
}
+ void clear() {
+ m_bitmapRef = RefCountedNativeImageSkia::create();
+ m_rect = IntRect();
+ m_status = FrameEmpty;
+ m_duration = 0;
+ m_disposalMethod = DisposeNotSpecified;
+ }
+
// This function creates a new copy of the image data in |other|, so the
// two images can be modified independently.
void copyBitmapData(const RGBA32Buffer& other) {
@@ -257,6 +265,14 @@ public:
bool failed() const { return m_failed; }
void setFailed() { m_failed = true; }
+ // Wipe out frames in the frame buffer cache before |clearBeforeFrame|,
+ // assuming this can be done without breaking decoding. Different decoders
+ // place different restrictions on what frames are safe to destroy, so this
+ // is left to them to implement.
+ // For convenience's sake, we provide a default (empty) implementation,
+ // since in practice only GIFs will ever use this.
+ virtual void clearFrameBufferCache(size_t clearBeforeFrame) { }
+
protected:
// Called by the image decoders to set their decoded size, this also check
// the size for validity. It will return true if the size was set, or false
diff --git a/webkit/port/platform/image-decoders/gif/GIFImageDecoder.cpp b/webkit/port/platform/image-decoders/gif/GIFImageDecoder.cpp
index 678e080..6bc4133 100644
--- a/webkit/port/platform/image-decoders/gif/GIFImageDecoder.cpp
+++ b/webkit/port/platform/image-decoders/gif/GIFImageDecoder.cpp
@@ -157,9 +157,18 @@ int GIFImageDecoder::repetitionCount() const
// packets sent back by the webserver) not always. Our caller is
// responsible for waiting until image decoding has finished to ask this if
// it needs an authoritative answer. In the meantime, we should default to
- // "loop once", both in the reader and here.
- if (m_reader)
- m_repetitionCount = m_reader->repetitionCount();
+ // "loop once".
+ if (m_reader) {
+ // Added wrinkle: ImageSource::clear() may destroy the reader, making
+ // the result from the reader _less_ authoritative on future calls. To
+ // detect this, the reader returns cLoopCountNotSeen (-2) instead of
+ // cAnimationLoopOnce (-1) when its current incarnation hasn't actually
+ // seen a loop count yet; in this case we return our previously-cached
+ // value.
+ const int repetitionCount = m_reader->repetitionCount();
+ if (repetitionCount != cLoopCountNotSeen)
+ m_repetitionCount = repetitionCount;
+ }
return m_repetitionCount;
}
@@ -175,6 +184,40 @@ RGBA32Buffer* GIFImageDecoder::frameBufferAtIndex(size_t index)
return &frame;
}
+void GIFImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame)
+{
+ // In some cases, like if the decoder was destroyed while animating, we
+ // can be asked to clear more frames than we currently have.
+ if (m_frameBufferCache.isEmpty())
+ return; // Nothing to do.
+ // The "-1" here is tricky. It does not mean that |clearBeforeFrame| is the
+ // last frame we wish to preserve, but rather that we never want to clear
+ // the very last frame in the cache: it's empty (so clearing it is
+ // pointless), it's partial (so we don't want to clear it anyway), or the
+ // cache could be enlarged with a future setData() call and it could be
+ // needed to construct the next frame (see comments below). Callers can
+ // always use ImageSource::clear(true, ...) to completely free the memory in
+ // this case.
+ clearBeforeFrame = std::min(clearBeforeFrame, m_frameBufferCache.size() - 1);
+ const Vector<RGBA32Buffer>::iterator end(m_frameBufferCache.begin() + clearBeforeFrame);
+ for (Vector<RGBA32Buffer>::iterator i(m_frameBufferCache.begin()); i != end; ++i) {
+ if (i->status() == RGBA32Buffer::FrameEmpty)
+ continue; // Nothing to do.
+
+ // The layout of frames is:
+ // [empty frames][complete frames][partial frame][empty frames]
+ // ...where each of these groups may be empty. We should not clear a
+ // partial frame since that's what's being decoded right now, and we
+ // also should not clear the last complete frame, since it may be needed
+ // when constructing the next frame. Note that "i + 1" is safe since
+ // i < end < m_frameBufferCache.end().
+ if ((i->status() == RGBA32Buffer::FramePartial) || ((i + 1)->status() != RGBA32Buffer::FrameComplete))
+ break;
+
+ i->clear();
+ }
+}
+
// Feed data to the GIF reader.
void GIFImageDecoder::decode(GIFQuery query, unsigned haltAtFrame) const
{
@@ -232,6 +275,7 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex)
// first frame specifies this method, it will get treated like
// DisposeOverwriteBgcolor below and reset to a completely empty image.)
const RGBA32Buffer* prevBuffer = &m_frameBufferCache[--frameIndex];
+ ASSERT(prevBuffer->status() == RGBA32Buffer::FrameComplete);
RGBA32Buffer::FrameDisposalMethod prevMethod =
prevBuffer->disposalMethod();
while ((frameIndex > 0) &&
diff --git a/webkit/port/platform/image-decoders/gif/GIFImageDecoder.h b/webkit/port/platform/image-decoders/gif/GIFImageDecoder.h
index a93f7c1..a8b16df 100644
--- a/webkit/port/platform/image-decoders/gif/GIFImageDecoder.h
+++ b/webkit/port/platform/image-decoders/gif/GIFImageDecoder.h
@@ -54,6 +54,8 @@ public:
virtual RGBA32Buffer* frameBufferAtIndex(size_t index);
+ virtual void clearFrameBufferCache(size_t clearBeforeFrame);
+
virtual unsigned frameDurationAtIndex(size_t index) { return 0; }
enum GIFQuery { GIFFullQuery, GIFSizeQuery, GIFFrameCountQuery };
diff --git a/webkit/port/platform/image-decoders/gif/GIFImageReader.h b/webkit/port/platform/image-decoders/gif/GIFImageReader.h
index c05c80b..09d15ea 100644
--- a/webkit/port/platform/image-decoders/gif/GIFImageReader.h
+++ b/webkit/port/platform/image-decoders/gif/GIFImageReader.h
@@ -47,6 +47,8 @@
#define MAX_COLORS 256
#define MAX_HOLD_SIZE 256
+const int cLoopCountNotSeen = -2;
+
/* gif2.h
The interface for the GIF87/89a decoder.
*/
@@ -187,7 +189,7 @@ struct GIFImageReader {
screen_bgcolor = version = 0;
screen_width = screen_height = 0;
global_colormap_size = images_decoded = images_count = 0;
- loop_count = -1;
+ loop_count = cLoopCountNotSeen;
count = 0;
}