2008-04-25 13:37:36 +00:00
|
|
|
/*
|
2009-04-27 14:48:12 +00:00
|
|
|
* Cogl
|
2008-04-25 13:37:36 +00:00
|
|
|
*
|
2009-04-27 14:48:12 +00:00
|
|
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
2008-04-25 13:37:36 +00:00
|
|
|
*
|
2013-01-24 16:28:09 +00:00
|
|
|
* Copyright (C) 2007,2008,2009,2010,2011,2013 Intel Corporation.
|
2008-04-25 13:37:36 +00:00
|
|
|
*
|
|
|
|
* 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
|
2011-02-25 00:31:41 +00:00
|
|
|
* License along with this library. If not, see
|
|
|
|
* <http://www.gnu.org/licenses/>.
|
2010-03-01 12:56:10 +00:00
|
|
|
*
|
|
|
|
*
|
2011-02-25 00:31:41 +00:00
|
|
|
* Authors:
|
|
|
|
* Robert Bragg <robert@linux.intel.com>
|
2008-04-25 13:37:36 +00:00
|
|
|
*/
|
|
|
|
|
Intial Re-layout of the Cogl source code and introduction of a Cogl Winsys
As part of an incremental process to have Cogl be a standalone project we
want to re-consider how we organise the Cogl source code.
Currently this is the structure I'm aiming for:
cogl/
cogl/
<put common source here>
winsys/
cogl-glx.c
cogl-wgl.c
driver/
gl/
gles/
os/ ?
utils/
cogl-fixed
cogl-matrix-stack?
cogl-journal?
cogl-primitives?
pango/
The new winsys component is a starting point for migrating window system
code (i.e. x11,glx,wgl,osx,egl etc) from Clutter to Cogl.
The utils/ and pango/ directories aren't added by this commit, but they are
noted because I plan to add them soon.
Overview of the planned structure:
* The winsys/ API is the API that binds OpenGL to a specific window system,
be that X11 or win32 etc. Example are glx, wgl and egl. Much of the logic
under clutter/{glx,osx,win32 etc} should migrate here.
* Note there is also the idea of a winsys-base that may represent a window
system for which there are multiple winsys APIs. An example of this is
x11, since glx and egl may both be used with x11. (currently only Clutter
has the idea of a winsys-base)
* The driver/ represents a specific varient of OpenGL. Currently we have "gl"
representing OpenGL 1.4-2.1 (mostly fixed function) and "gles" representing
GLES 1.1 (fixed funciton) and 2.0 (fully shader based)
* Everything under cogl/ should fundamentally be supporting access to the
GPU. Essentially Cogl's most basic requirement is to provide a nice GPU
Graphics API and drawing a line between this and the utility functionality
we add to support Clutter should help keep this lean and maintainable.
* Code under utils/ as suggested builds on cogl/ adding more convenient
APIs or mechanism to optimize special cases. Broadly speaking you can
compare cogl/ to OpenGL and utils/ to GLU.
* clutter/pango will be moved to clutter/cogl/pango
How some of the internal configure.ac/pkg-config terminology has changed:
backendextra -> CLUTTER_WINSYS_BASE # e.g. "x11"
backendextralib -> CLUTTER_WINSYS_BASE_LIB # e.g. "x11/libclutter-x11.la"
clutterbackend -> {CLUTTER,COGL}_WINSYS # e.g. "glx"
CLUTTER_FLAVOUR -> {CLUTTER,COGL}_WINSYS
clutterbackendlib -> CLUTTER_WINSYS_LIB
CLUTTER_COGL -> COGL_DRIVER # e.g. "gl"
Note: The CLUTTER_FLAVOUR and CLUTTER_COGL defines are kept for apps
As the first thing to take advantage of the new winsys component in Cogl;
cogl_get_proc_address() has been moved from cogl/{gl,gles}/cogl.c into
cogl/common/cogl.c and this common implementation first trys
_cogl_winsys_get_proc_address() but if that fails then it falls back to
gmodule.
2009-07-28 01:02:02 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
2008-04-25 13:37:36 +00:00
|
|
|
|
2013-04-28 01:42:24 +00:00
|
|
|
#include "cogl-i18n-private.h"
|
2011-10-13 21:34:30 +00:00
|
|
|
#include "cogl-util.h"
|
2011-05-24 22:15:37 +00:00
|
|
|
#include "cogl-winsys-egl-private.h"
|
2011-02-25 00:31:41 +00:00
|
|
|
#include "cogl-winsys-private.h"
|
|
|
|
#include "cogl-feature-private.h"
|
|
|
|
#include "cogl-context-private.h"
|
|
|
|
#include "cogl-framebuffer.h"
|
2011-10-13 20:31:04 +00:00
|
|
|
#include "cogl-onscreen-private.h"
|
2011-02-25 00:31:41 +00:00
|
|
|
#include "cogl-swap-chain-private.h"
|
|
|
|
#include "cogl-renderer-private.h"
|
|
|
|
#include "cogl-onscreen-template-private.h"
|
2012-03-06 03:21:30 +00:00
|
|
|
#include "cogl-gles2-context-private.h"
|
2012-08-31 18:28:27 +00:00
|
|
|
#include "cogl-error-private.h"
|
2011-05-24 22:15:37 +00:00
|
|
|
|
2011-02-25 00:31:41 +00:00
|
|
|
#include "cogl-private.h"
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
2011-11-07 17:16:13 +00:00
|
|
|
#include <stdio.h>
|
2011-02-25 00:31:41 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
2013-02-27 15:22:59 +00:00
|
|
|
|
|
|
|
#ifndef EGL_KHR_create_context
|
|
|
|
#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
|
|
|
|
#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
|
|
|
|
#define EGL_CONTEXT_FLAGS_KHR 0x30FC
|
|
|
|
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
|
|
|
|
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
|
|
|
|
#define EGL_OPENGL_ES3_BIT_KHR 0x0040
|
|
|
|
#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE
|
|
|
|
#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF
|
|
|
|
#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
|
|
|
|
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
|
|
|
|
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
|
|
|
|
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
|
|
|
|
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2011-08-22 22:55:57 +00:00
|
|
|
#define MAX_EGL_CONFIG_ATTRIBS 30
|
|
|
|
|
2011-02-25 00:31:41 +00:00
|
|
|
/* Define a set of arrays containing the functions required from GL
|
|
|
|
for each winsys feature */
|
|
|
|
#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \
|
2011-05-24 16:21:28 +00:00
|
|
|
egl_private_flags) \
|
2011-02-25 00:31:41 +00:00
|
|
|
static const CoglFeatureFunction \
|
|
|
|
cogl_egl_feature_ ## name ## _funcs[] = {
|
|
|
|
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args) \
|
|
|
|
{ G_STRINGIFY (name), G_STRUCT_OFFSET (CoglRendererEGL, pf_ ## name) },
|
|
|
|
#define COGL_WINSYS_FEATURE_END() \
|
|
|
|
{ NULL, 0 }, \
|
|
|
|
};
|
|
|
|
#include "cogl-winsys-egl-feature-functions.h"
|
|
|
|
|
|
|
|
/* Define an array of features */
|
|
|
|
#undef COGL_WINSYS_FEATURE_BEGIN
|
|
|
|
#define COGL_WINSYS_FEATURE_BEGIN(name, namespaces, extension_names, \
|
2011-05-24 16:21:28 +00:00
|
|
|
egl_private_flags) \
|
2011-07-06 17:59:20 +00:00
|
|
|
{ 255, 255, 0, namespaces, extension_names, \
|
2011-05-24 16:21:28 +00:00
|
|
|
0, egl_private_flags, \
|
|
|
|
0, \
|
2011-02-25 00:31:41 +00:00
|
|
|
cogl_egl_feature_ ## name ## _funcs },
|
|
|
|
#undef COGL_WINSYS_FEATURE_FUNCTION
|
|
|
|
#define COGL_WINSYS_FEATURE_FUNCTION(ret, name, args)
|
|
|
|
#undef COGL_WINSYS_FEATURE_END
|
|
|
|
#define COGL_WINSYS_FEATURE_END()
|
|
|
|
|
|
|
|
static const CoglFeatureData winsys_feature_data[] =
|
|
|
|
{
|
|
|
|
#include "cogl-winsys-egl-feature-functions.h"
|
|
|
|
};
|
|
|
|
|
2012-03-06 03:21:30 +00:00
|
|
|
static const char *
|
|
|
|
get_error_string (void)
|
|
|
|
{
|
|
|
|
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 ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-25 11:29:08 +00:00
|
|
|
static CoglFuncPtr
|
2011-07-27 11:30:02 +00:00
|
|
|
_cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer,
|
2012-06-20 11:42:31 +00:00
|
|
|
const char *name,
|
|
|
|
CoglBool in_core)
|
Intial Re-layout of the Cogl source code and introduction of a Cogl Winsys
As part of an incremental process to have Cogl be a standalone project we
want to re-consider how we organise the Cogl source code.
Currently this is the structure I'm aiming for:
cogl/
cogl/
<put common source here>
winsys/
cogl-glx.c
cogl-wgl.c
driver/
gl/
gles/
os/ ?
utils/
cogl-fixed
cogl-matrix-stack?
cogl-journal?
cogl-primitives?
pango/
The new winsys component is a starting point for migrating window system
code (i.e. x11,glx,wgl,osx,egl etc) from Clutter to Cogl.
The utils/ and pango/ directories aren't added by this commit, but they are
noted because I plan to add them soon.
Overview of the planned structure:
* The winsys/ API is the API that binds OpenGL to a specific window system,
be that X11 or win32 etc. Example are glx, wgl and egl. Much of the logic
under clutter/{glx,osx,win32 etc} should migrate here.
* Note there is also the idea of a winsys-base that may represent a window
system for which there are multiple winsys APIs. An example of this is
x11, since glx and egl may both be used with x11. (currently only Clutter
has the idea of a winsys-base)
* The driver/ represents a specific varient of OpenGL. Currently we have "gl"
representing OpenGL 1.4-2.1 (mostly fixed function) and "gles" representing
GLES 1.1 (fixed funciton) and 2.0 (fully shader based)
* Everything under cogl/ should fundamentally be supporting access to the
GPU. Essentially Cogl's most basic requirement is to provide a nice GPU
Graphics API and drawing a line between this and the utility functionality
we add to support Clutter should help keep this lean and maintainable.
* Code under utils/ as suggested builds on cogl/ adding more convenient
APIs or mechanism to optimize special cases. Broadly speaking you can
compare cogl/ to OpenGL and utils/ to GLU.
* clutter/pango will be moved to clutter/cogl/pango
How some of the internal configure.ac/pkg-config terminology has changed:
backendextra -> CLUTTER_WINSYS_BASE # e.g. "x11"
backendextralib -> CLUTTER_WINSYS_BASE_LIB # e.g. "x11/libclutter-x11.la"
clutterbackend -> {CLUTTER,COGL}_WINSYS # e.g. "glx"
CLUTTER_FLAVOUR -> {CLUTTER,COGL}_WINSYS
clutterbackendlib -> CLUTTER_WINSYS_LIB
CLUTTER_COGL -> COGL_DRIVER # e.g. "gl"
Note: The CLUTTER_FLAVOUR and CLUTTER_COGL defines are kept for apps
As the first thing to take advantage of the new winsys component in Cogl;
cogl_get_proc_address() has been moved from cogl/{gl,gles}/cogl.c into
cogl/common/cogl.c and this common implementation first trys
_cogl_winsys_get_proc_address() but if that fails then it falls back to
gmodule.
2009-07-28 01:02:02 +00:00
|
|
|
{
|
2012-06-20 11:42:31 +00:00
|
|
|
void *ptr = NULL;
|
2011-07-27 11:30:02 +00:00
|
|
|
|
2012-06-20 11:42:31 +00:00
|
|
|
if (!in_core)
|
|
|
|
ptr = eglGetProcAddress (name);
|
2011-07-27 11:30:02 +00:00
|
|
|
|
|
|
|
/* eglGetProcAddress doesn't support fetching core API so we need to
|
|
|
|
get that separately with GModule */
|
|
|
|
if (ptr == NULL)
|
|
|
|
g_module_symbol (renderer->libgl_module, name, &ptr);
|
|
|
|
|
|
|
|
return ptr;
|
Intial Re-layout of the Cogl source code and introduction of a Cogl Winsys
As part of an incremental process to have Cogl be a standalone project we
want to re-consider how we organise the Cogl source code.
Currently this is the structure I'm aiming for:
cogl/
cogl/
<put common source here>
winsys/
cogl-glx.c
cogl-wgl.c
driver/
gl/
gles/
os/ ?
utils/
cogl-fixed
cogl-matrix-stack?
cogl-journal?
cogl-primitives?
pango/
The new winsys component is a starting point for migrating window system
code (i.e. x11,glx,wgl,osx,egl etc) from Clutter to Cogl.
The utils/ and pango/ directories aren't added by this commit, but they are
noted because I plan to add them soon.
Overview of the planned structure:
* The winsys/ API is the API that binds OpenGL to a specific window system,
be that X11 or win32 etc. Example are glx, wgl and egl. Much of the logic
under clutter/{glx,osx,win32 etc} should migrate here.
* Note there is also the idea of a winsys-base that may represent a window
system for which there are multiple winsys APIs. An example of this is
x11, since glx and egl may both be used with x11. (currently only Clutter
has the idea of a winsys-base)
* The driver/ represents a specific varient of OpenGL. Currently we have "gl"
representing OpenGL 1.4-2.1 (mostly fixed function) and "gles" representing
GLES 1.1 (fixed funciton) and 2.0 (fully shader based)
* Everything under cogl/ should fundamentally be supporting access to the
GPU. Essentially Cogl's most basic requirement is to provide a nice GPU
Graphics API and drawing a line between this and the utility functionality
we add to support Clutter should help keep this lean and maintainable.
* Code under utils/ as suggested builds on cogl/ adding more convenient
APIs or mechanism to optimize special cases. Broadly speaking you can
compare cogl/ to OpenGL and utils/ to GLU.
* clutter/pango will be moved to clutter/cogl/pango
How some of the internal configure.ac/pkg-config terminology has changed:
backendextra -> CLUTTER_WINSYS_BASE # e.g. "x11"
backendextralib -> CLUTTER_WINSYS_BASE_LIB # e.g. "x11/libclutter-x11.la"
clutterbackend -> {CLUTTER,COGL}_WINSYS # e.g. "glx"
CLUTTER_FLAVOUR -> {CLUTTER,COGL}_WINSYS
clutterbackendlib -> CLUTTER_WINSYS_LIB
CLUTTER_COGL -> COGL_DRIVER # e.g. "gl"
Note: The CLUTTER_FLAVOUR and CLUTTER_COGL defines are kept for apps
As the first thing to take advantage of the new winsys component in Cogl;
cogl_get_proc_address() has been moved from cogl/{gl,gles}/cogl.c into
cogl/common/cogl.c and this common implementation first trys
_cogl_winsys_get_proc_address() but if that fails then it falls back to
gmodule.
2009-07-28 01:02:02 +00:00
|
|
|
}
|
2008-04-25 13:37:36 +00:00
|
|
|
|
2011-02-25 11:29:08 +00:00
|
|
|
static void
|
|
|
|
_cogl_winsys_renderer_disconnect (CoglRenderer *renderer)
|
|
|
|
{
|
2011-12-13 13:09:34 +00:00
|
|
|
/* This function must be overridden by a platform winsys */
|
|
|
|
g_assert_not_reached ();
|
2011-02-25 11:29:08 +00:00
|
|
|
}
|
|
|
|
|
2011-05-24 16:21:28 +00:00
|
|
|
/* Updates all the function pointers */
|
|
|
|
static void
|
|
|
|
check_egl_extensions (CoglRenderer *renderer)
|
|
|
|
{
|
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
|
|
|
const char *egl_extensions;
|
2012-09-26 19:32:36 +00:00
|
|
|
char **split_extensions;
|
2011-05-24 16:21:28 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
egl_extensions = eglQueryString (egl_renderer->edpy, EGL_EXTENSIONS);
|
2012-09-26 19:32:36 +00:00
|
|
|
split_extensions = g_strsplit (egl_extensions, " ", 0 /* max_tokens */);
|
2011-05-24 16:21:28 +00:00
|
|
|
|
|
|
|
COGL_NOTE (WINSYS, " EGL Extensions: %s", egl_extensions);
|
|
|
|
|
|
|
|
egl_renderer->private_features = 0;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (winsys_feature_data); i++)
|
2011-07-27 11:30:02 +00:00
|
|
|
if (_cogl_feature_check (renderer,
|
2011-07-07 19:44:56 +00:00
|
|
|
"EGL", winsys_feature_data + i, 0, 0,
|
|
|
|
COGL_DRIVER_GL, /* the driver isn't used */
|
2012-09-26 19:32:36 +00:00
|
|
|
split_extensions,
|
2011-05-24 16:21:28 +00:00
|
|
|
egl_renderer))
|
|
|
|
{
|
|
|
|
egl_renderer->private_features |=
|
2011-07-05 13:03:48 +00:00
|
|
|
winsys_feature_data[i].feature_flags_private;
|
2011-05-24 16:21:28 +00:00
|
|
|
}
|
2012-09-26 19:32:36 +00:00
|
|
|
|
|
|
|
g_strfreev (split_extensions);
|
2011-05-24 16:21:28 +00:00
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
CoglBool
|
2011-12-09 16:10:01 +00:00
|
|
|
_cogl_winsys_egl_renderer_connect_common (CoglRenderer *renderer,
|
2012-08-31 18:28:27 +00:00
|
|
|
CoglError **error)
|
2011-12-09 16:10:01 +00:00
|
|
|
{
|
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
|
|
|
|
|
|
|
if (!eglInitialize (egl_renderer->edpy,
|
|
|
|
&egl_renderer->egl_version_major,
|
|
|
|
&egl_renderer->egl_version_minor))
|
|
|
|
{
|
2012-08-31 18:28:27 +00:00
|
|
|
_cogl_set_error (error, COGL_WINSYS_ERROR,
|
2011-12-09 16:10:01 +00:00
|
|
|
COGL_WINSYS_ERROR_INIT,
|
|
|
|
"Couldn't initialize EGL");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
check_egl_extensions (renderer);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2011-02-25 00:31:41 +00:00
|
|
|
_cogl_winsys_renderer_connect (CoglRenderer *renderer,
|
2012-08-31 18:28:27 +00:00
|
|
|
CoglError **error)
|
2011-02-25 00:31:41 +00:00
|
|
|
{
|
2011-12-13 13:09:34 +00:00
|
|
|
/* This function must be overridden by a platform winsys */
|
|
|
|
g_assert_not_reached ();
|
2011-02-25 00:31:41 +00:00
|
|
|
}
|
|
|
|
|
2011-08-22 22:55:57 +00:00
|
|
|
static void
|
|
|
|
egl_attributes_from_framebuffer_config (CoglDisplay *display,
|
|
|
|
CoglFramebufferConfig *config,
|
|
|
|
EGLint *attributes)
|
|
|
|
{
|
2011-12-08 17:38:19 +00:00
|
|
|
CoglRenderer *renderer = display->renderer;
|
2011-12-13 11:42:42 +00:00
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
2011-08-22 22:55:57 +00:00
|
|
|
int i = 0;
|
|
|
|
|
2011-12-13 11:42:42 +00:00
|
|
|
/* Let the platform add attributes first */
|
2011-12-13 13:09:34 +00:00
|
|
|
if (egl_renderer->platform_vtable->add_config_attributes)
|
2011-12-13 11:42:42 +00:00
|
|
|
i = egl_renderer->platform_vtable->add_config_attributes (display,
|
|
|
|
config,
|
|
|
|
attributes);
|
|
|
|
|
2012-09-28 10:08:16 +00:00
|
|
|
if (config->need_stencil)
|
|
|
|
{
|
|
|
|
attributes[i++] = EGL_STENCIL_SIZE;
|
|
|
|
attributes[i++] = 2;
|
|
|
|
}
|
2011-08-22 22:55:57 +00:00
|
|
|
|
|
|
|
attributes[i++] = EGL_RED_SIZE;
|
|
|
|
attributes[i++] = 1;
|
|
|
|
attributes[i++] = EGL_GREEN_SIZE;
|
|
|
|
attributes[i++] = 1;
|
|
|
|
attributes[i++] = EGL_BLUE_SIZE;
|
|
|
|
attributes[i++] = 1;
|
|
|
|
|
|
|
|
attributes[i++] = EGL_ALPHA_SIZE;
|
|
|
|
attributes[i++] = config->swap_chain->has_alpha ? 1 : EGL_DONT_CARE;
|
|
|
|
|
|
|
|
attributes[i++] = EGL_DEPTH_SIZE;
|
|
|
|
attributes[i++] = 1;
|
|
|
|
|
|
|
|
attributes[i++] = EGL_BUFFER_SIZE;
|
|
|
|
attributes[i++] = EGL_DONT_CARE;
|
|
|
|
|
|
|
|
attributes[i++] = EGL_RENDERABLE_TYPE;
|
2012-09-26 19:32:36 +00:00
|
|
|
attributes[i++] = ((renderer->driver == COGL_DRIVER_GL ||
|
|
|
|
renderer->driver == COGL_DRIVER_GL3) ?
|
|
|
|
EGL_OPENGL_BIT :
|
|
|
|
renderer->driver == COGL_DRIVER_GLES1 ?
|
|
|
|
EGL_OPENGL_ES_BIT :
|
|
|
|
EGL_OPENGL_ES2_BIT);
|
2011-08-22 22:55:57 +00:00
|
|
|
|
|
|
|
attributes[i++] = EGL_SURFACE_TYPE;
|
|
|
|
attributes[i++] = EGL_WINDOW_BIT;
|
|
|
|
|
2011-08-21 20:27:13 +00:00
|
|
|
if (config->samples_per_pixel)
|
|
|
|
{
|
|
|
|
attributes[i++] = EGL_SAMPLE_BUFFERS;
|
|
|
|
attributes[i++] = 1;
|
|
|
|
attributes[i++] = EGL_SAMPLES;
|
|
|
|
attributes[i++] = config->samples_per_pixel;
|
|
|
|
}
|
|
|
|
|
2011-08-22 22:55:57 +00:00
|
|
|
attributes[i++] = EGL_NONE;
|
|
|
|
|
|
|
|
g_assert (i < MAX_EGL_CONFIG_ATTRIBS);
|
|
|
|
}
|
|
|
|
|
2012-09-28 10:08:16 +00:00
|
|
|
EGLBoolean
|
|
|
|
_cogl_winsys_egl_make_current (CoglDisplay *display,
|
|
|
|
EGLSurface draw,
|
|
|
|
EGLSurface read,
|
|
|
|
EGLContext context)
|
|
|
|
{
|
|
|
|
CoglDisplayEGL *egl_display = display->winsys;
|
|
|
|
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
|
|
|
EGLBoolean ret;
|
|
|
|
|
|
|
|
if (egl_display->current_draw_surface == draw &&
|
|
|
|
egl_display->current_read_surface == read &&
|
|
|
|
egl_display->current_context == context)
|
|
|
|
return EGL_TRUE;
|
|
|
|
|
|
|
|
ret = eglMakeCurrent (egl_renderer->edpy,
|
|
|
|
draw,
|
|
|
|
read,
|
|
|
|
context);
|
|
|
|
|
|
|
|
egl_display->current_draw_surface = draw;
|
|
|
|
egl_display->current_read_surface = read;
|
|
|
|
egl_display->current_context = context;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
cleanup_context (CoglDisplay *display)
|
|
|
|
{
|
|
|
|
CoglRenderer *renderer = display->renderer;
|
|
|
|
CoglDisplayEGL *egl_display = display->winsys;
|
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
|
|
|
|
|
|
|
if (egl_display->egl_context != EGL_NO_CONTEXT)
|
|
|
|
{
|
|
|
|
_cogl_winsys_egl_make_current (display,
|
|
|
|
EGL_NO_SURFACE, EGL_NO_SURFACE,
|
|
|
|
EGL_NO_CONTEXT);
|
|
|
|
eglDestroyContext (egl_renderer->edpy, egl_display->egl_context);
|
|
|
|
egl_display->egl_context = EGL_NO_CONTEXT;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (egl_renderer->platform_vtable->cleanup_context)
|
|
|
|
egl_renderer->platform_vtable->cleanup_context (display);
|
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2011-02-25 00:31:41 +00:00
|
|
|
try_create_context (CoglDisplay *display,
|
2012-08-31 18:28:27 +00:00
|
|
|
CoglError **error)
|
2011-02-25 00:31:41 +00:00
|
|
|
{
|
2011-12-08 17:38:19 +00:00
|
|
|
CoglRenderer *renderer = display->renderer;
|
2011-02-25 00:31:41 +00:00
|
|
|
CoglDisplayEGL *egl_display = display->winsys;
|
2011-12-08 17:38:19 +00:00
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
2011-02-25 00:31:41 +00:00
|
|
|
EGLDisplay edpy;
|
|
|
|
EGLConfig config;
|
|
|
|
EGLint config_count = 0;
|
|
|
|
EGLBoolean status;
|
2012-09-26 19:32:36 +00:00
|
|
|
EGLint attribs[9];
|
2011-11-07 17:16:13 +00:00
|
|
|
EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS];
|
2011-02-25 00:31:41 +00:00
|
|
|
const char *error_message;
|
|
|
|
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context == NULL, TRUE);
|
2011-07-07 19:44:56 +00:00
|
|
|
|
2012-09-26 19:32:36 +00:00
|
|
|
if (renderer->driver == COGL_DRIVER_GL ||
|
|
|
|
renderer->driver == COGL_DRIVER_GL3)
|
2011-07-07 19:44:56 +00:00
|
|
|
eglBindAPI (EGL_OPENGL_API);
|
2011-02-25 00:31:41 +00:00
|
|
|
|
2011-12-09 16:10:01 +00:00
|
|
|
egl_attributes_from_framebuffer_config (display,
|
|
|
|
&display->onscreen_template->config,
|
|
|
|
cfg_attribs);
|
2011-08-22 22:55:57 +00:00
|
|
|
|
2011-12-09 16:10:01 +00:00
|
|
|
edpy = egl_renderer->edpy;
|
2011-02-25 00:31:41 +00:00
|
|
|
|
2011-12-09 16:10:01 +00:00
|
|
|
status = eglChooseConfig (edpy,
|
|
|
|
cfg_attribs,
|
|
|
|
&config, 1,
|
|
|
|
&config_count);
|
|
|
|
if (status != EGL_TRUE || config_count == 0)
|
|
|
|
{
|
|
|
|
error_message = "Unable to find a usable EGL configuration";
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
egl_display->egl_config = config;
|
|
|
|
|
2012-09-26 19:32:36 +00:00
|
|
|
if (display->renderer->driver == COGL_DRIVER_GL3)
|
|
|
|
{
|
|
|
|
if (!(egl_renderer->private_features &
|
|
|
|
COGL_EGL_WINSYS_FEATURE_CREATE_CONTEXT))
|
|
|
|
{
|
|
|
|
error_message = "Driver does not support GL 3 contexts";
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Try to get a core profile 3.1 context with no deprecated features */
|
|
|
|
attribs[0] = EGL_CONTEXT_MAJOR_VERSION_KHR;
|
|
|
|
attribs[1] = 3;
|
|
|
|
attribs[2] = EGL_CONTEXT_MINOR_VERSION_KHR;
|
|
|
|
attribs[3] = 1;
|
|
|
|
attribs[4] = EGL_CONTEXT_FLAGS_KHR;
|
|
|
|
attribs[5] = EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
|
|
|
attribs[6] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
|
|
|
|
attribs[7] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
|
|
|
|
attribs[8] = EGL_NONE;
|
|
|
|
}
|
|
|
|
else if (display->renderer->driver == COGL_DRIVER_GLES2)
|
|
|
|
{
|
|
|
|
attribs[0] = EGL_CONTEXT_CLIENT_VERSION;
|
|
|
|
attribs[1] = 2;
|
|
|
|
attribs[2] = EGL_NONE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
attribs[0] = EGL_NONE;
|
|
|
|
|
2011-12-09 16:10:01 +00:00
|
|
|
egl_display->egl_context = eglCreateContext (edpy,
|
|
|
|
config,
|
|
|
|
EGL_NO_CONTEXT,
|
|
|
|
attribs);
|
2012-09-26 19:32:36 +00:00
|
|
|
|
2011-12-09 16:10:01 +00:00
|
|
|
if (egl_display->egl_context == EGL_NO_CONTEXT)
|
|
|
|
{
|
|
|
|
error_message = "Unable to create a suitable EGL context";
|
|
|
|
goto fail;
|
2011-02-25 00:31:41 +00:00
|
|
|
}
|
|
|
|
|
2011-12-13 13:09:34 +00:00
|
|
|
if (egl_renderer->platform_vtable->context_created &&
|
|
|
|
!egl_renderer->platform_vtable->context_created (display, error))
|
|
|
|
return FALSE;
|
2011-02-25 00:31:41 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
fail:
|
2012-08-31 18:28:27 +00:00
|
|
|
_cogl_set_error (error, COGL_WINSYS_ERROR,
|
2011-08-22 22:55:57 +00:00
|
|
|
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
|
|
|
"%s", error_message);
|
2011-02-25 00:31:41 +00:00
|
|
|
|
2012-09-28 10:08:16 +00:00
|
|
|
cleanup_context (display);
|
2011-02-25 00:31:41 +00:00
|
|
|
|
2012-09-28 10:08:16 +00:00
|
|
|
return FALSE;
|
2011-02-25 00:31:41 +00:00
|
|
|
}
|
|
|
|
|
2011-02-25 11:29:08 +00:00
|
|
|
static void
|
|
|
|
_cogl_winsys_display_destroy (CoglDisplay *display)
|
|
|
|
{
|
2011-12-09 16:10:01 +00:00
|
|
|
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
2011-02-25 11:29:08 +00:00
|
|
|
CoglDisplayEGL *egl_display = display->winsys;
|
|
|
|
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_IF_FAIL (egl_display != NULL);
|
2011-02-25 11:29:08 +00:00
|
|
|
|
|
|
|
cleanup_context (display);
|
|
|
|
|
2011-12-13 13:09:34 +00:00
|
|
|
if (egl_renderer->platform_vtable->display_destroy)
|
2011-12-09 16:10:01 +00:00
|
|
|
egl_renderer->platform_vtable->display_destroy (display);
|
|
|
|
|
2011-02-25 11:29:08 +00:00
|
|
|
g_slice_free (CoglDisplayEGL, display->winsys);
|
|
|
|
display->winsys = NULL;
|
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2011-02-25 00:31:41 +00:00
|
|
|
_cogl_winsys_display_setup (CoglDisplay *display,
|
2012-08-31 18:28:27 +00:00
|
|
|
CoglError **error)
|
2011-02-25 00:31:41 +00:00
|
|
|
{
|
|
|
|
CoglDisplayEGL *egl_display;
|
2011-12-08 17:38:19 +00:00
|
|
|
CoglRenderer *renderer = display->renderer;
|
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
2011-02-25 00:31:41 +00:00
|
|
|
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_VAL_IF_FAIL (display->winsys == NULL, FALSE);
|
2011-02-25 00:31:41 +00:00
|
|
|
|
|
|
|
egl_display = g_slice_new0 (CoglDisplayEGL);
|
|
|
|
display->winsys = egl_display;
|
|
|
|
|
2011-05-25 00:37:56 +00:00
|
|
|
#ifdef COGL_HAS_WAYLAND_EGL_SERVER_SUPPORT
|
2011-12-12 17:31:27 +00:00
|
|
|
if (display->wayland_compositor_display)
|
2011-05-25 00:37:56 +00:00
|
|
|
{
|
|
|
|
struct wl_display *wayland_display = display->wayland_compositor_display;
|
2011-12-12 17:31:27 +00:00
|
|
|
CoglRendererEGL *egl_renderer = display->renderer->winsys;
|
|
|
|
|
2013-07-23 15:10:57 +00:00
|
|
|
if (egl_renderer->pf_eglBindWaylandDisplay)
|
|
|
|
egl_renderer->pf_eglBindWaylandDisplay (egl_renderer->edpy,
|
|
|
|
wayland_display);
|
2011-05-25 00:37:56 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-12-13 13:09:34 +00:00
|
|
|
if (egl_renderer->platform_vtable->display_setup &&
|
2011-12-09 16:10:01 +00:00
|
|
|
!egl_renderer->platform_vtable->display_setup (display, error))
|
2011-11-07 17:16:13 +00:00
|
|
|
goto error;
|
|
|
|
|
2012-09-28 10:08:16 +00:00
|
|
|
if (!try_create_context (display, error))
|
2011-02-25 00:31:41 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
egl_display->found_egl_config = TRUE;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
error:
|
|
|
|
_cogl_winsys_display_destroy (display);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2012-08-31 18:28:27 +00:00
|
|
|
_cogl_winsys_context_init (CoglContext *context, CoglError **error)
|
2011-02-25 00:31:41 +00:00
|
|
|
{
|
2011-12-12 15:59:35 +00:00
|
|
|
CoglRenderer *renderer = context->display->renderer;
|
|
|
|
CoglDisplayEGL *egl_display = context->display->winsys;
|
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
|
|
|
|
2011-02-25 00:31:41 +00:00
|
|
|
context->winsys = g_new0 (CoglContextEGL, 1);
|
|
|
|
|
2011-12-12 15:59:35 +00:00
|
|
|
_COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE);
|
|
|
|
|
|
|
|
memset (context->winsys_features, 0, sizeof (context->winsys_features));
|
|
|
|
|
|
|
|
check_egl_extensions (renderer);
|
|
|
|
|
|
|
|
if (!_cogl_context_update_features (context, error))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_SWAP_REGION)
|
|
|
|
{
|
|
|
|
COGL_FLAGS_SET (context->winsys_features,
|
|
|
|
COGL_WINSYS_FEATURE_SWAP_REGION, TRUE);
|
|
|
|
COGL_FLAGS_SET (context->winsys_features,
|
|
|
|
COGL_WINSYS_FEATURE_SWAP_REGION_THROTTLE, TRUE);
|
|
|
|
}
|
|
|
|
|
2013-01-11 01:13:34 +00:00
|
|
|
if ((egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_FENCE_SYNC) &&
|
2013-11-25 16:11:36 +00:00
|
|
|
_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_OES_EGL_SYNC))
|
2013-01-11 01:13:34 +00:00
|
|
|
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_FENCE, TRUE);
|
|
|
|
|
2012-03-06 03:21:30 +00:00
|
|
|
/* NB: We currently only support creating standalone GLES2 contexts
|
|
|
|
* for offscreen rendering and so we need a dummy (non-visible)
|
|
|
|
* surface to be able to bind those contexts */
|
2012-10-01 10:30:50 +00:00
|
|
|
if (egl_display->dummy_surface != EGL_NO_SURFACE &&
|
|
|
|
context->driver == COGL_DRIVER_GLES2)
|
2012-03-06 03:21:30 +00:00
|
|
|
COGL_FLAGS_SET (context->features,
|
|
|
|
COGL_FEATURE_ID_GLES2_CONTEXT, TRUE);
|
|
|
|
|
2011-12-13 13:09:34 +00:00
|
|
|
if (egl_renderer->platform_vtable->context_init &&
|
2011-12-12 15:59:35 +00:00
|
|
|
!egl_renderer->platform_vtable->context_init (context, error))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return TRUE;
|
2011-02-25 00:31:41 +00:00
|
|
|
}
|
|
|
|
|
2011-02-25 11:29:08 +00:00
|
|
|
static void
|
2011-02-25 00:31:41 +00:00
|
|
|
_cogl_winsys_context_deinit (CoglContext *context)
|
|
|
|
{
|
2011-12-12 15:59:35 +00:00
|
|
|
CoglRenderer *renderer = context->display->renderer;
|
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
|
|
|
|
2011-12-13 13:09:34 +00:00
|
|
|
if (egl_renderer->platform_vtable->context_deinit)
|
2011-12-12 15:59:35 +00:00
|
|
|
egl_renderer->platform_vtable->context_deinit (context);
|
|
|
|
|
2011-02-25 00:31:41 +00:00
|
|
|
g_free (context->winsys);
|
|
|
|
}
|
|
|
|
|
2012-03-06 03:21:30 +00:00
|
|
|
typedef struct _CoglGLES2ContextEGL
|
|
|
|
{
|
|
|
|
EGLContext egl_context;
|
|
|
|
EGLSurface dummy_surface;
|
|
|
|
} CoglGLES2ContextEGL;
|
|
|
|
|
|
|
|
static void *
|
2012-08-31 18:28:27 +00:00
|
|
|
_cogl_winsys_context_create_gles2_context (CoglContext *ctx, CoglError **error)
|
2012-03-06 03:21:30 +00:00
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
2012-08-31 18:28:27 +00:00
|
|
|
_cogl_set_error (error, COGL_WINSYS_ERROR,
|
2012-03-06 03:21:30 +00:00
|
|
|
COGL_WINSYS_ERROR_CREATE_GLES2_CONTEXT,
|
|
|
|
"%s", get_error_string ());
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (void *)egl_context;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_winsys_destroy_gles2_context (CoglGLES2Context *gles2_ctx)
|
|
|
|
{
|
|
|
|
CoglContext *context = gles2_ctx->context;
|
|
|
|
CoglDisplay *display = context->display;
|
|
|
|
CoglDisplayEGL *egl_display = display->winsys;
|
|
|
|
CoglRenderer *renderer = display->renderer;
|
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
|
|
|
EGLContext egl_context = gles2_ctx->winsys;
|
|
|
|
|
|
|
|
_COGL_RETURN_IF_FAIL (egl_display->current_context != egl_context);
|
|
|
|
|
|
|
|
eglDestroyContext (egl_renderer->edpy, egl_context);
|
|
|
|
}
|
|
|
|
|
Switch use of primitive glib types to c99 equivalents
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
2012-04-16 20:56:40 +00:00
|
|
|
static CoglBool
|
2011-02-25 00:31:41 +00:00
|
|
|
_cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
|
2012-08-31 18:28:27 +00:00
|
|
|
CoglError **error)
|
2011-02-25 00:31:41 +00:00
|
|
|
{
|
|
|
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
|
|
|
CoglContext *context = framebuffer->context;
|
|
|
|
CoglDisplay *display = context->display;
|
|
|
|
CoglDisplayEGL *egl_display = display->winsys;
|
2011-12-08 17:38:19 +00:00
|
|
|
CoglRenderer *renderer = display->renderer;
|
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
2011-08-22 22:55:57 +00:00
|
|
|
EGLint attributes[MAX_EGL_CONFIG_ATTRIBS];
|
|
|
|
EGLConfig egl_config;
|
|
|
|
EGLint config_count = 0;
|
|
|
|
EGLBoolean status;
|
2011-02-25 00:31:41 +00:00
|
|
|
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE);
|
2011-02-25 00:31:41 +00:00
|
|
|
|
2011-12-09 16:10:01 +00:00
|
|
|
egl_attributes_from_framebuffer_config (display,
|
|
|
|
&framebuffer->config,
|
|
|
|
attributes);
|
|
|
|
|
|
|
|
status = eglChooseConfig (egl_renderer->edpy,
|
|
|
|
attributes,
|
|
|
|
&egl_config, 1,
|
|
|
|
&config_count);
|
|
|
|
if (status != EGL_TRUE || config_count == 0)
|
2011-08-22 22:55:57 +00:00
|
|
|
{
|
2012-08-31 18:28:27 +00:00
|
|
|
_cogl_set_error (error, COGL_WINSYS_ERROR,
|
2011-12-09 16:10:01 +00:00
|
|
|
COGL_WINSYS_ERROR_CREATE_ONSCREEN,
|
|
|
|
"Failed to find a suitable EGL configuration");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2011-12-08 17:38:19 +00:00
|
|
|
|
2011-12-09 16:10:01 +00:00
|
|
|
/* Update the real number of samples_per_pixel now that we have
|
|
|
|
* found an egl_config... */
|
|
|
|
if (framebuffer->config.samples_per_pixel)
|
|
|
|
{
|
|
|
|
EGLint samples;
|
|
|
|
status = eglGetConfigAttrib (egl_renderer->edpy,
|
|
|
|
egl_config,
|
|
|
|
EGL_SAMPLES, &samples);
|
|
|
|
g_return_val_if_fail (status == EGL_TRUE, TRUE);
|
|
|
|
framebuffer->samples_per_pixel = samples;
|
2011-08-22 22:55:57 +00:00
|
|
|
}
|
|
|
|
|
2011-12-08 17:38:19 +00:00
|
|
|
onscreen->winsys = g_slice_new0 (CoglOnscreenEGL);
|
2011-02-25 00:31:41 +00:00
|
|
|
|
2011-12-13 13:09:34 +00:00
|
|
|
if (egl_renderer->platform_vtable->onscreen_init &&
|
|
|
|
!egl_renderer->platform_vtable->onscreen_init (onscreen,
|
|
|
|
egl_config,
|
|
|
|
error))
|
2011-02-25 00:31:41 +00:00
|
|
|
{
|
2011-12-13 13:09:34 +00:00
|
|
|
g_slice_free (CoglOnscreenEGL, onscreen->winsys);
|
|
|
|
return FALSE;
|
2011-12-08 17:38:19 +00:00
|
|
|
}
|
|
|
|
|
2011-02-25 00:31:41 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2011-02-25 11:29:08 +00:00
|
|
|
static void
|
2011-02-25 00:31:41 +00:00
|
|
|
_cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
|
|
|
|
{
|
|
|
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
|
|
|
CoglContext *context = framebuffer->context;
|
2013-01-24 16:28:09 +00:00
|
|
|
CoglDisplayEGL *egl_display = context->display->winsys;
|
2011-12-08 17:38:19 +00:00
|
|
|
CoglRenderer *renderer = context->display->renderer;
|
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
2011-02-25 00:31:41 +00:00
|
|
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
|
|
|
|
2011-05-10 19:23:39 +00:00
|
|
|
/* If we never successfully allocated then there's nothing to do */
|
|
|
|
if (egl_onscreen == NULL)
|
|
|
|
return;
|
2013-01-24 16:28:09 +00:00
|
|
|
|
2011-12-09 16:10:01 +00:00
|
|
|
if (egl_onscreen->egl_surface != EGL_NO_SURFACE)
|
2011-02-25 00:31:41 +00:00
|
|
|
{
|
2013-01-24 16:28:09 +00:00
|
|
|
/* Cogl always needs a valid context bound to something so if we
|
|
|
|
* are destroying the onscreen that is currently bound we'll
|
|
|
|
* switch back to the dummy drawable. */
|
|
|
|
if (egl_display->dummy_surface != EGL_NO_SURFACE &&
|
|
|
|
(egl_display->current_draw_surface == egl_onscreen->egl_surface ||
|
|
|
|
egl_display->current_read_surface == egl_onscreen->egl_surface))
|
|
|
|
{
|
|
|
|
_cogl_winsys_egl_make_current (context->display,
|
|
|
|
egl_display->dummy_surface,
|
|
|
|
egl_display->dummy_surface,
|
|
|
|
egl_display->current_context);
|
|
|
|
}
|
|
|
|
|
2011-02-25 00:31:41 +00:00
|
|
|
if (eglDestroySurface (egl_renderer->edpy, egl_onscreen->egl_surface)
|
|
|
|
== EGL_FALSE)
|
|
|
|
g_warning ("Failed to destroy EGL surface");
|
|
|
|
egl_onscreen->egl_surface = EGL_NO_SURFACE;
|
|
|
|
}
|
|
|
|
|
2011-12-13 13:09:34 +00:00
|
|
|
if (egl_renderer->platform_vtable->onscreen_deinit)
|
2011-12-12 15:59:35 +00:00
|
|
|
egl_renderer->platform_vtable->onscreen_deinit (onscreen);
|
2011-02-25 00:31:41 +00:00
|
|
|
|
2011-05-10 19:23:39 +00:00
|
|
|
g_slice_free (CoglOnscreenEGL, onscreen->winsys);
|
|
|
|
onscreen->winsys = NULL;
|
2011-02-25 00:31:41 +00:00
|
|
|
}
|
|
|
|
|
2012-03-06 03:21:30 +00:00
|
|
|
static CoglBool
|
2012-10-01 11:05:06 +00:00
|
|
|
bind_onscreen_with_context (CoglOnscreen *onscreen,
|
|
|
|
EGLContext egl_context)
|
2011-02-25 00:31:41 +00:00
|
|
|
{
|
2012-01-16 11:26:45 +00:00
|
|
|
CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
|
|
|
|
CoglContext *context = fb->context;
|
2011-12-12 15:59:35 +00:00
|
|
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
2011-11-07 17:16:13 +00:00
|
|
|
|
2012-03-06 03:21:30 +00:00
|
|
|
CoglBool status = _cogl_winsys_egl_make_current (context->display,
|
|
|
|
egl_onscreen->egl_surface,
|
|
|
|
egl_onscreen->egl_surface,
|
2012-10-01 11:05:06 +00:00
|
|
|
egl_context);
|
2012-03-06 03:21:30 +00:00
|
|
|
if (status)
|
|
|
|
{
|
|
|
|
CoglRenderer *renderer = context->display->renderer;
|
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
|
|
|
|
|
|
|
if (fb->config.swap_throttled)
|
|
|
|
eglSwapInterval (egl_renderer->edpy, 1);
|
|
|
|
else
|
|
|
|
eglSwapInterval (egl_renderer->edpy, 0);
|
|
|
|
}
|
2011-12-12 15:59:35 +00:00
|
|
|
|
2012-03-06 03:21:30 +00:00
|
|
|
return status;
|
|
|
|
}
|
2011-12-12 15:59:35 +00:00
|
|
|
|
2012-10-01 11:05:06 +00:00
|
|
|
static CoglBool
|
|
|
|
bind_onscreen (CoglOnscreen *onscreen)
|
|
|
|
{
|
|
|
|
CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
|
|
|
|
CoglContext *context = fb->context;
|
|
|
|
CoglDisplayEGL *egl_display = context->display->winsys;
|
|
|
|
|
|
|
|
return bind_onscreen_with_context (onscreen, egl_display->egl_context);
|
|
|
|
}
|
|
|
|
|
2012-03-06 03:21:30 +00:00
|
|
|
static void
|
|
|
|
_cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
|
|
|
|
{
|
|
|
|
bind_onscreen (onscreen);
|
2011-02-25 00:31:41 +00:00
|
|
|
}
|
|
|
|
|
2013-01-22 21:21:33 +00:00
|
|
|
#ifndef EGL_BUFFER_AGE_EXT
|
|
|
|
#define EGL_BUFFER_AGE_EXT 0x313D
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int
|
|
|
|
_cogl_winsys_onscreen_get_buffer_age (CoglOnscreen *onscreen)
|
|
|
|
{
|
|
|
|
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
|
|
|
CoglRenderer *renderer = context->display->renderer;
|
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
|
|
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
|
|
|
EGLSurface surface = egl_onscreen->egl_surface;
|
|
|
|
int age;
|
|
|
|
|
|
|
|
if (!(egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_BUFFER_AGE))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
eglQuerySurface (egl_renderer->edpy, surface, EGL_BUFFER_AGE_EXT, &age);
|
|
|
|
|
|
|
|
return age;
|
|
|
|
}
|
|
|
|
|
2011-02-25 11:29:08 +00:00
|
|
|
static void
|
2011-02-25 00:31:41 +00:00
|
|
|
_cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
|
2011-07-22 11:23:40 +00:00
|
|
|
const int *user_rectangles,
|
2011-02-25 00:31:41 +00:00
|
|
|
int n_rectangles)
|
|
|
|
{
|
|
|
|
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
2011-12-08 17:38:19 +00:00
|
|
|
CoglRenderer *renderer = context->display->renderer;
|
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
2011-02-25 00:31:41 +00:00
|
|
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
2011-07-22 11:23:40 +00:00
|
|
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
|
|
|
int framebuffer_height = cogl_framebuffer_get_height (framebuffer);
|
|
|
|
int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4);
|
|
|
|
int i;
|
|
|
|
|
2011-12-09 16:10:01 +00:00
|
|
|
/* eglSwapBuffersRegion expects rectangles relative to the
|
|
|
|
* bottom left corner but we are given rectangles relative to
|
|
|
|
* the top left so we need to flip them... */
|
|
|
|
memcpy (rectangles, user_rectangles, sizeof (int) * n_rectangles * 4);
|
|
|
|
for (i = 0; i < n_rectangles; i++)
|
2011-07-22 11:23:40 +00:00
|
|
|
{
|
2011-12-09 16:10:01 +00:00
|
|
|
int *rect = &rectangles[4 * i];
|
|
|
|
rect[1] = framebuffer_height - rect[1] - rect[3];
|
2011-12-08 17:38:19 +00:00
|
|
|
}
|
2011-12-09 16:10:01 +00:00
|
|
|
|
|
|
|
/* At least for eglSwapBuffers the EGL spec says that the surface to
|
|
|
|
swap must be bound to the current context. It looks like Mesa
|
|
|
|
also validates that this is the case for eglSwapBuffersRegion so
|
|
|
|
we must bind here too */
|
|
|
|
_cogl_framebuffer_flush_state (COGL_FRAMEBUFFER (onscreen),
|
|
|
|
COGL_FRAMEBUFFER (onscreen),
|
|
|
|
COGL_FRAMEBUFFER_STATE_BIND);
|
|
|
|
|
|
|
|
if (egl_renderer->pf_eglSwapBuffersRegion (egl_renderer->edpy,
|
|
|
|
egl_onscreen->egl_surface,
|
|
|
|
n_rectangles,
|
|
|
|
rectangles) == EGL_FALSE)
|
|
|
|
g_warning ("Error reported by eglSwapBuffersRegion");
|
2011-02-25 00:31:41 +00:00
|
|
|
}
|
|
|
|
|
2011-02-25 11:29:08 +00:00
|
|
|
static void
|
2012-02-07 17:59:51 +00:00
|
|
|
_cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|
|
|
const int *rectangles,
|
|
|
|
int n_rectangles)
|
2011-02-25 00:31:41 +00:00
|
|
|
{
|
|
|
|
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
2011-12-08 17:38:19 +00:00
|
|
|
CoglRenderer *renderer = context->display->renderer;
|
|
|
|
CoglRendererEGL *egl_renderer = renderer->winsys;
|
2011-02-25 00:31:41 +00:00
|
|
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
2011-12-08 17:38:19 +00:00
|
|
|
|
2011-12-05 15:55:12 +00:00
|
|
|
/* The specification for EGL (at least in 1.4) says that the surface
|
|
|
|
needs to be bound to the current context for the swap to work
|
|
|
|
although it may change in future. Mesa explicitly checks for this
|
|
|
|
and just returns an error if this is not the case so we can't
|
|
|
|
just pretend this isn't in the spec. */
|
|
|
|
_cogl_framebuffer_flush_state (COGL_FRAMEBUFFER (onscreen),
|
|
|
|
COGL_FRAMEBUFFER (onscreen),
|
|
|
|
COGL_FRAMEBUFFER_STATE_BIND);
|
|
|
|
|
2012-02-07 17:59:51 +00:00
|
|
|
if (n_rectangles && egl_renderer->pf_eglSwapBuffersWithDamage)
|
|
|
|
{
|
|
|
|
CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
|
|
|
|
size_t size = n_rectangles * sizeof (int) * 4;
|
|
|
|
int *flipped = alloca (size);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
memcpy (flipped, rectangles, size);
|
|
|
|
for (i = 0; i < n_rectangles; i++)
|
|
|
|
{
|
|
|
|
const int *rect = rectangles + 4 * i;
|
|
|
|
int *flip_rect = flipped + 4 * i;
|
|
|
|
flip_rect[1] = fb->height - rect[1] - rect[3];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (egl_renderer->pf_eglSwapBuffersWithDamage (egl_renderer->edpy,
|
|
|
|
egl_onscreen->egl_surface,
|
|
|
|
flipped,
|
|
|
|
n_rectangles) == EGL_FALSE)
|
|
|
|
g_warning ("Error reported by eglSwapBuffersWithDamage");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
eglSwapBuffers (egl_renderer->edpy, egl_onscreen->egl_surface);
|
2011-02-25 00:31:41 +00:00
|
|
|
}
|
|
|
|
|
2011-02-25 11:29:08 +00:00
|
|
|
static void
|
2011-02-25 00:31:41 +00:00
|
|
|
_cogl_winsys_onscreen_update_swap_throttled (CoglOnscreen *onscreen)
|
|
|
|
{
|
|
|
|
CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
|
2012-03-06 03:21:30 +00:00
|
|
|
CoglDisplayEGL *egl_display = context->display->winsys;
|
2011-12-09 16:10:01 +00:00
|
|
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
2011-12-08 17:38:19 +00:00
|
|
|
|
2012-03-06 03:21:30 +00:00
|
|
|
if (egl_display->current_draw_surface != egl_onscreen->egl_surface)
|
2011-12-09 16:10:01 +00:00
|
|
|
return;
|
2011-12-08 17:38:19 +00:00
|
|
|
|
2012-03-06 03:21:30 +00:00
|
|
|
egl_display->current_draw_surface = EGL_NO_SURFACE;
|
2011-02-25 00:31:41 +00:00
|
|
|
|
|
|
|
_cogl_winsys_onscreen_bind (onscreen);
|
|
|
|
}
|
|
|
|
|
2011-02-25 11:29:08 +00:00
|
|
|
static EGLDisplay
|
2011-02-25 00:31:41 +00:00
|
|
|
_cogl_winsys_context_egl_get_egl_display (CoglContext *context)
|
|
|
|
{
|
|
|
|
CoglRendererEGL *egl_renderer = context->display->renderer->winsys;
|
|
|
|
|
|
|
|
return egl_renderer->edpy;
|
|
|
|
}
|
2011-03-01 14:43:43 +00:00
|
|
|
|
2012-03-06 03:21:30 +00:00
|
|
|
static void
|
|
|
|
_cogl_winsys_save_context (CoglContext *ctx)
|
|
|
|
{
|
|
|
|
CoglContextEGL *egl_context = ctx->winsys;
|
|
|
|
CoglDisplayEGL *egl_display = ctx->display->winsys;
|
|
|
|
|
|
|
|
egl_context->saved_draw_surface = egl_display->current_draw_surface;
|
|
|
|
egl_context->saved_read_surface = egl_display->current_read_surface;
|
|
|
|
}
|
|
|
|
|
|
|
|
static CoglBool
|
2012-08-31 18:28:27 +00:00
|
|
|
_cogl_winsys_set_gles2_context (CoglGLES2Context *gles2_ctx, CoglError **error)
|
2012-03-06 03:21:30 +00:00
|
|
|
{
|
|
|
|
CoglContext *ctx = gles2_ctx->context;
|
|
|
|
CoglDisplayEGL *egl_display = ctx->display->winsys;
|
|
|
|
CoglBool status;
|
|
|
|
|
|
|
|
if (gles2_ctx->write_buffer &&
|
|
|
|
cogl_is_onscreen (gles2_ctx->write_buffer))
|
2012-10-01 11:05:06 +00:00
|
|
|
status =
|
|
|
|
bind_onscreen_with_context (COGL_ONSCREEN (gles2_ctx->write_buffer),
|
|
|
|
gles2_ctx->winsys);
|
2012-03-06 03:21:30 +00:00
|
|
|
else
|
|
|
|
status = _cogl_winsys_egl_make_current (ctx->display,
|
|
|
|
egl_display->dummy_surface,
|
|
|
|
egl_display->dummy_surface,
|
|
|
|
gles2_ctx->winsys);
|
|
|
|
|
|
|
|
if (!status)
|
|
|
|
{
|
2012-08-31 18:28:27 +00:00
|
|
|
_cogl_set_error (error,
|
2012-03-06 03:21:30 +00:00
|
|
|
COGL_WINSYS_ERROR,
|
|
|
|
COGL_WINSYS_ERROR_MAKE_CURRENT,
|
|
|
|
"Failed to make gles2 context current");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_winsys_restore_context (CoglContext *ctx)
|
|
|
|
{
|
|
|
|
CoglContextEGL *egl_context = ctx->winsys;
|
|
|
|
CoglDisplayEGL *egl_display = ctx->display->winsys;
|
|
|
|
|
|
|
|
_cogl_winsys_egl_make_current (ctx->display,
|
|
|
|
egl_context->saved_draw_surface,
|
|
|
|
egl_context->saved_read_surface,
|
|
|
|
egl_display->egl_context);
|
|
|
|
}
|
|
|
|
|
2013-01-11 01:13:34 +00:00
|
|
|
#if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync)
|
|
|
|
static void *
|
|
|
|
_cogl_winsys_fence_add (CoglContext *context)
|
|
|
|
{
|
|
|
|
CoglRendererEGL *renderer = context->display->renderer->winsys;
|
|
|
|
void *ret;
|
|
|
|
|
|
|
|
if (renderer->pf_eglCreateSync)
|
|
|
|
ret = renderer->pf_eglCreateSync (renderer->edpy,
|
|
|
|
EGL_SYNC_FENCE_KHR,
|
|
|
|
NULL);
|
|
|
|
else
|
|
|
|
ret = NULL;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static CoglBool
|
|
|
|
_cogl_winsys_fence_is_complete (CoglContext *context, void *fence)
|
|
|
|
{
|
|
|
|
CoglRendererEGL *renderer = context->display->renderer->winsys;
|
|
|
|
EGLint ret;
|
|
|
|
|
|
|
|
ret = renderer->pf_eglClientWaitSync (renderer->edpy,
|
|
|
|
fence,
|
|
|
|
EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
|
|
|
|
0);
|
|
|
|
return (ret == EGL_CONDITION_SATISFIED_KHR);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_cogl_winsys_fence_destroy (CoglContext *context, void *fence)
|
|
|
|
{
|
|
|
|
CoglRendererEGL *renderer = context->display->renderer->winsys;
|
|
|
|
|
|
|
|
renderer->pf_eglDestroySync (renderer->edpy, fence);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-02-25 11:29:08 +00:00
|
|
|
static CoglWinsysVtable _cogl_winsys_vtable =
|
|
|
|
{
|
2012-04-26 11:18:56 +00:00
|
|
|
.constraints = COGL_RENDERER_CONSTRAINT_USES_EGL |
|
|
|
|
COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2,
|
2011-12-13 18:57:53 +00:00
|
|
|
|
2011-12-08 17:24:40 +00:00
|
|
|
/* This winsys is only used as a base for the EGL-platform
|
|
|
|
winsys's so it does not have an ID or a name */
|
|
|
|
|
2011-07-27 11:30:02 +00:00
|
|
|
.renderer_get_proc_address = _cogl_winsys_renderer_get_proc_address,
|
2011-02-25 11:29:08 +00:00
|
|
|
.renderer_connect = _cogl_winsys_renderer_connect,
|
|
|
|
.renderer_disconnect = _cogl_winsys_renderer_disconnect,
|
|
|
|
.display_setup = _cogl_winsys_display_setup,
|
|
|
|
.display_destroy = _cogl_winsys_display_destroy,
|
|
|
|
.context_init = _cogl_winsys_context_init,
|
|
|
|
.context_deinit = _cogl_winsys_context_deinit,
|
|
|
|
.context_egl_get_egl_display =
|
|
|
|
_cogl_winsys_context_egl_get_egl_display,
|
2012-03-06 03:21:30 +00:00
|
|
|
.context_create_gles2_context =
|
|
|
|
_cogl_winsys_context_create_gles2_context,
|
|
|
|
.destroy_gles2_context = _cogl_winsys_destroy_gles2_context,
|
2011-02-25 11:29:08 +00:00
|
|
|
.onscreen_init = _cogl_winsys_onscreen_init,
|
|
|
|
.onscreen_deinit = _cogl_winsys_onscreen_deinit,
|
|
|
|
.onscreen_bind = _cogl_winsys_onscreen_bind,
|
2012-02-07 17:59:51 +00:00
|
|
|
.onscreen_swap_buffers_with_damage =
|
|
|
|
_cogl_winsys_onscreen_swap_buffers_with_damage,
|
2011-02-25 11:29:08 +00:00
|
|
|
.onscreen_swap_region = _cogl_winsys_onscreen_swap_region,
|
2013-01-22 21:21:33 +00:00
|
|
|
.onscreen_get_buffer_age = _cogl_winsys_onscreen_get_buffer_age,
|
2011-02-25 11:29:08 +00:00
|
|
|
.onscreen_update_swap_throttled =
|
|
|
|
_cogl_winsys_onscreen_update_swap_throttled,
|
2012-03-06 03:21:30 +00:00
|
|
|
|
|
|
|
/* CoglGLES2Context related methods */
|
|
|
|
.save_context = _cogl_winsys_save_context,
|
|
|
|
.set_gles2_context = _cogl_winsys_set_gles2_context,
|
|
|
|
.restore_context = _cogl_winsys_restore_context,
|
2013-01-11 01:13:34 +00:00
|
|
|
|
|
|
|
#if defined(EGL_KHR_fence_sync) || defined(EGL_KHR_reusable_sync)
|
|
|
|
.fence_add = _cogl_winsys_fence_add,
|
|
|
|
.fence_is_complete = _cogl_winsys_fence_is_complete,
|
|
|
|
.fence_destroy = _cogl_winsys_fence_destroy,
|
|
|
|
#endif
|
2011-02-25 11:29:08 +00:00
|
|
|
};
|
2011-03-01 14:43:43 +00:00
|
|
|
|
2011-02-25 11:29:08 +00:00
|
|
|
/* XXX: we use a function because no doubt someone will complain
|
|
|
|
* about using c99 member initializers because they aren't portable
|
|
|
|
* to windows. We want to avoid having to rigidly follow the real
|
|
|
|
* order of members since some members are #ifdefd and we'd have
|
|
|
|
* to mirror the #ifdefing to add padding etc. For any winsys that
|
|
|
|
* can assume the platform has a sane compiler then we can just use
|
|
|
|
* c99 initializers for insane platforms they can initialize
|
|
|
|
* the members by name in a function.
|
|
|
|
*/
|
|
|
|
const CoglWinsysVtable *
|
|
|
|
_cogl_winsys_egl_get_vtable (void)
|
2011-03-01 14:43:43 +00:00
|
|
|
{
|
2011-02-25 11:29:08 +00:00
|
|
|
return &_cogl_winsys_vtable;
|
2011-03-01 14:43:43 +00:00
|
|
|
}
|
2011-05-11 13:07:02 +00:00
|
|
|
|
2011-05-24 21:34:10 +00:00
|
|
|
#ifdef EGL_KHR_image_base
|
|
|
|
EGLImageKHR
|
|
|
|
_cogl_egl_create_image (CoglContext *ctx,
|
|
|
|
EGLenum target,
|
|
|
|
EGLClientBuffer buffer,
|
|
|
|
const EGLint *attribs)
|
|
|
|
{
|
|
|
|
CoglDisplayEGL *egl_display = ctx->display->winsys;
|
|
|
|
CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys;
|
2011-07-20 23:52:07 +00:00
|
|
|
EGLContext egl_ctx;
|
2011-05-24 21:34:10 +00:00
|
|
|
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_VAL_IF_FAIL (egl_renderer->pf_eglCreateImage, EGL_NO_IMAGE_KHR);
|
2011-05-24 21:34:10 +00:00
|
|
|
|
2011-07-20 23:52:07 +00:00
|
|
|
/* The EGL_KHR_image_pixmap spec explicitly states that EGL_NO_CONTEXT must
|
|
|
|
* always be used in conjunction with the EGL_NATIVE_PIXMAP_KHR target */
|
|
|
|
#ifdef EGL_KHR_image_pixmap
|
|
|
|
if (target == EGL_NATIVE_PIXMAP_KHR)
|
|
|
|
egl_ctx = EGL_NO_CONTEXT;
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
egl_ctx = egl_display->egl_context;
|
|
|
|
|
2011-05-24 21:34:10 +00:00
|
|
|
return egl_renderer->pf_eglCreateImage (egl_renderer->edpy,
|
2011-07-20 23:52:07 +00:00
|
|
|
egl_ctx,
|
2011-05-24 21:34:10 +00:00
|
|
|
target,
|
|
|
|
buffer,
|
|
|
|
attribs);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
_cogl_egl_destroy_image (CoglContext *ctx,
|
|
|
|
EGLImageKHR image)
|
|
|
|
{
|
|
|
|
CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys;
|
|
|
|
|
2011-10-13 21:34:30 +00:00
|
|
|
_COGL_RETURN_IF_FAIL (egl_renderer->pf_eglDestroyImage);
|
2011-05-24 21:34:10 +00:00
|
|
|
|
|
|
|
egl_renderer->pf_eglDestroyImage (egl_renderer->edpy, image);
|
|
|
|
}
|
|
|
|
#endif
|
2013-04-30 13:09:11 +00:00
|
|
|
|
|
|
|
#ifdef EGL_WL_bind_wayland_display
|
|
|
|
CoglBool
|
|
|
|
_cogl_egl_query_wayland_buffer (CoglContext *ctx,
|
2013-10-15 18:02:46 +00:00
|
|
|
struct wl_resource *buffer,
|
2013-04-30 13:09:11 +00:00
|
|
|
int attribute,
|
|
|
|
int *value)
|
|
|
|
{
|
|
|
|
CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys;
|
|
|
|
|
2013-05-30 12:57:56 +00:00
|
|
|
_COGL_RETURN_VAL_IF_FAIL (egl_renderer->pf_eglQueryWaylandBuffer, FALSE);
|
2013-04-30 13:09:11 +00:00
|
|
|
|
|
|
|
return egl_renderer->pf_eglQueryWaylandBuffer (egl_renderer->edpy,
|
|
|
|
buffer,
|
|
|
|
attribute,
|
|
|
|
value);
|
|
|
|
}
|
|
|
|
#endif
|