@@ -1079,30 +1079,45 @@ static void d3d11_font_render_line(
10791079 unsigned height ,
10801080 unsigned text_align )
10811081{
1082- size_t i ;
10831082 unsigned count ;
10841083 D3D11_MAPPED_SUBRESOURCE mapped_vbo ;
1084+ HRESULT hr ;
10851085 const char * msg_end = msg + msg_len ;
10861086 d3d11_sprite_t * v = NULL ;
10871087 int x = pre_x ;
1088- int y = roundf ((1.0 - pos_y ) * height );
1089-
1088+ int y = roundf ((1.0f - pos_y ) * height );
1089+
1090+ /* Hoist function pointer and data pointer out of the loop to avoid
1091+ * repeated dependent loads through font->font_driver->get_glyph. */
1092+ const struct font_glyph * (* get_glyph )(void * , uint32_t )
1093+ = font -> font_driver -> get_glyph ;
1094+ void * font_data = font -> font_data ;
1095+
1096+ /* Precompute reciprocals -- replaces 8 per-glyph divisions with
1097+ * multiplications (~3-5x faster per op on most hardware). */
1098+ const float inv_vp_w = 1.0f / (float )d3d11 -> viewport .Width ;
1099+ const float inv_vp_h = 1.0f / (float )d3d11 -> viewport .Height ;
1100+ const float inv_tex_w = 1.0f / (float )font -> texture .desc .Width ;
1101+ const float inv_tex_h = 1.0f / (float )font -> texture .desc .Height ;
1102+
1103+ /* msg_len is byte length, which is >= the actual glyph count for
1104+ * multi-byte UTF-8 sequences. This makes the capacity check
1105+ * conservatively safe. */
10901106 if (d3d11 -> sprites .offset + msg_len > (unsigned )d3d11 -> sprites .capacity )
10911107 d3d11 -> sprites .offset = 0 ;
10921108
10931109 /* For right/center alignment, compute width with a lightweight pass
1094- * that only accumulates advance_x — avoids the redundant glyph lookups
1110+ * that only accumulates advance_x -- avoids the redundant glyph lookups
10951111 * and atlas dirty checks that d3d11_font_get_message_width would repeat. */
10961112 if (text_align == TEXT_ALIGN_RIGHT || text_align == TEXT_ALIGN_CENTER )
10971113 {
1098- int width_accum = 0 ;
1099- const char * scan = msg ;
1100- const char * scan_end = msg_end ;
1101- while (scan < scan_end )
1114+ int width_accum = 0 ;
1115+ const char * scan = msg ;
1116+ while (scan < msg_end )
11021117 {
11031118 const struct font_glyph * glyph ;
11041119 uint32_t code = utf8_walk (& scan );
1105- if (!(glyph = font -> font_driver -> get_glyph (font -> font_data , code )))
1120+ if (!(glyph = get_glyph (font_data , code )))
11061121 if (!(glyph = glyph_q ))
11071122 continue ;
11081123 width_accum += glyph -> advance_x ;
@@ -1114,51 +1129,59 @@ static void d3d11_font_render_line(
11141129 x -= (int )(width_accum * scale ) / 2 ;
11151130 }
11161131
1117- d3d11 -> context -> lpVtbl -> Map (
1118- d3d11 -> context , (D3D11Resource )d3d11 -> sprites .vbo , 0 , D3D11_MAP_WRITE_NO_OVERWRITE , 0 , & mapped_vbo );
1132+ hr = d3d11 -> context -> lpVtbl -> Map (
1133+ d3d11 -> context , (D3D11Resource )d3d11 -> sprites .vbo ,
1134+ 0 , D3D11_MAP_WRITE_NO_OVERWRITE , 0 , & mapped_vbo );
1135+
1136+ if (FAILED (hr ))
1137+ return ;
1138+
11191139 v = (d3d11_sprite_t * )mapped_vbo .pData + d3d11 -> sprites .offset ;
11201140
1121- for (i = 0 ; i < msg_len ; i ++ )
1141+ /* Walk the string by pointer using utf8_walk -- cleaner and faster than
1142+ * the old byte-index loop with manual skip adjustment. */
11221143 {
1123- const struct font_glyph * glyph ;
1124- const char * msg_tmp = & msg [i ];
1125- unsigned code = utf8_walk (& msg_tmp );
1126- unsigned skip = msg_tmp - & msg [i ];
1144+ const char * scan = msg ;
1145+ d3d11_sprite_t * v_start = v ;
11271146
1128- if (skip > 1 )
1129- i += skip - 1 ;
1147+ while (scan < msg_end )
1148+ {
1149+ const struct font_glyph * glyph ;
1150+ uint32_t code = utf8_walk (& scan );
11301151
1131- /* Do something smarter here ... */
1132- if (!(glyph = font -> font_driver -> get_glyph (font -> font_data , code )))
1133- if (!(glyph = glyph_q ))
1134- continue ;
1152+ if (!(glyph = get_glyph (font_data , code )))
1153+ if (!(glyph = glyph_q ))
1154+ continue ;
11351155
1136- v -> pos .x = (x + (glyph -> draw_offset_x * scale )) / ( float ) d3d11 -> viewport . Width ;
1137- v -> pos .y = (y + (glyph -> draw_offset_y * scale )) / ( float ) d3d11 -> viewport . Height ;
1138- v -> pos .w = glyph -> width * scale / ( float ) d3d11 -> viewport . Width ;
1139- v -> pos .h = glyph -> height * scale / ( float ) d3d11 -> viewport . Height ;
1156+ v -> pos .x = (x + (glyph -> draw_offset_x * scale )) * inv_vp_w ;
1157+ v -> pos .y = (y + (glyph -> draw_offset_y * scale )) * inv_vp_h ;
1158+ v -> pos .w = glyph -> width * scale * inv_vp_w ;
1159+ v -> pos .h = glyph -> height * scale * inv_vp_h ;
11401160
1141- v -> coords .u = glyph -> atlas_offset_x / ( float ) font -> texture . desc . Width ;
1142- v -> coords .v = glyph -> atlas_offset_y / ( float ) font -> texture . desc . Height ;
1143- v -> coords .w = glyph -> width / ( float ) font -> texture . desc . Width ;
1144- v -> coords .h = glyph -> height / ( float ) font -> texture . desc . Height ;
1161+ v -> coords .u = glyph -> atlas_offset_x * inv_tex_w ;
1162+ v -> coords .v = glyph -> atlas_offset_y * inv_tex_h ;
1163+ v -> coords .w = glyph -> width * inv_tex_w ;
1164+ v -> coords .h = glyph -> height * inv_tex_h ;
11451165
1146- v -> params .scaling = 1 ;
1147- v -> params .rotation = 0 ;
1166+ v -> params .scaling = 1 ;
1167+ v -> params .rotation = 0 ;
11481168
1149- v -> colors [0 ] = color ;
1150- v -> colors [1 ] = color ;
1151- v -> colors [2 ] = color ;
1152- v -> colors [3 ] = color ;
1169+ v -> colors [0 ] = color ;
1170+ v -> colors [1 ] = color ;
1171+ v -> colors [2 ] = color ;
1172+ v -> colors [3 ] = color ;
11531173
1154- v ++ ;
1174+ v ++ ;
1175+
1176+ x += glyph -> advance_x * scale ;
1177+ y += glyph -> advance_y * scale ;
1178+ }
11551179
1156- x += glyph -> advance_x * scale ;
1157- y += glyph -> advance_y * scale ;
1180+ count = (unsigned )(v - v_start );
11581181 }
11591182
1160- count = v - (( d3d11_sprite_t * ) mapped_vbo . pData + d3d11 -> sprites . offset );
1161- d3d11 -> context -> lpVtbl -> Unmap ( d3d11 -> context , (D3D11Resource )d3d11 -> sprites .vbo , 0 );
1183+ d3d11 -> context -> lpVtbl -> Unmap (
1184+ d3d11 -> context , (D3D11Resource )d3d11 -> sprites .vbo , 0 );
11621185
11631186 if (!count )
11641187 return ;
@@ -1184,9 +1207,12 @@ static void d3d11_font_render_line(
11841207 d3d11 -> context -> lpVtbl -> OMSetBlendState (d3d11 -> context , d3d11 -> blend_enable ,
11851208 NULL , D3D11_DEFAULT_SAMPLE_MASK );
11861209
1187- d3d11 -> context -> lpVtbl -> PSSetShader (d3d11 -> context , d3d11 -> sprites .shader_font .ps , NULL , 0 );
1188- d3d11 -> context -> lpVtbl -> Draw (d3d11 -> context , count , d3d11 -> sprites .offset );
1189- d3d11 -> context -> lpVtbl -> PSSetShader (d3d11 -> context , d3d11 -> sprites .shader .ps , NULL , 0 );
1210+ d3d11 -> context -> lpVtbl -> PSSetShader (
1211+ d3d11 -> context , d3d11 -> sprites .shader_font .ps , NULL , 0 );
1212+ d3d11 -> context -> lpVtbl -> Draw (
1213+ d3d11 -> context , count , d3d11 -> sprites .offset );
1214+ d3d11 -> context -> lpVtbl -> PSSetShader (
1215+ d3d11 -> context , d3d11 -> sprites .shader .ps , NULL , 0 );
11901216
11911217 d3d11 -> sprites .offset += count ;
11921218}
0 commit comments