GIF: Use SkTArray instead of std::vector
Speculative fix for a memory regression seen in Chromium. Chromium previously used a WTF::Vector, which has a growth factor of 1.5, as does SkTArray. Depending on the implementation of std::vector, this may slow the allocation of memory. Bug: 758946 Change-Id: I323390027467e32a6c66667c927fae0aba292446 Reviewed-on: https://skia-review.googlesource.com/40777 Reviewed-by: Ben Wagner <bungeman@google.com> Commit-Queue: Leon Scroggins <scroggo@google.com>
This commit is contained in:
parent
64dc4f6d4f
commit
e750391c34
14
third_party/gif/SkGifImageReader.cpp
vendored
14
third_party/gif/SkGifImageReader.cpp
vendored
@ -344,7 +344,7 @@ sk_sp<SkColorTable> SkGIFColorMap::buildTable(SkStreamBuffer* streamBuffer, SkCo
|
||||
}
|
||||
|
||||
sk_sp<SkColorTable> SkGifImageReader::getColorTable(SkColorType colorType, int index) {
|
||||
if (index < 0 || static_cast<size_t>(index) >= m_frames.size()) {
|
||||
if (index < 0 || index >= m_frames.count()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -382,8 +382,7 @@ bool SkGIFFrameContext::decode(SkStreamBuffer* streamBuffer, SkGifCodec* client,
|
||||
}
|
||||
|
||||
// Some bad GIFs have extra blocks beyond the last row, which we don't want to decode.
|
||||
while (static_cast<size_t>(m_currentLzwBlock) < m_lzwBlocks.size()
|
||||
&& m_lzwContext->hasRemainingRows()) {
|
||||
while (m_currentLzwBlock < m_lzwBlocks.count() && m_lzwContext->hasRemainingRows()) {
|
||||
const auto& block = m_lzwBlocks[m_currentLzwBlock];
|
||||
const size_t len = block.blockSize;
|
||||
|
||||
@ -430,7 +429,7 @@ SkCodec::Result SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery query)
|
||||
|
||||
// SkGIFSizeQuery and SkGIFFrameCountQuery are negative, so this is only meaningful when >= 0.
|
||||
const int lastFrameToParse = (int) query;
|
||||
if (lastFrameToParse >= 0 && (int) m_frames.size() > lastFrameToParse
|
||||
if (lastFrameToParse >= 0 && m_frames.count() > lastFrameToParse
|
||||
&& m_frames[lastFrameToParse]->isComplete()) {
|
||||
// We have already parsed this frame.
|
||||
return SkCodec::kSuccess;
|
||||
@ -823,7 +822,7 @@ SkCodec::Result SkGifImageReader::parse(SkGifImageReader::SkGIFParseQuery query)
|
||||
// decode all rows but we treat it as frame complete.
|
||||
m_frames.back()->setComplete();
|
||||
GETN(1, SkGIFImageStart);
|
||||
if (lastFrameToParse >= 0 && (int) m_frames.size() > lastFrameToParse) {
|
||||
if (lastFrameToParse >= 0 && m_frames.count() > lastFrameToParse) {
|
||||
m_streamBuffer.flush();
|
||||
return SkCodec::kSuccess;
|
||||
}
|
||||
@ -874,9 +873,8 @@ bool SkGifImageReader::hasTransparency(int transparentPixel, bool isLocalColorma
|
||||
void SkGifImageReader::addFrameIfNecessary()
|
||||
{
|
||||
if (m_frames.empty() || m_frames.back()->isComplete()) {
|
||||
const size_t i = m_frames.size();
|
||||
std::unique_ptr<SkGIFFrameContext> frame(new SkGIFFrameContext(this, static_cast<int>(i)));
|
||||
m_frames.push_back(std::move(frame));
|
||||
const int i = m_frames.count();
|
||||
m_frames.emplace_back(new SkGIFFrameContext(this, i));
|
||||
}
|
||||
}
|
||||
|
||||
|
17
third_party/gif/SkGifImageReader.h
vendored
17
third_party/gif/SkGifImageReader.h
vendored
@ -52,7 +52,6 @@ class SkGifCodec;
|
||||
#include "SkStreamBuffer.h"
|
||||
#include "../private/SkTArray.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
typedef SkTArray<unsigned char, true> SkGIFRow;
|
||||
|
||||
@ -218,7 +217,7 @@ public:
|
||||
|
||||
void addLzwBlock(size_t position, size_t size)
|
||||
{
|
||||
m_lzwBlocks.push_back(SkGIFLZWBlock(position, size));
|
||||
m_lzwBlocks.emplace_back(position, size);
|
||||
}
|
||||
|
||||
bool decode(SkStreamBuffer*, SkGifCodec* client, bool* frameDecoded);
|
||||
@ -265,7 +264,7 @@ private:
|
||||
|
||||
std::unique_ptr<SkGIFLZWContext> m_lzwContext;
|
||||
// LZW blocks for this frame.
|
||||
std::vector<SkGIFLZWBlock> m_lzwBlocks;
|
||||
SkTArray<SkGIFLZWBlock> m_lzwBlocks;
|
||||
|
||||
SkGIFColorMap m_localColorMap;
|
||||
|
||||
@ -321,7 +320,7 @@ public:
|
||||
|
||||
int imagesCount() const
|
||||
{
|
||||
const size_t frames = m_frames.size();
|
||||
const int frames = m_frames.count();
|
||||
if (!frames) {
|
||||
return 0;
|
||||
}
|
||||
@ -331,7 +330,7 @@ public:
|
||||
// possibly SkGIFImageHeader) but before reading the color table. This
|
||||
// ensures that we do not count a frame before we know its required
|
||||
// frame.
|
||||
return static_cast<int>(m_frames.back()->reachedStartOfData() ? frames : frames - 1);
|
||||
return m_frames.back()->reachedStartOfData() ? frames : frames - 1;
|
||||
}
|
||||
int loopCount() const {
|
||||
if (cLoopCountNotSeen == m_loopCount) {
|
||||
@ -347,12 +346,12 @@ public:
|
||||
|
||||
const SkGIFFrameContext* frameContext(int index) const
|
||||
{
|
||||
return index >= 0 && index < static_cast<int>(m_frames.size())
|
||||
return index >= 0 && index < m_frames.count()
|
||||
? m_frames[index].get() : nullptr;
|
||||
}
|
||||
|
||||
void clearDecodeState() {
|
||||
for (size_t index = 0; index < m_frames.size(); index++) {
|
||||
for (int index = 0; index < m_frames.count(); index++) {
|
||||
m_frames[index]->clearDecodeState();
|
||||
}
|
||||
}
|
||||
@ -381,7 +380,7 @@ private:
|
||||
void addFrameIfNecessary();
|
||||
bool currentFrameIsFirstFrame() const
|
||||
{
|
||||
return m_frames.empty() || (m_frames.size() == 1u && !m_frames[0]->isComplete());
|
||||
return m_frames.empty() || (m_frames.count() == 1 && !m_frames[0]->isComplete());
|
||||
}
|
||||
|
||||
// Unowned pointer
|
||||
@ -398,7 +397,7 @@ private:
|
||||
static constexpr int cLoopCountNotSeen = -2;
|
||||
int m_loopCount; // Netscape specific extension block to control the number of animation loops a GIF renders.
|
||||
|
||||
std::vector<std::unique_ptr<SkGIFFrameContext>> m_frames;
|
||||
SkTArray<std::unique_ptr<SkGIFFrameContext>> m_frames;
|
||||
|
||||
SkStreamBuffer m_streamBuffer;
|
||||
bool m_parseCompleted;
|
||||
|
Loading…
Reference in New Issue
Block a user