summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Guyomarc'h <jean.guyomarch@openwide.fr>2016-08-24 12:12:59 +0200
committerJean Guyomarc'h <jean@guyomarch.bzh>2016-08-25 21:41:17 +0200
commitd8e488b1c80fad6a0057988015f955634877a9ca (patch)
treef06b2cd96b6925b9feb6b88b3208b2154f291aa4
parentc2856b040ae720ff384b0ce02751b8b3b9762b3e (diff)
downloadefl-d8e488b1c80fad6a0057988015f955634877a9ca.tar.gz
evas-gl_cocoa: start refactoring for gl_generic
-rw-r--r--src/Makefile_Evas.am2
-rw-r--r--src/modules/evas/engines/gl_cocoa/evas_engine.c100
-rw-r--r--src/modules/evas/engines/gl_cocoa/evas_engine.h58
-rw-r--r--src/modules/evas/engines/gl_cocoa/evas_gl_cocoa_main.m182
-rw-r--r--src/modules/evas/engines/gl_cocoa/evas_outbuf.m217
5 files changed, 310 insertions, 249 deletions
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 _Render_Engine
+{
+ Render_Engine_GL_Generic generic;
+
+ Outbuf *win;
+ int end;
+};
-struct _Evas_GL_Cocoa_Window
+struct _Outbuf
{
- void* window;
- void* view;
- int width;
- int height;
- int depth;
+ 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 <Cocoa/Cocoa.h>
-#include <dlfcn.h>
-
-#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 <Cocoa/Cocoa.h>
+
+#include "evas_engine.h"
+#include "../gl_common/evas_gl_define.h"
+
+#include <dlfcn.h>
+
+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)
+{
+}