summaryrefslogtreecommitdiff
path: root/src/mbgl/text/glyph_atlas.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/text/glyph_atlas.cpp')
-rw-r--r--src/mbgl/text/glyph_atlas.cpp79
1 files changed, 23 insertions, 56 deletions
diff --git a/src/mbgl/text/glyph_atlas.cpp b/src/mbgl/text/glyph_atlas.cpp
index dc1fe2b1d9..1b3f7518b5 100644
--- a/src/mbgl/text/glyph_atlas.cpp
+++ b/src/mbgl/text/glyph_atlas.cpp
@@ -23,16 +23,17 @@ GlyphAtlas::GlyphAtlas(const Size size, FileSource& fileSource_)
GlyphAtlas::~GlyphAtlas() = default;
void GlyphAtlas::requestGlyphRange(const FontStack& fontStack, const GlyphRange& range) {
- std::lock_guard<std::mutex> lock(rangesMutex);
- auto& rangeSets = ranges[fontStack];
+ std::lock_guard<std::mutex> lock(mutex);
+ auto& rangeSets = entries[fontStack].ranges;
const auto& rangeSetsIt = rangeSets.find(range);
if (rangeSetsIt != rangeSets.end()) {
return;
}
- rangeSets.emplace(range,
- std::make_unique<GlyphPBF>(this, fontStack, range, observer, fileSource));
+ rangeSets.emplace(std::piecewise_construct,
+ std::forward_as_tuple(range),
+ std::forward_as_tuple(this, fontStack, range, observer, fileSource));
}
bool GlyphAtlas::hasGlyphRanges(const FontStack& fontStack, const GlyphRangeSet& glyphRanges) {
@@ -40,8 +41,8 @@ bool GlyphAtlas::hasGlyphRanges(const FontStack& fontStack, const GlyphRangeSet&
return true;
}
- std::lock_guard<std::mutex> lock(rangesMutex);
- const auto& rangeSets = ranges[fontStack];
+ std::lock_guard<std::mutex> lock(mutex);
+ const auto& rangeSets = entries[fontStack].ranges;
bool hasRanges = true;
for (const auto& range : glyphRanges) {
@@ -55,7 +56,7 @@ bool GlyphAtlas::hasGlyphRanges(const FontStack& fontStack, const GlyphRangeSet&
continue;
}
- if (!rangeSetsIt->second->isParsed()) {
+ if (!rangeSetsIt->second.isParsed()) {
hasRanges = false;
}
}
@@ -64,16 +65,8 @@ bool GlyphAtlas::hasGlyphRanges(const FontStack& fontStack, const GlyphRangeSet&
}
util::exclusive<GlyphSet> GlyphAtlas::getGlyphSet(const FontStack& fontStack) {
- auto lock = std::make_unique<std::lock_guard<std::mutex>>(glyphSetsMutex);
-
- auto it = glyphSets.find(fontStack);
- if (it == glyphSets.end()) {
- it = glyphSets.emplace(fontStack, std::make_unique<GlyphSet>()).first;
- }
-
- // FIXME: We lock all GlyphSets, but what we should
- // really do is lock only the one we are returning.
- return { it->second.get(), std::move(lock) };
+ auto lock = std::make_unique<std::lock_guard<std::mutex>>(mutex);
+ return { &entries[fontStack].glyphSet, std::move(lock) };
}
void GlyphAtlas::setObserver(GlyphAtlasObserver* observer_) {
@@ -83,12 +76,10 @@ void GlyphAtlas::setObserver(GlyphAtlasObserver* observer_) {
void GlyphAtlas::addGlyphs(uintptr_t tileUID,
const std::u16string& text,
const FontStack& fontStack,
- const GlyphSet& glyphSet,
+ const util::exclusive<GlyphSet>& glyphSet,
GlyphPositions& face)
{
- std::lock_guard<std::mutex> lock(mtx);
-
- const std::map<uint32_t, SDFGlyph>& sdfs = glyphSet.getSDFs();
+ const std::map<uint32_t, SDFGlyph>& sdfs = glyphSet->getSDFs();
for (char16_t chr : text)
{
@@ -107,7 +98,7 @@ Rect<uint16_t> GlyphAtlas::addGlyph(uintptr_t tileUID,
const FontStack& fontStack,
const SDFGlyph& glyph)
{
- std::map<uint32_t, GlyphValue>& face = index[fontStack];
+ std::map<uint32_t, GlyphValue>& face = entries[fontStack].glyphValues;
auto it = face.find(glyph.id);
// The glyph is already in this texture.
@@ -124,48 +115,26 @@ Rect<uint16_t> GlyphAtlas::addGlyph(uintptr_t tileUID,
return Rect<uint16_t>{ 0, 0, 0, 0 };
}
- uint16_t buffered_width = glyph.metrics.width + SDFGlyph::borderSize * 2;
- uint16_t buffered_height = glyph.metrics.height + SDFGlyph::borderSize * 2;
-
- // Guard against mismatches between the glyph bitmap size and the size mandated by
- // its metrics.
- if (size_t(buffered_width * buffered_height) != glyph.bitmap.size()) {
- return Rect<uint16_t>{ 0, 0, 0, 0 };
- }
-
// Add a 1px border around every image.
- const uint16_t padding = 1;
- uint16_t pack_width = buffered_width + 2 * padding;
- uint16_t pack_height = buffered_height + 2 * padding;
+ const uint32_t padding = 1;
+ uint16_t width = glyph.bitmap.size.width + 2 * padding;
+ uint16_t height = glyph.bitmap.size.height + 2 * padding;
// Increase to next number divisible by 4, but at least 1.
// This is so we can scale down the texture coordinates and pack them
// into 2 bytes rather than 4 bytes.
- pack_width += (4 - pack_width % 4);
- pack_height += (4 - pack_height % 4);
+ width += (4 - width % 4);
+ height += (4 - height % 4);
- Rect<uint16_t> rect = bin.allocate(pack_width, pack_height);
+ Rect<uint16_t> rect = bin.allocate(width, height);
if (rect.w == 0) {
Log::Error(Event::OpenGL, "glyph bitmap overflow");
return rect;
}
- // Verify that binpack didn't produce a rect that goes beyond the size of the image.
- // This should never happen.
- assert(rect.x + rect.w <= image.size.width);
- assert(rect.y + rect.h <= image.size.height);
-
face.emplace(glyph.id, GlyphValue { rect, tileUID });
- // Copy the bitmap
- const uint8_t* source = reinterpret_cast<const uint8_t*>(glyph.bitmap.data());
- for (uint32_t y = 0; y < buffered_height; y++) {
- uint32_t y1 = image.size.width * (rect.y + y + padding) + rect.x + padding;
- uint32_t y2 = buffered_width * y;
- for (uint32_t x = 0; x < buffered_width; x++) {
- image.data[y1 + x] = source[y2 + x];
- }
- }
+ AlphaImage::copy(glyph.bitmap, image, { 0, 0 }, { rect.x + padding, rect.y + padding }, glyph.bitmap.size);
dirty = true;
@@ -173,10 +142,10 @@ Rect<uint16_t> GlyphAtlas::addGlyph(uintptr_t tileUID,
}
void GlyphAtlas::removeGlyphs(uintptr_t tileUID) {
- std::lock_guard<std::mutex> lock(mtx);
+ std::lock_guard<std::mutex> lock(mutex);
- for (auto& faces : index) {
- std::map<uint32_t, GlyphValue>& face = faces.second;
+ for (auto& entry : entries) {
+ std::map<uint32_t, GlyphValue>& face = entry.second.glyphValues;
for (auto it = face.begin(); it != face.end(); /* we advance in the body */) {
GlyphValue& value = it->second;
value.ids.erase(tileUID);
@@ -212,8 +181,6 @@ Size GlyphAtlas::getSize() const {
}
void GlyphAtlas::upload(gl::Context& context, gl::TextureUnit unit) {
- std::lock_guard<std::mutex> lock(mtx);
-
if (!texture) {
texture = context.createTexture(image, unit);
} else if (dirty) {