<commit_before>/*
 * Cogl
 *
 * An object oriented GL/GLES Abstraction/Utility Layer
 *
 * Copyright (C) 2007,2008,2009 Intel Corporation.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "cogl.h"
#include "cogl-internal.h"
#include "cogl-context.h"
#include "cogl-texture-private.h"
#include "cogl-material-private.h"

#include <string.h>
#include <gmodule.h>
#include <math.h>

#define _COGL_MAX_BEZ_RECURSE_DEPTH 16

#ifdef HAVE_COGL_GL

#define glDrawRangeElements ctx->pf_glDrawRangeElements
#define glClientActiveTexture ctx->pf_glClientActiveTexture

#else

/* GLES doesn't have glDrawRangeElements, so we simply pretend it does
 * but that it makes no use of the start, end constraints: */
#define glDrawRangeElements(mode, start, end, count, type, indices) \
  glDrawElements (mode, count, type, indices)

#endif

/* these are defined in the particular backend */
void _cogl_path_add_node    (gboolean new_sub_path,
			     float x,
                             float y);
void _cogl_path_fill_nodes    ();
void _cogl_path_stroke_nodes  ();

static void
_cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
                                gint              batch_len,
                                GLfloat          *vertex_pointer)
{
  int     needed_indices;
  gsize   stride;
  int     i;
  gulong  enable_flags = 0;
  guint32 disable_mask;
  int     prev_n_texcoord_arrays_enabled;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  /* The indices are always the same sequence regardless of the vertices so we
   * only need to change it if there are more vertices than ever before. */
  needed_indices = batch_len * 6;
  if (needed_indices > ctx->static_indices->len)
    {
      int old_len = ctx->static_indices->len;
      int vert_num = old_len / 6 * 4;
      GLushort *q;

      /* Add two triangles for each quad to the list of
         indices. That makes six new indices but two of the
         vertices in the triangles are shared. */
      g_array_set_size (ctx->static_indices, needed_indices);
      q = &g_array_index (ctx->static_indices, GLushort, old_len);

      for (i = old_len;
           i < ctx->static_indices->len;
           i += 6, vert_num += 4)
        {
          *(q++) = vert_num + 0;
          *(q++) = vert_num + 1;
          *(q++) = vert_num + 3;

          *(q++) = vert_num + 1;
          *(q++) = vert_num + 2;
          *(q++) = vert_num + 3;
        }
    }

  /* XXX NB:
   * Our vertex data is arranged as follows:
   * 4 vertices per quad: 2 GLfloats per position,
   *                      2 GLfloats per tex coord * n_layers
   */
  stride = 2 + 2 * batch_start->n_layers;
  stride *= sizeof (GLfloat);

  disable_mask = (1 << batch_start->n_layers) - 1;
  disable_mask = ~disable_mask;

  _cogl_material_flush_gl_state (ctx->source_material,
                                 COGL_MATERIAL_FLUSH_FALLBACK_MASK,
                                 batch_start->fallback_mask,
                                 COGL_MATERIAL_FLUSH_DISABLE_MASK,
                                 disable_mask,
                                 /* Redundant when dealing with unsliced
                                  * textures but does no harm... */
                                 COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
                                 batch_start->layer0_override_texture,
                                 NULL);

  for (i = 0; i < batch_start->n_layers; i++)
    {
      GE (glClientActiveTexture (GL_TEXTURE0 + i));
      GE (glEnableClientState (GL_TEXTURE_COORD_ARRAY));
      GE (glTexCoordPointer (2, GL_FLOAT, stride, vertex_pointer + 2 + 2 * i));
    }
  prev_n_texcoord_arrays_enabled =
    ctx->n_texcoord_arrays_enabled;
  ctx->n_texcoord_arrays_enabled = batch_start->n_layers;
  for (; i < prev_n_texcoord_arrays_enabled; i++)
    {
      GE (glClientActiveTexture (GL_TEXTURE0 + i));
      GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY));
    }

  /* FIXME: This api is a bit yukky, ideally it will be removed if we
   * re-work the cogl_enable mechanism */
  enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);

  if (ctx->enable_backface_culling)
    enable_flags |= COGL_ENABLE_BACKFACE_CULLING;

  enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
  cogl_enable (enable_flags);

  GE (glVertexPointer (2, GL_FLOAT, stride, vertex_pointer));
  _cogl_current_matrix_state_flush ();
  GE (glDrawRangeElements (GL_TRIANGLES,
                           0, ctx->static_indices->len - 1,
                           6 * batch_len,
                           GL_UNSIGNED_SHORT,
                           ctx->static_indices->data));


  /* DEBUGGING CODE XXX:
   * This path will cause all rectangles to be drawn with a red, green
   * or blue outline with no blending. This may e.g. help with debugging
   * texture slicing issues or blending issues, plus it looks quite cool.
   */
  if (cogl_debug_flags & COGL_DEBUG_RECTANGLES)<commit_msg>[cogl journal] If we are only flushing one quad use a TRIANGLE_FAN<commit_after>/*
 * Cogl
 *
 * An object oriented GL/GLES Abstraction/Utility Layer
 *
 * Copyright (C) 2007,2008,2009 Intel Corporation.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "cogl.h"
#include "cogl-internal.h"
#include "cogl-context.h"
#include "cogl-texture-private.h"
#include "cogl-material-private.h"

#include <string.h>
#include <gmodule.h>
#include <math.h>

#define _COGL_MAX_BEZ_RECURSE_DEPTH 16

#ifdef HAVE_COGL_GL

#define glDrawRangeElements ctx->pf_glDrawRangeElements
#define glClientActiveTexture ctx->pf_glClientActiveTexture

#else

/* GLES doesn't have glDrawRangeElements, so we simply pretend it does
 * but that it makes no use of the start, end constraints: */
#define glDrawRangeElements(mode, start, end, count, type, indices) \
  glDrawElements (mode, count, type, indices)

#endif

/* these are defined in the particular backend */
void _cogl_path_add_node    (gboolean new_sub_path,
			     float x,
                             float y);
void _cogl_path_fill_nodes    ();
void _cogl_path_stroke_nodes  ();

static void
_cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
                                gint              batch_len,
                                GLfloat          *vertex_pointer)
{
  int     needed_indices;
  gsize   stride;
  int     i;
  gulong  enable_flags = 0;
  guint32 disable_mask;
  int     prev_n_texcoord_arrays_enabled;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  /* XXX NB:
   * Our vertex data is arranged as follows:
   * 4 vertices per quad: 2 GLfloats per position,
   *                      2 GLfloats per tex coord * n_layers
   */
  stride = 2 + 2 * batch_start->n_layers;
  stride *= sizeof (GLfloat);

  disable_mask = (1 << batch_start->n_layers) - 1;
  disable_mask = ~disable_mask;

  _cogl_material_flush_gl_state (ctx->source_material,
                                 COGL_MATERIAL_FLUSH_FALLBACK_MASK,
                                 batch_start->fallback_mask,
                                 COGL_MATERIAL_FLUSH_DISABLE_MASK,
                                 disable_mask,
                                 /* Redundant when dealing with unsliced
                                  * textures but does no harm... */
                                 COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
                                 batch_start->layer0_override_texture,
                                 NULL);

  for (i = 0; i < batch_start->n_layers; i++)
    {
      GE (glClientActiveTexture (GL_TEXTURE0 + i));
      GE (glEnableClientState (GL_TEXTURE_COORD_ARRAY));
      GE (glTexCoordPointer (2, GL_FLOAT, stride, vertex_pointer + 2 + 2 * i));
    }
  prev_n_texcoord_arrays_enabled =
    ctx->n_texcoord_arrays_enabled;
  ctx->n_texcoord_arrays_enabled = batch_start->n_layers;
  for (; i < prev_n_texcoord_arrays_enabled; i++)
    {
      GE (glClientActiveTexture (GL_TEXTURE0 + i));
      GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY));
    }

  /* FIXME: This api is a bit yukky, ideally it will be removed if we
   * re-work the cogl_enable mechanism */
  enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);

  if (ctx->enable_backface_culling)
    enable_flags |= COGL_ENABLE_BACKFACE_CULLING;

  enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
  cogl_enable (enable_flags);

  GE (glVertexPointer (2, GL_FLOAT, stride, vertex_pointer));
  _cogl_current_matrix_state_flush ();


  if (batch_len > 1)
    {
      /* The indices are always the same sequence regardless of the vertices so
       * we only need to change it if there are more vertices than ever before.
       */
      needed_indices = batch_len * 6;
      if (needed_indices > ctx->static_indices->len)
        {
          int old_len = ctx->static_indices->len;
          int vert_num = old_len / 6 * 4;
          GLushort *q;

          /* Add two triangles for each quad to the list of
             indices. That makes six new indices but two of the
             vertices in the triangles are shared. */
          g_array_set_size (ctx->static_indices, needed_indices);
          q = &g_array_index (ctx->static_indices, GLushort, old_len);

          for (i = old_len;
               i < ctx->static_indices->len;
               i += 6, vert_num += 4)
            {
              *(q++) = vert_num + 0;
              *(q++) = vert_num + 1;
              *(q++) = vert_num + 3;

              *(q++) = vert_num + 1;
              *(q++) = vert_num + 2;
              *(q++) = vert_num + 3;
            }
        }

      GE (glDrawRangeElements (GL_TRIANGLES,
                               0, ctx->static_indices->len - 1,
                               6 * batch_len,
                               GL_UNSIGNED_SHORT,
                               ctx->static_indices->data));
    }
  else
    {
      GE (glDrawArrays (GL_TRIANGLE_FAN,
                        0, /* first */
                        4)); /* n vertices */
    }


  /* DEBUGGING CODE XXX:
   * This path will cause all rectangles to be drawn with a red, green
   * or blue outline with no blending. This may e.g. help with debugging
   * texture slicing issues or blending issues, plus it looks quite cool.
   */
  if (cogl_debug_flags & COGL_DEBUG_RECTANGLES)
{'fraction_non_alphanumeric': 0.08408664506225481, 'fraction_numerical': 0.010830632781852294, 'mean_word_length': 2.310841332580463, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 62, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7452615', 'n_tokens_mistral': 3723, 'n_tokens_neox': 3477, 'n_words': 1068}