updating to latest VEFontCache... tested 10k draw call target (worked)

This commit is contained in:
Edward R. Gonzalez 2025-02-13 19:12:13 -05:00
parent 0f5f9c18b1
commit 85dbaa37b9
16 changed files with 10064 additions and 18821 deletions

View File

@ -703,13 +703,13 @@ batch_generate_glyphs_draw_list :: proc ( draw_list : ^Draw_List,
dst_glyph_pos := glyph.region_pos
dst_glyph_size := bounds_size_scaled + atlas.glyph_padding
dst_glyph_size.x = ceil(dst_glyph_size.x)
dst_glyph_size.x = dst_glyph_size.x
dst_glyph_size.y = max(dst_glyph_size.y, ceil(dst_glyph_size.y) * glyph_buffer.snap_glyph_height) // Note(Ed): Seems to improve hinting
to_glyph_buffer_space( & dst_glyph_pos, & dst_glyph_size, atlas_size )
src_position := Vec2 { glyph.buffer_x, 0 }
src_size := (bounds_size_scaled + atlas.glyph_padding) * glyph_buffer.over_sample
src_size.x = ceil(src_size.x)
src_size.x = src_size.x
src_size.y = max(src_size.y, ceil(src_size.y) * glyph_buffer.snap_glyph_height) // Note(Ed): Seems to improve hinting
to_target_space( & src_position, & src_size, glyph_buffer_size )

View File

@ -10,9 +10,9 @@ Freetype isn't really supported and its not a high priority.
~~That interface is not exposed from this parser but could be added to parser_init.~~
STB_Truetype:
* Has macros for its allocation unfortuantely.
TODO(Ed): Just keep a local version of stb_truetype and modify it to support a sokol/odin compatible allocator.
Already wanted to do so anyway to evaluate the shape generation implementation.
* Added ability to set the stb_truetype allocator for STBTT_MALLOC and STBTT_FREE.
* Changed procedure signatures to pass the font_info struct by immutable ptr (#by_ptr)
when the C equivalent has their parameter as `const*`.
*/
import "core:c"
@ -27,10 +27,8 @@ Parser_Kind :: enum u32 {
Parser_Font_Info :: struct {
label : string,
kind : Parser_Kind,
using _ : struct #raw_union {
stbtt_info : stbtt.fontinfo,
// freetype_info : freetype.Face
},
stbtt_info : stbtt.fontinfo,
// freetype_info : freetype.Face
data : []byte,
}
@ -61,7 +59,7 @@ Parser_Context :: struct {
parser_stbtt_allocator_proc :: proc(
allocator_data : rawptr,
type : stbtt.gbAllocationType,
type : stbtt.zpl_allocator_type,
size : c.ssize_t,
alignment : c.ssize_t,
old_memory : rawptr,
@ -86,13 +84,13 @@ parser_init :: proc( ctx : ^Parser_Context, kind : Parser_Kind, allocator := con
ctx.kind = kind
ctx.lib_backing = allocator
stbtt_allocator := stbtt.gbAllocator { parser_stbtt_allocator_proc, & ctx.lib_backing }
stbtt_allocator := stbtt.zpl_allocator { parser_stbtt_allocator_proc, & ctx.lib_backing }
stbtt.SetAllocator( stbtt_allocator )
}
parser_reload :: proc( ctx : ^Parser_Context, allocator := context.allocator) {
ctx.lib_backing = allocator
stbtt_allocator := stbtt.gbAllocator { parser_stbtt_allocator_proc, & ctx.lib_backing }
stbtt_allocator := stbtt.zpl_allocator { parser_stbtt_allocator_proc, & ctx.lib_backing }
stbtt.SetAllocator( stbtt_allocator )
}

View File

@ -81,9 +81,6 @@ Context :: struct {
// debug_print : b32,
// debug_print_verbose : b32,
// Will enforce even px_size when drawing.
even_size_only : f32,
// Whether or not to snap positioning to the pixel of the view
// Helps with hinting
snap_to_view_extent : b32,
@ -176,8 +173,8 @@ startup :: proc( ctx : ^Context, parser_kind : Parser_Kind = .STB_TrueType, // N
glyph_draw_params := Init_Glyph_Draw_Params_Default,
shape_cache_params := Init_Shape_Cache_Params_Default,
shaper_params := Init_Shaper_Params_Default,
alpha_sharpen : f32 = 0.35,
px_scalar : f32 = 1.6,
alpha_sharpen : f32 = 0.1,
px_scalar : f32 = 1.4,
zoom_px_interval : i32 = 2,
// Curve quality to use for a font when unspecified,
@ -823,7 +820,7 @@ draw_text_normalized_space :: proc( ctx : ^Context,
zoom : Will affect the scale similar to how the zoom on a canvas would behave.
*/
// @(optimization_mode="favor_size")
draw_shape_view_space :: #force_inline proc( ctx : ^Context,
draw_shape_view_space :: proc( ctx : ^Context,
colour : RGBAN,
view : Vec2,
position : Vec2,
@ -849,10 +846,9 @@ draw_shape_view_space :: #force_inline proc( ctx : ^Context,
resolved_size, zoom_scale := resolve_zoom_size_scale( zoom, px_size, scale, ctx.zoom_px_interval, 2, 999.0, view )
target_position, norm_scale := get_normalized_position_scale( position, zoom_scale, view )
// Does nothing if px_scalar is 1.0
target_px_size := resolved_size * ctx.px_scalar
target_scale := norm_scale * px_scalar_quotient
target_font_scale := parser_scale( entry.parser_info, target_px_size )
target_px_size,
target_font_scale,
target_scale := resolve_px_scalar_size(entry.parser_info, resolved_size, ctx.px_scalar, norm_scale)
ctx.cursor_pos = generate_shape_draw_list( & ctx.draw_list, shape, & ctx.atlas, & ctx.glyph_buffer,
ctx.px_scalar,
@ -918,10 +914,9 @@ draw_text_view_space :: proc(ctx : ^Context,
resolved_size, zoom_scale := resolve_zoom_size_scale( zoom, px_size, scale, ctx.zoom_px_interval, 2, 999.0, view )
target_position, norm_scale := get_normalized_position_scale( position, zoom_scale, view )
// Does nothing if px_scalar is 1.0
target_px_size := resolved_size * ctx.px_scalar
target_scale := norm_scale * (1 / ctx.px_scalar)
target_font_scale := parser_scale( entry.parser_info, target_px_size )
target_px_size,
target_font_scale,
target_scale := resolve_px_scalar_size(entry.parser_info, resolved_size, ctx.px_scalar, norm_scale)
shape := shaper_shape_text_cached( text_utf8, & ctx.shaper_ctx, & ctx.shape_cache, ctx.atlas, vec2(ctx.glyph_buffer.size),
font,
@ -1002,11 +997,9 @@ draw_shape :: proc( ctx : ^Context, position, scale : Vec2, shape : Shaped_Text
absolute_scale := peek(stack.scale) * zoom_scale
target_position, norm_scale := get_normalized_position_scale( absolute_position, absolute_scale, view )
// Does nothing when px_scalar is 1.0
target_px_size := resolved_size * ctx.px_scalar
target_scale := norm_scale * px_scalar_quotient
target_font_scale := parser_scale( entry.parser_info, target_px_size )
target_px_size,
target_font_scale,
target_scale := resolve_px_scalar_size(entry.parser_info,resolved_size, ctx.px_scalar, norm_scale)
ctx.cursor_pos = generate_shape_draw_list( & ctx.draw_list, shape, & ctx.atlas, & ctx.glyph_buffer,
ctx.px_scalar,
@ -1082,11 +1075,9 @@ draw_text :: proc( ctx : ^Context, position, scale : Vec2, text_utf8 : string,
absolute_scale := peek(stack.scale) * scale
target_position, norm_scale := get_normalized_position_scale( absolute_position, absolute_scale, view )
// Does nothing when px_scalar is 1.0
target_px_size := resolved_size * ctx.px_scalar
target_scale := norm_scale * (1 / ctx.px_scalar)
target_font_scale := parser_scale( entry.parser_info, target_px_size )
target_px_size,
target_font_scale,
target_scale := resolve_px_scalar_size(entry.parser_info, resolved_size, ctx.px_scalar, norm_scale)
shape := shaper_shape_text_cached( text_utf8, & ctx.shaper_ctx, & ctx.shape_cache, ctx.atlas, vec2(ctx.glyph_buffer.size),
font,
@ -1150,7 +1141,8 @@ measure_shape_size :: #force_inline proc( ctx : Context, shape : Shaped_Text ) -
}
// Don't use this if you already have the shape instead use measure_shape_size
measure_text_size :: #force_inline proc( ctx : ^Context, font : Font_ID, px_size : f32, text_utf8 : string,
@(optimization_mode="favor_size")
measure_text_size :: proc( ctx : ^Context, font : Font_ID, px_size : f32, text_utf8 : string,
shaper_proc : $Shaper_Shape_Text_Uncached_Proc = shaper_shape_harfbuzz
) -> (measured : Vec2)
{
@ -1241,9 +1233,12 @@ resolve_zoom_size_scale :: #force_inline proc "contextless" (
return
}
// Get the target pixel, font_scale, and scale for the given font pixel size, and scalar multiple to apply. (Normalized space with norm_scale)
// To derived norm_scale use: get_normalized_position_scale or just do (scale * (1 / view))
resolve_px_scalar_size :: #force_inline proc "contextless" ( parser_info : Parser_Font_Info, px_size, px_scalar : f32, norm_scale : Vec2
) -> (target_px_size, target_font_scale : f32, target_scale : Vec2 )
{
// Does nothing when px_scalar is 1.0
target_px_size = px_size * px_scalar
target_scale = norm_scale * (1 / px_scalar)
target_font_scale = parser_scale( parser_info, target_px_size )
@ -1276,7 +1271,7 @@ set_snap_glyph_render_height :: #force_inline proc( ctx : ^Context, should_snap
ctx.glyph_buffer.snap_glyph_height = cast(f32) i32(should_snap)
}
//#endregion("misc")
//#endregion("miscellaneous")
//#region("scope stack")

View File

@ -1,10 +1,11 @@
/*
Odin's virtual arena allocator doesn't do what I ideally want for allocation resizing.
(It was also a nice exercise along with making the other allocators)
~~Odin's virtual arena allocator doesn't do what I ideally want for allocation resizing.~~
It was also a nice exercise along with making the other allocators)
So this is a virtual memory backed arena allocator designed
to take advantage of one large contigous reserve of memory.
With the expectation that resizes with its interface will only occur using the last allocated block.
Note(Ed): Odin's mem allocator now has that feature
All virtual address space memory for this application is managed by a virtual arena.
No other part of the program will directly touch the vitual memory interface direclty other than it.

View File

@ -90,6 +90,7 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
push( policy_ptr, SlabSizeClass { 64 * Megabyte, 64 * Megabyte, alignment })
push( policy_ptr, SlabSizeClass { 128 * Megabyte, 128 * Megabyte, alignment })
push( policy_ptr, SlabSizeClass { 256 * Megabyte, 256 * Megabyte, alignment })
push( policy_ptr, SlabSizeClass { 512 * Megabyte, 512 * Megabyte, alignment })
// Anything above 128 meg needs to have its own setup looked into.
alloc_error : AllocatorError
@ -355,19 +356,21 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem
// }
// Setup workspace UI state
ui_startup( & workspace.ui, cache_table_size = 8 * Kilo, cache_allocator = persistent_slab_allocator() )
ui_startup( & workspace.ui, cache_table_size = 64 * Kilo, cache_allocator = persistent_slab_allocator() )
}
// debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/Lorem Ipsum (197).txt", allocator = persistent_slab_allocator())
// debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/Lorem Ipsum (1022).txt", allocator = persistent_slab_allocator())
// debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/ve_fontcache.h", allocator = persistent_slab_allocator())
debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/sokol_gp.h", allocator = persistent_slab_allocator())
// debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/sokol_gp.h", allocator = persistent_slab_allocator())
// debug.path_lorem = str_fmt("C:/projects/SectrPrototype/examples/sokol_gl.h", allocator = persistent_slab_allocator())
debug.path_lorem = str_fmt("C:\\projects\\SectrPrototype\\examples\\gencpp_singleheader.hpp", allocator = persistent_slab_allocator())
alloc_error : AllocatorError; success : bool
debug.lorem_content, success = os.read_entire_file( debug.path_lorem, persistent_slab_allocator() )
debug.lorem_content, success = os.read_entire_file( debug.path_lorem, persistent_allocator() )
assert(success)
debug.lorem_parse, alloc_error = pws_parser_parse( transmute(string) debug.lorem_content, persistent_slab_allocator() )
debug.lorem_parse, alloc_error = pws_parser_parse( transmute(string) debug.lorem_content, persistent_allocator() )
verify( alloc_error == .None, "Faield to parse due to allocation failure" )
// Render texture test

View File

@ -67,14 +67,14 @@ font_provider_setup_sokol_gfx_objects :: proc( ctx : ^VE_RenderData, ve_ctx : ve
screen_shader = sokol_gfx.make_shader(ve_draw_text_shader_desc(backend) )
draw_list_vbuf = sokol_gfx.make_buffer( BufferDesciption {
size = size_of([4]f32) * 2 * Mega,
size = size_of([4]f32) * 4 * Mega,
usage = BufferUsage.STREAM,
type = BufferType.VERTEXBUFFER,
})
verify( sokol_gfx.query_buffer_state( draw_list_vbuf) < ResourceState.FAILED, "Failed to make draw_list_vbuf" )
draw_list_ibuf = sokol_gfx.make_buffer( BufferDesciption {
size = size_of(u32) * 3 * Mega,
size = size_of(u32) * 6 * Mega,
usage = BufferUsage.STREAM,
type = BufferType.INDEXBUFFER,
})

View File

@ -190,13 +190,13 @@ test_whitespace_ast :: proc( default_layout : ^UI_Layout, frame_style_default :
// index := 0
widgets : Array(UI_Widget)
// widgets, alloc_error = array_init_reserve( UI_Widget, frame_slab_allocator(), 8 )
widgets, alloc_error = make( Array(UI_Widget), 8 * Kilobyte )
widgets, alloc_error = make( Array(UI_Widget), 64 * Kilobyte )
widgets_ptr := & widgets
label_id := 0
builder : StringBuilder
str.builder_init_len_cap( & builder, len = 0, cap = 16 * Kilobyte )
str.builder_init_len_cap( & builder, len = 0, cap = 64 * Kilobyte )
line_id := 0
for line in array_to_slice( debug.lorem_parse.lines )

File diff suppressed because it is too large Load Diff

View File

@ -208,9 +208,9 @@ push-location $path_root
# $build_args += $flag_micro_architecture_native
$build_args += $flag_use_separate_modules
$build_args += $flag_thread_count + $CoreCount_Physical
$build_args += $flag_optimize_none
# $build_args += $flag_optimize_none
# $build_args += $flag_optimize_minimal
# $build_args += $flag_optimize_speed
$build_args += $flag_optimize_speed
# $build_args += $falg_optimize_aggressive
$build_args += $flag_debug
$build_args += $flag_pdb_name + $pdb

Binary file not shown.

View File

@ -6,55 +6,22 @@ else
all: unix
endif
$(info Current OS is: $(OS))
wasm:
mkdir -p ../lib
$(CC) -c -Os --target=wasm32 --sysroot=$(shell odin root)/vendor/libc stb_image.c -o ../lib/stb_image_wasm.o -DSTBI_NO_STDIO
$(CC) -c -Os --target=wasm32 --sysroot=$(shell odin root)/vendor/libc stb_image_write.c -o ../lib/stb_image_write_wasm.o -DSTBI_WRITE_NO_STDIO
$(CC) -c -Os --target=wasm32 --sysroot=$(shell odin root)/vendor/libc stb_image_resize.c -o ../lib/stb_image_resize_wasm.o
$(CC) -c -Os --target=wasm32 --sysroot=$(shell odin root)/vendor/libc stb_truetype.c -o ../lib/stb_truetype_wasm.o
# $(CC) -c -Os --target=wasm32 --sysroot=$(shell odin root)/vendor/libc stb_vorbis.c -o ../lib/stb_vorbis_wasm.o -DSTB_VORBIS_NO_STDIO
$(CC) -c -Os --target=wasm32 --sysroot=$(shell odin root)/vendor/libc stb_rect_pack.c -o ../lib/stb_rect_pack_wasm.o
$(CC) -c -Os --target=wasm32 stb_sprintf.c -o ../lib/stb_sprintf_wasm.o
unix:
mkdir -p ../lib
$(CC) -c -O2 -Os -fPIC stb_image.c stb_image_write.c stb_image_resize.c stb_truetype.c stb_rect_pack.c stb_vorbis.c stb_sprintf.c
$(AR) rcs ../lib/stb_image.a stb_image.o
$(AR) rcs ../lib/stb_image_write.a stb_image_write.o
$(AR) rcs ../lib/stb_image_resize.a stb_image_resize.o
$(CC) -c -O2 -Os -fPIC stb_truetype.c
$(AR) rcs ../lib/stb_truetype.a stb_truetype.o
$(AR) rcs ../lib/stb_rect_pack.a stb_rect_pack.o
$(AR) rcs ../lib/stb_vorbis.a stb_vorbis.o
$(AR) rcs ../lib/stb_sprintf.a stb_sprintf.o
#$(CC) -fPIC -shared -Wl,-soname=stb_image.so -o ../lib/stb_image.so stb_image.o
#$(CC) -fPIC -shared -Wl,-soname=stb_image_write.so -o ../lib/stb_image_write.so stb_image_write.o
#$(CC) -fPIC -shared -Wl,-soname=stb_image_resize.so -o ../lib/stb_image_resize.so stb_image_resize.o
#$(CC) -fPIC -shared -Wl,-soname=stb_truetype.so -o ../lib/stb_truetype.so stb_image_truetype.o
#$(CC) -fPIC -shared -Wl,-soname=stb_rect_pack.so -o ../lib/stb_rect_pack.so stb_rect_packl.o
#$(CC) -fPIC -shared -Wl,-soname=stb_vorbis.so -o ../lib/stb_vorbis.so stb_vorbisl.o
rm *.o
darwin:
mkdir -p ../lib
$(CC) -arch x86_64 -c -O2 -Os -fPIC stb_image.c -o stb_image-x86_64.o -mmacosx-version-min=10.12
$(CC) -arch arm64 -c -O2 -Os -fPIC stb_image.c -o stb_image-arm64.o -mmacosx-version-min=10.12
lipo -create stb_image-x86_64.o stb_image-arm64.o -output ../lib/darwin/stb_image.a
$(CC) -arch x86_64 -c -O2 -Os -fPIC stb_image_write.c -o stb_image_write-x86_64.o -mmacosx-version-min=10.12
$(CC) -arch arm64 -c -O2 -Os -fPIC stb_image_write.c -o stb_image_write-arm64.o -mmacosx-version-min=10.12
lipo -create stb_image_write-x86_64.o stb_image_write-arm64.o -output ../lib/darwin/stb_image_write.a
$(CC) -arch x86_64 -c -O2 -Os -fPIC stb_image_resize.c -o stb_image_resize-x86_64.o -mmacosx-version-min=10.12
$(CC) -arch arm64 -c -O2 -Os -fPIC stb_image_resize.c -o stb_image_resize-arm64.o -mmacosx-version-min=10.12
lipo -create stb_image_resize-x86_64.o stb_image_resize-arm64.o -output ../lib/darwin/stb_image_resize.a
$(CC) -arch x86_64 -c -O2 -Os -fPIC stb_truetype.c -o stb_truetype-x86_64.o -mmacosx-version-min=10.12
$(CC) -arch arm64 -c -O2 -Os -fPIC stb_truetype.c -o stb_truetype-arm64.o -mmacosx-version-min=10.12
lipo -create stb_truetype-x86_64.o stb_truetype-arm64.o -output ../lib/darwin/stb_truetype.a
$(CC) -arch x86_64 -c -O2 -Os -fPIC stb_rect_pack.c -o stb_rect_pack-x86_64.o -mmacosx-version-min=10.12
$(CC) -arch arm64 -c -O2 -Os -fPIC stb_rect_pack.c -o stb_rect_pack-arm64.o -mmacosx-version-min=10.12
lipo -create stb_rect_pack-x86_64.o stb_rect_pack-arm64.o -output ../lib/darwin/stb_rect_pack.a
$(CC) -arch x86_64 -c -O2 -Os -fPIC stb_vorbis.c -o stb_vorbis-x86_64.o -mmacosx-version-min=10.12
$(CC) -arch arm64 -c -O2 -Os -fPIC stb_vorbis.c -o stb_vorbis-arm64.o -mmacosx-version-min=10.12
lipo -create stb_vorbis-x86_64.o stb_vorbis-arm64.o -output ../lib/darwin/stb_vorbis.a
$(CC) -arch x86_64 -c -O2 -Os -fPIC stb_sprintf.c -o stb_sprintf-x86_64.o -mmacosx-version-min=10.12
$(CC) -arch arm64 -c -O2 -Os -fPIC stb_sprintf.c -o stb_sprintf-arm64.o -mmacosx-version-min=10.12
lipo -create stb_sprintf-x86_64.o stb_sprintf-arm64.o -output ../lib/darwin/stb_sprintf.a
rm *.o

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +0,0 @@
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

File diff suppressed because it is too large Load Diff

View File

@ -415,9 +415,9 @@ int main(int arg, char **argv)
#pragma region ODIN: CUSTOM ALLOCATOR
#ifdef STB_TRUETYPE_IMPLEMENTATION
#define GB_IMPLEMENTATION
#define ZPL_IMPLEMENTATION
#endif
#include "gb/gb.h"
#include "zpl/zpl.h"
#ifdef STBTT_STATIC
#define STBTT_DEF static
@ -429,21 +429,21 @@ int main(int arg, char **argv)
extern "C" {
#endif
STBTT_DEF void stbtt_SetAllocator( gbAllocator allocator );
STBTT_DEF void stbtt_SetAllocator( zpl_allocator allocator );
#ifdef __cplusplus
}
#endif
#ifndef STBTT_malloc
#define STBTT_malloc(x,u) ((void)(u), gb_alloc(stbtt__allocator, x))
#define STBTT_free(x,u) ((void)(u), gb_free(stbtt__allocator, x))
#define STBTT_malloc(x,u) ((void)(u), zpl_alloc(stbtt__allocator, x))
#define STBTT_free(x,u) ((void)(u), zpl_free(stbtt__allocator, x))
#endif
#ifdef STB_TRUETYPE_IMPLEMENTATION
gb_global gbAllocator stbtt__allocator = { gb_heap_allocator_proc, NULL };
zpl_global zpl_allocator stbtt__allocator = { zpl_heap_allocator_proc, NULL };
STBTT_DEF void stbtt_SetAllocator( gbAllocator allocator ) {
STBTT_DEF void stbtt_SetAllocator( zpl_allocator allocator ) {
stbtt__allocator = allocator;
}
#endif

View File

@ -40,27 +40,27 @@ when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
// CUSTOM: ODIN COMPATIBLE ALLOCATOR
//-----------------------------------------------------------------------------
gbAllocationType :: enum(i32) {
zpl_allocator_type :: enum(i32) {
Alloc,
Free,
FreeAll,
Resize,
}
gbAllocatorProc :: #type proc(allocator_data: rawptr, type: gbAllocationType,
zpl_allocator_proc :: #type proc(allocator_data: rawptr, type: zpl_allocator_type,
size: c.ssize_t, alignment: c.ssize_t,
old_memory: rawptr, old_size: c.ssize_t,
flags : c.ulonglong
) -> rawptr
gbAllocator :: struct {
procedure: gbAllocatorProc,
zpl_allocator :: struct {
procedure: zpl_allocator_proc,
data: rawptr,
}
@(default_calling_convention="c", link_prefix="stbtt_")
foreign stbtt {
SetAllocator :: proc(allocator : gbAllocator) ---
SetAllocator :: proc(allocator : zpl_allocator) ---
}
//-----------------------------------------------------------------------------