re-factor PNG compression to share and protect TileDesc updates.
Change-Id: I3cbda6ecd78c7be8ca7fc767d9a5a288a020df7b
This commit is contained in:
parent
adfaa76ff6
commit
a088e09193
1 changed files with 41 additions and 47 deletions
88
kit/Kit.cpp
88
kit/Kit.cpp
|
@ -389,20 +389,20 @@ namespace
|
|||
/// wherever possible.
|
||||
class PngCache
|
||||
{
|
||||
public:
|
||||
typedef std::shared_ptr< std::vector< char > > CacheData;
|
||||
|
||||
private:
|
||||
struct CacheEntry {
|
||||
private:
|
||||
size_t _hitCount;
|
||||
TileWireId _wireId;
|
||||
CacheData _data;
|
||||
public:
|
||||
CacheEntry(size_t defaultSize, TileWireId id) :
|
||||
CacheEntry(const CacheData &data, TileWireId id) :
|
||||
_hitCount(1), // Every entry is used at least once; prevent removal at birth.
|
||||
_wireId(id),
|
||||
_data( new std::vector< char >() )
|
||||
_data(data)
|
||||
{
|
||||
_data->reserve( defaultSize );
|
||||
}
|
||||
|
||||
size_t getHitCount() const
|
||||
|
@ -430,6 +430,7 @@ class PngCache
|
|||
return _wireId;
|
||||
}
|
||||
} ;
|
||||
|
||||
size_t _cacheSize;
|
||||
static const size_t CacheSizeSoftLimit = (1024 * 4 * 32); // 128k of cache
|
||||
static const size_t CacheSizeHardLimit = CacheSizeSoftLimit * 2;
|
||||
|
@ -509,7 +510,7 @@ class PngCache
|
|||
public:
|
||||
/// Lookup an entry in the cache and store the data in output.
|
||||
/// Returns true on success, otherwise false.
|
||||
bool copyFromCache(const uint64_t hash, std::vector<char>& output)
|
||||
bool copyFromCache(const TileBinaryHash hash, std::vector<char>& output, size_t &imgSize)
|
||||
{
|
||||
if (hash)
|
||||
{
|
||||
|
@ -523,6 +524,8 @@ public:
|
|||
it->second.getData()->begin(),
|
||||
it->second.getData()->end());
|
||||
it->second.incrementHitCount();
|
||||
imgSize = it->second.getData()->size();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -530,43 +533,17 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool encodeSubBufferToPNG(unsigned char* pixmap, size_t startX, size_t startY,
|
||||
int width, int height,
|
||||
int bufferWidth, int bufferHeight,
|
||||
std::vector<char>& output, LibreOfficeKitTileMode mode,
|
||||
TileBinaryHash hash, TileWireId wid, TileWireId /*oldWid*/)
|
||||
void addToCache(const CacheData &data, TileWireId wid, const TileBinaryHash hash)
|
||||
{
|
||||
LOG_DBG("PNG cache with hash " << hash << " missed.");
|
||||
/*
|
||||
*Disable for now - pushed in error.
|
||||
*
|
||||
if (_deltaGen.createDelta(pixmap, startX, startY, width, height,
|
||||
bufferWidth, bufferHeight,
|
||||
output, wid, oldWid))
|
||||
return true;
|
||||
*/
|
||||
CacheEntry newEntry(data, wid);
|
||||
|
||||
LOG_DBG("Encode a new png for this tile.");
|
||||
CacheEntry newEntry(bufferWidth * bufferHeight * 1, wid);
|
||||
if (Png::encodeSubBufferToPNG(pixmap, startX, startY, width, height,
|
||||
bufferWidth, bufferHeight,
|
||||
*newEntry.getData(), mode))
|
||||
if (hash)
|
||||
{
|
||||
if (hash)
|
||||
{
|
||||
newEntry.getData()->shrink_to_fit();
|
||||
_cache.emplace(hash, newEntry);
|
||||
_cacheSize += newEntry.getData()->size();
|
||||
}
|
||||
|
||||
output.insert(output.end(),
|
||||
newEntry.getData()->begin(),
|
||||
newEntry.getData()->end());
|
||||
data->shrink_to_fit();
|
||||
_cache.emplace(hash, newEntry);
|
||||
_cacheSize += data->size();
|
||||
balanceCache();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
PngCache()
|
||||
|
@ -1035,16 +1012,15 @@ public:
|
|||
output.reserve(pixmapSize);
|
||||
|
||||
// Compress the area as tiles
|
||||
const int pixelWidth = tileCombined.getWidth();
|
||||
const int pixelHeight = tileCombined.getHeight();
|
||||
|
||||
size_t tileIndex = 0;
|
||||
for (Util::Rectangle& tileRect : tileRecs)
|
||||
{
|
||||
const size_t positionX = (tileRect.getLeft() - renderArea.getLeft()) / tileCombined.getTileWidth();
|
||||
const size_t positionY = (tileRect.getTop() - renderArea.getTop()) / tileCombined.getTileHeight();
|
||||
|
||||
const size_t oldSize = output.size();
|
||||
const int pixelWidth = tileCombined.getWidth();
|
||||
const int pixelHeight = tileCombined.getHeight();
|
||||
|
||||
const int offsetX = positionX * pixelWidth;
|
||||
const int offsetY = positionY * pixelHeight;
|
||||
|
||||
|
@ -1062,27 +1038,45 @@ public:
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!_pngCache.copyFromCache(hash, output))
|
||||
size_t imgSize;
|
||||
|
||||
if (!_pngCache.copyFromCache(hash, output, imgSize))
|
||||
{
|
||||
LOG_DBG("PNG cache with hash " << hash << " missed.");
|
||||
|
||||
if (_docWatermark)
|
||||
_docWatermark->blending(pixmap.data(), offsetX, offsetY,
|
||||
pixmapWidth, pixmapHeight,
|
||||
pixelWidth, pixelHeight,
|
||||
mode);
|
||||
|
||||
if (!_pngCache.encodeSubBufferToPNG(pixmap.data(), offsetX, offsetY,
|
||||
pixelWidth, pixelHeight,
|
||||
pixmapWidth, pixmapHeight, output, mode,
|
||||
hash, wireId, oldWireId))
|
||||
PngCache::CacheData data(new std::vector< char >() );
|
||||
data->reserve(pixmapWidth * pixmapHeight * 1);
|
||||
|
||||
/*
|
||||
*Disable for now - pushed in error.
|
||||
*
|
||||
if (_deltaGen.createDelta(pixmap, startX, startY, width, height,
|
||||
bufferWidth, bufferHeight,
|
||||
output, wid, oldWid))
|
||||
else ...
|
||||
*/
|
||||
|
||||
LOG_DBG("Encode a new png for this tile.");
|
||||
if (!Png::encodeSubBufferToPNG(pixmap.data(), offsetX, offsetY, pixelWidth, pixelHeight,
|
||||
pixmapWidth, pixmapHeight, *data, mode))
|
||||
{
|
||||
// FIXME: Return error.
|
||||
// sendTextFrame("error: cmd=tile kind=failure");
|
||||
LOG_ERR("Failed to encode tile into PNG.");
|
||||
return;
|
||||
}
|
||||
|
||||
output.insert(output.end(), data->begin(), data->end());
|
||||
imgSize = data->size();
|
||||
_pngCache.addToCache(data, wireId, hash);
|
||||
}
|
||||
|
||||
const size_t imgSize = output.size() - oldSize;
|
||||
LOG_TRC("Encoded tile #" << tileIndex << " at (" << positionX << "," << positionY << ") with oldWireId=" <<
|
||||
tiles[tileIndex].getOldWireId() << ", hash=" << hash << " wireId: " << wireId << " in " << imgSize << " bytes.");
|
||||
tiles[tileIndex].setWireId(wireId);
|
||||
|
|
Loading…
Reference in a new issue