Added a hack to fix DeadLock problem regrading the system_memory_annotation function. Also started working on fixing the performance issues that I discovered in the graphics renderer on retina displays (for now I changed to FCoder_View to be layer backed which is faster for rendering animations, this seems to improve performance by a little margin but rendering on high dpi displays is not closed to being smooth yet...).

master
Yuval Dolev 2020-01-14 03:22:29 +02:00
parent a737a5409a
commit de9fc34c3e
6 changed files with 916 additions and 897 deletions

1684
4ed.cpp

File diff suppressed because it is too large Load Diff

View File

@ -347,11 +347,11 @@ function Fancy_String*
push_fancy_string_fixed(Arena *arena, Fancy_Line *line, FColor fore, push_fancy_string_fixed(Arena *arena, Fancy_Line *line, FColor fore,
String_Const_u8 value, i32 max){ String_Const_u8 value, i32 max){
if (value.size <= max){ if (value.size <= max){
return(push_fancy_stringf(arena, line, 0, fore, 0.f, 0.f, return(push_fancy_stringf(arena, line, (Face_ID)0, fore, 0.f, 0.f,
"%-*.*s", max, string_expand(value))); "%-*.*s", max, string_expand(value)));
} }
else{ else{
return(push_fancy_stringf(arena, line, 0, fore, 0.f, 0.f, return(push_fancy_stringf(arena, line, (Face_ID)0, fore, 0.f, 0.f,
"%-*.*s...", max - 3, string_expand(value))); "%-*.*s...", max - 3, string_expand(value)));
} }
} }
@ -360,12 +360,12 @@ push_fancy_string_fixed(Arena *arena, Fancy_Line *line,
f32 pre_margin, f32 post_margin, String_Const_u8 value, f32 pre_margin, f32 post_margin, String_Const_u8 value,
i32 max){ i32 max){
if (value.size <= max){ if (value.size <= max){
return(push_fancy_stringf(arena, line, 0, fcolor_zero(), return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(),
pre_margin, post_margin, pre_margin, post_margin,
"%-*.*s", max, string_expand(value))); "%-*.*s", max, string_expand(value)));
} }
else{ else{
return(push_fancy_stringf(arena, line, 0, fcolor_zero(), return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(),
pre_margin, post_margin, pre_margin, post_margin,
"%-*.*s...", max - 3, string_expand(value))); "%-*.*s...", max - 3, string_expand(value)));
} }
@ -374,11 +374,11 @@ function Fancy_String*
push_fancy_string_fixed(Arena *arena, Fancy_Line *line, String_Const_u8 value, push_fancy_string_fixed(Arena *arena, Fancy_Line *line, String_Const_u8 value,
i32 max){ i32 max){
if (value.size <= max){ if (value.size <= max){
return(push_fancy_stringf(arena, line, 0, fcolor_zero(), 0.f, 0.f, return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), 0.f, 0.f,
"%-*.*s", max, string_expand(value))); "%-*.*s", max, string_expand(value)));
} }
else{ else{
return(push_fancy_stringf(arena, line, 0, fcolor_zero(), 0.f, 0.f, return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), 0.f, 0.f,
"%-*.*s...", max - 3, string_expand(value))); "%-*.*s...", max - 3, string_expand(value)));
} }
} }
@ -452,11 +452,11 @@ function Fancy_String*
push_fancy_string_trunc(Arena *arena, Fancy_Line *line, FColor fore, push_fancy_string_trunc(Arena *arena, Fancy_Line *line, FColor fore,
String_Const_u8 value, i32 max){ String_Const_u8 value, i32 max){
if (value.size <= max){ if (value.size <= max){
return(push_fancy_stringf(arena, line, 0, fore, 0.f, 0.f, return(push_fancy_stringf(arena, line, (Face_ID)0, fore, 0.f, 0.f,
"%.*s", string_expand(value))); "%.*s", string_expand(value)));
} }
else{ else{
return(push_fancy_stringf(arena, line, 0, fore, 0.f, 0.f, return(push_fancy_stringf(arena, line, (Face_ID)0, fore, 0.f, 0.f,
"%.*s...", max - 3, value.str)); "%.*s...", max - 3, value.str));
} }
} }
@ -465,12 +465,12 @@ push_fancy_string_trunc(Arena *arena, Fancy_Line *line,
f32 pre_margin, f32 post_margin, String_Const_u8 value, f32 pre_margin, f32 post_margin, String_Const_u8 value,
i32 max){ i32 max){
if (value.size <= max){ if (value.size <= max){
return(push_fancy_stringf(arena, line, 0, fcolor_zero(), return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(),
pre_margin, post_margin, pre_margin, post_margin,
"%.*s", string_expand(value))); "%.*s", string_expand(value)));
} }
else{ else{
return(push_fancy_stringf(arena, line, 0, fcolor_zero(), return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(),
pre_margin, post_margin, pre_margin, post_margin,
"%.*s...", max - 3, value.str)); "%.*s...", max - 3, value.str));
} }
@ -479,11 +479,11 @@ function Fancy_String*
push_fancy_string_trunc(Arena *arena, Fancy_Line *line, String_Const_u8 value, push_fancy_string_trunc(Arena *arena, Fancy_Line *line, String_Const_u8 value,
i32 max){ i32 max){
if (value.size <= max){ if (value.size <= max){
return(push_fancy_stringf(arena, line, 0, fcolor_zero(), 0.f, 0.f, return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), 0.f, 0.f,
"%.*s", string_expand(value))); "%.*s", string_expand(value)));
} }
else{ else{
return(push_fancy_stringf(arena, line, 0, fcolor_zero(), 0.f, 0.f, return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), 0.f, 0.f,
"%.*s...", max - 3, value.str)); "%.*s...", max - 3, value.str));
} }
} }
@ -620,7 +620,7 @@ draw_fancy_string__inner(Application_Links *app, Face_ID face, FColor fore, Fanc
use_fore = string->fore; use_fore = string->fore;
} }
if (use_face != 0){ if (use_face != 0){
ARGB_Color use_argb = fcolor_resolve(use_fore); ARGB_Color use_argb = fcolor_resolve(use_fore);
Face_Metrics metrics = get_face_metrics(app, use_face); Face_Metrics metrics = get_face_metrics(app, use_face);
f32 down_shift = (base_line - metrics.ascent); f32 down_shift = (base_line - metrics.ascent);
down_shift = clamp_bot(0.f, down_shift); down_shift = clamp_bot(0.f, down_shift);
@ -668,7 +668,7 @@ get_fancy_string_height(Application_Links *app, Face_ID face,
function f32 function f32
get_fancy_string_text_height(Application_Links *app, Face_ID face, get_fancy_string_text_height(Application_Links *app, Face_ID face,
Fancy_String *string){ Fancy_String *string){
Fancy_String *next = string->next; Fancy_String *next = string->next;
string->next = 0; string->next = 0;
f32 result = get_fancy_string_text_height__inner(app, face, string); f32 result = get_fancy_string_text_height__inner(app, face, string);
@ -700,10 +700,10 @@ function f32
get_fancy_line_width(Application_Links *app, Face_ID face, Fancy_Line *line){ get_fancy_line_width(Application_Links *app, Face_ID face, Fancy_Line *line){
f32 result = 0.f; f32 result = 0.f;
if (line != 0){ if (line != 0){
if (line->face != 0){ if (line->face != 0){
face = line->face; face = line->face;
} }
result = get_fancy_string_width__inner(app, face, line->first); result = get_fancy_string_width__inner(app, face, line->first);
} }
return(result); return(result);
} }
@ -749,12 +749,12 @@ draw_fancy_line(Application_Links *app, Face_ID face, FColor fore,
Fancy_Line *line, Vec2_f32 p, u32 flags, Vec2_f32 delta){ Fancy_Line *line, Vec2_f32 p, u32 flags, Vec2_f32 delta){
Vec2_f32 result = {}; Vec2_f32 result = {};
if (line != 0){ if (line != 0){
if (line->face != 0){ if (line->face != 0){
face = line->face; face = line->face;
} }
if (fcolor_is_valid(line->fore)){ if (fcolor_is_valid(line->fore)){
fore = line->fore; fore = line->fore;
} }
result = draw_fancy_string__inner(app, face, fore, line->first, p, flags, delta); result = draw_fancy_string__inner(app, face, fore, line->first, p, flags, delta);
} }
return(result); return(result);

View File

@ -131,7 +131,6 @@ float shape_value = (1.0 - smoothstep(-1.0, 0.0, sd));
shape_value *= has_thickness; shape_value *= has_thickness;
float4 out_color = float4(in.color.xyz, in.color.a * (sample_value + shape_value)); float4 out_color = float4(in.color.xyz, in.color.a * (sample_value + shape_value));
//float4 out_color = float4(1, 1, 1, shape_value);
return(out_color); return(out_color);
} }
)"; )";
@ -274,9 +273,12 @@ metal__make_buffer(u32 size, id<MTLDevice> device){
} }
- (void)drawInMTKView:(nonnull MTKView*)view{ - (void)drawInMTKView:(nonnull MTKView*)view{
#if FRED_INTERNAL
[capture_scope beginScope]; [capture_scope beginScope];
#endif
// HACK(yuval): This is the best way I found to force valid width and height without drawing on the next draw cycle (1 frame delay).
// HACK(yuval): This is the best way I found to force valid width and height without drawing on the next drawing cycle (1 frame delay).
CGSize drawable_size = [view drawableSize]; CGSize drawable_size = [view drawableSize];
i32 width = (i32)Min(_target->width, drawable_size.width); i32 width = (i32)Min(_target->width, drawable_size.width);
i32 height = (i32)Min(_target->height, drawable_size.height); i32 height = (i32)Min(_target->height, drawable_size.height);
@ -293,8 +295,8 @@ metal__make_buffer(u32 size, id<MTLDevice> device){
render_pass_descriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0f, 0.0f, 0.0f, 1.0f); render_pass_descriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0f, 0.0f, 0.0f, 1.0f);
// NOTE(yuval): Create the render command encoder // NOTE(yuval): Create the render command encoder
id<MTLRenderCommandEncoder> render_encoder id<MTLRenderCommandEncoder> render_encoder =
= [command_buffer renderCommandEncoderWithDescriptor:render_pass_descriptor]; [command_buffer renderCommandEncoderWithDescriptor:render_pass_descriptor];
render_encoder.label = @"4coder Render Encoder"; render_encoder.label = @"4coder Render Encoder";
// NOTE(yuval): Set the region of the drawable to draw into // NOTE(yuval): Set the region of the drawable to draw into
@ -303,7 +305,7 @@ metal__make_buffer(u32 size, id<MTLDevice> device){
// NOTE(yuval): Set the render pipeline to use for drawing // NOTE(yuval): Set the render pipeline to use for drawing
[render_encoder setRenderPipelineState:pipeline_state]; [render_encoder setRenderPipelineState:pipeline_state];
// NOTE(yuval): Calculate and pass in the projection matrix // NOTE(yuval): Calculate the projection matrix
float left = 0, right = (float)width; float left = 0, right = (float)width;
float bottom = (float)height, top = 0; float bottom = (float)height, top = 0;
float near_depth = -1.0f, far_depth = 1.0f; float near_depth = -1.0f, far_depth = 1.0f;
@ -325,6 +327,8 @@ metal__make_buffer(u32 size, id<MTLDevice> device){
u32 vertex_buffer_size = (all_vertex_count * sizeof(Render_Vertex)); u32 vertex_buffer_size = (all_vertex_count * sizeof(Render_Vertex));
printf("Vertices to render: %d\n", all_vertex_count);
// NOTE(yuval): Find & Get a vertex buffer matching the required size // NOTE(yuval): Find & Get a vertex buffer matching the required size
Metal_Buffer *buffer = [self get_reusable_buffer_with_size:vertex_buffer_size]; Metal_Buffer *buffer = [self get_reusable_buffer_with_size:vertex_buffer_size];
@ -338,6 +342,8 @@ metal__make_buffer(u32 size, id<MTLDevice> device){
length:sizeof(proj) length:sizeof(proj)
atIndex:1]; atIndex:1];
u32 group_count = 0;
u32 buffer_offset = 0; u32 buffer_offset = 0;
for (Render_Group *group = _target->group_first; for (Render_Group *group = _target->group_first;
group; group;
@ -346,7 +352,6 @@ metal__make_buffer(u32 size, id<MTLDevice> device){
{ {
Rect_i32 box = Ri32(group->clip_box); Rect_i32 box = Ri32(group->clip_box);
NSUInteger x0 = (NSUInteger)Min(Max(0, box.x0), width - 1); NSUInteger x0 = (NSUInteger)Min(Max(0, box.x0), width - 1);
NSUInteger x1 = (NSUInteger)Min(Max(0, box.x1), width); NSUInteger x1 = (NSUInteger)Min(Max(0, box.x1), width);
NSUInteger y0 = (NSUInteger)Min(Max(0, box.y0), height - 1); NSUInteger y0 = (NSUInteger)Min(Max(0, box.y0), height - 1);
@ -405,8 +410,12 @@ metal__make_buffer(u32 size, id<MTLDevice> device){
buffer_offset += (vertex_count * sizeof(Render_Vertex)); buffer_offset += (vertex_count * sizeof(Render_Vertex));
} }
++group_count;
} }
printf("Group Count: %u\n", group_count);
[render_encoder endEncoding]; [render_encoder endEncoding];
// NOTE(yuval): Schedule a present once the framebuffer is complete using the current drawable // NOTE(yuval): Schedule a present once the framebuffer is complete using the current drawable
@ -422,7 +431,9 @@ metal__make_buffer(u32 size, id<MTLDevice> device){
// NOTE(yuval): Finalize rendering here and push the command buffer to the GPU // NOTE(yuval): Finalize rendering here and push the command buffer to the GPU
[command_buffer commit]; [command_buffer commit];
#if FRED_INTERNAL
[capture_scope endScope]; [capture_scope endScope];
#endif
} }
- (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind{ - (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind{

View File

@ -315,6 +315,22 @@ mac_error_box(char *msg, b32 shutdown = true){
//////////////////////////////// ////////////////////////////////
#if defined(FRED_INTERNAL)
function inline void
mac_profile(char *name, u64 begin, u64 end){
printf("%s Time: %fs\n", name, ((end - begin) / 1000000.0f));
}
#define MacProfileScope(name) for (u64 glue(_i_, __LINE__) = 0, glue(_begin_, __LINE__) = system_now_time();\
glue(_i_, __LINE__) == 0;\
glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_time()))
#else
# define mac_profile(...)
# define MacProfileScope(...)
#endif
////////////////////////////////
#import "mac_4ed_renderer.mm" #import "mac_4ed_renderer.mm"
#include "4ed_font_provider_freetype.h" #include "4ed_font_provider_freetype.h"
@ -545,21 +561,6 @@ mac_toggle_fullscreen(void){
//////////////////////////////// ////////////////////////////////
#if defined(FRED_INTERNAL)
function inline void
mac_profile(char *name, u64 begin, u64 end){
printf("%s Time: %fs\n", name, ((end - begin) / 1000000.0f));
}
#define MacProfileScope(name) for (u64 glue(_i_, __LINE__) = 0, glue(_begin_, __LINE__) = system_now_time();\
glue(_i_, __LINE__) == 0;\
glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_time()))
#else
# define MacProfileScope(...)
#endif
////////////////////////////////
@implementation FCoder_App_Delegate @implementation FCoder_App_Delegate
- (void)applicationDidFinishLaunching:(id)sender{ - (void)applicationDidFinishLaunching:(id)sender{
} }
@ -628,7 +629,12 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t
mac_resize(mac_vars.window); mac_resize(mac_vars.window);
} }
- (void)drawRect:(NSRect)bounds{ - (BOOL)wantsUpdateLayer
{
return YES;
}
- (void)updateLayer{
u64 prev_timer_start; u64 prev_timer_start;
MacProfileScope("Draw Rect"){ MacProfileScope("Draw Rect"){
@ -840,7 +846,9 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t
} }
mac_profile("Frame", prev_timer_start, mac_vars.timer_start); mac_profile("Frame", prev_timer_start, mac_vars.timer_start);
#if FRED_INTERNAL
printf("\n"); printf("\n");
#endif
} }
- (BOOL)acceptsFirstResponder{ - (BOOL)acceptsFirstResponder{
@ -856,8 +864,6 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t
} }
- (void)keyDown:(NSEvent*)event{ - (void)keyDown:(NSEvent*)event{
printf("Key Down: %#X\n", [event keyCode]);
// NOTE(yuval): Process keyboard event // NOTE(yuval): Process keyboard event
[self process_keyboard_event:event down:true]; [self process_keyboard_event:event down:true];
@ -896,7 +902,6 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t
} }
- (void)keyUp:(NSEvent*)event{ - (void)keyUp:(NSEvent*)event{
printf("Key Up: %#X\n", [event keyCode]);
[self process_keyboard_event:event down:false]; [self process_keyboard_event:event down:false];
} }
@ -988,7 +993,7 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t
} }
- (void)request_display{ - (void)request_display{
printf("Display Requested!\n"); //printf("Display Requested!\n");
CGRect cg_rect = CGRectMake(0, 0, mac_vars.width, mac_vars.height); CGRect cg_rect = CGRectMake(0, 0, mac_vars.width, mac_vars.height);
NSRect rect = NSRectFromCGRect(cg_rect); NSRect rect = NSRectFromCGRect(cg_rect);
[self setNeedsDisplayInRect:rect]; [self setNeedsDisplayInRect:rect];
@ -1068,6 +1073,10 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t
Vec2_i32 new_m = V2i32(backing_location.x, mac_vars.height - backing_location.y); Vec2_i32 new_m = V2i32(backing_location.x, mac_vars.height - backing_location.y);
if (new_m != mac_vars.input_chunk.pers.mouse){ if (new_m != mac_vars.input_chunk.pers.mouse){
mac_vars.input_chunk.pers.mouse = new_m; mac_vars.input_chunk.pers.mouse = new_m;
Rect_i32 screen = Ri32(0, 0, target.width, target.height);
mac_vars.input_chunk.trans.out_of_window = !rect_contains_point(screen, new_m);
} }
system_signal_step(0); system_signal_step(0);
@ -1270,6 +1279,7 @@ main(int arg_count, char **args){
mac_vars.view = [[FCoder_View alloc] init]; mac_vars.view = [[FCoder_View alloc] init];
[mac_vars.view setFrame:[content_view bounds]]; [mac_vars.view setFrame:[content_view bounds]];
[mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
mac_vars.view.wantsLayer = true;
// NOTE(yuval): Display window and view // NOTE(yuval): Display window and view
[content_view addSubview:mac_vars.view]; [content_view addSubview:mac_vars.view];

View File

@ -844,7 +844,9 @@ system_memory_annotation_sig(){
for (Memory_Annotation_Tracker_Node *node = memory_tracker.first; for (Memory_Annotation_Tracker_Node *node = memory_tracker.first;
node != 0; node != 0;
node = node->next){ node = node->next){
Memory_Annotation_Node *r_node = push_array(arena, Memory_Annotation_Node, 1); // TODO(yuval): Fix the API so that annotations would not mess with the system memory.
// Memory_Annotation_Node *r_node = push_array(arena, Memory_Annotation_Node, 1);
Memory_Annotation_Node *r_node = (Memory_Annotation_Node*)malloc(sizeof(Memory_Annotation_Node));
sll_queue_push(result.first, result.last, r_node); sll_queue_push(result.first, result.last, r_node);
result.count += 1; result.count += 1;

View File

@ -15,8 +15,6 @@ struct Mac_Metal{
function function
mac_render_sig(mac_metal__render){ mac_render_sig(mac_metal__render){
printf("Rendering using Metal!\n");
Mac_Metal *metal = (Mac_Metal*)renderer; Mac_Metal *metal = (Mac_Metal*)renderer;
[metal->view draw]; [metal->view draw];
} }
@ -77,8 +75,6 @@ mac_metal__init(NSWindow *window, Render_Target *target){
// TODO(yuval): This function should be exported to a DLL // TODO(yuval): This function should be exported to a DLL
function function
mac_load_renderer_sig(mac_load_metal_renderer){ mac_load_renderer_sig(mac_load_metal_renderer){
printf("Loding The Metal Renderer!\n");
Mac_Renderer *renderer = (Mac_Renderer*)mac_metal__init(window, target); Mac_Renderer *renderer = (Mac_Renderer*)mac_metal__init(window, target);
return(renderer); return(renderer);
} }