diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2022-04-06 08:39:45 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-06 08:39:45 +0200 |
commit | 5d558467151530eb68b894497e65f7cb81fbd752 (patch) | |
tree | 2d73a77588186bb3ccccac7ed9cdb2cdcd2870ea | |
parent | b79721fede1dd64e319acaeccc494203a58fd274 (diff) | |
parent | aad9d1414c04e4e5eb5a8832a1f94133971f9cbb (diff) |
Merge pull request #59862 from bruvzg/font_delay_texture_update
Delay font texture update, until `draw` is called. Rasterize glyphs during shaping.
-rw-r--r-- | modules/text_server_adv/text_server_adv.cpp | 95 | ||||
-rw-r--r-- | modules/text_server_adv/text_server_adv.h | 1 | ||||
-rw-r--r-- | modules/text_server_fb/text_server_fb.cpp | 92 | ||||
-rw-r--r-- | modules/text_server_fb/text_server_fb.h | 9 |
4 files changed, 105 insertions, 92 deletions
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 71b09a5e69..ae662a0a9b 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -768,12 +768,6 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_ for (int i = 0; i < p_data->textures.size(); i++) { const FontTexture &ct = p_data->textures[i]; - if (RenderingServer::get_singleton() != nullptr) { - if (ct.texture->get_format() != p_image_format) { - continue; - } - } - if (mw > ct.texture_w || mh > ct.texture_h) { // Too big for this texture. continue; } @@ -815,12 +809,6 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_ ret.y = 0; int texsize = MAX(p_data->size.x * p_data->oversampling * 8, 256); - if (mw > texsize) { - texsize = mw; // Special case, adapt to it? - } - if (mh > texsize) { - texsize = mh; // Special case, adapt to it? - } #ifdef GDEXTENSION texsize = Math::next_power_of_2(texsize); @@ -832,6 +820,20 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_ } else { texsize = MIN(texsize, 1024); } + if (mw > texsize) { // Special case, adapt to it? +#ifdef GDEXTENSION + texsize = Math::next_power_of_2(mw); +#else + texsize = next_power_of_2(mw); +#endif + } + if (mh > texsize) { // Special case, adapt to it? +#ifdef GDEXTENSION + texsize = Math::next_power_of_2(mh); +#else + texsize = next_power_of_2(mh); +#endif + } FontTexture tex; tex.texture_w = texsize; @@ -997,8 +999,8 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf( int mw = w + p_rect_margin * 2; int mh = h + p_rect_margin * 2; - ERR_FAIL_COND_V(mw > 1024, FontGlyph()); - ERR_FAIL_COND_V(mh > 1024, FontGlyph()); + ERR_FAIL_COND_V(mw > 4096, FontGlyph()); + ERR_FAIL_COND_V(mh > 4096, FontGlyph()); FontTexturePosition tex_pos = find_texture_pos_for_glyph(p_data, 4, Image::FORMAT_RGBA8, mw, mh, true); ERR_FAIL_COND_V(tex_pos.index < 0, FontGlyph()); @@ -1039,20 +1041,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf( } } - // Blit to image and texture. - { - if (RenderingServer::get_singleton() != nullptr) { - Ref<Image> img; - img.instantiate(); - img->create_from_data(tex.texture_w, tex.texture_h, false, Image::FORMAT_RGBA8, tex.imgdata); - if (tex.texture.is_null()) { - tex.texture.instantiate(); - tex.texture->create_from_image(img); - } else { - tex.texture->update(img); - } - } - } + tex.dirty = true; // Update height array. int32_t *offw = tex.offsets.ptrw(); @@ -1078,8 +1067,8 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma int mw = w + p_rect_margin * 2; int mh = h + p_rect_margin * 2; - ERR_FAIL_COND_V(mw > 1024, FontGlyph()); - ERR_FAIL_COND_V(mh > 1024, FontGlyph()); + ERR_FAIL_COND_V(mw > 4096, FontGlyph()); + ERR_FAIL_COND_V(mh > 4096, FontGlyph()); int color_size = bitmap.pixel_mode == FT_PIXEL_MODE_BGRA ? 4 : 2; Image::Format require_format = color_size == 4 ? Image::FORMAT_RGBA8 : Image::FORMAT_LA8; @@ -1124,21 +1113,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma } } - // Blit to image and texture. - { - if (RenderingServer::get_singleton() != nullptr) { - Ref<Image> img; - img.instantiate(); - img->create_from_data(tex.texture_w, tex.texture_h, false, require_format, tex.imgdata); - - if (tex.texture.is_null()) { - tex.texture.instantiate(); - tex.texture->create_from_image(img); - } else { - tex.texture->update(img); - } - } - } + tex.dirty = true; // Update height array. int32_t *offw = tex.offsets.ptrw(); @@ -2311,6 +2286,7 @@ void TextServerAdvanced::font_set_texture_image(const RID &p_font_rid, const Vec tex.texture = Ref<ImageTexture>(); tex.texture.instantiate(); tex.texture->create_from_image(img); + tex.dirty = false; } Ref<Image> TextServerAdvanced::font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const { @@ -2890,6 +2866,19 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can } #endif if (RenderingServer::get_singleton() != nullptr) { + if (fd->cache[size]->textures[gl.texture_idx].dirty) { + FontTexture &tex = fd->cache[size]->textures.write[gl.texture_idx]; + Ref<Image> img; + img.instantiate(); + img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (tex.texture.is_null()) { + tex.texture.instantiate(); + tex.texture->create_from_image(img); + } else { + tex.texture->update(img); + } + tex.dirty = false; + } RID texture = fd->cache[size]->textures[gl.texture_idx].texture->get_rid(); if (fd->msdf) { Point2 cpos = p_pos; @@ -2953,6 +2942,19 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI } #endif if (RenderingServer::get_singleton() != nullptr) { + if (fd->cache[size]->textures[gl.texture_idx].dirty) { + FontTexture &tex = fd->cache[size]->textures.write[gl.texture_idx]; + Ref<Image> img; + img.instantiate(); + img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (tex.texture.is_null()) { + tex.texture.instantiate(); + tex.texture->create_from_image(img); + } else { + tex.texture->update(img); + } + tex.dirty = false; + } RID texture = fd->cache[size]->textures[gl.texture_idx].texture->get_rid(); if (fd->msdf) { Point2 cpos = p_pos; @@ -4638,6 +4640,8 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star } RID f = p_fonts[p_fb_index]; + FontDataAdvanced *fd = font_owner.get_or_null(f); + Vector2i fss = _get_size(fd, fs); hb_font_t *hb_font = _font_get_hb_handle(f, fs); double scale = font_get_scale(f, fs); double sp_sp = font_get_spacing(f, fs, SPACING_SPACE); @@ -4719,6 +4723,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int64_t p_star gl.index = glyph_info[i].codepoint; if (gl.index != 0) { + _ensure_glyph(fd, fss, gl.index); if (p_sd->orientation == ORIENTATION_HORIZONTAL) { if (subpos) { gl.advance = glyph_pos[i].x_advance / (64.0 / scale) + ea; diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index bb3968ee3f..8afba6adca 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -159,6 +159,7 @@ class TextServerAdvanced : public TextServerExtension { int texture_h = 0; PackedInt32Array offsets; Ref<ImageTexture> texture; + bool dirty = true; }; struct FontTexturePosition { diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 2e8ccf28b9..027c01c716 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -209,12 +209,6 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_ for (int i = 0; i < p_data->textures.size(); i++) { const FontTexture &ct = p_data->textures[i]; - if (RenderingServer::get_singleton() != nullptr) { - if (ct.texture->get_format() != p_image_format) { - continue; - } - } - if (mw > ct.texture_w || mh > ct.texture_h) { // Too big for this texture. continue; } @@ -256,12 +250,6 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_ ret.y = 0; int texsize = MAX(p_data->size.x * p_data->oversampling * 8, 256); - if (mw > texsize) { - texsize = mw; // Special case, adapt to it? - } - if (mh > texsize) { - texsize = mh; // Special case, adapt to it? - } #ifdef GDEXTENSION texsize = Math::next_power_of_2(texsize); @@ -274,6 +262,20 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_ } else { texsize = MIN(texsize, 1024); } + if (mw > texsize) { // Special case, adapt to it? +#ifdef GDEXTENSION + texsize = Math::next_power_of_2(mw); +#else + texsize = next_power_of_2(mw); +#endif + } + if (mh > texsize) { // Special case, adapt to it? +#ifdef GDEXTENSION + texsize = Math::next_power_of_2(mh); +#else + texsize = next_power_of_2(mh); +#endif + } FontTexture tex; tex.texture_w = texsize; @@ -439,8 +441,8 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf( int mw = w + p_rect_margin * 2; int mh = h + p_rect_margin * 2; - ERR_FAIL_COND_V(mw > 1024, FontGlyph()); - ERR_FAIL_COND_V(mh > 1024, FontGlyph()); + ERR_FAIL_COND_V(mw > 4096, FontGlyph()); + ERR_FAIL_COND_V(mh > 4096, FontGlyph()); FontTexturePosition tex_pos = find_texture_pos_for_glyph(p_data, 4, Image::FORMAT_RGBA8, mw, mh, true); ERR_FAIL_COND_V(tex_pos.index < 0, FontGlyph()); @@ -481,20 +483,7 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf( } } - // Blit to image and texture. - { - if (RenderingServer::get_singleton() != nullptr) { - Ref<Image> img; - img.instantiate(); - img->create_from_data(tex.texture_w, tex.texture_h, false, Image::FORMAT_RGBA8, tex.imgdata); - if (tex.texture.is_null()) { - tex.texture.instantiate(); - tex.texture->create_from_image(img); - } else { - tex.texture->update(img); - } - } - } + tex.dirty = true; // Update height array. int32_t *offw = tex.offsets.ptrw(); @@ -520,8 +509,8 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma int mw = w + p_rect_margin * 2; int mh = h + p_rect_margin * 2; - ERR_FAIL_COND_V(mw > 1024, FontGlyph()); - ERR_FAIL_COND_V(mh > 1024, FontGlyph()); + ERR_FAIL_COND_V(mw > 4096, FontGlyph()); + ERR_FAIL_COND_V(mh > 4096, FontGlyph()); int color_size = bitmap.pixel_mode == FT_PIXEL_MODE_BGRA ? 4 : 2; Image::Format require_format = color_size == 4 ? Image::FORMAT_RGBA8 : Image::FORMAT_LA8; @@ -566,21 +555,7 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma } } - // Blit to image and texture. - { - if (RenderingServer::get_singleton() != nullptr) { - Ref<Image> img; - img.instantiate(); - img->create_from_data(tex.texture_w, tex.texture_h, false, require_format, tex.imgdata); - - if (tex.texture.is_null()) { - tex.texture.instantiate(); - tex.texture->create_from_image(img); - } else { - tex.texture->update(img); - } - } - } + tex.dirty = true; // Update height array. int32_t *offw = tex.offsets.ptrw(); @@ -1472,6 +1447,7 @@ void TextServerFallback::font_set_texture_image(const RID &p_font_rid, const Vec tex.texture = Ref<ImageTexture>(); tex.texture.instantiate(); tex.texture->create_from_image(img); + tex.dirty = false; } Ref<Image> TextServerFallback::font_get_texture_image(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) const { @@ -2019,6 +1995,19 @@ void TextServerFallback::font_draw_glyph(const RID &p_font_rid, const RID &p_can } #endif if (RenderingServer::get_singleton() != nullptr) { + if (fd->cache[size]->textures[gl.texture_idx].dirty) { + FontTexture &tex = fd->cache[size]->textures.write[gl.texture_idx]; + Ref<Image> img; + img.instantiate(); + img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (tex.texture.is_null()) { + tex.texture.instantiate(); + tex.texture->create_from_image(img); + } else { + tex.texture->update(img); + } + tex.dirty = false; + } RID texture = fd->cache[size]->textures[gl.texture_idx].texture->get_rid(); if (fd->msdf) { Point2 cpos = p_pos; @@ -2082,6 +2071,19 @@ void TextServerFallback::font_draw_glyph_outline(const RID &p_font_rid, const RI } #endif if (RenderingServer::get_singleton() != nullptr) { + if (fd->cache[size]->textures[gl.texture_idx].dirty) { + FontTexture &tex = fd->cache[size]->textures.write[gl.texture_idx]; + Ref<Image> img; + img.instantiate(); + img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (tex.texture.is_null()) { + tex.texture.instantiate(); + tex.texture->create_from_image(img); + } else { + tex.texture->update(img); + } + tex.dirty = false; + } RID texture = fd->cache[size]->textures[gl.texture_idx].texture->get_rid(); if (fd->msdf) { Point2 cpos = p_pos; diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index 3944c371b7..ea77659b5d 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -127,6 +127,7 @@ class TextServerFallback : public TextServerExtension { int texture_h = 0; PackedInt32Array offsets; Ref<ImageTexture> texture; + bool dirty = true; }; struct FontTexturePosition { @@ -343,8 +344,12 @@ public: virtual bool has(const RID &p_rid) override; virtual bool load_support_data(const String &p_filename) override; - virtual String get_support_data_filename() const override { return ""; }; - virtual String get_support_data_info() const override { return "Not supported"; }; + virtual String get_support_data_filename() const override { + return ""; + }; + virtual String get_support_data_info() const override { + return "Not supported"; + }; virtual bool save_support_data(const String &p_filename) const override; virtual bool is_locale_right_to_left(const String &p_locale) const override; |