4
* An object oriented GL/GLES Abstraction/Utility Layer
6
* Copyright (C) 2007,2008,2009 Intel Corporation.
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2 of the License, or (at your option) any later version.
13
* This library is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
29
#include "cogl-internal.h"
30
#include "cogl-context.h"
31
#include "cogl-journal-private.h"
32
#include "cogl-texture-private.h"
33
#include "cogl-material-private.h"
34
#include "cogl-vertex-buffer-private.h"
35
#include "cogl-framebuffer-private.h"
36
#include "cogl-profile.h"
42
#define _COGL_MAX_BEZ_RECURSE_DEPTH 16
46
#define glGenBuffers ctx->drv.pf_glGenBuffers
47
#define glBindBuffer ctx->drv.pf_glBindBuffer
48
#define glBufferData ctx->drv.pf_glBufferData
49
#define glBufferSubData ctx->drv.pf_glBufferSubData
50
#define glDeleteBuffers ctx->drv.pf_glDeleteBuffers
51
#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture
53
#elif defined (HAVE_COGL_GLES2)
55
#include "../gles/cogl-gles2-wrapper.h"
60
* Our journal's vertex data is arranged as follows:
61
* 4 vertices per quad:
62
* 2 or 3 GLfloats per position (3 when doing software transforms)
64
* 2 GLfloats per tex coord * n_layers
66
* Where n_layers corresponds to the number of material layers enabled
68
* To avoid frequent changes in the stride of our vertex data we always pad
71
* When we are transforming quads in software we need to also track the z
72
* coordinate of transformed vertices.
74
* So for a given number of layers this gets the stride in 32bit words:
76
#define SW_TRANSFORM (!(cogl_debug_flags & \
77
COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))
78
#define POS_STRIDE (SW_TRANSFORM ? 3 : 2) /* number of 32bit words */
79
#define N_POS_COMPONENTS POS_STRIDE
80
#define COLOR_STRIDE 1 /* number of 32bit words */
81
#define TEX_STRIDE 2 /* number of 32bit words */
82
#define MIN_LAYER_PADING 2
83
#define GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS(N_LAYERS) \
84
(POS_STRIDE + COLOR_STRIDE + \
85
TEX_STRIDE * (N_LAYERS < MIN_LAYER_PADING ? MIN_LAYER_PADING : N_LAYERS))
87
typedef CoglVertexBufferIndices CoglJournalIndices;
89
typedef struct _CoglJournalFlushState
92
/* Note: this is a pointer to handle fallbacks. It normally holds a VBO
93
* offset, but when the driver doesn't support VBOs then this points into
94
* our GArray of logged vertices. */
98
CoglJournalIndices *indices;
99
gsize indices_type_size;
101
CoglMatrixStack *modelview_stack;
102
} CoglJournalFlushState;
104
typedef void (*CoglJournalBatchCallback) (CoglJournalEntry *start,
107
typedef gboolean (*CoglJournalBatchTest) (CoglJournalEntry *entry0,
108
CoglJournalEntry *entry1);
111
_cogl_journal_dump_quad_vertices (guint8 *data, int n_layers)
113
gsize stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (n_layers);
116
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
118
g_print ("n_layers = %d; stride = %d; pos stride = %d; color stride = %d; "
119
"tex stride = %d; stride in bytes = %d\n",
120
n_layers, (int)stride, POS_STRIDE, COLOR_STRIDE,
121
TEX_STRIDE, (int)stride * 4);
123
for (i = 0; i < 4; i++)
125
float *v = (float *)data + (i * stride);
126
guint8 *c = data + (POS_STRIDE * 4) + (i * stride * 4);
129
if (G_UNLIKELY (cogl_debug_flags &
130
COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))
131
g_print ("v%d: x = %f, y = %f, rgba=0x%02X%02X%02X%02X",
132
i, v[0], v[1], c[0], c[1], c[2], c[3]);
134
g_print ("v%d: x = %f, y = %f, z = %f, rgba=0x%02X%02X%02X%02X",
135
i, v[0], v[1], v[2], c[0], c[1], c[2], c[3]);
136
for (j = 0; j < n_layers; j++)
138
float *t = v + POS_STRIDE + COLOR_STRIDE + TEX_STRIDE * j;
139
g_print (", tx%d = %f, ty%d = %f", j, t[0], j, t[1]);
146
_cogl_journal_dump_quad_batch (guint8 *data, int n_layers, int n_quads)
148
gsize byte_stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (n_layers) * 4;
151
g_print ("_cogl_journal_dump_quad_batch: n_layers = %d, n_quads = %d\n",
153
for (i = 0; i < n_quads; i++)
154
_cogl_journal_dump_quad_vertices (data + byte_stride * 4 * i, n_layers);
158
batch_and_call (CoglJournalEntry *entries,
160
CoglJournalBatchTest can_batch_callback,
161
CoglJournalBatchCallback batch_callback,
166
CoglJournalEntry *batch_start = entries;
171
for (i = 1; i < n_entries; i++)
173
CoglJournalEntry *entry0 = &entries[i - 1];
174
CoglJournalEntry *entry1 = entry0 + 1;
176
if (can_batch_callback (entry0, entry1))
182
batch_callback (batch_start, batch_len, data);
184
batch_start = entry1;
188
/* The last batch... */
189
batch_callback (batch_start, batch_len, data);
193
_cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
197
CoglJournalFlushState *state = data;
199
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_BATCHING))
200
g_print ("BATCHING: modelview batch len = %d\n", batch_len);
202
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))
204
_cogl_matrix_stack_set (state->modelview_stack,
205
&batch_start->model_view);
206
_cogl_matrix_stack_flush_to_gl (state->modelview_stack,
207
COGL_MATRIX_MODELVIEW);
212
GE (glDrawArrays (GL_QUADS, state->vertex_offset, batch_len * 4));
214
#else /* HAVE_COGL_GL */
218
int indices_offset = (state->vertex_offset / 4) * 6;
219
GE (glDrawElements (GL_TRIANGLES,
221
state->indices->type,
222
(GLvoid*)(indices_offset * state->indices_type_size)));
226
GE (glDrawArrays (GL_TRIANGLE_FAN,
227
state->vertex_offset, /* first */
228
4)); /* n vertices */
232
/* DEBUGGING CODE XXX: This path will cause all rectangles to be
233
* drawn with a coloured outline. Each batch will be rendered with
234
* the same color. This may e.g. help with debugging texture slicing
235
* issues, visually seeing what is batched and debugging blending
236
* issues, plus it looks quite cool.
238
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_RECTANGLES))
240
static CoglHandle outline = COGL_INVALID_HANDLE;
241
guint8 color_intensity;
244
_COGL_GET_CONTEXT (ctxt, NO_RETVAL);
246
if (outline == COGL_INVALID_HANDLE)
247
outline = cogl_material_new ();
249
/* The least significant three bits represent the three
250
components so that the order of colours goes red, green,
251
yellow, blue, magenta, cyan. Black and white are skipped. The
252
next two bits give four scales of intensity for those colours
253
in the order 0xff, 0xcc, 0x99, and 0x66. This gives a total
254
of 24 colours. If there are more than 24 batches on the stage
255
then it will wrap around */
256
color_intensity = 0xff - 0x33 * (ctxt->journal_rectangles_color >> 3);
257
cogl_material_set_color4ub (outline,
258
(ctxt->journal_rectangles_color & 1) ?
260
(ctxt->journal_rectangles_color & 2) ?
262
(ctxt->journal_rectangles_color & 4) ?
265
_cogl_material_flush_gl_state (outline, NULL);
266
cogl_enable (COGL_ENABLE_VERTEX_ARRAY);
267
for (i = 0; i < batch_len; i++)
268
GE( glDrawArrays (GL_LINE_LOOP, 4 * i + state->vertex_offset, 4) );
270
/* Go to the next color */
272
ctxt->journal_rectangles_color = ((ctxt->journal_rectangles_color + 1) &
274
/* We don't want to use black or white */
275
while ((ctxt->journal_rectangles_color & 0x07) == 0
276
|| (ctxt->journal_rectangles_color & 0x07) == 0x07);
279
state->vertex_offset += (4 * batch_len);
283
compare_entry_modelviews (CoglJournalEntry *entry0,
284
CoglJournalEntry *entry1)
286
/* Batch together quads with the same model view matrix */
288
/* FIXME: this is nasty, there are much nicer ways to track this
289
* (at the add_quad_vertices level) without resorting to a memcmp!
291
* E.g. If the cogl-current-matrix code maintained an "age" for
292
* the modelview matrix we could simply check in add_quad_vertices
293
* if the age has increased, and if so record the change as a
294
* boolean in the journal.
297
if (memcmp (&entry0->model_view, &entry1->model_view,
298
sizeof (GLfloat) * 16) == 0)
304
/* At this point we have a run of quads that we know have compatible
305
* materials, but they may not all have the same modelview matrix */
307
_cogl_journal_flush_material_and_entries (CoglJournalEntry *batch_start,
311
unsigned long enable_flags = 0;
313
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
315
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_BATCHING))
316
g_print ("BATCHING: material batch len = %d\n", batch_len);
318
_cogl_material_flush_gl_state (batch_start->material,
319
&batch_start->flush_options);
321
/* FIXME: This api is a bit yukky, ideally it will be removed if we
322
* re-work the cogl_enable mechanism */
323
enable_flags |= _cogl_material_get_cogl_enable_flags (batch_start->material);
325
if (ctx->enable_backface_culling)
326
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
328
enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
329
enable_flags |= COGL_ENABLE_COLOR_ARRAY;
330
cogl_enable (enable_flags);
331
_cogl_flush_face_winding ();
333
/* If we haven't transformed the quads in software then we need to also break
334
* up batches according to changes in the modelview matrix... */
335
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))
337
batch_and_call (batch_start,
339
compare_entry_modelviews,
340
_cogl_journal_flush_modelview_and_entries,
344
_cogl_journal_flush_modelview_and_entries (batch_start, batch_len, data);
348
compare_entry_materials (CoglJournalEntry *entry0, CoglJournalEntry *entry1)
350
/* batch rectangles using compatible materials */
352
/* XXX: _cogl_material_equal may give false negatives since it avoids
353
* deep comparisons as an optimization. It aims to compare enough so
354
* that we that we are able to batch the 90% common cases, but may not
355
* look at less common differences. */
356
if (_cogl_material_equal (entry0->material,
357
&entry0->flush_options,
359
&entry1->flush_options))
365
/* Since the stride may not reflect the number of texture layers in use
366
* (due to padding) we deal with texture coordinate offsets separately
367
* from vertex and color offsets... */
369
_cogl_journal_flush_texcoord_vbo_offsets_and_entries (
370
CoglJournalEntry *batch_start,
374
CoglJournalFlushState *state = data;
375
int prev_n_texcoord_arrays_enabled;
378
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
380
for (i = 0; i < batch_start->n_layers; i++)
382
GE (glClientActiveTexture (GL_TEXTURE0 + i));
383
GE (glEnableClientState (GL_TEXTURE_COORD_ARRAY));
385
* Our journal's vertex data is arranged as follows:
386
* 4 vertices per quad:
387
* 2 or 3 GLfloats per position (3 when doing software transforms)
389
* 2 GLfloats per tex coord * n_layers
390
* (though n_layers may be padded; see definition of
391
* GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS for details)
393
GE (glTexCoordPointer (2, GL_FLOAT, state->stride,
394
(void *)(state->vbo_offset +
395
(POS_STRIDE + COLOR_STRIDE) * 4 +
396
TEX_STRIDE * 4 * i)));
398
prev_n_texcoord_arrays_enabled =
399
ctx->n_texcoord_arrays_enabled;
400
ctx->n_texcoord_arrays_enabled = batch_start->n_layers;
401
for (; i < prev_n_texcoord_arrays_enabled; i++)
403
GE (glClientActiveTexture (GL_TEXTURE0 + i));
404
GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY));
407
batch_and_call (batch_start,
409
compare_entry_materials,
410
_cogl_journal_flush_material_and_entries,
415
compare_entry_n_layers (CoglJournalEntry *entry0, CoglJournalEntry *entry1)
417
if (entry0->n_layers == entry1->n_layers)
423
/* At this point we know the stride has changed from the previous batch
424
* of journal entries */
426
_cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start,
430
CoglJournalFlushState *state = data;
433
int needed_indices = batch_len * 6;
434
CoglHandle indices_handle;
435
CoglVertexBufferIndices *indices;
438
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
440
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_BATCHING))
441
g_print ("BATCHING: vbo offset batch len = %d\n", batch_len);
444
* Our journal's vertex data is arranged as follows:
445
* 4 vertices per quad:
446
* 2 or 3 GLfloats per position (3 when doing software transforms)
448
* 2 GLfloats per tex coord * n_layers
449
* (though n_layers may be padded; see definition of
450
* GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS for details)
452
stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (batch_start->n_layers);
453
stride *= sizeof (GLfloat);
454
state->stride = stride;
456
GE (glVertexPointer (N_POS_COMPONENTS, GL_FLOAT, stride,
457
(void *)state->vbo_offset));
458
GE (glColorPointer (4, GL_UNSIGNED_BYTE, stride,
459
(void *)(state->vbo_offset + (POS_STRIDE * 4))));
462
indices_handle = cogl_vertex_buffer_indices_get_for_quads (needed_indices);
463
indices = _cogl_vertex_buffer_indices_pointer_from_handle (indices_handle);
464
state->indices = indices;
466
if (indices->type == GL_UNSIGNED_BYTE)
467
state->indices_type_size = 1;
468
else if (indices->type == GL_UNSIGNED_SHORT)
469
state->indices_type_size = 2;
471
g_critical ("unknown indices type %d", indices->type);
473
GE (glBindBuffer (GL_ELEMENT_ARRAY_BUFFER,
474
GPOINTER_TO_UINT (indices->vbo_name)));
477
/* We only call gl{Vertex,Color,Texture}Pointer when the stride within
478
* the VBO changes. (due to a change in the number of material layers)
479
* While the stride remains constant we walk forward through the above
480
* VBO using a vertex offset passed to glDraw{Arrays,Elements} */
481
state->vertex_offset = 0;
483
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_JOURNAL))
487
if (cogl_get_features () & COGL_FEATURE_VBOS)
488
verts = ((guint8 *)ctx->logged_vertices->data) +
489
(size_t)state->vbo_offset;
491
verts = (guint8 *)state->vbo_offset;
492
_cogl_journal_dump_quad_batch (verts,
493
batch_start->n_layers,
497
batch_and_call (batch_start,
499
compare_entry_n_layers,
500
_cogl_journal_flush_texcoord_vbo_offsets_and_entries,
503
/* progress forward through the VBO containing all our vertices */
504
state->vbo_offset += (stride * 4 * batch_len);
505
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_JOURNAL))
506
g_print ("new vbo offset = %lu\n", (unsigned long)state->vbo_offset);
510
compare_entry_strides (CoglJournalEntry *entry0, CoglJournalEntry *entry1)
512
/* Currently the only thing that affects the stride for our vertex arrays
513
* is the number of material layers. We need to update our VBO offsets
514
* whenever the stride changes. */
515
/* TODO: We should be padding the n_layers == 1 case as if it were
516
* n_layers == 2 so we can reduce the need to split batches. */
517
if (entry0->n_layers == entry1->n_layers ||
518
(entry0->n_layers <= MIN_LAYER_PADING &&
519
entry1->n_layers <= MIN_LAYER_PADING))
526
upload_vertices_to_vbo (GArray *vertices, CoglJournalFlushState *state)
528
gsize needed_vbo_len;
531
_COGL_GET_CONTEXT (ctx, 0);
533
needed_vbo_len = vertices->len * sizeof (GLfloat);
535
g_assert (needed_vbo_len);
536
GE (glGenBuffers (1, &journal_vbo));
537
GE (glBindBuffer (GL_ARRAY_BUFFER, journal_vbo));
538
GE (glBufferData (GL_ARRAY_BUFFER,
543
/* As we flush the journal entries in batches we walk forward through the
544
* above VBO starting at offset 0... */
545
state->vbo_offset = 0;
550
/* XXX NB: When _cogl_journal_flush() returns all state relating
551
* to materials, all glEnable flags and current matrix state
555
_cogl_journal_flush (void)
557
CoglJournalFlushState state;
560
gboolean vbo_fallback =
561
(cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
562
CoglHandle framebuffer;
563
CoglMatrixStack *modelview_stack;
564
COGL_STATIC_TIMER (flush_timer,
565
"Mainloop", /* parent */
567
"The time spent flushing the Cogl journal",
568
0 /* no application private data */);
570
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
572
if (ctx->journal->len == 0)
575
COGL_TIMER_START (_cogl_uprof_context, flush_timer);
577
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_BATCHING))
578
g_print ("BATCHING: journal len = %d\n", ctx->journal->len);
580
/* Load all the vertex data we have accumulated so far into a single VBO
581
* to minimize memory management costs within the GL driver. */
583
journal_vbo = upload_vertices_to_vbo (ctx->logged_vertices, &state);
585
state.vbo_offset = (char *)ctx->logged_vertices->data;
587
framebuffer = _cogl_get_framebuffer ();
588
modelview_stack = _cogl_framebuffer_get_modelview_stack (framebuffer);
589
state.modelview_stack = modelview_stack;
591
_cogl_matrix_stack_push (modelview_stack);
593
/* If we have transformed all our quads at log time then we ensure no
594
* further model transform is applied by loading the identity matrix
596
if (G_LIKELY (!(cogl_debug_flags & COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM)))
598
_cogl_matrix_stack_load_identity (modelview_stack);
599
_cogl_matrix_stack_flush_to_gl (modelview_stack, COGL_MATRIX_MODELVIEW);
602
/* batch_and_call() batches a list of journal entries according to some
603
* given criteria and calls a callback once for each determined batch.
605
* The process of flushing the journal is staggered to reduce the amount
606
* of driver/GPU state changes necessary:
607
* 1) We split the entries according to the stride of the vertices:
608
* Each time the stride of our vertex data changes we need to call
609
* gl{Vertex,Color}Pointer to inform GL of new VBO offsets.
610
* Currently the only thing that affects the stride of our vertex data
611
* is the number of material layers.
612
* 2) We split the entries explicitly by the number of material layers:
613
* We pad our vertex data when the number of layers is < 2 so that we
614
* can minimize changes in stride. Each time the number of layers
615
* changes we need to call glTexCoordPointer to inform GL of new VBO
617
* 3) We then split according to compatible Cogl materials:
618
* This is where we flush material state
619
* 4) Finally we split according to modelview matrix changes:
620
* This is when we finally tell GL to draw something.
621
* Note: Splitting by modelview changes is skipped when are doing the
622
* vertex transformation in software at log time.
624
batch_and_call ((CoglJournalEntry *)ctx->journal->data, /* first entry */
625
ctx->journal->len, /* max number of entries to consider */
626
compare_entry_strides,
627
_cogl_journal_flush_vbo_offsets_and_entries, /* callback */
630
_cogl_matrix_stack_pop (modelview_stack);
632
for (i = 0; i < ctx->journal->len; i++)
634
CoglJournalEntry *entry =
635
&g_array_index (ctx->journal, CoglJournalEntry, i);
636
_cogl_material_journal_unref (entry->material);
640
GE (glDeleteBuffers (1, &journal_vbo));
642
g_array_set_size (ctx->journal, 0);
643
g_array_set_size (ctx->logged_vertices, 0);
645
COGL_TIMER_STOP (_cogl_uprof_context, flush_timer);
649
_cogl_journal_init (void)
651
/* Here we flush anything that we know must remain constant until the
652
* next the the journal is flushed. Note: This lets up flush things
653
* that themselves depend on the journal, such as clip state. */
655
/* NB: the journal deals with flushing the modelview stack manually */
656
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (),
657
COGL_FRAMEBUFFER_FLUSH_SKIP_MODELVIEW);
661
_cogl_journal_log_quad (const float *position,
664
guint32 fallback_layers,
665
GLuint layer0_override_texture,
666
const float *tex_coords,
667
unsigned int tex_coords_len)
677
guint32 disable_layers;
678
CoglJournalEntry *entry;
679
COGL_STATIC_TIMER (log_timer,
680
"Mainloop", /* parent */
682
"The time spent logging in the Cogl journal",
683
0 /* no application private data */);
685
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
687
COGL_TIMER_START (_cogl_uprof_context, log_timer);
689
if (ctx->logged_vertices->len == 0)
690
_cogl_journal_init ();
692
/* The vertex data is logged into a separate array in a layout that can be
693
* directly passed to OpenGL
696
/* XXX: See definition of GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS for details
697
* about how we pack our vertex data */
698
stride = GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS (n_layers);
699
/* NB: stride is in 32bit words */
700
byte_stride = stride * 4;
702
next_vert = ctx->logged_vertices->len;
703
g_array_set_size (ctx->logged_vertices, next_vert + 4 * stride);
704
v = &g_array_index (ctx->logged_vertices, GLfloat, next_vert);
705
c = (GLubyte *)(v + POS_STRIDE);
707
/* XXX: All the jumping around to fill in this strided buffer doesn't
710
/* XXX: we could defer expanding the vertex data for GL until we come
711
* to flushing the journal. */
713
/* FIXME: This is a hacky optimization, since it will break if we
714
* change the definition of CoglColor: */
715
_cogl_material_get_colorubv (material, c);
717
for (i = 0; i < 3; i++)
720
memcpy (c, src_c, 4);
728
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))
730
v[0] = position[X0]; v[1] = position[Y0];
732
v[0] = position[X0]; v[1] = position[Y1];
734
v[0] = position[X1]; v[1] = position[Y1];
736
v[0] = position[X1]; v[1] = position[Y0];
743
cogl_get_modelview_matrix (&mv);
745
x = position[X0], y = position[Y0], z = 0; w = 1;
746
cogl_matrix_transform_point (&mv, &x, &y, &z, &w);
747
v[0] = x; v[1] = y; v[2] = z;
749
x = position[X0], y = position[Y1], z = 0; w = 1;
750
cogl_matrix_transform_point (&mv, &x, &y, &z, &w);
751
v[0] = x; v[1] = y; v[2] = z;
753
x = position[X1], y = position[Y1], z = 0; w = 1;
754
cogl_matrix_transform_point (&mv, &x, &y, &z, &w);
755
v[0] = x; v[1] = y; v[2] = z;
757
x = position[X1], y = position[Y0], z = 0; w = 1;
758
cogl_matrix_transform_point (&mv, &x, &y, &z, &w);
759
v[0] = x; v[1] = y; v[2] = z;
767
for (i = 0; i < n_layers; i++)
769
/* XXX: See definition of GET_JOURNAL_VB_STRIDE_FOR_N_LAYERS for details
770
* about how we pack our vertex data */
771
GLfloat *t = &g_array_index (ctx->logged_vertices, GLfloat,
772
next_vert + POS_STRIDE +
773
COLOR_STRIDE + TEX_STRIDE * i);
775
t[0] = tex_coords[i * 4 + 0]; t[1] = tex_coords[i * 4 + 1];
777
t[0] = tex_coords[i * 4 + 0]; t[1] = tex_coords[i * 4 + 3];
779
t[0] = tex_coords[i * 4 + 2]; t[1] = tex_coords[i * 4 + 3];
781
t[0] = tex_coords[i * 4 + 2]; t[1] = tex_coords[i * 4 + 1];
784
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_JOURNAL))
786
g_print ("Logged new quad:\n");
787
v = &g_array_index (ctx->logged_vertices, GLfloat, next_vert);
788
_cogl_journal_dump_quad_vertices ((guint8 *)v, n_layers);
791
next_entry = ctx->journal->len;
792
g_array_set_size (ctx->journal, next_entry + 1);
793
entry = &g_array_index (ctx->journal, CoglJournalEntry, next_entry);
795
disable_layers = (1 << n_layers) - 1;
796
disable_layers = ~disable_layers;
798
entry->material = _cogl_material_journal_ref (material);
799
entry->n_layers = n_layers;
800
entry->flush_options.flags =
801
COGL_MATERIAL_FLUSH_FALLBACK_MASK |
802
COGL_MATERIAL_FLUSH_DISABLE_MASK |
803
COGL_MATERIAL_FLUSH_SKIP_GL_COLOR;
804
entry->flush_options.fallback_layers = fallback_layers;
805
entry->flush_options.disable_layers = disable_layers;
806
if (layer0_override_texture)
808
entry->flush_options.flags |= COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE;
809
entry->flush_options.layer0_override_texture = layer0_override_texture;
811
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM))
812
cogl_get_modelview_matrix (&entry->model_view);
814
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_BATCHING))
815
_cogl_journal_flush ();
817
COGL_TIMER_STOP (_cogl_uprof_context, log_timer);