Merge pull request #423 from mapbox/coalesce-texture-uploads
Upload textures at the beginning of a frame
This commit is contained in:
@@ -32,6 +32,7 @@ public:
|
||||
const SDFGlyph& glyph);
|
||||
void removeGlyphs(uint64_t tile_id);
|
||||
void bind();
|
||||
void upload();
|
||||
|
||||
public:
|
||||
const uint16_t width = 0;
|
||||
|
||||
@@ -41,10 +41,12 @@ public:
|
||||
// NEVER CALL THIS FUNCTION FROM THE RENDER THREAD! it is blocking.
|
||||
Rect<dimension> waitForImage(const std::string &name, const Sprite &sprite);
|
||||
|
||||
// Binds the image buffer of this sprite atlas to the GPU, and uploads data if it is out
|
||||
// of date.
|
||||
// Binds the image buffer of this sprite atlas to the GPU.
|
||||
void bind(bool linear = false);
|
||||
|
||||
// Uploads the image buffer to the GPU if it is out of date.
|
||||
void upload();
|
||||
|
||||
inline float getWidth() const { return width; }
|
||||
inline float getHeight() const { return height; }
|
||||
inline float getTextureWidth() const { return width * pixelRatio; }
|
||||
|
||||
@@ -120,6 +120,20 @@ void GlyphAtlas::removeGlyphs(uint64_t tile_id) {
|
||||
}
|
||||
}
|
||||
|
||||
void GlyphAtlas::upload() {
|
||||
if (dirty) {
|
||||
bind();
|
||||
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
|
||||
dirty = false;
|
||||
|
||||
#if defined(DEBUG)
|
||||
// platform::show_debug_image("Glyph Atlas", data, width, height);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void GlyphAtlas::bind() {
|
||||
if (!texture) {
|
||||
glGenTextures(1, &texture);
|
||||
@@ -131,14 +145,4 @@ void GlyphAtlas::bind() {
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
}
|
||||
|
||||
if (dirty) {
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
|
||||
dirty = false;
|
||||
|
||||
#if defined(DEBUG)
|
||||
// platform::show_debug_image("Glyph Atlas", data, width, height);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -196,13 +196,11 @@ void SpriteAtlas::update(const Sprite &sprite) {
|
||||
}
|
||||
|
||||
void SpriteAtlas::bind(bool linear) {
|
||||
bool first = false;
|
||||
if (!texture) {
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
first = true;
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
}
|
||||
@@ -213,12 +211,17 @@ void SpriteAtlas::bind(bool linear) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_val);
|
||||
filter = filter_val;
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteAtlas::upload() {
|
||||
if (dirty) {
|
||||
bool exists = texture;
|
||||
bind(filter); // Make sure we don't change the filter value.
|
||||
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
allocate();
|
||||
|
||||
if (first) {
|
||||
if (!exists) {
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, // GLenum target
|
||||
0, // GLint level
|
||||
@@ -248,7 +251,7 @@ void SpriteAtlas::bind(bool linear) {
|
||||
#endif
|
||||
dirty = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
SpriteAtlas::~SpriteAtlas() {
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
|
||||
@@ -558,6 +558,10 @@ void Map::render() {
|
||||
#if defined(DEBUG)
|
||||
std::vector<std::string> debug;
|
||||
#endif
|
||||
|
||||
glyphAtlas->upload();
|
||||
spriteAtlas->upload();
|
||||
|
||||
painter.clear();
|
||||
|
||||
painter.resetFramebuffer();
|
||||
|
||||
Reference in New Issue
Block a user