Started working on an abstraction for the macOS renderer implementations.
parent
521fb82113
commit
912bcae8a7
|
@ -263,8 +263,10 @@ metal__make_buffer(u32 size, id<MTLDevice> device){
|
|||
|
||||
[capture_scope beginScope];
|
||||
|
||||
i32 width = _target->width;
|
||||
i32 height = _target->height;
|
||||
// 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];
|
||||
i32 width = (i32)Min(_target->width, drawable_size.width);
|
||||
i32 height = (i32)Min(_target->height, drawable_size.height);
|
||||
|
||||
Font_Set *font_set = (Font_Set*)_target->font_set;
|
||||
|
||||
|
@ -332,6 +334,7 @@ metal__make_buffer(u32 size, id<MTLDevice> device){
|
|||
{
|
||||
Rect_i32 box = Ri32(group->clip_box);
|
||||
|
||||
|
||||
NSUInteger x0 = (NSUInteger)Min(Max(0, box.x0), width - 1);
|
||||
NSUInteger x1 = (NSUInteger)Min(Max(0, box.x1), width);
|
||||
NSUInteger y0 = (NSUInteger)Min(Max(0, box.y0), height - 1);
|
||||
|
|
|
@ -129,7 +129,7 @@ sd = abs(sd + half_thickness) - half_thickness;
|
|||
float shape_value = 1.0 - smoothstep(-1.0, 0.0, sd);
|
||||
shape_value *= has_thickness;
|
||||
|
||||
out_color = fragment_color;//vec4(fragment_color.xyz, fragment_color.a*(sample_value + shape_value));
|
||||
out_color = vec4(fragment_color.xyz, fragment_color.a*(sample_value + shape_value));
|
||||
}
|
||||
)foo";
|
||||
|
||||
|
@ -285,8 +285,6 @@ gl_render(Render_Target *t){
|
|||
t->free_texture_first = 0;
|
||||
t->free_texture_last = 0;
|
||||
|
||||
u32 all_vertex_count = 0;
|
||||
|
||||
u64 begin_draw = system_now_time();
|
||||
for (Render_Group *group = t->group_first;
|
||||
group != 0;
|
||||
|
@ -342,18 +340,9 @@ gl_render(Render_Target *t){
|
|||
glDisableVertexAttribArray(gpu_program.vertex_c);
|
||||
glDisableVertexAttribArray(gpu_program.vertex_ht);
|
||||
}
|
||||
|
||||
all_vertex_count += vertex_count;
|
||||
}
|
||||
u64 end_draw = system_now_time();
|
||||
printf("Draw time: %fs\n", mac_get_time_diff_sec(begin_draw, end_draw));
|
||||
|
||||
u64 begin_flush = system_now_time();
|
||||
glFlush();
|
||||
u64 end_flush = system_now_time();
|
||||
printf("Flush time: %fs\n", mac_get_time_diff_sec(begin_flush, end_flush));
|
||||
|
||||
printf("Drawn %d Vertices\n", all_vertex_count);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
|
|
@ -132,8 +132,6 @@ struct Mac_Input_Chunk{
|
|||
|
||||
////////////////////////////////
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
typedef i32 Mac_Object_Kind;
|
||||
enum{
|
||||
MacObjectKind_ERROR = 0,
|
||||
|
@ -203,7 +201,12 @@ struct Mac_Vars {
|
|||
|
||||
////////////////////////////////
|
||||
|
||||
#include "mac_4ed_renderer.h"
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
global Mac_Vars mac_vars;
|
||||
global Mac_Renderer *renderer;
|
||||
global Render_Target target;
|
||||
global App_Functions app;
|
||||
|
||||
|
@ -269,30 +272,6 @@ mac_to_object(Plat_Handle handle){
|
|||
|
||||
////////////////////////////////
|
||||
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include <OpenGL/gl.h>
|
||||
#import "mac_4ed_opengl.mm"
|
||||
|
||||
#import "mac_4ed_metal.mm"
|
||||
|
||||
#include "4ed_font_provider_freetype.h"
|
||||
#include "4ed_font_provider_freetype.cpp"
|
||||
|
||||
#import "mac_4ed_functions.mm"
|
||||
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
global Key_Code keycode_lookup_table[255];
|
||||
|
||||
function void
|
||||
mac_key_code_init(void){
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
function void
|
||||
mac_error_box(char *msg, b32 shutdown = true){
|
||||
NSAlert *alert = [[[NSAlert alloc] init] autorelease];
|
||||
|
@ -309,6 +288,26 @@ mac_error_box(char *msg, b32 shutdown = true){
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
#import "mac_4ed_renderer.mm"
|
||||
|
||||
#include "4ed_font_provider_freetype.h"
|
||||
#include "4ed_font_provider_freetype.cpp"
|
||||
|
||||
#import "mac_4ed_functions.mm"
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
global Key_Code keycode_lookup_table[255];
|
||||
|
||||
function void
|
||||
mac_key_code_init(void){
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
function b32
|
||||
mac_file_can_be_made(u8* filename){
|
||||
b32 result = access((char*)filename, W_OK) == 0;
|
||||
|
@ -389,7 +388,7 @@ mac_resize(NSWindow *window){
|
|||
}
|
||||
|
||||
- (void)viewDidChangeBackingProperties{
|
||||
// NOTE(yuval): Screen scale factor calculation
|
||||
// TODO(yuval): Screen scale factor calculation
|
||||
printf("Backing changed!\n");
|
||||
mac_resize(mac_vars.window);
|
||||
}
|
||||
|
@ -449,7 +448,8 @@ this only gets called for window creation and other extraordinary events.
|
|||
}
|
||||
|
||||
//mac_gl_render(&target);
|
||||
mac_metal_render(&target);
|
||||
//mac_metal_render(&target);
|
||||
renderer->render(renderer, &target);
|
||||
|
||||
mac_vars.first = false;
|
||||
|
||||
|
@ -707,8 +707,9 @@ main(int arg_count, char **args){
|
|||
[mac_vars.window makeKeyAndOrderFront:nil];
|
||||
|
||||
// NOTE(yuval): Initialize the renderer
|
||||
mac_gl_init(mac_vars.window);
|
||||
mac_metal_init(mac_vars.window);
|
||||
//mac_gl_init(mac_vars.window);
|
||||
//mac_metal_init(mac_vars.window, &target);
|
||||
renderer = mac_init_renderer(MacRenderer_OpenGL, mac_vars.window, &target);
|
||||
|
||||
mac_resize(w, h);
|
||||
|
||||
|
|
|
@ -804,13 +804,13 @@ system_get_keyboard_modifiers_sig(){
|
|||
|
||||
function
|
||||
graphics_get_texture_sig(){
|
||||
u32 result = mac_metal_get_texture(dim, texture_kind);
|
||||
u32 result = renderer->get_texture(renderer, dim, texture_kind);
|
||||
return(result);
|
||||
}
|
||||
|
||||
function
|
||||
graphics_fill_texture_sig(){
|
||||
b32 result = mac_metal_fill_texture(texture_kind, texture, p, dim, data);
|
||||
b32 result = renderer->fill_texture(renderer, texture_kind, texture, p, dim, data);
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ global Metal_Renderer *metal_renderer;
|
|||
global MTKView *metal_view;
|
||||
|
||||
function void
|
||||
mac_metal_init(NSWindow *window){
|
||||
mac_metal_init(NSWindow *window, Render_Target *target){
|
||||
// NOTE(yuval): Create Metal view
|
||||
NSView *content_view = [window contentView];
|
||||
|
||||
|
@ -26,11 +26,8 @@ mac_metal_init(NSWindow *window){
|
|||
|
||||
function void
|
||||
mac_metal_render(Render_Target* target){
|
||||
u64 begin_time = system_now_time();
|
||||
metal_renderer.target = target;
|
||||
[metal_view draw];
|
||||
u64 end_time = system_now_time();
|
||||
printf("Metal Render Time: %fs\n\n", mac_get_time_diff_sec(begin_time, end_time));
|
||||
}
|
||||
|
||||
function u32
|
||||
|
@ -50,4 +47,4 @@ mac_metal_fill_texture(Texture_Kind texture_kind, u32 texture, Vec3_i32 p, Vec3_
|
|||
data:data];
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,38 @@
|
|||
/* Mac OpenGL layer for 4coder */
|
||||
|
||||
#include "mac_4ed_renderer.h"
|
||||
|
||||
////////////////////////////////
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include <OpenGL/gl.h>
|
||||
|
||||
#include "opengl/4ed_opengl_defines.h"
|
||||
|
||||
#define GL_FUNC(N,R,P) typedef R (CALL_CONVENTION N##_Function)P; N##_Function *N = 0;
|
||||
#include "mac_4ed_opengl_funcs.h"
|
||||
|
||||
f64 mac_get_time_diff_sec(u64 begin, u64 end){
|
||||
f64 result = ((end - begin) / 1000000.0);
|
||||
return result;
|
||||
}
|
||||
////////////////////////////////
|
||||
|
||||
#include "opengl/4ed_opengl_render.cpp"
|
||||
|
||||
@interface OpenGLView : NSOpenGLView
|
||||
- (void)initGL;
|
||||
////////////////////////////////
|
||||
|
||||
@interface OpenGL_View : NSOpenGLView
|
||||
- (void)init_gl;
|
||||
- (void)render:(Render_Target*)target;
|
||||
@end
|
||||
|
||||
@implementation OpenGLView{
|
||||
b32 glIsInitialized;
|
||||
////////////////////////////////
|
||||
|
||||
struct Mac_OpenGL_Renderer{
|
||||
Mac_Renderer base;
|
||||
OpenGL_View *opengl_view;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
@implementation OpenGL_View{
|
||||
b32 gl_is_initialized;
|
||||
}
|
||||
|
||||
- (id)init{
|
||||
|
@ -27,8 +41,8 @@ f64 mac_get_time_diff_sec(u64 begin, u64 end){
|
|||
return nil;
|
||||
}
|
||||
|
||||
glIsInitialized = false;
|
||||
[self initGL];
|
||||
gl_is_initialized = false;
|
||||
[self init_gl];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -43,13 +57,13 @@ f64 mac_get_time_diff_sec(u64 begin, u64 end){
|
|||
[[self openGLContext] makeCurrentContext];
|
||||
|
||||
// NOTE(yuval): Setup vsync
|
||||
GLint swapInt = 1;
|
||||
printf("Using vsync: %d\n", swapInt);
|
||||
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
||||
GLint swap_int = 1;
|
||||
printf("Using vsync: %d\n", swap_int);
|
||||
[[self openGLContext] setValues:&swap_int forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
|
||||
- (void)awakeFromNib{
|
||||
[self initGL];
|
||||
[self init_gl];
|
||||
}
|
||||
|
||||
- (void)reshape{
|
||||
|
@ -59,8 +73,8 @@ f64 mac_get_time_diff_sec(u64 begin, u64 end){
|
|||
[[self openGLContext] update];
|
||||
}
|
||||
|
||||
- (void)initGL{
|
||||
if (glIsInitialized){
|
||||
- (void)init_gl{
|
||||
if (gl_is_initialized){
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -92,65 +106,78 @@ f64 mac_get_time_diff_sec(u64 begin, u64 end){
|
|||
|
||||
[pixel_format release];
|
||||
|
||||
glIsInitialized = true;
|
||||
gl_is_initialized = true;
|
||||
}
|
||||
|
||||
- (void)render:(Render_Target*)target{
|
||||
Assert(glIsInitialized);
|
||||
Assert(gl_is_initialized);
|
||||
|
||||
u64 context_lock_begin = system_now_time();
|
||||
CGLLockContext([[self openGLContext] CGLContextObj]);
|
||||
u64 context_lock_end = system_now_time();
|
||||
printf("Context lock time: %fs\n", mac_get_time_diff_sec(context_lock_begin, context_lock_end));
|
||||
|
||||
u64 make_current_context_begin = system_now_time();
|
||||
[[self openGLContext] makeCurrentContext];
|
||||
u64 make_current_context_end = system_now_time();
|
||||
printf("Make current context time: %fs\n", mac_get_time_diff_sec(make_current_context_begin, make_current_context_end));
|
||||
|
||||
u64 gl_render_begin = system_now_time();
|
||||
gl_render(target);
|
||||
u64 gl_render_end = system_now_time();
|
||||
printf("GL render time: %fs\n", mac_get_time_diff_sec(gl_render_begin, gl_render_end));
|
||||
|
||||
u64 gl_flush_buffer_begin = system_now_time();
|
||||
[[self openGLContext] flushBuffer];
|
||||
u64 gl_flush_buffer_end = system_now_time();
|
||||
printf("GL flush buffer time: %fs\n", mac_get_time_diff_sec(gl_flush_buffer_begin, gl_flush_buffer_end));
|
||||
|
||||
u64 context_unlock_begin = system_now_time();
|
||||
CGLUnlockContext([[self openGLContext] CGLContextObj]);
|
||||
u64 context_unlock_end = system_now_time();
|
||||
printf("Context unlock time: %fs\n", mac_get_time_diff_sec(context_unlock_begin, context_unlock_end));
|
||||
}
|
||||
@end
|
||||
|
||||
global OpenGLView *opengl_view;
|
||||
////////////////////////////////
|
||||
|
||||
function void
|
||||
mac_gl_init(NSWindow *window){
|
||||
// NOTE(yuval): Create OpenGLView
|
||||
function
|
||||
mac_render_sig(mac_gl_render){
|
||||
printf("Rendering using OpenGL!\n");
|
||||
|
||||
Mac_OpenGL_Renderer *gl = (Mac_OpenGL_Renderer*)renderer;
|
||||
[gl->opengl_view render:target];
|
||||
}
|
||||
|
||||
function
|
||||
mac_get_texture_sig(mac_gl_get_texture){
|
||||
u32 result = gl__get_texture(dim, texture_kind);
|
||||
return(result);
|
||||
}
|
||||
|
||||
function
|
||||
mac_fill_texture_sig(mac_gl_fill_texture){
|
||||
b32 result = gl__fill_texture(texture_kind, texture, p, dim, data);
|
||||
return(result);
|
||||
}
|
||||
|
||||
function Mac_OpenGL_Renderer*
|
||||
mac_gl__init(NSWindow *window, Render_Target *target){
|
||||
// NOTE(yuval): Create the Mac Renderer
|
||||
Mac_OpenGL_Renderer *gl = (Mac_OpenGL_Renderer*)system_memory_allocate(sizeof(Mac_OpenGL_Renderer),
|
||||
file_name_line_number_lit_u8);
|
||||
gl->base.render = mac_gl_render;
|
||||
gl->base.get_texture = mac_gl_get_texture;
|
||||
gl->base.fill_texture = mac_gl_fill_texture;
|
||||
|
||||
// NOTE(yuval): Create the OpenGL view
|
||||
NSView *content_view = [window contentView];
|
||||
|
||||
opengl_view = [[OpenGLView alloc] init];
|
||||
[opengl_view setFrame:[content_view bounds]];
|
||||
[opengl_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
[opengl_view setWantsBestResolutionOpenGLSurface:YES];
|
||||
gl->opengl_view = [[OpenGL_View alloc] init];
|
||||
[gl->opengl_view setFrame:[content_view bounds]];
|
||||
[gl->opengl_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
[gl->opengl_view setWantsBestResolutionOpenGLSurface:YES];
|
||||
|
||||
// NOTE(yuval): Add the OpenGL view as a subview of the window
|
||||
[content_view addSubview:opengl_view];
|
||||
[content_view addSubview:gl->opengl_view];
|
||||
|
||||
// NOTE(yuval): Load gl functions
|
||||
void *gl_image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
|
||||
|
||||
#define GL_FUNC(f,R,P) ((f) = (f##_Function*)dlsym(gl_image, #f));
|
||||
#include "mac_4ed_opengl_funcs.h"
|
||||
|
||||
return(gl);
|
||||
}
|
||||
|
||||
function void
|
||||
mac_gl_render(Render_Target* target){
|
||||
u64 begin_time = system_now_time();
|
||||
[opengl_view render:target];
|
||||
u64 end_time = system_now_time();
|
||||
printf("Render Time: %fs\n\n", mac_get_time_diff_sec(begin_time, end_time));
|
||||
}
|
||||
// TODO(yuval): This function should be exported to a DLL
|
||||
function
|
||||
mac_load_renderer_sig(mac_load_opengl_renderer){
|
||||
printf("Initializing The OpenGL Renderer!\n");
|
||||
|
||||
Mac_Renderer *renderer = (Mac_Renderer*)mac_gl__init(window, target);
|
||||
return(renderer);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/* Mac Renderer Abstraction */
|
||||
|
||||
#if !defined(FRED_MAC_RENDERER_H)
|
||||
#define FRED_MAC_RENDERER_H
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
// TODO(yuval): This should be refactored into a platform independent renderer
|
||||
|
||||
struct Mac_Renderer;
|
||||
|
||||
#define mac_render_sig(name) void name(Mac_Renderer *renderer, Render_Target *target)
|
||||
typedef mac_render_sig(mac_render_type);
|
||||
|
||||
#define mac_get_texture_sig(name) u32 name(Mac_Renderer *renderer, Vec3_i32 dim, Texture_Kind texture_kind)
|
||||
typedef mac_get_texture_sig(mac_get_texture_type);
|
||||
|
||||
#define mac_fill_texture_sig(name) b32 name(Mac_Renderer *renderer, Texture_Kind texture_kind, u32 texture, Vec3_i32 p, Vec3_i32 dim, void* data)
|
||||
typedef mac_fill_texture_sig(mac_fill_texture_type);
|
||||
|
||||
typedef i32 Mac_Renderer_Kind;
|
||||
enum{
|
||||
MacRenderer_OpenGL,
|
||||
MacRenderer_Metal
|
||||
};
|
||||
|
||||
struct Mac_Renderer{
|
||||
mac_render_type *render;
|
||||
|
||||
mac_get_texture_type *get_texture;
|
||||
mac_fill_texture_type *fill_texture;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
// NOTE(yuval): This is the actual platform dependent function that each renderer implementation implements and should be exported into a DLL
|
||||
#define mac_load_renderer_sig(name) Mac_Renderer* name(NSWindow *window, Render_Target *target)
|
||||
typedef mac_load_renderer_sig(mac_load_renderer_type);
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
/* Mac Renderer Abstraction Implementation */
|
||||
|
||||
// TODO(yuval): This should NOT be included here once the renderer is exported to a DLL
|
||||
#import "mac_4ed_opengl.mm"
|
||||
#import "mac_4ed_metal.mm"
|
||||
|
||||
function Mac_Renderer*
|
||||
mac_init_renderer(Mac_Renderer_Kind kind, NSWindow *window, Render_Target *target){
|
||||
// TODO(yuval): Import renderer load function from a DLL instead of using a switch statement and a renderer kind. This would allow us to switch the renderer backend and implemented new backends with ease.
|
||||
|
||||
Mac_Renderer *result = 0;
|
||||
|
||||
switch (kind){
|
||||
case MacRenderer_OpenGL:
|
||||
{
|
||||
result = mac_load_opengl_renderer(window, target);
|
||||
} break;
|
||||
|
||||
case MacRenderer_Metal:
|
||||
{
|
||||
//result = mac_load_metal_renderer(window, target);
|
||||
} break;
|
||||
|
||||
default: InvalidPath;
|
||||
}
|
||||
|
||||
if (!result){
|
||||
mac_error_box("Unable to initialize the renderer!");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
Loading…
Reference in New Issue