From d8e488b1c80fad6a0057988015f955634877a9ca Mon Sep 17 00:00:00 2001 From: Jean Guyomarc'h Date: Wed, 24 Aug 2016 12:12:59 +0200 Subject: [PATCH] evas-gl_cocoa: start refactoring for gl_generic --- src/Makefile_Evas.am | 2 +- .../evas/engines/gl_cocoa/evas_engine.c | 100 ++++---- .../evas/engines/gl_cocoa/evas_engine.h | 58 +++-- .../engines/gl_cocoa/evas_gl_cocoa_main.m | 182 --------------- .../evas/engines/gl_cocoa/evas_outbuf.m | 217 ++++++++++++++++++ 5 files changed, 310 insertions(+), 249 deletions(-) delete mode 100644 src/modules/evas/engines/gl_cocoa/evas_gl_cocoa_main.m create mode 100644 src/modules/evas/engines/gl_cocoa/evas_outbuf.m diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index 1f07e7ec33..0695e0a19b 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am @@ -914,7 +914,7 @@ if BUILD_ENGINE_GL_COCOA dist_installed_evasmainheaders_DATA += modules/evas/engines/gl_cocoa/Evas_Engine_GL_Cocoa.h GL_COCOA_SOURCES = \ modules/evas/engines/gl_cocoa/evas_engine.c \ -modules/evas/engines/gl_cocoa/evas_gl_cocoa_main.m \ +modules/evas/engines/gl_cocoa/evas_outbuf.m \ modules/evas/engines/gl_cocoa/evas_engine.h if EVAS_STATIC_BUILD_GL_COCOA lib_evas_libevas_la_SOURCES += $(GL_COCOA_SOURCES) diff --git a/src/modules/evas/engines/gl_cocoa/evas_engine.c b/src/modules/evas/engines/gl_cocoa/evas_engine.c index f4f347b3d3..d4c2f371d5 100644 --- a/src/modules/evas/engines/gl_cocoa/evas_engine.c +++ b/src/modules/evas/engines/gl_cocoa/evas_engine.c @@ -7,15 +7,13 @@ #define EVAS_GL_NO_GL_H_CHECK 1 #include "Evas_GL.h" -typedef struct _Render_Engine Render_Engine; Evas_Gl_Symbols glsym_evas_gl_symbols = NULL; - -struct _Render_Engine -{ - Evas_GL_Cocoa_Window *win; - int end; -}; +Evas_GL_Common_Context_New glsym_evas_gl_common_context_new = NULL; +Evas_GL_Common_Context_Call glsym_evas_gl_common_context_free = NULL; +Evas_GL_Common_Context_Call glsym_evas_gl_common_context_flush = NULL; +Evas_GL_Common_Context_Call glsym_evas_gl_common_context_use = NULL; +Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize = NULL; int _evas_engine_gl_cocoa_log_dom = -1; /* function tables - filled in later (func and parent func) */ @@ -55,16 +53,17 @@ eng_info_free(Evas *e EINA_UNUSED, void *info) } static int -eng_setup(Evas *eo_e, void *in) +eng_setup(Evas *evas, void *in) { EINA_SAFETY_ON_NULL_RETURN_VAL(in, 0); Evas_Engine_Info_GL_Cocoa *const info = in; Evas_Public_Data *e; - Render_Engine *re; + Render_Engine *re = NULL; + Outbuf *ob; DBG("Engine Setup"); - e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); + e = efl_data_scope_get(evas, EVAS_CANVAS_CLASS); if (EINA_UNLIKELY(!e)) { CRI("Failed to get evas public data"); @@ -89,36 +88,38 @@ eng_setup(Evas *eo_e, void *in) goto err; } - re->win = eng_window_new(info->window, + ob = evas_outbuf_new(info, e->output.w, e->output.h); - info->view = re->win->view; - if (!re->win) + if (EINA_UNLIKELY(!ob)) { - free(re); - e->engine.data.output = NULL; - return 0; + CRI("Failed to create outbuf"); + goto err; } + re->win = ob; // FIXME REMVOE ME + ob->evas = evas; + info->view = ob->ns_gl_view; e->engine.data.output = re; } else { re = e->engine.data.output; - eng_window_free(re->win); - re->win = eng_window_new(info->window, + evas_outbuf_free(re->win); + re->win = evas_outbuf_new(info, e->output.w, e->output.h); - info->view = re->win->view; + info->view = re->win->ns_gl_view; } if (!e->engine.data.output) return 0; if (!e->engine.data.context) e->engine.data.context = e->engine.func->context_new(e->engine.data.output); - eng_window_use(re->win); + evas_outbuf_use(re->win); return 1; err: + free(re); return 0; } @@ -129,7 +130,7 @@ eng_output_free(void *data) DBG("Output free"); re = (Render_Engine *)data; - eng_window_free(re->win); + evas_outbuf_free(re->win); free(re); if (_initted) @@ -152,7 +153,7 @@ eng_output_resize(void *data, int w, int h) re->win->height = h; evas_gl_common_context_resize(re->win->gl_context, w, h, 0); - eng_window_resize(re->win, w, h); + evas_outbuf_resize(re->win, w, h); } static void @@ -168,7 +169,7 @@ eng_output_redraws_rect_add(void *data, int x, int y, int w, int h) DBG("Redraw rect %d %d %d %d", x, y, w, h); re = (Render_Engine *)data; - eng_window_lock_focus(re->win); + evas_outbuf_lock_focus(re->win); evas_gl_common_context_resize(re->win->gl_context, re->win->width, re->win->height, 0); /* simple bounding box */ RECTS_CLIP_TO_RECT(x, y, w, h, 0, 0, re->win->width, re->win->height); @@ -196,7 +197,7 @@ eng_output_redraws_rect_add(void *data, int x, int y, int w, int h) } re->win->draw.redraw = 1; end: - eng_window_unlock_focus(re->win); + evas_outbuf_unlock_focus(re->win); } static void @@ -291,14 +292,14 @@ eng_output_flush(void *data, Evas_Render_Mode render_mode) if (!re->win->draw.drew) return; re->win->draw.drew = 0; - eng_window_use(re->win); + evas_outbuf_use(re->win); #ifdef VSYNC_TO_SCREEN - eng_window_vsync_set(1); + evas_outbuf_vsync_set(1); #endif - eng_window_lock_focus(re->win); - eng_window_swap_buffers(re->win); - eng_window_unlock_focus(re->win); + evas_outbuf_lock_focus(re->win); + evas_outbuf_swap_buffers(re->win); + evas_outbuf_unlock_focus(re->win); } static void @@ -319,7 +320,7 @@ eng_rectangle_draw(void *data, void *context, void *surface, int x, int y, int w Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); + evas_outbuf_use(re->win); evas_gl_common_context_target_surface_set(re->win->gl_context, surface); re->win->gl_context->dc = context; evas_gl_common_rect_draw(re->win->gl_context, x, y, w, h); @@ -331,7 +332,7 @@ eng_line_draw(void *data, void *context, void *surface, int p1x, int p1y, int p2 Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); + evas_outbuf_use(re->win); evas_gl_common_context_target_surface_set(re->win->gl_context, surface); re->win->gl_context->dc = context; evas_gl_common_line_draw(re->win->gl_context, p1x, p1y, p2x, p2y); @@ -361,7 +362,7 @@ eng_polygon_draw(void *data, void *context, void *surface EINA_UNUSED, void *pol Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); + evas_outbuf_use(re->win); evas_gl_common_context_target_surface_set(re->win->gl_context, surface); re->win->gl_context->dc = context; evas_gl_common_poly_draw(re->win->gl_context, polygon, x, y); @@ -402,7 +403,7 @@ eng_image_alpha_set(void *data, void *image, int has_alpha) im->alpha = has_alpha; return image; } - eng_window_use(re->win); + evas_outbuf_use(re->win); if ((im->tex) && (im->tex->pt->dyn.img)) { im->alpha = has_alpha; @@ -469,7 +470,7 @@ eng_image_colorspace_set(void *data, void *image, Evas_Colorspace cspace) if (im->native.data) return; /* FIXME: can move to gl_common */ if (im->cs.space == cspace) return; - eng_window_use(re->win); + evas_outbuf_use(re->win); evas_gl_common_image_alloc_ensure(im); evas_cache_image_colorspace(&im->im->cache_entry, cspace); switch (cspace) @@ -531,7 +532,7 @@ eng_image_load(void *data, const char *file, const char *key, int *error, Evas_I re = (Render_Engine *)data; *error = EVAS_LOAD_ERROR_NONE; - eng_window_use(re->win); + evas_outbuf_use(re->win); return evas_gl_common_image_load(re->win->gl_context, file, key, lo, error); } @@ -542,7 +543,7 @@ eng_image_mmap(void *data, Eina_File *f, const char *key, int *error, Evas_Image re = (Render_Engine *)data; *error = EVAS_LOAD_ERROR_NONE; - eng_window_use(re->win); + evas_outbuf_use(re->win); return evas_gl_common_image_mmap(re->win->gl_context, f, key, lo, error); } @@ -552,7 +553,7 @@ eng_image_new_from_data(void *data, int w, int h, DATA32 *image_data, int alpha, Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); + evas_outbuf_use(re->win); return evas_gl_common_image_new_from_data(re->win->gl_context, w, h, image_data, alpha, cspace); } @@ -562,7 +563,7 @@ eng_image_new_from_copied_data(void *data, int w, int h, DATA32 *image_data, int Render_Engine *re; re = (Render_Engine *)data; - eng_window_use(re->win); + evas_outbuf_use(re->win); return evas_gl_common_image_new_from_copied_data(re->win->gl_context, w, h, image_data, alpha, cspace); } @@ -573,7 +574,7 @@ eng_image_free(void *data, void *image) re = (Render_Engine *)data; if (!image) return; - eng_window_use(re->win); + evas_outbuf_use(re->win); evas_gl_common_image_unref(image); } @@ -605,7 +606,7 @@ eng_image_size_set(void *data, void *image, int w, int h) im->h = h; return image; } - eng_window_use(re->win); + evas_outbuf_use(re->win); if ((im->tex) && (im->tex->pt->dyn.img)) { evas_gl_common_texture_free(im->tex, EINA_TRUE); @@ -652,7 +653,7 @@ eng_image_dirty_region(void *data, void *image, int x, int y, int w, int h) re = (Render_Engine *)data; if (!image) return NULL; if (im->native.data) return image; - eng_window_use(re->win); + evas_outbuf_use(re->win); evas_gl_common_image_dirty(image, x, y, w, h); return image; } @@ -684,7 +685,7 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i if (err) *err = EVAS_LOAD_ERROR_NONE; return im; } - eng_window_use(re->win); + evas_outbuf_use(re->win); error = evas_cache_image_load_data(&im->im->cache_entry); evas_gl_common_image_alloc_ensure(im); switch (im->cs.space) @@ -740,7 +741,7 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data) if (!image) return NULL; im = image; if (im->native.data) return image; - eng_window_use(re->win); + evas_outbuf_use(re->win); evas_gl_common_image_alloc_ensure(im); if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.data)) { @@ -834,7 +835,7 @@ eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, re = (Render_Engine *)data; if (!image) return EINA_FALSE; - eng_window_use(re->win); + evas_outbuf_use(re->win); evas_gl_common_context_target_surface_set(re->win->gl_context, surface); re->win->gl_context->dc = context; evas_gl_common_image_draw(re->win->gl_context, image, @@ -866,7 +867,7 @@ eng_image_map_draw(void *data, void *context, void *surface, void *image, RGBA_M re = (Render_Engine *)data; if (!image) return EINA_FALSE; - eng_window_use(re->win); + evas_outbuf_use(re->win); evas_gl_common_context_target_surface_set(re->win->gl_context, surface); re->win->gl_context->dc = context; if (m->count != 4) @@ -926,7 +927,7 @@ eng_image_content_hint_set(void *data, void *image, int hint) Render_Engine *re; re = (Render_Engine *)data; - if (re) eng_window_use(re->win); + if (re) evas_outbuf_use(re->win); if (image) evas_gl_common_image_content_hint_set(image, hint); } @@ -990,7 +991,7 @@ static Eina_Bool eng_font_draw(void *data, void *context, void *surface, Evas_Font_Set *font EINA_UNUSED, int x, int y, int w EINA_UNUSED, int h EINA_UNUSED, int ow EINA_UNUSED, int oh EINA_UNUSED, Evas_Text_Props *intl_props, Eina_Bool do_async EINA_UNUSED) { Render_Engine *re = data; - eng_window_use(re->win); + evas_outbuf_use(re->win); evas_gl_common_context_target_surface_set(re->win->gl_context, surface); re->win->gl_context->dc = context; @@ -1386,6 +1387,11 @@ module_open(Evas_Module *em) #define LINK2GENERIC(sym) \ glsym_##sym = dlsym(RTLD_DEFAULT, #sym); + LINK2GENERIC(evas_gl_common_context_new); + LINK2GENERIC(evas_gl_common_context_flush); + LINK2GENERIC(evas_gl_common_context_free); + LINK2GENERIC(evas_gl_common_context_use); + LINK2GENERIC(evas_gl_common_context_resize); LINK2GENERIC(evas_gl_symbols); /* now advertise out own api */ diff --git a/src/modules/evas/engines/gl_cocoa/evas_engine.h b/src/modules/evas/engines/gl_cocoa/evas_engine.h index 07d0dc6a65..9c7cbdd554 100644 --- a/src/modules/evas/engines/gl_cocoa/evas_engine.h +++ b/src/modules/evas/engines/gl_cocoa/evas_engine.h @@ -9,8 +9,8 @@ #include "evas_gl_common.h" #include "Evas_Engine_GL_Cocoa.h" +#include "../gl_generic/Evas_Engine_GL_Generic.h" -extern Evas_Gl_Symbols glsym_evas_gl_symbols; extern int _evas_engine_gl_cocoa_log_dom; @@ -39,17 +39,30 @@ extern int _evas_engine_gl_cocoa_log_dom; #endif #define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_gl_cocoa_log_dom, __VA_ARGS__) -typedef struct _Evas_GL_Cocoa_Window Evas_GL_Cocoa_Window; +typedef struct _Render_Engine Render_Engine; -struct _Evas_GL_Cocoa_Window +struct _Render_Engine { - void* window; - void* view; - int width; - int height; - int depth; + Render_Engine_GL_Generic generic; + + Outbuf *win; + int end; +}; + +struct _Outbuf +{ + Evas_Engine_Info_GL_Cocoa *info; Evas_Engine_GL_Context *gl_context; - struct { + Evas *evas; + + void *ns_gl_view; // NSOpenGLView* + void *ns_window; // NSWindow* + + int width; + int height; + + // FIXME + struct { int x1; int y1; int x2; @@ -57,17 +70,24 @@ struct _Evas_GL_Cocoa_Window int redraw : 1; int drew : 1; } draw; + }; -Evas_GL_Cocoa_Window *eng_window_new(void *window, - int width, - int height); -void eng_window_free(Evas_GL_Cocoa_Window *gw); -void eng_window_use(Evas_GL_Cocoa_Window *gw); -void eng_window_swap_buffers(Evas_GL_Cocoa_Window *gw); -void eng_window_vsync_set(int on); -void eng_window_resize(Evas_GL_Cocoa_Window *gw, int width, int height); -void eng_window_lock_focus(Evas_GL_Cocoa_Window *gw); -void eng_window_unlock_focus(Evas_GL_Cocoa_Window *gw); + +extern Evas_Gl_Symbols glsym_evas_gl_symbols; +extern Evas_GL_Common_Context_New glsym_evas_gl_common_context_new; +extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_free; +extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_flush; +extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_use; +extern Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize; + +Outbuf *evas_outbuf_new(Evas_Engine_Info_GL_Cocoa *info, int w, int h); +void evas_outbuf_free(Outbuf *ob); +void evas_outbuf_use(Outbuf *ob); +void evas_outbuf_lock_focus(Outbuf *ob); +void evas_outbuf_unlock_focus(Outbuf *ob); +void evas_outbuf_resize(Outbuf *ob, int w, int h); +void evas_outbuf_swap_buffers(Outbuf *ob); +void evas_outbuf_vsync_set(int on); // FIXME #endif /* __EVAS_ENGINE_H__ */ diff --git a/src/modules/evas/engines/gl_cocoa/evas_gl_cocoa_main.m b/src/modules/evas/engines/gl_cocoa/evas_gl_cocoa_main.m deleted file mode 100644 index 082de38fd2..0000000000 --- a/src/modules/evas/engines/gl_cocoa/evas_gl_cocoa_main.m +++ /dev/null @@ -1,182 +0,0 @@ -#include -#include - -#include "evas_engine.h" - -static Evas_GL_Cocoa_Window *_evas_gl_cocoa_window = NULL; -static NSOpenGLContext *_evas_gl_cocoa_shared_context = NULL; - -@interface EvasGLView : NSOpenGLView -{ -} - -+ (NSOpenGLPixelFormat*) basicPixelFormat; -- (id) initWithFrame: (NSRect) frameRect; - -@end - - -@implementation EvasGLView - -- (id) init -{ - self = [super init]; - return self; -} - -+ (NSOpenGLPixelFormat*) basicPixelFormat -{ - NSOpenGLPixelFormatAttribute attributes [] = { - NSOpenGLPFAWindow, - NSOpenGLPFAAccelerated, - NSOpenGLPFADoubleBuffer, - /*NSOpenGLPFAColorSize, 24, - NSOpenGLPFAAlphaSize, 8, - NSOpenGLPFADepthSize, 24,*/ - 0 - }; - return [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease]; -} - -// --------------------------------- - --(id) initWithFrame: (NSRect) frameRect -{ - NSOpenGLPixelFormat * pf = [EvasGLView basicPixelFormat]; - self = [super initWithFrame: frameRect pixelFormat: pf]; - - - NSOpenGLContext *ctx; - if (!_evas_gl_cocoa_shared_context) { - _evas_gl_cocoa_shared_context = [[NSOpenGLContext alloc] initWithFormat: [EvasGLView basicPixelFormat] shareContext: nil]; - ctx = _evas_gl_cocoa_shared_context; - } else { - ctx = [[NSOpenGLContext alloc] initWithFormat: [EvasGLView basicPixelFormat] shareContext: _evas_gl_cocoa_shared_context]; - } - [self setOpenGLContext: ctx]; - [ctx setView: self]; - - return self; -} - -- (void)unlockFocus -{ - //[super unlockFocus]; -} - -- (void)lockFocus -{ - NSOpenGLContext* context = [self openGLContext]; - - //[super lockFocus]; - if ([context view] != self) { - [context setView:self]; - } - [context makeCurrentContext]; -} - -@end - -static void * -_dlsym(const char *sym) -{ - return dlsym(RTLD_DEFAULT, sym); -} - - -Evas_GL_Cocoa_Window * -eng_window_new(void *window, - int w, - int h) -{ - Evas_GL_Cocoa_Window *gw; - - gw = calloc(1, sizeof(Evas_GL_Cocoa_Window)); - if (!gw) return NULL; - - _evas_gl_cocoa_window = gw; - gw->window = window; - gw->view = [[EvasGLView alloc] initWithFrame:NSMakeRect(0,0,w,h)]; - NSOpenGLContext *ctx = [(NSOpenGLView*)gw->view openGLContext]; - [ctx makeCurrentContext]; - - glsym_evas_gl_symbols(_dlsym); - gw->gl_context = evas_gl_common_context_new(); - - if (!gw->gl_context) - { - free(gw); - return NULL; - } - evas_gl_common_context_use(gw->gl_context); - evas_gl_common_context_resize(gw->gl_context, w, h, 0); - - return gw; -} - -void -eng_window_free(Evas_GL_Cocoa_Window *gw) -{ - if (gw == _evas_gl_cocoa_window) - _evas_gl_cocoa_window = NULL; - - evas_common_font_ext_clear(); - evas_gl_common_context_free(gw->gl_context); - [(EvasGLView*)gw->view release]; - free(gw); -} - -void -eng_window_use(Evas_GL_Cocoa_Window *gw) -{ - if ((gw) && (!gw->gl_context)) return; - if (_evas_gl_cocoa_window != gw) - { - [[(NSOpenGLView*)gw->view openGLContext] makeCurrentContext]; - if (_evas_gl_cocoa_window) - evas_gl_common_context_flush(_evas_gl_cocoa_window->gl_context); - _evas_gl_cocoa_window = gw; - - } - evas_gl_common_context_use(gw->gl_context); -} - -void -eng_window_swap_buffers(Evas_GL_Cocoa_Window *gw) -{ - [[(NSOpenGLView*)gw->view openGLContext] flushBuffer]; -} - -void -eng_window_vsync_set(int on EINA_UNUSED) -{ - -} - - -void -eng_window_resize(Evas_GL_Cocoa_Window *gw, int width, int height) -{ - NSRect view_frame; - - INF("Resize %d %d\n", width, height); - - view_frame = [(EvasGLView*)gw->view frame]; - view_frame.size.height = height; - view_frame.size.width = width; - - [(EvasGLView*)gw->view setFrame:view_frame]; - [[(NSOpenGLView*)gw->view openGLContext] flushBuffer]; -} - -void -eng_window_lock_focus(Evas_GL_Cocoa_Window *gw) -{ - [(NSOpenGLView*)gw->view lockFocus]; -} - -void -eng_window_unlock_focus(Evas_GL_Cocoa_Window *gw) -{ - [(NSOpenGLView*)gw->view unlockFocus]; -} diff --git a/src/modules/evas/engines/gl_cocoa/evas_outbuf.m b/src/modules/evas/engines/gl_cocoa/evas_outbuf.m new file mode 100644 index 0000000000..56a1b809b9 --- /dev/null +++ b/src/modules/evas/engines/gl_cocoa/evas_outbuf.m @@ -0,0 +1,217 @@ +#include + +#include "evas_engine.h" +#include "../gl_common/evas_gl_define.h" + +#include + +static Outbuf *_evas_gl_cocoa_window = NULL; +static int _win_count = 0; + +@interface EvasGLView : NSOpenGLView + ++ (NSOpenGLPixelFormat*) basicPixelFormat; + +@end + +@implementation EvasGLView + ++ (NSOpenGLPixelFormat*) basicPixelFormat +{ + NSOpenGLPixelFormatAttribute attributes [] = { + NSOpenGLPFAWindow, + NSOpenGLPFAAccelerated, + NSOpenGLPFADoubleBuffer, + /*NSOpenGLPFAColorSize, 24, + NSOpenGLPFAAlphaSize, 8, + NSOpenGLPFADepthSize, 24,*/ + 0 + }; + return [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease]; +} + +- (id) initWithFrame: (NSRect) frameRect +{ + NSOpenGLPixelFormat *pf; + NSOpenGLContext *ctx; + + pf = [EvasGLView basicPixelFormat]; + self = [super initWithFrame: frameRect + pixelFormat: pf]; + ctx = [[NSOpenGLContext alloc] initWithFormat:pf + shareContext: nil]; + + [self setOpenGLContext: ctx]; + [ctx setView: self]; + + return self; +} + +- (void)unlockFocus +{ + //[super unlockFocus]; +} + +- (void)lockFocus +{ + NSOpenGLContext* context = [self openGLContext]; + + //[super lockFocus]; + if ([context view] != self) { + [context setView:self]; + } + [context makeCurrentContext]; +} + +@end + +static void * +_dlsym(const char *sym) +{ + return dlsym(RTLD_DEFAULT, sym); +} + +Outbuf * +evas_outbuf_new(Evas_Engine_Info_GL_Cocoa *info, + int w, + int h) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(info, NULL); + + Outbuf *ob; + + ob = calloc(1, sizeof(*ob)); + if (EINA_UNLIKELY(!ob)) + { + CRI("Failed to allocate memory"); + goto die; + } + _win_count++; + + ob->width = w; + ob->height = h; + ob->info = info; + ob->ns_window = info->window; + + ob->ns_gl_view = [[EvasGLView alloc] initWithFrame: NSMakeRect(0, 0, w, h)]; + if (EINA_UNLIKELY(!ob->ns_gl_view)) + { + CRI("Failed to create gl_view"); + goto die; + } + [[(NSOpenGLView *)ob->ns_gl_view openGLContext] makeCurrentContext]; + + glsym_evas_gl_symbols(_dlsym); + ob->gl_context = glsym_evas_gl_common_context_new(); + if (EINA_UNLIKELY(!ob->gl_context)) + { + CRI("Failed to create gl_context"); + goto die; + } + + + evas_outbuf_use(ob); + + glsym_evas_gl_common_context_resize(ob->gl_context, ob->width, ob->height, 0); // TODO rotation + + return ob; + +die: + if (ob) free(ob); + return NULL; +} + +void +evas_outbuf_free(Outbuf *ob) +{ + int refs = 0; + + _win_count--; + evas_outbuf_use(ob); + + if (_win_count == 0) evas_common_font_ext_clear(); + + if (ob == _evas_gl_cocoa_window) _evas_gl_cocoa_window = NULL; + if (ob->gl_context) + { + refs = ob->gl_context->references - 1; + glsym_evas_gl_common_context_free(ob->gl_context); + [(NSOpenGLView *) ob->ns_gl_view release]; + } + + if (refs == 0) + { + // TODO + } + free(ob); +} + +void +evas_outbuf_use(Outbuf *ob) +{ + Eina_Bool force = EINA_FALSE; + + // TODO preload_render_Lock + + if (_evas_gl_cocoa_window) + { + // TODO ifcurrent context is not glcontext + force = EINA_TRUE; + } + + if ((_evas_gl_cocoa_window != ob) || (force)) + { + if (_evas_gl_cocoa_window) + { + glsym_evas_gl_common_context_use(_evas_gl_cocoa_window->gl_context); + glsym_evas_gl_common_context_flush(_evas_gl_cocoa_window->gl_context); + } + + [[(NSOpenGLView *)ob->ns_gl_view openGLContext] makeCurrentContext]; + _evas_gl_cocoa_window = ob; + // TODO blah + } + + if (ob) glsym_evas_gl_common_context_use(ob->gl_context); +} + +void +evas_outbuf_resize(Outbuf *ob, + int w, + int h) +{ + NSRect view_frame; + NSOpenGLView *const view = ob->ns_gl_view; + + INF("Resize %d %d\n", w, h); + + view_frame = [view frame]; + view_frame.size.height = h; + view_frame.size.width = w; + + [view setFrame:view_frame]; + [[view openGLContext] flushBuffer]; +} + +void +evas_outbuf_lock_focus(Outbuf *ob) +{ + [(NSOpenGLView *)ob->ns_gl_view lockFocus]; +} + +void +evas_outbuf_unlock_focus(Outbuf *ob) +{ + [(NSOpenGLView *)ob->ns_gl_view unlockFocus]; +} + +void +evas_outbuf_swap_buffers(Outbuf *ob) +{ + [[(NSOpenGLView *)ob->ns_gl_view openGLContext] flushBuffer]; +} + +void // FIXME +evas_outbuf_vsync_set(int on EINA_UNUSED) +{ +}