mirror of
https://github.com/brl/mutter.git
synced 2024-12-24 12:02:04 +00:00
Improve cogl-texture maintainability by moving 90% into cogl/common
This splits the limited components that differed between cogl/{gl,gles}/cogl-texture.c into new {gl,gles}/cogl-texture-driver.c files and the rest that can now be shared into cogl/common/cogl-texture.c
This commit is contained in:
parent
4f5e6b77d5
commit
739b460c7a
@ -84,6 +84,9 @@ libclutter_cogl_common_la_SOURCES = \
|
|||||||
cogl-blend-string.c \
|
cogl-blend-string.c \
|
||||||
cogl-blend-string.h \
|
cogl-blend-string.h \
|
||||||
cogl-debug.c \
|
cogl-debug.c \
|
||||||
|
cogl-texture-private.h \
|
||||||
|
cogl-texture-driver.h \
|
||||||
|
cogl-texture.c \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
EXTRA_DIST = stb_image.c cogl-enum-types.h.in cogl-enum-types.c.in
|
EXTRA_DIST = stb_image.c cogl-enum-types.h.in cogl-enum-types.c.in
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#define __COGL_INTERNAL_H
|
#define __COGL_INTERNAL_H
|
||||||
|
|
||||||
#include "cogl-debug.h"
|
#include "cogl-debug.h"
|
||||||
|
#include "cogl-types.h"
|
||||||
|
|
||||||
#ifdef HAVE_COGL_GLES2
|
#ifdef HAVE_COGL_GLES2
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
157
common/cogl-texture-driver.h
Normal file
157
common/cogl-texture-driver.h
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007,2008,2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __COGL_TEXTURE_DRIVER_H
|
||||||
|
#define __COGL_TEXTURE_DRIVER_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Basically just a wrapper around glBindTexture, but the GLES2 backend
|
||||||
|
* for example also wants to know about the internal format so it can
|
||||||
|
* identify when alpha only textures are bound.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_bind (GLenum gl_target, GLuint gl_handle, GLenum gl_intformat);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This sets up the glPixelStore state for an upload to a destination with
|
||||||
|
* the same size, and with no offset.
|
||||||
|
*/
|
||||||
|
/* NB: GLES can't upload a sub region of pixel data from a larger source
|
||||||
|
* buffer which is why this interface is limited. The GL driver has a more
|
||||||
|
* flexible version of this function that is uses internally */
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_prep_gl_for_pixels_upload (int pixels_rowstride,
|
||||||
|
int pixels_bpp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This uploads a sub-region from source_bmp to a single GL texture handle (i.e
|
||||||
|
* a single CoglTexture slice)
|
||||||
|
*
|
||||||
|
* It also updates the array of tex->first_pixels[slice_index] if
|
||||||
|
* dst_{x,y} == 0
|
||||||
|
*
|
||||||
|
* The driver abstraction is in place because GLES doesn't support the pixel
|
||||||
|
* store options required to source from a subregion, so for GLES we have
|
||||||
|
* to manually create a transient source bitmap.
|
||||||
|
*
|
||||||
|
* XXX: sorry for the ridiculous number of arguments :-(
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_upload_subregion_to_gl (CoglTexture *tex,
|
||||||
|
int src_x,
|
||||||
|
int src_y,
|
||||||
|
int dst_x,
|
||||||
|
int dst_y,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
CoglBitmap *source_bmp,
|
||||||
|
GLuint source_gl_format,
|
||||||
|
GLuint source_gl_type,
|
||||||
|
GLuint gl_handle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This sets up the glPixelStore state for an download to a destination with
|
||||||
|
* the same size, and with no offset.
|
||||||
|
*/
|
||||||
|
/* NB: GLES can't download pixel data into a sub region of a larger destination
|
||||||
|
* buffer, the GL driver has a more flexible version of this function that it
|
||||||
|
* uses internally. */
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_prep_gl_for_pixels_download (int pixels_rowstride,
|
||||||
|
int pixels_bpp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This driver abstraction is in place because GLES doesn't have a sane way to
|
||||||
|
* download data from a texture so you litterally render the texture to the
|
||||||
|
* backbuffer, and retrive the data using glReadPixels :-(
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_driver_download_from_gl (CoglTexture *tex,
|
||||||
|
CoglBitmap *target_bmp,
|
||||||
|
GLuint target_gl_format,
|
||||||
|
GLuint target_gl_type);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* It may depend on the driver as to what texture sizes are supported...
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_driver_size_supported (GLenum gl_target,
|
||||||
|
GLenum gl_format,
|
||||||
|
GLenum gl_type,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This driver abstraction is needed because GLES doesn't support setting
|
||||||
|
* a texture border color.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_try_setting_gl_border_color (
|
||||||
|
GLuint gl_target,
|
||||||
|
const GLfloat *transparent_color);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX: this should live in cogl/{gl,gles}/cogl.c
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
_cogl_pixel_format_from_gl_internal (GLenum gl_int_format,
|
||||||
|
CoglPixelFormat *out_format);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XXX: this should live in cogl/{gl,gles}/cogl.c
|
||||||
|
*/
|
||||||
|
CoglPixelFormat
|
||||||
|
_cogl_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
|
||||||
|
* but GLES doesn't
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_driver_allows_foreign_gl_target (GLenum gl_target);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* glGenerateMipmap semantics may need to be emulated for some drivers. E.g. by
|
||||||
|
* enabling auto mipmap generation an re-loading a number of known texels.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_gl_generate_mipmaps (GLenum texture_target);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The driver may impose constraints on what formats can be used to store
|
||||||
|
* texture data read from textures. For example GLES currently only supports
|
||||||
|
* RGBA_8888, and so we need to manually convert the data if the final
|
||||||
|
* destination has another format.
|
||||||
|
*/
|
||||||
|
CoglPixelFormat
|
||||||
|
_cogl_texture_driver_find_best_gl_get_data_format (
|
||||||
|
CoglPixelFormat format,
|
||||||
|
GLenum *closest_gl_format,
|
||||||
|
GLenum *closest_gl_type);
|
||||||
|
|
||||||
|
#endif /* __COGL_TEXTURE_DRIVER_H */
|
||||||
|
|
@ -21,8 +21,8 @@
|
|||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __COGL_TEXTURE_H
|
#ifndef __COGL_TEXTURE_PRIVATE_H
|
||||||
#define __COGL_TEXTURE_H
|
#define __COGL_TEXTURE_PRIVATE_H
|
||||||
|
|
||||||
#include "cogl-bitmap-private.h"
|
#include "cogl-bitmap-private.h"
|
||||||
#include "cogl-handle.h"
|
#include "cogl-handle.h"
|
||||||
@ -142,4 +142,10 @@ _cogl_span_iter_end (CoglSpanIter *iter);
|
|||||||
void
|
void
|
||||||
_cogl_span_iter_next (CoglSpanIter *iter);
|
_cogl_span_iter_next (CoglSpanIter *iter);
|
||||||
|
|
||||||
#endif /* __COGL_TEXTURE_H */
|
void
|
||||||
|
_cogl_texture_prep_gl_alignment_for_pixels_upload (int pixels_rowstride);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_prep_gl_alignment_for_pixels_download (int pixels_rowstride);
|
||||||
|
|
||||||
|
#endif /* __COGL_TEXTURE_PRIVATE_H */
|
@ -36,6 +36,7 @@
|
|||||||
#include "cogl-bitmap.h"
|
#include "cogl-bitmap.h"
|
||||||
#include "cogl-bitmap-private.h"
|
#include "cogl-bitmap-private.h"
|
||||||
#include "cogl-texture-private.h"
|
#include "cogl-texture-private.h"
|
||||||
|
#include "cogl-texture-driver.h"
|
||||||
#include "cogl-material.h"
|
#include "cogl-material.h"
|
||||||
#include "cogl-context.h"
|
#include "cogl-context.h"
|
||||||
#include "cogl-handle.h"
|
#include "cogl-handle.h"
|
||||||
@ -45,22 +46,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#ifdef HAVE_COGL_GL
|
|
||||||
|
|
||||||
#define glDrawRangeElements ctx->pf_glDrawRangeElements
|
|
||||||
#define glActiveTexture ctx->pf_glActiveTexture
|
|
||||||
#define glClientActiveTexture ctx->pf_glClientActiveTexture
|
|
||||||
#define glGenerateMipmap ctx->pf_glGenerateMipmapEXT
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* GLES doesn't have glDrawRangeElements, so we simply pretend it does
|
|
||||||
* but that it makes no use of the start, end constraints: */
|
|
||||||
#define glDrawRangeElements(mode, start, end, count, type, indices) \
|
|
||||||
glDrawElements (mode, count, type, indices)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void _cogl_texture_free (CoglTexture *tex);
|
static void _cogl_texture_free (CoglTexture *tex);
|
||||||
|
|
||||||
COGL_HANDLE_DEFINE (Texture, texture);
|
COGL_HANDLE_DEFINE (Texture, texture);
|
||||||
@ -162,17 +147,9 @@ _cogl_span_iter_end (CoglSpanIter *iter)
|
|||||||
return iter->pos >= iter->cover_end;
|
return iter->pos >= iter->cover_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
prep_for_gl_pixels_upload (gint pixels_rowstride,
|
_cogl_texture_prep_gl_alignment_for_pixels_upload (int pixels_rowstride)
|
||||||
gint pixels_src_x,
|
|
||||||
gint pixels_src_y,
|
|
||||||
gint pixels_bpp)
|
|
||||||
{
|
{
|
||||||
GE( glPixelStorei (GL_UNPACK_ROW_LENGTH, pixels_rowstride / pixels_bpp) );
|
|
||||||
|
|
||||||
GE( glPixelStorei (GL_UNPACK_SKIP_PIXELS, pixels_src_x) );
|
|
||||||
GE( glPixelStorei (GL_UNPACK_SKIP_ROWS, pixels_src_y) );
|
|
||||||
|
|
||||||
if (!(pixels_rowstride & 0x7))
|
if (!(pixels_rowstride & 0x7))
|
||||||
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 8) );
|
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 8) );
|
||||||
else if (!(pixels_rowstride & 0x3))
|
else if (!(pixels_rowstride & 0x3))
|
||||||
@ -183,17 +160,9 @@ prep_for_gl_pixels_upload (gint pixels_rowstride,
|
|||||||
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 1) );
|
GE( glPixelStorei (GL_UNPACK_ALIGNMENT, 1) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
prep_for_gl_pixels_download (gint pixels_rowstride,
|
_cogl_texture_prep_gl_alignment_for_pixels_download (int pixels_rowstride)
|
||||||
gint pixels_src_x,
|
|
||||||
gint pixels_src_y,
|
|
||||||
gint pixels_bpp)
|
|
||||||
{
|
{
|
||||||
GE( glPixelStorei (GL_PACK_ROW_LENGTH, pixels_rowstride / pixels_bpp) );
|
|
||||||
|
|
||||||
GE( glPixelStorei (GL_PACK_SKIP_PIXELS, pixels_src_x) );
|
|
||||||
GE( glPixelStorei (GL_PACK_SKIP_ROWS, pixels_src_y) );
|
|
||||||
|
|
||||||
if (!(pixels_rowstride & 0x7))
|
if (!(pixels_rowstride & 0x7))
|
||||||
GE( glPixelStorei (GL_PACK_ALIGNMENT, 8) );
|
GE( glPixelStorei (GL_PACK_ALIGNMENT, 8) );
|
||||||
else if (!(pixels_rowstride & 0x3))
|
else if (!(pixels_rowstride & 0x3))
|
||||||
@ -262,11 +231,18 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
|||||||
/* Pick the gl texture object handle */
|
/* Pick the gl texture object handle */
|
||||||
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, slice_num);
|
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, slice_num);
|
||||||
|
|
||||||
/* Setup gl alignment to match rowstride and top-left corner */
|
_cogl_texture_driver_upload_subregion_to_gl (
|
||||||
prep_for_gl_pixels_upload (tex->bitmap.rowstride,
|
tex,
|
||||||
x_span->start,
|
x_span->start, /* src x */
|
||||||
y_span->start,
|
y_span->start, /* src y */
|
||||||
bpp);
|
0, /* dst x */
|
||||||
|
0, /* dst y */
|
||||||
|
x_span->size - x_span->waste, /* width */
|
||||||
|
y_span->size - y_span->waste, /* height */
|
||||||
|
&tex->bitmap,
|
||||||
|
tex->gl_format,
|
||||||
|
tex->gl_type,
|
||||||
|
gl_handle);
|
||||||
|
|
||||||
/* Keep a copy of the first pixel if needed */
|
/* Keep a copy of the first pixel if needed */
|
||||||
if (tex->first_pixels)
|
if (tex->first_pixels)
|
||||||
@ -279,17 +255,6 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
|||||||
tex->first_pixels[slice_num].gl_type = tex->gl_type;
|
tex->first_pixels[slice_num].gl_type = tex->gl_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Upload new image data */
|
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
x_span->size - x_span->waste,
|
|
||||||
y_span->size - y_span->waste,
|
|
||||||
tex->gl_format, tex->gl_type,
|
|
||||||
tex->bitmap.data) );
|
|
||||||
|
|
||||||
/* Fill the waste with a copies of the rightmost pixels */
|
/* Fill the waste with a copies of the rightmost pixels */
|
||||||
if (x_span->waste > 0)
|
if (x_span->waste > 0)
|
||||||
{
|
{
|
||||||
@ -309,10 +274,9 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
|||||||
src += tex->bitmap.rowstride;
|
src += tex->bitmap.rowstride;
|
||||||
}
|
}
|
||||||
|
|
||||||
prep_for_gl_pixels_upload (x_span->waste * bpp,
|
_cogl_texture_driver_prep_gl_for_pixels_upload (
|
||||||
0, /* src x */
|
x_span->waste * bpp,
|
||||||
0, /* src y */
|
bpp);
|
||||||
bpp);
|
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||||
x_span->size - x_span->waste,
|
x_span->size - x_span->waste,
|
||||||
@ -344,10 +308,9 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prep_for_gl_pixels_upload (x_span->size * bpp,
|
_cogl_texture_driver_prep_gl_for_pixels_upload (
|
||||||
0, /* src x */
|
x_span->size * bpp,
|
||||||
0, /* src y */
|
bpp);
|
||||||
bpp);
|
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||||
0,
|
0,
|
||||||
@ -368,95 +331,6 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_cogl_texture_download_from_gl (CoglTexture *tex,
|
|
||||||
CoglBitmap *target_bmp,
|
|
||||||
GLuint target_gl_format,
|
|
||||||
GLuint target_gl_type)
|
|
||||||
{
|
|
||||||
CoglTexSliceSpan *x_span;
|
|
||||||
CoglTexSliceSpan *y_span;
|
|
||||||
GLuint gl_handle;
|
|
||||||
gint bpp;
|
|
||||||
gint x,y;
|
|
||||||
CoglBitmap slice_bmp;
|
|
||||||
|
|
||||||
bpp = _cogl_get_format_bpp (target_bmp->format);
|
|
||||||
|
|
||||||
/* Iterate vertical slices */
|
|
||||||
for (y = 0; y < tex->slice_y_spans->len; ++y)
|
|
||||||
{
|
|
||||||
y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan, y);
|
|
||||||
|
|
||||||
/* Iterate horizontal slices */
|
|
||||||
for (x = 0; x < tex->slice_x_spans->len; ++x)
|
|
||||||
{
|
|
||||||
/*if (x != 0 || y != 1) continue;*/
|
|
||||||
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, x);
|
|
||||||
|
|
||||||
/* Pick the gl texture object handle */
|
|
||||||
gl_handle = g_array_index (tex->slice_gl_handles, GLuint,
|
|
||||||
y * tex->slice_x_spans->len + x);
|
|
||||||
|
|
||||||
/* If there's any waste we need to copy manually
|
|
||||||
(no glGetTexSubImage) */
|
|
||||||
|
|
||||||
if (y_span->waste != 0 || x_span->waste != 0)
|
|
||||||
{
|
|
||||||
/* Setup temp bitmap for slice subregion */
|
|
||||||
slice_bmp.format = target_bmp->format;
|
|
||||||
slice_bmp.width = x_span->size;
|
|
||||||
slice_bmp.height = y_span->size;
|
|
||||||
slice_bmp.rowstride = bpp * slice_bmp.width;
|
|
||||||
slice_bmp.data = (guchar*) g_malloc (slice_bmp.rowstride *
|
|
||||||
slice_bmp.height);
|
|
||||||
|
|
||||||
/* Setup gl alignment to 0,0 top-left corner */
|
|
||||||
prep_for_gl_pixels_download (slice_bmp.rowstride, 0, 0, bpp);
|
|
||||||
|
|
||||||
/* Download slice image data into temp bmp */
|
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
|
||||||
|
|
||||||
GE (glGetTexImage (tex->gl_target,
|
|
||||||
0, /* level */
|
|
||||||
target_gl_format,
|
|
||||||
target_gl_type,
|
|
||||||
slice_bmp.data) );
|
|
||||||
|
|
||||||
/* Copy portion of slice from temp to target bmp */
|
|
||||||
_cogl_bitmap_copy_subregion (&slice_bmp,
|
|
||||||
target_bmp,
|
|
||||||
0, 0,
|
|
||||||
x_span->start,
|
|
||||||
y_span->start,
|
|
||||||
x_span->size - x_span->waste,
|
|
||||||
y_span->size - y_span->waste);
|
|
||||||
/* Free temp bitmap */
|
|
||||||
g_free (slice_bmp.data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GLvoid *dst = target_bmp->data
|
|
||||||
+ x_span->start * bpp
|
|
||||||
+ y_span->start * target_bmp->rowstride;
|
|
||||||
|
|
||||||
prep_for_gl_pixels_download (target_bmp->rowstride, 0, 0, bpp);
|
|
||||||
|
|
||||||
/* Download slice image data */
|
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
|
||||||
|
|
||||||
GE( glGetTexImage (tex->gl_target,
|
|
||||||
0, /* level */
|
|
||||||
target_gl_format,
|
|
||||||
target_gl_type,
|
|
||||||
dst) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
_cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
||||||
gint src_x,
|
gint src_x,
|
||||||
@ -529,27 +403,29 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
x_iter.index);
|
x_iter.index);
|
||||||
|
|
||||||
/* Pick intersection width and height */
|
/* Pick intersection width and height */
|
||||||
inter_w = (x_iter.intersect_end -
|
inter_w = (x_iter.intersect_end - x_iter.intersect_start);
|
||||||
x_iter.intersect_start);
|
inter_h = (y_iter.intersect_end - y_iter.intersect_start);
|
||||||
inter_h = (y_iter.intersect_end -
|
|
||||||
y_iter.intersect_start);
|
|
||||||
|
|
||||||
/* Localize intersection top-left corner to slice*/
|
/* Localize intersection top-left corner to slice*/
|
||||||
local_x = (x_iter.intersect_start -
|
local_x = (x_iter.intersect_start - x_iter.pos);
|
||||||
x_iter.pos);
|
local_y = (y_iter.intersect_start - y_iter.pos);
|
||||||
local_y = (y_iter.intersect_start -
|
|
||||||
y_iter.pos);
|
|
||||||
|
|
||||||
slice_num = y_iter.index * tex->slice_x_spans->len + x_iter.index;
|
slice_num = y_iter.index * tex->slice_x_spans->len + x_iter.index;
|
||||||
|
|
||||||
/* Pick slice GL handle */
|
/* Pick slice GL handle */
|
||||||
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, slice_num);
|
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, slice_num);
|
||||||
|
|
||||||
/* Setup gl alignment to match rowstride and top-left corner */
|
_cogl_texture_driver_upload_subregion_to_gl (tex,
|
||||||
prep_for_gl_pixels_upload (source_bmp->rowstride,
|
source_x,
|
||||||
source_x,
|
source_y,
|
||||||
source_y,
|
local_x, /* dst x */
|
||||||
bpp);
|
local_y, /* dst x */
|
||||||
|
inter_w, /* width */
|
||||||
|
inter_h, /* height */
|
||||||
|
source_bmp,
|
||||||
|
source_gl_format,
|
||||||
|
source_gl_type,
|
||||||
|
gl_handle);
|
||||||
|
|
||||||
/* Keep a copy of the first pixel if needed */
|
/* Keep a copy of the first pixel if needed */
|
||||||
if (tex->first_pixels && local_x == 0 && local_y == 0)
|
if (tex->first_pixels && local_x == 0 && local_y == 0)
|
||||||
@ -562,16 +438,6 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
tex->first_pixels[slice_num].gl_type = source_gl_type;
|
tex->first_pixels[slice_num].gl_type = source_gl_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Upload new image data */
|
|
||||||
GE( glBindTexture (tex->gl_target, gl_handle) );
|
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
|
||||||
local_x, local_y,
|
|
||||||
inter_w, inter_h,
|
|
||||||
source_gl_format,
|
|
||||||
source_gl_type,
|
|
||||||
source_bmp->data) );
|
|
||||||
|
|
||||||
/* If the x_span is sliced and the upload touches the
|
/* If the x_span is sliced and the upload touches the
|
||||||
rightmost pixels then fill the waste with copies of the
|
rightmost pixels then fill the waste with copies of the
|
||||||
pixels */
|
pixels */
|
||||||
@ -603,10 +469,9 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
src += source_bmp->rowstride;
|
src += source_bmp->rowstride;
|
||||||
}
|
}
|
||||||
|
|
||||||
prep_for_gl_pixels_upload (x_span->waste * bpp,
|
_cogl_texture_driver_prep_gl_for_pixels_upload (
|
||||||
0, /* src x */
|
x_span->waste * bpp,
|
||||||
0, /* src y */
|
bpp);
|
||||||
bpp);
|
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||||
x_span->size - x_span->waste,
|
x_span->size - x_span->waste,
|
||||||
@ -655,10 +520,9 @@ _cogl_texture_upload_subregion_to_gl (CoglTexture *tex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prep_for_gl_pixels_upload (copy_width * bpp,
|
_cogl_texture_driver_prep_gl_for_pixels_upload (
|
||||||
0, /* src x */
|
copy_width * bpp,
|
||||||
0, /* src y */
|
bpp);
|
||||||
bpp);
|
|
||||||
|
|
||||||
GE( glTexSubImage2D (tex->gl_target, 0,
|
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||||
local_x,
|
local_x,
|
||||||
@ -739,7 +603,9 @@ _cogl_pot_slices_for_size (gint size_to_fill,
|
|||||||
if (size_to_fill > span.size)
|
if (size_to_fill > span.size)
|
||||||
{
|
{
|
||||||
/* Not yet - add a span of this size */
|
/* Not yet - add a span of this size */
|
||||||
if (out_spans) g_array_append_val (out_spans, span);
|
if (out_spans)
|
||||||
|
g_array_append_val (out_spans, span);
|
||||||
|
|
||||||
span.start += span.size;
|
span.start += span.size;
|
||||||
size_to_fill -= span.size;
|
size_to_fill -= span.size;
|
||||||
n_spans++;
|
n_spans++;
|
||||||
@ -748,7 +614,9 @@ _cogl_pot_slices_for_size (gint size_to_fill,
|
|||||||
{
|
{
|
||||||
/* Yes and waste is small enough */
|
/* Yes and waste is small enough */
|
||||||
span.waste = span.size - size_to_fill;
|
span.waste = span.size - size_to_fill;
|
||||||
if (out_spans) g_array_append_val (out_spans, span);
|
if (out_spans)
|
||||||
|
g_array_append_val (out_spans, span);
|
||||||
|
|
||||||
return ++n_spans;
|
return ++n_spans;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -766,35 +634,6 @@ _cogl_pot_slices_for_size (gint size_to_fill,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_cogl_texture_size_supported (GLenum gl_target,
|
|
||||||
GLenum gl_format,
|
|
||||||
GLenum gl_type,
|
|
||||||
int width,
|
|
||||||
int height)
|
|
||||||
{
|
|
||||||
if (gl_target == GL_TEXTURE_2D)
|
|
||||||
{
|
|
||||||
/* Proxy texture allows for a quick check for supported size */
|
|
||||||
|
|
||||||
GLint new_width = 0;
|
|
||||||
|
|
||||||
GE( glTexImage2D (GL_PROXY_TEXTURE_2D, 0, GL_RGBA,
|
|
||||||
width, height, 0 /* border */,
|
|
||||||
gl_format, gl_type, NULL) );
|
|
||||||
|
|
||||||
GE( glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0,
|
|
||||||
GL_TEXTURE_WIDTH, &new_width) );
|
|
||||||
|
|
||||||
return new_width != 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* not used */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_cogl_texture_set_wrap_mode_parameter (CoglTexture *tex,
|
_cogl_texture_set_wrap_mode_parameter (CoglTexture *tex,
|
||||||
GLenum wrap_mode)
|
GLenum wrap_mode)
|
||||||
@ -863,11 +702,11 @@ _cogl_texture_slices_create (CoglTexture *tex)
|
|||||||
CoglTexSliceSpan span;
|
CoglTexSliceSpan span;
|
||||||
|
|
||||||
/* Check if size supported else bail out */
|
/* Check if size supported else bail out */
|
||||||
if (!_cogl_texture_size_supported (tex->gl_target,
|
if (!_cogl_texture_driver_size_supported (tex->gl_target,
|
||||||
tex->gl_format,
|
tex->gl_format,
|
||||||
tex->gl_type,
|
tex->gl_type,
|
||||||
max_width,
|
max_width,
|
||||||
max_height))
|
max_height))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -897,11 +736,11 @@ _cogl_texture_slices_create (CoglTexture *tex)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Decrease the size of largest slice until supported by GL */
|
/* Decrease the size of largest slice until supported by GL */
|
||||||
while (!_cogl_texture_size_supported (tex->gl_target,
|
while (!_cogl_texture_driver_size_supported (tex->gl_target,
|
||||||
tex->gl_format,
|
tex->gl_format,
|
||||||
tex->gl_type,
|
tex->gl_type,
|
||||||
max_width,
|
max_width,
|
||||||
max_height))
|
max_height))
|
||||||
{
|
{
|
||||||
/* Alternate between width and height */
|
/* Alternate between width and height */
|
||||||
if (max_width > max_height)
|
if (max_width > max_height)
|
||||||
@ -951,7 +790,7 @@ _cogl_texture_slices_create (CoglTexture *tex)
|
|||||||
g_array_set_size (tex->slice_gl_handles, n_slices);
|
g_array_set_size (tex->slice_gl_handles, n_slices);
|
||||||
|
|
||||||
/* Allocate some space to store a copy of the first pixel of each
|
/* Allocate some space to store a copy of the first pixel of each
|
||||||
slice. This is only needed to glGenerateMipmap (which is part of
|
slice. This is only needed if glGenerateMipmap (which is part of
|
||||||
the FBO extension) is not available */
|
the FBO extension) is not available */
|
||||||
if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
|
if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
|
||||||
tex->first_pixels = NULL;
|
tex->first_pixels = NULL;
|
||||||
@ -984,14 +823,12 @@ _cogl_texture_slices_create (CoglTexture *tex)
|
|||||||
y_span->size - y_span->waste);
|
y_span->size - y_span->waste);
|
||||||
|
|
||||||
/* Setup texture parameters */
|
/* Setup texture parameters */
|
||||||
GE( glBindTexture (tex->gl_target,
|
GE( _cogl_texture_driver_bind (tex->gl_target,
|
||||||
gl_handles[y * n_x_slices + x]) );
|
gl_handles[y * n_x_slices + x],
|
||||||
|
tex->gl_intformat) );
|
||||||
|
|
||||||
/* Use a transparent border color so that we can leave the
|
_cogl_texture_driver_try_setting_gl_border_color (tex->gl_target,
|
||||||
color buffer alone when using texture co-ordinates
|
transparent_color);
|
||||||
outside of the texture */
|
|
||||||
GE( glTexParameterfv (tex->gl_target, GL_TEXTURE_BORDER_COLOR,
|
|
||||||
transparent_color) );
|
|
||||||
|
|
||||||
/* Pass NULL data to init size and internal format */
|
/* Pass NULL data to init size and internal format */
|
||||||
GE( glTexImage2D (tex->gl_target, 0, tex->gl_intformat,
|
GE( glTexImage2D (tex->gl_target, 0, tex->gl_intformat,
|
||||||
@ -1041,153 +878,6 @@ _cogl_texture_span_has_waste (CoglTexture *tex,
|
|||||||
return (x_span->waste || y_span->waste) ? TRUE : FALSE;
|
return (x_span->waste || y_span->waste) ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
_cogl_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_pixel_format_to_gl (CoglPixelFormat format,
|
|
||||||
GLenum *out_glintformat,
|
|
||||||
GLenum *out_glformat,
|
|
||||||
GLenum *out_gltype)
|
|
||||||
{
|
|
||||||
CoglPixelFormat required_format;
|
|
||||||
GLenum glintformat = 0;
|
|
||||||
GLenum glformat = 0;
|
|
||||||
GLenum gltype = 0;
|
|
||||||
|
|
||||||
/* FIXME: check YUV support */
|
|
||||||
|
|
||||||
required_format = format;
|
|
||||||
|
|
||||||
/* Find GL equivalents */
|
|
||||||
switch (format & COGL_UNPREMULT_MASK)
|
|
||||||
{
|
|
||||||
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:
|
|
||||||
glintformat = GL_RGBA;
|
|
||||||
glformat = GL_RGBA;
|
|
||||||
gltype = GL_UNSIGNED_BYTE;
|
|
||||||
break;
|
|
||||||
case COGL_PIXEL_FORMAT_BGRA_8888:
|
|
||||||
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:
|
|
||||||
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:
|
|
||||||
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;
|
|
||||||
|
|
||||||
/* 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:
|
|
||||||
glintformat = GL_RGBA;
|
|
||||||
glformat = GL_RGBA;
|
|
||||||
gltype = GL_UNSIGNED_SHORT_4_4_4_4;
|
|
||||||
break;
|
|
||||||
case COGL_PIXEL_FORMAT_RGBA_5551:
|
|
||||||
glintformat = GL_RGBA;
|
|
||||||
glformat = GL_RGBA;
|
|
||||||
gltype = GL_UNSIGNED_SHORT_5_5_5_1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* FIXME: check extensions for YUV support */
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
static gboolean
|
||||||
_cogl_texture_bitmap_prepare (CoglTexture *tex,
|
_cogl_texture_bitmap_prepare (CoglTexture *tex,
|
||||||
CoglPixelFormat internal_format)
|
CoglPixelFormat internal_format)
|
||||||
@ -1496,14 +1186,7 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
|||||||
CoglTexSliceSpan x_span;
|
CoglTexSliceSpan x_span;
|
||||||
CoglTexSliceSpan y_span;
|
CoglTexSliceSpan y_span;
|
||||||
|
|
||||||
/* GL_ARB_texture_rectangle textures are supported if they are
|
if (!_cogl_texture_driver_allows_foreign_gl_target (gl_target))
|
||||||
created from foreign because some chipsets have trouble with
|
|
||||||
GL_ARB_texture_non_power_of_two. There is no Cogl call to create
|
|
||||||
them directly to emphasize the fact that they don't work fully
|
|
||||||
(for example, no mipmapping and complicated shader support) */
|
|
||||||
|
|
||||||
/* Allow 2-dimensional or rectangle textures only */
|
|
||||||
if (gl_target != GL_TEXTURE_2D && gl_target != CGL_TEXTURE_RECTANGLE_ARB)
|
|
||||||
return COGL_INVALID_HANDLE;
|
return COGL_INVALID_HANDLE;
|
||||||
|
|
||||||
/* Make sure it is a valid GL texture object */
|
/* Make sure it is a valid GL texture object */
|
||||||
@ -1520,6 +1203,7 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
|||||||
/* Obtain texture parameters
|
/* Obtain texture parameters
|
||||||
(only level 0 we are interested in) */
|
(only level 0 we are interested in) */
|
||||||
|
|
||||||
|
#if HAVE_COGL_GL
|
||||||
GE( glGetTexLevelParameteriv (gl_target, 0,
|
GE( glGetTexLevelParameteriv (gl_target, 0,
|
||||||
GL_TEXTURE_COMPRESSED,
|
GL_TEXTURE_COMPRESSED,
|
||||||
&gl_compressed) );
|
&gl_compressed) );
|
||||||
@ -1536,6 +1220,10 @@ cogl_texture_new_from_foreign (GLuint gl_handle,
|
|||||||
GE( glGetTexLevelParameteriv (gl_target, 0,
|
GE( glGetTexLevelParameteriv (gl_target, 0,
|
||||||
GL_TEXTURE_HEIGHT,
|
GL_TEXTURE_HEIGHT,
|
||||||
&gl_height) );
|
&gl_height) );
|
||||||
|
#else
|
||||||
|
gl_width = width + x_pot_waste;
|
||||||
|
gl_height = height + y_pot_waste;
|
||||||
|
#endif
|
||||||
|
|
||||||
GE( glGetTexParameteriv (gl_target,
|
GE( glGetTexParameteriv (gl_target,
|
||||||
GL_GENERATE_MIPMAP,
|
GL_GENERATE_MIPMAP,
|
||||||
@ -1796,7 +1484,7 @@ _cogl_texture_ensure_mipmaps (CoglHandle handle)
|
|||||||
|
|
||||||
/* glGenerateMipmap is defined in the FBO extension */
|
/* glGenerateMipmap is defined in the FBO extension */
|
||||||
if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
|
if (cogl_features_available (COGL_FEATURE_OFFSCREEN))
|
||||||
GE( glGenerateMipmap (tex->gl_target) );
|
_cogl_texture_driver_gl_generate_mipmaps (tex->gl_target);
|
||||||
else if (tex->first_pixels)
|
else if (tex->first_pixels)
|
||||||
{
|
{
|
||||||
CoglTexturePixel *pixel = tex->first_pixels + i;
|
CoglTexturePixel *pixel = tex->first_pixels + i;
|
||||||
@ -1935,12 +1623,10 @@ cogl_texture_get_data (CoglHandle handle,
|
|||||||
byte_size = tex->bitmap.height * rowstride;
|
byte_size = tex->bitmap.height * rowstride;
|
||||||
if (data == NULL) return byte_size;
|
if (data == NULL) return byte_size;
|
||||||
|
|
||||||
/* Find closest format that's supported by GL */
|
closest_format =
|
||||||
closest_format = _cogl_pixel_format_to_gl (format,
|
_cogl_texture_driver_find_best_gl_get_data_format (format,
|
||||||
NULL, /* don't need */
|
&closest_gl_format,
|
||||||
&closest_gl_format,
|
&closest_gl_type);
|
||||||
&closest_gl_type);
|
|
||||||
|
|
||||||
closest_bpp = _cogl_get_format_bpp (closest_format);
|
closest_bpp = _cogl_get_format_bpp (closest_format);
|
||||||
|
|
||||||
/* Is the requested format supported? */
|
/* Is the requested format supported? */
|
||||||
@ -1963,9 +1649,9 @@ cogl_texture_get_data (CoglHandle handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve data from slices */
|
/* Retrieve data from slices */
|
||||||
_cogl_texture_download_from_gl (tex, &target_bmp,
|
_cogl_texture_driver_download_from_gl (tex, &target_bmp,
|
||||||
closest_gl_format,
|
closest_gl_format,
|
||||||
closest_gl_type);
|
closest_gl_type);
|
||||||
|
|
||||||
/* Was intermediate used? */
|
/* Was intermediate used? */
|
||||||
if (closest_format != format)
|
if (closest_format != format)
|
@ -20,7 +20,6 @@ cogl_headers = \
|
|||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
cogl_priv_headers = \
|
cogl_priv_headers = \
|
||||||
cogl-texture-private.h \
|
|
||||||
cogl-fbo.h \
|
cogl-fbo.h \
|
||||||
cogl-shader-private.h \
|
cogl-shader-private.h \
|
||||||
cogl-program.h \
|
cogl-program.h \
|
||||||
@ -30,7 +29,7 @@ cogl_priv_headers = \
|
|||||||
cogl_sources = \
|
cogl_sources = \
|
||||||
cogl.c \
|
cogl.c \
|
||||||
cogl-primitives.c \
|
cogl-primitives.c \
|
||||||
cogl-texture.c \
|
cogl-texture-driver.c \
|
||||||
cogl-fbo.c \
|
cogl-fbo.c \
|
||||||
cogl-shader.c \
|
cogl-shader.c \
|
||||||
cogl-program.c \
|
cogl-program.c \
|
||||||
|
454
gl/cogl-texture-driver.c
Normal file
454
gl/cogl-texture-driver.c
Normal file
@ -0,0 +1,454 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007,2008,2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Matthew Allum <mallum@openedhand.com>
|
||||||
|
* Neil Roberts <neil@linux.intel.com>
|
||||||
|
* Robert Bragg <robert@linux.intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "cogl.h"
|
||||||
|
#include "cogl-internal.h"
|
||||||
|
#include "cogl-util.h"
|
||||||
|
#include "cogl-bitmap.h"
|
||||||
|
#include "cogl-bitmap-private.h"
|
||||||
|
#include "cogl-texture-private.h"
|
||||||
|
#include "cogl-material.h"
|
||||||
|
#include "cogl-context.h"
|
||||||
|
#include "cogl-handle.h"
|
||||||
|
#include "cogl-primitives.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#define glGenerateMipmap ctx->pf_glGenerateMipmapEXT
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_bind (GLenum gl_target,
|
||||||
|
GLuint gl_handle,
|
||||||
|
GLenum gl_intformat)
|
||||||
|
{
|
||||||
|
GE (glBindTexture (gl_target, gl_handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OpenGL - unlike GLES - can upload a sub region of pixel data from a larger
|
||||||
|
* source buffer */
|
||||||
|
static void
|
||||||
|
prep_gl_for_pixels_upload_full (int pixels_rowstride,
|
||||||
|
int pixels_src_x,
|
||||||
|
int pixels_src_y,
|
||||||
|
int pixels_bpp)
|
||||||
|
{
|
||||||
|
GE( glPixelStorei (GL_UNPACK_ROW_LENGTH, pixels_rowstride / pixels_bpp) );
|
||||||
|
|
||||||
|
GE( glPixelStorei (GL_UNPACK_SKIP_PIXELS, pixels_src_x) );
|
||||||
|
GE( glPixelStorei (GL_UNPACK_SKIP_ROWS, pixels_src_y) );
|
||||||
|
|
||||||
|
_cogl_texture_prep_gl_alignment_for_pixels_upload (pixels_rowstride);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_prep_gl_for_pixels_upload (int pixels_rowstride,
|
||||||
|
int pixels_bpp)
|
||||||
|
{
|
||||||
|
prep_gl_for_pixels_upload_full (pixels_rowstride, 0, 0, pixels_bpp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OpenGL - unlike GLES - can download pixel data into a sub region of
|
||||||
|
* a larger destination buffer */
|
||||||
|
static void
|
||||||
|
prep_gl_for_pixels_download_full (int pixels_rowstride,
|
||||||
|
int pixels_src_x,
|
||||||
|
int pixels_src_y,
|
||||||
|
int pixels_bpp)
|
||||||
|
{
|
||||||
|
GE( glPixelStorei (GL_PACK_ROW_LENGTH, pixels_rowstride / pixels_bpp) );
|
||||||
|
|
||||||
|
GE( glPixelStorei (GL_PACK_SKIP_PIXELS, pixels_src_x) );
|
||||||
|
GE( glPixelStorei (GL_PACK_SKIP_ROWS, pixels_src_y) );
|
||||||
|
|
||||||
|
_cogl_texture_prep_gl_alignment_for_pixels_download (pixels_rowstride);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_prep_gl_for_pixels_download (int pixels_rowstride,
|
||||||
|
int pixels_bpp)
|
||||||
|
{
|
||||||
|
prep_gl_for_pixels_download_full (pixels_rowstride, 0, 0, pixels_bpp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_upload_subregion_to_gl (CoglTexture *tex,
|
||||||
|
int src_x,
|
||||||
|
int src_y,
|
||||||
|
int dst_x,
|
||||||
|
int dst_y,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
CoglBitmap *source_bmp,
|
||||||
|
GLuint source_gl_format,
|
||||||
|
GLuint source_gl_type,
|
||||||
|
GLuint gl_handle)
|
||||||
|
{
|
||||||
|
int bpp = _cogl_get_format_bpp (source_bmp->format);
|
||||||
|
|
||||||
|
/* Setup gl alignment to match rowstride and top-left corner */
|
||||||
|
prep_gl_for_pixels_upload_full (source_bmp->rowstride,
|
||||||
|
src_x,
|
||||||
|
src_y,
|
||||||
|
bpp);
|
||||||
|
|
||||||
|
/* Upload new image data */
|
||||||
|
GE( _cogl_texture_driver_bind (tex->gl_target,
|
||||||
|
gl_handle, tex->gl_intformat) );
|
||||||
|
|
||||||
|
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||||
|
dst_x, dst_y,
|
||||||
|
width, height,
|
||||||
|
source_gl_format,
|
||||||
|
source_gl_type,
|
||||||
|
source_bmp->data) );
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_driver_download_from_gl (CoglTexture *tex,
|
||||||
|
CoglBitmap *target_bmp,
|
||||||
|
GLuint target_gl_format,
|
||||||
|
GLuint target_gl_type)
|
||||||
|
{
|
||||||
|
CoglTexSliceSpan *x_span;
|
||||||
|
CoglTexSliceSpan *y_span;
|
||||||
|
GLuint gl_handle;
|
||||||
|
gint bpp;
|
||||||
|
gint x,y;
|
||||||
|
CoglBitmap slice_bmp;
|
||||||
|
|
||||||
|
bpp = _cogl_get_format_bpp (target_bmp->format);
|
||||||
|
|
||||||
|
/* Iterate vertical slices */
|
||||||
|
for (y = 0; y < tex->slice_y_spans->len; ++y)
|
||||||
|
{
|
||||||
|
y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan, y);
|
||||||
|
|
||||||
|
/* Iterate horizontal slices */
|
||||||
|
for (x = 0; x < tex->slice_x_spans->len; ++x)
|
||||||
|
{
|
||||||
|
/*if (x != 0 || y != 1) continue;*/
|
||||||
|
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, x);
|
||||||
|
|
||||||
|
/* Pick the gl texture object handle */
|
||||||
|
gl_handle = g_array_index (tex->slice_gl_handles, GLuint,
|
||||||
|
y * tex->slice_x_spans->len + x);
|
||||||
|
|
||||||
|
/* If there's any waste we need to copy manually
|
||||||
|
(no glGetTexSubImage) */
|
||||||
|
|
||||||
|
if (y_span->waste != 0 || x_span->waste != 0)
|
||||||
|
{
|
||||||
|
/* Setup temp bitmap for slice subregion */
|
||||||
|
slice_bmp.format = target_bmp->format;
|
||||||
|
slice_bmp.width = x_span->size;
|
||||||
|
slice_bmp.height = y_span->size;
|
||||||
|
slice_bmp.rowstride = bpp * slice_bmp.width;
|
||||||
|
slice_bmp.data = (guchar*) g_malloc (slice_bmp.rowstride *
|
||||||
|
slice_bmp.height);
|
||||||
|
|
||||||
|
/* Setup gl alignment to 0,0 top-left corner */
|
||||||
|
_cogl_texture_driver_prep_gl_for_pixels_download (
|
||||||
|
slice_bmp.rowstride,
|
||||||
|
bpp);
|
||||||
|
|
||||||
|
/* Download slice image data into temp bmp */
|
||||||
|
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||||
|
|
||||||
|
GE (glGetTexImage (tex->gl_target,
|
||||||
|
0, /* level */
|
||||||
|
target_gl_format,
|
||||||
|
target_gl_type,
|
||||||
|
slice_bmp.data) );
|
||||||
|
|
||||||
|
/* Copy portion of slice from temp to target bmp */
|
||||||
|
_cogl_bitmap_copy_subregion (&slice_bmp,
|
||||||
|
target_bmp,
|
||||||
|
0, 0,
|
||||||
|
x_span->start,
|
||||||
|
y_span->start,
|
||||||
|
x_span->size - x_span->waste,
|
||||||
|
y_span->size - y_span->waste);
|
||||||
|
/* Free temp bitmap */
|
||||||
|
g_free (slice_bmp.data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GLvoid *dst = target_bmp->data
|
||||||
|
+ x_span->start * bpp
|
||||||
|
+ y_span->start * target_bmp->rowstride;
|
||||||
|
|
||||||
|
_cogl_texture_driver_prep_gl_for_pixels_download (
|
||||||
|
target_bmp->rowstride,
|
||||||
|
bpp);
|
||||||
|
|
||||||
|
/* Download slice image data */
|
||||||
|
GE( glBindTexture (tex->gl_target, gl_handle) );
|
||||||
|
|
||||||
|
GE( glGetTexImage (tex->gl_target,
|
||||||
|
0, /* level */
|
||||||
|
target_gl_format,
|
||||||
|
target_gl_type,
|
||||||
|
dst) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_driver_size_supported (GLenum gl_target,
|
||||||
|
GLenum gl_format,
|
||||||
|
GLenum gl_type,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
if (gl_target == GL_TEXTURE_2D)
|
||||||
|
{
|
||||||
|
/* Proxy texture allows for a quick check for supported size */
|
||||||
|
|
||||||
|
GLint new_width = 0;
|
||||||
|
|
||||||
|
GE( glTexImage2D (GL_PROXY_TEXTURE_2D, 0, GL_RGBA,
|
||||||
|
width, height, 0 /* border */,
|
||||||
|
gl_format, gl_type, NULL) );
|
||||||
|
|
||||||
|
GE( glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0,
|
||||||
|
GL_TEXTURE_WIDTH, &new_width) );
|
||||||
|
|
||||||
|
return new_width != 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* not used */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_try_setting_gl_border_color (
|
||||||
|
GLuint gl_target,
|
||||||
|
const GLfloat *transparent_color)
|
||||||
|
{
|
||||||
|
/* Use a transparent border color so that we can leave the
|
||||||
|
color buffer alone when using texture co-ordinates
|
||||||
|
outside of the texture */
|
||||||
|
GE( glTexParameterfv (gl_target, GL_TEXTURE_BORDER_COLOR,
|
||||||
|
transparent_color) );
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglPixelFormat
|
||||||
|
_cogl_pixel_format_to_gl (CoglPixelFormat format,
|
||||||
|
GLenum *out_glintformat,
|
||||||
|
GLenum *out_glformat,
|
||||||
|
GLenum *out_gltype)
|
||||||
|
{
|
||||||
|
CoglPixelFormat required_format;
|
||||||
|
GLenum glintformat = 0;
|
||||||
|
GLenum glformat = 0;
|
||||||
|
GLenum gltype = 0;
|
||||||
|
|
||||||
|
/* FIXME: check YUV support */
|
||||||
|
|
||||||
|
required_format = format;
|
||||||
|
|
||||||
|
/* Find GL equivalents */
|
||||||
|
switch (format & COGL_UNPREMULT_MASK)
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
glintformat = GL_RGBA;
|
||||||
|
glformat = GL_RGBA;
|
||||||
|
gltype = GL_UNSIGNED_BYTE;
|
||||||
|
break;
|
||||||
|
case COGL_PIXEL_FORMAT_BGRA_8888:
|
||||||
|
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:
|
||||||
|
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:
|
||||||
|
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;
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
glintformat = GL_RGBA;
|
||||||
|
glformat = GL_RGBA;
|
||||||
|
gltype = GL_UNSIGNED_SHORT_4_4_4_4;
|
||||||
|
break;
|
||||||
|
case COGL_PIXEL_FORMAT_RGBA_5551:
|
||||||
|
glintformat = GL_RGBA;
|
||||||
|
glformat = GL_RGBA;
|
||||||
|
gltype = GL_UNSIGNED_SHORT_5_5_5_1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* FIXME: check extensions for YUV support */
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out_glintformat != NULL)
|
||||||
|
*out_glintformat = glintformat;
|
||||||
|
if (out_glformat != NULL)
|
||||||
|
*out_glformat = glformat;
|
||||||
|
if (out_gltype != NULL)
|
||||||
|
*out_gltype = gltype;
|
||||||
|
|
||||||
|
return required_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_driver_allows_foreign_gl_target (GLenum gl_target)
|
||||||
|
{
|
||||||
|
/* GL_ARB_texture_rectangle textures are supported if they are
|
||||||
|
created from foreign because some chipsets have trouble with
|
||||||
|
GL_ARB_texture_non_power_of_two. There is no Cogl call to create
|
||||||
|
them directly to emphasize the fact that they don't work fully
|
||||||
|
(for example, no mipmapping and complicated shader support) */
|
||||||
|
|
||||||
|
/* Allow 2-dimensional or rectangle textures only */
|
||||||
|
if (gl_target != GL_TEXTURE_2D && gl_target != CGL_TEXTURE_RECTANGLE_ARB)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_gl_generate_mipmaps (GLenum gl_target)
|
||||||
|
{
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
GE( glGenerateMipmap (gl_target) );
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglPixelFormat
|
||||||
|
_cogl_texture_driver_find_best_gl_get_data_format (
|
||||||
|
CoglPixelFormat format,
|
||||||
|
GLenum *closest_gl_format,
|
||||||
|
GLenum *closest_gl_type)
|
||||||
|
{
|
||||||
|
/* Find closest format that's supported by GL */
|
||||||
|
return _cogl_pixel_format_to_gl (format,
|
||||||
|
NULL, /* don't need */
|
||||||
|
closest_gl_format,
|
||||||
|
closest_gl_type);
|
||||||
|
}
|
||||||
|
|
@ -48,12 +48,11 @@ libclutter_cogl_gles_la_SOURCES = \
|
|||||||
$(top_builddir)/clutter/cogl/cogl-texture.h \
|
$(top_builddir)/clutter/cogl/cogl-texture.h \
|
||||||
$(top_builddir)/clutter/cogl/cogl-types.h \
|
$(top_builddir)/clutter/cogl/cogl-types.h \
|
||||||
$(top_builddir)/clutter/cogl/cogl-debug.h \
|
$(top_builddir)/clutter/cogl/cogl-debug.h \
|
||||||
cogl-texture-private.h \
|
|
||||||
cogl-fbo.h \
|
cogl-fbo.h \
|
||||||
cogl-context.h \
|
cogl-context.h \
|
||||||
cogl.c \
|
cogl.c \
|
||||||
cogl-primitives.c \
|
cogl-primitives.c \
|
||||||
cogl-texture.c \
|
cogl-texture-driver.c \
|
||||||
cogl-fbo.c \
|
cogl-fbo.c \
|
||||||
cogl-context.c \
|
cogl-context.c \
|
||||||
cogl-gles2-wrapper.h \
|
cogl-gles2-wrapper.h \
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#ifndef __COGL_GLES2_WRAPPER_H__
|
#ifndef __COGL_GLES2_WRAPPER_H__
|
||||||
#define __COGL_GLES2_WRAPPER_H__
|
#define __COGL_GLES2_WRAPPER_H__
|
||||||
|
|
||||||
|
#include "cogl.h" /* needed for gl header include */
|
||||||
#include "cogl-internal.h"
|
#include "cogl-internal.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
481
gles/cogl-texture-driver.c
Normal file
481
gles/cogl-texture-driver.c
Normal file
@ -0,0 +1,481 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007,2008,2009 Intel Corporation.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Matthew Allum <mallum@openedhand.com>
|
||||||
|
* Neil Roberts <neil@linux.intel.com>
|
||||||
|
* Robert Bragg <robert@linux.intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "cogl.h"
|
||||||
|
#include "cogl-internal.h"
|
||||||
|
#include "cogl-util.h"
|
||||||
|
#include "cogl-bitmap.h"
|
||||||
|
#include "cogl-bitmap-private.h"
|
||||||
|
#include "cogl-texture-private.h"
|
||||||
|
#include "cogl-material.h"
|
||||||
|
#include "cogl-context.h"
|
||||||
|
#include "cogl-handle.h"
|
||||||
|
#include "cogl-primitives.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "cogl-gles2-wrapper.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_bind (GLenum gl_target,
|
||||||
|
GLuint gl_handle,
|
||||||
|
GLenum gl_intformat)
|
||||||
|
{
|
||||||
|
GE (cogl_gles2_wrapper_bind_texture (gl_target, gl_handle, gl_intformat));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_prep_gl_for_pixels_upload (int pixels_rowstride,
|
||||||
|
int pixels_bpp)
|
||||||
|
{
|
||||||
|
_cogl_texture_prep_gl_alignment_for_pixels_upload (pixels_rowstride);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_prep_gl_for_pixels_download (int pixels_rowstride,
|
||||||
|
int pixels_bpp)
|
||||||
|
{
|
||||||
|
_cogl_texture_prep_gl_alignment_for_pixels_download (pixels_rowstride);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_upload_subregion_to_gl (CoglTexture *tex,
|
||||||
|
int src_x,
|
||||||
|
int src_y,
|
||||||
|
int dst_x,
|
||||||
|
int dst_y,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
CoglBitmap *source_bmp,
|
||||||
|
GLuint source_gl_format,
|
||||||
|
GLuint source_gl_type,
|
||||||
|
GLuint gl_handle)
|
||||||
|
{
|
||||||
|
int bpp = _cogl_get_format_bpp (source_bmp->format);
|
||||||
|
CoglBitmap slice_bmp;
|
||||||
|
|
||||||
|
/* NB: GLES doesn't support the GL_UNPACK_ROW_LENGTH, GL_UNPACK_SKIP_PIXELS
|
||||||
|
* or GL_UNPACK_SKIP_ROWS pixel store options so we can't directly source a
|
||||||
|
* sub-region from source_bmp, we need to use a transient bitmap instead. */
|
||||||
|
|
||||||
|
/* FIXME: optimize by not copying to intermediate slice bitmap when source
|
||||||
|
* rowstride = bpp * width and the texture image is not sliced */
|
||||||
|
|
||||||
|
/* Setup temp bitmap for slice subregion */
|
||||||
|
slice_bmp.format = tex->bitmap.format;
|
||||||
|
slice_bmp.width = width;
|
||||||
|
slice_bmp.height = height;
|
||||||
|
slice_bmp.rowstride = bpp * slice_bmp.width;
|
||||||
|
slice_bmp.data = (guchar*) g_malloc (slice_bmp.rowstride * slice_bmp.height);
|
||||||
|
|
||||||
|
/* Setup gl alignment to match rowstride and top-left corner */
|
||||||
|
_cogl_texture_driver_prep_gl_for_pixels_upload (slice_bmp.rowstride,
|
||||||
|
bpp);
|
||||||
|
|
||||||
|
/* Copy subregion data */
|
||||||
|
_cogl_bitmap_copy_subregion (source_bmp,
|
||||||
|
&slice_bmp,
|
||||||
|
src_x,
|
||||||
|
src_y,
|
||||||
|
0, 0,
|
||||||
|
slice_bmp.width,
|
||||||
|
slice_bmp.height);
|
||||||
|
|
||||||
|
/* Upload new image data */
|
||||||
|
GE( _cogl_texture_driver_bind (tex->gl_target,
|
||||||
|
gl_handle, tex->gl_intformat) );
|
||||||
|
|
||||||
|
GE( glTexSubImage2D (tex->gl_target, 0,
|
||||||
|
dst_x, dst_y,
|
||||||
|
width, height,
|
||||||
|
source_gl_format,
|
||||||
|
source_gl_type,
|
||||||
|
slice_bmp.data) );
|
||||||
|
|
||||||
|
/* Free temp bitmap */
|
||||||
|
g_free (slice_bmp.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_cogl_texture_draw_and_read (CoglTexture *tex,
|
||||||
|
CoglBitmap *target_bmp,
|
||||||
|
GLint *viewport)
|
||||||
|
{
|
||||||
|
gint bpp;
|
||||||
|
float rx1, ry1;
|
||||||
|
float rx2, ry2;
|
||||||
|
float tx1, ty1;
|
||||||
|
float tx2, ty2;
|
||||||
|
int bw, bh;
|
||||||
|
CoglBitmap rect_bmp;
|
||||||
|
CoglHandle handle;
|
||||||
|
|
||||||
|
handle = (CoglHandle) tex;
|
||||||
|
bpp = _cogl_get_format_bpp (COGL_PIXEL_FORMAT_RGBA_8888);
|
||||||
|
|
||||||
|
ry1 = 0; ry2 = 0;
|
||||||
|
ty1 = 0; ty2 = 0;
|
||||||
|
|
||||||
|
/* Walk Y axis until whole bitmap height consumed */
|
||||||
|
for (bh = tex->bitmap.height; bh > 0; bh -= viewport[3])
|
||||||
|
{
|
||||||
|
/* Rectangle Y coords */
|
||||||
|
ry1 = ry2;
|
||||||
|
ry2 += (bh < viewport[3]) ? bh : viewport[3];
|
||||||
|
|
||||||
|
/* Normalized texture Y coords */
|
||||||
|
ty1 = ty2;
|
||||||
|
ty2 = (ry2 / (float)tex->bitmap.height);
|
||||||
|
|
||||||
|
rx1 = 0; rx2 = 0;
|
||||||
|
tx1 = 0; tx2 = 0;
|
||||||
|
|
||||||
|
/* Walk X axis until whole bitmap width consumed */
|
||||||
|
for (bw = tex->bitmap.width; bw > 0; bw-=viewport[2])
|
||||||
|
{
|
||||||
|
/* Rectangle X coords */
|
||||||
|
rx1 = rx2;
|
||||||
|
rx2 += (bw < viewport[2]) ? bw : viewport[2];
|
||||||
|
|
||||||
|
/* Normalized texture X coords */
|
||||||
|
tx1 = tx2;
|
||||||
|
tx2 = (rx2 / (float)tex->bitmap.width);
|
||||||
|
|
||||||
|
/* Draw a portion of texture */
|
||||||
|
cogl_rectangle_with_texture_coords (0, 0,
|
||||||
|
rx2 - rx1,
|
||||||
|
ry2 - ry1,
|
||||||
|
tx1, ty1,
|
||||||
|
tx2, ty2);
|
||||||
|
|
||||||
|
/* Read into a temporary bitmap */
|
||||||
|
rect_bmp.format = COGL_PIXEL_FORMAT_RGBA_8888;
|
||||||
|
rect_bmp.width = rx2 - rx1;
|
||||||
|
rect_bmp.height = ry2 - ry1;
|
||||||
|
rect_bmp.rowstride = bpp * rect_bmp.width;
|
||||||
|
rect_bmp.data = (guchar*) g_malloc (rect_bmp.rowstride *
|
||||||
|
rect_bmp.height);
|
||||||
|
|
||||||
|
_cogl_texture_driver_prep_gl_for_pixels_download (rect_bmp.rowstride,
|
||||||
|
bpp);
|
||||||
|
GE( glReadPixels (viewport[0], viewport[1],
|
||||||
|
rect_bmp.width,
|
||||||
|
rect_bmp.height,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE,
|
||||||
|
rect_bmp.data) );
|
||||||
|
|
||||||
|
/* Copy to target bitmap */
|
||||||
|
_cogl_bitmap_copy_subregion (&rect_bmp,
|
||||||
|
target_bmp,
|
||||||
|
0,0,
|
||||||
|
rx1,ry1,
|
||||||
|
rect_bmp.width,
|
||||||
|
rect_bmp.height);
|
||||||
|
|
||||||
|
/* Free temp bitmap */
|
||||||
|
g_free (rect_bmp.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_driver_download_from_gl (CoglTexture *tex,
|
||||||
|
CoglBitmap *target_bmp,
|
||||||
|
GLuint target_gl_format,
|
||||||
|
GLuint target_gl_type)
|
||||||
|
{
|
||||||
|
gint bpp;
|
||||||
|
GLint viewport[4];
|
||||||
|
CoglBitmap alpha_bmp;
|
||||||
|
CoglHandle prev_source;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, FALSE);
|
||||||
|
|
||||||
|
|
||||||
|
bpp = _cogl_get_format_bpp (COGL_PIXEL_FORMAT_RGBA_8888);
|
||||||
|
|
||||||
|
/* Viewport needs to have some size and be inside the window for this */
|
||||||
|
GE( glGetIntegerv (GL_VIEWPORT, viewport) );
|
||||||
|
|
||||||
|
if (viewport[0] < 0 || viewport[1] < 0 ||
|
||||||
|
viewport[2] <= 0 || viewport[3] <= 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Setup orthographic projection into current viewport
|
||||||
|
(0,0 in bottom-left corner to draw the texture
|
||||||
|
upside-down so we match the way glReadPixels works) */
|
||||||
|
|
||||||
|
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
|
||||||
|
_cogl_current_matrix_push ();
|
||||||
|
_cogl_current_matrix_identity ();
|
||||||
|
|
||||||
|
_cogl_current_matrix_ortho (0, (float)(viewport[2]),
|
||||||
|
0, (float)(viewport[3]),
|
||||||
|
(float)(0),
|
||||||
|
(float)(100));
|
||||||
|
|
||||||
|
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
|
||||||
|
_cogl_current_matrix_push ();
|
||||||
|
_cogl_current_matrix_identity ();
|
||||||
|
|
||||||
|
/* Direct copy operation */
|
||||||
|
|
||||||
|
if (ctx->texture_download_material == COGL_INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
ctx->texture_download_material = cogl_material_new ();
|
||||||
|
cogl_material_set_blend (ctx->texture_download_material,
|
||||||
|
"RGBA = ADD (SRC_COLOR, 0)",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_source = cogl_handle_ref (ctx->source_material);
|
||||||
|
cogl_set_source (ctx->texture_download_material);
|
||||||
|
|
||||||
|
cogl_material_set_layer (ctx->texture_download_material, 0, tex);
|
||||||
|
|
||||||
|
cogl_material_set_layer_combine (ctx->texture_download_material,
|
||||||
|
0, /* layer */
|
||||||
|
"RGBA = REPLACE (TEXTURE)",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
_cogl_texture_draw_and_read (tex, target_bmp, viewport);
|
||||||
|
|
||||||
|
/* Check whether texture has alpha and framebuffer not */
|
||||||
|
/* FIXME: For some reason even if ALPHA_BITS is 8, the framebuffer
|
||||||
|
still doesn't seem to have an alpha buffer. This might be just
|
||||||
|
a PowerVR issue.
|
||||||
|
GLint r_bits, g_bits, b_bits, a_bits;
|
||||||
|
GE( glGetIntegerv (GL_ALPHA_BITS, &a_bits) );
|
||||||
|
GE( glGetIntegerv (GL_RED_BITS, &r_bits) );
|
||||||
|
GE( glGetIntegerv (GL_GREEN_BITS, &g_bits) );
|
||||||
|
GE( glGetIntegerv (GL_BLUE_BITS, &b_bits) );
|
||||||
|
printf ("R bits: %d\n", r_bits);
|
||||||
|
printf ("G bits: %d\n", g_bits);
|
||||||
|
printf ("B bits: %d\n", b_bits);
|
||||||
|
printf ("A bits: %d\n", a_bits); */
|
||||||
|
if ((tex->bitmap.format & COGL_A_BIT)/* && a_bits == 0*/)
|
||||||
|
{
|
||||||
|
guchar *srcdata;
|
||||||
|
guchar *dstdata;
|
||||||
|
guchar *srcpixel;
|
||||||
|
guchar *dstpixel;
|
||||||
|
gint x,y;
|
||||||
|
|
||||||
|
/* Create temp bitmap for alpha values */
|
||||||
|
alpha_bmp.format = COGL_PIXEL_FORMAT_RGBA_8888;
|
||||||
|
alpha_bmp.width = target_bmp->width;
|
||||||
|
alpha_bmp.height = target_bmp->height;
|
||||||
|
alpha_bmp.rowstride = bpp * alpha_bmp.width;
|
||||||
|
alpha_bmp.data = (guchar*) g_malloc (alpha_bmp.rowstride *
|
||||||
|
alpha_bmp.height);
|
||||||
|
|
||||||
|
/* Draw alpha values into RGB channels */
|
||||||
|
cogl_material_set_layer_combine (ctx->texture_download_material,
|
||||||
|
0, /* layer */
|
||||||
|
"RGBA = REPLACE (TEXTURE[A])",
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
_cogl_texture_draw_and_read (tex, &alpha_bmp, viewport);
|
||||||
|
|
||||||
|
/* Copy temp R to target A */
|
||||||
|
srcdata = alpha_bmp.data;
|
||||||
|
dstdata = target_bmp->data;
|
||||||
|
|
||||||
|
for (y=0; y<target_bmp->height; ++y)
|
||||||
|
{
|
||||||
|
for (x=0; x<target_bmp->width; ++x)
|
||||||
|
{
|
||||||
|
srcpixel = srcdata + x*bpp;
|
||||||
|
dstpixel = dstdata + x*bpp;
|
||||||
|
dstpixel[3] = srcpixel[0];
|
||||||
|
}
|
||||||
|
srcdata += alpha_bmp.rowstride;
|
||||||
|
dstdata += target_bmp->rowstride;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (alpha_bmp.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore old state */
|
||||||
|
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
|
||||||
|
_cogl_current_matrix_pop ();
|
||||||
|
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
|
||||||
|
_cogl_current_matrix_pop ();
|
||||||
|
|
||||||
|
/* restore the original material */
|
||||||
|
cogl_set_source (prev_source);
|
||||||
|
cogl_handle_unref (prev_source);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_driver_size_supported (GLenum gl_target,
|
||||||
|
GLenum gl_format,
|
||||||
|
GLenum gl_type,
|
||||||
|
int width,
|
||||||
|
int height)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_try_setting_gl_border_color (
|
||||||
|
GLuint gl_target,
|
||||||
|
const GLfloat *transparent_color)
|
||||||
|
{
|
||||||
|
/* FAIL! */
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_pixel_format_from_gl_internal (GLenum gl_int_format,
|
||||||
|
CoglPixelFormat *out_format)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglPixelFormat
|
||||||
|
_cogl_pixel_format_to_gl (CoglPixelFormat format,
|
||||||
|
GLenum *out_glintformat,
|
||||||
|
GLenum *out_glformat,
|
||||||
|
GLenum *out_gltype)
|
||||||
|
{
|
||||||
|
CoglPixelFormat required_format;
|
||||||
|
GLenum glintformat = 0;
|
||||||
|
GLenum glformat = 0;
|
||||||
|
GLenum gltype = 0;
|
||||||
|
|
||||||
|
/* FIXME: check YUV support */
|
||||||
|
|
||||||
|
required_format = format;
|
||||||
|
|
||||||
|
/* Find GL equivalents */
|
||||||
|
switch (format & COGL_UNPREMULT_MASK)
|
||||||
|
{
|
||||||
|
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_BGRA_8888:
|
||||||
|
case COGL_PIXEL_FORMAT_ARGB_8888:
|
||||||
|
case COGL_PIXEL_FORMAT_ABGR_8888:
|
||||||
|
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:
|
||||||
|
glintformat = GL_RGBA;
|
||||||
|
glformat = GL_RGBA;
|
||||||
|
gltype = GL_UNSIGNED_SHORT_4_4_4_4;
|
||||||
|
break;
|
||||||
|
case COGL_PIXEL_FORMAT_RGBA_5551:
|
||||||
|
glintformat = GL_RGBA;
|
||||||
|
glformat = GL_RGBA;
|
||||||
|
gltype = GL_UNSIGNED_SHORT_5_5_5_1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* FIXME: check extensions for YUV support */
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (out_glintformat != NULL)
|
||||||
|
*out_glintformat = glintformat;
|
||||||
|
if (out_glformat != NULL)
|
||||||
|
*out_glformat = glformat;
|
||||||
|
if (out_gltype != NULL)
|
||||||
|
*out_gltype = gltype;
|
||||||
|
|
||||||
|
return required_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_texture_driver_allows_foreign_gl_target (GLenum gl_target)
|
||||||
|
{
|
||||||
|
/* Allow 2-dimensional textures only */
|
||||||
|
if (gl_target != GL_TEXTURE_2D)
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_texture_driver_gl_generate_mipmaps (GLenum gl_target)
|
||||||
|
{
|
||||||
|
GE( cogl_wrap_glGenerateMipmap (gl_target) );
|
||||||
|
}
|
||||||
|
|
||||||
|
CoglPixelFormat
|
||||||
|
_cogl_texture_driver_find_best_gl_get_data_format (
|
||||||
|
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
|
||||||
|
when reading pixels on GLES are severely limited) */
|
||||||
|
*closest_gl_format = GL_RGBA;
|
||||||
|
*closest_gl_type = GL_UNSIGNED_BYTE;
|
||||||
|
return COGL_PIXEL_FORMAT_RGBA_8888;
|
||||||
|
}
|
||||||
|
|
@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
* Cogl
|
|
||||||
*
|
|
||||||
* An object oriented GL/GLES Abstraction/Utility Layer
|
|
||||||
*
|
|
||||||
* Copyright (C) 2007,2008,2009 Intel Corporation.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the
|
|
||||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
||||||
* Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __COGL_TEXTURE_H
|
|
||||||
#define __COGL_TEXTURE_H
|
|
||||||
|
|
||||||
#include "cogl-bitmap-private.h"
|
|
||||||
#include "cogl-material-private.h"
|
|
||||||
#include "cogl-handle.h"
|
|
||||||
|
|
||||||
typedef struct _CoglTexture CoglTexture;
|
|
||||||
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
|
|
||||||
typedef struct _CoglSpanIter CoglSpanIter;
|
|
||||||
typedef struct _CoglTexturePixel CoglTexturePixel;
|
|
||||||
|
|
||||||
struct _CoglTexSliceSpan
|
|
||||||
{
|
|
||||||
gint start;
|
|
||||||
gint size;
|
|
||||||
gint waste;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _CoglSpanIter
|
|
||||||
{
|
|
||||||
gint index;
|
|
||||||
GArray *array;
|
|
||||||
CoglTexSliceSpan *span;
|
|
||||||
float pos;
|
|
||||||
float next_pos;
|
|
||||||
float origin;
|
|
||||||
float cover_start;
|
|
||||||
float cover_end;
|
|
||||||
float intersect_start;
|
|
||||||
float intersect_end;
|
|
||||||
float intersect_start_local;
|
|
||||||
float intersect_end_local;
|
|
||||||
gboolean intersects;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This is used to store the first pixel of each slice. This is only
|
|
||||||
used when glGenerateMipmap is not available */
|
|
||||||
struct _CoglTexturePixel
|
|
||||||
{
|
|
||||||
/* We need to store the format of the pixel because we store the
|
|
||||||
data in the source format which might end up being different for
|
|
||||||
each slice if a subregion is updated with a different format */
|
|
||||||
GLenum gl_format;
|
|
||||||
GLenum gl_type;
|
|
||||||
guint8 data[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct _CoglTexture
|
|
||||||
{
|
|
||||||
CoglHandleObject _parent;
|
|
||||||
CoglBitmap bitmap;
|
|
||||||
gboolean bitmap_owner;
|
|
||||||
GLenum gl_target;
|
|
||||||
GLenum gl_intformat;
|
|
||||||
GLenum gl_format;
|
|
||||||
GLenum gl_type;
|
|
||||||
GArray *slice_x_spans;
|
|
||||||
GArray *slice_y_spans;
|
|
||||||
GArray *slice_gl_handles;
|
|
||||||
gint max_waste;
|
|
||||||
GLenum min_filter;
|
|
||||||
GLenum mag_filter;
|
|
||||||
gboolean is_foreign;
|
|
||||||
GLint wrap_mode;
|
|
||||||
gboolean auto_mipmap;
|
|
||||||
gboolean mipmaps_dirty;
|
|
||||||
|
|
||||||
/* This holds a copy of the first pixel in each slice. It is only
|
|
||||||
used to force an automatic update of the mipmaps when
|
|
||||||
glGenerateMipmap is not available. */
|
|
||||||
CoglTexturePixel *first_pixels;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* To improve batching of geometry when submitting vertices to OpenGL we
|
|
||||||
* log the texture rectangles we want to draw to a journal, so when we
|
|
||||||
* later flush the journal we aim to batch data, and gl draw calls. */
|
|
||||||
typedef struct _CoglJournalEntry
|
|
||||||
{
|
|
||||||
CoglHandle material;
|
|
||||||
gint n_layers;
|
|
||||||
guint32 fallback_mask;
|
|
||||||
GLuint layer0_override_texture;
|
|
||||||
CoglMatrix model_view;
|
|
||||||
CoglMaterialFlushOptions flush_options;
|
|
||||||
} CoglJournalEntry;
|
|
||||||
|
|
||||||
CoglTexture*
|
|
||||||
_cogl_texture_pointer_from_handle (CoglHandle handle);
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_texture_set_wrap_mode_parameter (CoglTexture *tex,
|
|
||||||
GLenum wrap_mode);
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_texture_set_filters (CoglHandle handle,
|
|
||||||
GLenum min_filter,
|
|
||||||
GLenum mag_filter);
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_texture_ensure_mipmaps (CoglHandle handle);
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
_cogl_texture_span_has_waste (CoglTexture *tex,
|
|
||||||
gint x_span_index,
|
|
||||||
gint y_span_index);
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_span_iter_begin (CoglSpanIter *iter,
|
|
||||||
GArray *array,
|
|
||||||
float origin,
|
|
||||||
float cover_start,
|
|
||||||
float cover_end);
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
_cogl_span_iter_end (CoglSpanIter *iter);
|
|
||||||
|
|
||||||
void
|
|
||||||
_cogl_span_iter_next (CoglSpanIter *iter);
|
|
||||||
|
|
||||||
#endif /* __COGL_TEXTURE_H */
|
|
2066
gles/cogl-texture.c
2066
gles/cogl-texture.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user