splitting graphics_surface and graphics_common in order to isolate surface dispatch stuff from orca apps
This commit is contained in:
		
							parent
							
								
									346979a21a
								
							
						
					
					
						commit
						ca1caf8537
					
				|  | @ -1,6 +1,6 @@ | |||
| /************************************************************//**
 | ||||
| * | ||||
| *	@file: graphics.c | ||||
| *	@file: graphics_common.c | ||||
| *	@author: Martin Fouilleul | ||||
| *	@date: 23/01/2023 | ||||
| *	@revision: | ||||
|  | @ -62,7 +62,6 @@ typedef struct mg_font_data | |||
| } mg_font_data; | ||||
| 
 | ||||
| typedef struct mg_canvas_data mg_canvas_data; | ||||
| typedef struct mg_image_data mg_image_data; | ||||
| 
 | ||||
| typedef enum mg_handle_kind | ||||
| { | ||||
|  | @ -123,18 +122,10 @@ typedef struct mg_canvas_data | |||
| 
 | ||||
| 	//NOTE: these are used at render time
 | ||||
| 	mg_color clearColor; | ||||
| 	mp_rect clip; | ||||
| 	mg_mat2x3 transform; | ||||
| 	mg_image image; | ||||
| 	mp_rect srcRegion; | ||||
| 
 | ||||
| 	vec4 shapeExtents; | ||||
| 	vec4 shapeScreenExtents; | ||||
| 	u32 nextShapeIndex; | ||||
| 	u32 vertexCount; | ||||
| 	u32 indexCount; | ||||
| 
 | ||||
| 	int splitCount; | ||||
| } mg_canvas_data; | ||||
| 
 | ||||
| static mg_data __mgData = {0}; | ||||
|  | @ -221,347 +212,6 @@ void* mg_data_from_handle(mg_handle_kind kind, u64 h) | |||
| 	return(data); | ||||
| } | ||||
| 
 | ||||
| //---------------------------------------------------------------
 | ||||
| // typed handles functions
 | ||||
| //---------------------------------------------------------------
 | ||||
| mg_surface mg_surface_handle_alloc(mg_surface_data* surface) | ||||
| { | ||||
| 	mg_surface handle = {.h = mg_handle_alloc(MG_HANDLE_SURFACE, (void*)surface) }; | ||||
| 	return(handle); | ||||
| } | ||||
| 
 | ||||
| mg_surface_data* mg_surface_data_from_handle(mg_surface handle) | ||||
| { | ||||
| 	mg_surface_data* data = mg_data_from_handle(MG_HANDLE_SURFACE, handle.h); | ||||
| 	return(data); | ||||
| } | ||||
| 
 | ||||
| mg_canvas mg_canvas_handle_alloc(mg_canvas_data* canvas) | ||||
| { | ||||
| 	mg_canvas handle = {.h = mg_handle_alloc(MG_HANDLE_CANVAS, (void*)canvas) }; | ||||
| 	return(handle); | ||||
| } | ||||
| 
 | ||||
| mg_canvas_data* mg_canvas_data_from_handle(mg_canvas handle) | ||||
| { | ||||
| 	mg_canvas_data* data = mg_data_from_handle(MG_HANDLE_CANVAS, handle.h); | ||||
| 	return(data); | ||||
| } | ||||
| 
 | ||||
| mg_font mg_font_handle_alloc(mg_font_data* font) | ||||
| { | ||||
| 	mg_font handle = {.h = mg_handle_alloc(MG_HANDLE_FONT, (void*)font) }; | ||||
| 	return(handle); | ||||
| } | ||||
| 
 | ||||
| mg_font_data* mg_font_data_from_handle(mg_font handle) | ||||
| { | ||||
| 	mg_font_data* data = mg_data_from_handle(MG_HANDLE_FONT, handle.h); | ||||
| 	return(data); | ||||
| } | ||||
| 
 | ||||
| mg_image mg_image_handle_alloc(mg_image_data* image) | ||||
| { | ||||
| 	mg_image handle = {.h = mg_handle_alloc(MG_HANDLE_IMAGE, (void*)image) }; | ||||
| 	return(handle); | ||||
| } | ||||
| 
 | ||||
| mg_image_data* mg_image_data_from_handle(mg_image handle) | ||||
| { | ||||
| 	mg_image_data* data = mg_data_from_handle(MG_HANDLE_IMAGE, handle.h); | ||||
| 	return(data); | ||||
| } | ||||
| 
 | ||||
| //---------------------------------------------------------------
 | ||||
| // surface API
 | ||||
| //---------------------------------------------------------------
 | ||||
| 
 | ||||
| #if MG_COMPILE_GL | ||||
| 	#if PLATFORM_WINDOWS | ||||
| 		#include"wgl_surface.h" | ||||
| 		#define gl_surface_create_for_window mg_wgl_surface_create_for_window | ||||
| 	#endif | ||||
| #endif | ||||
| 
 | ||||
| #if MG_COMPILE_GLES | ||||
| 	#include"egl_surface.h" | ||||
| #endif | ||||
| 
 | ||||
| #if MG_COMPILE_METAL | ||||
| 	#include"mtl_surface.h" | ||||
| #endif | ||||
| 
 | ||||
| #if MG_COMPILE_CANVAS | ||||
| 	#if PLATFORM_MACOS | ||||
| 		mg_surface_data* mtl_canvas_surface_create_for_window(mp_window window); | ||||
| 	#elif PLATFORM_WINDOWS | ||||
| 		//TODO
 | ||||
| 	#endif | ||||
| #endif | ||||
| 
 | ||||
| bool mg_is_surface_backend_available(mg_surface_api api) | ||||
| { | ||||
| 	bool result = false; | ||||
| 	switch(api) | ||||
| 	{ | ||||
| 		#if MG_COMPILE_METAL | ||||
| 			case MG_METAL: | ||||
| 		#endif | ||||
| 
 | ||||
| 		#if MG_COMPILE_GL | ||||
| 			case MG_GL: | ||||
| 		#endif | ||||
| 
 | ||||
| 		#if MG_COMPILE_GLES | ||||
| 			case MG_GLES: | ||||
| 		#endif | ||||
| 
 | ||||
| 		#if MG_COMPILE_CANVAS | ||||
| 			case MG_CANVAS: | ||||
| 		#endif | ||||
| 			result = true; | ||||
| 			break; | ||||
| 
 | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| 	return(result); | ||||
| } | ||||
| 
 | ||||
| mg_surface mg_surface_nil() { return((mg_surface){.h = 0}); } | ||||
| bool mg_surface_is_nil(mg_surface surface) { return(surface.h == 0); } | ||||
| 
 | ||||
| mg_surface mg_surface_create_for_window(mp_window window, mg_surface_api api) | ||||
| { | ||||
| 	if(__mgData.init) | ||||
| 	{ | ||||
| 		mg_init(); | ||||
| 	} | ||||
| 	mg_surface surfaceHandle = mg_surface_nil(); | ||||
| 	mg_surface_data* surface = 0; | ||||
| 
 | ||||
| 	switch(api) | ||||
| 	{ | ||||
| 	#if MG_COMPILE_GL | ||||
| 		case MG_GL: | ||||
| 			surface = gl_surface_create_for_window(window); | ||||
| 			break; | ||||
| 	#endif | ||||
| 
 | ||||
| 	#if MG_COMPILE_GLES | ||||
| 		case MG_GLES: | ||||
| 			surface = mg_egl_surface_create_for_window(window); | ||||
| 			break; | ||||
| 	#endif | ||||
| 
 | ||||
| 	#if MG_COMPILE_METAL | ||||
| 		case MG_METAL: | ||||
| 			surface = mg_mtl_surface_create_for_window(window); | ||||
| 			break; | ||||
| 	#endif | ||||
| 
 | ||||
| 	#if MG_COMPILE_CANVAS | ||||
| 		case MG_CANVAS: | ||||
| 
 | ||||
| 		#if PLATFORM_MACOS | ||||
| 			surface = mtl_canvas_surface_create_for_window(window); | ||||
| 		#elif PLATFORM_WINDOWS | ||||
| 			surface = gl_canvas_surface_create_for_window(window); | ||||
| 		#endif | ||||
| 			break; | ||||
| 	#endif | ||||
| 
 | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| 	if(surface) | ||||
| 	{ | ||||
| 		surfaceHandle = mg_surface_handle_alloc(surface); | ||||
| 	} | ||||
| 	return(surfaceHandle); | ||||
| } | ||||
| 
 | ||||
| mg_surface mg_surface_create_remote(u32 width, u32 height, mg_surface_api api) | ||||
| { | ||||
| 	if(__mgData.init) | ||||
| 	{ | ||||
| 		mg_init(); | ||||
| 	} | ||||
| 	mg_surface surfaceHandle = mg_surface_nil(); | ||||
| 	mg_surface_data* surface = 0; | ||||
| 
 | ||||
| 	switch(api) | ||||
| 	{ | ||||
| 	#if MG_COMPILE_GLES | ||||
| 		case MG_GLES: | ||||
| 			surface = mg_egl_surface_create_remote(width, height); | ||||
| 			break; | ||||
| 	#endif | ||||
| 
 | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| 	if(surface) | ||||
| 	{ | ||||
| 		surfaceHandle = mg_surface_handle_alloc(surface); | ||||
| 	} | ||||
| 	return(surfaceHandle); | ||||
| } | ||||
| 
 | ||||
| mg_surface mg_surface_create_host(mp_window window) | ||||
| { | ||||
| 	if(__mgData.init) | ||||
| 	{ | ||||
| 		mg_init(); | ||||
| 	} | ||||
| 	mg_surface handle = mg_surface_nil(); | ||||
| 	mg_surface_data* surface = 0; | ||||
| 	#if PLATFORM_MACOS | ||||
| 		surface = mg_osx_surface_create_host(window); | ||||
| 	#elif PLATFORM_WINDOWS | ||||
| 		surface = mg_win32_surface_create_host(window); | ||||
| 	#endif | ||||
| 
 | ||||
| 	if(surface) | ||||
| 	{ | ||||
| 		handle = mg_surface_handle_alloc(surface); | ||||
| 	} | ||||
| 	return(handle); | ||||
| } | ||||
| 
 | ||||
| void mg_surface_destroy(mg_surface handle) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mg_surface_data* surface = mg_surface_data_from_handle(handle); | ||||
| 	if(surface) | ||||
| 	{ | ||||
| 		if(surface->backend && surface->backend->destroy) | ||||
| 		{ | ||||
| 			surface->backend->destroy(surface->backend); | ||||
| 		} | ||||
| 		surface->destroy(surface); | ||||
| 		mg_handle_recycle(handle.h); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void mg_surface_prepare(mg_surface surface) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->prepare) | ||||
| 	{ | ||||
| 		surfaceData->prepare(surfaceData); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void mg_surface_present(mg_surface surface) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->present) | ||||
| 	{ | ||||
| 		surfaceData->present(surfaceData); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void mg_surface_swap_interval(mg_surface surface, int swap) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->swapInterval) | ||||
| 	{ | ||||
| 		surfaceData->swapInterval(surfaceData, swap); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| vec2 mg_surface_contents_scaling(mg_surface surface) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	vec2 scaling = {1, 1}; | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->contentsScaling) | ||||
| 	{ | ||||
| 		scaling = surfaceData->contentsScaling(surfaceData); | ||||
| 	} | ||||
| 	return(scaling); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void mg_surface_set_frame(mg_surface surface, mp_rect frame) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->setFrame) | ||||
| 	{ | ||||
| 		surfaceData->setFrame(surfaceData, frame); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| mp_rect mg_surface_get_frame(mg_surface surface) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mp_rect res = {0}; | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->getFrame) | ||||
| 	{ | ||||
| 		res = surfaceData->getFrame(surfaceData); | ||||
| 	} | ||||
| 	return(res); | ||||
| } | ||||
| 
 | ||||
| void mg_surface_set_hidden(mg_surface surface, bool hidden) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->setHidden) | ||||
| 	{ | ||||
| 		surfaceData->setHidden(surfaceData, hidden); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| bool mg_surface_get_hidden(mg_surface surface) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	bool res = false; | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->getHidden) | ||||
| 	{ | ||||
| 		res = surfaceData->getHidden(surfaceData); | ||||
| 	} | ||||
| 	return(res); | ||||
| } | ||||
| 
 | ||||
| void* mg_surface_native_layer(mg_surface surface) | ||||
| { | ||||
| 	void* res = 0; | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->nativeLayer) | ||||
| 	{ | ||||
| 		res = surfaceData->nativeLayer(surfaceData); | ||||
| 	} | ||||
| 	return(res); | ||||
| } | ||||
| 
 | ||||
| mg_surface_id mg_surface_remote_id(mg_surface handle) | ||||
| { | ||||
| 	mg_surface_id remoteId = 0; | ||||
| 	mg_surface_data* surface = mg_surface_data_from_handle(handle); | ||||
| 	if(surface && surface->remoteID) | ||||
| 	{ | ||||
| 		remoteId = surface->remoteID(surface); | ||||
| 	} | ||||
| 	return(remoteId); | ||||
| } | ||||
| 
 | ||||
| void mg_surface_host_connect(mg_surface handle, mg_surface_id remoteID) | ||||
| { | ||||
| 	mg_surface_data* surface = mg_surface_data_from_handle(handle); | ||||
| 	if(surface && surface->hostConnect) | ||||
| 	{ | ||||
| 		surface->hostConnect(surface, remoteID); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //------------------------------------------------------------------------------------------
 | ||||
| //NOTE(martin): graphics canvas internal
 | ||||
| //------------------------------------------------------------------------------------------
 | ||||
|  | @ -740,6 +390,18 @@ void mg_path_push_element(mg_canvas_data* canvas, mg_path_elt elt) | |||
| mg_font mg_font_nil() { return((mg_font){.h = 0}); } | ||||
| bool mg_font_is_nil(mg_font font) { return(font.h == 0); } | ||||
| 
 | ||||
| mg_font mg_font_handle_alloc(mg_font_data* font) | ||||
| { | ||||
| 	mg_font handle = {.h = mg_handle_alloc(MG_HANDLE_FONT, (void*)font) }; | ||||
| 	return(handle); | ||||
| } | ||||
| 
 | ||||
| mg_font_data* mg_font_data_from_handle(mg_font handle) | ||||
| { | ||||
| 	mg_font_data* data = mg_data_from_handle(MG_HANDLE_FONT, handle.h); | ||||
| 	return(data); | ||||
| } | ||||
| 
 | ||||
| mg_font mg_font_create_from_memory(u32 size, byte* buffer, u32 rangeCount, unicode_range* ranges) | ||||
| { | ||||
| 	if(!__mgData.init) | ||||
|  | @ -1189,6 +851,18 @@ mp_rect mg_text_bounding_box(mg_font font, f32 fontSize, str8 text) | |||
| mg_canvas mg_canvas_nil() { return((mg_canvas){.h = 0}); } | ||||
| bool mg_canvas_is_nil(mg_canvas canvas) { return(canvas.h == 0); } | ||||
| 
 | ||||
| mg_canvas mg_canvas_handle_alloc(mg_canvas_data* canvas) | ||||
| { | ||||
| 	mg_canvas handle = {.h = mg_handle_alloc(MG_HANDLE_CANVAS, (void*)canvas) }; | ||||
| 	return(handle); | ||||
| } | ||||
| 
 | ||||
| mg_canvas_data* mg_canvas_data_from_handle(mg_canvas handle) | ||||
| { | ||||
| 	mg_canvas_data* data = mg_data_from_handle(MG_HANDLE_CANVAS, handle.h); | ||||
| 	return(data); | ||||
| } | ||||
| 
 | ||||
| mg_canvas mg_canvas_create() | ||||
| { | ||||
| 	mg_canvas canvasHandle = mg_canvas_nil(); | ||||
|  | @ -1896,38 +1570,6 @@ void mg_arc(f32 x, f32 y, f32 r, f32 arcAngle, f32 startAngle) | |||
| mg_image mg_image_nil() { return((mg_image){.h = 0}); } | ||||
| bool mg_image_is_nil(mg_image image) { return(image.h == 0); } | ||||
| 
 | ||||
| vec2 mg_image_size(mg_image image) | ||||
| { | ||||
| 	vec2 res = {0}; | ||||
| 	mg_canvas_data* canvas = __mgCurrentCanvas; | ||||
| 	if(canvas) | ||||
| 	{ | ||||
| 		mg_image_data* imageData = mg_image_data_from_handle(image); | ||||
| 		if(imageData) | ||||
| 		{ | ||||
| 			res = imageData->size; | ||||
| 		} | ||||
| 	} | ||||
| 	return(res); | ||||
| } | ||||
| 
 | ||||
| mg_image mg_image_create(mg_surface surface, u32 width, u32 height) | ||||
| { | ||||
| 	mg_image image = mg_image_nil(); | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->backend) | ||||
| 	{ | ||||
| 		DEBUG_ASSERT(surfaceData->api == MG_CANVAS); | ||||
| 
 | ||||
| 		mg_image_data* imageData = surfaceData->backend->imageCreate(surfaceData->backend, (vec2){width, height}); | ||||
| 		if(imageData) | ||||
| 		{ | ||||
| 			image = mg_image_handle_alloc(imageData); | ||||
| 		} | ||||
| 	} | ||||
| 	return(image); | ||||
| } | ||||
| 
 | ||||
| mg_image mg_image_create_from_rgba8(mg_surface surface, u32 width, u32 height, u8* pixels) | ||||
| { | ||||
| 	mg_image image = mg_image_create(surface, width, height); | ||||
|  | @ -1971,33 +1613,6 @@ mg_image mg_image_create_from_file(mg_surface surface, str8 path, bool flip) | |||
| 	return(image); | ||||
| } | ||||
| 
 | ||||
| void mg_image_destroy(mg_image image) | ||||
| { | ||||
| 	mg_image_data* imageData = mg_image_data_from_handle(image); | ||||
| 	if(imageData) | ||||
| 	{ | ||||
| 		mg_surface_data* surface = mg_surface_data_from_handle(imageData->surface); | ||||
| 		if(surface && surface->backend) | ||||
| 		{ | ||||
| 			surface->backend->imageDestroy(surface->backend, imageData); | ||||
| 			mg_handle_recycle(image.h); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void mg_image_upload_region_rgba8(mg_image image, mp_rect region, u8* pixels) | ||||
| { | ||||
| 	mg_image_data* imageData = mg_image_data_from_handle(image); | ||||
| 	if(imageData) | ||||
| 	{ | ||||
| 		mg_surface_data* surfaceData = mg_surface_data_from_handle(imageData->surface); | ||||
| 		if(surfaceData) | ||||
| 		{ | ||||
| 			DEBUG_ASSERT(surfaceData->backend); | ||||
| 			surfaceData->backend->imageUploadRegion(surfaceData->backend, imageData, region, pixels); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void mg_image_draw_region(mg_image image, mp_rect srcRegion, mp_rect dstRegion) | ||||
| { | ||||
|  | @ -0,0 +1,392 @@ | |||
| /************************************************************//**
 | ||||
| * | ||||
| *	@file: graphics_surface.c | ||||
| *	@author: Martin Fouilleul | ||||
| *	@date: 25/04/2023 | ||||
| * | ||||
| *****************************************************************/ | ||||
| 
 | ||||
| #include"graphics_internal.h" | ||||
| 
 | ||||
| 
 | ||||
| //---------------------------------------------------------------
 | ||||
| // typed handles functions
 | ||||
| //---------------------------------------------------------------
 | ||||
| 
 | ||||
| mg_surface mg_surface_handle_alloc(mg_surface_data* surface) | ||||
| { | ||||
| 	mg_surface handle = {.h = mg_handle_alloc(MG_HANDLE_SURFACE, (void*)surface) }; | ||||
| 	return(handle); | ||||
| } | ||||
| 
 | ||||
| mg_surface_data* mg_surface_data_from_handle(mg_surface handle) | ||||
| { | ||||
| 	mg_surface_data* data = mg_data_from_handle(MG_HANDLE_SURFACE, handle.h); | ||||
| 	return(data); | ||||
| } | ||||
| 
 | ||||
| mg_image mg_image_handle_alloc(mg_image_data* image) | ||||
| { | ||||
| 	mg_image handle = {.h = mg_handle_alloc(MG_HANDLE_IMAGE, (void*)image) }; | ||||
| 	return(handle); | ||||
| } | ||||
| 
 | ||||
| mg_image_data* mg_image_data_from_handle(mg_image handle) | ||||
| { | ||||
| 	mg_image_data* data = mg_data_from_handle(MG_HANDLE_IMAGE, handle.h); | ||||
| 	return(data); | ||||
| } | ||||
| 
 | ||||
| //---------------------------------------------------------------
 | ||||
| // surface API
 | ||||
| //---------------------------------------------------------------
 | ||||
| 
 | ||||
| #if MG_COMPILE_GL | ||||
| 	#if PLATFORM_WINDOWS | ||||
| 		#include"wgl_surface.h" | ||||
| 		#define gl_surface_create_for_window mg_wgl_surface_create_for_window | ||||
| 	#endif | ||||
| #endif | ||||
| 
 | ||||
| #if MG_COMPILE_GLES | ||||
| 	#include"egl_surface.h" | ||||
| #endif | ||||
| 
 | ||||
| #if MG_COMPILE_METAL | ||||
| 	#include"mtl_surface.h" | ||||
| #endif | ||||
| 
 | ||||
| #if MG_COMPILE_CANVAS | ||||
| 	#if PLATFORM_MACOS | ||||
| 		mg_surface_data* mtl_canvas_surface_create_for_window(mp_window window); | ||||
| 	#elif PLATFORM_WINDOWS | ||||
| 		//TODO
 | ||||
| 	#endif | ||||
| #endif | ||||
| 
 | ||||
| bool mg_is_surface_backend_available(mg_surface_api api) | ||||
| { | ||||
| 	bool result = false; | ||||
| 	switch(api) | ||||
| 	{ | ||||
| 		#if MG_COMPILE_METAL | ||||
| 			case MG_METAL: | ||||
| 		#endif | ||||
| 
 | ||||
| 		#if MG_COMPILE_GL | ||||
| 			case MG_GL: | ||||
| 		#endif | ||||
| 
 | ||||
| 		#if MG_COMPILE_GLES | ||||
| 			case MG_GLES: | ||||
| 		#endif | ||||
| 
 | ||||
| 		#if MG_COMPILE_CANVAS | ||||
| 			case MG_CANVAS: | ||||
| 		#endif | ||||
| 			result = true; | ||||
| 			break; | ||||
| 
 | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| 	return(result); | ||||
| } | ||||
| 
 | ||||
| mg_surface mg_surface_nil() { return((mg_surface){.h = 0}); } | ||||
| bool mg_surface_is_nil(mg_surface surface) { return(surface.h == 0); } | ||||
| 
 | ||||
| mg_surface mg_surface_create_for_window(mp_window window, mg_surface_api api) | ||||
| { | ||||
| 	if(__mgData.init) | ||||
| 	{ | ||||
| 		mg_init(); | ||||
| 	} | ||||
| 	mg_surface surfaceHandle = mg_surface_nil(); | ||||
| 	mg_surface_data* surface = 0; | ||||
| 
 | ||||
| 	switch(api) | ||||
| 	{ | ||||
| 	#if MG_COMPILE_GL | ||||
| 		case MG_GL: | ||||
| 			surface = gl_surface_create_for_window(window); | ||||
| 			break; | ||||
| 	#endif | ||||
| 
 | ||||
| 	#if MG_COMPILE_GLES | ||||
| 		case MG_GLES: | ||||
| 			surface = mg_egl_surface_create_for_window(window); | ||||
| 			break; | ||||
| 	#endif | ||||
| 
 | ||||
| 	#if MG_COMPILE_METAL | ||||
| 		case MG_METAL: | ||||
| 			surface = mg_mtl_surface_create_for_window(window); | ||||
| 			break; | ||||
| 	#endif | ||||
| 
 | ||||
| 	#if MG_COMPILE_CANVAS | ||||
| 		case MG_CANVAS: | ||||
| 
 | ||||
| 		#if PLATFORM_MACOS | ||||
| 			surface = mtl_canvas_surface_create_for_window(window); | ||||
| 		#elif PLATFORM_WINDOWS | ||||
| 			surface = gl_canvas_surface_create_for_window(window); | ||||
| 		#endif | ||||
| 			break; | ||||
| 	#endif | ||||
| 
 | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| 	if(surface) | ||||
| 	{ | ||||
| 		surfaceHandle = mg_surface_handle_alloc(surface); | ||||
| 	} | ||||
| 	return(surfaceHandle); | ||||
| } | ||||
| 
 | ||||
| mg_surface mg_surface_create_remote(u32 width, u32 height, mg_surface_api api) | ||||
| { | ||||
| 	if(__mgData.init) | ||||
| 	{ | ||||
| 		mg_init(); | ||||
| 	} | ||||
| 	mg_surface surfaceHandle = mg_surface_nil(); | ||||
| 	mg_surface_data* surface = 0; | ||||
| 
 | ||||
| 	switch(api) | ||||
| 	{ | ||||
| 	#if MG_COMPILE_GLES | ||||
| 		case MG_GLES: | ||||
| 			surface = mg_egl_surface_create_remote(width, height); | ||||
| 			break; | ||||
| 	#endif | ||||
| 
 | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| 	if(surface) | ||||
| 	{ | ||||
| 		surfaceHandle = mg_surface_handle_alloc(surface); | ||||
| 	} | ||||
| 	return(surfaceHandle); | ||||
| } | ||||
| 
 | ||||
| mg_surface mg_surface_create_host(mp_window window) | ||||
| { | ||||
| 	if(__mgData.init) | ||||
| 	{ | ||||
| 		mg_init(); | ||||
| 	} | ||||
| 	mg_surface handle = mg_surface_nil(); | ||||
| 	mg_surface_data* surface = 0; | ||||
| 	#if PLATFORM_MACOS | ||||
| 		surface = mg_osx_surface_create_host(window); | ||||
| 	#elif PLATFORM_WINDOWS | ||||
| 		surface = mg_win32_surface_create_host(window); | ||||
| 	#endif | ||||
| 
 | ||||
| 	if(surface) | ||||
| 	{ | ||||
| 		handle = mg_surface_handle_alloc(surface); | ||||
| 	} | ||||
| 	return(handle); | ||||
| } | ||||
| 
 | ||||
| void mg_surface_destroy(mg_surface handle) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mg_surface_data* surface = mg_surface_data_from_handle(handle); | ||||
| 	if(surface) | ||||
| 	{ | ||||
| 		if(surface->backend && surface->backend->destroy) | ||||
| 		{ | ||||
| 			surface->backend->destroy(surface->backend); | ||||
| 		} | ||||
| 		surface->destroy(surface); | ||||
| 		mg_handle_recycle(handle.h); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void mg_surface_prepare(mg_surface surface) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->prepare) | ||||
| 	{ | ||||
| 		surfaceData->prepare(surfaceData); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void mg_surface_present(mg_surface surface) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->present) | ||||
| 	{ | ||||
| 		surfaceData->present(surfaceData); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void mg_surface_swap_interval(mg_surface surface, int swap) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->swapInterval) | ||||
| 	{ | ||||
| 		surfaceData->swapInterval(surfaceData, swap); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| vec2 mg_surface_contents_scaling(mg_surface surface) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	vec2 scaling = {1, 1}; | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->contentsScaling) | ||||
| 	{ | ||||
| 		scaling = surfaceData->contentsScaling(surfaceData); | ||||
| 	} | ||||
| 	return(scaling); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void mg_surface_set_frame(mg_surface surface, mp_rect frame) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->setFrame) | ||||
| 	{ | ||||
| 		surfaceData->setFrame(surfaceData, frame); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| mp_rect mg_surface_get_frame(mg_surface surface) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mp_rect res = {0}; | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->getFrame) | ||||
| 	{ | ||||
| 		res = surfaceData->getFrame(surfaceData); | ||||
| 	} | ||||
| 	return(res); | ||||
| } | ||||
| 
 | ||||
| void mg_surface_set_hidden(mg_surface surface, bool hidden) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->setHidden) | ||||
| 	{ | ||||
| 		surfaceData->setHidden(surfaceData, hidden); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| bool mg_surface_get_hidden(mg_surface surface) | ||||
| { | ||||
| 	DEBUG_ASSERT(__mgData.init); | ||||
| 	bool res = false; | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->getHidden) | ||||
| 	{ | ||||
| 		res = surfaceData->getHidden(surfaceData); | ||||
| 	} | ||||
| 	return(res); | ||||
| } | ||||
| 
 | ||||
| void* mg_surface_native_layer(mg_surface surface) | ||||
| { | ||||
| 	void* res = 0; | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->nativeLayer) | ||||
| 	{ | ||||
| 		res = surfaceData->nativeLayer(surfaceData); | ||||
| 	} | ||||
| 	return(res); | ||||
| } | ||||
| 
 | ||||
| mg_surface_id mg_surface_remote_id(mg_surface handle) | ||||
| { | ||||
| 	mg_surface_id remoteId = 0; | ||||
| 	mg_surface_data* surface = mg_surface_data_from_handle(handle); | ||||
| 	if(surface && surface->remoteID) | ||||
| 	{ | ||||
| 		remoteId = surface->remoteID(surface); | ||||
| 	} | ||||
| 	return(remoteId); | ||||
| } | ||||
| 
 | ||||
| void mg_surface_host_connect(mg_surface handle, mg_surface_id remoteID) | ||||
| { | ||||
| 	mg_surface_data* surface = mg_surface_data_from_handle(handle); | ||||
| 	if(surface && surface->hostConnect) | ||||
| 	{ | ||||
| 		surface->hostConnect(surface, remoteID); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| //------------------------------------------------------------------------------------------
 | ||||
| //NOTE(martin): images
 | ||||
| //------------------------------------------------------------------------------------------
 | ||||
| 
 | ||||
| vec2 mg_image_size(mg_image image) | ||||
| { | ||||
| 	vec2 res = {0}; | ||||
| 	mg_canvas_data* canvas = __mgCurrentCanvas; | ||||
| 	if(canvas) | ||||
| 	{ | ||||
| 		mg_image_data* imageData = mg_image_data_from_handle(image); | ||||
| 		if(imageData) | ||||
| 		{ | ||||
| 			res = imageData->size; | ||||
| 		} | ||||
| 	} | ||||
| 	return(res); | ||||
| } | ||||
| 
 | ||||
| mg_image mg_image_create(mg_surface surface, u32 width, u32 height) | ||||
| { | ||||
| 	mg_image image = mg_image_nil(); | ||||
| 	mg_surface_data* surfaceData = mg_surface_data_from_handle(surface); | ||||
| 	if(surfaceData && surfaceData->backend) | ||||
| 	{ | ||||
| 		DEBUG_ASSERT(surfaceData->api == MG_CANVAS); | ||||
| 
 | ||||
| 		mg_image_data* imageData = surfaceData->backend->imageCreate(surfaceData->backend, (vec2){width, height}); | ||||
| 		if(imageData) | ||||
| 		{ | ||||
| 			image = mg_image_handle_alloc(imageData); | ||||
| 		} | ||||
| 	} | ||||
| 	return(image); | ||||
| } | ||||
| 
 | ||||
| void mg_image_destroy(mg_image image) | ||||
| { | ||||
| 	mg_image_data* imageData = mg_image_data_from_handle(image); | ||||
| 	if(imageData) | ||||
| 	{ | ||||
| 		mg_surface_data* surface = mg_surface_data_from_handle(imageData->surface); | ||||
| 		if(surface && surface->backend) | ||||
| 		{ | ||||
| 			surface->backend->imageDestroy(surface->backend, imageData); | ||||
| 			mg_handle_recycle(image.h); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void mg_image_upload_region_rgba8(mg_image image, mp_rect region, u8* pixels) | ||||
| { | ||||
| 	mg_image_data* imageData = mg_image_data_from_handle(image); | ||||
| 	if(imageData) | ||||
| 	{ | ||||
| 		mg_surface_data* surfaceData = mg_surface_data_from_handle(imageData->surface); | ||||
| 		if(surfaceData) | ||||
| 		{ | ||||
| 			DEBUG_ASSERT(surfaceData->backend); | ||||
| 			surfaceData->backend->imageUploadRegion(surfaceData->backend, imageData, region, pixels); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -54,7 +54,8 @@ | |||
| 
 | ||||
| #if PLATFORM_WINDOWS | ||||
| 	#include"win32_app.c" | ||||
| 	#include"graphics.c" | ||||
| 	#include"graphics_common.c" | ||||
| 	#include"graphics_surface.c" | ||||
| 
 | ||||
| 	#if MG_COMPILE_GL || MG_COMPILE_GLES | ||||
| 		#include"gl_loader.c" | ||||
|  |  | |||
|  | @ -8,7 +8,8 @@ | |||
| *****************************************************************/ | ||||
| 
 | ||||
| #include"osx_app.m" | ||||
| #include"graphics.c" | ||||
| #include"graphics_common.c" | ||||
| #include"graphics_surface.c" | ||||
| 
 | ||||
| #if MG_COMPILE_METAL | ||||
| 	#include"mtl_surface.m" | ||||
|  |  | |||
|  | @ -259,9 +259,6 @@ vec2 mg_quadratic_get_point(vec2 p[3], f32 t) | |||
| 
 | ||||
| void mg_quadratic_split(vec2 p[3], f32 t, vec2 outLeft[3], vec2 outRight[3]) | ||||
| { | ||||
| 	//DEBUG | ||||
| 	__mgCurrentCanvas->splitCount++; | ||||
| 
 | ||||
| 	//NOTE(martin): split bezier curve p at parameter t, using De Casteljau's algorithm | ||||
| 	//              the q_n are the points along the hull's segments at parameter t | ||||
| 	//              s is the split point. | ||||
|  |  | |||
|  | @ -7,6 +7,18 @@ | |||
| *****************************************************************/ | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
| 	mp_rect clip; | ||||
| 	mg_mat2x3 transform; | ||||
| 	mg_image image; | ||||
| 	mp_rect srcRegion; | ||||
| 
 | ||||
| 	u32 nextShapeIndex; | ||||
| 	u32 vertexCount; | ||||
| 	u32 indexCount; | ||||
| 
 | ||||
| */ | ||||
| 
 | ||||
| void mg_reset_shape_index(mg_canvas_data* canvas) | ||||
| { | ||||
| 	canvas->nextShapeIndex = 0; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue