init
This commit is contained in:
commit
2c2202e60d
2491 files changed
+1295990
No files matched your search
@@ -0,0 +1,263 @@
|
||||
/* DO NOT EDIT THIS FILE */
|
||||
/* This file is autogenerated by the text-database code generator */
|
||||
|
||||
#include <fonts/CompressedUnmappedFontCache.hpp>
|
||||
#include <touchgfx/hal/HAL.hpp>
|
||||
#include <touchgfx/hal/Paint.hpp>
|
||||
|
||||
namespace touchgfx
|
||||
{
|
||||
LOCATION_PRAGMA_32("TouchGFX_CompressedUnmappedFontCache")
|
||||
uint32_t CompressedUnmappedFontCache::bitmapFontCache[cacheWords] LOCATION_ATTRIBUTE_32("TouchGFX_CompressedUnmappedFontCache");
|
||||
uint8_t* CompressedUnmappedFontCache::pixelsTop = (uint8_t*)CompressedUnmappedFontCache::bitmapFontCache;
|
||||
int CompressedUnmappedFontCache::glyphsAllocated = 0;
|
||||
int CompressedUnmappedFontCache::cacheClearCounter = 0;
|
||||
|
||||
namespace
|
||||
{
|
||||
/* Read nibbles from compressed data in unmapped flash. Must read through reader object */
|
||||
struct NibUnmapReader
|
||||
{
|
||||
NibUnmapReader(const uint8_t* srcAddress, touchgfx::FlashDataReader* reader)
|
||||
: address(srcAddress), reader(reader), byteIndex(0), low(true)
|
||||
{
|
||||
address += bufferSize;
|
||||
reader->copyData(srcAddress, buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
const uint8_t* address; //next reading address
|
||||
touchgfx::FlashDataReader* reader;
|
||||
static const int bufferSize = 16;
|
||||
uint8_t buffer[bufferSize];
|
||||
uint8_t value;
|
||||
int byteIndex;
|
||||
bool low;
|
||||
uint8_t getNext()
|
||||
{
|
||||
if (low)
|
||||
{
|
||||
value = buffer[byteIndex];
|
||||
const uint8_t val = value & 0xF;
|
||||
low = false;
|
||||
return val;
|
||||
}
|
||||
const uint8_t val = value >> 4;
|
||||
low = true;
|
||||
if (byteIndex == bufferSize - 1)
|
||||
{
|
||||
reader->copyData(address, buffer, bufferSize);
|
||||
address += bufferSize;
|
||||
byteIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
byteIndex++;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
struct NibWriter
|
||||
{
|
||||
NibWriter(uint8_t* buffer, int size)
|
||||
: buffer(buffer), bufferEnd(buffer + size), low(true) {}
|
||||
|
||||
uint8_t* buffer;
|
||||
uint8_t* bufferEnd;
|
||||
int low;
|
||||
void put(uint8_t v)
|
||||
{
|
||||
if (low)
|
||||
{
|
||||
*buffer = v;
|
||||
low = false;
|
||||
return;
|
||||
}
|
||||
*buffer |= (v << 4);
|
||||
buffer++;
|
||||
low = true;
|
||||
}
|
||||
bool eof() { return buffer >= bufferEnd; }
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
uint8_t* CompressedUnmappedFontCache::decompressGlyph(uint8_t* pixelsTop, const GlyphNode* glyphNode, const uint8_t* compressedData, touchgfx::FlashDataReader* flashReader)
|
||||
{
|
||||
const int byteSize = (glyphNode->width() + 1) / 2 * glyphNode->height();
|
||||
NibWriter writer(pixelsTop, byteSize);
|
||||
NibUnmapReader reader(compressedData, flashReader);
|
||||
uint8_t* const pixelsEnd = pixelsTop + byteSize;
|
||||
const int algorithm = glyphNode->dataOffset >> 30;
|
||||
if (algorithm == 1)
|
||||
{
|
||||
// RLE1
|
||||
while (!writer.eof())
|
||||
{
|
||||
const uint8_t value = reader.getNext();
|
||||
if (value == 0)
|
||||
{
|
||||
int zeroCount = reader.getNext();
|
||||
while (zeroCount)
|
||||
{
|
||||
writer.put(0);
|
||||
zeroCount--;
|
||||
}
|
||||
}
|
||||
writer.put(value);
|
||||
}
|
||||
}
|
||||
else if (algorithm == 2)
|
||||
{
|
||||
// RLE2
|
||||
while (!writer.eof())
|
||||
{
|
||||
const uint8_t value = reader.getNext();
|
||||
if (value == 0 || value == 0xF)
|
||||
{
|
||||
int count = reader.getNext();
|
||||
while (count)
|
||||
{
|
||||
writer.put(value);
|
||||
count--;
|
||||
}
|
||||
}
|
||||
writer.put(value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Uncompressed
|
||||
flashReader->copyData(compressedData, pixelsTop, byteSize);
|
||||
}
|
||||
|
||||
return pixelsEnd;
|
||||
}
|
||||
|
||||
void CompressedUnmappedFontCache::clearCache()
|
||||
{
|
||||
// Wait for DMA2D/GPU2D to finish drawing
|
||||
HAL::getInstance()->lockUnlockFrameBuffer();
|
||||
glyphsAllocated = 0;
|
||||
cacheClearCounter++;
|
||||
pixelsTop = (uint8_t*)bitmapFontCache;
|
||||
}
|
||||
|
||||
void CompressedUnmappedFontCache::unableToCache(const GlyphNode* glyphNode, int byteSize)
|
||||
{
|
||||
while(1);
|
||||
}
|
||||
|
||||
const GlyphNode* CompressedUnmappedFontCache::hasCachedGlyphNode(const GlyphNode* glyphNode)
|
||||
{
|
||||
const BitmapFontCacheKey* end = (const BitmapFontCacheKey*)&bitmapFontCache[cacheWords];
|
||||
const BitmapFontCacheKey* first = end - glyphsAllocated;
|
||||
while (first < end)
|
||||
{
|
||||
if (first->glyphNodeSrc == glyphNode)
|
||||
{
|
||||
return &first->glyphNodeCopy;
|
||||
}
|
||||
first++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const GlyphNode* CompressedUnmappedFontCache::hasCachedGlyphData(const GlyphNode* glyphNode, const uint8_t*& pixelData)
|
||||
{
|
||||
const BitmapFontCacheKey* end = (const BitmapFontCacheKey*)&bitmapFontCache[cacheWords];
|
||||
const BitmapFontCacheKey* first = end - glyphsAllocated;
|
||||
while (first < end)
|
||||
{
|
||||
if (first->glyphNodeSrc == glyphNode)
|
||||
{
|
||||
//Pixel data can be zero!
|
||||
pixelData = first->pixels;
|
||||
return &first->glyphNodeCopy;
|
||||
}
|
||||
first++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
GlyphNode* CompressedUnmappedFontCache::cacheGlyphNode(const GlyphNode* glyph)
|
||||
{
|
||||
const BitmapFontCacheKey* end = (const BitmapFontCacheKey*)&bitmapFontCache[cacheWords];
|
||||
if (pixelsTop + sizeof(BitmapFontCacheKey) > (const uint8_t*)&end[-glyphsAllocated])
|
||||
{
|
||||
// Unable to fit GlyphNode in data, clear cache
|
||||
clearCache();
|
||||
}
|
||||
|
||||
glyphsAllocated++;
|
||||
BitmapFontCacheKey* key = const_cast<BitmapFontCacheKey*>(end - glyphsAllocated);
|
||||
key->glyphNodeSrc = glyph;
|
||||
key->pixels = 0;
|
||||
|
||||
return &key->glyphNodeCopy;
|
||||
}
|
||||
|
||||
const uint8_t* CompressedUnmappedFontCache::cacheGlyphData(const GlyphNode* glyph, const uint8_t* compressedData, touchgfx::FlashDataReader* reader)
|
||||
{
|
||||
// Search keys for glyph
|
||||
BitmapFontCacheKey* end = (BitmapFontCacheKey*)&bitmapFontCache[cacheWords];
|
||||
BitmapFontCacheKey* it = end - glyphsAllocated;
|
||||
while (it < end)
|
||||
{
|
||||
if (it->glyphNodeSrc == glyph)
|
||||
{
|
||||
break;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
if (it == end)
|
||||
{
|
||||
// broken invariant!
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int byteSize = (it->glyphNodeCopy.width() + 1) / 2 * it->glyphNodeCopy.height();
|
||||
// Check if pixels can fit in cache
|
||||
if (pixelsTop + byteSize > (const uint8_t*)&end[-glyphsAllocated])
|
||||
{
|
||||
// Can it fit in a clean cache?
|
||||
if (byteSize + sizeof(BitmapFontCacheKey) > cacheSizeBytes)
|
||||
{
|
||||
unableToCache(glyph, byteSize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Unable to fit pixel in data, must clear cache
|
||||
|
||||
// Save address of GlyphNode in cache
|
||||
const GlyphNode* cachedGn = &it->glyphNodeCopy;
|
||||
|
||||
// Now clear (reset pointer)
|
||||
clearCache();
|
||||
|
||||
// Insert glyph node again
|
||||
glyphsAllocated++;
|
||||
it = const_cast<BitmapFontCacheKey*>(end - 1);
|
||||
it->glyphNodeSrc = glyph;
|
||||
it->pixels = 0;
|
||||
// Copy GlyphNode content from previous position in cache
|
||||
it->glyphNodeCopy = *cachedGn;
|
||||
}
|
||||
|
||||
//Now decompress data
|
||||
const uint8_t* glyphData = pixelsTop;
|
||||
pixelsTop = decompressGlyph(pixelsTop, &it->glyphNodeCopy, compressedData, reader);
|
||||
|
||||
// Flush the cache lines, must be 32byte aligned
|
||||
uint8_t* rowStart = reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(glyphData) & ~0x1F);
|
||||
int alignmentOffset = glyphData - rowStart;
|
||||
paint::flushLine((uint32_t*)rowStart, byteSize + alignmentOffset);
|
||||
paint::invalidateTextureCache();
|
||||
|
||||
it->pixels = glyphData;
|
||||
|
||||
return glyphData;
|
||||
}
|
||||
|
||||
} // namespace touchgfx
|
||||
Reference in new issue
Block a user