diff --git a/cogl/Makefile.am b/cogl/Makefile.am index 538fbf397..69cb5df4b 100644 --- a/cogl/Makefile.am +++ b/cogl/Makefile.am @@ -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 \ diff --git a/cogl/cogl-atlas.c b/cogl/cogl-atlas.c index bfa76dcf2..68f48c05e 100644 --- a/cogl/cogl-atlas.c +++ b/cogl/cogl-atlas.c @@ -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 */ diff --git a/cogl/cogl-context-private.h b/cogl/cogl-context-private.h index 6d92faf39..a79672fa5 100644 --- a/cogl/cogl-context-private.h +++ b/cogl/cogl-context-private.h @@ -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 */ diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c index 8b1ea2b8f..8ed310399 100644 --- a/cogl/cogl-context.c +++ b/cogl/cogl-context.c @@ -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 diff --git a/cogl/cogl-driver.h b/cogl/cogl-driver.h new file mode 100644 index 000000000..b68e37a8c --- /dev/null +++ b/cogl/cogl-driver.h @@ -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 . + * + * + */ + +#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 */ + diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c index 74d595f04..647b61df3 100644 --- a/cogl/cogl-framebuffer.c +++ b/cogl/cogl-framebuffer.c @@ -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... */ diff --git a/cogl/cogl-private.h b/cogl/cogl-private.h index 6130c113f..0985ec8b8 100644 --- a/cogl/cogl-private.h +++ b/cogl/cogl-private.h @@ -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); diff --git a/cogl/cogl-texture-2d-sliced.c b/cogl/cogl-texture-2d-sliced.c index 836caaff1..7150d2b2d 100644 --- a/cogl/cogl-texture-2d-sliced.c +++ b/cogl/cogl-texture-2d-sliced.c @@ -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) diff --git a/cogl/cogl-texture-2d.c b/cogl/cogl-texture-2d.c index dad1eaca7..cd0d522bd 100644 --- a/cogl/cogl-texture-2d.c +++ b/cogl/cogl-texture-2d.c @@ -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); diff --git a/cogl/cogl-texture-3d.c b/cogl/cogl-texture-3d.c index 8662d5afd..e33c248d8 100644 --- a/cogl/cogl-texture-3d.c +++ b/cogl/cogl-texture-3d.c @@ -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, diff --git a/cogl/cogl-texture-driver.h b/cogl/cogl-texture-driver.h index 6cbc3afd0..07ccdf858 100644 --- a/cogl/cogl-texture-driver.h +++ b/cogl/cogl-texture-driver.h @@ -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); }; diff --git a/cogl/cogl-texture-rectangle.c b/cogl/cogl-texture-rectangle.c index b906f5878..a7c4ae283 100644 --- a/cogl/cogl-texture-rectangle.c +++ b/cogl/cogl-texture-rectangle.c @@ -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); diff --git a/cogl/cogl-texture.c b/cogl/cogl-texture.c index 6b08ec50d..27cbb64d5 100644 --- a/cogl/cogl-texture.c +++ b/cogl/cogl-texture.c @@ -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); diff --git a/cogl/driver/gl/cogl-gl.c b/cogl/driver/gl/cogl-gl.c index b35ddbef8..6d390339e 100644 --- a/cogl/driver/gl/cogl-gl.c +++ b/cogl/driver/gl/cogl-gl.c @@ -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 + }; diff --git a/cogl/driver/gl/cogl-texture-driver-gl.c b/cogl/driver/gl/cogl-texture-driver-gl.c index 83d47ae5d..373fade9a 100644 --- a/cogl/driver/gl/cogl-texture-driver-gl.c +++ b/cogl/driver/gl/cogl-texture-driver-gl.c @@ -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 diff --git a/cogl/driver/gles/cogl-gles.c b/cogl/driver/gles/cogl-gles.c index 8087ae0e4..d4c596879 100644 --- a/cogl/driver/gles/cogl-gles.c +++ b/cogl/driver/gles/cogl-gles.c @@ -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 + }; diff --git a/cogl/driver/gles/cogl-texture-driver-gles.c b/cogl/driver/gles/cogl-texture-driver-gles.c index 2bc596b32..ad1c248b4 100644 --- a/cogl/driver/gles/cogl-texture-driver-gles.c +++ b/cogl/driver/gles/cogl-texture-driver-gles.c @@ -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