evas-gl_cocoa: start refactoring for gl_generic
authorJean Guyomarc'h <jean.guyomarch@openwide.fr>
Wed, 24 Aug 2016 10:12:59 +0000 (12:12 +0200)
committerJean Guyomarc'h <jean@guyomarch.bzh>
Thu, 25 Aug 2016 19:41:17 +0000 (21:41 +0200)
src/Makefile_Evas.am
src/modules/evas/engines/gl_cocoa/evas_engine.c
src/modules/evas/engines/gl_cocoa/evas_engine.h
src/modules/evas/engines/gl_cocoa/evas_gl_cocoa_main.m [deleted file]
src/modules/evas/engines/gl_cocoa/evas_outbuf.m [new file with mode: 0644]

index 1f07e7e..0695e0a 100644 (file)
@@ -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)
index f4f347b..d4c2f37 100644 (file)
@@ -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 */
index 07d0dc6..9c7cbdd 100644 (file)
@@ -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 (file)
index 082de38..0000000
+++ /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 (file)
index 0000000..56a1b80
--- /dev/null
@@ -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)
+{
+}