Minor API cleanup:

- Removing unused remote/host surfaces for now
- Complete canvas attributes getters
- Separate surface creation APIs accessible by host and guest
- added oc_get_matrix(), removed oc_viewport()
- oc_get_clip -> oc_clip_top, oc_get_matrix -> oc_matrix_top
This commit is contained in:
Martin Fouilleul 2023-09-05 16:07:43 +02:00
parent fbb03d27a3
commit bd35b75f4b
14 changed files with 89 additions and 752 deletions

View File

@ -16,7 +16,6 @@ STDLIB_DIR=../../src/libc-shim
wasmFlags="--target=wasm32 \
--no-standard-libraries \
-fno-builtin \
-Wl,--no-entry \
-Wl,--export-dynamic \
-g \

View File

@ -1,8 +0,0 @@
set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle/include
if not exist "bin" mkdir bin
cl /we4013 /Zi /Zc:preprocessor /std:c11 /experimental:c11atomics %INCLUDES% main.c /link /LIBPATH:../../build/bin orca.dll.lib /out:bin/example_surface_sharing.exe
copy ..\..\build\bin\orca.dll bin
copy ..\..\ext\angle\bin\libEGL.dll bin
copy ..\..\ext\angle\bin\libGLESv2.dll bin

View File

@ -1,22 +0,0 @@
#!/bin/bash
BINDIR=bin
LIBDIR=../../build/bin
RESDIR=../resources
SRCDIR=../../src
EXTDIR=../../ext
ANGLEDIR=../../ext/angle/
INCLUDES="-I$SRCDIR -I$SRCDIR/util -I$SRCDIR/platform -I$SRCDIR/app -I$EXTDIR/ -I$ANGLEDIR/include"
LIBS="-L$LIBDIR -lorca"
FLAGS="-mmacos-version-min=10.15.4 -DOC_DEBUG -DLOG_COMPILE_DEBUG"
mkdir -p $BINDIR
clang -g $FLAGS $LIBS $INCLUDES -o $BINDIR/example_surface_sharing main.c
cp $LIBDIR/liborca.dylib $BINDIR/
cp $LIBDIR/mtl_renderer.metallib $BINDIR/
cp $ANGLEDIR/bin/libEGL.dylib $BINDIR/
cp $ANGLEDIR/bin/libGLESv2.dylib $BINDIR/
install_name_tool -add_rpath "@executable_path" $BINDIR/example_surface_sharing

View File

@ -1,289 +0,0 @@
#include <stdlib.h>
#include <string.h>
#define _USE_MATH_DEFINES //NOTE: necessary for MSVC
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define OC_INCLUDE_GL_API
#include "orca.h"
#ifdef OC_PLATFORM_WINDOWS
#include <process.h>
#include <io.h>
#include <fcntl.h>
#define dup2 _dup2
#define pipe(fds) _pipe(fds, 256, O_BINARY)
#define read _read
#define write _write
#define process_id HANDLE
process_id spawn_child(char* program, char** argv)
{
return ((process_id)_spawnv(P_NOWAIT, program, argv));
}
void terminate_child(process_id child)
{
TerminateProcess(child, 0);
}
#elif OC_PLATFORM_MACOS
#include <unistd.h>
#include <signal.h>
#define process_id pid_t
process_id spawn_child(char* program, char** argv)
{
pid_t pid = fork();
if(!pid)
{
char* envp[] = { 0 };
execve(program, argv, envp);
OC_ASSERT(0);
}
return (pid);
}
void terminate_child(process_id child)
{
kill(child, SIGTERM);
}
#endif
unsigned int program;
const char* vshaderSource =
//"#version 320 es\n"
"attribute vec4 vPosition;\n"
"uniform mat4 transform;\n"
"void main()\n"
"{\n"
" gl_Position = transform*vPosition;\n"
"}\n";
const char* fshaderSource =
//"#version 320 es\n"
"precision mediump float;\n"
"void main()\n"
"{\n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
void compile_shader(GLuint shader, const char* source)
{
glShaderSource(shader, 1, &source, 0);
glCompileShader(shader);
int err = glGetError();
if(err)
{
oc_log_error("gl error: %i\n", err);
}
int status = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetShaderInfoLog(shader, 256, &size, buffer);
oc_log_error("shader error: %.*s\n", size, buffer);
}
}
int child_main(int writeFd)
{
oc_init();
oc_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 };
oc_window window = oc_window_create(rect, OC_STR8("test"), 0);
//NOTE: create surface
oc_surface surface = oc_surface_create_remote(800, 600, OC_GLES);
oc_surface_id connectionID = oc_surface_remote_id(surface);
oc_surface_select(surface);
//NOTE: init shader and gl state
oc_surface_select(surface);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
GLfloat vertices[] = {
-0.866 / 2, -0.5 / 2, 0, 0.866 / 2, -0.5 / 2, 0, 0, 0.5, 0
};
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
unsigned int vshader = glCreateShader(GL_VERTEX_SHADER);
unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();
compile_shader(vshader, vshaderSource);
compile_shader(fshader, fshaderSource);
glAttachShader(program, vshader);
glAttachShader(program, fshader);
glLinkProgram(program);
int status = 0;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(!status)
{
char buffer[256];
int size = 0;
glGetProgramInfoLog(program, 256, &size, buffer);
oc_log_error("link error: %.*s\n", size, buffer);
}
glUseProgram(program);
//NOTE: send context id to parent
write(writeFd, &connectionID, sizeof(connectionID));
//NOTE: render loop
while(!oc_should_quit())
{
oc_pump_events(0);
oc_event* event = 0;
while((event = oc_next_event(oc_scratch())) != 0)
{
switch(event->type)
{
case OC_EVENT_WINDOW_CLOSE:
{
oc_request_quit();
}
break;
default:
break;
}
}
oc_surface_select(surface);
oc_vec2 size = oc_surface_get_size(surface);
oc_vec2 scaling = oc_surface_contents_scaling(surface);
glViewport(0, 0, size.x * scaling.x, size.y * scaling.y);
glClearColor(0.3, 0.3, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
static float alpha = 0;
//f32 aspect = frameSize.x/frameSize.y;
f32 aspect = 800 / (f32)600;
GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0,
-sinf(alpha) / aspect, cosf(alpha), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
alpha += 2 * M_PI / 120;
glUniformMatrix4fv(0, 1, false, matrix);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
oc_surface_present(surface);
}
oc_terminate();
return (0);
}
int main(int argc, char** argv)
{
if(argc > 1)
{
if(!strcmp(argv[1], "--child"))
{
int writeFd = atoi(argv[2]);
oc_log_info("child process created with file desc %i\n", writeFd);
return (child_main(writeFd));
}
else
{
return (-1);
}
}
// setvbuf( stdout, NULL, _IONBF, 0 );
oc_init();
//NOTE: create main window
oc_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 };
oc_window window = oc_window_create(rect, OC_STR8("test"), 0);
//NOTE: create surface client
oc_surface surface = oc_surface_create_host(window);
//NOTE setup descriptors
int fileDesc[2];
pipe(fileDesc);
oc_log_info("parent process created readFd %i and writeFd %i\n", fileDesc[0], fileDesc[1]);
char writeDescStr[64];
snprintf(writeDescStr, 64, "%i", fileDesc[1]);
char* args[] = { "bin/example_surface_sharing", "--child", writeDescStr, 0 };
process_id child = spawn_child(args[0], args);
//NOTE: read the connection id
oc_surface_id connectionID = 0;
read(fileDesc[0], &connectionID, sizeof(connectionID));
oc_log_info("received child connection id %llu\n", connectionID);
//NOTE: connect the client
oc_surface_host_connect(surface, connectionID);
//NOTE: show the window
oc_window_bring_to_front(window);
while(!oc_should_quit())
{
oc_pump_events(0);
oc_event* event = 0;
while((event = oc_next_event(oc_scratch())) != 0)
{
switch(event->type)
{
case OC_EVENT_WINDOW_CLOSE:
{
oc_request_quit();
}
break;
default:
break;
}
oc_arena_clear(oc_scratch());
}
oc_surface_select(surface);
oc_surface_present(surface);
}
terminate_child(child);
oc_terminate();
return (0);
}

View File

@ -1843,213 +1843,6 @@ void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window
}
}
//------------------------------------------------------------------------------------------------
// Remote surfaces
//------------------------------------------------------------------------------------------------
oc_surface_id oc_osx_surface_remote_id(oc_surface_data* surface)
{
oc_surface_id remoteID = 0;
if(surface->layer.caContext)
{
@autoreleasepool
{
remoteID = (oc_surface_id)[surface->layer.caContext contextId];
}
}
return (remoteID);
}
void oc_surface_init_remote(oc_surface_data* surface, u32 width, u32 height)
{
@autoreleasepool
{
surface->nativeLayer = oc_osx_surface_native_layer;
surface->contentsScaling = oc_osx_surface_contents_scaling;
surface->getSize = oc_osx_surface_get_size;
surface->getHidden = oc_osx_surface_get_hidden;
surface->setHidden = oc_osx_surface_set_hidden;
surface->remoteID = oc_osx_surface_remote_id;
surface->layer.caLayer = [[CALayer alloc] init];
[surface->layer.caLayer retain];
[surface->layer.caLayer setFrame:(CGRect){ { 0, 0 }, { width, height } }];
NSDictionary* dict = [[NSDictionary alloc] init];
CGSConnectionID connectionID = CGSMainConnectionID();
surface->layer.caContext = [CAContext contextWithCGSConnection:connectionID options:dict];
[surface->layer.caContext retain];
[surface->layer.caContext setLayer:surface->layer.caLayer];
}
}
void oc_osx_surface_host_connect(oc_surface_data* surface, oc_surface_id remoteID)
{
@autoreleasepool
{
[(CALayerHost*)surface->layer.caLayer setContextId:(CAContextID)remoteID];
}
}
void oc_surface_init_host(oc_surface_data* surface, oc_window_data* window)
{
@autoreleasepool
{
surface->api = OC_HOST;
surface->nativeLayer = oc_osx_surface_native_layer;
surface->contentsScaling = oc_osx_surface_contents_scaling;
surface->getSize = oc_osx_surface_get_size;
surface->getHidden = oc_osx_surface_get_hidden;
surface->setHidden = oc_osx_surface_set_hidden;
surface->hostConnect = oc_osx_surface_host_connect;
surface->layer.caLayer = [[CALayerHost alloc] init];
[surface->layer.caLayer retain];
NSRect frame = [[window->osx.nsWindow contentView] frame];
CGSize size = frame.size;
[surface->layer.caLayer setFrame:(CGRect){ { 0, 0 }, size }];
[window->osx.nsView.layer addSublayer:surface->layer.caLayer];
}
}
oc_surface_data* oc_osx_surface_create_host(oc_window windowHandle)
{
oc_surface_data* surface = 0;
oc_window_data* window = oc_window_ptr_from_handle(windowHandle);
if(window)
{
surface = oc_malloc_type(oc_surface_data);
if(surface)
{
oc_surface_init_host(surface, window);
}
}
return (surface);
}
//--------------------------------------------------------------------
// view management
//--------------------------------------------------------------------
/*
oc_view oc_view_create(oc_window windowHandle, oc_rect frame)
{@autoreleasepool{
oc_window_data* window = oc_window_ptr_from_handle(windowHandle);
if(!window)
{
oc_log_error("Can't create view for nil window\n");
return(oc_view_nil());
}
oc_view_data* view = oc_view_alloc();
if(!view)
{
oc_log_error("Could not allocate view data\n");
return(oc_view_nil());
}
view->window = windowHandle;
NSRect nsFrame = {{frame.x, frame.y}, {frame.w, frame.h}};
view->nsView = [[NSView alloc] initWithFrame: nsFrame];
[view->nsView setWantsLayer:YES];
[[window->osx.nsWindow contentView] addSubview: view->nsView];
return(oc_view_handle_from_ptr(view));
}}
void oc_view_destroy(oc_view viewHandle)
{@autoreleasepool{
oc_view_data* view = oc_view_ptr_from_handle(viewHandle);
if(!view)
{
return;
}
oc_window_data* window = oc_window_ptr_from_handle(view->window);
if(!window)
{
return;
}
[view->nsView removeFromSuperview];
oc_view_recycle_ptr(view);
}}
void oc_view_set_frame(oc_view viewHandle, oc_rect frame)
{
oc_view_data* view = oc_view_ptr_from_handle(viewHandle);
if(!view)
{
return;
}
NSRect nsFrame = {{frame.x, frame.y}, {frame.w, frame.h}};
[view->nsView setFrame: nsFrame];
if(!oc_surface_is_nil(view->surface))
{
oc_surface_resize(view->surface, frame.w, frame.h);
}
}
*/
//--------------------------------------------------------------------
// Main loop throttle
//--------------------------------------------------------------------
void oc_set_target_fps(u32 fps)
{
oc_appData.frameStats.targetFramePeriod = 1. / (f64)fps;
oc_appData.frameStats.workTime = 0;
oc_appData.frameStats.remainingTime = 0;
if(oc_appData.osx.frameTimer)
{
[oc_appData.osx.frameTimer invalidate];
}
oc_appData.osx.frameTimer = [NSTimer timerWithTimeInterval:oc_appData.frameStats.targetFramePeriod
target:[NSApp delegate]
selector:@selector(timerElapsed:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:oc_appData.osx.frameTimer forMode:NSRunLoopCommonModes];
}
/*
void oc_begin_frame()
{
oc_appData.frameStats.start = oc_get_elapsed_seconds();
LOG_DEBUG("workTime = %.6f (%.6f fps), remaining = %.6f\n",
oc_appData.frameStats.workTime,
1/oc_appData.frameStats.workTime,
oc_appData.frameStats.remainingTime);
}
void oc_end_frame()
{
oc_appData.frameStats.workTime = oc_get_elapsed_seconds() - oc_appData.frameStats.start;
oc_appData.frameStats.remainingTime = oc_appData.frameStats.targetFramePeriod - oc_appData.frameStats.workTime;
while(oc_appData.frameStats.remainingTime > 100e-9)
{
if(oc_appData.frameStats.remainingTime > 10e-6)
{
oc_sleep_nano(oc_appData.frameStats.remainingTime*0.8*1e9);
}
oc_appData.frameStats.workTime = oc_get_elapsed_seconds() - oc_appData.frameStats.start;
oc_appData.frameStats.remainingTime = oc_appData.frameStats.targetFramePeriod - oc_appData.frameStats.workTime;
}
}
*/
//--------------------------------------------------------------------
// Events handling
//--------------------------------------------------------------------

View File

@ -1206,31 +1206,6 @@ void* oc_win32_surface_native_layer(oc_surface_data* surface)
return ((void*)surface->layer.hWnd);
}
oc_surface_id oc_win32_surface_remote_id(oc_surface_data* surface)
{
return ((oc_surface_id)surface->layer.hWnd);
}
void oc_win32_surface_host_connect(oc_surface_data* surface, oc_surface_id remoteID)
{
HWND dstWnd = surface->layer.hWnd;
HWND srcWnd = (HWND)remoteID;
RECT dstRect;
GetClientRect(dstWnd, &dstRect);
SetParent(srcWnd, dstWnd);
ShowWindow(srcWnd, SW_NORMAL);
SetWindowPos(srcWnd,
HWND_TOP,
0,
0,
dstRect.right - dstRect.left,
dstRect.bottom - dstRect.top,
SWP_NOACTIVATE | SWP_NOZORDER);
}
void oc_surface_cleanup(oc_surface_data* surface)
{
oc_list_remove(&surface->layer.parent->win32.layers, &surface->layer.listElt);
@ -1307,68 +1282,6 @@ void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window
oc_list_append(&window->win32.layers, &surface->layer.listElt);
}
void oc_surface_init_remote(oc_surface_data* surface, u32 width, u32 height)
{
surface->contentsScaling = oc_win32_surface_contents_scaling;
surface->getSize = oc_win32_surface_get_size;
surface->getHidden = oc_win32_surface_get_hidden;
surface->setHidden = oc_win32_surface_set_hidden;
surface->nativeLayer = oc_win32_surface_native_layer;
surface->remoteID = oc_win32_surface_remote_id;
WNDCLASS layerWindowClass = { .style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
.lpfnWndProc = DefWindowProc,
.hInstance = GetModuleHandleW(NULL),
.lpszClassName = "server_layer_window_class",
.hCursor = LoadCursor(0, IDC_ARROW) };
RegisterClass(&layerWindowClass);
//NOTE(martin): create a temporary parent window. This seems like a necessary hack, because if layer window is created as
// a normal window first, and then parented to the client window, it breaks resizing the parent
// window for some reason...
HWND tmpParent = CreateWindow("server_layer_window_class", "layerParent",
WS_OVERLAPPED,
0, 0, width, height,
0,
0,
layerWindowClass.hInstance,
0);
//NOTE: create the layer window
surface->layer.hWnd = CreateWindowEx(WS_EX_NOACTIVATE,
"server_layer_window_class", "layer",
WS_CHILD,
0, 0, width, height,
tmpParent,
0,
layerWindowClass.hInstance,
0);
//NOTE: unparent it and destroy tmp parent
SetParent(surface->layer.hWnd, 0);
DestroyWindow(tmpParent);
}
oc_surface_data* oc_win32_surface_create_host(oc_window window)
{
oc_surface_data* surface = 0;
oc_window_data* windowData = oc_window_ptr_from_handle(window);
if(windowData)
{
surface = oc_malloc_type(oc_surface_data);
if(surface)
{
memset(surface, 0, sizeof(oc_surface_data));
oc_surface_init_for_window(surface, windowData);
surface->api = OC_HOST;
surface->hostConnect = oc_win32_surface_host_connect;
}
}
return (surface);
}
//--------------------------------------------------------------------
// native open/save/alert windows
//--------------------------------------------------------------------

View File

@ -150,22 +150,6 @@ void oc_egl_surface_init(oc_egl_surface* surface)
eglSwapInterval(surface->eglDisplay, 1);
}
oc_surface_data* oc_egl_surface_create_remote(u32 width, u32 height)
{
oc_egl_surface* surface = 0;
surface = oc_malloc_type(oc_egl_surface);
if(surface)
{
memset(surface, 0, sizeof(oc_egl_surface));
oc_surface_init_remote((oc_surface_data*)surface, width, height);
oc_egl_surface_init(surface);
}
return ((oc_surface_data*)surface);
}
oc_surface_data* oc_egl_surface_create_for_window(oc_window window)
{
oc_egl_surface* surface = 0;

View File

@ -14,7 +14,7 @@
#include "util/typedefs.h"
//------------------------------------------------------------------------------------------
//NOTE(martin): backends selection
//SECTION: backends selection
//------------------------------------------------------------------------------------------
typedef enum
@ -85,49 +85,48 @@ typedef enum
#include "wgl_surface.h"
#endif
//TODO: expose nsgl surface when supported, expose egl surface, etc...
//TODO: add OC_INCLUDE_OPENGL/GLES/etc, once we know how we make different gl versions co-exist
ORCA_API bool oc_is_surface_api_available(oc_surface_api api);
//------------------------------------------------------------------------------------------
//NOTE(martin): graphics surface
//SECTION: graphics surface
//------------------------------------------------------------------------------------------
typedef struct oc_surface
{
u64 h;
} oc_surface;
ORCA_API oc_surface oc_surface_nil(void);
ORCA_API bool oc_surface_is_nil(oc_surface surface);
ORCA_API oc_surface oc_surface_nil(void); //DOC: returns a nil surface
ORCA_API bool oc_surface_is_nil(oc_surface surface); //DOC: true if surface is nil
#if !defined(OC_PLATFORM_ORCA) || !OC_PLATFORM_ORCA
ORCA_API oc_surface oc_surface_create_for_window(oc_window window, oc_surface_api api);
ORCA_API void oc_surface_destroy(oc_surface surface);
ORCA_API void oc_surface_select(oc_surface surface);
ORCA_API void oc_surface_present(oc_surface surface);
ORCA_API void oc_surface_deselect(void);
ORCA_API void oc_surface_swap_interval(oc_surface surface, int swap);
ORCA_API oc_vec2 oc_surface_get_size(oc_surface surface);
ORCA_API oc_vec2 oc_surface_contents_scaling(oc_surface surface);
ORCA_API bool oc_surface_get_hidden(oc_surface surface);
ORCA_API void oc_surface_set_hidden(oc_surface surface, bool hidden);
ORCA_API void oc_surface_bring_to_front(oc_surface surface);
ORCA_API void oc_surface_send_to_back(oc_surface surface);
#else
//NOTE(martin): surface sharing
typedef u64 oc_surface_id;
ORCA_API oc_surface oc_surface_canvas(); //DOC: creates a surface for use with the canvas API
ORCA_API oc_surface oc_surface_gles(); //DOC: create a surface for use with GLES API
ORCA_API oc_surface oc_surface_create_remote(u32 width, u32 height, oc_surface_api api);
ORCA_API oc_surface oc_surface_create_host(oc_window window);
ORCA_API oc_surface_id oc_surface_remote_id(oc_surface surface);
ORCA_API void oc_surface_host_connect(oc_surface surface, oc_surface_id remoteId);
#endif
ORCA_API void oc_surface_destroy(oc_surface surface); //DOC: destroys the surface
ORCA_API void oc_surface_select(oc_surface surface); //DOC: selects the surface in the current thread before drawing
ORCA_API void oc_surface_present(oc_surface surface); //DOC: presents the surface to its window
ORCA_API void oc_surface_deselect(void); //DOC: deselects the current thread's previously selected surface
ORCA_API oc_vec2 oc_surface_get_size(oc_surface surface);
ORCA_API oc_vec2 oc_surface_contents_scaling(oc_surface surface); //DOC: returns the scaling of the surface (pixels = points * scale)
ORCA_API void oc_surface_bring_to_front(oc_surface surface); //DOC: puts surface on top of the surface stack
ORCA_API void oc_surface_send_to_back(oc_surface surface); //DOC: puts surface at the bottom of the surface stack
//------------------------------------------------------------------------------------------
//NOTE(martin): graphics canvas structs
//SECTION: graphics canvas structs
//------------------------------------------------------------------------------------------
typedef struct oc_canvas
{
@ -196,18 +195,18 @@ typedef struct oc_text_extents
} oc_text_extents;
//------------------------------------------------------------------------------------------
//NOTE(martin): graphics canvas
//SECTION: graphics canvas
//------------------------------------------------------------------------------------------
ORCA_API oc_canvas oc_canvas_nil(void);
ORCA_API bool oc_canvas_is_nil(oc_canvas canvas);
ORCA_API oc_canvas oc_canvas_nil(void); //DOC: returns a nil canvas
ORCA_API bool oc_canvas_is_nil(oc_canvas canvas); //DOC: true if canvas is nil
ORCA_API oc_canvas oc_canvas_create(void);
ORCA_API void oc_canvas_destroy(oc_canvas canvas);
ORCA_API oc_canvas oc_canvas_set_current(oc_canvas canvas);
ORCA_API void oc_render(oc_surface surface, oc_canvas canvas);
ORCA_API oc_canvas oc_canvas_create(void); //DOC: create a new canvas
ORCA_API void oc_canvas_destroy(oc_canvas canvas); //DOC: destroys canvas
ORCA_API oc_canvas oc_canvas_set_current(oc_canvas canvas); //DOC: selects canvas in the current thread
ORCA_API void oc_render(oc_surface surface, oc_canvas canvas); //DOC: renders all canvas commands onto surface
//------------------------------------------------------------------------------------------
//NOTE(martin): fonts
//SECTION: fonts
//------------------------------------------------------------------------------------------
ORCA_API oc_font oc_font_nil(void);
ORCA_API oc_font oc_font_create_from_memory(oc_str8 mem, u32 rangeCount, oc_unicode_range* ranges);
@ -235,7 +234,7 @@ ORCA_API oc_rect oc_text_bounding_box_utf32(oc_font font, f32 fontSize, oc_str32
ORCA_API oc_rect oc_text_bounding_box(oc_font font, f32 fontSize, oc_str8 text);
//------------------------------------------------------------------------------------------
//NOTE(martin): images
//SECTION: images
//------------------------------------------------------------------------------------------
ORCA_API oc_image oc_image_nil(void);
ORCA_API bool oc_image_is_nil(oc_image a);
@ -251,7 +250,7 @@ ORCA_API void oc_image_upload_region_rgba8(oc_image image, oc_rect region, u8* p
ORCA_API oc_vec2 oc_image_size(oc_image image);
//------------------------------------------------------------------------------------------
//NOTE(martin): atlasing
//SECTION: atlasing
//------------------------------------------------------------------------------------------
//NOTE: rectangle allocator
@ -274,19 +273,18 @@ ORCA_API oc_image_region oc_image_atlas_alloc_from_file(oc_rect_atlas* atlas, oc
ORCA_API void oc_image_atlas_recycle(oc_rect_atlas* atlas, oc_image_region imageRgn);
//------------------------------------------------------------------------------------------
//NOTE(martin): transform, viewport and clipping
//SECTION: transform, viewport and clipping
//------------------------------------------------------------------------------------------
ORCA_API void oc_viewport(oc_rect viewPort);
ORCA_API void oc_matrix_push(oc_mat2x3 matrix);
ORCA_API void oc_matrix_pop(void);
ORCA_API oc_mat2x3 oc_matrix_top();
ORCA_API void oc_clip_push(f32 x, f32 y, f32 w, f32 h);
ORCA_API void oc_clip_pop(void);
ORCA_API oc_rect oc_clip();
ORCA_API oc_rect oc_clip_top();
//------------------------------------------------------------------------------------------
//NOTE(martin): graphics attributes setting/getting
//SECTION: graphics attributes setting/getting
//------------------------------------------------------------------------------------------
ORCA_API void oc_set_color(oc_color color);
ORCA_API void oc_set_color_rgba(f32 r, f32 g, f32 b, f32 a);
@ -310,9 +308,11 @@ ORCA_API oc_cap_type oc_get_cap(void);
ORCA_API oc_font oc_get_font(void);
ORCA_API f32 oc_get_font_size(void);
ORCA_API bool oc_get_text_flip(void);
ORCA_API oc_image oc_get_image();
ORCA_API oc_rect oc_get_image_source_region();
//------------------------------------------------------------------------------------------
//NOTE(martin): path construction
//SECTION: path construction
//------------------------------------------------------------------------------------------
ORCA_API oc_vec2 oc_get_position(void);
ORCA_API void oc_move_to(f32 x, f32 y);
@ -326,14 +326,14 @@ ORCA_API void oc_codepoints_outlines(oc_str32 string);
ORCA_API void oc_text_outlines(oc_str8 string);
//------------------------------------------------------------------------------------------
//NOTE(martin): clear/fill/stroke
//SECTION: clear/fill/stroke
//------------------------------------------------------------------------------------------
ORCA_API void oc_clear(void);
ORCA_API void oc_fill(void);
ORCA_API void oc_stroke(void);
//------------------------------------------------------------------------------------------
//NOTE(martin): 'fast' shapes primitives
//SECTION: shapes helpers
//------------------------------------------------------------------------------------------
ORCA_API void oc_rectangle_fill(f32 x, f32 y, f32 w, f32 h);
ORCA_API void oc_rectangle_stroke(f32 x, f32 y, f32 w, f32 h);

View File

@ -928,6 +928,21 @@ void oc_matrix_pop()
}
}
oc_mat2x3 oc_matrix_top()
{
oc_mat2x3 mat = {
1, 0, 0,
0, 1, 0
};
oc_canvas_data* canvas = __mgCurrentCanvas;
if(canvas)
{
mat = oc_matrix_stack_top(canvas);
}
return (mat);
}
void oc_clip_push(f32 x, f32 y, f32 w, f32 h)
{
oc_canvas_data* canvas = __mgCurrentCanvas;
@ -972,7 +987,7 @@ void oc_clip_pop()
}
}
oc_rect oc_clip()
oc_rect oc_clip_top()
{
oc_rect clip = { -FLT_MAX / 2, -FLT_MAX / 2, FLT_MAX, FLT_MAX };
@ -1193,6 +1208,28 @@ bool oc_get_text_flip()
return (flip);
}
oc_image oc_get_image()
{
oc_image image = oc_image_nil();
oc_canvas_data* canvas = __mgCurrentCanvas;
if(canvas)
{
image = canvas->attributes.image;
}
return (image);
}
oc_rect oc_get_image_source_region()
{
oc_rect rect = { 0 };
oc_canvas_data* canvas = __mgCurrentCanvas;
if(canvas)
{
rect = canvas->attributes.srcRegion;
}
return (rect);
}
//------------------------------------------------------------------------------------------
//NOTE(martin): path construction
//------------------------------------------------------------------------------------------

View File

@ -153,55 +153,6 @@ oc_surface oc_surface_create_for_window(oc_window window, oc_surface_api api)
return (surfaceHandle);
}
oc_surface oc_surface_create_remote(u32 width, u32 height, oc_surface_api api)
{
if(!oc_graphicsData.init)
{
oc_graphics_init();
}
oc_surface surfaceHandle = oc_surface_nil();
oc_surface_data* surface = 0;
switch(api)
{
#if OC_COMPILE_GLES
case OC_GLES:
surface = oc_egl_surface_create_remote(width, height);
break;
#endif
default:
break;
}
if(surface)
{
surfaceHandle = oc_surface_handle_alloc(surface);
oc_surface_select(surfaceHandle);
}
return (surfaceHandle);
}
oc_surface oc_surface_create_host(oc_window window)
{
if(!oc_graphicsData.init)
{
oc_graphics_init();
}
oc_surface handle = oc_surface_nil();
oc_surface_data* surface = 0;
#if OC_PLATFORM_MACOS
surface = oc_osx_surface_create_host(window);
#elif OC_PLATFORM_WINDOWS
surface = oc_win32_surface_create_host(window);
#endif
if(surface)
{
handle = oc_surface_handle_alloc(surface);
}
return (handle);
}
void oc_surface_destroy(oc_surface handle)
{
OC_DEBUG_ASSERT(oc_graphicsData.init);
@ -328,26 +279,6 @@ void* oc_surface_native_layer(oc_surface surface)
return (res);
}
oc_surface_id oc_surface_remote_id(oc_surface handle)
{
oc_surface_id remoteId = 0;
oc_surface_data* surface = oc_surface_data_from_handle(handle);
if(surface && surface->remoteID)
{
remoteId = surface->remoteID(surface);
}
return (remoteId);
}
void oc_surface_host_connect(oc_surface handle, oc_surface_id remoteID)
{
oc_surface_data* surface = oc_surface_data_from_handle(handle);
if(surface && surface->hostConnect)
{
surface->hostConnect(surface, remoteID);
}
}
void oc_surface_render_commands(oc_surface surface,
oc_color clearColor,
u32 primitiveCount,

View File

@ -31,8 +31,6 @@ typedef oc_vec2 (*oc_surface_contents_scaling_proc)(oc_surface_data* surface);
typedef bool (*oc_surface_get_hidden_proc)(oc_surface_data* surface);
typedef void (*oc_surface_set_hidden_proc)(oc_surface_data* surface, bool hidden);
typedef void* (*oc_surface_native_layer_proc)(oc_surface_data* surface);
typedef oc_surface_id (*oc_surface_remote_id_proc)(oc_surface_data* surface);
typedef void (*oc_surface_host_connect_proc)(oc_surface_data* surface, oc_surface_id remoteId);
typedef void (*oc_surface_bring_to_front_proc)(oc_surface_data* surface);
typedef void (*oc_surface_send_to_back_proc)(oc_surface_data* surface);
@ -52,8 +50,6 @@ typedef struct oc_surface_data
oc_surface_get_hidden_proc getHidden;
oc_surface_set_hidden_proc setHidden;
oc_surface_native_layer_proc nativeLayer;
oc_surface_remote_id_proc remoteID;
oc_surface_host_connect_proc hostConnect;
oc_surface_bring_to_front_proc bringToFront;
oc_surface_send_to_back_proc sendToBack;
@ -66,8 +62,6 @@ oc_surface oc_surface_handle_alloc(oc_surface_data* surface);
oc_surface_data* oc_surface_data_from_handle(oc_surface handle);
void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window);
void oc_surface_init_remote(oc_surface_data* surface, u32 width, u32 height);
void oc_surface_init_host(oc_surface_data* surface, oc_window_data* window);
void oc_surface_cleanup(oc_surface_data* surface);
void* oc_surface_native_layer(oc_surface surface);

View File

@ -40,9 +40,6 @@
//TODO: maybe make this conditional
#include "graphics/orca_gl31.h"
oc_surface oc_surface_canvas();
oc_surface oc_surface_gles();
#else
#ifdef OC_INCLUDE_GL_API
#include "graphics/gl_api.h"

View File

@ -1303,7 +1303,7 @@ void oc_ui_draw_box(oc_ui_box* box)
bool draw = true;
{
oc_rect clip = oc_clip();
oc_rect clip = oc_clip_top();
oc_rect expRect = {
box->rect.x - 0.5 * style->borderSize,
box->rect.y - 0.5 * style->borderSize,

View File

@ -36,6 +36,14 @@
{"name": "pixels",
"type": {"name": "u8*", "tag": "p"}}]
},
{
"name": "oc_surface_get_size",
"cname": "oc_surface_get_size",
"ret": {"name": "oc_vec2", "tag": "S"},
"args": [
{"name": "surface",
"type": {"name": "oc_surface", "tag": "S"}}]
},
{
"name": "oc_surface_contents_scaling",
"cname": "oc_surface_contents_scaling",