diff --git a/examples/canvas/build.sh b/examples/canvas/build.sh index 65a3ee3..96c8692 100755 --- a/examples/canvas/build.sh +++ b/examples/canvas/build.sh @@ -5,7 +5,12 @@ RESDIR=../../resources SRCDIR=../../src INCLUDES="-I$SRCDIR -I$SRCDIR/util -I$SRCDIR/platform -I$SRCDIR/app" -LIBS="-L$BINDIR -lmilepost -framework Carbon -framework Cocoa -framework Metal -framework QuartzCore" +LIBS="-L$BINDIR -lmilepost -framework Carbon -framework Cocoa -framework Metal -framework QuartzCore -L$BINDIR -lEGL -lGLESv2" FLAGS="-mmacos-version-min=10.15.4 -DDEBUG -DLOG_COMPILE_DEBUG -Wl,-dead_strip" clang -g $FLAGS $LIBS $INCLUDES -o $BINDIR/example_canvas main.c + +# change dynamic libraries install name +#TODO: this shouldn't be needed for apps using only metal backend... +install_name_tool -change "./libEGL.dylib" "@loader_path/libEGL.dylib" $BINDIR/example_canvas +install_name_tool -change "./libGLESv2.dylib" "@loader_path/libGLESv2.dylib" $BINDIR/example_canvas diff --git a/examples/triangleMetal/build.sh b/examples/triangleMetal/build.sh index fc51e7d..69abc2f 100755 --- a/examples/triangleMetal/build.sh +++ b/examples/triangleMetal/build.sh @@ -5,10 +5,16 @@ RESDIR=../../resources SRCDIR=../../src INCLUDES="-I$SRCDIR -I$SRCDIR/util -I$SRCDIR/platform -I$SRCDIR/app" -LIBS="-L$BINDIR -lmilepost -framework Carbon -framework Cocoa -framework Metal -framework QuartzCore" +LIBS="-L$BINDIR -lmilepost -framework Carbon -framework Cocoa -framework Metal -framework QuartzCore -L$BINDIR -lEGL -lGLESv2" FLAGS="-mmacos-version-min=10.15.4 -DDEBUG -DLOG_COMPILE_DEBUG -Wl,-dead_strip" xcrun -sdk macosx metal -c -o shader.air shader.metal xcrun -sdk macosx metallib -o shader.metallib shader.air +cp shader.metallib $BINDIR/triangle_shader.metallib -clang -g $FLAGS $LIBS $INCLUDES -o test main.m +clang -g $FLAGS $LIBS $INCLUDES -o $BINDIR/example_metal_triangle main.m + +# change dynamic libraries install name +#TODO: this shouldn't be needed for apps using only metal backend... +install_name_tool -change "./libEGL.dylib" "@loader_path/libEGL.dylib" $BINDIR/example_metal_triangle +install_name_tool -change "./libGLESv2.dylib" "@loader_path/libGLESv2.dylib" $BINDIR/example_metal_triangle diff --git a/examples/triangleMetal/main.m b/examples/triangleMetal/main.m index 91309df..78a2d3a 100644 --- a/examples/triangleMetal/main.m +++ b/examples/triangleMetal/main.m @@ -13,7 +13,7 @@ #include #include"milepost.h" -#include"metal_surface.h" +#include"mtl_surface.h" #define LOG_SUBSYSTEM "Main" @@ -36,13 +36,14 @@ int main() mp_window window = mp_window_create(rect, "test", 0); //NOTE: create surface - mg_surface surface = mg_metal_surface_create_for_window(window); + mg_surface surface = mg_surface_create_for_window(window, MG_BACKEND_METAL); //NOTE(martin): load the library id device = MTLCreateSystemDefaultDevice(); - const char* shaderPath = "shader.metallib"; - NSString* metalFileName = [[NSString alloc] initWithCString: shaderPath encoding: NSUTF8StringEncoding]; + str8 shaderPath = mp_app_get_resource_path(mem_scratch(), "triangle_shader.metallib"); + const char* shaderPathCString = str8_to_cstring(mem_scratch(), shaderPath); + NSString* metalFileName = [[NSString alloc] initWithCString: shaderPathCString encoding: NSUTF8StringEncoding]; NSError* err = 0; id library = [device newLibraryWithFile: metalFileName error:&err]; if(err != nil) @@ -60,7 +61,7 @@ int main() pipelineStateDescriptor.vertexFunction = vertexFunction; pipelineStateDescriptor.fragmentFunction = fragmentFunction; - CAMetalLayer* layer = mg_metal_surface_layer(surface); + CAMetalLayer* layer = mg_mtl_surface_layer(surface); pipelineStateDescriptor.colorAttachments[0].pixelFormat = layer.pixelFormat; id pipelineState = [device newRenderPipelineStateWithDescriptor: pipelineStateDescriptor error:&err]; @@ -89,69 +90,6 @@ int main() mp_request_quit(); } break; - case MP_EVENT_WINDOW_RESIZE: - { - printf("resized, rect = {%f, %f, %f, %f}\n", - event.frame.rect.x, - event.frame.rect.y, - event.frame.rect.w, - event.frame.rect.h); - } break; - - case MP_EVENT_WINDOW_MOVE: - { - printf("moved, rect = {%f, %f, %f, %f}\n", - event.frame.rect.x, - event.frame.rect.y, - event.frame.rect.w, - event.frame.rect.h); - } break; - - case MP_EVENT_MOUSE_MOVE: - { - printf("mouse moved, pos = {%f, %f}, delta = {%f, %f}\n", - event.move.x, - event.move.y, - event.move.deltaX, - event.move.deltaY); - } break; - - case MP_EVENT_MOUSE_WHEEL: - { - printf("mouse wheel, delta = {%f, %f}\n", - event.move.deltaX, - event.move.deltaY); - } break; - - case MP_EVENT_MOUSE_ENTER: - { - printf("mouse enter\n"); - } break; - - case MP_EVENT_MOUSE_LEAVE: - { - printf("mouse leave\n"); - } break; - - case MP_EVENT_MOUSE_BUTTON: - { - printf("mouse button %i: %i\n", - event.key.code, - event.key.action == MP_KEY_PRESS ? 1 : 0); - } break; - - case MP_EVENT_KEYBOARD_KEY: - { - printf("key %i: %s\n", - event.key.code, - event.key.action == MP_KEY_PRESS ? "press" : (event.key.action == MP_KEY_RELEASE ? "release" : "repeat")); - } break; - - case MP_EVENT_KEYBOARD_CHAR: - { - printf("entered char %s\n", event.character.sequence); - } break; - default: break; } @@ -162,8 +100,8 @@ int main() viewportSize.y = 600; mg_surface_prepare(surface); - id drawable = mg_metal_surface_drawable(surface); - id commandBuffer = mg_metal_surface_command_buffer(surface); + id drawable = mg_mtl_surface_drawable(surface); + id commandBuffer = mg_mtl_surface_command_buffer(surface); MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; renderPassDescriptor.colorAttachments[0].texture = drawable.texture; diff --git a/src/egl_surface.c b/src/egl_surface.c index e6f0eae..4a2d5b6 100644 --- a/src/egl_surface.c +++ b/src/egl_surface.c @@ -30,22 +30,6 @@ typedef struct mg_egl_surface } mg_egl_surface; -#if OS_MACOS -#include"osx_app.h" - -void* mg_egl_get_native_surface(mp_window_data* window) -{ - return((void*)window->osx.nsView.layer); -} -#elif OS_WIN64 -#include"win32_app.h" - -void* mg_egl_get_native_surface(mp_window_data* window) -{ - return((void*)window->win32.hWnd); -} -#endif - void mg_egl_surface_destroy(mg_surface_data* interface) { ////////////////////////////////////////////////// @@ -73,11 +57,23 @@ void mg_egl_surface_set_hidden(mg_surface_data* interface, bool hidden); bool mg_egl_surface_get_hidden(mg_surface_data* interface); */ +#if OS_MACOS + //NOTE: on macOS we need to explicitly set EGL_PLATFORM_ANGLE_TYPE_ANGLE to EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE, because + // EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE defaults to using CGL, and eglSetSwapInterval is broken for this backend + #define MG_EGL_PLATFORM_ANGLE_TYPE EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE +#elif OS_WIN64 + #define MG_EGL_PLATFORM_ANGLE_TYPE EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE +#endif + mg_surface mg_egl_surface_create_for_window(mp_window window) { mg_surface res = mg_surface_nil(); - mp_window_data* windowData = mp_window_ptr_from_handle(window); - if(windowData) + + //TODO: just need to check that the handle is valid + // then get native pointer from window handle + void* nativeSurface = mg_egl_get_native_surface(window); + + if(nativeSurface) { mg_egl_surface* surface = malloc_type(mg_egl_surface); memset(surface, 0, sizeof(mg_egl_surface)); @@ -93,22 +89,12 @@ mg_surface mg_egl_surface_create_for_window(mp_window window) surface->interface.setHidden = mg_egl_surface_set_hidden; */ - surface->nativeSurface = mg_egl_get_native_surface(windowData); + surface->nativeSurface = nativeSurface; - - #if OS_MACOS - //NOTE: we need to explicitly set EGL_PLATFORM_ANGLE_TYPE_ANGLE to EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE, because - // EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE defaults to using CGL, and eglSetSwapInterval is broken for this backend - EGLAttrib displayAttribs[] = { - EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE, - EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, - EGL_NONE}; - #else - EGLAttrib displayAttribs[] = { - EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE, - EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, - EGL_NONE}; - #endif + EGLAttrib displayAttribs[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, MG_EGL_PLATFORM_ANGLE_TYPE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, + EGL_NONE}; surface->eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, (void*)EGL_DEFAULT_DISPLAY, displayAttribs); eglInitialize(surface->eglDisplay, NULL, NULL); diff --git a/src/graphics_internal.h b/src/graphics_internal.h index cb1c67f..4a628e9 100644 --- a/src/graphics_internal.h +++ b/src/graphics_internal.h @@ -15,6 +15,9 @@ extern "C" { #endif +//--------------------------------------------------------------- +// surface data +//--------------------------------------------------------------- typedef struct mg_surface_data mg_surface_data; typedef void (*mg_surface_destroy_proc)(mg_surface_data* surface); diff --git a/src/milepost.c b/src/milepost.c index b1e7562..10c35c0 100644 --- a/src/milepost.c +++ b/src/milepost.c @@ -60,7 +60,7 @@ #endif #if MG_COMPILE_BACKEND_GL - #include"wgl_surface.c" += #include"wgl_surface.c" #include"gl_canvas.c" #endif diff --git a/src/milepost.m b/src/milepost.m index 3c41b2b..b42d45a 100644 --- a/src/milepost.m +++ b/src/milepost.m @@ -17,7 +17,7 @@ #if MG_COMPILE_BACKEND_GLES #include"gl_loader.c" - #include"egl_surface.c" + #include"osx_egl_surface.m" #endif /* diff --git a/src/mp_app_internal.h b/src/mp_app_internal.h index 2a7a5a3..8489e70 100644 --- a/src/mp_app_internal.h +++ b/src/mp_app_internal.h @@ -9,6 +9,8 @@ #ifndef __MP_APP_INTERNAL_H_ #define __MP_APP_INTERNAL_H_ +#include"mp_app.h" + #include"platform.h" #include"ringbuffer.h" @@ -148,6 +150,4 @@ typedef struct mp_app MP_PLATFORM_APP_DATA } mp_app; -mp_window_data* mp_window_ptr_from_handle(mp_window handle); - #endif // __MP_APP_INTERNAL_H_ diff --git a/src/mtl_surface.m b/src/mtl_surface.m index d8179b2..e639578 100644 --- a/src/mtl_surface.m +++ b/src/mtl_surface.m @@ -24,7 +24,6 @@ typedef struct mg_mtl_surface mg_surface_data interface; // permanent mtl resources - NSView* view; id device; CAMetalLayer* mtlLayer; id commandQueue; @@ -44,6 +43,7 @@ void mg_mtl_surface_destroy(mg_surface_data* interface) @autoreleasepool { [surface->commandQueue release]; + [surface->mtlLayer removeFromSuperlayer]; [surface->mtlLayer release]; [surface->device release]; } @@ -143,7 +143,8 @@ void mg_mtl_surface_set_frame(mg_surface_data* interface, mp_rect frame) @autoreleasepool { CGRect cgFrame = {{frame.x, frame.y}, {frame.w, frame.h}}; - [surface->view setFrame: cgFrame]; + [surface->mtlLayer setFrame: cgFrame]; + f32 scale = surface->mtlLayer.contentsScale; CGSize drawableSize = (CGSize){.width = frame.w * scale, .height = frame.h * scale}; surface->mtlLayer.drawableSize = drawableSize; @@ -156,7 +157,7 @@ mp_rect mg_mtl_surface_get_frame(mg_surface_data* interface) @autoreleasepool { - CGRect frame = surface->view.frame; + CGRect frame = surface->mtlLayer.frame; return((mp_rect){frame.origin.x, frame.origin.y, frame.size.width, frame.size.height}); } } @@ -209,17 +210,12 @@ mg_surface mg_mtl_surface_create_for_window(mp_window window) @autoreleasepool { - NSRect frame = [[windowData->osx.nsWindow contentView] frame]; - surface->view = [[NSView alloc] initWithFrame: frame]; - [surface->view setWantsLayer:YES]; - - [[windowData->osx.nsWindow contentView] addSubview: surface->view]; - surface->drawableSemaphore = dispatch_semaphore_create(MP_MTL_MAX_DRAWABLES_IN_FLIGHT); //----------------------------------------------------------- //NOTE(martin): create a mtl device and a mtl layer and //----------------------------------------------------------- + surface->device = MTLCreateSystemDefaultDevice(); [surface->device retain]; surface->mtlLayer = [CAMetalLayer layer]; @@ -231,7 +227,9 @@ mg_surface mg_mtl_surface_create_for_window(mp_window window) //----------------------------------------------------------- //NOTE(martin): set the size and scaling //----------------------------------------------------------- - CGSize size = surface->view.bounds.size; + NSRect frame = [[windowData->osx.nsWindow contentView] frame]; + CGSize size = frame.size; + surface->mtlLayer.frame = (CGRect){{0, 0}, size}; size.width *= MG_MTL_SURFACE_CONTENTS_SCALING; size.height *= MG_MTL_SURFACE_CONTENTS_SCALING; surface->mtlLayer.drawableSize = size; @@ -239,11 +237,9 @@ mg_surface mg_mtl_surface_create_for_window(mp_window window) surface->mtlLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; - surface->view.wantsLayer = YES; - surface->view.layer = surface->mtlLayer; + [windowData->osx.nsView.layer addSublayer: surface->mtlLayer]; //NOTE(martin): handling resizing - surface->view.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize; surface->mtlLayer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable; surface->mtlLayer.needsDisplayOnBoundsChange = YES; diff --git a/src/osx_app.m b/src/osx_app.m index 5d3f689..e7c7a66 100644 --- a/src/osx_app.m +++ b/src/osx_app.m @@ -729,6 +729,7 @@ static void mp_update_key_mods(mp_key_mods mods) window = mpWindow; mpWindow->osx.nsView = self; [mpWindow->osx.nsView setWantsLayer:YES]; + mpWindow->osx.nsView.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize; NSTrackingAreaOptions trackingOptions = NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved diff --git a/src/osx_egl_surface.m b/src/osx_egl_surface.m new file mode 100644 index 0000000..6de1019 --- /dev/null +++ b/src/osx_egl_surface.m @@ -0,0 +1,194 @@ +/************************************************************//** +* +* @file: osx_egl_surface.m +* @author: Martin Fouilleul +* @date: 17/02/2023 +* @revision: +* +*****************************************************************/ + +#define EGL_EGLEXT_PROTOTYPES +#include +#include + +#include"mp_app_internal.h" +#include"graphics_internal.h" +#include"gl_loader.h" + +typedef struct mg_egl_surface +{ + mg_surface_data interface; + + CALayer* layer; + + EGLDisplay eglDisplay; + EGLConfig eglConfig; + EGLContext eglContext; + EGLSurface eglSurface; + + mg_gl_api api; + +} mg_egl_surface; + +void mg_egl_surface_destroy(mg_surface_data* interface) +{ + mg_egl_surface* surface = (mg_egl_surface*)interface; + @autoreleasepool + { + [surface->layer release]; + } + ////////////////////////////////////////////////// + //TODO + ////////////////////////////////////////////////// + + free(surface); +} + +void mg_egl_surface_prepare(mg_surface_data* interface) +{ + mg_egl_surface* surface = (mg_egl_surface*)interface; + eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext); + mg_gl_select_api(&surface->api); +} + +void mg_egl_surface_present(mg_surface_data* interface) +{ + mg_egl_surface* surface = (mg_egl_surface*)interface; + eglSwapBuffers(surface->eglDisplay, surface->eglSurface); +} + +void mg_egl_surface_swap_interval(mg_surface_data* interface, int swap) +{ + mg_egl_surface* surface = (mg_egl_surface*)interface; + eglSwapInterval(surface->eglDisplay, 1); +} + +void mg_egl_surface_set_frame(mg_surface_data* interface, mp_rect frame) +{ + mg_egl_surface* surface = (mg_egl_surface*)interface; + + @autoreleasepool + { + CGRect cgFrame = {{frame.x, frame.y}, {frame.w, frame.h}}; + [surface->layer setFrame: cgFrame]; + } +} + +mp_rect mg_egl_surface_get_frame(mg_surface_data* interface) +{ + mg_egl_surface* surface = (mg_egl_surface*)interface; + + @autoreleasepool + { + CGRect frame = surface->layer.frame; + return((mp_rect){frame.origin.x, frame.origin.y, frame.size.width, frame.size.height}); + } +} + +void mg_egl_surface_set_hidden(mg_surface_data* interface, bool hidden) +{ + mg_egl_surface* surface = (mg_egl_surface*)interface; + @autoreleasepool + { + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + [surface->layer setHidden:hidden]; + [CATransaction commit]; + } +} + +bool mg_egl_surface_get_hidden(mg_surface_data* interface) +{ + mg_egl_surface* surface = (mg_egl_surface*)interface; + @autoreleasepool + { + return([surface->layer isHidden]); + } +} + +/* +mp_rect mg_egl_surface_get_frame(mg_surface_data* interface); +void mg_egl_surface_set_frame(mg_surface_data* interface, mp_rect frame); +void mg_egl_surface_set_hidden(mg_surface_data* interface, bool hidden); +bool mg_egl_surface_get_hidden(mg_surface_data* interface); +*/ + +mg_surface mg_egl_surface_create_for_window(mp_window window) +{ + mg_surface res = mg_surface_nil(); + + mp_window_data* windowData = mp_window_ptr_from_handle(window); + if(windowData) + { + mg_egl_surface* surface = malloc_type(mg_egl_surface); + memset(surface, 0, sizeof(mg_egl_surface)); + + surface->interface.backend = MG_BACKEND_GLES; + surface->interface.destroy = mg_egl_surface_destroy; + surface->interface.prepare = mg_egl_surface_prepare; + surface->interface.present = mg_egl_surface_present; + surface->interface.getFrame = mg_egl_surface_get_frame; + surface->interface.setFrame = mg_egl_surface_set_frame; + surface->interface.getHidden = mg_egl_surface_get_hidden; + surface->interface.setHidden = mg_egl_surface_set_hidden; + surface->interface.swapInterval = mg_egl_surface_swap_interval; + + @autoreleasepool + { + surface->layer = [[CALayer alloc] init]; + [surface->layer retain]; + + [windowData->osx.nsView.layer addSublayer: surface->layer]; + + NSRect frame = [[windowData->osx.nsWindow contentView] frame]; + CGSize size = frame.size; + surface->layer.frame = (CGRect){{0, 0}, size}; + } + + EGLAttrib displayAttribs[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, + EGL_NONE}; + + surface->eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, (void*)EGL_DEFAULT_DISPLAY, displayAttribs); + eglInitialize(surface->eglDisplay, NULL, NULL); + + EGLint const configAttributes[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 24, + EGL_STENCIL_SIZE, 8, + EGL_SAMPLE_BUFFERS, 0, + EGL_SAMPLES, EGL_DONT_CARE, + EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT, + EGL_NONE }; + + int numConfigs = 0; + eglChooseConfig(surface->eglDisplay, configAttributes, &surface->eglConfig, 1, &numConfigs); + + EGLint const surfaceAttributes[] = {EGL_NONE}; + surface->eglSurface = eglCreateWindowSurface(surface->eglDisplay, surface->eglConfig, surface->layer, surfaceAttributes); + + eglBindAPI(EGL_OPENGL_ES_API); + EGLint contextAttributes[] = { + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 0, + EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE, + EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE, + EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_FALSE, + EGL_NONE}; + + surface->eglContext = eglCreateContext(surface->eglDisplay, surface->eglConfig, EGL_NO_CONTEXT, contextAttributes); + eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext); + + mg_gl_load_gles32(&surface->api, (mg_gl_load_proc)eglGetProcAddress); + + eglSwapInterval(surface->eglDisplay, 1); + + res = mg_surface_alloc_handle((mg_surface_data*)surface); + } + return(res); +} diff --git a/src/win32_app.c b/src/win32_app.c index 27659e3..cda0c58 100644 --- a/src/win32_app.c +++ b/src/win32_app.c @@ -822,4 +822,15 @@ str8 mp_app_get_resource_path(mem_arena* arena, const char* name) } ////////////////////////////////////////////////////////////////////////////////////////////////// +void* mg_egl_get_native_surface(mp_window_data* window) +{ + void* res = 0; + mp_window_data* windowData = mp_window_ptr_from_handle(window); + if(windowData) + { + res = (void*)windowData->win32.hWnd; + } + return(res); +} + #undef LOG_SUBSYSTEM diff --git a/todo.txt b/todo.txt index 2187116..e4518d8 100644 --- a/todo.txt +++ b/todo.txt @@ -1,17 +1,11 @@ Overview -------- -[x] Pan/Zoom on text example -[.] Clean+Fixes of canvas code and examples - [.] Make backend selection easier - [x] rename backend-specific files with api prefix (e.g. egl_, nsgl_, wgl_, mtl_, ...) - [x] option macros to select surface/canvas backends to compile into milepost lib [.] option macros to select backend-specific APIs to include when building an app (ie, include gl_api.h when using gl backend) - [x] surface/canvas functions that take a backend id - [x] feature-detection functions to know what surface/canvas backends are available at run-time - [>] write doc about these options + [ ] error on bad option macro combinations + [ ] write doc about backend option macros [>] Image API and backend [ ] Build image atlas on top @@ -24,25 +18,36 @@ Overview [/] Keep dummy window/dummy context around for gl context creation, and don't reload wgl functions every time [.] Reintroduce GLES surface - [ ] See how we can isolate platform-specific stuff and just deal with egl there.. + [?] See how we can isolate platform-specific stuff and just deal with egl there... -[>] Back surface by child windows and implement moving frame/hiding/overlay +[.] Back surface by child windows and implement moving frame/hiding/overlay + [x] osx gles surface + [ ] Sort out gles contents scaling for high dpi + [ ] win32 opengl surfaces + [ ] win32 gles surface -[>] Check that we can make GLES and GL surfaces co-exist in the app + [/] could have an internal, per-platform mp_layer struct that handles resizing/hiding etc... + -> avoid duplication of frame/hiding and duplication of egl code. -[?] Backport canvas to GLES + [ ] then check that we can make GLES and GL surfaces co-exist in the app +[!] Make linking with libEGL optional, even if EGL backend is compiled in milepost? +[!] Bundle examples with their own resources?? (e.g. avoiding clashes in metal libs files in bin directory) [!] Fix canvas shader precision issue on OSX [!] Fix canvas perf issue on OSX [!] osx: Remove need to include objc defs from osx_app.h in egl impl. Also properly guard angle backend attribute (must be metal on osx and default on win32) [ ] Delegated drawing API+Impl + + [ ] Make building apps simpler [ ] single include path [ ] script for embedding dependencies / create app bundle +[?] Backport canvas to GLES + Clean+Fixes -----------