From 2dccfa55473e654b1ca63ea4f04e27a51e715ba0 Mon Sep 17 00:00:00 2001 From: martinfouilleul Date: Mon, 20 Feb 2023 18:34:29 +0100 Subject: [PATCH] [win32 surfaces] Backing win32 surfaces with child window and implementing frame/hidding control --- examples/triangleGL/build.bat | 2 +- src/egl_surface.c | 140 -------------------- src/glsl_shaders.h | 2 +- src/milepost.c | 4 +- src/wgl_surface.c | 106 +++++++++++++-- src/win32_app.c | 11 -- src/win32_egl_surface.c | 234 ++++++++++++++++++++++++++++++++++ todo.txt | 26 ++-- 8 files changed, 342 insertions(+), 183 deletions(-) delete mode 100644 src/egl_surface.c create mode 100644 src/win32_egl_surface.c diff --git a/examples/triangleGL/build.bat b/examples/triangleGL/build.bat index e408577..a324aa1 100644 --- a/examples/triangleGL/build.bat +++ b/examples/triangleGL/build.bat @@ -1,3 +1,3 @@ set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext -cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GL /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib shcore.lib /out:../../bin/example_gl_triangle.exe +cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GL /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib shcore.lib /LIBPATH:../../bin libEGL.dll.lib libGLESv2.dll.lib /out:../../bin/example_gl_triangle.exe diff --git a/src/egl_surface.c b/src/egl_surface.c deleted file mode 100644 index 4a2d5b6..0000000 --- a/src/egl_surface.c +++ /dev/null @@ -1,140 +0,0 @@ -/************************************************************//** -* -* @file: egl_surface.cpp -* @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; - - void* nativeSurface; - - EGLDisplay eglDisplay; - EGLConfig eglConfig; - EGLContext eglContext; - EGLSurface eglSurface; - - mg_gl_api api; - -} mg_egl_surface; - -void mg_egl_surface_destroy(mg_surface_data* interface) -{ - ////////////////////////////////////////////////// - //TODO - ////////////////////////////////////////////////// -} - -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); -} - -/* -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); -*/ - -#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(); - - //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)); - - 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; - /*TODO - 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->nativeSurface = nativeSurface; - - 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); - - 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->nativeSurface, 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/glsl_shaders.h b/src/glsl_shaders.h index cf12adc..8588131 100644 --- a/src/glsl_shaders.h +++ b/src/glsl_shaders.h @@ -2,7 +2,7 @@ * * file: glsl_shaders.h * note: string literals auto-generated by embed_text.py -* date: 17/022023 +* date: 20/022023 * **********************************************************************/ #ifndef __GLSL_SHADERS_H__ diff --git a/src/milepost.c b/src/milepost.c index 10c35c0..aa2e44a 100644 --- a/src/milepost.c +++ b/src/milepost.c @@ -60,12 +60,12 @@ #endif #if MG_COMPILE_BACKEND_GL -= #include"wgl_surface.c" + #include"wgl_surface.c" #include"gl_canvas.c" #endif #if MG_COMPILE_BACKEND_GLES - #include"egl_surface.c" + #include"win32_egl_surface.c" #endif #elif defined(OS_MACOS) diff --git a/src/wgl_surface.c b/src/wgl_surface.c index ed1c95a..8e14e1e 100644 --- a/src/wgl_surface.c +++ b/src/wgl_surface.c @@ -57,6 +57,9 @@ void mg_wgl_surface_destroy(mg_surface_data* interface) wglMakeCurrent(NULL, NULL); } wglDeleteContext(surface->glContext); + + DestroyWindow(surface->hWnd); + free(surface); } @@ -80,7 +83,7 @@ void mg_wgl_surface_swap_interval(mg_surface_data* interface, int swap) wglSwapIntervalEXT(swap); } -vec2 mg_wgl_contents_scaling(mg_surface_data* interface) +vec2 mg_wgl_surface_contents_scaling(mg_surface_data* interface) { mg_wgl_surface* surface = (mg_wgl_surface*)interface; return(surface->contentsScaling); @@ -88,19 +91,64 @@ vec2 mg_wgl_contents_scaling(mg_surface_data* interface) mp_rect mg_wgl_surface_get_frame(mg_surface_data* interface) { + mp_rect res = {0}; mg_wgl_surface* surface = (mg_wgl_surface*)interface; - RECT rect = {0}; - GetClientRect(surface->hWnd, &rect); + if(surface) + { + RECT rect = {0}; + GetClientRect(surface->hWnd, &rect); - vec2 scale = surface->contentsScaling; + vec2 scale = surface->contentsScaling; - mp_rect res = {rect.left/scale.x, - rect.bottom/scale.y, - (rect.right - rect.left)/scale.x, - (rect.bottom - rect.top)/scale.y}; + res = (mp_rect){rect.left/scale.x, + rect.bottom/scale.y, + (rect.right - rect.left)/scale.x, + (rect.bottom - rect.top)/scale.y}; + } return(res); } +void mg_wgl_surface_set_frame(mg_surface_data* interface, mp_rect frame) +{ + mg_wgl_surface* surface = (mg_wgl_surface*)interface; + if(surface) + { + HWND parent = GetParent(surface->hWnd); + RECT parentContentRect; + GetClientRect(parent, &parentContentRect); + int parentHeight = parentContentRect.bottom - parentContentRect.top; + + SetWindowPos(surface->hWnd, + HWND_TOP, + frame.x * surface->contentsScaling.x, + parentHeight - (frame.y + frame.h) * surface->contentsScaling.y, + frame.w * surface->contentsScaling.x, + frame.h * surface->contentsScaling.y, + SWP_NOACTIVATE | SWP_NOZORDER); + } +} + +void mg_wgl_surface_set_hidden(mg_surface_data* interface, bool hidden) +{ + mg_wgl_surface* surface = (mg_wgl_surface*)interface; + if(surface) + { + ShowWindow(surface->hWnd, hidden ? SW_HIDE : SW_NORMAL); + } +} + +bool mg_wgl_surface_get_hidden(mg_surface_data* interface) +{ + bool hidden = false; + mg_wgl_surface* surface = (mg_wgl_surface*)interface; + if(surface) + { + hidden = !IsWindowVisible(surface->hWnd); + } + return(hidden); +} + + void* mg_wgl_get_proc(const char* name) { void* p = wglGetProcAddress(name); @@ -117,6 +165,11 @@ void* mg_wgl_get_proc(const char* name) return(p); } +LRESULT mg_wgl_surface_window_proc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam) +{ + return(DefWindowProc(windowHandle, message, wParam, lParam)); +} + mg_surface mg_wgl_surface_create_for_window(mp_window window) { mg_surface surfaceHandle = mg_surface_nil(); @@ -180,6 +233,31 @@ mg_surface mg_wgl_surface_create_for_window(mp_window window) //NOTE(martin): now load WGL extension functions wgl_load_procs(); + //NOTE(martin): create a child window for the surface + WNDCLASS childWindowClass = {.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC, + .lpfnWndProc = mg_wgl_surface_window_proc, + .hInstance = GetModuleHandleW(NULL), + .lpszClassName = "wgl_surface_window_class", + .hCursor = LoadCursor(0, IDC_ARROW)}; + + if(!RegisterClass(&childWindowClass)) + { + //TODO: error + } + + mp_rect frame = mp_window_get_content_rect(window); + + u32 dpi = GetDpiForWindow(windowData->win32.hWnd); + vec2 contentsScaling = (vec2){(float)dpi/96., (float)dpi/96.}; + + HWND childWindow = CreateWindow("wgl_surface_window_class", "Test", + WS_CHILD|WS_VISIBLE, + 0, 0, frame.w*contentsScaling.x, frame.h*contentsScaling.y, + windowData->win32.hWnd, + 0, + childWindowClass.hInstance, + 0); + //NOTE(martin): now create the true pixel format and gl context int pixelFormatAttrs[] = { WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, @@ -191,7 +269,7 @@ mg_surface mg_wgl_surface_create_for_window(mp_window window) WGL_STENCIL_BITS_ARB, 8, 0}; - HDC hDC = GetDC(windowData->win32.hWnd); + HDC hDC = GetDC(childWindow); u32 numFormats = 0; wglChoosePixelFormatARB(hDC, pixelFormatAttrs, 0, 1, &pixelFormat, &numFormats); @@ -234,16 +312,18 @@ mg_surface mg_wgl_surface_create_for_window(mp_window window) surface->interface.prepare = mg_wgl_surface_prepare; surface->interface.present = mg_wgl_surface_present; surface->interface.swapInterval = mg_wgl_surface_swap_interval; - surface->interface.contentsScaling = mg_wgl_contents_scaling; + surface->interface.contentsScaling = mg_wgl_surface_contents_scaling; surface->interface.getFrame = mg_wgl_surface_get_frame; + surface->interface.setFrame = mg_wgl_surface_set_frame; + surface->interface.getHidden = mg_wgl_surface_get_hidden; + surface->interface.setHidden = mg_wgl_surface_set_hidden; //TODO: get/set frame/hidden - surface->hWnd = windowData->win32.hWnd; + surface->hWnd = childWindow; surface->hDC = hDC; surface->glContext = glContext; - u32 dpi = GetDpiForWindow(windowData->win32.hWnd); - surface->contentsScaling = (vec2){(float)dpi/96., (float)dpi/96.}; + surface->contentsScaling = contentsScaling; mg_gl_load_gl43(&surface->api, mg_wgl_get_proc); diff --git a/src/win32_app.c b/src/win32_app.c index cda0c58..27659e3 100644 --- a/src/win32_app.c +++ b/src/win32_app.c @@ -822,15 +822,4 @@ 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/src/win32_egl_surface.c b/src/win32_egl_surface.c new file mode 100644 index 0000000..1e5663f --- /dev/null +++ b/src/win32_egl_surface.c @@ -0,0 +1,234 @@ +/************************************************************//** +* +* @file: win32_egl_surface.cpp +* @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; + + HWND hWnd; + vec2 contentsScaling; + + 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; + + ////////////////////////////////////////////////// + //TODO + ////////////////////////////////////////////////// + DestroyWindow(surface->hWnd); + 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, swap); +} + +vec2 mg_egl_surface_contents_scaling(mg_surface_data* interface) +{ + mg_egl_surface* surface = (mg_egl_surface*)interface; + return(surface->contentsScaling); +} + +mp_rect mg_egl_surface_get_frame(mg_surface_data* interface) +{ + mp_rect res = {0}; + mg_egl_surface* surface = (mg_egl_surface*)interface; + if(surface) + { + RECT rect = {0}; + GetClientRect(surface->hWnd, &rect); + + vec2 scale = surface->contentsScaling; + + res = (mp_rect){rect.left/scale.x, + rect.bottom/scale.y, + (rect.right - rect.left)/scale.x, + (rect.bottom - rect.top)/scale.y}; + } + return(res); +} + +void mg_egl_surface_set_frame(mg_surface_data* interface, mp_rect frame) +{ + mg_egl_surface* surface = (mg_egl_surface*)interface; + if(surface) + { + HWND parent = GetParent(surface->hWnd); + RECT parentContentRect; + GetClientRect(parent, &parentContentRect); + int parentHeight = parentContentRect.bottom - parentContentRect.top; + + SetWindowPos(surface->hWnd, + HWND_TOP, + frame.x * surface->contentsScaling.x, + parentHeight - (frame.y + frame.h) * surface->contentsScaling.y, + frame.w * surface->contentsScaling.x, + frame.h * surface->contentsScaling.y, + SWP_NOACTIVATE | SWP_NOZORDER); + } +} + +void mg_egl_surface_set_hidden(mg_surface_data* interface, bool hidden) +{ + mg_egl_surface* surface = (mg_egl_surface*)interface; + if(surface) + { + ShowWindow(surface->hWnd, hidden ? SW_HIDE : SW_NORMAL); + } +} + +bool mg_egl_surface_get_hidden(mg_surface_data* interface) +{ + bool hidden = false; + mg_egl_surface* surface = (mg_egl_surface*)interface; + if(surface) + { + hidden = !IsWindowVisible(surface->hWnd); + } + return(hidden); +} + + +LRESULT mg_egl_surface_window_proc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam) +{ + return(DefWindowProc(windowHandle, message, wParam, lParam)); +} + + +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) + { + //NOTE(martin): create a child window for the surface + WNDCLASS childWindowClass = {.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC, + .lpfnWndProc = mg_egl_surface_window_proc, + .hInstance = GetModuleHandleW(NULL), + .lpszClassName = "egl_surface_window_class", + .hCursor = LoadCursor(0, IDC_ARROW)}; + + if(!RegisterClass(&childWindowClass)) + { + //TODO: error + } + + mp_rect frame = mp_window_get_content_rect(window); + + u32 dpi = GetDpiForWindow(windowData->win32.hWnd); + vec2 contentsScaling = (vec2){(float)dpi/96., (float)dpi/96.}; + + HWND childWindow = CreateWindow("egl_surface_window_class", "Test", + WS_CHILD|WS_VISIBLE, + 0, 0, frame.w*contentsScaling.x, frame.h*contentsScaling.y, + windowData->win32.hWnd, + 0, + childWindowClass.hInstance, + 0); + + 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.swapInterval = mg_egl_surface_swap_interval; + surface->interface.contentsScaling = mg_egl_surface_contents_scaling; + 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->hWnd = childWindow; + surface->contentsScaling = contentsScaling; + + 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}; + + 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->hWnd, + surfaceAttributes); + + eglBindAPI(EGL_OPENGL_ES_API); + EGLint contextAttributes[] = { + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 1, + 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/todo.txt b/todo.txt index e4518d8..c5e27e5 100644 --- a/todo.txt +++ b/todo.txt @@ -15,27 +15,23 @@ Overview [>] Allow selecting version of GL/GLES context when creating surface - pass/set attributes when creating surface? +[ ] Check that we can make GLES and GL surfaces co-exist in the app +[ ] Allow controlling surface overlaying + +[/] could have an internal, per-platform mp_layer struct that handles resizing/hiding etc... + -> avoid duplication of frame/hiding and duplication of egl code. +[/] EGL surfaces: See how we can isolate platform-specific stuff and just deal with one egl impl... +[/] Automatic surface resizing [/] 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... - -[.] 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 - - [/] could have an internal, per-platform mp_layer struct that handles resizing/hiding etc... - -> avoid duplication of frame/hiding and duplication of egl code. - - [ ] then check that we can make GLES and GL surfaces co-exist in the app - +[!] Sort out gles contents scaling for high dpi on osx +[!] Properly destroy egl surfaces +[!] win32 surfaces: only register surface child window once? [!] 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