Commit Graph

81 Commits

Author SHA1 Message Date
Neil Roberts
ccc3068ffd cogl-bitmap: Encapsulate the CoglBitmap even internally
The CoglBitmap struct is now only defined within cogl-bitmap.c so that
all of its members can now only be accessed with accessor
functions. To get to the data pointer for the bitmap image you must
first call _cogl_bitmap_map and later call _cogl_bitmap_unmap. The map
function takes the same arguments as cogl_pixel_array_map so that
eventually we can make a bitmap optionally internally divert to a
pixel array.

There is a _cogl_bitmap_new_from_data function which constructs a new
bitmap object and takes ownership of the data pointer. The function
gets passed a destroy callback which gets called when the bitmap is
freed. This is similar to how gdk_pixbuf_new_from_data
works. Alternatively NULL can be passed for the destroy function which
means that the caller will manage the life of the pointer (but must
guarantee that it stays alive at least until the bitmap is
freed). This mechanism is used instead of the old approach of creating
a CoglBitmap struct on the stack and manually filling in the
members. It could also later be used to create a CoglBitmap that owns
a GdkPixbuf ref so that we don't necessarily have to copy the
GdkPixbuf data when converting to a bitmap.

There is also _cogl_bitmap_new_shared. This creates a bitmap using a
reference to another CoglBitmap for the data. This is a bit of a hack
but it is needed by the atlas texture backend which wants to divert
the set_region virtual to another texture but it needs to override the
format of the bitmap to ignore the premult flag.
2010-07-15 17:24:01 +01:00
Robert Bragg
5442e429ba material: split the texture unit management out
In general cogl-material.c has become far to large to manage in one
source file. As one of the ways to try and break it down this patch
starts to move some of lower level texture unit state management out
into cogl-material-opengl.c. The naming is such because the plan is to
follow up and migrate the very GL specific state flushing code into the
same file.
2010-07-13 19:26:58 +01:00
Neil Roberts
ae88bff329 Add a GL_GENERATE_MIPMAP fallback to the texture 2d and 3d backends
The CoglTexture2DSliced backend has a fallback for when the
framebuffer extension is missing so it's not possible to use
glGenerateMipmap. This involves keeping a copy of the upper-left pixel
of the tex image so that we can temporarily enable GL_GENERATE_MIPMAP
on the texture object and do a sub texture update by reuploading the
contents of the first pixel. This patch copies that mechanism to the
2D and 3D backends. The CoglTexturePixel structure which was
previously internal to the sliced backend has been moved to
cogl-texture-private.h so that it can be shared.
2010-07-13 18:41:01 +01:00
Neil Roberts
ec718d4ca4 Rename the third texure coordinate from 'r' to 'p'
Using 'r' to name the third component is problematic because that is
commonly used to represent the red component of a vector representing
a color. Under GLSL this is awkward because the texture swizzling for
a vector uses a single letter for each component and the names for
colors, textures and positions are synonymous. GLSL works around this
by naming the components of the texture s, t, p and q. Cogl already
effectively already exposes this naming because it exposes GLSL so it
makes sense to use that naming consistently. Another alternative could
be u, v and w. This is what Blender and Direct3D use. However the w
component conflicts with the w component of a position vertex.
2010-07-13 14:29:07 +01:00
Neil Roberts
c3489a0a22 Move _cogl_texture_2d_is_pot to cogl-util.h
This function could be used in many places in Cogl so it makes sense
to share it in cogl-util.h as _cogl_util_is_pot().
2010-07-13 14:28:35 +01:00
Neil Roberts
2c8bf00995 Don't define public cogl_is_* functions for internal types
This adds a COGL_OBJECT_INTERNAL_DEFINE macro and friends that are the
same as COGL_OBJECT_DEFINE except that they prefix the cogl_is_*
function with an underscore so that it doesn't get exported in the
shared library.
2010-07-09 18:57:54 +01:00
Neil Roberts
61cbeeacfa cogl-texture: Share the common code in the set_region virtual
There was a lot of common code that was copied to all of the backends
to convert the data to a suitable format and wrap it into a CoglBitmap
so that it can be passed to _cogl_texture_driver_upload_subregion_to_gl.
This patch moves the common code to cogl-texture.c so that the virtual
just takes a CoglBitmap that is already in the right format.
2010-07-09 11:14:14 +01:00
Neil Roberts
223317c500 cogl-texture: Share the common code in the get_data virtual
Previously cogl_texture_get_data would pretty much directly pass on to
the get_data texture virtual function. This ended up with a lot of
common code that was copied to all of the backends. For example, the
method is expected to return the required data size if the data
pointer is NULL and to calculate its own rowstride if the rowstride is
0. Also it needs to convert the downloaded data if GL can't support
that format directly.

This patch moves the common code to cogl-texture.c so the virtual is
always called with a format that can be downloaded directly by GL and
with a valid rowstride. If the download fails then the virtual can
return FALSE in which case cogl-texture will use the draw and read
fallback.
2010-07-09 11:00:48 +01:00
Neil Roberts
82e63a4753 cogl-texture: Replace the ensure_mipmaps virtual with pre_paint
Instead of the ensure_mipmaps virtual that is only called whenever the
texture is about to be rendered with a min filter that needs the
mipmap, there is now a pre_paint virtual that is always called when
the texture is about to be painted in any way. It has a flags
parameter which is used to specify whether the mipmap will be needed.

This is useful for CoglTexturePixmapX11 because it needs to do stuff
before painting that is unrelated to mipmapping.
2010-06-22 11:47:33 +01:00
Neil Roberts
ebb05bcb64 cogl-texture: List texture subclass types rather than hardcoding them
Instead of having a hardcoded series of if-statements in
cogl_is_texture to determine which types should appear as texture
subclasses, they are now stored in a GSList attached to the Cogl
context. The list is amended to using a new cogl_texture_register_type
function. There is a convenience macro called COGL_TEXTURE_DEFINE
which uses COGL_HANDLE_DEFINE_WITH_CODE to register the texture type
when the _get_type() function is first called.
2010-06-22 11:47:33 +01:00
Neil Roberts
f9f2f6bc6c Add _cogl_texture_2d_externally_modified
_cogl_texture_2d_externally_modified is a function specific to the
CoglTexture2D texture backend that should be called whenever the
contents of the texture are modified without the backend knowing about
it. It simply marks the mipmap tree as invalid.
2010-06-22 11:47:32 +01:00
Robert Bragg
82e80e6765 material: Avoid redundant glBindTexture calls
This adds a _cogl_bind_gl_texture_transient function that should be used
instead of glBindTexture so we can have a consistent cache of the
textures bound to each texture unit so we can avoid some redundant
binding.
2010-06-09 17:26:15 +01:00
Neil Roberts
0f32fb4acd cogl-texture-2d: Regenerate the mipmaps when the texture is modified
When the texture is modified by cogl_texture_set_region, it wasn't
setting mipmaps_dirty so it would never update the mipmaps.
2010-05-28 18:13:53 +01:00
Neil Roberts
af591f5c09 cogl-texture-2d: Optimise _cogl_texture_2d_is_pot
This takes the simple algorithm from here:

http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2

This avoids a loop and is much faster.
2010-05-20 12:40:59 +01:00
Neil Roberts
e007bc5358 cogl-material: Add support for setting the wrap mode for a layer
Previously, Cogl's texture coordinate system was effectively always
GL_REPEAT so that if an application specifies coordinates outside the
range 0→1 it would get repeated copies of the texture. It would
however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates
are in the range 0→1 so that in the common case that the whole texture
is being drawn with linear filtering it will not blend in edge pixels
from the opposite sides.

This patch adds the option for applications to change the wrap mode
per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge'
and 'automatic'. The automatic map mode is the default and it
implements the previous behaviour. The wrap mode can be changed for
the s and t coordinates independently. I've tried to make the
internals support setting the r coordinate but as we don't support 3D
textures yet I haven't exposed any public API for it.

The texture backends still have a set_wrap_mode virtual but this value
is intended to be transitory and it will be changed whenever the
material is flushed (although the backends are expected to cache it so
that it won't use too many GL calls). In my understanding this value
was always meant to be transitory and all primitives were meant to set
the value before drawing. However there were comments suggesting that
this is not the expected behaviour. In particular the vertex buffer
drawing code never set a wrap mode so it would end up with whatever
the texture was previously used for. These issues are now fixed
because the material will always set the wrap modes.

There is code to manually implement clamp-to-edge for textures that
can't be hardware repeated. However this doesn't fully work because it
relies on being able to draw the stretched parts using quads with the
same values for tx1 and tx2. The texture iteration code doesn't
support this so it breaks. This is a separate bug and it isn't
trivially solved.

When flushing a material there are now extra options to set wrap mode
overrides. The overrides are an array of values for each layer that
specifies an override for the s, t or r coordinates. The primitives
use this to implement the automatic wrap mode. cogl_polygon also uses
it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced
textures. Although this code has been added it looks like the sliced
trick has been broken for a while and I haven't attempted to fix it
here.

I've added a constant to represent the maximum number of layers that a
material supports so that I can size the overrides array. I've set it
to 32 because as far as I can tell we have that limit imposed anyway
because the other flush options use a guint32 to store a flag about
each layer. The overrides array ends up adding 32 bytes to each flush
options struct which may be a concern.

http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-12 15:44:23 +01:00
Neil Roberts
fb7f1a7fd6 Split the wrap mode of _cogl_texture_set_wrap_mode into three
GL supports setting different wrap modes for the s, t and r
coordinates so we should design the backend interface to support that
also. The r coordinate is not currently used by any of the backends
but we might as well have it to make life easier if we ever add
support for 3D textures.

http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-12 15:44:23 +01:00
Owen W. Taylor
e1aec63980 Set pixel store parameters before calling glGetTexImage
We need to set up the rowstride and alignment properly in
CoglTexture2D before reading texture data.

http://bugzilla.openedhand.com/show_bug.cgi?id=2036

Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
2010-03-19 10:21:34 +00:00
Neil Roberts
9fc9aa562e cogl-texture-2d: Determine format before checking texture support
When entering cogl_texture_2d_new_from_bitmap the internal format can
be COGL_PIXEL_FORMAT_ANY. This was causing _cogl_texture_2d_can_create
to use an invalid GL format type. Mesa apparently ignores this but it
was causing errors when Cogl is compiled with debugging under NVidia.

http://bugzilla.openedhand.com/show_bug.cgi?id=2026
2010-03-15 16:09:52 +00:00
Owen W. Taylor
770ca1311d Fix checks for out-of-bounds coordinates and repeats
Add a return result from CoglTexture.transform_quad_coords_to_gl(),
so that we can properly determine the nature of repeats in
the face of GL_TEXTURE_RECTANGLE_ARB, where the returned
coordinates are not normalized.

The comment "We also work out whether any of the texture
coordinates are outside the range [0.0,1.0]. We need to do
this after calling transform_coords_to_gl in case the texture
backend is munging the coordinates (such as in the sub texture
backend)." is disregarded and removed, since it's actually
the virtual coordinates that determine whether we repeat,
not the GL coordinates.

Warnings about disregarded layers are used in all cases where
applicable, including for subtextures.

http://bugzilla.openedhand.com/show_bug.cgi?id=2016

Signed-off-by: Neil Roberts <neil@linux.intel.com>
2010-03-15 16:09:41 +00:00
Owen W. Taylor
d29b3c8f81 Fall back in _cogl_texture_2d_new_from_bitmap()
Just like _cogl_texture_2d_new_with_size(),
_cogl_texture_2d_new_from_bitmap() needs to check if an unsliced
texture can be created at the given size, or if hardware
limitations prevent this.

http://bugzilla.openedhand.com/show_bug.cgi?id=2014

Signed-off-by: Neil Roberts <neil@linux.intel.com>
2010-03-02 11:48:15 +00:00
Emmanuele Bassi
72f4ddf532 Remove mentions of the FSF address
Since using addresses that might change is something that finally
the FSF acknowledge as a plausible scenario (after changing address
twice), the license blurb in the source files should use the URI
for getting the license in case the library did not come with it.

Not that URIs cannot possibly change, but at least it's easier to
set up a redirection at the same place.

As a side note: this commit closes the oldes bug in Clutter's bug
report tool.

http://bugzilla.openedhand.com/show_bug.cgi?id=521
2010-03-01 12:56:10 +00:00
Robert Bragg
ba4b00be42 cogl: remove redundant _cogl_journal_flush prototype
There was a redundant _cogl_journal_flush function prototype in
cogl-primitives.h
2010-02-12 14:05:01 +00:00
Robert Bragg
0f5f4e8645 cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.

There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.

The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:

 return_type
 cogl_function_name (CoglType arg0,
                     CoglType arg1);

Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.

The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.

The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.

The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-12 14:05:00 +00:00
Neil Roberts
f74f4bdc2b cogl: Add a fallback for when the signbit macro is missing
The signbit macro is defined in C99 so it should be available but some
versions of GCC don't appear to define it by default. If it's not
available we can use a hack to test the bit directly.
2010-02-11 15:59:53 +00:00
Neil Roberts
2938ae0475 cogl-texture-2d: Use _cogl_texture_driver_gen to generate the GL tex
_cogl_texture_driver_gen is needed to set the texture minification
mode to Cogl's default of GL_LINEAR. There was also a line to set this
in _cogl_texture_2d_new_with_size but it wasn't working because it was
called *before* the texture was bound. If the texture was later
rendered with the default material it then it would end up with GL's
default mipmap filtering mode but without mipmaps so it would render
white squares instead.
2010-02-09 12:21:10 +00:00
Damien Lespiau
dbef77cd8b cogl: new textures sould have GL_TEXTURE_MIN_FILTER set to GL_LINEAR
The only way the user has to set the mipmap filters is through the
material/layer API. This API defaults to GL_LINEAR/GL_LINEAR for the max
and min filters. With the main use case of cogl being 2D interfaces, it
makes sense do default to GL_LINEAR for the min filter.

When creating new textures, we did not set any filter on them, using
OpenGL defaults': GL_NEAREST_MIPMAP_LINEAR for the min filter and
GL_LINEAR for the max filter. This will make the driver allocate memory
for the mipmap tree, memory that will not be used in the nominal case
(as the material API defaults to GL_LINEAR).

This patch tries to ensure that the min filter is set to GL_LINEAR
before any glTexImage*() call is done on the texture by setting the
filter when generating new OpenGL handles.
2010-02-08 17:14:49 +00:00
Neil Roberts
e20c98e548 cogl: Let GL do the format conversion when uploading texture data
Cogl accepts a pixel format for both the data in memory and the
internal format to be used for the texture. If they do not match then
it would convert them using the CoglBitmap functions before uploading
the data. However, GL also lets you specify both formats so it makes
more sense to let GL do the conversion. The driver may need the
texture in a specific format so it may end up being converted anyway.

The cogl_texture_upload_data functions have been removed and replaced
with a single function to prepare the bitmap. This will only do the
premultiplication conversion because that is the only part that GL
can't do directly.
2010-02-01 13:27:34 +00:00
Neil Roberts
a6f061e41f cogl: Do the premult conversion in-place rather than copying to a new buffer
The premult part of _cogl_convert_premult has now been split out as
_cogl_convert_premult_status. _cogl_convert_premult has been renamed
to _cogl_convert_format to make it less confusing. The premult
conversion is now done in-place instead of copying the
buffer. Previously it was copying the buffer once for the format
conversion and then copying it again for the premult conversion. The
premult conversion never changes the size of the buffer so it's quite
easy to do in place. We can also use the separated out function
independently.
2010-02-01 13:27:34 +00:00
Neil Roberts
ae7825275e cogl: Make CoglSubTexture only work for quad rendering
The sub texture backend doesn't work well as a completely general
texture backend because for example when rendering with cogl_polygon
it needs to be able to tranform arbitrary texture coordinates without
reference to the other coordintes. This can't be done when the texture
coordinates are a multiple of one because sometimes the coordinate
should represent the left or top edge and sometimes it should
represent the bottom or top edge. For example if the s coordinates are
0 and 1 then 1 represents the right edge but if they are 1 and 2 then
1 represents the left edge.

Instead the sub-textures are now documented not to support coordinates
outside the range [0,1]. The coordinates for the sub-region are now
represented as integers as this helps avoid rounding issues. The
region can no longer be a super-region of the texture as this
simplifies the code quite a lot.

There are two new texture virtual functions:

transform_quad_coords_to_gl - This transforms two pairs of coordinates
     representing a quad. It will return FALSE if the coordinates can
     not be transformed. The sub texture backend uses this to detect
     coordinates that require repeating which causes cogl-primitives
     to use manual repeating.

ensure_non_quad_rendering - This is used in cogl_polygon and
     cogl_vertex_buffer to inform the texture backend that
     transform_quad_to_gl is going to be used. The atlas backend
     migrates the texture out of the atlas when it hits this.
2010-01-18 09:22:04 +00:00
Neil Roberts
f1c289378e cogl-texture-2d: Fix the coordinate wrapping for negative coordinates
The formula to wrap the coordinates to the [0,1] range was broken when
the coordinates were negative.
2010-01-15 12:16:06 +00:00
Neil Roberts
05d42ed390 cogl: Add a CoglTexture2D backend
This is an optimised version of CoglTexture2DSliced that always deals
with a single texture and always uses the GL_TEXTURE_2D
target. cogl_texture_new_from_bitmap now tries to use this backend
first. If it can't create a texture with that size then it falls back
the sliced backend.

cogl_texture_upload_data_prepare has been split into two functions
because the sliced backend needs to know the real internal format
before the conversion is performed. Otherwise the converted bitmap
will be wasted if the backend can't support the size.
2009-12-02 22:03:27 +00:00