back osx surfaces by CALayer
This commit is contained in:
parent
2232b647ed
commit
4306d0a01c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include<math.h>
|
||||
|
||||
#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<MTLDevice> 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<MTLLibrary> 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<MTLRenderPipelineState> 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<CAMetalDrawable> drawable = mg_metal_surface_drawable(surface);
|
||||
id<MTLCommandBuffer> commandBuffer = mg_metal_surface_command_buffer(surface);
|
||||
id<CAMetalDrawable> drawable = mg_mtl_surface_drawable(surface);
|
||||
id<MTLCommandBuffer> commandBuffer = mg_mtl_surface_command_buffer(surface);
|
||||
|
||||
MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||
renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
|
||||
|
|
|
@ -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_TYPE_ANGLE, MG_EGL_PLATFORM_ANGLE_TYPE,
|
||||
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
|
||||
|
||||
surface->eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, (void*)EGL_DEFAULT_DISPLAY, displayAttribs);
|
||||
eglInitialize(surface->eglDisplay, NULL, NULL);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
#endif
|
||||
|
||||
#if MG_COMPILE_BACKEND_GL
|
||||
#include"wgl_surface.c"
|
||||
= #include"wgl_surface.c"
|
||||
#include"gl_canvas.c"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#if MG_COMPILE_BACKEND_GLES
|
||||
#include"gl_loader.c"
|
||||
#include"egl_surface.c"
|
||||
#include"osx_egl_surface.m"
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -24,7 +24,6 @@ typedef struct mg_mtl_surface
|
|||
mg_surface_data interface;
|
||||
|
||||
// permanent mtl resources
|
||||
NSView* view;
|
||||
id<MTLDevice> device;
|
||||
CAMetalLayer* mtlLayer;
|
||||
id<MTLCommandQueue> 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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,194 @@
|
|||
/************************************************************//**
|
||||
*
|
||||
* @file: osx_egl_surface.m
|
||||
* @author: Martin Fouilleul
|
||||
* @date: 17/02/2023
|
||||
* @revision:
|
||||
*
|
||||
*****************************************************************/
|
||||
|
||||
#define EGL_EGLEXT_PROTOTYPES
|
||||
#include<EGL/egl.h>
|
||||
#include<EGL/eglext.h>
|
||||
|
||||
#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);
|
||||
}
|
|
@ -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
|
||||
|
|
29
todo.txt
29
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
|
||||
-----------
|
||||
|
||||
|
|
Loading…
Reference in New Issue