glyph cache progress
This commit is contained in:
parent
ad359c8495
commit
e9e8dcc04d
@ -94,20 +94,15 @@ void *PushBytesNoZero(Arena *arena, u64 size, u64 align)
|
|||||||
{
|
{
|
||||||
Assert(align > 0);
|
Assert(align > 0);
|
||||||
|
|
||||||
void *result = 0;
|
|
||||||
u8 *base = ArenaFirst(arena, u8);
|
u8 *base = ArenaFirst(arena, u8);
|
||||||
|
|
||||||
/* Check to avoid aligning when size = 0 */
|
u64 start_pos = AlignU64(arena->pos, align);
|
||||||
if (size > 0)
|
u64 end_pos = start_pos + size;
|
||||||
{
|
|
||||||
u64 aligned_start_pos = (arena->pos + (align - 1));
|
|
||||||
aligned_start_pos -= aligned_start_pos % align;
|
|
||||||
|
|
||||||
u64 new_pos = aligned_start_pos + size;
|
|
||||||
if (new_pos > arena->committed)
|
|
||||||
{
|
|
||||||
/* Commit new block(s) */
|
/* Commit new block(s) */
|
||||||
u64 blocks_needed = (new_pos - arena->committed + ArenaBlockSize - 1) / ArenaBlockSize;
|
if (end_pos > arena->committed)
|
||||||
|
{
|
||||||
|
u64 blocks_needed = (end_pos - arena->committed + ArenaBlockSize - 1) / ArenaBlockSize;
|
||||||
u64 commit_bytes = blocks_needed * ArenaBlockSize;
|
u64 commit_bytes = blocks_needed * ArenaBlockSize;
|
||||||
u64 new_capacity = arena->committed + commit_bytes;
|
u64 new_capacity = arena->committed + commit_bytes;
|
||||||
if (new_capacity > arena->reserved)
|
if (new_capacity > arena->reserved)
|
||||||
@ -126,14 +121,9 @@ void *PushBytesNoZero(Arena *arena, u64 size, u64 align)
|
|||||||
AsanPoison(commit_address, commit_bytes);
|
AsanPoison(commit_address, commit_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = base + aligned_start_pos;
|
void *result = base + start_pos;
|
||||||
AsanUnpoison(result, new_pos - aligned_start_pos);
|
AsanUnpoison(result, end_pos - start_pos);
|
||||||
arena->pos = new_pos;
|
arena->pos = end_pos;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = base + arena->pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -147,28 +137,8 @@ void *PushBytes(Arena *arena, u64 size, u64 align)
|
|||||||
|
|
||||||
void *PushAlign(Arena *arena, u64 align)
|
void *PushAlign(Arena *arena, u64 align)
|
||||||
{
|
{
|
||||||
void *result = 0;
|
u64 push_count = AlignU64(arena->pos, align) - arena->pos;
|
||||||
if (align > 0)
|
return PushStructsNoZero(arena, u8, push_count);
|
||||||
{
|
|
||||||
u64 aligned_start_pos = (arena->pos + (align - 1));
|
|
||||||
aligned_start_pos -= aligned_start_pos % align;
|
|
||||||
u64 align_bytes = aligned_start_pos - (u64)arena->pos;
|
|
||||||
if (align_bytes > 0)
|
|
||||||
{
|
|
||||||
result = (void *)PushStructsNoZero(arena, u8, align_bytes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = (void *)(ArenaFirst(arena, u8) + arena->pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 0 alignment */
|
|
||||||
Assert(0);
|
|
||||||
result = (void *)(ArenaFirst(arena, u8) + arena->pos);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PopTo(Arena *arena, u64 pos)
|
void PopTo(Arena *arena, u64 pos)
|
||||||
@ -198,17 +168,13 @@ void PopBytes(Arena *arena, u64 size, void *copy_dst)
|
|||||||
|
|
||||||
void *ArenaFirst_(Arena *arena, u64 align)
|
void *ArenaFirst_(Arena *arena, u64 align)
|
||||||
{
|
{
|
||||||
u64 aligned_start_pos = align - 1;
|
void *result = (void *)AlignU64((u64)arena + ArenaHeaderSize, align);
|
||||||
aligned_start_pos -= aligned_start_pos % align;
|
|
||||||
void *result = ((u8 *)arena + ArenaHeaderSize) + aligned_start_pos;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ArenaNext_(Arena *arena, u64 align)
|
void *ArenaNext_(Arena *arena, u64 align)
|
||||||
{
|
{
|
||||||
u64 aligned_start_pos = (arena->pos + (align - 1));
|
void *result = (void *)AlignU64((u64)arena + ArenaHeaderSize + arena->pos, align);
|
||||||
aligned_start_pos -= aligned_start_pos % align;
|
|
||||||
void *result = ((u8 *)arena + ArenaHeaderSize) + aligned_start_pos;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +199,7 @@ void EndTempArena(TempArena temp)
|
|||||||
|
|
||||||
TempArena BeginScratch(Arena *potential_conflict)
|
TempArena BeginScratch(Arena *potential_conflict)
|
||||||
{
|
{
|
||||||
/* This function is currently hard-coded to search through 2 scratch arenas */
|
/* This function is currently hard-coded for 2 thread-local scratch arenas */
|
||||||
StaticAssert(ScratchArenasPerCtx == 2);
|
StaticAssert(ScratchArenasPerCtx == 2);
|
||||||
|
|
||||||
/* Use `BeginScratchNoConflict` if no conflicts are present */
|
/* Use `BeginScratchNoConflict` if no conflicts are present */
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/* TODO: Elminiate meta arena. Just store levels in first 4096 bytes of buddy arena, and then zone header data at the beginning of each allocation. */
|
/* TODO: Elminiate meta arena. Just store levels in first 4096 bytes of buddy arena, and then zone header data at the beginning of each allocation. */
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Buddy ctx
|
//~ Buddy context
|
||||||
|
|
||||||
BuddyCtx *AcquireBuddyCtx(u64 reserve)
|
BuddyCtx *AcquireBuddyCtx(u64 reserve)
|
||||||
{
|
{
|
||||||
@ -31,105 +31,7 @@ void ReleaseBuddyCtx(BuddyCtx *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Block acquire / release
|
//~ Buddy block
|
||||||
|
|
||||||
BuddyBlock *AcquireBuddyBlock(BuddyCtx *ctx, u64 size)
|
|
||||||
{
|
|
||||||
if (size > 0x00FFFFFFFFFFFFFFULL)
|
|
||||||
{
|
|
||||||
/* TODO: Error */
|
|
||||||
Assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Minimum block size */
|
|
||||||
|
|
||||||
/* TODO: Faster MSB calculation */
|
|
||||||
|
|
||||||
u64 desired_block_size = 1;
|
|
||||||
u64 desired_level_tier = 0;
|
|
||||||
while (desired_block_size < size && desired_level_tier < 64)
|
|
||||||
{
|
|
||||||
desired_block_size <<= 1;
|
|
||||||
++desired_level_tier;
|
|
||||||
}
|
|
||||||
|
|
||||||
BuddyBlock *block = GetUnusedBuddyBlock(ctx, &ctx->levels[desired_level_tier]);
|
|
||||||
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReleaseBuddyBlock(BuddyBlock *block)
|
|
||||||
{
|
|
||||||
block->is_used = 0;
|
|
||||||
BuddyLevel *level = block->level;
|
|
||||||
BuddyBlock *parent = block->parent;
|
|
||||||
BuddyBlock *sibling = block->sibling;
|
|
||||||
if (!sibling->is_used && parent != 0)
|
|
||||||
{
|
|
||||||
/* Merge siblings */
|
|
||||||
BuddyCtx *ctx = level->ctx;
|
|
||||||
PopBuddyBlock(ctx, level, block);
|
|
||||||
PopBuddyBlock(ctx, level, sibling);
|
|
||||||
/* Release parent */
|
|
||||||
ReleaseBuddyBlock(parent);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (level->first_unused_block)
|
|
||||||
{
|
|
||||||
block->next = level->first_unused_block;
|
|
||||||
level->first_unused_block->prev = block;
|
|
||||||
}
|
|
||||||
level->first_unused_block = block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Block push / pop
|
|
||||||
|
|
||||||
//- Push
|
|
||||||
BuddyBlock *PushBuddyBlock(BuddyCtx *ctx)
|
|
||||||
{
|
|
||||||
BuddyBlock *block;
|
|
||||||
if (ctx->first_free_block)
|
|
||||||
{
|
|
||||||
block = ctx->first_free_block;
|
|
||||||
ctx->first_free_block = block->next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
block = PushStructNoZero(ctx->meta_arena, BuddyBlock);
|
|
||||||
}
|
|
||||||
ZeroStruct(block);
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Pop
|
|
||||||
void PopBuddyBlock(BuddyCtx *ctx, BuddyLevel *level, BuddyBlock *block)
|
|
||||||
{
|
|
||||||
/* Remove from unused list */
|
|
||||||
{
|
|
||||||
BuddyBlock *prev = block->prev;
|
|
||||||
BuddyBlock *next = block->next;
|
|
||||||
if (prev)
|
|
||||||
{
|
|
||||||
prev->next = next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
level->first_unused_block = next;
|
|
||||||
}
|
|
||||||
if (next)
|
|
||||||
{
|
|
||||||
next->prev = prev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
block->next = ctx->first_free_block;
|
|
||||||
ctx->first_free_block = block;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Get unused block
|
|
||||||
|
|
||||||
BuddyBlock *GetUnusedBuddyBlock(BuddyCtx *ctx, BuddyLevel *level)
|
BuddyBlock *GetUnusedBuddyBlock(BuddyCtx *ctx, BuddyLevel *level)
|
||||||
{
|
{
|
||||||
@ -212,3 +114,93 @@ BuddyBlock *GetUnusedBuddyBlock(BuddyCtx *ctx, BuddyLevel *level)
|
|||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BuddyBlock *PushBuddyBlock(BuddyCtx *ctx)
|
||||||
|
{
|
||||||
|
BuddyBlock *block;
|
||||||
|
if (ctx->first_free_block)
|
||||||
|
{
|
||||||
|
block = ctx->first_free_block;
|
||||||
|
ctx->first_free_block = block->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
block = PushStructNoZero(ctx->meta_arena, BuddyBlock);
|
||||||
|
}
|
||||||
|
ZeroStruct(block);
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopBuddyBlock(BuddyCtx *ctx, BuddyLevel *level, BuddyBlock *block)
|
||||||
|
{
|
||||||
|
/* Remove from unused list */
|
||||||
|
{
|
||||||
|
BuddyBlock *prev = block->prev;
|
||||||
|
BuddyBlock *next = block->next;
|
||||||
|
if (prev)
|
||||||
|
{
|
||||||
|
prev->next = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
level->first_unused_block = next;
|
||||||
|
}
|
||||||
|
if (next)
|
||||||
|
{
|
||||||
|
next->prev = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
block->next = ctx->first_free_block;
|
||||||
|
ctx->first_free_block = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
BuddyBlock *AcquireBuddyBlock(BuddyCtx *ctx, u64 size)
|
||||||
|
{
|
||||||
|
if (size > 0x00FFFFFFFFFFFFFFULL)
|
||||||
|
{
|
||||||
|
/* TODO: Error */
|
||||||
|
Assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Minimum block size */
|
||||||
|
|
||||||
|
/* TODO: Faster MSB calculation */
|
||||||
|
|
||||||
|
u64 desired_block_size = 1;
|
||||||
|
u64 desired_level_tier = 0;
|
||||||
|
while (desired_block_size < size && desired_level_tier < 64)
|
||||||
|
{
|
||||||
|
desired_block_size <<= 1;
|
||||||
|
++desired_level_tier;
|
||||||
|
}
|
||||||
|
|
||||||
|
BuddyBlock *block = GetUnusedBuddyBlock(ctx, &ctx->levels[desired_level_tier]);
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReleaseBuddyBlock(BuddyBlock *block)
|
||||||
|
{
|
||||||
|
block->is_used = 0;
|
||||||
|
BuddyLevel *level = block->level;
|
||||||
|
BuddyBlock *parent = block->parent;
|
||||||
|
BuddyBlock *sibling = block->sibling;
|
||||||
|
if (!sibling->is_used && parent != 0)
|
||||||
|
{
|
||||||
|
/* Merge siblings */
|
||||||
|
BuddyCtx *ctx = level->ctx;
|
||||||
|
PopBuddyBlock(ctx, level, block);
|
||||||
|
PopBuddyBlock(ctx, level, sibling);
|
||||||
|
/* Release parent */
|
||||||
|
ReleaseBuddyBlock(parent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (level->first_unused_block)
|
||||||
|
{
|
||||||
|
block->next = level->first_unused_block;
|
||||||
|
level->first_unused_block->prev = block;
|
||||||
|
}
|
||||||
|
level->first_unused_block = block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -44,13 +44,13 @@ void ReleaseBuddyCtx(BuddyCtx *ctx);
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Buddy block
|
//~ Buddy block
|
||||||
|
|
||||||
//- Acquire / release
|
//- Get unused
|
||||||
BuddyBlock *AcquireBuddyBlock(BuddyCtx *ctx, u64 size);
|
BuddyBlock *GetUnusedBuddyBlock(BuddyCtx *ctx, BuddyLevel *level);
|
||||||
void ReleaseBuddyBlock(BuddyBlock *block);
|
|
||||||
|
|
||||||
//- Push / pop
|
//- Push / pop
|
||||||
BuddyBlock *PushBuddyBlock(BuddyCtx *ctx);
|
BuddyBlock *PushBuddyBlock(BuddyCtx *ctx);
|
||||||
void PopBuddyBlock(BuddyCtx *ctx, BuddyLevel *level, BuddyBlock *block);
|
void PopBuddyBlock(BuddyCtx *ctx, BuddyLevel *level, BuddyBlock *block);
|
||||||
|
|
||||||
//- Get unused
|
//- Acquire / release
|
||||||
BuddyBlock *GetUnusedBuddyBlock(BuddyCtx *ctx, BuddyLevel *level);
|
BuddyBlock *AcquireBuddyBlock(BuddyCtx *ctx, u64 size);
|
||||||
|
void ReleaseBuddyBlock(BuddyBlock *block);
|
||||||
|
|||||||
@ -1148,6 +1148,43 @@ u32 U32FromVec4(Vec4 v)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Range
|
||||||
|
|
||||||
|
Vec2 DimsFromRng2(Rng2 r)
|
||||||
|
{
|
||||||
|
Vec2 result = ZI;
|
||||||
|
result.x = r.p1.x - r.p0.x;
|
||||||
|
result.y = r.p1.y - r.p0.y;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rng2 UnionRng2(Rng2 a, Rng2 b)
|
||||||
|
{
|
||||||
|
Rng2 result = ZI;
|
||||||
|
result.p0.x = MinF32(a.p0.x, b.p0.x);
|
||||||
|
result.p0.y = MinF32(a.p0.y, b.p0.y);
|
||||||
|
result.p1.x = MaxF32(a.p1.x, b.p1.x);
|
||||||
|
result.p1.y = MaxF32(a.p1.y, b.p1.y);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rng2 AddRng2Vec2(Rng2 r, Vec2 v)
|
||||||
|
{
|
||||||
|
Rng2 result = ZI;
|
||||||
|
result.p0 = AddVec2(result.p0, v);
|
||||||
|
result.p1 = AddVec2(result.p1, v);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rng2 DivRng2Vec2(Rng2 r, Vec2 v)
|
||||||
|
{
|
||||||
|
Rng2 result = ZI;
|
||||||
|
result.p0 = DivVec2Vec2(result.p0, v);
|
||||||
|
result.p1 = DivVec2Vec2(result.p1, v);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Xform
|
//~ Xform
|
||||||
|
|
||||||
|
|||||||
@ -385,6 +385,15 @@ Vec2I32 SubVec2I32(Vec2I32 a, Vec2I32 b);
|
|||||||
Vec4 Vec4FromU32(u32 v);
|
Vec4 Vec4FromU32(u32 v);
|
||||||
u32 U32FromVec4(Vec4 v);
|
u32 U32FromVec4(Vec4 v);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Range
|
||||||
|
|
||||||
|
Vec2 DimsFromRng2(Rng2 r);
|
||||||
|
Rng2 UnionRng2(Rng2 a, Rng2 b);
|
||||||
|
|
||||||
|
Rng2 AddRng2Vec2(Rng2 r, Vec2 v);
|
||||||
|
Rng2 DivRng2Vec2(Rng2 a, Vec2 v);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Xform
|
//~ Xform
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Math types
|
//~ Base math types
|
||||||
|
|
||||||
#define Pi ((f32)3.14159265358979323846)
|
#define Pi ((f32)3.14159265358979323846)
|
||||||
#define Tau ((f32)6.28318530717958647693)
|
#define Tau ((f32)6.28318530717958647693)
|
||||||
@ -21,6 +21,21 @@ typedef float4 Aabb;
|
|||||||
typedef float4 Quad;
|
typedef float4 Quad;
|
||||||
typedef float4x4 Mat4x4;
|
typedef float4x4 Mat4x4;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Range types
|
||||||
|
|
||||||
|
Struct(Rng) { f32 min; f32 max; };
|
||||||
|
Struct(RngI32) { i32 min; i32 max; };
|
||||||
|
Struct(RngU32) { u32 min; u32 max; };
|
||||||
|
|
||||||
|
Struct(Rng2) { Vec2 p0; Vec2 p1; };
|
||||||
|
Struct(Rng2I32) { Vec2I32 p0; Vec2I32 p1; };
|
||||||
|
Struct(Rng2U32) { Vec2U32 p0; Vec2U32 p1; };
|
||||||
|
|
||||||
|
Struct(Rng3) { Vec3 p0; Vec3 p1; };
|
||||||
|
Struct(Rng3I32) { Vec3I32 p0; Vec3I32 p1; };
|
||||||
|
Struct(Rng3U32) { Vec3U32 p0; Vec3U32 p1; };
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Countof
|
//~ Countof
|
||||||
|
|
||||||
|
|||||||
@ -69,7 +69,7 @@
|
|||||||
|
|
||||||
#define FLOOD_DEBUG 0
|
#define FLOOD_DEBUG 0
|
||||||
|
|
||||||
#define GPU_DEBUG 1
|
#define GPU_DEBUG 0
|
||||||
#define GPU_DEBUG_VALIDATION 0
|
#define GPU_DEBUG_VALIDATION 0
|
||||||
|
|
||||||
#define GPU_SHADER_PRINT 1
|
#define GPU_SHADER_PRINT 1
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
/* TODO: Use default font texture handle */
|
GC_State GC = ZI;
|
||||||
Readonly GC_RunRect GC_NilRunRect = {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
Readonly GC_Run GC_NilRun = {
|
////////////////////////////////////////////////////////////
|
||||||
.count = 1,
|
//~ Bootstrap
|
||||||
.rects = &GC_NilRunRect
|
|
||||||
};
|
void GC_BootStrap(void)
|
||||||
|
{
|
||||||
|
// OnAsync(GC_AsyncTick);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Key helpers
|
//~ Key helpers
|
||||||
@ -18,22 +18,119 @@ GC_FontKey GC_FontKeyFromResource(ResourceKey resource)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 GC_HashFromGlyphDesc(GC_GlyphDesc desc)
|
||||||
|
{
|
||||||
|
return RandU64FromSeeds(desc.font.v, ((u64)desc.codepoint << 32) | *(u32 *)&desc.font_size);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Run
|
//~ Run
|
||||||
|
|
||||||
GC_Run *GC_RunFromString(Arena *arena, GC_FontKey key, String str)
|
/* TODO: Thread-local cache */
|
||||||
|
GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size)
|
||||||
{
|
{
|
||||||
/* TODO */
|
GC_Run result = ZI;
|
||||||
GC_Run *result = PushStruct(arena, GC_Run);
|
TempArena scratch = BeginScratch(arena);
|
||||||
|
|
||||||
GC_RunRect *rr = PushStruct(arena, GC_RunRect);
|
String32 codepoints = String32FromString(scratch.arena, str);
|
||||||
rr->advance = 1;
|
|
||||||
result->rects = rr;
|
|
||||||
result->count = 1;
|
|
||||||
|
|
||||||
|
String32 uncached_codepoints = ZI;
|
||||||
|
uncached_codepoints.text = PushStructsNoZero(scratch.arena, u32, codepoints.len);
|
||||||
|
|
||||||
|
u64 ready_glyphs_count = 0;
|
||||||
|
GC_Glyph **ready_glyphs = PushStructsNoZero(scratch.arena, GC_Glyph *, str.len);
|
||||||
|
{
|
||||||
|
if (codepoints.len > 0)
|
||||||
|
{
|
||||||
|
Lock lock = LockS(&GC.glyphs_mutex);
|
||||||
|
for (u64 codepoint_idx = 0; codepoint_idx < codepoints.len; ++codepoint_idx)
|
||||||
|
{
|
||||||
|
u32 codepoint = codepoints.text[codepoint_idx];
|
||||||
|
|
||||||
|
GC_GlyphDesc desc = ZI;
|
||||||
|
desc.font = font;
|
||||||
|
desc.font_size = font_size;
|
||||||
|
desc.codepoint = codepoint;
|
||||||
|
|
||||||
|
u64 hash = GC_HashFromGlyphDesc(desc);
|
||||||
|
GC_GlyphBin *bin = &GC.glyph_bins[hash % countof(GC.glyph_bins)];
|
||||||
|
|
||||||
|
GC_Glyph *glyph = bin->first;
|
||||||
|
for (; glyph; glyph = glyph->next)
|
||||||
|
{
|
||||||
|
if (glyph->hash == hash)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (glyph == 0)
|
||||||
|
{
|
||||||
|
uncached_codepoints.text[uncached_codepoints.len] = codepoint;
|
||||||
|
uncached_codepoints.len += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ready_glyphs[ready_glyphs_count] = glyph;
|
||||||
|
ready_glyphs_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Unlock(&lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f32 baseline_pos = 0;
|
||||||
|
result.rects = PushStructs(arena, GC_RunRect, ready_glyphs_count);
|
||||||
|
result.rects_count = ready_glyphs_count;
|
||||||
|
for (u64 glyph_idx = 0; glyph_idx < ready_glyphs_count; ++glyph_idx)
|
||||||
|
{
|
||||||
|
GC_Glyph *glyph = ready_glyphs[glyph_idx];
|
||||||
|
GC_RunRect *rect = &result.rects[glyph_idx];
|
||||||
|
|
||||||
|
rect->tex = glyph->tex_ref;
|
||||||
|
rect->tex_uv = glyph->tex_uv;
|
||||||
|
rect->tex_rect = glyph->tex_rect;
|
||||||
|
|
||||||
|
rect->baseline_pos = baseline_pos;
|
||||||
|
rect->advance = glyph->advance;
|
||||||
|
|
||||||
|
rect->bounds.p0 = glyph->baseline_offset;
|
||||||
|
rect->bounds.p1 = AddVec2(rect->bounds.p0, DimsFromRng2(glyph->tex_rect));
|
||||||
|
|
||||||
|
if (glyph_idx == 0)
|
||||||
|
{
|
||||||
|
result.bounds = rect->bounds;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.bounds = UnionRng2(result.bounds, rect->bounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
baseline_pos += rect->advance;
|
||||||
|
result.baseline_length = MaxF32(result.baseline_length, baseline_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ready_glyphs_count > 0)
|
||||||
|
{
|
||||||
|
GC_Glyph *glyph = ready_glyphs[0];
|
||||||
|
result.font_size = glyph->font_size;
|
||||||
|
result.font_ascent = glyph->font_ascent;
|
||||||
|
result.font_descent = glyph->font_descent;
|
||||||
|
result.font_cap = glyph->font_cap;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.ready = uncached_codepoints.len == 0;
|
||||||
|
|
||||||
|
EndScratch(scratch);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Async tick
|
||||||
|
|
||||||
|
void GC_AsyncTick(WaveLaneCtx *lane)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,50 +6,102 @@ Struct(GC_FontKey)
|
|||||||
u64 v;
|
u64 v;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Glyph types
|
||||||
|
|
||||||
|
Struct(GC_GlyphDesc)
|
||||||
|
{
|
||||||
|
GC_FontKey font;
|
||||||
|
f32 font_size;
|
||||||
|
u32 codepoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
Struct(GC_Glyph)
|
||||||
|
{
|
||||||
|
GC_Glyph *next;
|
||||||
|
u64 hash;
|
||||||
|
|
||||||
|
/* Layout info */
|
||||||
|
Vec2 baseline_offset;
|
||||||
|
f32 advance;
|
||||||
|
|
||||||
|
/* Atlas info */
|
||||||
|
G_Texture2DRef tex_ref;
|
||||||
|
Rng2 tex_uv;
|
||||||
|
Rng2 tex_rect;
|
||||||
|
|
||||||
|
/* Font info */
|
||||||
|
f32 font_size;
|
||||||
|
f32 font_ascent;
|
||||||
|
f32 font_descent;
|
||||||
|
f32 font_cap;
|
||||||
|
};
|
||||||
|
|
||||||
|
Struct(GC_GlyphBin)
|
||||||
|
{
|
||||||
|
GC_Glyph *first;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Run types
|
//~ Run types
|
||||||
|
|
||||||
Struct(GC_RunRect)
|
Struct(GC_RunRect)
|
||||||
{
|
{
|
||||||
Vec2 offset; /* Vector from baseline offset to top left of glyph rect */
|
Rng2 bounds; /* Visual bounds in relation to the baseline */
|
||||||
f32 pos; /* Horizontal distance from start of baseline */
|
f32 baseline_pos; /* Horizontal distance from start of baseline */
|
||||||
f32 advance;
|
f32 advance;
|
||||||
|
|
||||||
Vec2 size;
|
|
||||||
G_Texture2DRef tex;
|
G_Texture2DRef tex;
|
||||||
Rng2 uv;
|
Rng2 tex_uv;
|
||||||
|
Rng2 tex_rect;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(GC_Run)
|
Struct(GC_Run)
|
||||||
{
|
{
|
||||||
/* Run data */
|
/* Run data */
|
||||||
Vec2 p0; /* Start of baseline to top-left-most rect */
|
Rng2 bounds; /* Visual bounds of the run in relation to the baseline */
|
||||||
Vec2 p1; /* Start of baseline to bottom-right-most rect corner */
|
f32 baseline_length;
|
||||||
u32 count;
|
u64 rects_count;
|
||||||
GC_RunRect *rects;
|
GC_RunRect *rects;
|
||||||
|
|
||||||
/* Font stats */
|
/* Font info */
|
||||||
f32 size;
|
f32 font_size;
|
||||||
f32 ascent;
|
f32 font_ascent;
|
||||||
f32 descent;
|
f32 font_descent;
|
||||||
f32 cap;
|
f32 font_cap;
|
||||||
|
|
||||||
b32 loaded;
|
b32 ready;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Readonly GC_RunRect GC_NilRunRect;
|
////////////////////////////////////////////////////////////
|
||||||
extern Readonly GC_Run GC_NilRun;
|
//~ State
|
||||||
|
|
||||||
|
Struct(GC_State)
|
||||||
|
{
|
||||||
|
Mutex glyphs_mutex;
|
||||||
|
GC_GlyphBin glyph_bins[16384];
|
||||||
|
} extern GC;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Bootstrap
|
||||||
|
|
||||||
|
void GC_Bootstrap(void);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Key helpers
|
//~ Key helpers
|
||||||
|
|
||||||
GC_FontKey GC_FontKeyFromResource(ResourceKey resource);
|
GC_FontKey GC_FontKeyFromResource(ResourceKey resource);
|
||||||
|
u64 GC_HashFromGlyphDesc(GC_GlyphDesc desc);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Run
|
//~ Run
|
||||||
|
|
||||||
GC_Run *GC_RunFromString(Arena *arena, GC_FontKey key, String str);
|
GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Async tick
|
||||||
|
|
||||||
|
void GC_AsyncTick(WaveLaneCtx *lane);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -317,6 +317,7 @@ void G_Bootstrap(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
|||||||
@ -249,7 +249,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
{
|
{
|
||||||
/* TODO: Don't rely on ui report for draw size since it introduces one frame of delay when resizing */
|
/* TODO: Don't rely on ui report for draw size since it introduces one frame of delay when resizing */
|
||||||
UI_Report vis_rep = UI_ReportFromKey(vis_box);
|
UI_Report vis_rep = UI_ReportFromKey(vis_box);
|
||||||
draw_size = Vec2I32FromFields(SubVec2(vis_rep.screen_p1, vis_rep.screen_p0));
|
draw_size = Vec2I32FromVec(DimsFromRng2(vis_rep.screen_rect));
|
||||||
}
|
}
|
||||||
draw_size.x = MaxI32(draw_size.x, 1);
|
draw_size.x = MaxI32(draw_size.x, 1);
|
||||||
draw_size.y = MaxI32(draw_size.y, 1);
|
draw_size.y = MaxI32(draw_size.y, 1);
|
||||||
@ -624,9 +624,11 @@ void V_TickForever(WaveLaneCtx *lane)
|
|||||||
|
|
||||||
G_DumbMemoryLayoutSync(frame->cl, draw_target, G_Layout_DirectQueue_ShaderRead);
|
G_DumbMemoryLayoutSync(frame->cl, draw_target, G_Layout_DirectQueue_ShaderRead);
|
||||||
{
|
{
|
||||||
Vec2 uv0 = DivVec2Vec2(Vec2FromVec(viewport.p0), Vec2FromVec(window_frame.monitor_size));
|
Rng2 uv = ZI;
|
||||||
Vec2 uv1 = DivVec2Vec2(Vec2FromVec(viewport.p1), Vec2FromVec(window_frame.monitor_size));
|
uv.p0 = Vec2FromVec(viewport.p0);
|
||||||
UI_SetRawTexture(vis_box, draw_target_ro, uv0, uv1);
|
uv.p1 = Vec2FromVec(viewport.p1);
|
||||||
|
uv = DivRng2Vec2(uv, Vec2FromVec(window_frame.monitor_size));
|
||||||
|
UI_SetRawTexture(vis_box, draw_target_ro, uv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -53,7 +53,7 @@ PixelShader(V_DQuadPS, V_DQuadPSOutput, V_DQuadPSInput input)
|
|||||||
Vec4 final_color = 0;
|
Vec4 final_color = 0;
|
||||||
|
|
||||||
V_DQuadPSOutput output;
|
V_DQuadPSOutput output;
|
||||||
output.SV_Target0 = final_color;
|
output.sv_target0 = final_color;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +85,6 @@ VertexShader(V_DVertVS, V_DVertPSInput)
|
|||||||
PixelShader(V_DVertPS, V_DVertPSOutput, V_DVertPSInput input)
|
PixelShader(V_DVertPS, V_DVertPSOutput, V_DVertPSInput input)
|
||||||
{
|
{
|
||||||
V_DVertPSOutput output;
|
V_DVertPSOutput output;
|
||||||
output.SV_Target0 = input.color_lin;
|
output.sv_target0 = input.color_lin;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ Struct(V_DQuadPSInput)
|
|||||||
|
|
||||||
Struct(V_DQuadPSOutput)
|
Struct(V_DQuadPSOutput)
|
||||||
{
|
{
|
||||||
Semantic(Vec4, SV_Target0);
|
Semantic(Vec4, sv_target0);
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -24,7 +24,7 @@ Struct(V_DVertPSInput)
|
|||||||
|
|
||||||
Struct(V_DVertPSOutput)
|
Struct(V_DVertPSOutput)
|
||||||
{
|
{
|
||||||
Semantic(Vec4, SV_Target0);
|
Semantic(Vec4, sv_target0);
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -31,7 +31,7 @@ Struct(PT_BlitPSInput)
|
|||||||
|
|
||||||
Struct(PT_BlitPSOutput)
|
Struct(PT_BlitPSOutput)
|
||||||
{
|
{
|
||||||
Semantic(Vec4, SV_Target0);
|
Semantic(Vec4, sv_target0);
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
@ -68,6 +68,6 @@ PixelShader(PT_BlitPS, PT_BlitPSOutput, PT_BlitPSInput input)
|
|||||||
result.r = (f32)noise_val / (f32)U16Max;
|
result.r = (f32)noise_val / (f32)U16Max;
|
||||||
|
|
||||||
PT_BlitPSOutput output;
|
PT_BlitPSOutput output;
|
||||||
output.SV_Target0 = result;
|
output.sv_target0 = result;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|||||||
181
src/ui/ui_core.c
181
src/ui/ui_core.c
@ -150,15 +150,15 @@ void UI_PushDefaults(void)
|
|||||||
case UI_StyleKind_Font: { desc.style.Font = UI_GetDefaultFont(); } break;
|
case UI_StyleKind_Font: { desc.style.Font = UI_GetDefaultFont(); } break;
|
||||||
|
|
||||||
u8 prefetch[127] = ZI;
|
u8 prefetch[127] = ZI;
|
||||||
for (u64 i = 0; i < countof(prefetch); ++i)
|
for (u64 idx = 0; idx < countof(prefetch); ++idx)
|
||||||
{
|
{
|
||||||
prefetch[i] = i;
|
prefetch[idx] = idx;
|
||||||
}
|
}
|
||||||
case UI_StyleKind_FontSize: { desc.style.FontSize = 16.0f; } break;
|
case UI_StyleKind_FontSize: { desc.style.FontSize = 16.0f; } break;
|
||||||
case UI_StyleKind_Tint: { desc.style.Tint = Color_White; } break;
|
case UI_StyleKind_Tint: { desc.style.Tint = Color_White; } break;
|
||||||
case UI_StyleKind_Tag: { desc.style.Tag = HashFnv64(Fnv64Basis, Lit("root")); } break;
|
case UI_StyleKind_Tag: { desc.style.Tag = HashFnv64(Fnv64Basis, Lit("root")); } break;
|
||||||
case UI_StyleKind_DebugColor: { desc.style.DebugColor = Rgba(1, 0, 1, 0.5); } break;
|
case UI_StyleKind_DebugColor: { desc.style.DebugColor = Rgba(1, 0, 1, 0.5); } break;
|
||||||
case UI_StyleKind_BackgroundTextureUv1: { desc.style.BackgroundTextureUv1 = VEC2(1, 1); } break;
|
case UI_StyleKind_BackgroundTextureSliceUv: { desc.style.BackgroundTextureSliceUv = RNG2(VEC2(0, 0), VEC2(1, 1)); } break;
|
||||||
};
|
};
|
||||||
UI_PushStyle(desc);
|
UI_PushStyle(desc);
|
||||||
}
|
}
|
||||||
@ -411,7 +411,7 @@ UI_Key UI_BuildBoxEx(UI_Key key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void UI_SetRawTexture(UI_Key key, G_Texture2DRef tex, Vec2 uv0, Vec2 uv1)
|
void UI_SetRawTexture(UI_Key key, G_Texture2DRef tex, Rng2 uv)
|
||||||
{
|
{
|
||||||
UI_Frame *frame = UI_CurrentFrame();
|
UI_Frame *frame = UI_CurrentFrame();
|
||||||
UI_CmdNode *n = PushStruct(frame->arena, UI_CmdNode);
|
UI_CmdNode *n = PushStruct(frame->arena, UI_CmdNode);
|
||||||
@ -419,8 +419,7 @@ void UI_SetRawTexture(UI_Key key, G_Texture2DRef tex, Vec2 uv0, Vec2 uv1)
|
|||||||
{
|
{
|
||||||
n->cmd.set_raw_texture.key = key;
|
n->cmd.set_raw_texture.key = key;
|
||||||
n->cmd.set_raw_texture.tex = tex;
|
n->cmd.set_raw_texture.tex = tex;
|
||||||
n->cmd.set_raw_texture.uv0 = uv0;
|
n->cmd.set_raw_texture.slice_uv = uv;
|
||||||
n->cmd.set_raw_texture.uv1 = uv1;
|
|
||||||
}
|
}
|
||||||
++frame->cmds_count;
|
++frame->cmds_count;
|
||||||
SllQueuePush(frame->first_cmd_node, frame->last_cmd_node, n);
|
SllQueuePush(frame->first_cmd_node, frame->last_cmd_node, n);
|
||||||
@ -547,8 +546,8 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
|
|||||||
b32 is_cursor_in_box = 0;
|
b32 is_cursor_in_box = 0;
|
||||||
{
|
{
|
||||||
/* TODO: More efficient test. This logic is just copied from the renderer's SDF function for now. */
|
/* TODO: More efficient test. This logic is just copied from the renderer's SDF function for now. */
|
||||||
Vec2 p0 = box->p0;
|
Vec2 p0 = box->rect.p0;
|
||||||
Vec2 p1 = box->p1;
|
Vec2 p1 = box->rect.p1;
|
||||||
Vec2 point = frame->cursor_pos;
|
Vec2 point = frame->cursor_pos;
|
||||||
b32 is_corner = 0;
|
b32 is_corner = 0;
|
||||||
f32 non_corner_edge_dist = MinF32(MinF32(point.x - p0.x, p1.x - point.x), MinF32(point.y - p0.y, p1.y - point.y));
|
f32 non_corner_edge_dist = MinF32(MinF32(point.x - p0.x, p1.x - point.x), MinF32(point.y - p0.y, p1.y - point.y));
|
||||||
@ -597,7 +596,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
|
|||||||
{
|
{
|
||||||
++hovered_box->report.m1_downs;
|
++hovered_box->report.m1_downs;
|
||||||
hovered_box->report.m1_held = 1;
|
hovered_box->report.m1_held = 1;
|
||||||
hovered_box->report.last_m1_offset = SubVec2(frame->cursor_pos, hovered_box->p0);
|
hovered_box->report.last_m1_offset = SubVec2(frame->cursor_pos, hovered_box->rect.p0);
|
||||||
active_box = hovered_box;
|
active_box = hovered_box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -642,8 +641,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
|
|||||||
report->active = LerpF32(report->active, target_active, active_blend_rate);
|
report->active = LerpF32(report->active, target_active, active_blend_rate);
|
||||||
report->hovered = LerpF32(report->hovered, target_hovered, hovered_blend_rate);
|
report->hovered = LerpF32(report->hovered, target_hovered, hovered_blend_rate);
|
||||||
|
|
||||||
report->screen_p0 = box->p0;
|
report->screen_rect = box->rect;
|
||||||
report->screen_p1 = box->p1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->hovered_box = hovered_box ? hovered_box->key : UI_NilKey;
|
frame->hovered_box = hovered_box ? hovered_box->key : UI_NilKey;
|
||||||
@ -789,10 +787,9 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch run */
|
/* Fetch run */
|
||||||
box->glyph_run = &GC_NilRun;
|
|
||||||
if (box->desc.text.len > 0)
|
if (box->desc.text.len > 0)
|
||||||
{
|
{
|
||||||
box->glyph_run = GC_RunFromString(frame->arena, box->desc.font, box->desc.text);
|
box->glyph_run = GC_RunFromString(frame->arena, box->desc.text, box->desc.font, box->desc.font_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -809,8 +806,7 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
if (box)
|
if (box)
|
||||||
{
|
{
|
||||||
box->raw_texture = cmd.set_raw_texture.tex;
|
box->raw_texture = cmd.set_raw_texture.tex;
|
||||||
box->raw_texture_uv0 = cmd.set_raw_texture.uv0;
|
box->raw_texture_slice_uv = cmd.set_raw_texture.slice_uv;
|
||||||
box->raw_texture_uv1 = cmd.set_raw_texture.uv1;
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@ -908,13 +904,11 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
f32 text_size = 0;
|
f32 text_size = 0;
|
||||||
if (axis == Axis_X)
|
if (axis == Axis_X)
|
||||||
{
|
{
|
||||||
GC_RunRect rr = box->glyph_run->rects[box->glyph_run->count - 1];
|
text_size = box->glyph_run.baseline_length;
|
||||||
f32 baseline_length = rr.pos + rr.advance;
|
|
||||||
text_size = baseline_length;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
text_size = box->glyph_run->ascent + box->glyph_run->descent;
|
text_size = box->glyph_run.font_ascent + box->glyph_run.font_descent;
|
||||||
}
|
}
|
||||||
box->solved_dims[axis] = text_size + (pref_size.v * 2);
|
box->solved_dims[axis] = text_size + (pref_size.v * 2);
|
||||||
}
|
}
|
||||||
@ -1107,16 +1101,16 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
if (AnyBit(box->desc.flags, UI_BoxFlag_Floating))
|
if (AnyBit(box->desc.flags, UI_BoxFlag_Floating))
|
||||||
{
|
{
|
||||||
Vec2 offset = box->desc.floating_pos;
|
Vec2 offset = box->desc.floating_pos;
|
||||||
final_pos = AddVec2(parent->p0, offset);
|
final_pos = AddVec2(parent->rect.p0, offset);
|
||||||
if (!AnyBit(box->desc.flags, UI_BoxFlag_NoFloatingClamp))
|
if (!AnyBit(box->desc.flags, UI_BoxFlag_NoFloatingClamp))
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
f32 overshoot = MaxF32(0, (final_pos.x + dims_vec.x) - parent->p1.x);
|
f32 overshoot = MaxF32(0, (final_pos.x + dims_vec.x) - parent->rect.p1.x);
|
||||||
final_pos.x = MaxF32(parent->p0.x, final_pos.x - overshoot);
|
final_pos.x = MaxF32(parent->rect.p0.x, final_pos.x - overshoot);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
f32 overshoot = MaxF32((final_pos.y + dims_vec.y) - parent->p1.y, 0);
|
f32 overshoot = MaxF32((final_pos.y + dims_vec.y) - parent->rect.p1.y, 0);
|
||||||
final_pos.y = MaxF32(parent->p0.y, final_pos.y - overshoot);
|
final_pos.y = MaxF32(parent->rect.p0.y, final_pos.y - overshoot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1151,22 +1145,22 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final_pos.x = parent->p0.x + offset[0];
|
final_pos.x = parent->rect.p0.x + offset[0];
|
||||||
final_pos.y = parent->p0.y + offset[1];
|
final_pos.y = parent->rect.p0.y + offset[1];
|
||||||
parent->layout_cursor += dims_arr[parent->desc.child_layout_axis];
|
parent->layout_cursor += dims_arr[parent->desc.child_layout_axis];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Submit position */
|
/* Submit position */
|
||||||
Vec2 floored_final_pos = FloorVec2(final_pos);
|
Vec2 floored_final_pos = FloorVec2(final_pos);
|
||||||
Vec2 ceiled_dims = CeilVec2(dims_vec);
|
Vec2 ceiled_dims = CeilVec2(dims_vec);
|
||||||
box->p0 = FloorVec2(floored_final_pos);
|
box->rect.p0 = FloorVec2(floored_final_pos);
|
||||||
box->p1 = AddVec2(floored_final_pos, ceiled_dims);
|
box->rect.p1 = AddVec2(floored_final_pos, ceiled_dims);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rounding */
|
/* Rounding */
|
||||||
{
|
{
|
||||||
UI_Round rounding = box->desc.rounding;
|
UI_Round rounding = box->desc.rounding;
|
||||||
Vec2 half_dims = MulVec2(SubVec2(box->p1, box->p0), 0.5);
|
Vec2 half_dims = MulVec2(SubVec2(box->rect.p1, box->rect.p0), 0.5);
|
||||||
f32 min_half_dims = MinF32(half_dims.x, half_dims.y);
|
f32 min_half_dims = MinF32(half_dims.x, half_dims.y);
|
||||||
f32 final_rounding_tl = 0;
|
f32 final_rounding_tl = 0;
|
||||||
f32 final_rounding_tr = 0;
|
f32 final_rounding_tr = 0;
|
||||||
@ -1194,10 +1188,10 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
|
|
||||||
if (parent && !AllBits(box->desc.flags, UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClamp))
|
if (parent && !AllBits(box->desc.flags, UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClamp))
|
||||||
{
|
{
|
||||||
Vec2 vtl = SubVec2(VEC2(parent->p0.x, parent->p0.y), VEC2(box->p0.x, box->p0.y));
|
Vec2 vtl = SubVec2(VEC2(parent->rect.p0.x, parent->rect.p0.y), VEC2(box->rect.p0.x, box->rect.p0.y));
|
||||||
Vec2 vtr = SubVec2(VEC2(parent->p1.x, parent->p0.y), VEC2(box->p1.x, box->p0.y));
|
Vec2 vtr = SubVec2(VEC2(parent->rect.p1.x, parent->rect.p0.y), VEC2(box->rect.p1.x, box->rect.p0.y));
|
||||||
Vec2 vbr = SubVec2(VEC2(parent->p1.x, parent->p1.y), VEC2(box->p1.x, box->p1.y));
|
Vec2 vbr = SubVec2(VEC2(parent->rect.p1.x, parent->rect.p1.y), VEC2(box->rect.p1.x, box->rect.p1.y));
|
||||||
Vec2 vbl = SubVec2(VEC2(parent->p0.x, parent->p1.y), VEC2(box->p0.x, box->p1.y));
|
Vec2 vbl = SubVec2(VEC2(parent->rect.p0.x, parent->rect.p1.y), VEC2(box->rect.p0.x, box->rect.p1.y));
|
||||||
final_rounding_tl = MaxF32(final_rounding_tl, parent->rounding_tl - Vec2Len(vtl));
|
final_rounding_tl = MaxF32(final_rounding_tl, parent->rounding_tl - Vec2Len(vtl));
|
||||||
final_rounding_tr = MaxF32(final_rounding_tr, parent->rounding_tr - Vec2Len(vtr));
|
final_rounding_tr = MaxF32(final_rounding_tr, parent->rounding_tr - Vec2Len(vtr));
|
||||||
final_rounding_br = MaxF32(final_rounding_br, parent->rounding_br - Vec2Len(vbr));
|
final_rounding_br = MaxF32(final_rounding_br, parent->rounding_br - Vec2Len(vbr));
|
||||||
@ -1226,18 +1220,15 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
UI_Box *box = boxes_pre[pre_index];
|
UI_Box *box = boxes_pre[pre_index];
|
||||||
b32 is_visible = 1;
|
b32 is_visible = 1;
|
||||||
is_visible = is_visible && (box->desc.tint.w != 0);
|
is_visible = is_visible && (box->desc.tint.w != 0);
|
||||||
is_visible = is_visible && (box->p1.x > box->p0.x);
|
is_visible = is_visible && (box->rect.p1.x > box->rect.p0.x);
|
||||||
is_visible = is_visible && (box->p1.y > box->p0.y);
|
is_visible = is_visible && (box->rect.p1.y > box->rect.p0.y);
|
||||||
if (is_visible || AnyBit(frame->frame_flags, UI_FrameFlag_Debug))
|
if (is_visible || AnyBit(frame->frame_flags, UI_FrameFlag_Debug))
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Box rect */
|
/* Box rect */
|
||||||
{
|
{
|
||||||
UI_DRect *rect = PushStruct(frame->rects_arena, UI_DRect);
|
UI_DRect *rect = PushStruct(frame->rects_arena, UI_DRect);
|
||||||
rect->p0 = box->p0;
|
rect->bounds = box->rect;
|
||||||
rect->p1 = box->p1;
|
|
||||||
rect->tex_uv0 = VEC2(0, 0);
|
|
||||||
rect->tex_uv1 = VEC2(1, 1);
|
|
||||||
rect->background_lin = LinearFromSrgb(box->desc.background_color);
|
rect->background_lin = LinearFromSrgb(box->desc.background_color);
|
||||||
rect->border_lin = LinearFromSrgb(box->desc.border_color);
|
rect->border_lin = LinearFromSrgb(box->desc.border_color);
|
||||||
rect->debug_lin = LinearFromSrgb(box->desc.debug_color);
|
rect->debug_lin = LinearFromSrgb(box->desc.debug_color);
|
||||||
@ -1248,55 +1239,55 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
rect->br_rounding = box->rounding_br;
|
rect->br_rounding = box->rounding_br;
|
||||||
rect->bl_rounding = box->rounding_bl;
|
rect->bl_rounding = box->rounding_bl;
|
||||||
rect->tex = box->raw_texture;
|
rect->tex = box->raw_texture;
|
||||||
rect->tex_uv0 = box->raw_texture_uv0;
|
rect->tex_slice_uv = box->raw_texture_slice_uv;
|
||||||
rect->tex_uv1 = box->raw_texture_uv1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Text rects */
|
/* Text rects */
|
||||||
GC_Run *raw_run = box->glyph_run;
|
GC_Run raw_run = box->glyph_run;
|
||||||
if (AnyBit(box->desc.flags, UI_BoxFlag_DrawText) && raw_run->loaded)
|
if (AnyBit(box->desc.flags, UI_BoxFlag_DrawText) && raw_run.ready)
|
||||||
{
|
{
|
||||||
f32 max_baseline = box->p1.x - box->p0.x;
|
f32 max_baseline = DimsFromRng2(box->rect).x;
|
||||||
b32 should_truncate = raw_run->count > 0 && (raw_run->rects[raw_run->count - 1].pos + raw_run->rects[raw_run->count - 1].advance) > max_baseline;
|
b32 should_truncate = raw_run.baseline_length > max_baseline && !AnyBit(box->desc.flags, UI_BoxFlag_NoTextTruncation);
|
||||||
|
|
||||||
/* Truncate run */
|
/* Truncate run */
|
||||||
GC_RunRect *truncated_rects = raw_run->rects;
|
u64 final_rects_count = 0;
|
||||||
u32 truncated_rects_count = raw_run->count;
|
GC_RunRect *final_rects = 0;
|
||||||
if (should_truncate && !AnyBit(box->desc.flags, UI_BoxFlag_NoTextTruncation))
|
if (should_truncate)
|
||||||
{
|
{
|
||||||
/* Get elipses run */
|
/* Get elipses run */
|
||||||
GC_Run *elipses_run = GC_RunFromString(scratch.arena, box->desc.font, Lit("..."));
|
GC_Run elipses_run = GC_RunFromString(scratch.arena, Lit("..."), box->desc.font, box->desc.font_size);
|
||||||
if (elipses_run->count > 0)
|
f32 elipses_start_pos = max_baseline - elipses_run.baseline_length;
|
||||||
|
|
||||||
|
/* Append non-overflowed rects */
|
||||||
|
final_rects = PushStructsNoZero(scratch.arena, GC_RunRect, raw_run.rects_count);
|
||||||
|
for (u64 rect_idx = 0; rect_idx < raw_run.rects_count; ++rect_idx)
|
||||||
{
|
{
|
||||||
max_baseline -= elipses_run->rects[elipses_run->count - 1].pos + elipses_run->rects[elipses_run->count - 1].advance;
|
GC_RunRect rr = raw_run.rects[rect_idx];
|
||||||
|
if ((rr.baseline_pos + rr.advance) <= elipses_start_pos)
|
||||||
|
{
|
||||||
|
final_rects[final_rects_count] = rr;
|
||||||
|
final_rects_count += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Subtract glyphs */
|
/* Append elipses */
|
||||||
while (truncated_rects_count > 0)
|
for (u64 rect_idx = 0; rect_idx < elipses_run.rects_count; ++rect_idx)
|
||||||
{
|
{
|
||||||
GC_RunRect rr = raw_run->rects[truncated_rects_count - 1];
|
GC_RunRect rr = elipses_run.rects[rect_idx];
|
||||||
if (rr.pos + rr.advance <= max_baseline)
|
rr.baseline_pos += elipses_start_pos;
|
||||||
|
rr.bounds = AddRng2Vec2(rr.bounds, VEC2(elipses_start_pos, 0));
|
||||||
|
if ((rr.baseline_pos + rr.advance) <= max_baseline)
|
||||||
{
|
{
|
||||||
break;
|
final_rects[final_rects_count] = rr;
|
||||||
}
|
final_rects_count += 1;
|
||||||
--truncated_rects_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Merge trunc rects */
|
|
||||||
/* FIXME: Verify this stil works as expected */
|
|
||||||
{
|
|
||||||
truncated_rects_count += elipses_run->count;
|
|
||||||
truncated_rects = PushStructsNoZero(scratch.arena, GC_RunRect, truncated_rects_count + elipses_run->count);
|
|
||||||
CopyStructs(truncated_rects, raw_run->rects, raw_run->count);
|
|
||||||
f32 elipses_offset = truncated_rects_count > 0 ? (truncated_rects[truncated_rects_count - 1].pos + truncated_rects[truncated_rects_count - 1].advance) : 0;
|
|
||||||
for (u32 i = 0; i < elipses_run->count; ++i)
|
|
||||||
{
|
|
||||||
GC_RunRect *rr = &truncated_rects[i + truncated_rects_count];
|
|
||||||
*rr = elipses_run->rects[i];
|
|
||||||
rr->pos += elipses_offset;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
final_rects = raw_run.rects;
|
||||||
|
final_rects_count = raw_run.rects_count;
|
||||||
|
}
|
||||||
|
|
||||||
UI_AxisAlignment x_alignment = box->desc.child_alignment[Axis_X];
|
UI_AxisAlignment x_alignment = box->desc.child_alignment[Axis_X];
|
||||||
UI_AxisAlignment y_alignment = box->desc.child_alignment[Axis_Y];
|
UI_AxisAlignment y_alignment = box->desc.child_alignment[Axis_Y];
|
||||||
@ -1306,68 +1297,64 @@ void UI_EndFrame(UI_Frame *frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Compute baseline */
|
/* Compute baseline */
|
||||||
f32 ascent = raw_run->ascent;
|
f32 ascent = raw_run.font_ascent;
|
||||||
f32 descent = raw_run->descent;
|
f32 font_descent = raw_run.font_descent;
|
||||||
f32 cap = raw_run->cap;
|
f32 cap = raw_run.font_cap;
|
||||||
f32 baseline_width = truncated_rects_count > 0 ? (truncated_rects[truncated_rects_count - 1].pos + truncated_rects[truncated_rects_count - 1].advance) : 0;
|
f32 baseline_width = raw_run.baseline_length;
|
||||||
f32 baseline_height = ascent + descent;
|
f32 baseline_height = ascent + font_descent;
|
||||||
f32 box_width = box->p1.x - box->p0.x;
|
Vec2 box_dims = DimsFromRng2(box->rect);
|
||||||
f32 box_height = box->p1.y - box->p0.y;
|
|
||||||
Vec2 baseline = ZI;
|
Vec2 baseline = ZI;
|
||||||
switch (x_alignment)
|
switch (x_alignment)
|
||||||
{
|
{
|
||||||
case UI_AxisAlignment_Start:
|
case UI_AxisAlignment_Start:
|
||||||
{
|
{
|
||||||
baseline.x = box->p0.x;
|
baseline.x = box->rect.p0.x;
|
||||||
} break;
|
} break;
|
||||||
case UI_AxisAlignment_End:
|
case UI_AxisAlignment_End:
|
||||||
{
|
{
|
||||||
baseline.x = box->p1.x;
|
baseline.x = box->rect.p1.x;
|
||||||
baseline.x -= baseline_width;
|
baseline.x -= baseline_width;
|
||||||
} break;
|
} break;
|
||||||
case UI_AxisAlignment_Center:
|
case UI_AxisAlignment_Center:
|
||||||
{
|
{
|
||||||
baseline.x = box->p0.x;
|
baseline.x = box->rect.p0.x;
|
||||||
baseline.x += (box_width - baseline_width) / 2;
|
baseline.x += (box_dims.x - baseline_width) / 2;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
switch (y_alignment)
|
switch (y_alignment)
|
||||||
{
|
{
|
||||||
case UI_AxisAlignment_Start:
|
case UI_AxisAlignment_Start:
|
||||||
{
|
{
|
||||||
baseline.y = box->p0.y;
|
baseline.y = box->rect.p0.y;
|
||||||
baseline.y += ascent;
|
baseline.y += ascent;
|
||||||
} break;
|
} break;
|
||||||
case UI_AxisAlignment_End:
|
case UI_AxisAlignment_End:
|
||||||
{
|
{
|
||||||
baseline.y = box->p1.y;
|
baseline.y = box->rect.p1.y;
|
||||||
baseline.y -= descent;
|
baseline.y -= font_descent;
|
||||||
} break;
|
} break;
|
||||||
case UI_AxisAlignment_Center:
|
case UI_AxisAlignment_Center:
|
||||||
{
|
{
|
||||||
baseline.y = box->p0.y;
|
baseline.y = box->rect.p0.y;
|
||||||
baseline.y += box_height / 2;
|
baseline.y += box_dims.y / 2;
|
||||||
baseline.y += cap / 2;
|
baseline.y += cap / 2;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
baseline = CeilVec2(baseline);
|
baseline = CeilVec2(baseline);
|
||||||
|
|
||||||
/* Push text rects */
|
/* Push text rects */
|
||||||
for (u64 i = 0; i < truncated_rects_count; ++i)
|
for (u64 rect_idx = 0; rect_idx < final_rects_count; ++rect_idx)
|
||||||
{
|
{
|
||||||
GC_RunRect rr = truncated_rects[i];
|
GC_RunRect rr = final_rects[rect_idx];
|
||||||
Vec2 glyph_size = rr.size;
|
Vec2 glyph_dims = DimsFromRng2(rr.bounds);
|
||||||
if (glyph_size.x != 0 || glyph_size.y != 0)
|
if (glyph_dims.x != 0 || glyph_dims.y != 0)
|
||||||
{
|
{
|
||||||
UI_DRect *rect = PushStruct(frame->rects_arena, UI_DRect);
|
UI_DRect *rect = PushStruct(frame->rects_arena, UI_DRect);
|
||||||
rect->p0 = AddVec2(baseline, VEC2(rr.pos, 0));
|
rect->bounds = AddRng2Vec2(rr.bounds, baseline);
|
||||||
rect->p0 = AddVec2(rect->p0, rr.offset);
|
|
||||||
rect->p1 = AddVec2(rect->p0, glyph_size);
|
|
||||||
rect->debug_lin = LinearFromSrgb(box->desc.debug_color);
|
rect->debug_lin = LinearFromSrgb(box->desc.debug_color);
|
||||||
rect->tint_lin = LinearFromSrgb(box->desc.tint);
|
rect->tint_lin = LinearFromSrgb(box->desc.tint);
|
||||||
rect->tex = rr.tex;
|
rect->tex = rr.tex;
|
||||||
rect->tex_uv0 = rr.uv.p0;
|
rect->tex_slice_uv = rr.tex_uv;
|
||||||
rect->tex_uv1 = rr.uv.p1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -110,11 +110,10 @@ Enum(UI_BoxFlag)
|
|||||||
X(FontSize, u32) \
|
X(FontSize, u32) \
|
||||||
X(Text, String) \
|
X(Text, String) \
|
||||||
X(BackgroundTexture, G_Texture2DRef) \
|
X(BackgroundTexture, G_Texture2DRef) \
|
||||||
X(BackgroundTextureUv0, Vec2) \
|
X(BackgroundTextureSliceUv, Rng2) \
|
||||||
X(BackgroundTextureUv1, Vec2) \
|
/* -------------------------------------------- */ \
|
||||||
/* --------------------------------------- */ \
|
/* -------------- Virtual styles -------------- */ \
|
||||||
/* ----------- Virtual styles ----------- */ \
|
/* -------------------------------------------- */ \
|
||||||
/* --------------------------------------- */ \
|
|
||||||
X(BeginVirtualStyles_, i8) \
|
X(BeginVirtualStyles_, i8) \
|
||||||
X(ChildAlignment, UI_Alignment) \
|
X(ChildAlignment, UI_Alignment) \
|
||||||
X(AxisSize, UI_Size) \
|
X(AxisSize, UI_Size) \
|
||||||
@ -187,8 +186,7 @@ Struct(UI_Report)
|
|||||||
Vec2 last_m1_offset;
|
Vec2 last_m1_offset;
|
||||||
|
|
||||||
/* Where was this box last rendered in screen coordinates */
|
/* Where was this box last rendered in screen coordinates */
|
||||||
Vec2 screen_p0;
|
Rng2 screen_rect;
|
||||||
Vec2 screen_p1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -233,8 +231,7 @@ Struct(UI_Cmd)
|
|||||||
{
|
{
|
||||||
UI_Key key;
|
UI_Key key;
|
||||||
G_Texture2DRef tex;
|
G_Texture2DRef tex;
|
||||||
Vec2 uv0;
|
Rng2 slice_uv;
|
||||||
Vec2 uv1;
|
|
||||||
} set_raw_texture;
|
} set_raw_texture;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -269,22 +266,20 @@ Struct(UI_Box)
|
|||||||
//- Cmd data
|
//- Cmd data
|
||||||
UI_BoxDesc desc;
|
UI_BoxDesc desc;
|
||||||
G_Texture2DRef raw_texture;
|
G_Texture2DRef raw_texture;
|
||||||
Vec2 raw_texture_uv0;
|
Rng2 raw_texture_slice_uv;
|
||||||
Vec2 raw_texture_uv1;
|
|
||||||
|
|
||||||
//- Pre-layout data
|
//- Pre-layout data
|
||||||
u64 pre_index;
|
u64 pre_index;
|
||||||
u64 post_index;
|
u64 post_index;
|
||||||
|
|
||||||
//- Layout data
|
//- Layout data
|
||||||
GC_Run *glyph_run;
|
GC_Run glyph_run;
|
||||||
f32 layout_cursor;
|
f32 layout_cursor;
|
||||||
f32 solved_dims[Axis_CountXY];
|
f32 solved_dims[Axis_CountXY];
|
||||||
f32 final_children_size_accum[Axis_CountXY];
|
f32 final_children_size_accum[Axis_CountXY];
|
||||||
|
|
||||||
//- Layout results
|
//- Layout results
|
||||||
Vec2 p0;
|
Rng2 rect;
|
||||||
Vec2 p1;
|
|
||||||
f32 rounding_tl;
|
f32 rounding_tl;
|
||||||
f32 rounding_tr;
|
f32 rounding_tr;
|
||||||
f32 rounding_br;
|
f32 rounding_br;
|
||||||
@ -443,7 +438,7 @@ UI_Style UI_PopStyle(UI_StyleDesc desc);
|
|||||||
UI_Key UI_BuildBoxEx(UI_Key key);
|
UI_Key UI_BuildBoxEx(UI_Key key);
|
||||||
#define UI_BuildBox() UI_BuildBoxEx(UI_TransKey())
|
#define UI_BuildBox() UI_BuildBoxEx(UI_TransKey())
|
||||||
|
|
||||||
void UI_SetRawTexture(UI_Key key, G_Texture2DRef tex, Vec2 uv0, Vec2 uv1);
|
void UI_SetRawTexture(UI_Key key, G_Texture2DRef tex, Rng2 uv);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Report
|
//~ Report
|
||||||
|
|||||||
@ -20,16 +20,16 @@ Struct(UI_DParams)
|
|||||||
|
|
||||||
Struct(UI_DRect)
|
Struct(UI_DRect)
|
||||||
{
|
{
|
||||||
Vec2 p0;
|
Rng2 bounds;
|
||||||
Vec2 p1;
|
|
||||||
|
G_Texture2DRef tex;
|
||||||
|
Rng2 tex_slice_uv;
|
||||||
|
|
||||||
Vec4 tint_lin;
|
Vec4 tint_lin;
|
||||||
Vec4 background_lin;
|
Vec4 background_lin;
|
||||||
Vec4 border_lin;
|
Vec4 border_lin;
|
||||||
Vec4 debug_lin;
|
Vec4 debug_lin;
|
||||||
f32 border;
|
f32 border;
|
||||||
Vec2 tex_uv0;
|
|
||||||
Vec2 tex_uv1;
|
|
||||||
G_Texture2DRef tex;
|
|
||||||
|
|
||||||
f32 tl_rounding;
|
f32 tl_rounding;
|
||||||
f32 tr_rounding;
|
f32 tr_rounding;
|
||||||
|
|||||||
@ -11,8 +11,8 @@ VertexShader(UI_DRectVS, UI_DRectPSInput)
|
|||||||
UI_DRect rect = rects[SV_InstanceID];
|
UI_DRect rect = rects[SV_InstanceID];
|
||||||
|
|
||||||
Vec2 rect_uv = RectUvFromVertexId(SV_VertexID);
|
Vec2 rect_uv = RectUvFromVertexId(SV_VertexID);
|
||||||
Vec2 tex_uv = lerp(rect.tex_uv0, rect.tex_uv1, rect_uv);
|
Vec2 tex_uv = lerp(rect.tex_slice_uv.p0, rect.tex_slice_uv.p1, rect_uv);
|
||||||
Vec2 target_pos = lerp(rect.p0, rect.p1, rect_uv);
|
Vec2 target_pos = lerp(rect.bounds.p0, rect.bounds.p1, rect_uv);
|
||||||
|
|
||||||
UI_DRectPSInput result;
|
UI_DRectPSInput result;
|
||||||
result.sv_position = Vec4(NdcFromPos(target_pos, Vec2(params.target_size).xy), 0, 1);
|
result.sv_position = Vec4(NdcFromPos(target_pos, Vec2(params.target_size).xy), 0, 1);
|
||||||
@ -39,8 +39,8 @@ PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input)
|
|||||||
|
|
||||||
Vec2 p = input.sv_position.xy;
|
Vec2 p = input.sv_position.xy;
|
||||||
Vec2 rect_uv = input.rect_uv;
|
Vec2 rect_uv = input.rect_uv;
|
||||||
Vec2 p0 = rect.p0;
|
Vec2 p0 = rect.bounds.p0;
|
||||||
Vec2 p1 = rect.p1;
|
Vec2 p1 = rect.bounds.p1;
|
||||||
|
|
||||||
/* Compute rect sdf (negative means pixel is inside of rect) */
|
/* Compute rect sdf (negative means pixel is inside of rect) */
|
||||||
f32 rect_dist = min(min(p.x - p0.x, p1.x - p.x), min(p.y - p0.y, p1.y - p.y));
|
f32 rect_dist = min(min(p.x - p0.x, p1.x - p.x), min(p.y - p0.y, p1.y - p.y));
|
||||||
@ -147,6 +147,6 @@ PixelShader(UI_BlitPS, UI_BlitPSOutput, UI_BlitPSInput input)
|
|||||||
Vec4 result = tex.Sample(sampler, uv);
|
Vec4 result = tex.Sample(sampler, uv);
|
||||||
|
|
||||||
UI_BlitPSOutput output;
|
UI_BlitPSOutput output;
|
||||||
output.SV_Target0 = result;
|
output.sv_target0 = result;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,7 +28,7 @@ Struct(UI_BlitPSInput)
|
|||||||
|
|
||||||
Struct(UI_BlitPSOutput)
|
Struct(UI_BlitPSOutput)
|
||||||
{
|
{
|
||||||
Semantic(Vec4, SV_Target0);
|
Semantic(Vec4, sv_target0);
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user