[cogl/wip/gles2-context] WIP: Add CoglGLES2Context



commit b3a441e8be133c0a903beabc4b239c8aa81387f4
Author: Tomeu Vizoso <tomeu vizoso collabora com>
Date:   Tue Dec 6 17:18:41 2011 +0100

    WIP: Add CoglGLES2Context

 cogl/Makefile.am                  |    4 +-
 cogl/cogl-ext-functions.h         |   31 ++++++++++
 cogl/cogl-framebuffer.c           |   56 +++++++++++++++++++
 cogl/cogl-framebuffer.h           |    9 +++
 cogl/cogl-gles2-context-private.h |   33 +++++++++++
 cogl/cogl-gles2-context.c         |  110 +++++++++++++++++++++++++++++++++++++
 cogl/cogl-gles2-context.h         |   68 +++++++++++++++++++++++
 cogl/cogl.h                       |    6 ++-
 cogl/winsys/cogl-winsys-egl.c     |  105 +++++++++++++++++++++++++++++++++++
 cogl/winsys/cogl-winsys-private.h |   10 +++
 examples/Makefile.am              |    5 +-
 examples/cogl-gles2-context.c     |   92 +++++++++++++++++++++++++++++++
 12 files changed, 526 insertions(+), 3 deletions(-)
---
diff --git a/cogl/Makefile.am b/cogl/Makefile.am
index 2f732bc..82dcdeb 100644
--- a/cogl/Makefile.am
+++ b/cogl/Makefile.am
@@ -105,6 +105,8 @@ cogl_experimental_h = \
 	$(srcdir)/cogl-pipeline-state.h 	\
 	$(srcdir)/cogl-pipeline-layer-state.h 	\
 	$(srcdir)/cogl-snippet.h		\
+	$(srcdir)/cogl-ext-functions.h			\
+	$(srcdir)/cogl-gles2-context.h			\
 	$(srcdir)/cogl2-path.h 			\
 	$(srcdir)/cogl2-clip-state.h		\
 	$(srcdir)/cogl2-experimental.h		\
@@ -216,7 +218,6 @@ cogl_sources_c = \
 	$(srcdir)/cogl-clip-state.c			\
 	$(srcdir)/cogl2-clip-state.h 			\
 	$(srcdir)/cogl2-clip-state.c 			\
-	$(srcdir)/cogl-ext-functions.h			\
 	$(srcdir)/cogl-feature-private.h                \
 	$(srcdir)/cogl-feature-private.c                \
 	$(srcdir)/cogl-fixed.c		    		\
@@ -336,6 +337,7 @@ cogl_sources_c = \
 	$(srcdir)/cogl-boxed-value.c			\
 	$(srcdir)/cogl-snippet-private.h		\
 	$(srcdir)/cogl-snippet.c			\
+	$(srcdir)/cogl-gles2-context.c			\
 	$(NULL)
 
 if SUPPORT_XLIB
diff --git a/cogl/cogl-ext-functions.h b/cogl/cogl-ext-functions.h
index ecc8b8a..a9c2001 100644
--- a/cogl/cogl-ext-functions.h
+++ b/cogl/cogl-ext-functions.h
@@ -69,6 +69,8 @@ COGL_EXT_FUNCTION (void, glClearColor,
                     GLclampf alpha))
 COGL_EXT_FUNCTION (void, glClearStencil,
                    (GLint s))
+COGL_EXT_FUNCTION (void, glClearDepthf,
+                   (GLclampf depth))
 COGL_EXT_FUNCTION (void, glColorMask,
                    (GLboolean red,
                     GLboolean green,
@@ -150,6 +152,10 @@ COGL_EXT_FUNCTION (void, glTexImage2D,
                     const GLvoid* pixels))
 COGL_EXT_FUNCTION (void, glTexParameterfv,
                    (GLenum target, GLenum pname, const GLfloat* params))
+COGL_EXT_FUNCTION (void, glTexParameterf,
+                   (GLenum target,
+                    GLenum pname,
+                    GLfloat param))
 COGL_EXT_FUNCTION (void, glTexParameteri,
                    (GLenum target, GLenum pname, GLint param))
 COGL_EXT_FUNCTION (void, glTexSubImage2D,
@@ -164,6 +170,31 @@ COGL_EXT_FUNCTION (void, glTexSubImage2D,
                     const GLvoid* pixels))
 COGL_EXT_FUNCTION (void, glViewport,
                    (GLint x, GLint y, GLsizei width, GLsizei height))
+COGL_EXT_FUNCTION (void, glGetActiveAttrib,
+                   (GLuint program,
+                    GLuint index,
+                    GLsizei bufsize,
+                    GLsizei* length,
+                    GLint* size,
+                    GLenum* type,
+                    GLchar* name))
+COGL_EXT_FUNCTION (void, glColor3f,
+                   (GLfloat red,
+                    GLfloat green,
+                    GLfloat blue))
+COGL_EXT_FUNCTION (void, glRectf,
+                   (GLfloat x1,
+                    GLfloat y1,
+                    GLfloat x2,
+                    GLfloat y2))
+COGL_EXT_FUNCTION (void, glBegin,
+                   (GLenum mode))
+COGL_EXT_FUNCTION (void, glEnd,
+                   ())
+COGL_EXT_FUNCTION (void, glVertex3f,
+                   (GLfloat x,
+                    GLfloat y,
+                    GLfloat z))
 COGL_EXT_END ()
 
 /* These are the core GL functions which are available when the API
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index 829b5c2..0c16261 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -41,6 +41,7 @@
 #include "cogl-winsys-private.h"
 #include "cogl-pipeline-state-private.h"
 #include "cogl-matrix-private.h"
+#include "cogl-gles2-context-private.h"
 
 #ifndef GL_FRAMEBUFFER
 #define GL_FRAMEBUFFER		0x8D40
@@ -2407,3 +2408,58 @@ _cogl_framebuffer_restore_clip_stack (CoglFramebuffer *framebuffer)
     framebuffer->context->current_draw_buffer_changes |=
       COGL_FRAMEBUFFER_STATE_CLIP;
 }
+
+gboolean
+cogl_framebuffer_push_gles2_context (CoglFramebuffer *framebuffer,
+                                     CoglGLES2Context *gles2_ctx,
+                                     GError **error)
+{
+  CoglContext *ctx = gles2_ctx->context;
+  CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer);
+  const CoglWinsysVtable *winsys;
+  GLuint tex_gl_handle;
+  GLenum tex_gl_target;
+  GLuint fbo_gl_handle;
+  gboolean result;
+
+  if (!cogl_has_feature (ctx, COGL_FEATURE_ID_GLES2_CONTEXT))
+    return FALSE;
+
+  winsys = ctx->display->renderer->winsys_vtable;
+  result = winsys->make_current (gles2_ctx, error);
+  if (!result)
+    return FALSE;
+
+  fbo_gl_handle = cogl_object_get_user_data (COGL_OBJECT (framebuffer), gles2_ctx);
+  if (fbo_gl_handle == 0)
+    {
+      ctx->glGenFramebuffers(1, &fbo_gl_handle);
+      cogl_object_set_user_data (COGL_OBJECT (framebuffer), gles2_ctx, fbo_gl_handle, NULL);
+    }
+
+  GE (ctx, glBindFramebuffer (GL_FRAMEBUFFER, fbo_gl_handle));
+
+  if (!cogl_texture_get_gl_texture (offscreen->texture,
+                                    &tex_gl_handle, &tex_gl_target))
+    return FALSE;
+
+  GE (ctx, glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                   tex_gl_target, tex_gl_handle,
+                                   offscreen->texture_level));
+
+  return TRUE;
+}
+
+void
+cogl_framebuffer_pop_gles2_context (CoglFramebuffer *framebuffer)
+{
+  //CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
+  const CoglWinsysVtable *winsys;
+
+  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+  ctx->glFlush ();
+
+  winsys = ctx->display->renderer->winsys_vtable;
+  winsys->make_current (NULL, NULL);
+}
diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h
index e6be63a..8807ea2 100644
--- a/cogl/cogl-framebuffer.h
+++ b/cogl/cogl-framebuffer.h
@@ -29,6 +29,7 @@
 #define __COGL_FRAMEBUFFER_H
 
 #include <cogl/cogl.h>
+#include <cogl/cogl-gles2-context.h>
 
 #include <glib.h>
 
@@ -943,6 +944,14 @@ cogl_framebuffer_finish (CoglFramebuffer *framebuffer);
 CoglFramebuffer *
 cogl_get_draw_framebuffer (void);
 
+#define cogl_framebuffer_push_gles2_context cogl_framebuffer_push_gles2_context_EXP
+gboolean cogl_framebuffer_push_gles2_context (CoglFramebuffer *framebuffer,
+                                              CoglGLES2Context *gles2_ctx,
+                                              GError **error);
+
+#define cogl_framebuffer_pop_gles2_context cogl_framebuffer_pop_gles2_context_EXP
+void cogl_framebuffer_pop_gles2_context (CoglFramebuffer *framebuffer);
+
 #endif /* COGL_ENABLE_EXPERIMENTAL_API */
 
 /* XXX: Note these are defined outside the COGL_ENABLE_EXPERIMENTAL_API guard since
diff --git a/cogl/cogl-gles2-context-private.h b/cogl/cogl-gles2-context-private.h
new file mode 100644
index 0000000..70ba753
--- /dev/null
+++ b/cogl/cogl-gles2-context-private.h
@@ -0,0 +1,33 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2007,2008,2009 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ */
+
+#ifndef __COGL_GLES2_CONTEXT_PRIVATE_H
+#define __COGL_GLES2_CONTEXT_PRIVATE_H
+
+struct _CoglGLES2Context
+{
+    CoglContext *context;
+    void        *winsys;
+};
+
+#endif /* __COGL_GLES2_CONTEXT_PRIVATE_H */
diff --git a/cogl/cogl-gles2-context.c b/cogl/cogl-gles2-context.c
new file mode 100644
index 0000000..5a5a00c
--- /dev/null
+++ b/cogl/cogl-gles2-context.c
@@ -0,0 +1,110 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *  Tomeu Vizoso <tomeu vizoso collabora com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "cogl-gles2-context.h"
+#include "cogl-gles2-context-private.h"
+
+#include "cogl-context-private.h"
+#include "cogl-display-private.h"
+#include "cogl-framebuffer-private.h"
+#include "cogl-onscreen-template-private.h"
+#include "cogl-renderer-private.h"
+#include "cogl-swap-chain-private.h"
+#include "cogl-texture-2d-private.h"
+#include "winsys/cogl-winsys-egl-private.h"
+
+GQuark
+_cogl_gles2_context_error_quark (void)
+{
+  return g_quark_from_static_string ("cogl-gles2-context-error-quark");
+}
+
+#define COGL_GLES2_CONTEXT_ERROR (_cogl_gles2_context_error_quark ())
+
+typedef enum { /*< prefix=COGL_GLES2_CONTEXT_ERROR >*/
+  COGL_GLES2_CONTEXT_ERROR_NEW,
+  COGL_GLES2_CONTEXT_ERROR_PUSH_CONTEXT,
+} CoglGLES2ContextError;
+
+CoglGLES2Context *
+cogl_gles2_context_new (CoglContext *ctx, GError **error)
+{
+  CoglGLES2Context *gles2_context;
+  const CoglWinsysVtable *winsys;
+
+  if (!cogl_has_feature (ctx, COGL_FEATURE_ID_GLES2_CONTEXT))
+    {
+      g_set_error (error, COGL_GLES2_CONTEXT_ERROR,
+                   COGL_GLES2_CONTEXT_ERROR_NEW,
+                   "Backend doesn't support creating GLES2 contexts");
+
+      return NULL;
+    }
+
+  gles2_context = g_malloc (sizeof (CoglGLES2Context));
+
+  cogl_object_ref (ctx);
+  gles2_context->context = ctx;
+
+  winsys = ctx->display->renderer->winsys_vtable;
+  gles2_context->winsys = winsys->create_gles2_context (ctx, error);
+  if (gles2_context->winsys == NULL)
+    {
+      g_free (gles2_context);
+      return NULL;
+    }
+
+  return gles2_context;
+}
+
+CoglGLES2Vtable *
+cogl_gles2_context_get_vtable (CoglGLES2Context *gles2_ctx)
+{
+  CoglContext *ctx = gles2_ctx->context;
+  CoglGLES2Vtable *vtable = g_malloc (sizeof (CoglGLES2Vtable));
+
+#define COGL_EXT_BEGIN(name, \
+                       min_gl_major, min_gl_minor, \
+                       gles_availability, \
+                       extension_suffixes, extension_names)
+
+#define COGL_EXT_FUNCTION(ret, name, args) \
+  vtable->name = ctx->name;
+
+#define COGL_EXT_END()
+
+#include "cogl-ext-functions.h"
+
+#undef COGL_EXT_BEGIN
+#undef COGL_EXT_FUNCTION
+#undef COGL_EXT_END
+
+  return vtable;
+}
diff --git a/cogl/cogl-gles2-context.h b/cogl/cogl-gles2-context.h
new file mode 100644
index 0000000..eea9cbd
--- /dev/null
+++ b/cogl/cogl-gles2-context.h
@@ -0,0 +1,68 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *  Tomeu Vizoso <tomeu vizoso collabora com>
+ *
+ */
+
+#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
+#error "Only <cogl/cogl.h> can be included directly."
+#endif
+
+#ifndef __COGL_GLES2_CONTEXT_H__
+#define __COGL_GLES2_CONTEXT_H__
+
+#include <cogl/cogl-defines.h>
+#include <cogl/cogl-context.h>
+
+G_BEGIN_DECLS
+
+typedef struct _CoglGLES2Context CoglGLES2Context;
+typedef struct _CoglGLES2Vtable CoglGLES2Vtable;
+
+struct _CoglGLES2Vtable
+{
+#define COGL_EXT_BEGIN(name, \
+                       min_gl_major, min_gl_minor, \
+                       gles_availability, \
+                       extension_suffixes, extension_names)
+
+#define COGL_EXT_FUNCTION(ret, name, args) \
+  ret (* name) args;
+
+#define COGL_EXT_END()
+
+#include <cogl/cogl-ext-functions.h>
+
+#undef COGL_EXT_BEGIN
+#undef COGL_EXT_FUNCTION
+#undef COGL_EXT_END
+};
+
+CoglGLES2Context *cogl_gles2_context_new (CoglContext *ctx, GError **error);
+
+CoglGLES2Vtable *cogl_gles2_context_get_vtable (CoglGLES2Context *gles2_ctx);
+
+G_END_DECLS
+
+#endif /* __COGL_GLES2_CONTEXT_H__ */
+
diff --git a/cogl/cogl.h b/cogl/cogl.h
index ec2ccc7..945ee60 100644
--- a/cogl/cogl.h
+++ b/cogl/cogl.h
@@ -97,10 +97,11 @@ typedef struct _CoglFramebuffer CoglFramebuffer;
 #include <cogl/cogl-snippet.h>
 #include <cogl/cogl-framebuffer.h>
 #include <cogl/cogl-onscreen.h>
+#include <cogl/cogl-gles2-context.h>
 #if defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
 #include <cogl/cogl-wayland-renderer.h>
 #endif
-#if COGL_HAS_WIN32_SUPPORT
+#ifdef COGL_HAS_WIN32_SUPPORT
 #include <cogl/cogl-win32-renderer.h>
 #endif
 /* XXX: This will definitly go away once all the Clutter winsys
@@ -200,6 +201,8 @@ cogl_features_available (CoglFeatureFlags features);
  *     supported with CoglBufferAccess including write support.
  * @COGL_FEATURE_ID_MIRRORED_REPEAT: Whether
  *    %COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT is supported.
+ * @COGL_FEATURE_ID_GLES2_CONTEXT: Whether creating new GLES2 contexts is
+ *    suported.
  *
  *
  * All the capabilities that can vary between different GPUs supported
@@ -227,6 +230,7 @@ typedef enum _CoglFeatureID
   COGL_FEATURE_ID_MAP_BUFFER_FOR_READ,
   COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE,
   COGL_FEATURE_ID_MIRRORED_REPEAT,
+  COGL_FEATURE_ID_GLES2_CONTEXT,
 
   /*< private > */
   _COGL_N_FEATURE_IDS
diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c
index 895a8d8..c068177 100644
--- a/cogl/winsys/cogl-winsys-egl.c
+++ b/cogl/winsys/cogl-winsys-egl.c
@@ -40,6 +40,7 @@
 #include "cogl-swap-chain-private.h"
 #include "cogl-renderer-private.h"
 #include "cogl-onscreen-template-private.h"
+#include "cogl-gles2-context-private.h"
 #ifdef COGL_HAS_EGL_PLATFORM_POWERVR_X11_SUPPORT
 #include "cogl-xlib-renderer-private.h"
 #include "cogl-xlib-display-private.h"
@@ -458,6 +459,9 @@ update_winsys_features (CoglContext *context, GError **error)
                       COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE);
     }
 
+  COGL_FLAGS_SET (context->features,
+                  COGL_FEATURE_ID_GLES2_CONTEXT, TRUE);
+
   return TRUE;
 }
 
@@ -1771,6 +1775,103 @@ _cogl_winsys_texture_pixmap_x11_get_texture (CoglTexturePixmapX11 *tex_pixmap)
 }
 #endif /* defined (COGL_HAS_XLIB_SUPPORT) && defined (EGL_KHR_image_pixmap) */
 
+static const gchar *
+get_error_string ()
+{
+  switch (eglGetError()){
+  case EGL_BAD_DISPLAY:
+    return "Invalid display";
+  case EGL_NOT_INITIALIZED:
+    return "Display not initialized";
+  case EGL_BAD_ALLOC:
+    return "Not enough resources to allocate context";
+  case EGL_BAD_ATTRIBUTE:
+    return "Invalid attribute";
+  case EGL_BAD_CONFIG:
+    return "Invalid config";
+  case EGL_BAD_CONTEXT:
+    return "Invalid context";
+  case EGL_BAD_CURRENT_SURFACE:
+     return "Invalid current surface";
+  case EGL_BAD_MATCH:
+     return "Bad match";
+  case EGL_BAD_NATIVE_PIXMAP:
+     return "Invalid native pixmap";
+  case EGL_BAD_NATIVE_WINDOW:
+     return "Invalid native window";
+  case EGL_BAD_PARAMETER:
+     return "Invalid parameter";
+  case EGL_BAD_SURFACE:
+     return "Invalid surface";
+  default:
+    g_assert_not_reached ();
+  }
+}
+
+void *
+_cogl_winsys_create_gles2_context (CoglContext *ctx, GError **error)
+{
+  CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys;
+  CoglDisplayEGL *egl_display = ctx->display->winsys;
+  EGLint attribs[3];
+  EGLContext egl_context;
+
+  attribs[0] = EGL_CONTEXT_CLIENT_VERSION;
+  attribs[1] = 2;
+  attribs[2] = EGL_NONE;
+
+  egl_context = eglCreateContext (egl_renderer->edpy,
+                                  egl_display->egl_config,
+                                  egl_display->egl_context,
+                                  attribs);
+  if (egl_context == EGL_NO_CONTEXT)
+    {
+      g_set_error (error, COGL_WINSYS_ERROR,
+                   COGL_WINSYS_ERROR_CREATE_GLES2_CONTEXT,
+                   "%s", get_error_string ());
+    }
+
+  return egl_context;
+}
+
+gboolean
+_cogl_winsys_make_current (CoglGLES2Context *gles2_ctx,
+                           GError **error)
+{
+  //CoglContext *ctx = gles2_ctx->context;
+  CoglDisplayEGL *egl_display;
+  CoglRendererEGL *egl_renderer;
+  EGLContext egl_context;
+  gboolean result;
+
+  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+  egl_display = ctx->display->winsys;
+  egl_renderer = ctx->display->renderer->winsys;
+
+  if (gles2_ctx != NULL)
+    {
+      ctx = gles2_ctx->context;
+      egl_context = gles2_ctx->winsys;
+    }
+  else
+    {
+      egl_context = egl_display->egl_context;
+    }
+
+  result = eglMakeCurrent (egl_renderer->edpy,
+                           egl_display->dummy_surface,
+                           egl_display->dummy_surface,
+                           egl_context);
+  if (!result)
+    {
+      g_set_error (error, COGL_WINSYS_ERROR,
+                   COGL_WINSYS_ERROR_MAKE_CURRENT,
+                   "%s", get_error_string ());
+    }
+
+  return result;
+}
 
 static CoglWinsysVtable _cogl_winsys_vtable =
   {
@@ -1817,6 +1918,10 @@ static CoglWinsysVtable _cogl_winsys_vtable =
     .texture_pixmap_x11_get_texture =
       _cogl_winsys_texture_pixmap_x11_get_texture,
 #endif /* defined (COGL_HAS_XLIB_SUPPORT) && defined (EGL_KHR_image_pixmap) */
+    .create_gles2_context =
+      _cogl_winsys_create_gles2_context,
+    .make_current =
+      _cogl_winsys_make_current,
   };
 
 /* XXX: we use a function because no doubt someone will complain
diff --git a/cogl/winsys/cogl-winsys-private.h b/cogl/winsys/cogl-winsys-private.h
index 16317b7..b4f0f2c 100644
--- a/cogl/winsys/cogl-winsys-private.h
+++ b/cogl/winsys/cogl-winsys-private.h
@@ -26,6 +26,7 @@
 
 #include "cogl-renderer.h"
 #include "cogl-onscreen.h"
+#include "cogl-gles2-context.h"
 
 #ifdef COGL_HAS_XLIB_SUPPORT
 #include "cogl-texture-pixmap-x11-private.h"
@@ -45,6 +46,8 @@ typedef enum { /*< prefix=COGL_WINSYS_ERROR >*/
   COGL_WINSYS_ERROR_INIT,
   COGL_WINSYS_ERROR_CREATE_CONTEXT,
   COGL_WINSYS_ERROR_CREATE_ONSCREEN,
+  COGL_WINSYS_ERROR_MAKE_CURRENT,
+  COGL_WINSYS_ERROR_CREATE_GLES2_CONTEXT,
 } CoglWinsysError;
 
 typedef enum
@@ -154,6 +157,13 @@ typedef struct _CoglWinsysVtable
   (*texture_pixmap_x11_get_texture) (CoglTexturePixmapX11 *tex_pixmap);
 #endif
 
+  void *
+  (*create_gles2_context) (CoglContext *ctx, GError **error);
+
+  gboolean
+  (*make_current) (CoglGLES2Context *gles2_ctx,
+                   GError **error);
+
 } CoglWinsysVtable;
 
 gboolean
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 8403a46..cf963f2 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -18,7 +18,7 @@ common_ldadd = \
 	$(COGL_DEP_LIBS) \
 	$(top_builddir)/cogl/libcogl.la
 
-programs = cogl-hello cogl-info cogl-msaa
+programs = cogl-hello cogl-info cogl-msaa cogl-gles2-context
 examples_datadir = $(pkgdatadir)/examples-data
 examples_data_DATA =
 
@@ -51,6 +51,9 @@ cogland_SOURCES = cogland.c
 cogland_LDADD = $(common_ldadd)
 endif
 
+cogl_gles2_context_SOURCES = cogl-gles2-context.c
+cogl_gles2_context_LDADD = $(common_ldadd)
+
 if INSTALL_EXAMPLES
 bin_PROGRAMS = $(programs)
 else
diff --git a/examples/cogl-gles2-context.c b/examples/cogl-gles2-context.c
new file mode 100644
index 0000000..b3faed3
--- /dev/null
+++ b/examples/cogl-gles2-context.c
@@ -0,0 +1,92 @@
+#include <cogl/cogl.h>
+#include <glib.h>
+#include <stdio.h>
+
+CoglColor black;
+
+#define OFFSCREEN_WIDTH 100
+#define OFFSCREEN_HEIGHT 100
+
+int
+main (int argc, char **argv)
+{
+    CoglContext *ctx;
+    CoglOnscreen *onscreen;
+    CoglFramebuffer *fb;
+    GError *error = NULL;
+    CoglVertexP2C4 triangle_vertices[] = {
+        {0, 0.7, 0xff, 0x00, 0x00, 0x80},
+        {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
+        {0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
+    };
+    CoglPrimitive *triangle;
+    CoglGLES2Context *gles2_ctx;
+    CoglGLES2Vtable *vtable;
+    CoglTexture *offscreen_texture;
+    CoglFramebuffer *offscreen_framebuffer;
+
+    ctx = cogl_context_new (NULL, &error);
+    if (!ctx) {
+        fprintf (stderr, "Failed to create context: %s\n", error->message);
+        return 1;
+    }
+
+    onscreen = cogl_onscreen_new (ctx, 640, 480);
+    /* Eventually there will be an implicit allocate on first use so this
+     * will become optional... */
+    fb = COGL_FRAMEBUFFER (onscreen);
+    if (!cogl_framebuffer_allocate (fb, &error)) {
+        fprintf (stderr, "Failed to allocate framebuffer: %s\n", error->message);
+        return 1;
+    }
+
+    cogl_onscreen_show (onscreen);
+
+    /* Prepare offscreen framebuffer */
+    gles2_ctx = cogl_gles2_context_new (ctx, &error);
+    if (!gles2_ctx) {
+        fprintf (stderr, "Failed to create GLES2 context: %s\n", error->message);
+        return 1;
+    }
+
+    vtable = cogl_gles2_context_get_vtable (gles2_ctx);
+
+    offscreen_texture = cogl_texture_new_with_size (OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT,
+                                                    COGL_TEXTURE_NO_SLICING,
+                                                    COGL_PIXEL_FORMAT_ANY);
+
+    offscreen_framebuffer = cogl_offscreen_new_to_texture (offscreen_texture);
+
+    /* Clear offscreen framebuffer with green */
+    if (!cogl_framebuffer_push_gles2_context (offscreen_framebuffer,
+                                         gles2_ctx,
+                                         &error)) {
+        fprintf (stderr, "Failed to push GLES2 context: %s\n", error->message);
+        return 1;
+    }
+
+    vtable->glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+    vtable->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    cogl_framebuffer_pop_gles2_context (offscreen_framebuffer);
+
+    /* Prepare onscreen primitive */
+    triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
+                                        3, triangle_vertices);
+    for (;;) {
+        /* Draw scene with Cogl */
+        cogl_push_framebuffer (fb);
+        cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
+
+        cogl_set_source_color4f (0.0f, 0.0f, 0.0f, 1.0f);
+        cogl_primitive_draw (triangle);
+
+        cogl_set_source_texture (offscreen_texture);
+        cogl_rectangle_with_texture_coords (-0.5, -0.5, 0.5, 0.5,
+                                            0, 0, 1.0, 1.0);
+
+        cogl_framebuffer_swap_buffers (fb);
+    }
+
+    return 0;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]