diff options
author | dglazkov@google.com <dglazkov@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-16 02:13:24 +0000 |
---|---|---|
committer | dglazkov@google.com <dglazkov@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-16 02:13:24 +0000 |
commit | 5b0d9165de0e8c5652d731bb83e72a3d39d4d066 (patch) | |
tree | ad34ccba3e9999e27f126ee4bc7064dd0e354b40 /webkit/port/platform | |
parent | 381e299978874f38b6c9af4afdac1f9d05bb4a29 (diff) | |
download | chromium_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')
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; } |