Texture allocation is now consistently handled lazily such that the
internal format can now be controlled using
cogl_texture_set_components() and cogl_texture_set_premultiplied()
before allocating the texture with cogl_texture_allocate(). This means
that the internal_format arguments to texture constructors are now
redundant and since most of the texture constructors now can't ever fail
the error arguments are also redundant. This now means we no longer
use CoglPixelFormat in the public api for describing the internal format
of textures which had been bad solution originally due to how specific
CoglPixelFormat is which is missleading when we don't support such
explicit control over the internal format.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 99a53c82e9ab0a1e5ee35941bf83dc334b1fbe87)
Note: there are numerous API changes for functions currently marked
as 'unstable' which we don't think are in use by anyone depending on
a stable 1.x api. Compared to the original patch though this avoids
changing the cogl_texture_rectangle_new_with_size() api which we know
is used by Mutter.
This introduces the internal idea of texture loaders that track the
state for loading and allocating a texture. This defers a lot more work
until the texture is allocated.
There are several intentions to this change:
- provides a means for extending how textures are allocated without
requiring all the parameters to be supplied in a single _texture_new()
function call.
- allow us to remove the internal_format argument from all
_texture_new() apis since using CoglPixelFormat is bad way of
expressing the internal format constraints because it is too specific.
For now the internal_format arguments haven't actually been removed
but this patch does introduce replacement apis for controlling the
internal format:
cogl_texture_set_components() lets you specify what components your
texture needs when it is allocated.
cogl_texture_set_premultiplied() lets you specify whether a texture
data should be interpreted as premultiplied or not.
- Enable us to support asynchronous texture loading + allocation in the
future.
Of note, the _new_from_data() texture constructors all continue to
allocate textures immediately so that existing code doesn't need to be
adapted to manage the lifetime of the data being uploaded.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 6a83de9ef4210f380a31f410797447b365a8d02c)
Note: Compared to the original patch, the ->premultipled state for
textures isn't forced to be %TRUE in _cogl_texture_init since that
effectively ignores the users explicitly given internal_format which was
a mistake and on master that change should have been made in the patch
that followed. The gtk-doc comments for cogl_texture_set_premultiplied()
and cogl_texture_set_components() have also been updated in-line with
this fix.
CoglPixelFormat is not a good way of describing the internal
format of a texture because it's too specific given that we don't
actually have exact knowledge of the internal format used by the driver.
This makes cogl_texture_get_format private and in the future we'll
provide a better way of querying the channels and their precision.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit ffde82981f22bd0185a7f33e1e6e1479f4c295b8)
Note: Since we can't break API compatibility on the 1.x branch this adds
a cogl/deprecated/cogl-texture-deprecated.c file with a
cogl_texture_get_format() wrapper around the private api. This also
moves the cogl_texture_get_rowstride() and cogl_texture_ref/unref()
functions that were previously deprecated into cogl-texture-deprecated.c
This removes the gl centric _cogl_texture_prepare_for_upload api from
cogl-texture.c and instead adds a _cogl_bitmap_convert_for_upload() api
which everything now uses instead. GL specific code that needed the gl
internal/format/type enums returned by _cogl_texture_prepare_for_upload
now use ->pixel_format_to_gl directly.
Since there was a special case optimization in
cogl_texture_new_from_file that aimed to avoid copying the temporary
bitmap that's created for the given file and allow conversions to
happen in-place the new _cogl_bitmap_convert_for_upload() api supports
converting in place depending on a 'can_convert_in_place' argument.
This ability to convert bitmaps in-place has been integrated across the
different components as appropriate.
In updating cogl-texture-2d-sliced.c this was able to remove a number of
other GL specific parts to how spans are setup.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit e190dd23c655da34b9c5c263a9f6006dcc0413b0)
Conflicts:
cogl/cogl-auto-texture.c
cogl/cogl.symbols
Consistent with how we lazily allocate framebuffers this patch allows us
to instantiate textures but still specify constraints and requirements
before allocating storage so that we can be sure to allocate the most
appropriate/efficient storage.
This adds a cogl_texture_allocate() function that is analogous to
cogl_framebuffer_allocate() which can optionally be called to explicitly
allocate storage and catch any errors. If this function isn't used
explicitly then Cogl will implicitly ensure textures are allocated
before the storage is needed.
It is generally recommended to rely on lazy storage allocation or at
least perform explicit allocation as late as possible so Cogl can be
fully informed about the best way to allocate storage.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 1fa7c0f10a8a03043e3c75cb079a49625df098b7)
Note: This reverts the cogl_texture_rectangle_new_with_size API change
that dropped the CoglError argument and keeps the semantics of
allocating the texture immediately. This is because Mutter currently
uses this API so we will probably look at updating this later once
we have a corresponding Mutter patch prepared. The other API changes
were kept since they only affected experimental api.
There was a lot of redundancy in how we tracked the width and height of
different texture types which is greatly simplified by adding width and
height members to CoglTexture directly and removing the get_width and
get_height vfuncs from CoglTextureVtable
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 3236e47723e4287d5e0023f29083521aeffc75dd)
This moves the _cogl_texture_get_gl_format function from cogl-texture.c
to cogl-texture-gl.c and renames it _cogl_texture_gl_get_format.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit f8deec01eff7d8d9900b509048cf1ff1c86ca879)
cogl_texture_set_region() and cogl_texture_set_region_from_bitmap() now
have a level argument so image data can be uploaded to a specific mipmap
level.
The prototype for cogl_texture_set_region was also updated to simplify
the arguments.
The arguments for cogl_texture_set_region_from_bitmap were reordered to
be consistent with cogl_texture_set_region with the source related
arguments listed first followed by the destination arguments.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 3a336a8adcd406b53731a6de0e7d97ba7932c1a8)
Note: Public API changes were reverted in cherry-picking this patch
This adds a driver/gl/cogl-texture-gl.c file and moves some gl specific
bits from cogl-texture.c into it. The moved symbols were also given a
_gl_ infix and the calling code was updated accordingly.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 2c9e81de70cc02d72b1ce9013c49e39300a05b6a)
This splits out the very high level texture constructors that may
internally construct one of several types of lower level texture due to
various constraints.
This also updates the prototypes for these constructors to take an
explicit context pointer and return a CoglError consistent with other
texture constructors.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit a1cabfae6ad50c51006c608cdde7d631b7832e71)
This allows apps to catch out-of-memory errors when allocating textures.
Textures can be pretty huge at times and so it's quite possible for an
application to try and allocate more memory than is available. It's also
very possible that the application can take some action in response to
reduce memory pressure (such as freeing up texture caches perhaps) so
we shouldn't just automatically abort like we do for trivial heap
allocations.
These public functions now take a CoglError argument so applications can
catch out of memory errors:
cogl_buffer_map
cogl_buffer_map_range
cogl_buffer_set_data
cogl_framebuffer_read_pixels_into_bitmap
cogl_pixel_buffer_new
cogl_texture_new_from_data
cogl_texture_new_from_bitmap
Note: we've been quite conservative with how many apis we let throw OOM
CoglErrors since we don't really want to put a burdon on developers to
be checking for errors with every cogl api call. So long as there is
some lower level api for apps to use that let them catch OOM errors
for everything necessary that's enough and we don't have to make more
convenient apis more awkward to use.
The main focus is on bitmaps and texture allocations since they
can be particularly large and prone to failing.
A new cogl_attribute_buffer_new_with_size() function has been added in
case developers need to catch OOM errors when allocating attribute buffers
whereby they can first use _buffer_new_with_size() (which doesn't take a
CoglError) followed by cogl_buffer_set_data() which will lazily allocate
the buffer storage and report OOM errors.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit f7735e141ad537a253b02afa2a8238f96340b978)
Note: since we can't break the API for Cogl 1.x then actually the main
purpose of cherry picking this patch is to keep in-line with changes
on the master branch so that we can easily cherry-pick patches.
All the api changes relating stable apis released on the 1.12 branch
have been reverted as part of cherry-picking this patch so this most
just applies all the internal plumbing changes that enable us to
correctly propagate OOM errors.
The function pointer for texture_2d_get_data in the driver vtable was
expecting an unsigned int for the rowstride but the definition in
cogl-texture-2d-gl.c took a size_t so it was giving an annoying
warning. This normalizes them both to just take an int. This seems to
better match the pattern used for cogl_bitmap_new_from_data and
cogl_texture_2d_new_from_data.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
(cherry picked from commit 003f080531d5368835081568779b031ef4f09a77)
This renames the set_filters and set_wrap_mode_parameters texture
virtual functions to gl_flush_legacy_texobj_filters and
gl_flush_legacy_texobj_wrap_modes respectively to clarify that they are
opengl driver specific and that they are only used to support the legacy
opengl apis for setting filters and wrap modes where the state is
associated with texture objects instead of being associated with sampler
objects.
This part of an effort to clearly delimit our abstraction over opengl so
that we can start to consider non-opengl backends for Cogl.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 6f78b8a613340d7c6b736e51a16c625f52154430)
As part of our on-going goal to remove our dependence on a global Cogl
context this patch adds a pointer to the context to each CoglTexture
so that the various texture apis no longer need to use
_COGL_GET_CONTEXT.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 83131072eea395f18ab0525ea2446f443a6033b1)
The coding style has for a long time said to avoid using redundant glib
data types such as gint or gchar etc because we feel that they make the
code look unnecessarily foreign to developers coming from outside of the
Gnome developer community.
Note: When we tried to find the historical rationale for the types we
just found that they were apparently only added for consistent syntax
highlighting which didn't seem that compelling.
Up until now we have been continuing to use some of the platform
specific type such as gint{8,16,32,64} and gsize but this patch switches
us over to using the standard c99 equivalents instead so we can further
ensure that our code looks familiar to the widest range of C developers
who might potentially contribute to Cogl.
So instead of using the gint{8,16,32,64} and guint{8,16,32,64} types this
switches all Cogl code to instead use the int{8,16,32,64}_t and
uint{8,16,32,64}_t c99 types instead.
Instead of gsize we now use size_t
For now we are not going to use the c99 _Bool type and instead we have
introduced a new CoglBool type to use instead of gboolean.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 5967dad2400d32ca6319cef6cb572e81bf2c15f0)
Removing CoglHandle has been an on going goal for quite a long time now
and finally this patch removes the last remaining uses of the CoglHandle
type and the cogl_handle_ apis.
Since the big remaining users of CoglHandle were the cogl_program_ and
cogl_shader_ apis which have replaced with the CoglSnippets api this
patch removes both of these apis.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
(cherry picked from commit 6ed3aaf4be21d605a1ed3176b3ea825933f85cf0)
Since the original patch was done after removing deprecated API
this back ported patch doesn't affect deprecated API and so
actually this cherry-pick doesn't remove all remaining use of
CoglHandle as it did for the master branch of Cogl.
The Intel driver currently has an optimisation when calling
glReadPixels into a PBO so that it will use a blit instead of the Mesa
fallback path. However this only works if the GL_PACK_ALIGNMENT is
exactly 1, even if this would be equivalent to a higher alignment
value because the bpp*width is already aligned. To make it more likely
to hit this fast path, we now detect this situation and explicitly use
an alignment of 1. To make this work the texture driver needs to be
passed down the bpp*width as well as the rowstride when configuring
the alignment.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
This interface represents any textures that are backed by a single
texture in GL and that can be used directly with the
cogl_framebuffer_draw_attributes family of functions. This currently
equates to CoglTexture2D, CoglTexture3D and CoglTextureRectangle.
The interface currently has only one method called
cogl_primitive_set_auto_mipmap. This replaces the
COGL_TEXTURE_NO_AUTO_MIPMAP flag from the CoglTextureFlags parameter
in the constructors. None of the other flags in CoglTextureFlags make
sense for primitive textures so it doesn't seem like a good idea to
need them for primitive constructors.
There is a boolean in the vtable to mark whether a texture type is
primitive which the new cogl_is_primitive function uses. There is also
a new texture virtual called set_auto_mipmap which is only required to
be implemented for primitive textures.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
The idea is that CoglPixelBuffer should just be a buffer that can be
used for pixel data and it has no idea about the details of any images
that are stored in it. This is analogous to CoglAttributeBuffer which
itself does not have any information about the attributes. When you
want to use a pixel buffer you should create a CoglBitmap which points
to a region of the attribute buffer and provides the extra needed
information such as the width, height and format. That way it is also
possible to use a single CoglPixelBuffer with multiple bitmaps.
The changes that are made are:
• cogl_pixel_buffer_new_with_size has been removed and in its place is
cogl_bitmap_new_with_size. This will create a pixel buffer at the
right size and rowstride for the given width/height/format and
immediately create a single CoglBitmap to point into it. The old
function had an out-parameter for the stride of the image but with
the new API this should be queriable from the bitmap (although there
is no function for this yet).
• There is now a public cogl_pixel_buffer_new constructor. This takes
a size in bytes and data pointer similarly to
cogl_attribute_buffer_new.
• cogl_texture_new_from_buffer has been removed. If you want to create
a texture from a pixel buffer you should wrap it up in a bitmap
first. There is already API to create a texture from a bitmap.
This patch also does a bit of header juggling because cogl-context.h
was including cogl-texture.h and cogl-framebuffer.h which were causing
some circular dependencies when cogl-bitmap.h includes cogl-context.h.
These weren't actually needed in cogl-context.h itself but a few other
headers were relying on them being included so this adds the #includes
where necessary.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
The cogl.h header is meant to be the public header for including the 1.x
api used by Clutter so we should stop using that as a convenient way to
include all likely prototypes and typedefs. Actually we already do a
good job of listing the specific headers we depend on in each of the .c
files we have so mostly this patch just strip out the redundant
includes for cogl.h with a few fixups where that broke the build.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
This adds an internal function to get the type of the underlying
hardware texture for any CoglTexture. It can return one of three
values to represent 2D textures, 3D textures or rectangle textures.
The idea is that this can be used as a replacement for
cogl_texture_get_gl_texture when only the target is required to make
it a bit less GL-centric. The implementation adds a new virtual
function which all of the texture backends now implement.
The enum is in a public header because a later patch will want to use
it from the CoglPipeline API. We may want to consider making the
function public too later.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
Unlike in GObject the type number for a CoglObject is entirely an
internal implementation detail so there is no need to make a GQuark to
make it safe to export out of the library. Instead we can just
directly use a fixed pointer address as the identifier for the type.
This patch makes it use the address of the class struct of the
identifier. This should make it faster to do type checks because it
does not need to call a function every time it wants to get the type
number.
Reviewed-by: Robert Bragg <robert@linux.intel.com>
CoglMetaTexture is an interface for dealing with high level textures
that may be comprised of one or more low-level textures internally. The
interface allows the development of primitive drawing APIs that can draw
with high-level textures (such as atlas textures) even though the
GPU doesn't natively understand these texture types.
There is currently just one function that's part of this interface:
cogl_meta_texture_foreach_in_region() which allows an application to
resolve the internal, low-level textures of a high-level texture.
cogl_rectangle() uses this API for example so that it can easily emulate
the _REPEAT wrap mode for textures that the hardware can't natively
handle repeating of.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
As part of the on going, incremental effort to purge the non type safe
CoglHandle type from the Cogl API this patch tackles most of the
CoglHandle uses relating to textures.
We'd postponed making this change for quite a while because we wanted to
have a clearer understanding of how we wanted to evolve the texture APIs
towards Cogl 2.0 before exposing type safety here which would be
difficult to change later since it would imply breaking APIs.
The basic idea that we are steering towards now is that CoglTexture
can be considered to be the most primitive interface we have for any
object representing a texture. The texture interface would provide
roughly these methods:
cogl_texture_get_width
cogl_texture_get_height
cogl_texture_can_repeat
cogl_texture_can_mipmap
cogl_texture_generate_mipmap;
cogl_texture_get_format
cogl_texture_set_region
cogl_texture_get_region
Besides the texture interface we will then start to expose types
corresponding to specific texture types: CoglTexture2D,
CoglTexture3D, CoglTexture2DSliced, CoglSubTexture, CoglAtlasTexture and
CoglTexturePixmapX11.
We will then also expose an interface for the high-level texture types
we have (such as CoglTexture2DSlice, CoglSubTexture and
CoglAtlasTexture) called CoglMetaTexture. CoglMetaTexture is an
additional interface that lets you iterate a virtual region of a meta
texture and get mappings of primitive textures to sub-regions of that
virtual region. Internally we already have this kind of abstraction for
dealing with sliced texture, sub-textures and atlas textures in a
consistent way, so this will just make that abstraction public. The aim
here is to clarify that there is a difference between primitive textures
(CoglTexture2D/3D) and some of the other high-level textures, and also
enable developers to implement primitives that can support meta textures
since they can only be used with the cogl_rectangle API currently.
The thing that's not so clean-cut with this are the texture constructors
we have currently; such as cogl_texture_new_from_file which no longer
make sense when CoglTexture is considered to be an interface. These
will basically just become convenient factory functions and it's just a
bit unusual that they are within the cogl_texture namespace. It's worth
noting here that all the texture type APIs will also have their own type
specific constructors so these functions will only be used for the
convenience of being able to create a texture without really wanting to
know the details of what type of texture you need. Longer term for 2.0
we may come up with replacement names for these factory functions or the
other thing we are considering is designing some asynchronous factory
functions instead since it's so often detrimental to application
performance to be blocked waiting for a texture to be uploaded to the
GPU.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
Instead of calling _cogl_texutre_prepare_for_upload in
cogl_texture_set_region_from_bitmap the call is now deferred to the
implementation of the virtual for set_region. This is needed if the
texture backend is using a different format for the actual GL texture
than what is reported by cogl_texture_get_format. This happens for
example with atlas textures which report the original internal format
specified when the texture was created but actually always store the
data in an RGBA texture.
Also when creating an atlas texture from a bitmap it was preparing the
bitmap to be uploaded to the original format instead of the format of
the actual texture used for the atlas. Then it was using
cogl_texture_set_region_from_bitmap to upload the 5 pieces to make the
copies of the edge pixels. This would end up converting the image to
the actual format 5 times. The atlas textures have now been changed to
prepare the bitmap for the right format.
https://bugzilla.gnome.org/show_bug.cgi?id=657840
Reviewed-by: Robert Bragg <robert@linux.intel.com>
This exposes 2 experimental functions that make it possible to upload a
subregion of a texture from a CoglBuffer by first wrapping the buffer as
a CoglBitmap and then allowing uploading of a subregion from a
CoglBitmap. The new functions are:
cogl_bitmap_new_from_buffer() and
cogl_texture_set_region_from_bitmap()
Actually for now we are exporting this API for practical reasons since
we already had this API internally and it enables a specific feature
that was requested, but it is worth nothing that it's quite likely we
will replace these with functions that don't involve the CoglBitmap API
at some point.
For reference: The CoglBitmap API was actually removed from the 2.0
experimental API reference manual some time ago because the hope was
that we'd come up with a neater replacement. It doesn't seem entirely
clear what the scope of the CoglBitmap api is so it has became a bit of
a dumping ground. CoglBitmap is used for image loading, as a means to
represent the layout of image data and also internally deals with format
conversions.
Note: Because we are avoiding including CoglBitmap as part of the 2.0
API these functions aren't currently included in the 2.0 reference
manual.
Reviewed-by: Neil Roberts <neil@linux.intel.com>
The texture driver functions are now accessed through a vtable pointed
to by a struct in the CoglContext so that eventually it will be
possible to compile both the GL and GLES texture drivers into a single
binary and then select between them at runtime.
Instead of having a single journal per context, we now have a
CoglJournal object for each CoglFramebuffer. This means we now don't
have to flush the journal when switching/pushing/popping between
different framebuffers so for example a Clutter scene that involves some
ClutterEffect actors that transiently redirect to an FBO can still be
batched.
This also allows us to track state in the journal that relates to the
current frame of its associated framebuffer which we'll need for our
optimization for using the CPU to handle reading a single pixel back
from a framebuffer when we know the whole scene is currently comprised
of simple rectangles in a journal.
There's no longer any need to use the GL handle in the callback for
_cogl_texture_foreach_sub_texture_in_region because it can now work in
terms of primitive cogl textures so it has now been removed. This
would be helpful if we ever want to make the foreach function public
so that apps could implement their own primitives using sliced
textures.
This applies an API naming change that's been deliberated over for a
while now which is to rename CoglMaterial to CoglPipeline.
For now the new pipeline API is marked as experimental and public
headers continue to talk about materials not pipelines. The CoglMaterial
API is now maintained in terms of the cogl_pipeline API internally.
Currently this API is targeting Cogl 2.0 so we will have time to
integrate it properly with other upcoming Cogl 2.0 work.
The basic reasons for the rename are:
- That the term "material" implies to many people that they are
constrained to fragment processing; perhaps as some kind of high-level
texture abstraction.
- In Clutter they get exposed by ClutterTexture actors which may be
re-inforcing this misconception.
- When comparing how other frameworks use the term material, a material
sometimes describes a multi-pass fragment processing technique which
isn't the case in Cogl.
- In code, "CoglPipeline" will hopefully be a much more self documenting
summary of what these objects represent; a full GPU pipeline
configuration including, for example, vertex processing, fragment
processing and blending.
- When considering the API documentation story, at some point we need a
document introducing developers to how the "GPU pipeline" works so it
should become intuitive that CoglPipeline maps back to that
description of the GPU pipeline.
- This is consistent in terminology and concept to OpenGL 4's new
pipeline object which is a container for program objects.
Note: The cogl-material.[ch] files have been renamed to
cogl-material-compat.[ch] because otherwise git doesn't seem to treat
the change as a moving the old cogl-material.c->cogl-pipeline.c and so
we loose all our git-blame history.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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>
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
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.
The Cogl atlas code was using _cogl_texture_prepare_for_upload with a
NULL pointer for the dst_bmp to determine the internal format of the
texture without converting the bitmap. It needs to do this to decide
whether the texture will go in the atlas before wasting time on the
conversion. This use of the function is a little confusing so that
part of it has been split out into a new function called
_cogl_texture_determine_internal_format. The code to decide whether a
premult conversion is needed has also been split out.
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.
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.
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.
The CoglTextureSliceCallback function pointer now takes const pointers
for the texture coordinates. This makes it clearer that the callback
should not modify the array and therefore the backend can use the same
array for both sets of coords.
Given a region of texture coordinates this utility invokes a callback
enough times to cover the region with a subregion that spans the
texture at most once. Eg, if called with tx1 and tx2 as 0.5 and 3.0 it
it would invoke the callback with:
0.5,1.0 1.0,2.0 2.0,3.0
Manual repeating is needed by all texture backends regardless of
whether they can support hardware repeating because when Cogl calls
the foreach_sub_texture_in_region method then it sets the wrap mode to
GL_CLAMP_TO_EDGE and no hardware repeating is possible.
Most of the fields that were previously in CoglTexture are specific to
the implementation of CoglTexture2DSliced so they should be placed
there instead. For example, the 'mipmaps_dirty' flag is an
implementation detail of the ensure_mipmaps function so it doesn't
make sense to force all texture backends to have this function.
Other fields such as width, height, gl_format and format may make
sense for all textures but I've added them as virtual functions
instead. This may make more sense for a sub-texture backend for
example where it can calculate these based on the full texture.