Commit Graph

1233 Commits

Author SHA1 Message Date
Chun-wei Fan
7069825cb5 cogl/Makefile.am: VS support-Create a .bat to gen enums
Pre-generate a .bat file to be used to generate the cogl-enum-types.[ch]
for the build process.  This will greatly simplify the maintenace process
as the listing of headers to be parsed by glib-mkenums can be manifested
automatically during 'make dist', and this list changes quite a bit during
the development cycle.
2011-12-08 16:16:58 +08:00
Chun-wei Fan
9cff9236ca cogl/Makefile.am: Visual C++ support updates
Filter out the kms winsys sources... these aren't for Windows.
2011-12-08 12:51:05 +08:00
Neil Roberts
39203cb8f1 attribute: Fix including progend-glsl-private.h on GL2
Previously this header was only included on GLES2 but since 7283e0a4
the progend is used on any driver where GLSL is available. This
changes the #ifdef to check for the presence of the GLSL progend.

Based on a patch by Fan, Chun-wei

https://bugzilla.gnome.org/show_bug.cgi?id=665722

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-07 19:01:29 +00:00
Robert Bragg
09520a7d61 renderer: don't re-connect for display check
This ensure that cogl_renderer_check_onscreen_template() doesn't call
winsys->renderer_connect() if the renderer has already been connected
as that can fail with some backends.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-07 15:53:05 +00:00
Robert Bragg
79f20d08b6 wayland: Updates the wayland compositor side support
The compositor side wayland support enabling us to create textures from
wayland buffers needed updating since visuals were removed from the
wayland protocol.

This also fixes the #ifdef guards for the bind_wayland_display extension
in cogl-winsys-egl-feature-functions.h since it was mistakenly checking
that client-side wayland support had been enabled which won't be the
case.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-07 15:53:05 +00:00
Robert Bragg
14ddbd980b wayland: Add api to set a foreign shell
Since the wayland protocol doesn't currently provide a way to
retrospectively query the interfaces that get notified when a client
first connects then when using a foreign display with Cogl then we also
need api for telling cogl what compositor and shell objects to use. We
already had api for setting a foreign compositor so this patch just adds
api for setting a foreign shell.

This patch also adds documentation for all the wayland specific apis.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-07 15:53:05 +00:00
Neil Roberts
fb8c48108b attribute: Add a missing 'else'
The handler for the normal attribute was missing an else so presumably
it would have crashed on GLES2.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-07 14:52:52 +00:00
Neil Roberts
5f0a57ffdb snippet: Add some more documentation
This adds a documentation section for CoglSnippet which gives an
overview of how to use them. It also fixes some syntax errors in the
existing documentation and adds the missing pipeline functions for
adding snippets to the documentation sections file.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-07 14:52:48 +00:00
Chun-wei Fan
1be2cdab21 cogl-bitmask.h: Eliminate compiler warning
Both _cogl_bitmask_set_flags and _cogl_bitmask_set_flags_array have void
return types, so just execute _cogl_bitmask_set_flags_array without
returning that to elimate a compiler warning.

https://bugzilla.gnome.org/show_bug.cgi?id=665722

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-07 12:08:15 +00:00
Neil Roberts
dba42715d4 egl-winsys: Bind the framebuffer before swapping
For some reason the EGL spec says that the surface passed to
eglSwapBuffers must be bound as the current surface for the swap to
work. Mesa validates that this is the case and returns an error from
the swap buffers call if not.

https://bugzilla.gnome.org/show_bug.cgi?id=665604

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-07 12:08:15 +00:00
Chun-wei Fan
364dae7e1f Update cogl.symbols
-For the snippets APIs.
-For the introduction of the cogl_matrix_orthographic(_EXP) API.
-Also for the new attribute and framebuffer APIs
2011-12-07 16:54:04 +08:00
Chun-wei Fan
a540245489 cogl-snippets.h: Fix typo 2011-12-07 16:52:12 +08:00
Neil Roberts
3f28168f1e attribute: Add the buffer and normalized property APIs to the header
The header was missing declarations for
cogl_attribute_{get,set}_{buffer,normalized}.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
f005f517fe Flush matrices in the progend and flip with a vector
Previously flushing the matrices was performed as part of the
framebuffer state. When on GLES2 this matrix flushing is actually
diverted so that it only keeps a reference to the intended matrix
stack. This is necessary because on GLES2 there are no builtin
uniforms so it can't actually flush the matrices until the program for
the pipeline is generated. When the matrices are flushed it would
store the age of modifications on the matrix stack so that it could
detect when the matrix hasn't changed and avoid flushing it.

This patch changes it so that the pipeline is responsible for flushing
the matrices even when we are using the GL builtins. The same
mechanism for detecting unmodified matrix stacks is used in all
cases. There is a new CoglMatrixStackCache type which is used to store
a reference to the intended matrix stack along with its last flushed
age. There are now two of these attached to the CoglContext to track
the flushed state for the global matrix builtins and also two for each
glsl progend program state to track the flushed state for a
program. The framebuffer matrix flush now just updates the intended
matrix stacks without actually trying to flush.

When a vertex snippet is attached to the pipeline, the GLSL vertend
will now avoid using the projection matrix to flip the rendering. This
is necessary because any vertex snippet may cause the projection
matrix not to be used. Instead the flip is done as a forced final step
by multiplying cogl_position_out by a vec4 uniform. This uniform is
updated as part of the progend pre_paint depending on whether the
framebuffer is offscreen or not.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
7590fc3ec3 snippet: Add a hook for the vertex transform
This adds a hook to wrap or replace the vertex transform stage.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
68b3643b25 snippet: Add a hook for the layer texture coordinate transformation
This adds a hook called COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM.
This can be used to alter the application of the layer user matrix to
a texture coordinate or it can bypass it altogether.

This is the first per-layer hook that affects the vertex shader state
so the patch includes the boilerplate needed to get that to work.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
b7e15929b6 snippet: Add a hook for the layer fragment processing
This adds a hook to replace or wrap the fragment processing for a
particular layer.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
4581ce5f15 fragend-glsl: Don't generate the default texture lookup if replaced
Previously the function containing the default texture lookup is
always generated regardless of whether there is a snippet with a
replace string which would cause it not be used. Now this snippets are
all scanned to check for replace strings before generating the texture
lookup.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
272c6567fa glsl-fragend: Store the cached variables in global variables
The variables caching the result of texture lookups and layer
calculations are now stored in global variables so that when a hook
for the layer processing is added the variables can still be accessed
even if the generated code is within a separate function.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
a0903e0cfb snippet: Don't generate code for snippets that are replaced
The loop that generates code for a list of snippets now starts from
the first snippet that has a replace string. Any snippets before that
would be ignored so there's no point in generating code for them.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
cdc4bd6361 snippet: Fix detecting the last snippet
The function for generating the GLSL for a list of snippets was trying
to detect the last snippet so that it could use a different function
name. However this wouldn't work if the last snippet has a different
hook. To fix this it now just counts the snippets that have the same
hook beforehand and detects the last one using the count.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
09c2e4abe7 snippet: Move the hook to be a property of the snippet
Instead of specifying the hook point when adding to the pipeline using
a separate function for each hook, the hook is now a property of the
snippet. The hook is set on construction and is then read-only.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
5be5a03343 pipeline: Assume blend enabled when there are snippets
Whenever snippets are enabled we can't determine whether the final
color will be fully opaque so we just have to assume blending should
be enabled.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
df0f9a862f pipeline: Add a snippet hook for the texture lookup
This adds a per-layer snippet hook for the texure lookup. Here the
snippet can modify the texture coordinates used for the lookup or
modify the texel resulting from the lookup. This is the first
per-layer hook so this also adds the
COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS state and all of the
boilerplate needed to make that work.

Most of the functions used by the pipeline state to manage the snippet
list has been moved into cogl-pipeline-snippet.c so that it can be
shared with the layer state.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
4cdf66f89b pipeline: Move the snippet source loop into a common function
The two loops that generate the functions for the snippets in the
fragend and vertend are very similar so to avoid code duplication this
patch moves the logic to its own function in a new
cogl-pipeline-snippet.c file.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:06 +00:00
Neil Roberts
717e96b304 snippet: Add a 'replace' string
If present, the 'replace' string will be used instead of whatever code
would normally be invoked for that hook point. It will also replace
any previous snippets.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:05 +00:00
Neil Roberts
0fdd5690c6 pipeline: Wrap each snippet in its own function
Each snippet is now given its own function which contains the pre and
post strings. Between these strings the function will chain on to
another function. The generated cogl source is now stored in a
function called cogl_generated_source() which the last snippet will
chain on to. This should make it so that each snippet has its own
namespace for local variables and it can share variables declared in
the pre string in the post string. Hopefully the GLSL compiler will
just inline all of the functions so it shouldn't make much difference
to the compiled output.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:05 +00:00
Neil Roberts
d38ae0284b cogl-pipeline: Add two hook points for adding shader snippets
This adds two new public experimental functions for attaching
CoglSnippets to two hook points on a CoglPipeline:

void cogl_pipeline_add_vertex_hook (CoglPipeline *, CoglSnippet *)
void cogl_pipeline_add_fragment_hook (CoglPipeline *, CoglSnippet *)

The hooks are intended to be around the entire vertex or fragment
processing. That means the pre string in the snippet will be inserted
at the very top of the main function and the post function will be
inserted at the very end. The declarations get inserted in the global
scope.

The snippets are stored in two separate linked lists with a structure
containing an enum representing the hook point and a pointer to the
snippet. The lists are meant to be for hooks that affect the vertex
shader and fragment shader respectively. Although there are currently
only two hooks and the names match these two lists, the intention is
*not* that each new hook will be in a separate list. The separation of
the lists is just to make it easier to determine which shader needs to
be regenerated when a new snippet is added.

When a pipeline becomes the authority for either the vertex or
fragment snipper state, it simply copies the entire list from the
previous authority (although of course the shader snippet objects are
referenced instead of copied so it doesn't duplicate the source
strings).

Each string is inserted into its own block in the shader. This means
that each string has its own scope so it doesn't need to worry about
name collisions with variables in other snippets. However it does mean
that the pre and post strings can't share variables. It could be
possible to wrap both parts in one block and then wrap the actual
inner hook code in another block, however this would mean that any
further snippets within the outer snippet would be able to see those
variables. Perhaps something to consider would be to put each snippet
into its own function which calls another function between the pre and
post strings to do further processing.

The pipeline cache for generated programs was previously shared with
the fragment shader cache because the state that affects vertex
shaders was a subset of the state that affects fragment shaders. This
is no longer the case because there is a separate state mask for
vertex snippets so the program cache now has its own hash table.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:05 +00:00
Neil Roberts
f37738453e Add a CoglSnippet type
This adds a CoglObject called CoglSnippet which will be used to store
strings used as GLSL snippets to be attached at hook points to a
CoglPipeline. The snippets can currently contain three strings:

declarations - This will be placed in the global scope and is intended
               to be used to declare uniforms, attributes and
               functions.

pre           - This will be inserted before the hook point.

post          - This will be inserted after the hook point.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:05 +00:00
Neil Roberts
0c82c296bf framebuffer: Handle a NULL previous framebuffer when flushing
_cogl_framebuffer_flush_state needs to handle the case where
ctx->current_draw_buffer is NULL because this will be set in the
destructor for CoglFramebuffer if the framebuffer being destroyed is
the current framebuffer. This patch just makes it assume all state has
changed in that case.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-12-06 19:02:05 +00:00
Robert Bragg
7283e0a49c rework enabling of attributes, removing _cogl_enable()
This removes the limited caching of enabled attributes done by
_cogl_enable() and replaces it with a more generalized set of bitmasks
associated with the context that allow us to efficiently compare the set
of attribute locations that are currently enabled vs the new locations
that need enabling so we only have to inform OpenGL of the changes in
which locations are enabled/disabled.

This also adds a per-context hash table for mapping attribute names to
global name-state structs which includes a unique name-index for any
name as well as pre-validated information about builtin "cogl_"
attribute names including whether the attribute is normalized and what
texture unit a texture attribute corresponds too.

The name-state hash table means that cogl_attribute_new() now only needs
to validate names the first time they are seen.

CoglAttributes now reference a name-state structure instead of just the
attribute name, so now we can efficiently get the name-index for any
attribute and we can use that to index into a per-glsl-program cache
that maps name indices to real GL attribute locations so when we get
asked to draw a set of attributes we can very quickly determine what GL
attributes need to be setup and enabled. If we don't have a cached
location though we can still quickly access the string name so we can
query OpenGL.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:57 +00:00
Robert Bragg
2112af0bc5 framebuffer: deal with winding state like other state
We should not be deciding whether we need to really update the GL face
winding state at the point where a new framebuffer has been pushed, we
should be waiting until we have really been asked to flush some
framebuffer state otherwise we may do redundant work if multiple
framebuffers are pushed/popped before something is really drawn.

This integrates the face winding state tracking with the design we have
for handling most of the other framebuffer state so we benefit from the
optimizations for minimizing the cost of _cogl_framebuffer_flush_state()

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:57 +00:00
Robert Bragg
cf4b228fc0 framebuffer: track fb color mask like other fb state
We should not be deciding whether we need to really update the GL color
mask state at the point where a new framebuffer has been pushed, we
should be waiting until we have really been asked to flush some
framebuffer state otherwise we may do redundant work if multiple
framebuffers are pushed/popped before something is really drawn.

This integrates the color mask state tracking with the design we have
for handling most of the other framebuffer state so we benefit from the
optimizations for minimizing the cost of _cogl_framebuffer_flush_state()

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:57 +00:00
Robert Bragg
042dc7c8cd framebuffer: Optimize _cogl_framebuffer_flush_state()
Previously the cost of _cogl_framebuffer_state_flush() would always
scale by the total amount of state tracked by CoglFramebuffer even in
cases where we knew up-front that we only wanted to flush a subset of
the state or in cases where we requested to flush the same framebuffer
multiple times with no changes being made to the framebuffer.

We now track a set of state changed flags with each framebuffer and
track the current read/draw buffers as part of the CoglContext so that
we can quickly bail out when asked to flush the same framebuffer
multiple times with no changes.

_cogl_framebuffer_flush_state() now takes a mask of the state that we
want to flush and the implementation has been redesigned so that the
cost of checking what needs to be flushed and flushing those changes
now scales by how much state we actually plan to update.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:57 +00:00
Robert Bragg
6ab371d587 clip-state: remove redundant _cogl_clip_state_flush() api
There was only one place where we called _cogl_clip_state_flush() in
_cogl_framebuffer_flush_state() and we can just as well use
_cogl_clip_state_get_stack() and _cogl_clip_stack_flush() directly
instead.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:57 +00:00
Robert Bragg
6d1bf9a0d4 remove redundant _cogl_clip_stack_dirty() api
The only place we were calling _cogl_clip_stack_dirty() was when
changing the current draw_buffer which also implies a change in
the current clip stack. _cogl_clip_stack_flush() would already
be able to quickly determine that the clip stack has changed by
checking ctx->current_clip_stack so there isn't really any need
to explicitly mark the clip_stack state as dirty.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:57 +00:00
Robert Bragg
104a6be84c cogl-matrix-stack: remove flush avoidance checks
The aim is to make cogl-framebuffer.c responsible for avoiding redundant
flushing of its matrix stacks so this removes the checks done directly
within cogl-matrix-stack.c.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:57 +00:00
Robert Bragg
ff4921cef9 docs: updates cogl-matrix.h docs to be consistent
This update some of the cogl-matrix.h documentation to be consistent
with the corresponding documentation for framebuffer matrix-stack
methods in cogl-framebuffer.h

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:57 +00:00
Robert Bragg
39a7bcff67 matrix-stack: Avoid referencing the default CoglContext
This removes the use of _COGL_GET_CONTEXT() from cogl-matrix-stack.c
as part of the ongoing effort to evolve cogl to get rid of the need for
a default context.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Robert Bragg
5156365eae path: use cogl_framebuffer_push_path_clip in cogl2-path.c
_cogl_path_fill_nodes_with_clipped_rectangle() sometimes falls back to
pushing a framebuffer clip region and filling the region using
cogl_rectangle(). Since we aim to eventually deprecate
cogl_clip_push_from_path() as it relies on the default CoglContext we
would rather this internal code update a framebuffer's clip-state using
the cogl_framebuffer clip stack api instead.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Robert Bragg
36575502e8 docs: make cogl2-clip-state.h docs consistent
This updates some of the cogl2-clip-state.h cogl_clip_ API documentation
to make it consistent with the documentation for corresponding
framebuffer clip stack API in cogl-framebuffer.h

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Robert Bragg
de04a58f30 docs: make cogl.h clip stack docs consistent
This updates some of the cogl.h cogl_clip_ API documentation to make it
consistent with the documentation for corresponding framebuffer clip
stack API in cogl-framebuffer.h

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Robert Bragg
6bb409e996 framebuffer: Add CoglFramebuffer clip stack methods
This adds CoglFramebuffer methods for accessing the clip stack. We plan
on making some optimizations to how framebuffer state is flushed which
will require us to track when a framebuffer's clip state has changed.

This api also ties in to the longer term goal of removing the need for a
default global CoglContext since these methods are all implicitly
related to a specific context via their framebuffer argument.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Robert Bragg
652c8c31cf avoid touching fb matrix stack directly
This ensures we don't touch a framebuffer's matrix stack directly if we
are also relying on _cogl_framebuffer_flush_state(). We want to get to
the point where we can set dirty flags against framebuffer state at the
point it changes but that means we can't allow direct access to the
matrix stack. _cogl_texture_draw_and_read() has now been changed so it
uses cogl_framebuffer_ methods to update the matrix stacks including
adding new internal _cogl_framebuffer_push/pop_projection() functions
that allow us to set transient projections.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Robert Bragg
5ca78668af Adds cogl_framebuffer_identity_matrix
This adds a cogl_framebuffer_identity_matrix() method that can be used
to reset the current modelview matrix to the identity matrix.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Robert Bragg
a81458f5b9 docs: make cogl.h matrix stack documentation consistent
This updates the cogl.h matrix stack documentation consistent with the
corresponding documentation in cogl-framebuffer.h for the framebuffer
matrix stack methods.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Robert Bragg
ccde191191 framebuffer: Add CoglFramebuffer matrix stack methods
This adds cogl_framebuffer_ methods to update the modelview and
projection matrix stacks to replace functions like cogl_translate(),
cogl_rotate() and cogl_scale() etc.

This is part of the on-going effort to get rid of the global CoglContext
pointer since the existing methods don't take an explicit pointer to a
CoglContext. All the methods are now related to a context via the
framebuffer.

We added framebuffer methods instead of direct context methods because
the matrix stacks are per-framebuffer and as well as removing the global
CoglContext we would rather aim for a more direct state access API
design than, say, cairo or OpenGL, so we'd like to avoid needing the
cogl_push/pop_framebuffer(). We anticipate that Cogl will mostly be
consumed by middleware graphics layers such as toolkits or game engines
and feel that a more stateless model will avoid impedance mismatches if
higher levels want to expose a stateless model to their developers and
statefullness can still be added by higher levels if really desired.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Robert Bragg
595311ba55 cogl-matrix-stack: Adds _cogl_matrix_stack_equal
Adds a function for comparing the top matrix entries of two matrix
stacks.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Robert Bragg
a4f3d0d18b matrix: Add cogl_matrix_orthographic
This adds an experimental cogl_matrix_orthographic() function that is
more consistent with other Cogl api by taking x_1, y_1, x_2, y_2
arguments to define the top-left and bottom-right coordinates of the
orthographic coordinates instead of OpenGL style left, right, bottom and
top values.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Robert Bragg
ba02f70961 texture: assert set_region size <= src size
This improves the documentation for cogl_texture_set_region() and
cogl_texture_set_region_from_bitmap() to explain that the region can't
be larger than the source data and also adds runtime assertions that
such a request isn't made.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Robert Bragg
aa59dc5e8d docs: Fix a s/called/culled/ typo
The documentation for CoglPipelineCullFaceMode had a repeated typo with
"called" being used instead of "culled" which this fixes.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-12-06 18:51:56 +00:00
Tomeu Vizoso
1de6575ca2 build: Add missing include in cogl-winsys-egl-private.h
We were missing APIENTRY.
2011-12-06 19:49:00 +01:00
Rob Bradford
7f2a896351 kms: Avoid using struct member before it is set
When saving the CRTC we were trying to use a struct member for the encoder
that wasn't valid at that point in time - instead use the local variable.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-30 15:37:09 +00:00
Neil Roberts
da154b9a3b pipeline: Add a missing break for the uniforms state
_cogl_pipeline_init_multi_property_sparse_state was missing a break in
the case statement handling uniforms. This doesn't yet matter because
it is the last one handled anyway but it will bite someone later.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-29 13:03:25 +00:00
Robert Bragg
be40cbb8c3 build: include missing headers in cogl-winsys-egl-private.h
We were missing various platform header includes in
cogl-winsys-egl-private.h when building support for non KMS egl
platforms.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-11-28 23:19:45 +00:00
Robert Bragg
c2729e4ea8 build: don't inc egl headers for non EGL builds
For example when building on windows we don't want to require EGL
headers when compiling cogl-renderer.c or cogl-texture-2d.c so we make
sure not to include cogl-winsys-egl-private.h if we aren't supporting
EGL.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-11-28 23:19:35 +00:00
Robert Bragg
40b14c6084 kms: avoid using redundant g* and GL* types
A small, pedantic change to remove the use of redundant gint and GLuint
types instead of int and unsigned int.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-11-28 22:43:15 +00:00
Robert Bragg
056daad850 build: only include cogl-winsys-kms.h if KMS enabled
Only include cogl-winsys-kms.h in cogl-winsys-egl-private.h if KMS
support has been enabled.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-11-28 22:39:19 +00:00
Robert Bragg
aa6433d8c5 kms: Check for EGL_KHR_surfaceless_opengl extension
This adds a check for the EGL_KHR_surfaceless_opengl extension which we
depend on for being able to MakeCurrent (NO_SURFACE) as well as create a
context without and EGLConfig.

Reviewed-by: Rob Bradford <rob@linux.intel.com>
2011-11-28 17:38:17 +00:00
Robert Bragg
7a91c91994 kms: flatten setup_kms into _cogl_winsys_kms_display_setup
Since _cogl_winsys_kms_display_setup was basically just calling
setup_kms() it made sense to fold the code of setup_kms() back into the
_cogl_winsys_kms_display_setup() function.

Reviewed-by: Rob Bradford <rob@linux.intel.com>
2011-11-28 17:38:15 +00:00
Robert Bragg
607bfec48d kms: move Cogl*EGL typedefs to cogl-winsys-egl-private.h
So that the various internal Cogl*EGL typedefs can be available to
cogl-winsys-kms.c this moves them into cogl-winsys-egl-private.h

Reviewed-by: Rob Bradford <rob@linux.intel.com>
2011-11-28 17:37:31 +00:00
Rob Bradford
1b54c8023e kms: Add first version of "baremetal" backend for EGL on KMS
To start with this backend only supports creating a single CoglOnscreen
framebuffer and will automatically set is up to display fullscreen on
the first suitable crtc it can find.

To compile this backend - get some dribbly black candles, sacrifice a
goat and configure with: --enable-kms-egl-platform

Note: There is currently a problem with using GLES2 with this winsys
so you need to run with EGL_DRIVER=gl
Note: If you have problems with mesa crashing in XCB during
eglInitialize then you may need to explicitly run with EGL_PLATFORM=gbm

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-28 17:37:28 +00:00
Neil Roberts
d44e548715 cogl-debug: Mark _cogl_debug_flags with dllexport for MSVC
When building with MSVC, symbols to be exported that point to data
need to be marked with dllimport to be successfully imported. The
_cogl_debug_flags variable is currently exported because it is used
from cogl-pango. This patch adds a COGL_EXPORT macro to cogl-util.h
which is used in cogl-debug.h

Based on a patch by Chun-wei Fan

https://bugzilla.gnome.org/show_bug.cgi?id=650020

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-25 13:14:10 +00:00
Chun-wei Fan
2055f6ba91 VS 2008/2010 project files to build Cogl
These are the VS 2008/2010 project files to build Cogl, with a README.txt
to explain the process involved.

Note that the Cogl and Cogl-Pango projects (and filters for VS2010) are
expanded with the correct source file listings during "make dist", which
is done to simplify maintenance of these project files.

-added preconfigured config.h(.win32.in), which is expanded with the
 correct versioining info during autogen
-added preconfigued cogl/cogl-defines.h.win32
-added symbols files for cogl and cogl-pango
-Have configure.ac expand the config.h.win32.in into config.h.win32
 with the correct versioning info, etc, and to include the Visual C++
 project files for distribution
-Added rules in cogl/Makefile.am to expand the cogl VS 2008/2010 projects
 and filters from the templates with up-to-date source file listings, to
 distribute cogl-enum-types.c, cogl-enum-types.h to ease compilation and
 to avoid depending on PERL on Windows installations.
-Added rules in cogl-pango/Makefile.am to expand the cogl-pango VS2008/
 2010 projects and filters from the templates with up-to-date source file
 listings.
-Added/edited various Makefile.am's in build to distribute the VS2008/2010
 project files and associated items required for the build.
-Update .gitignore. There needs to be a pre-configured
 config.h(.win32) and its template, config.h.win32.in for Visual C++
 builds

https://bugzilla.gnome.org/show_bug.cgi?id=650020

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-11-25 13:12:45 +00:00
Neil Roberts
9e52b4d714 Fix comparing the uniforms state
When comparing uniform values, it was not correctly handling the case
where pipeline0 has the value set but pipeline1 does not (only the
other way around) so it would crash.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-24 13:23:00 +00:00
Chun-wei Fan
80a9c3bb32 Update cogl/winsys/cogl-winsys-stub.c
Deal with c99ism... I know it's not pretty, but it is the way
to go with non-c99 compilers.  That's life...

Reviewed-by: Neil Roberts <neil@linux.intel.com>
Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-23 12:16:45 +00:00
Neil Roberts
61d71c0926 cogl-flags: Fix iterating flag when the most-significant bit is set
When the flags contain a value that only has the most-significant bit
set then ffsl will return the size of an unsigned long. According to
the C spec it is undefined what happens when shifting by a number
greater than or equal to the size of the left operand. On Intel (and
probably others) this seems to end up being a no-op so the iteration
breaks. To fix this we can split the shift into two separate
shifts. We always need to shift by at least one bit so we can put this
one bit shift into a separate operator.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-22 16:07:21 +00:00
Neil Roberts
c269817edd cogl-pipeline: Use a hash table for faster uniform name lookup
The uniform names are now stored in a GPtrArray instead of a linked
list. There is also a hash table to speed up converting names to
locations.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:11 +00:00
Neil Roberts
4a7cd0d2ac cogl-pipeline: Store the uniform overrides in an array instead of list
Previously the uniform overrides were stored in a linked list. Now
they are stored in a g_malloc'd array. The values are still tightly
packed so that there is only a value for each uniform that has a
corresponding bit in override_mask. The allocated size of the array
always exactly corresponds to the number of bits set in the
override_mask. This means that when a new uniform value is set on a
pipeline it will have to grow the array and copy the old values
in. The assumption is that setting a value for a new uniform is much
less frequent then setting a value for an existing uniform so it makes
more sense to optimise the latter.

The advantage of using an array is that we can quickly jump to right
boxed value given a uniform location by doing a population count in
the bitmask for the number of bits less than the given uniform
location. This can be done in O(1) time whereas the old approach using
a list would scale by the number of bits set.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:11 +00:00
Neil Roberts
f23b12a886 cogl-bitmask: Add _cogl_bitmask_popcount
This returns a population count of all the bits that are set in the
bitmask.

There is now also a _cogl_bitmask_popcount_upto which counts the
number of bits set up to but not including the given bit index. This
will be useful to determine the number of uniform overrides to skip if
we tightly pack the values in an array.

The test-bitmask test has been modified to check these two functions.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:11 +00:00
Neil Roberts
4553ca0695 cogl-pipeline: Add support for setting uniform values
This adds the following new public experimental functions to set
uniform values on a CoglPipeline:

void
cogl_pipeline_set_uniform_1f (CoglPipeline *pipeline,
                              int uniform_location,
                              float value);
void
cogl_pipeline_set_uniform_1i (CoglPipeline *pipeline,
                              int uniform_location,
                              int value);
void
cogl_pipeline_set_uniform_float (CoglPipeline *pipeline,
                                 int uniform_location,
                                 int n_components,
                                 int count,
                                 const float *value);
void
cogl_pipeline_set_uniform_int (CoglPipeline *pipeline,
                               int uniform_location,
                               int n_components,
                               int count,
                               const int *value);
void
cogl_pipeline_set_uniform_matrix (CoglPipeline *pipeline,
                                  int uniform_location,
                                  int dimensions,
                                  int count,
                                  gboolean transpose,
                                  const float *value);

These are similar to the old functions used to set uniforms on a
CoglProgram. To get a value to pass in as the uniform_location there
is also:

int
cogl_pipeline_get_uniform_location (CoglPipeline *pipeline,
                                    const char *uniform_name);

Conceptually the uniform locations are tied to the pipeline so that
whenever setting a value for a new pipeline the application is
expected to call this function. However in practice the uniform
locations are global to the CoglContext. The names are stored in a
linked list where the position in the list is the uniform location.

The global indices are used so that each pipeline can store a mask of
which uniforms it overrides. That way it is quicker to detect which
uniforms are different from the last pipeline that used the same
CoglProgramState so it can avoid flushing uniforms that haven't
changed. Currently the values are not actually compared which means
that it will only avoid flushing a uniform if there is a common
ancestor that sets the value (or if the same pipeline is being flushed
again - in which case the pipeline and its common ancestor are the
same thing).

The uniform values are stored in the big state of the pipeline as a
sparse linked list. A bitmask stores which values have been overridden
and only overridden values are stored in the linked list.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:11 +00:00
Neil Roberts
4e760d51f1 cogl-bitmask: Add _cogl_bitmask_set_flags
This adds a _cogl_bitmask_set_flags function which can be used to copy
the values from a CoglBitmask to an array of unsigned longs which can
be used with the COGL_FLAGS_* macros. The values are or'd in so that
in can be used multiple times to combine multiple bitmasks.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:11 +00:00
Neil Roberts
d2fd168351 cogl-matrix: Add a public cogl_matrix_transpose()
This function takes a single matrix argument and replaces the matrix
with its transpose.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:11 +00:00
Neil Roberts
037c0aa88c Move POPCOUNTL to cogl-util
This moves the POPCOUNTL macro from cogl-winsys-glx to cogl-util and
renames it to _cogl_util_popcountl so that it can be used in more
places. The fallback function for when the GCC builtin is not
available has been replaced with an 8-bit lookup table because the
HAKMEM implementation doesn't look like it would work when longs are
64-bit so it's not suitable for a general purpose function on 64-bit
architectures. Some of the pages regarding population counts seem to
suggest that using a lookup table is the fastest method anyway.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:11 +00:00
Neil Roberts
436a7a45da cogl-boxed-value: Add _cogl_boxed_value_copy
This adds a function to copy one boxed value to another. It is assumed
that the destination boxed value is totally initialised (so it won't
try to free any memory in it).

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:11 +00:00
Neil Roberts
7068849ae6 cogl-boxed-value: Wrap the GL calls in the GE() macro
This wraps all of the calls to glUniform* in the GE() macro so that it
will detect GL errors in the right place.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:11 +00:00
Neil Roberts
256f5791fd cogl-program: Move the code for CoglBoxedValue to its own file
The code for manipulating CoglBoxedValues is now separated from
cogl-program.c into its own file. That way when we add support for
setting uniform values on a CoglPipeline the code for storing the
values can be shared.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:10 +00:00
Neil Roberts
d706991579 cogl-flags: Add some macros to help iterate the bits
This adds some macros to iterate over all the bits set in an array of
flags. The macros are a bit awkward because it tries to avoid using a
callback pointer so that the code is inlined.

cogl_bitmask is now using these macros as well so that the logic can
be shared.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:32:00 +00:00
Neil Roberts
dbc31b70cc cogl-bitmask: Add a return value for the foreach callback
The foreach callback can now return FALSE to stop the iteration.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:21:31 +00:00
Neil Roberts
f4c1ba9ed9 cogl-flags: Use longs instead of ints
Previously cogl-flags was using an array of ints to store the
flags. There was a comment saying that it would be nice to use longs
but this is awkward because g_parse_debug_flags can only work in
ints. This is a silly reason not to use longs because we can just
parse multiple sets of flags per long. This patch therefore changes
cogl-flags to use longs and tweaks the debug key parsing code.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:21:31 +00:00
Neil Roberts
2ba4fe417a cogl-bitmask: Use ffsl to speedup bitmask iteration
Instead of testing each bit when iterating a bitmask, we can use ffsl
to skip over unset bits in single instruction. That way it will scale
by the number of bits set, not the total number of bits.

ffsl is a non-standard function which glibc only provides by defining
GNUC_SOURCE. However if we are compiling with GCC we can avoid that
mess and just use the equivalent builtin. When not compiling for GCC
it will fall back to _cogl_util_ffs if the size of ints and longs are
the same (which is the case on i686). Otherwise it fallbacks to a slow
function implementation.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:21:31 +00:00
Neil Roberts
f0f9493f5c cogl-fixed: Move the GType defs from cogl-util.c to cogl-fixed.c
The boilerplate for defining a GType for CoglFixed lived in
cogl-util.c but this didn't seem to make much sense seeing as nothing
in the cogl-util.h header file relates to CoglFixed and there is
already a separate C file for CoglFixed code. This also removes some
redundant header includes from cogl-util.c

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 16:21:31 +00:00
Neil Roberts
93321d9b89 cogl-bitmask: Use longs instead of ints
Instead of storing only 31 bits in the pointer for a CoglBitmask, it
now assumes it can store a whole unsigned long minus the one bit used
to mark whether it has been converted to a GArray or not. This works
on the assumption that we can cast an unsigned long to a pointer and
back without losing information which I think should be true for any
platforms that Cogl is interested in. This has the advantage that on
64-bit architectures we can store 63 bits before we have to resort to
using a GArray at no extra cost. The values in the GArray are now
stored as unsigned longs as well on the assumption that it is more
efficient to load and store data in chunks of longs rather than ints.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-16 15:43:25 +00:00
Neil Roberts
39ca3e51df Don't take a reference to the last used onscreen framebuffer
Cogl keeps a pointer to the last used onscreen framebuffer from the
context to implement the deprecated cogl_set_draw_buffer function
which can take COGL_WINDOW_BUFFER as the target to use the last
onscreen buffer. Previously this would also take a reference to that
pointer. However that was causing a circular reference between the
framebuffer and the context which makes it impossible to clean up
resources properly when onscreen buffers are used. This patch instead
changes it to just store the pointer and then clear the pointer during
_cogl_onscreen_free as a kind of cheap weak reference.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-14 18:40:28 +00:00
Neil Roberts
5369b3c601 pipeline: Make the backface culling experimental public
This adds two new experimental public functions to replace the old
internal _cogl_pipeline_set_cull_face_state function:

void
cogl_pipeline_set_cull_face_mode (CoglPipeline *pipeline,
                                  CoglPipelineCullFaceMode cull_face_mode);

void
cogl_pipeline_set_front_face_winding (CoglPipeline *pipeline,
                                      CoglWinding front_winding);

There are also the corresponding getters.

https://bugzilla.gnome.org/show_bug.cgi?id=663628

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-14 18:40:27 +00:00
Neil Roberts
8be44f9876 cogl-utils: Include cogl-defines.h
cogl-utils.h needs to include cogl-defines.h so that it knows whether
COGL_HAS_GLIB_SUPPORT is defined.

https://bugzilla.gnome.org/show_bug.cgi?id=663578

Reviewed-by: Robert Bragg <robert@linux.intel.com>
Reviewed-by: Emmanuele Bassi <ebassi@linux.intel.com>
2011-11-14 18:40:27 +00:00
Chun-wei Fan
91f91dc678 cogl-renderer.c: Fix includes
Only include cogl-xlib-renderer.h when XLIB support is available

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-14 18:37:57 +00:00
Neil Roberts
1566941c2f cogl-context: Destroy texture units later on
This patch moves the call to _cogl_destroy_texture_units() from
_cogl_context_free() to later on. When destroying a GL texture the
texture units are checked. This would end up accessing invalid memory
so we need to try to destroy the texture units only after everything
that might be referencing a texture has been destroyed.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-04 13:03:01 +00:00
Neil Roberts
c637324663 cogl-program: Don't ignore the transpose property of matrix uniforms
When setting a matrix uniform value the transpose property was getting
lost and left uninitialized.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 15:50:02 +00:00
Robert Bragg
89731d160e Skip clip flush in _texture_2d_copy_from_framebuffer
Although there was a comment in cogl_texture_2d_copy_from_framebuffer
explaining that we shouldn't flush the clip state, the comment was a bit
miss-leading implying we were going to explicitly set a NULL clip. Also
we weren't actually avoiding flushing the clip state since we were
passing 0 for the CoglDrawFlags.

We now pass COGL_FRAMEBUFFER_FLUSH_SKIP_CLIP_STATE in to the flags when
flushing the framebuffer state and the comment has be updated to explain
that clipping won't affect reading from the framebuffer so we don't need
to flush it.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-11-03 13:57:06 +00:00
Robert Bragg
e2c758c105 clip: make cogl_clip_ensure a NOP
This api is deprecated and documented to be a NOP which wasn't actually
true. This patch actually updates the function to be a NOP. Its nice
that this gets rid of a point where we flush framebuffer state because
we are looking to add a new VirtualFramebuffer interface which will need
special consideration at each of the points we flush framebuffer state.

It was a mistake that this API was ever published, we don't believe
anyone is using the api but until we break api we have to keep the
symbol. The documented semantics are vague enough that a NOP is ok since
we never explicitly documented how the state would be flushed to GL so
there would be no way to reliably use that state anyway.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-11-03 13:57:06 +00:00
Rob Bradford
11d38e7ce8 wayland: Port to current Wayland
This change is one logical update to update the Wayland support. This
comprises of the following parts:

* Binding to both the shell and compositor global objects - necessary since
the API for setting top level status moved to the wl_shell interface
* The Wayland visual API went away and instead you setup the EGL surface
appropriately
* The message handling was refined to reflect the current behaviour - now
obsolete comments were removed and new comments updated

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 13:57:01 +00:00
Rob Bradford
00ca539845 wayland: Remove unused function
The function force_roundtrip was unused and required API that was
removed from Wayland.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-03 13:52:37 +00:00
Robert Bragg
061ef6ed06 glx: remove miss leading comment
There was a comment implying that if a rgba config has been requested
but no suitable config was found then we would automatically fall back
to an rgb config instead. Actually if no rgba visual is found we simply
fail without any automatic fall back because Cogl is not in a good
position to judge if automatic fall backs are acceptable for higher
level apis such as clutter.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-11-03 13:52:30 +00:00
Neil Roberts
00f0a66ec9 Use the same number for n_tex_coord_attribs in all linked shaders
On GLES2, we need to specify an array size for the texture coord
varying array. Previously this size would be decided in one of the
following ways:

- For generated vertex shaders it is always the number of layers in
  the pipeline.

- For generated fragment shaders it is the highest sampled texture
  unit in the pipeline or the number of attributes supplied by the
  primitive, whichever is higher.

- For user shaders it is usually the number of attributes supplied by
  the primitive. However, if the application tries to compile the
  shader and query the result before using it, it will always be at
  least 4.

These shaders can quite easily end up with different values for the
declaration which makes it fail to link. This patch changes it so that
all of the shaders are generated with the maximum of the number of
texture attributes supplied by the primitive and the number of layers
in the pipeline. If this value changes then the shaders are
regenerated, including user shaders. That way all of the shaders will
always have the same value.

https://bugzilla.gnome.org/show_bug.cgi?id=662184

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-02 13:50:28 +00:00
Robert Bragg
757916f17a doc: deprecate cogl_texture_get_rowstride()
This documents that cogl_texture_get_rowstride() is deprecated (or
rather it was a mistake that the api was ever published) and also
clarifies the rowstride argument documentation for
cogl_texture_get_data() to explain how it's automatically calculated
when 0 is passed to help avoid misleading people into thinking that
cogl_texture_get_rowstride() is an appropriate way to get a valid
rowstride for that.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-11-02 13:34:14 +00:00
Rico Tzschichholz
567661ccf3 build: add missing header to fix make dist 2011-11-02 07:34:26 -04:00
Zan Dobersek
d8c47e25f2 Remove inclusion of Xlib headers in Cogl headers
Xlib headers define many trivially named objects which can later cause
name collision problems when only cogl.h header is included in a program
or library. Xlib headers are now only included through including the
standalone header cogl-xlib.h.

https://bugzilla.gnome.org/show_bug.cgi?id=661174

Reviewed-by: Robert Bragg <robert@linux.intel.com>
2011-11-01 15:55:53 +00:00
Robert Bragg
e0344468d8 docs: Adds various missing 2.0 sections and symbols
This adds a number of missing sections and symbols to the experimental
2.0 reference manual.
2011-11-01 12:03:04 +00:00
Robert Bragg
e9075931e3 rectangles: rely on meta-texture api for clamping
Instead of emulating _CLAMP_TO_EDGE in cogl-primitives.c we now defer to
cogl_meta_texture_foreach_in_region() to support _CLAMP_TO_EDGE for us.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
2011-11-01 12:03:03 +00:00