Add a vtable for the driver

Cogl already had a vtable for the texture driver. This ended up being
used for some things that are not strictly related to texturing such
as converting between pixel formats and GL enums. Some other functions
that are driver dependent such as updating the features were not
indirected through a vtable but instead switched directly by looking
at the ctx->driver enum value. This patch normalises to the two uses
by adding a separate vtable for driver functions not related to
texturing and moves the pixel format conversion functions to it from
the texture driver vtable. It also adds a context parameter to all of
the functions in the new driver vtable so that they won't have to rely
on the global context.
This commit is contained in:
Neil Roberts 2012-03-22 16:32:56 +00:00
parent ccb6792781
commit 60812e6a0e
17 changed files with 515 additions and 453 deletions

View File

@ -196,6 +196,7 @@ cogl_sources_c = \
$(srcdir)/cogl-display.h \
$(srcdir)/cogl-display.c \
$(srcdir)/cogl-internal.h \
$(srcdir)/cogl-driver.h \
$(srcdir)/cogl.c \
$(srcdir)/cogl-object-private.h \
$(srcdir)/cogl-object.h \

View File

@ -177,10 +177,11 @@ _cogl_atlas_get_initial_size (CoglPixelFormat format,
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
ctx->texture_driver->pixel_format_to_gl (format,
&gl_intformat,
NULL, /* gl_format */
&gl_type);
ctx->driver_vtable->pixel_format_to_gl (ctx,
format,
&gl_intformat,
NULL, /* gl_format */
&gl_type);
/* At least on Intel hardware, the texture size will be rounded up
to at least 1MB so we might as well try to aim for that as an
@ -217,10 +218,11 @@ _cogl_atlas_create_map (CoglPixelFormat format,
_COGL_GET_CONTEXT (ctx, NULL);
ctx->texture_driver->pixel_format_to_gl (format,
&gl_intformat,
NULL, /* gl_format */
&gl_type);
ctx->driver_vtable->pixel_format_to_gl (ctx,
format,
&gl_intformat,
NULL, /* gl_format */
&gl_type);
/* Keep trying increasingly larger atlases until we can fit all of
the textures */

View File

@ -41,6 +41,7 @@
#include "cogl-buffer-private.h"
#include "cogl-bitmask.h"
#include "cogl-atlas.h"
#include "cogl-driver.h"
#include "cogl-texture-driver.h"
#include "cogl-pipeline-cache.h"
#include "cogl-texture-2d.h"
@ -62,7 +63,8 @@ struct _CoglContext
CoglDriver driver;
/* vtable for the texture driver functions */
/* vtables for the driver functions */
const CoglDriverVtable *driver_vtable;
const CoglTextureDriver *texture_driver;
/* Features cache */

View File

@ -61,9 +61,11 @@
#ifdef HAVE_COGL_GL
extern const CoglTextureDriver _cogl_texture_driver_gl;
extern const CoglDriverVtable _cogl_driver_gl;
#endif
#if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GLES2)
extern const CoglTextureDriver _cogl_texture_driver_gles;
extern const CoglDriverVtable _cogl_driver_gles;
#endif
static void _cogl_context_free (CoglContext *context);
@ -203,18 +205,11 @@ cogl_context_new (CoglDisplay *display,
lot throughout Cogl */
context->driver = display->renderer->driver;
winsys = _cogl_context_get_winsys (context);
if (!winsys->context_init (context, error))
{
cogl_object_unref (display);
g_free (context);
return NULL;
}
switch (context->driver)
{
#ifdef HAVE_COGL_GL
case COGL_DRIVER_GL:
context->driver_vtable = &_cogl_driver_gl;
context->texture_driver = &_cogl_texture_driver_gl;
break;
#endif
@ -222,6 +217,7 @@ cogl_context_new (CoglDisplay *display,
#if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GLES2)
case COGL_DRIVER_GLES1:
case COGL_DRIVER_GLES2:
context->driver_vtable = &_cogl_driver_gles;
context->texture_driver = &_cogl_texture_driver_gles;
break;
#endif
@ -230,6 +226,14 @@ cogl_context_new (CoglDisplay *display,
g_assert_not_reached ();
}
winsys = _cogl_context_get_winsys (context);
if (!winsys->context_init (context, error))
{
cogl_object_unref (display);
g_free (context);
return NULL;
}
context->attribute_name_states_hash =
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
context->attribute_name_index_map = NULL;
@ -578,16 +582,7 @@ gboolean
_cogl_context_update_features (CoglContext *context,
GError **error)
{
#ifdef HAVE_COGL_GL
if (context->driver == COGL_DRIVER_GL)
return _cogl_gl_update_features (context, error);
#endif
#if defined(HAVE_COGL_GLES) || defined(HAVE_COGL_GLES2)
return _cogl_gles_update_features (context, error);
#endif
g_assert_not_reached ();
return context->driver_vtable->update_features (context, error);
}
void

51
cogl/cogl-driver.h Normal file
View File

@ -0,0 +1,51 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2012 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_DRIVER_H
#define __COGL_DRIVER_H
#include "cogl-context.h"
typedef struct _CoglDriverVtable CoglDriverVtable;
struct _CoglDriverVtable
{
gboolean
(* pixel_format_from_gl_internal) (CoglContext *context,
GLenum gl_int_format,
CoglPixelFormat *out_format);
CoglPixelFormat
(* pixel_format_to_gl) (CoglContext *context,
CoglPixelFormat format,
GLenum *out_glintformat,
GLenum *out_glformat,
GLenum *out_gltype);
gboolean
(* update_features) (CoglContext *context,
GError **error);
};
#endif /* __COGL_DRIVER_H */

View File

@ -2005,10 +2005,11 @@ cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
format = cogl_bitmap_get_format (bitmap);
required_format = ctx->texture_driver->pixel_format_to_gl (format,
&gl_intformat,
&gl_format,
&gl_type);
required_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
format,
&gl_intformat,
&gl_format,
&gl_type);
/* NB: All offscreen rendering is done upside down so there is no need
* to flip in this case... */

View File

@ -30,14 +30,6 @@
G_BEGIN_DECLS
gboolean
_cogl_gl_update_features (CoglContext *context,
GError **error);
gboolean
_cogl_gles_update_features (CoglContext *context,
GError **error);
gboolean
_cogl_check_extension (const char *name, const char *ext);

View File

@ -639,10 +639,11 @@ _cogl_texture_2d_sliced_slices_create (CoglContext *ctx,
slices_for_size = _cogl_pot_slices_for_size;
}
ctx->texture_driver->pixel_format_to_gl (format,
&gl_intformat,
NULL,
&gl_type);
ctx->driver_vtable->pixel_format_to_gl (ctx,
format,
&gl_intformat,
NULL,
&gl_type);
/* Negative number means no slicing forced by the user */
if (tex_2ds->max_waste <= -1)

View File

@ -120,10 +120,11 @@ _cogl_texture_2d_can_create (unsigned int width,
!_cogl_util_is_pot (height)))
return FALSE;
ctx->texture_driver->pixel_format_to_gl (internal_format,
&gl_intformat,
NULL,
&gl_type);
ctx->driver_vtable->pixel_format_to_gl (ctx,
internal_format,
&gl_intformat,
NULL,
&gl_type);
/* Check that the driver can create a texture with that size */
if (!ctx->texture_driver->size_supported (GL_TEXTURE_2D,
@ -192,10 +193,11 @@ cogl_texture_2d_new_with_size (CoglContext *ctx,
return NULL;
}
internal_format = ctx->texture_driver->pixel_format_to_gl (internal_format,
&gl_intformat,
&gl_format,
&gl_type);
internal_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
internal_format,
&gl_intformat,
&gl_format,
&gl_type);
tex_2d = _cogl_texture_2d_create_base (width, height, COGL_TEXTURE_NONE,
internal_format);
@ -382,8 +384,9 @@ cogl_texture_2d_new_from_foreign (CoglContext *ctx,
/* If we can query GL for the actual pixel format then we'll ignore
the passed in format and use that. */
if (!ctx->texture_driver->pixel_format_from_gl_internal (gl_int_format,
&format))
if (!ctx->driver_vtable->pixel_format_from_gl_internal (ctx,
gl_int_format,
&format))
return COGL_INVALID_HANDLE;
}
else
@ -391,10 +394,11 @@ cogl_texture_2d_new_from_foreign (CoglContext *ctx,
{
/* Otherwise we'll assume we can derive the GL format from the
passed in format */
ctx->texture_driver->pixel_format_to_gl (format,
&gl_int_format,
NULL,
NULL);
ctx->driver_vtable->pixel_format_to_gl (ctx,
format,
&gl_int_format,
NULL,
NULL);
}
/* Note: We always trust the given width and height without querying
@ -812,10 +816,11 @@ _cogl_texture_2d_get_data (CoglTexture *tex,
bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
ctx->texture_driver->pixel_format_to_gl (format,
NULL, /* internal format */
&gl_format,
&gl_type);
ctx->driver_vtable->pixel_format_to_gl (ctx,
format,
NULL, /* internal format */
&gl_format,
&gl_type);
ctx->texture_driver->prep_gl_for_pixels_download (rowstride, bpp);

View File

@ -167,10 +167,11 @@ _cogl_texture_3d_can_create (CoglContext *ctx,
return FALSE;
}
ctx->texture_driver->pixel_format_to_gl (internal_format,
&gl_intformat,
NULL,
&gl_type);
ctx->driver_vtable->pixel_format_to_gl (ctx,
internal_format,
&gl_intformat,
NULL,
&gl_type);
/* Check that the driver can create a texture with that size */
if (!ctx->texture_driver->size_supported_3d (GL_TEXTURE_3D,
@ -213,10 +214,11 @@ cogl_texture_3d_new_with_size (CoglContext *ctx,
error))
return NULL;
internal_format = ctx->texture_driver->pixel_format_to_gl (internal_format,
&gl_intformat,
&gl_format,
&gl_type);
internal_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
internal_format,
&gl_intformat,
&gl_format,
&gl_type);
tex_3d = _cogl_texture_3d_create_base (ctx,
width, height, depth,

View File

@ -160,22 +160,6 @@ struct _CoglTextureDriver
GLuint gl_target,
const GLfloat *transparent_color);
/*
* XXX: this should live in cogl/{gl,gles}/cogl.c
*/
gboolean
(* pixel_format_from_gl_internal) (GLenum gl_int_format,
CoglPixelFormat *out_format);
/*
* XXX: this should live in cogl/{gl,gles}/cogl.c
*/
CoglPixelFormat
(* pixel_format_to_gl) (CoglPixelFormat format,
GLenum *out_glintformat,
GLenum *out_glformat,
GLenum *out_gltype);
/*
* It may depend on the driver as to what texture targets may be used when
* creating a foreign texture. E.g. OpenGL supports ARB_texture_rectangle
@ -199,7 +183,8 @@ struct _CoglTextureDriver
* destination has another format.
*/
CoglPixelFormat
(* find_best_gl_get_data_format) (CoglPixelFormat format,
(* find_best_gl_get_data_format) (CoglContext *context,
CoglPixelFormat format,
GLenum *closest_gl_format,
GLenum *closest_gl_type);
};

View File

@ -128,10 +128,11 @@ _cogl_texture_rectangle_can_create (unsigned int width,
return FALSE;
}
ctx->texture_driver->pixel_format_to_gl (internal_format,
&gl_intformat,
NULL,
&gl_type);
ctx->driver_vtable->pixel_format_to_gl (ctx,
internal_format,
&gl_intformat,
NULL,
&gl_type);
/* Check that the driver can create a texture with that size */
if (!ctx->texture_driver->size_supported (GL_TEXTURE_RECTANGLE_ARB,
@ -196,10 +197,11 @@ cogl_texture_rectangle_new_with_size (CoglContext *ctx,
internal_format, error))
return NULL;
internal_format = ctx->texture_driver->pixel_format_to_gl (internal_format,
&gl_intformat,
&gl_format,
&gl_type);
internal_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
internal_format,
&gl_intformat,
&gl_format,
&gl_type);
tex_rect = _cogl_texture_rectangle_create_base (width, height,
internal_format);
@ -320,8 +322,9 @@ _cogl_texture_rectangle_new_from_foreign (GLuint gl_handle,
/* If we can query GL for the actual pixel format then we'll ignore
the passed in format and use that. */
if (!ctx->texture_driver->pixel_format_from_gl_internal (gl_int_format,
&format))
if (!ctx->driver_vtable->pixel_format_from_gl_internal (ctx,
gl_int_format,
&format))
return NULL;
}
else
@ -329,10 +332,11 @@ _cogl_texture_rectangle_new_from_foreign (GLuint gl_handle,
{
/* Otherwise we'll assume we can derive the GL format from the
passed in format */
ctx->texture_driver->pixel_format_to_gl (format,
&gl_int_format,
NULL,
NULL);
ctx->driver_vtable->pixel_format_to_gl (ctx,
format,
&gl_int_format,
NULL,
NULL);
}
/* Note: We always trust the given width and height without querying
@ -532,10 +536,11 @@ _cogl_texture_rectangle_get_data (CoglTexture *tex,
bpp = _cogl_pixel_format_get_bytes_per_pixel (format);
ctx->texture_driver->pixel_format_to_gl (format,
NULL, /* internal format */
&gl_format,
&gl_type);
ctx->driver_vtable->pixel_format_to_gl (ctx,
format,
NULL, /* internal format */
&gl_format,
&gl_type);
ctx->texture_driver->prep_gl_for_pixels_download (rowstride, bpp);

View File

@ -212,24 +212,27 @@ _cogl_texture_prepare_for_upload (CoglBitmap *src_bmp,
/* Use the source format from the src bitmap type and the internal
format from the dst format type so that GL can do the
conversion */
ctx->texture_driver->pixel_format_to_gl (src_format,
NULL, /* internal format */
out_glformat,
out_gltype);
ctx->texture_driver->pixel_format_to_gl (dst_format,
out_glintformat,
NULL,
NULL);
ctx->driver_vtable->pixel_format_to_gl (ctx,
src_format,
NULL, /* internal format */
out_glformat,
out_gltype);
ctx->driver_vtable->pixel_format_to_gl (ctx,
dst_format,
out_glintformat,
NULL,
NULL);
}
else
{
CoglPixelFormat closest_format;
closest_format = ctx->texture_driver->pixel_format_to_gl (dst_format,
out_glintformat,
out_glformat,
out_gltype);
closest_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
dst_format,
out_glintformat,
out_glformat,
out_gltype);
if (closest_format != src_format)
dst_bmp = _cogl_bitmap_convert (src_bmp, closest_format);
@ -1148,7 +1151,8 @@ cogl_texture_get_data (CoglTexture *texture,
return byte_size;
closest_format =
ctx->texture_driver->find_best_gl_get_data_format (format,
ctx->texture_driver->find_best_gl_get_data_format (ctx,
format,
&closest_gl_format,
&closest_gl_type);

View File

@ -34,13 +34,199 @@
#include "cogl-renderer-private.h"
static gboolean
_cogl_get_gl_version (int *major_out, int *minor_out)
_cogl_driver_pixel_format_from_gl_internal (CoglContext *context,
GLenum gl_int_format,
CoglPixelFormat *out_format)
{
/* It doesn't really matter we convert to exact same
format (some have no cogl match anyway) since format
is re-matched against cogl when getting or setting
texture image data.
*/
switch (gl_int_format)
{
case GL_ALPHA: case GL_ALPHA4: case GL_ALPHA8:
case GL_ALPHA12: case GL_ALPHA16:
*out_format = COGL_PIXEL_FORMAT_A_8;
return TRUE;
case GL_LUMINANCE: case GL_LUMINANCE4: case GL_LUMINANCE8:
case GL_LUMINANCE12: case GL_LUMINANCE16:
*out_format = COGL_PIXEL_FORMAT_G_8;
return TRUE;
case GL_RGB: case GL_RGB4: case GL_RGB5: case GL_RGB8:
case GL_RGB10: case GL_RGB12: case GL_RGB16: case GL_R3_G3_B2:
*out_format = COGL_PIXEL_FORMAT_RGB_888;
return TRUE;
case GL_RGBA: case GL_RGBA2: case GL_RGBA4: case GL_RGB5_A1:
case GL_RGBA8: case GL_RGB10_A2: case GL_RGBA12: case GL_RGBA16:
*out_format = COGL_PIXEL_FORMAT_RGBA_8888;
return TRUE;
}
return FALSE;
}
static CoglPixelFormat
_cogl_driver_pixel_format_to_gl (CoglContext *context,
CoglPixelFormat format,
GLenum *out_glintformat,
GLenum *out_glformat,
GLenum *out_gltype)
{
CoglPixelFormat required_format;
GLenum glintformat;
GLenum glformat = 0;
GLenum gltype;
required_format = format;
/* Find GL equivalents */
switch (format)
{
case COGL_PIXEL_FORMAT_A_8:
glintformat = GL_ALPHA;
glformat = GL_ALPHA;
gltype = GL_UNSIGNED_BYTE;
break;
case COGL_PIXEL_FORMAT_G_8:
glintformat = GL_LUMINANCE;
glformat = GL_LUMINANCE;
gltype = GL_UNSIGNED_BYTE;
break;
case COGL_PIXEL_FORMAT_RGB_888:
glintformat = GL_RGB;
glformat = GL_RGB;
gltype = GL_UNSIGNED_BYTE;
break;
case COGL_PIXEL_FORMAT_BGR_888:
glintformat = GL_RGB;
glformat = GL_BGR;
gltype = GL_UNSIGNED_BYTE;
break;
case COGL_PIXEL_FORMAT_RGBA_8888:
case COGL_PIXEL_FORMAT_RGBA_8888_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_BYTE;
break;
case COGL_PIXEL_FORMAT_BGRA_8888:
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
glintformat = GL_RGBA;
glformat = GL_BGRA;
gltype = GL_UNSIGNED_BYTE;
break;
/* The following two types of channel ordering
* have no GL equivalent unless defined using
* system word byte ordering */
case COGL_PIXEL_FORMAT_ARGB_8888:
case COGL_PIXEL_FORMAT_ARGB_8888_PRE:
glintformat = GL_RGBA;
glformat = GL_BGRA;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
gltype = GL_UNSIGNED_INT_8_8_8_8;
#else
gltype = GL_UNSIGNED_INT_8_8_8_8_REV;
#endif
break;
case COGL_PIXEL_FORMAT_ABGR_8888:
case COGL_PIXEL_FORMAT_ABGR_8888_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
gltype = GL_UNSIGNED_INT_8_8_8_8;
#else
gltype = GL_UNSIGNED_INT_8_8_8_8_REV;
#endif
break;
case COGL_PIXEL_FORMAT_RGBA_1010102:
case COGL_PIXEL_FORMAT_RGBA_1010102_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_INT_10_10_10_2;
break;
case COGL_PIXEL_FORMAT_BGRA_1010102:
case COGL_PIXEL_FORMAT_BGRA_1010102_PRE:
glintformat = GL_RGBA;
glformat = GL_BGRA;
gltype = GL_UNSIGNED_INT_10_10_10_2;
break;
case COGL_PIXEL_FORMAT_ABGR_2101010:
case COGL_PIXEL_FORMAT_ABGR_2101010_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_INT_2_10_10_10_REV;
break;
case COGL_PIXEL_FORMAT_ARGB_2101010:
case COGL_PIXEL_FORMAT_ARGB_2101010_PRE:
glintformat = GL_RGBA;
glformat = GL_BGRA;
gltype = GL_UNSIGNED_INT_2_10_10_10_REV;
break;
/* The following three types of channel ordering
* are always defined using system word byte
* ordering (even according to GLES spec) */
case COGL_PIXEL_FORMAT_RGB_565:
glintformat = GL_RGB;
glformat = GL_RGB;
gltype = GL_UNSIGNED_SHORT_5_6_5;
break;
case COGL_PIXEL_FORMAT_RGBA_4444:
case COGL_PIXEL_FORMAT_RGBA_4444_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_SHORT_4_4_4_4;
break;
case COGL_PIXEL_FORMAT_RGBA_5551:
case COGL_PIXEL_FORMAT_RGBA_5551_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_SHORT_5_5_5_1;
break;
case COGL_PIXEL_FORMAT_ANY:
case COGL_PIXEL_FORMAT_YUV:
g_assert_not_reached ();
break;
}
/* All of the pixel formats are handled above so if this hits then
we've been given an invalid pixel format */
g_assert (glformat != 0);
if (out_glintformat != NULL)
*out_glintformat = glintformat;
if (out_glformat != NULL)
*out_glformat = glformat;
if (out_gltype != NULL)
*out_gltype = gltype;
return required_format;
}
static gboolean
_cogl_get_gl_version (CoglContext *ctx,
int *major_out,
int *minor_out)
{
const char *version_string, *major_end, *minor_end;
int major = 0, minor = 0;
_COGL_GET_CONTEXT (ctx, FALSE);
/* Get the OpenGL version number */
if ((version_string = (const char *) ctx->glGetString (GL_VERSION)) == NULL)
return FALSE;
@ -77,7 +263,7 @@ check_gl_version (CoglContext *ctx,
int major, minor;
const char *gl_extensions;
if (!_cogl_get_gl_version (&major, &minor))
if (!_cogl_get_gl_version (ctx, &major, &minor))
{
g_set_error (error,
COGL_DRIVER_ERROR,
@ -119,9 +305,9 @@ check_gl_version (CoglContext *ctx,
return TRUE;
}
gboolean
_cogl_gl_update_features (CoglContext *context,
GError **error)
static gboolean
_cogl_driver_update_features (CoglContext *ctx,
GError **error)
{
CoglPrivateFeatureFlags private_flags = 0;
CoglFeatureFlags flags = 0;
@ -130,16 +316,14 @@ _cogl_gl_update_features (CoglContext *context,
int num_stencil_bits = 0;
int gl_major = 0, gl_minor = 0;
_COGL_GET_CONTEXT (ctx, FALSE);
/* We have to special case getting the pointer to the glGetString
function because we need to use it to determine what functions we
can expect */
context->glGetString =
(void *) _cogl_renderer_get_proc_address (context->display->renderer,
ctx->glGetString =
(void *) _cogl_renderer_get_proc_address (ctx->display->renderer,
"glGetString");
if (!check_gl_version (context, error))
if (!check_gl_version (ctx, error))
return FALSE;
COGL_NOTE (WINSYS,
@ -153,7 +337,7 @@ _cogl_gl_update_features (CoglContext *context,
ctx->glGetString (GL_VERSION),
ctx->glGetString (GL_EXTENSIONS));
_cogl_get_gl_version (&gl_major, &gl_minor);
_cogl_get_gl_version (ctx, &gl_major, &gl_minor);
flags = (COGL_FEATURE_TEXTURE_READ_PIXELS
| COGL_FEATURE_UNSIGNED_INT_INDICES
@ -167,7 +351,7 @@ _cogl_gl_update_features (CoglContext *context,
gl_extensions = (const char *)ctx->glGetString (GL_EXTENSIONS);
_cogl_feature_check_ext_functions (context,
_cogl_feature_check_ext_functions (ctx,
gl_major,
gl_minor,
gl_extensions);
@ -200,16 +384,16 @@ _cogl_gl_update_features (CoglContext *context,
if (max_clip_planes >= 4)
private_flags |= COGL_PRIVATE_FEATURE_FOUR_CLIP_PLANES;
if (context->glGenRenderbuffers)
if (ctx->glGenRenderbuffers)
{
flags |= COGL_FEATURE_OFFSCREEN;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_OFFSCREEN, TRUE);
}
if (context->glBlitFramebuffer)
if (ctx->glBlitFramebuffer)
private_flags |= COGL_PRIVATE_FEATURE_OFFSCREEN_BLIT;
if (context->glRenderbufferStorageMultisampleIMG)
if (ctx->glRenderbufferStorageMultisampleIMG)
{
flags |= COGL_FEATURE_OFFSCREEN_MULTISAMPLE;
COGL_FLAGS_SET (ctx->features,
@ -227,19 +411,19 @@ _cogl_gl_update_features (CoglContext *context,
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_POINT_SPRITE, TRUE);
}
if (context->glGenPrograms)
if (ctx->glGenPrograms)
{
flags |= COGL_FEATURE_SHADERS_ARBFP;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_ARBFP, TRUE);
}
if (context->glCreateProgram)
if (ctx->glCreateProgram)
{
flags |= COGL_FEATURE_SHADERS_GLSL;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_GLSL, TRUE);
}
if (context->glGenBuffers)
if (ctx->glGenBuffers)
{
private_flags |= COGL_PRIVATE_FEATURE_VBOS;
flags |= (COGL_FEATURE_MAP_BUFFER_FOR_READ |
@ -257,21 +441,29 @@ _cogl_gl_update_features (CoglContext *context,
COGL_FEATURE_ID_TEXTURE_RECTANGLE, TRUE);
}
if (context->glTexImage3D)
if (ctx->glTexImage3D)
{
flags |= COGL_FEATURE_TEXTURE_3D;
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_TEXTURE_3D, TRUE);
}
if (context->glEGLImageTargetTexture2D)
if (ctx->glEGLImageTargetTexture2D)
private_flags |= COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE;
if (_cogl_check_extension ("GL_EXT_packed_depth_stencil", gl_extensions))
private_flags |= COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL;
/* Cache features */
context->private_feature_flags |= private_flags;
context->feature_flags |= flags;
ctx->private_feature_flags |= private_flags;
ctx->feature_flags |= flags;
return TRUE;
}
const CoglDriverVtable
_cogl_driver_gl =
{
_cogl_driver_pixel_format_from_gl_internal,
_cogl_driver_pixel_format_to_gl,
_cogl_driver_update_features
};

View File

@ -352,190 +352,6 @@ _cogl_texture_driver_try_setting_gl_border_color (
transparent_color) );
}
static gboolean
_cogl_texture_driver_pixel_format_from_gl_internal (GLenum gl_int_format,
CoglPixelFormat *out_format)
{
/* It doesn't really matter we convert to exact same
format (some have no cogl match anyway) since format
is re-matched against cogl when getting or setting
texture image data.
*/
switch (gl_int_format)
{
case GL_ALPHA: case GL_ALPHA4: case GL_ALPHA8:
case GL_ALPHA12: case GL_ALPHA16:
*out_format = COGL_PIXEL_FORMAT_A_8;
return TRUE;
case GL_LUMINANCE: case GL_LUMINANCE4: case GL_LUMINANCE8:
case GL_LUMINANCE12: case GL_LUMINANCE16:
*out_format = COGL_PIXEL_FORMAT_G_8;
return TRUE;
case GL_RGB: case GL_RGB4: case GL_RGB5: case GL_RGB8:
case GL_RGB10: case GL_RGB12: case GL_RGB16: case GL_R3_G3_B2:
*out_format = COGL_PIXEL_FORMAT_RGB_888;
return TRUE;
case GL_RGBA: case GL_RGBA2: case GL_RGBA4: case GL_RGB5_A1:
case GL_RGBA8: case GL_RGB10_A2: case GL_RGBA12: case GL_RGBA16:
*out_format = COGL_PIXEL_FORMAT_RGBA_8888;
return TRUE;
}
return FALSE;
}
static CoglPixelFormat
_cogl_texture_driver_pixel_format_to_gl (CoglPixelFormat format,
GLenum *out_glintformat,
GLenum *out_glformat,
GLenum *out_gltype)
{
CoglPixelFormat required_format;
GLenum glintformat;
GLenum glformat = 0;
GLenum gltype;
required_format = format;
/* Find GL equivalents */
switch (format)
{
case COGL_PIXEL_FORMAT_A_8:
glintformat = GL_ALPHA;
glformat = GL_ALPHA;
gltype = GL_UNSIGNED_BYTE;
break;
case COGL_PIXEL_FORMAT_G_8:
glintformat = GL_LUMINANCE;
glformat = GL_LUMINANCE;
gltype = GL_UNSIGNED_BYTE;
break;
case COGL_PIXEL_FORMAT_RGB_888:
glintformat = GL_RGB;
glformat = GL_RGB;
gltype = GL_UNSIGNED_BYTE;
break;
case COGL_PIXEL_FORMAT_BGR_888:
glintformat = GL_RGB;
glformat = GL_BGR;
gltype = GL_UNSIGNED_BYTE;
break;
case COGL_PIXEL_FORMAT_RGBA_8888:
case COGL_PIXEL_FORMAT_RGBA_8888_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_BYTE;
break;
case COGL_PIXEL_FORMAT_BGRA_8888:
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
glintformat = GL_RGBA;
glformat = GL_BGRA;
gltype = GL_UNSIGNED_BYTE;
break;
/* The following two types of channel ordering
* have no GL equivalent unless defined using
* system word byte ordering */
case COGL_PIXEL_FORMAT_ARGB_8888:
case COGL_PIXEL_FORMAT_ARGB_8888_PRE:
glintformat = GL_RGBA;
glformat = GL_BGRA;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
gltype = GL_UNSIGNED_INT_8_8_8_8;
#else
gltype = GL_UNSIGNED_INT_8_8_8_8_REV;
#endif
break;
case COGL_PIXEL_FORMAT_ABGR_8888:
case COGL_PIXEL_FORMAT_ABGR_8888_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
gltype = GL_UNSIGNED_INT_8_8_8_8;
#else
gltype = GL_UNSIGNED_INT_8_8_8_8_REV;
#endif
break;
case COGL_PIXEL_FORMAT_RGBA_1010102:
case COGL_PIXEL_FORMAT_RGBA_1010102_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_INT_10_10_10_2;
break;
case COGL_PIXEL_FORMAT_BGRA_1010102:
case COGL_PIXEL_FORMAT_BGRA_1010102_PRE:
glintformat = GL_RGBA;
glformat = GL_BGRA;
gltype = GL_UNSIGNED_INT_10_10_10_2;
break;
case COGL_PIXEL_FORMAT_ABGR_2101010:
case COGL_PIXEL_FORMAT_ABGR_2101010_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_INT_2_10_10_10_REV;
break;
case COGL_PIXEL_FORMAT_ARGB_2101010:
case COGL_PIXEL_FORMAT_ARGB_2101010_PRE:
glintformat = GL_RGBA;
glformat = GL_BGRA;
gltype = GL_UNSIGNED_INT_2_10_10_10_REV;
break;
/* The following three types of channel ordering
* are always defined using system word byte
* ordering (even according to GLES spec) */
case COGL_PIXEL_FORMAT_RGB_565:
glintformat = GL_RGB;
glformat = GL_RGB;
gltype = GL_UNSIGNED_SHORT_5_6_5;
break;
case COGL_PIXEL_FORMAT_RGBA_4444:
case COGL_PIXEL_FORMAT_RGBA_4444_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_SHORT_4_4_4_4;
break;
case COGL_PIXEL_FORMAT_RGBA_5551:
case COGL_PIXEL_FORMAT_RGBA_5551_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_SHORT_5_5_5_1;
break;
case COGL_PIXEL_FORMAT_ANY:
case COGL_PIXEL_FORMAT_YUV:
g_assert_not_reached ();
break;
}
/* All of the pixel formats are handled above so if this hits then
we've been given an invalid pixel format */
g_assert (glformat != 0);
if (out_glintformat != NULL)
*out_glintformat = glintformat;
if (out_glformat != NULL)
*out_glformat = glformat;
if (out_gltype != NULL)
*out_gltype = gltype;
return required_format;
}
static gboolean
_cogl_texture_driver_allows_foreign_gl_target (GLenum gl_target)
{
@ -561,16 +377,17 @@ _cogl_texture_driver_gl_generate_mipmaps (GLenum gl_target)
}
static CoglPixelFormat
_cogl_texture_driver_find_best_gl_get_data_format (
CoglPixelFormat format,
GLenum *closest_gl_format,
GLenum *closest_gl_type)
_cogl_texture_driver_find_best_gl_get_data_format
(CoglContext *context,
CoglPixelFormat format,
GLenum *closest_gl_format,
GLenum *closest_gl_type)
{
/* Find closest format that's supported by GL */
return _cogl_texture_driver_pixel_format_to_gl (format,
NULL, /* don't need */
closest_gl_format,
closest_gl_type);
return context->driver_vtable->pixel_format_to_gl (context,
format,
NULL, /* don't need */
closest_gl_format,
closest_gl_type);
}
const CoglTextureDriver
@ -586,8 +403,6 @@ _cogl_texture_driver_gl =
_cogl_texture_driver_size_supported,
_cogl_texture_driver_size_supported_3d,
_cogl_texture_driver_try_setting_gl_border_color,
_cogl_texture_driver_pixel_format_from_gl_internal,
_cogl_texture_driver_pixel_format_to_gl,
_cogl_texture_driver_allows_foreign_gl_target,
_cogl_texture_driver_gl_generate_mipmaps,
_cogl_texture_driver_find_best_gl_get_data_format

View File

@ -33,9 +33,119 @@
#include "cogl-renderer-private.h"
#include "cogl-private.h"
gboolean
_cogl_gles_update_features (CoglContext *context,
GError **error)
static gboolean
_cogl_driver_pixel_format_from_gl_internal (CoglContext *context,
GLenum gl_int_format,
CoglPixelFormat *out_format)
{
return TRUE;
}
static CoglPixelFormat
_cogl_driver_pixel_format_to_gl (CoglContext *context,
CoglPixelFormat format,
GLenum *out_glintformat,
GLenum *out_glformat,
GLenum *out_gltype)
{
CoglPixelFormat required_format;
GLenum glintformat;
GLenum glformat = 0;
GLenum gltype;
required_format = format;
/* Find GL equivalents */
switch (format)
{
case COGL_PIXEL_FORMAT_A_8:
glintformat = GL_ALPHA;
glformat = GL_ALPHA;
gltype = GL_UNSIGNED_BYTE;
break;
case COGL_PIXEL_FORMAT_G_8:
glintformat = GL_LUMINANCE;
glformat = GL_LUMINANCE;
gltype = GL_UNSIGNED_BYTE;
break;
/* Just one 24-bit ordering supported */
case COGL_PIXEL_FORMAT_RGB_888:
case COGL_PIXEL_FORMAT_BGR_888:
glintformat = GL_RGB;
glformat = GL_RGB;
gltype = GL_UNSIGNED_BYTE;
required_format = COGL_PIXEL_FORMAT_RGB_888;
break;
/* Just one 32-bit ordering supported */
case COGL_PIXEL_FORMAT_RGBA_8888:
case COGL_PIXEL_FORMAT_RGBA_8888_PRE:
case COGL_PIXEL_FORMAT_BGRA_8888:
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
case COGL_PIXEL_FORMAT_ARGB_8888:
case COGL_PIXEL_FORMAT_ARGB_8888_PRE:
case COGL_PIXEL_FORMAT_ABGR_8888:
case COGL_PIXEL_FORMAT_ABGR_8888_PRE:
case COGL_PIXEL_FORMAT_RGBA_1010102:
case COGL_PIXEL_FORMAT_RGBA_1010102_PRE:
case COGL_PIXEL_FORMAT_BGRA_1010102:
case COGL_PIXEL_FORMAT_BGRA_1010102_PRE:
case COGL_PIXEL_FORMAT_ABGR_2101010:
case COGL_PIXEL_FORMAT_ABGR_2101010_PRE:
case COGL_PIXEL_FORMAT_ARGB_2101010:
case COGL_PIXEL_FORMAT_ARGB_2101010_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_BYTE;
required_format = COGL_PIXEL_FORMAT_RGBA_8888;
required_format |= (format & COGL_PREMULT_BIT);
break;
/* The following three types of channel ordering
* are always defined using system word byte
* ordering (even according to GLES spec) */
case COGL_PIXEL_FORMAT_RGB_565:
glintformat = GL_RGB;
glformat = GL_RGB;
gltype = GL_UNSIGNED_SHORT_5_6_5;
break;
case COGL_PIXEL_FORMAT_RGBA_4444:
case COGL_PIXEL_FORMAT_RGBA_4444_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_SHORT_4_4_4_4;
break;
case COGL_PIXEL_FORMAT_RGBA_5551:
case COGL_PIXEL_FORMAT_RGBA_5551_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_SHORT_5_5_5_1;
break;
case COGL_PIXEL_FORMAT_ANY:
case COGL_PIXEL_FORMAT_YUV:
g_assert_not_reached ();
break;
}
/* All of the pixel formats are handled above so if this hits then
we've been given an invalid pixel format */
g_assert (glformat != 0);
if (out_glintformat != NULL)
*out_glintformat = glintformat;
if (out_glformat != NULL)
*out_glformat = glformat;
if (out_gltype != NULL)
*out_gltype = gltype;
return required_format;
}
static gboolean
_cogl_driver_update_features (CoglContext *context,
GError **error)
{
CoglPrivateFeatureFlags private_flags = 0;
CoglFeatureFlags flags = 0;
@ -172,3 +282,11 @@ _cogl_gles_update_features (CoglContext *context,
return TRUE;
}
const CoglDriverVtable
_cogl_driver_gles =
{
_cogl_driver_pixel_format_from_gl_internal,
_cogl_driver_pixel_format_to_gl,
_cogl_driver_update_features
};

View File

@ -389,114 +389,6 @@ _cogl_texture_driver_try_setting_gl_border_color (
/* FAIL! */
}
static gboolean
_cogl_texture_driver_pixel_format_from_gl_internal (GLenum gl_int_format,
CoglPixelFormat *out_format)
{
return TRUE;
}
static CoglPixelFormat
_cogl_texture_driver_pixel_format_to_gl (CoglPixelFormat format,
GLenum *out_glintformat,
GLenum *out_glformat,
GLenum *out_gltype)
{
CoglPixelFormat required_format;
GLenum glintformat;
GLenum glformat = 0;
GLenum gltype;
required_format = format;
/* Find GL equivalents */
switch (format)
{
case COGL_PIXEL_FORMAT_A_8:
glintformat = GL_ALPHA;
glformat = GL_ALPHA;
gltype = GL_UNSIGNED_BYTE;
break;
case COGL_PIXEL_FORMAT_G_8:
glintformat = GL_LUMINANCE;
glformat = GL_LUMINANCE;
gltype = GL_UNSIGNED_BYTE;
break;
/* Just one 24-bit ordering supported */
case COGL_PIXEL_FORMAT_RGB_888:
case COGL_PIXEL_FORMAT_BGR_888:
glintformat = GL_RGB;
glformat = GL_RGB;
gltype = GL_UNSIGNED_BYTE;
required_format = COGL_PIXEL_FORMAT_RGB_888;
break;
/* Just one 32-bit ordering supported */
case COGL_PIXEL_FORMAT_RGBA_8888:
case COGL_PIXEL_FORMAT_RGBA_8888_PRE:
case COGL_PIXEL_FORMAT_BGRA_8888:
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
case COGL_PIXEL_FORMAT_ARGB_8888:
case COGL_PIXEL_FORMAT_ARGB_8888_PRE:
case COGL_PIXEL_FORMAT_ABGR_8888:
case COGL_PIXEL_FORMAT_ABGR_8888_PRE:
case COGL_PIXEL_FORMAT_RGBA_1010102:
case COGL_PIXEL_FORMAT_RGBA_1010102_PRE:
case COGL_PIXEL_FORMAT_BGRA_1010102:
case COGL_PIXEL_FORMAT_BGRA_1010102_PRE:
case COGL_PIXEL_FORMAT_ABGR_2101010:
case COGL_PIXEL_FORMAT_ABGR_2101010_PRE:
case COGL_PIXEL_FORMAT_ARGB_2101010:
case COGL_PIXEL_FORMAT_ARGB_2101010_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_BYTE;
required_format = COGL_PIXEL_FORMAT_RGBA_8888;
required_format |= (format & COGL_PREMULT_BIT);
break;
/* The following three types of channel ordering
* are always defined using system word byte
* ordering (even according to GLES spec) */
case COGL_PIXEL_FORMAT_RGB_565:
glintformat = GL_RGB;
glformat = GL_RGB;
gltype = GL_UNSIGNED_SHORT_5_6_5;
break;
case COGL_PIXEL_FORMAT_RGBA_4444:
case COGL_PIXEL_FORMAT_RGBA_4444_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_SHORT_4_4_4_4;
break;
case COGL_PIXEL_FORMAT_RGBA_5551:
case COGL_PIXEL_FORMAT_RGBA_5551_PRE:
glintformat = GL_RGBA;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_SHORT_5_5_5_1;
break;
case COGL_PIXEL_FORMAT_ANY:
case COGL_PIXEL_FORMAT_YUV:
g_assert_not_reached ();
break;
}
/* All of the pixel formats are handled above so if this hits then
we've been given an invalid pixel format */
g_assert (glformat != 0);
if (out_glintformat != NULL)
*out_glintformat = glintformat;
if (out_glformat != NULL)
*out_glformat = glformat;
if (out_gltype != NULL)
*out_gltype = gltype;
return required_format;
}
static gboolean
_cogl_texture_driver_allows_foreign_gl_target (GLenum gl_target)
{
@ -516,10 +408,11 @@ _cogl_texture_driver_gl_generate_mipmaps (GLenum gl_target)
}
static CoglPixelFormat
_cogl_texture_driver_find_best_gl_get_data_format (
CoglPixelFormat format,
GLenum *closest_gl_format,
GLenum *closest_gl_type)
_cogl_texture_driver_find_best_gl_get_data_format
(CoglContext *context,
CoglPixelFormat format,
GLenum *closest_gl_format,
GLenum *closest_gl_type)
{
/* Find closest format that's supported by GL
(Can't use _cogl_pixel_format_to_gl since available formats
@ -542,8 +435,6 @@ _cogl_texture_driver_gles =
_cogl_texture_driver_size_supported,
_cogl_texture_driver_size_supported_3d,
_cogl_texture_driver_try_setting_gl_border_color,
_cogl_texture_driver_pixel_format_from_gl_internal,
_cogl_texture_driver_pixel_format_to_gl,
_cogl_texture_driver_allows_foreign_gl_target,
_cogl_texture_driver_gl_generate_mipmaps,
_cogl_texture_driver_find_best_gl_get_data_format