Пример #1
0
/* should only be called once on initialization */
void
dropbox_client_setup(DropboxClient *dc) {
  caja_dropbox_hooks_setup(&(dc->hookserv));
  dropbox_command_client_setup(&(dc->dcc));

  g_hook_list_init(&(dc->ondisconnect_hooklist), sizeof(GHook));
  g_hook_list_init(&(dc->onconnect_hooklist), sizeof(GHook));

  dc->hook_disconnect_called = dc->command_disconnect_called = FALSE;
  dc->hook_connect_called = dc->command_connect_called = FALSE;

  caja_dropbox_hooks_add_on_connect_hook(&(dc->hookserv), 
					     (DropboxHookClientConnectHook)
					     hook_on_connect, dc);
  
  dropbox_command_client_add_on_connect_hook(&(dc->dcc),
					     (DropboxCommandClientConnectHook)
					     command_on_connect, dc);
  
  caja_dropbox_hooks_add_on_disconnect_hook(&(dc->hookserv), 
						(DropboxHookClientConnectHook)
						hook_on_disconnect, dc);
  
  dropbox_command_client_add_on_disconnect_hook(&(dc->dcc),
						(DropboxCommandClientConnectHook)
						command_on_disconnect, dc);
}
/* should only be called once on initialization */
void
dropbox_command_client_setup(DropboxCommandClient *dcc) {
  dcc->command_queue = g_async_queue_new();
  dcc->command_connected_mutex = g_mutex_new();
  dcc->command_connected = FALSE;
  dcc->ca_hooklist = NULL;

  g_hook_list_init(&(dcc->ondisconnect_hooklist), sizeof(GHook));
  g_hook_list_init(&(dcc->onconnect_hooklist), sizeof(GHook));
}
void
nautilus_dropbox_hooks_setup(NautilusDropboxHookserv *hookserv) {
  hookserv->dispatch_table = g_hash_table_new_full((GHashFunc) g_str_hash,
						   (GEqualFunc) g_str_equal,
						   g_free, g_free);
  hookserv->connected = FALSE;

  g_hook_list_init(&(hookserv->ondisconnect_hooklist), sizeof(GHook));
  g_hook_list_init(&(hookserv->onconnect_hooklist), sizeof(GHook));
}
Пример #4
0
void
gnc_gconf_general_register_cb (const gchar *key,
                               GncGconfGeneralCb func,
                               gpointer user_data)
{
    GHookList *hook_list;
    GHook *hook;

    g_once(&gcb_init_once, gcb_init, NULL);
    hook_list = g_hash_table_lookup(gcb_callback_hash, key);
    if (hook_list == NULL)
    {
        hook_list = g_malloc(sizeof(GHookList));
        g_hook_list_init(hook_list, sizeof(GHook));
        g_hash_table_insert(gcb_callback_hash, (gpointer)key, hook_list);
    }

    hook = g_hook_find_func_data(hook_list, TRUE, func, user_data);
    if (hook != NULL)
    {
        return;
    }

    hook = g_hook_alloc(hook_list);
    hook->func = func;
    hook->data = user_data;
    g_hook_append(hook_list, hook);
}
Пример #5
0
 /*
 * initiate a gfal's context with default parameters for use
 */
gfal2_context_t gfal_initG (GError** err)
{
	GError* tmp_err=NULL;
	gfal2_context_t handle = g_new0(struct gfal_handle_,1);// clear allocation of the struct and set defautl options
	if(handle == NULL){
		errno= ENOMEM;
        g_set_error(err, gfal2_get_plugins_quark(), ENOMEM, "[gfal_initG] bad allocation, no more memory free");
		return NULL;
	}
	handle->plugin_opt.plugin_number= 0;

    if((handle->conf = gfal_conf_new(&tmp_err)) && !tmp_err){
        // load and instanciate all the plugins
        gfal_plugins_instance(handle, &tmp_err);
        // cancel logic init
        handle->cancel = FALSE;
        handle->running_ops = 0;
        handle->mux_cancel = g_mutex_new();
        g_hook_list_init(&handle->cancel_hooks, sizeof(GHook));
    }


    if(tmp_err){
        if (handle && handle->conf)
            gfal_conf_delete(handle->conf);
        g_free(handle);
        handle = NULL;
    }
    G_RETURN_ERR(handle, tmp_err, err);
}
Пример #6
0
CoglPangoGlyphCache *
cogl_pango_glyph_cache_new (CoglContext *ctx,
                            gboolean use_mipmapping)
{
  CoglPangoGlyphCache *cache;

  cache = g_malloc (sizeof (CoglPangoGlyphCache));

  /* Note: as a rule we don't take references to a CoglContext
   * internally since */
  cache->ctx = ctx;

  cache->hash_table = g_hash_table_new_full
    (cogl_pango_glyph_cache_hash_func,
     cogl_pango_glyph_cache_equal_func,
     (GDestroyNotify) cogl_pango_glyph_cache_key_free,
     (GDestroyNotify) cogl_pango_glyph_cache_value_free);

  cache->atlases = NULL;
  g_hook_list_init (&cache->reorganize_callbacks, sizeof (GHook));

  cache->has_dirty_glyphs = FALSE;

  cache->using_global_atlas = FALSE;

  cache->use_mipmapping = use_mipmapping;

  return cache;
}
Пример #7
0
CoglAtlas *
_cogl_atlas_new (CoglPixelFormat texture_format,
                 CoglAtlasFlags flags,
                 CoglAtlasUpdatePositionCallback update_position_cb)
{
  CoglAtlas *atlas = g_new (CoglAtlas, 1);

  atlas->update_position_cb = update_position_cb;
  atlas->map = NULL;
  atlas->texture = NULL;
  atlas->flags = flags;
  atlas->texture_format = texture_format;
  g_hook_list_init (&atlas->pre_reorganize_callbacks, sizeof (GHook));
  g_hook_list_init (&atlas->post_reorganize_callbacks, sizeof (GHook));

  return _cogl_atlas_object_new (atlas);
}
Пример #8
0
static gpointer
gcb_init (gpointer unused)
{
    gcb_callback_hash = g_hash_table_new(g_str_hash, g_str_equal);

    gcb_final_hook_list = g_malloc(sizeof(GHookList));
    g_hook_list_init(gcb_final_hook_list, sizeof(GHook));
    return NULL;
}
Пример #9
0
static void
kiro_sb_init (KiroSb *self)
{
    g_return_if_fail (self != NULL);
    KiroSbPrivate *priv = KIRO_SB_GET_PRIVATE (self);
    priv->initialized = 0;
    priv->trb = NULL;
    priv->server = NULL;
    priv->client = NULL;
    priv->freeze = FALSE;
    g_hook_list_init (&(priv->callbacks), sizeof (GHook));
}
Пример #10
0
gchar *
gnc_hook_create (const gchar *name, gint num_args, const gchar *desc)
{
    GncHook *hook_list;

    g_return_val_if_fail(name != NULL, NULL);
    g_return_val_if_fail(num_args <= 1, NULL);
    g_return_val_if_fail(desc != NULL, NULL);

    ENTER("name %s", name);
    if (gnc_hooks_list == NULL)
    {
        gnc_hooks_list = g_hash_table_new(g_str_hash, g_str_equal);

        /* If we're not initialized then initialize now */
        if (!gnc_hooks_initialized)
            gnc_hooks_init();
    }

    hook_list = g_hash_table_lookup(gnc_hooks_list, name);
    if (hook_list)
    {
        LEAVE("List %s(%p) already exists", name, hook_list);
        return((gchar*)name);
    }

    hook_list = new GncHook;//g_new0(GncHook, 1);
    hook_list->desc = g_strdup(desc);
    hook_list->c_danglers = g_malloc(sizeof(GHookList));
    g_hook_list_init(hook_list->c_danglers, sizeof(GHook));
    hook_list->scm_danglers = g_malloc(sizeof(GHookList));
    hook_list->num_args = num_args;
    g_hook_list_init(hook_list->scm_danglers, sizeof(GHook));
    g_hash_table_insert(gnc_hooks_list, (gchar *)name, hook_list);

    LEAVE("created list %s(%p)", name, hook_list);
    return (gchar *)name;
}
Пример #11
0
static DeskmenuObject
*deskmenu_object_init (void) {
	DeskmenuObject *dm_object = g_slice_new0 (DeskmenuObject);

	dm_object->menu = NULL;
    dm_object->current_menu = NULL;
    dm_object->current_item = NULL;
    dm_object->make_from_pipe = FALSE;
    dm_object->pin_items = NULL;
	dm_object->show_hooks = g_slice_new0 (GHookList);

    g_hook_list_init (dm_object->show_hooks, sizeof (GHook));

	return dm_object;
}
guint 
g_source_add (gint           priority,
	      gboolean       can_recurse,
	      GSourceFuncs  *funcs,
	      gpointer       source_data, 
	      gpointer       user_data,
	      GDestroyNotify notify)
{
  guint return_val;
  GSource *source;

  G_LOCK (main_loop);

  if (!source_list.is_setup)
    {
      g_hook_list_init (&source_list, sizeof (GSource));

      source_list.hook_destroy = G_HOOK_DEFERRED_DESTROY;
      source_list.hook_free = g_source_destroy_func;
    }

  source = (GSource*) g_hook_alloc (&source_list);
  source->priority = priority;
  source->source_data = source_data;
  source->hook.func = funcs;
  source->hook.data = user_data;
  source->hook.destroy = notify;
  
  g_hook_insert_sorted (&source_list, 
			(GHook *)source, 
			g_source_compare);

  if (can_recurse)
    source->hook.flags |= G_SOURCE_CAN_RECURSE;

  return_val = source->hook.hook_id;

#ifdef G_THREADS_ENABLED
  /* Now wake up the main loop if it is waiting in the poll() */
  g_main_wakeup ();
#endif

  G_UNLOCK (main_loop);

  return return_val;
}
Пример #13
0
void
qof_session_add_close_hook (GFunc fn, gpointer data)
{
    GHook *hook;

    if (session_closed_hooks == NULL)
    {
        session_closed_hooks = static_cast<GHookList*>(malloc(sizeof(GHookList))); /* LEAKED */
        g_hook_list_init (session_closed_hooks, sizeof(GHook));
    }

    hook = g_hook_alloc(session_closed_hooks);
    if (!hook)
        return;

    hook->func = reinterpret_cast<void*>(fn);
    hook->data = data;
    g_hook_append(session_closed_hooks, hook);
}
Пример #14
0
void
qof_session_add_close_hook (GFunc fn, gpointer data)
{
    GHook *hook;

    if (session_closed_hooks == NULL)
    {
        session_closed_hooks = malloc(sizeof(GHookList)); /* LEAKED */
        g_hook_list_init (session_closed_hooks, sizeof(GHook));
    }

    hook = g_hook_alloc(session_closed_hooks);
    if (!hook)
        return;

    hook->func = (GHookFunc)fn;
    hook->data = data;
    g_hook_append(session_closed_hooks, hook);
}
Пример #15
0
void
gth_hook_register (const char *name,
	           int         n_args)
{
	GthHook *hook;

	g_return_if_fail (name != NULL);
	g_return_if_fail ((n_args >= 0) || (n_args <= 4));

	if (g_hash_table_lookup (hooks, name) != NULL) {
		g_warning ("hook '%s' already registered", name);
		return;
	}

	hook = g_new0 (GthHook, 1);
	hook->list = g_new (GHookList, 1);
	g_hook_list_init (hook->list, sizeof (GthHookCallback));
	hook->n_args = n_args;

	g_hash_table_insert (hooks, g_strdup (name), hook);
}
void prefs_register(
	const gchar * name,
	enum prefs_type type,
	const gchar * description,
	prefs_validator_func * validator_func,
	gpointer validator_user_data)
{
	struct prefs_value * value;

	g_assert(name && description);
	g_assert(prefs_hash != NULL);

	/* setup preference value struct */
	value = g_new(struct prefs_value, 1);

	value->description = g_strdup(description);
	value->type = type;
	switch(type) {
	case PREFS_TYPE_BOOL:
		value->value.boolean = FALSE;
		break;
	case PREFS_TYPE_STR:
		value->value.string = g_strdup("");
		break;
	case PREFS_TYPE_UINT:
		value->value.integer = 0;
		break;
	case PREFS_TYPE_LIST:
		value->value.list = NULL;
		break;
	}

	value->validator_func = validator_func;
	value->validator_user_data = validator_user_data;

	g_hook_list_init(&value->change_hook, sizeof(GHook));

	/* add it into the prefs hash */
	g_hash_table_insert(prefs_hash, g_strdup(name), value);
}
Пример #17
0
/**
 * Add an InitFunc to the hooklist with the name 'name'
 */
void
NamedInitFuncAdd(const char *name, InitFuncPriority priority, InitFunc func, const char *func_name)
{
    if (!namedInitFuncs)
    {
        namedInitFuncs = g_hash_table_new(g_str_hash, g_str_equal);
        if (!namedInitFuncs)
        {
            g_error("%s: Out of memory on initialization.\n", __FUNCTION__);
            abort();
        }
    }

    if (g_hash_table_lookup(namedInitFuncs, (gconstpointer)name) == NULL)
    {
        GNamedHookList *namedHookList = malloc(sizeof (GNamedHookList));
        if (!namedHookList)
        {
            g_error("%s: Out of memory on initialization.\n", __FUNCTION__);
            abort();
        }
        g_hook_list_init((GHookList*)namedHookList, sizeof(GPrioritizedHook));

        namedHookList->name = name;
       
        g_hash_table_insert(namedInitFuncs, (char*)name, namedHookList);
    }

    GHookList *hookList = (GHookList*)g_hash_table_lookup(namedInitFuncs, (gconstpointer)name);

    GPrioritizedHook *hook = (GPrioritizedHook*)g_hook_alloc(hookList);

    hook->base.data = func;
    hook->base.func = HookInit;
    hook->priority  = priority;
    hook->func_name = func_name;

    g_hook_insert_sorted(hookList, (GHook*)hook, GPrioritizedHookCompare);
}
Пример #18
0
CoglPangoGlyphCache *
cogl_pango_glyph_cache_new (CoglBool use_mipmapping)
{
  CoglPangoGlyphCache *cache;

  cache = g_malloc (sizeof (CoglPangoGlyphCache));

  cache->hash_table = g_hash_table_new_full
    (cogl_pango_glyph_cache_hash_func,
     cogl_pango_glyph_cache_equal_func,
     (GDestroyNotify) cogl_pango_glyph_cache_key_free,
     (GDestroyNotify) cogl_pango_glyph_cache_value_free);

  cache->atlases = NULL;
  g_hook_list_init (&cache->reorganize_callbacks, sizeof (GHook));

  cache->has_dirty_glyphs = FALSE;

  cache->using_global_atlas = FALSE;

  cache->use_mipmapping = use_mipmapping;

  return cache;
}
Пример #19
0
/* For reference: There was some deliberation over whether to have a
 * constructor that could throw an exception but looking at standard
 * practices with several high level OO languages including python, C++,
 * C# Java and Ruby they all support exceptions in constructors and the
 * general consensus appears to be that throwing an exception is neater
 * than successfully constructing with an internal error status that
 * would then have to be explicitly checked via some form of ::is_ok()
 * method.
 */
CoglContext *
cogl_context_new (CoglDisplay *display,
                  CoglError **error)
{
  CoglContext *context;
  uint8_t white_pixel[] = { 0xff, 0xff, 0xff, 0xff };
  CoglBitmap *white_pixel_bitmap;
  const CoglWinsysVtable *winsys;
  int i;
  CoglError *internal_error = NULL;

  _cogl_init ();

#ifdef COGL_ENABLE_PROFILE
  /* We need to be absolutely sure that uprof has been initialized
   * before calling _cogl_uprof_init. uprof_init (NULL, NULL)
   * will be a NOP if it has been initialized but it will also
   * mean subsequent parsing of the UProf GOptionGroup will have no
   * affect.
   *
   * Sadly GOptionGroup based library initialization is extremely
   * fragile by design because GOptionGroups have no notion of
   * dependencies and so the order things are initialized isn't
   * currently under tight control.
   */
  uprof_init (NULL, NULL);
  _cogl_uprof_init ();
#endif

  /* Allocate context memory */
  context = g_malloc0 (sizeof (CoglContext));

  /* Convert the context into an object immediately in case any of the
     code below wants to verify that the context pointer is a valid
     object */
  _cogl_context_object_new (context);

  /* XXX: Gross hack!
   * Currently everything in Cogl just assumes there is a default
   * context which it can access via _COGL_GET_CONTEXT() including
   * code used to construct a CoglContext. Until all of that code
   * has been updated to take an explicit context argument we have
   * to immediately make our pointer the default context.
   */
  _cogl_context = context;

  /* Init default values */
  memset (context->features, 0, sizeof (context->features));
  context->feature_flags = 0;
  memset (context->private_features, 0, sizeof (context->private_features));

  context->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_UNKNOWN;

  memset (context->winsys_features, 0, sizeof (context->winsys_features));

  if (!display)
    {
      CoglRenderer *renderer = cogl_renderer_new ();
      if (!cogl_renderer_connect (renderer, error))
        {
          g_free (context);
          return NULL;
        }

      display = cogl_display_new (renderer, NULL);
      cogl_object_unref(renderer);
    }
  else
    cogl_object_ref (display);

  if (!cogl_display_setup (display, error))
    {
      cogl_object_unref (display);
      g_free (context);
      return NULL;
    }

  context->display = display;

  /* This is duplicated data, but it's much more convenient to have
     the driver attached to the context and the value is accessed a
     lot throughout Cogl */
  context->driver = display->renderer->driver;

  /* Again this is duplicated data, but it convenient to be able
   * access these from the context. */
  context->driver_vtable = display->renderer->driver_vtable;
  context->texture_driver = display->renderer->texture_driver;

  for (i = 0; i < G_N_ELEMENTS (context->private_features); i++)
    context->private_features[i] |= display->renderer->private_features[i];

  winsys = _cogl_context_get_winsys (context);
  if (!winsys->context_init (context, error))
    {
      cogl_object_unref (display);
      g_free (context);
      return NULL;
    }

  context->attribute_name_states_hash =
    g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  context->attribute_name_index_map = NULL;
  context->n_attribute_names = 0;

  /* The "cogl_color_in" attribute needs a deterministic name_index
   * so we make sure it's the first attribute name we register */
  _cogl_attribute_register_attribute_name (context, "cogl_color_in");


  context->uniform_names =
    g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
  context->uniform_name_hash = g_hash_table_new (g_str_hash, g_str_equal);
  context->n_uniform_names = 0;

  /* Initialise the driver specific state */
  _cogl_init_feature_overrides (context);

  /* XXX: ONGOING BUG: Intel viewport scissor
   *
   * Intel gen6 drivers don't currently correctly handle offset
   * viewports, since primitives aren't clipped within the bounds of
   * the viewport.  To workaround this we push our own clip for the
   * viewport that will use scissoring to ensure we clip as expected.
   *
   * TODO: file a bug upstream!
   */
  if (context->gpu.driver_package == COGL_GPU_INFO_DRIVER_PACKAGE_MESA &&
      context->gpu.architecture == COGL_GPU_INFO_ARCHITECTURE_SANDYBRIDGE &&
      !getenv ("COGL_DISABLE_INTEL_VIEWPORT_SCISSORT_WORKAROUND"))
    context->needs_viewport_scissor_workaround = TRUE;
  else
    context->needs_viewport_scissor_workaround = FALSE;

  context->sampler_cache = _cogl_sampler_cache_new (context);

  _cogl_pipeline_init_default_pipeline ();
  _cogl_pipeline_init_default_layers ();
  _cogl_pipeline_init_state_hash_functions ();
  _cogl_pipeline_init_layer_state_hash_functions ();

  context->current_clip_stack_valid = FALSE;
  context->current_clip_stack = NULL;

  context->legacy_backface_culling_enabled = FALSE;

  cogl_matrix_init_identity (&context->identity_matrix);
  cogl_matrix_init_identity (&context->y_flip_matrix);
  cogl_matrix_scale (&context->y_flip_matrix, 1, -1, 1);

  context->flushed_matrix_mode = COGL_MATRIX_MODELVIEW;

  context->texture_units =
    g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit));

  if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_ANY_GL))
    {
      /* See cogl-pipeline.c for more details about why we leave texture unit 1
       * active by default... */
      context->active_texture_unit = 1;
      GE (context, glActiveTexture (GL_TEXTURE1));
    }

  context->legacy_fog_state.enabled = FALSE;

  context->opaque_color_pipeline = cogl_pipeline_new (context);
  context->blended_color_pipeline = cogl_pipeline_new (context);
  context->texture_pipeline = cogl_pipeline_new (context);
  context->codegen_header_buffer = g_string_new ("");
  context->codegen_source_buffer = g_string_new ("");
  context->codegen_boilerplate_buffer = g_string_new ("");
  context->source_stack = NULL;

  context->legacy_state_set = 0;

  context->default_gl_texture_2d_tex = NULL;
  context->default_gl_texture_3d_tex = NULL;
  context->default_gl_texture_rect_tex = NULL;

  context->framebuffers = NULL;
  context->current_draw_buffer = NULL;
  context->current_read_buffer = NULL;
  context->current_draw_buffer_state_flushed = 0;
  context->current_draw_buffer_changes = COGL_FRAMEBUFFER_STATE_ALL;

  context->swap_callback_closures =
    g_hash_table_new (g_direct_hash, g_direct_equal);

  _cogl_list_init (&context->onscreen_events_queue);
  _cogl_list_init (&context->onscreen_dirty_queue);

  g_queue_init (&context->gles2_context_stack);

  context->journal_flush_attributes_array =
    g_array_new (TRUE, FALSE, sizeof (CoglAttribute *));
  context->journal_clip_bounds = NULL;

  context->polygon_vertices = g_array_new (FALSE, FALSE, sizeof (float));

  context->current_pipeline = NULL;
  context->current_pipeline_changes_since_flush = 0;
  context->current_pipeline_with_color_attrib = FALSE;

  _cogl_bitmask_init (&context->enabled_builtin_attributes);
  _cogl_bitmask_init (&context->enable_builtin_attributes_tmp);
  _cogl_bitmask_init (&context->enabled_texcoord_attributes);
  _cogl_bitmask_init (&context->enable_texcoord_attributes_tmp);
  _cogl_bitmask_init (&context->enabled_custom_attributes);
  _cogl_bitmask_init (&context->enable_custom_attributes_tmp);
  _cogl_bitmask_init (&context->changed_bits_tmp);

  context->max_texture_units = -1;
  context->max_activateable_texture_units = -1;

  context->current_fragment_program_type = COGL_PIPELINE_PROGRAM_TYPE_GLSL;
  context->current_vertex_program_type = COGL_PIPELINE_PROGRAM_TYPE_GLSL;
  context->current_gl_program = 0;

  context->current_gl_dither_enabled = TRUE;
  context->current_gl_color_mask = COGL_COLOR_MASK_ALL;

  context->gl_blend_enable_cache = FALSE;

  context->depth_test_enabled_cache = FALSE;
  context->depth_test_function_cache = COGL_DEPTH_TEST_FUNCTION_LESS;
  context->depth_writing_enabled_cache = TRUE;
  context->depth_range_near_cache = 0;
  context->depth_range_far_cache = 1;

  context->legacy_depth_test_enabled = FALSE;

  context->pipeline_cache = _cogl_pipeline_cache_new ();

  for (i = 0; i < COGL_BUFFER_BIND_TARGET_COUNT; i++)
    context->current_buffer[i] = NULL;

  context->window_buffer = NULL;
  context->framebuffer_stack = _cogl_create_framebuffer_stack ();

  /* XXX: In this case the Clutter backend is still responsible for
   * the OpenGL binding API and for creating onscreen framebuffers and
   * so we have to add a dummy framebuffer to represent the backend
   * owned window... */
  if (_cogl_context_get_winsys (context) == _cogl_winsys_stub_get_vtable ())
    {
      CoglOnscreen *window = _cogl_onscreen_new ();
      cogl_set_framebuffer (COGL_FRAMEBUFFER (window));
      cogl_object_unref (COGL_FRAMEBUFFER (window));
    }

  context->current_path = NULL;
  context->stencil_pipeline = cogl_pipeline_new (context);

  context->in_begin_gl_block = FALSE;

  context->quad_buffer_indices_byte = NULL;
  context->quad_buffer_indices = NULL;
  context->quad_buffer_indices_len = 0;

  context->rectangle_byte_indices = NULL;
  context->rectangle_short_indices = NULL;
  context->rectangle_short_indices_len = 0;

  context->texture_download_pipeline = NULL;
  context->blit_texture_pipeline = NULL;

#ifdef HAVE_COGL_GL
  if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_ALPHA_TEST))
    /* The default for GL_ALPHA_TEST is to always pass which is equivalent to
     * the test being disabled therefore we assume that for all drivers there
     * will be no performance impact if we always leave the test enabled which
     * makes things a bit simpler for us. Under GLES2 the alpha test is
     * implemented in the fragment shader so there is no enable for it
     */
    GE (context, glEnable (GL_ALPHA_TEST));

  if ((context->driver == COGL_DRIVER_GL3))
    {
      GLuint vertex_array;

      /* In a forward compatible context, GL 3 doesn't support rendering
       * using the default vertex array object. Cogl doesn't use vertex
       * array objects yet so for now we just create a dummy array
       * object that we will use as our own default object. Eventually
       * it could be good to attach the vertex array objects to
       * CoglPrimitives */
      context->glGenVertexArrays (1, &vertex_array);
      context->glBindVertexArray (vertex_array);
    }
#endif

  context->current_modelview_entry = NULL;
  context->current_projection_entry = NULL;
  _cogl_matrix_entry_identity_init (&context->identity_entry);
  _cogl_matrix_entry_cache_init (&context->builtin_flushed_projection);
  _cogl_matrix_entry_cache_init (&context->builtin_flushed_modelview);

  /* Create default textures used for fall backs */
  context->default_gl_texture_2d_tex =
    cogl_texture_2d_new_from_data (context,
                                   1, 1,
                                   COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                   0, /* rowstride */
                                   white_pixel,
                                   NULL); /* abort on error */

  /* If 3D or rectangle textures aren't supported then these will
   * return errors that we can simply ignore. */
  internal_error = NULL;
  context->default_gl_texture_3d_tex =
    cogl_texture_3d_new_from_data (context,
                                   1, 1, 1, /* width, height, depth */
                                   COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                   0, /* rowstride */
                                   0, /* image stride */
                                   white_pixel,
                                   &internal_error);
  if (internal_error)
    cogl_error_free (internal_error);

  /* TODO: add cogl_texture_rectangle_new_from_data() */
  white_pixel_bitmap =
    cogl_bitmap_new_for_data (context,
                              1, 1, /* width/height */
                              COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                              4, /* rowstride */
                              white_pixel);

  internal_error = NULL;
  context->default_gl_texture_rect_tex =
    cogl_texture_rectangle_new_from_bitmap (white_pixel_bitmap);

  /* XXX: we need to allocate the texture now because the white_pixel
   * data is on the stack */
  cogl_texture_allocate (COGL_TEXTURE (context->default_gl_texture_rect_tex),
                         &internal_error);
  if (internal_error)
    cogl_error_free (internal_error);

  cogl_object_unref (white_pixel_bitmap);

  cogl_push_source (context->opaque_color_pipeline);

  context->atlases = NULL;
  g_hook_list_init (&context->atlas_reorganize_callbacks, sizeof (GHook));

  context->buffer_map_fallback_array = g_byte_array_new ();
  context->buffer_map_fallback_in_use = FALSE;

  /* As far as I can tell, GL_POINT_SPRITE doesn't have any effect
     unless GL_COORD_REPLACE is enabled for an individual layer.
     Therefore it seems like it should be ok to just leave it enabled
     all the time instead of having to have a set property on each
     pipeline to track whether any layers have point sprite coords
     enabled. We don't need to do this for GL3 or GLES2 because point
     sprites are handled using a builtin varying in the shader. */
  if (_cogl_has_private_feature (context, COGL_PRIVATE_FEATURE_GL_FIXED) &&
      cogl_has_feature (context, COGL_FEATURE_ID_POINT_SPRITE))
    GE (context, glEnable (GL_POINT_SPRITE));

  _cogl_list_init (&context->fences);

  return context;
}
Пример #20
0
/* For reference: There was some deliberation over whether to have a
 * constructor that could throw an exception but looking at standard
 * practices with several high level OO languages including python, C++,
 * C# Java and Ruby they all support exceptions in constructors and the
 * general consensus appears to be that throwing an exception is neater
 * than successfully constructing with an internal error status that
 * would then have to be explicitly checked via some form of ::is_ok()
 * method.
 */
CoglContext *
cogl_context_new (CoglDisplay *display,
                  GError **error)
{
  CoglContext *context;
  GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
  CoglBitmap *default_texture_bitmap;
  const CoglWinsysVtable *winsys;
  int i;

  _cogl_init ();

#ifdef COGL_ENABLE_PROFILE
  /* We need to be absolutely sure that uprof has been initialized
   * before calling _cogl_uprof_init. uprof_init (NULL, NULL)
   * will be a NOP if it has been initialized but it will also
   * mean subsequent parsing of the UProf GOptionGroup will have no
   * affect.
   *
   * Sadly GOptionGroup based library initialization is extremely
   * fragile by design because GOptionGroups have no notion of
   * dependencies and so the order things are initialized isn't
   * currently under tight control.
   */
  uprof_init (NULL, NULL);
  _cogl_uprof_init ();
#endif

  /* Allocate context memory */
  context = g_malloc0 (sizeof (CoglContext));

  /* Convert the context into an object immediately in case any of the
     code below wants to verify that the context pointer is a valid
     object */
  _cogl_context_object_new (context);

  /* XXX: Gross hack!
   * Currently everything in Cogl just assumes there is a default
   * context which it can access via _COGL_GET_CONTEXT() including
   * code used to construct a CoglContext. Until all of that code
   * has been updated to take an explicit context argument we have
   * to immediately make our pointer the default context.
   */
  _context = context;

  /* Init default values */
  memset (context->features, 0, sizeof (context->features));
  context->feature_flags = 0;
  context->private_feature_flags = 0;

  context->texture_types = NULL;
  context->buffer_types = NULL;

  context->rectangle_state = COGL_WINSYS_RECTANGLE_STATE_UNKNOWN;

  memset (context->winsys_features, 0, sizeof (context->winsys_features));

  if (!display)
    {
      CoglRenderer *renderer = cogl_renderer_new ();
      if (!cogl_renderer_connect (renderer, error))
        {
          g_free (context);
          return NULL;
        }

      display = cogl_display_new (renderer, NULL);
    }
  else
    cogl_object_ref (display);

  if (!cogl_display_setup (display, error))
    {
      cogl_object_unref (display);
      g_free (context);
      return NULL;
    }

  context->display = display;

  /* This is duplicated data, but it's much more convenient to have
     the driver attached to the context and the value is accessed a
     lot throughout Cogl */
  context->driver = display->renderer->driver;

  switch (context->driver)
    {
#ifdef HAVE_COGL_GL
    case COGL_DRIVER_GL:
      context->driver_vtable = &_cogl_driver_gl;
      context->texture_driver = &_cogl_texture_driver_gl;
      break;
#endif

#if defined (HAVE_COGL_GLES) || defined (HAVE_COGL_GLES2)
    case COGL_DRIVER_GLES1:
    case COGL_DRIVER_GLES2:
      context->driver_vtable = &_cogl_driver_gles;
      context->texture_driver = &_cogl_texture_driver_gles;
      break;
#endif

    default:
      g_assert_not_reached ();
    }

  winsys = _cogl_context_get_winsys (context);
  if (!winsys->context_init (context, error))
    {
      cogl_object_unref (display);
      g_free (context);
      return NULL;
    }

  context->attribute_name_states_hash =
    g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
  context->attribute_name_index_map = NULL;
  context->n_attribute_names = 0;

  /* The "cogl_color_in" attribute needs a deterministic name_index
   * so we make sure it's the first attribute name we register */
  _cogl_attribute_register_attribute_name (context, "cogl_color_in");


  context->uniform_names =
    g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);
  context->uniform_name_hash = g_hash_table_new (g_str_hash, g_str_equal);
  context->n_uniform_names = 0;

  /* Initialise the driver specific state */
  _cogl_init_feature_overrides (context);

  _context->sampler_cache = _cogl_sampler_cache_new (_context);

  _cogl_pipeline_init_default_pipeline ();
  _cogl_pipeline_init_default_layers ();
  _cogl_pipeline_init_state_hash_functions ();
  _cogl_pipeline_init_layer_state_hash_functions ();

  context->current_clip_stack_valid = FALSE;
  context->current_clip_stack = NULL;

  cogl_matrix_init_identity (&context->identity_matrix);
  cogl_matrix_init_identity (&context->y_flip_matrix);
  cogl_matrix_scale (&context->y_flip_matrix, 1, -1, 1);

  context->flushed_matrix_mode = COGL_MATRIX_MODELVIEW;

  context->texture_units =
    g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit));

  /* See cogl-pipeline.c for more details about why we leave texture unit 1
   * active by default... */
  context->active_texture_unit = 1;
  GE (context, glActiveTexture (GL_TEXTURE1));

  context->opaque_color_pipeline = cogl_pipeline_new (context);
  context->blended_color_pipeline = cogl_pipeline_new (context);
  context->texture_pipeline = cogl_pipeline_new (context);
  context->codegen_header_buffer = g_string_new ("");
  context->codegen_source_buffer = g_string_new ("");

  context->default_gl_texture_2d_tex = NULL;
  context->default_gl_texture_3d_tex = NULL;
  context->default_gl_texture_rect_tex = NULL;

  context->framebuffers = NULL;
  context->current_draw_buffer = NULL;
  context->current_read_buffer = NULL;
  context->current_draw_buffer_state_flushed = 0;
  context->current_draw_buffer_changes = COGL_FRAMEBUFFER_STATE_ALL;

  g_queue_init (&context->gles2_context_stack);

  context->journal_flush_attributes_array =
    g_array_new (TRUE, FALSE, sizeof (CoglAttribute *));
  context->journal_clip_bounds = NULL;

  context->polygon_vertices = g_array_new (FALSE, FALSE, sizeof (float));

  context->current_pipeline = NULL;
  context->current_pipeline_changes_since_flush = 0;
  context->current_pipeline_skip_gl_color = FALSE;

  _cogl_bitmask_init (&context->enabled_builtin_attributes);
  _cogl_bitmask_init (&context->enable_builtin_attributes_tmp);
  _cogl_bitmask_init (&context->enabled_texcoord_attributes);
  _cogl_bitmask_init (&context->enable_texcoord_attributes_tmp);
  _cogl_bitmask_init (&context->enabled_custom_attributes);
  _cogl_bitmask_init (&context->enable_custom_attributes_tmp);
  _cogl_bitmask_init (&context->changed_bits_tmp);

  context->max_texture_units = -1;
  context->max_activateable_texture_units = -1;

  context->current_fragment_program_type = COGL_PIPELINE_PROGRAM_TYPE_FIXED;
  context->current_vertex_program_type = COGL_PIPELINE_PROGRAM_TYPE_FIXED;
  context->current_gl_program = 0;

  context->current_gl_dither_enabled = TRUE;
  context->current_gl_color_mask = COGL_COLOR_MASK_ALL;

  context->gl_blend_enable_cache = FALSE;

  context->depth_test_enabled_cache = FALSE;
  context->depth_test_function_cache = COGL_DEPTH_TEST_FUNCTION_LESS;
  context->depth_writing_enabled_cache = TRUE;
  context->depth_range_near_cache = 0;
  context->depth_range_far_cache = 1;

  context->pipeline_cache = cogl_pipeline_cache_new ();

  for (i = 0; i < COGL_BUFFER_BIND_TARGET_COUNT; i++)
    context->current_buffer[i] = NULL;

  context->window_buffer = NULL;
  context->framebuffer_stack = _cogl_create_framebuffer_stack ();

  /* XXX: In this case the Clutter backend is still responsible for
   * the OpenGL binding API and for creating onscreen framebuffers and
   * so we have to add a dummy framebuffer to represent the backend
   * owned window... */
  if (_cogl_context_get_winsys (context) == _cogl_winsys_stub_get_vtable ())
    {
      CoglOnscreen *window = _cogl_onscreen_new ();
      cogl_set_framebuffer (COGL_FRAMEBUFFER (window));
      cogl_object_unref (COGL_FRAMEBUFFER (window));
    }

  context->stencil_pipeline = cogl_pipeline_new (context);

  context->in_begin_gl_block = FALSE;

  context->quad_buffer_indices_byte = NULL;
  context->quad_buffer_indices = NULL;
  context->quad_buffer_indices_len = 0;

  context->rectangle_byte_indices = NULL;
  context->rectangle_short_indices = NULL;
  context->rectangle_short_indices_len = 0;

  context->texture_download_pipeline = NULL;
  context->blit_texture_pipeline = NULL;

#if defined (HAVE_COGL_GL) || defined (HAVE_COGL_GLES)
  if (context->driver != COGL_DRIVER_GLES2)
    /* The default for GL_ALPHA_TEST is to always pass which is equivalent to
     * the test being disabled therefore we assume that for all drivers there
     * will be no performance impact if we always leave the test enabled which
     * makes things a bit simpler for us. Under GLES2 the alpha test is
     * implemented in the fragment shader so there is no enable for it
     */
    GE (context, glEnable (GL_ALPHA_TEST));
#endif

  _context->current_modelview_entry = NULL;
  _context->current_projection_entry = NULL;
  _cogl_matrix_entry_identity_init (&_context->identity_entry);
  _cogl_matrix_entry_cache_init (&_context->builtin_flushed_projection);
  _cogl_matrix_entry_cache_init (&_context->builtin_flushed_modelview);

  default_texture_bitmap =
    cogl_bitmap_new_for_data (_context,
                              1, 1, /* width/height */
                              COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                              4, /* rowstride */
                              default_texture_data);

  /* Create default textures used for fall backs */
  context->default_gl_texture_2d_tex =
    cogl_texture_2d_new_from_bitmap (default_texture_bitmap,
                                     /* internal format */
                                     COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                     NULL);
  /* If 3D or rectangle textures aren't supported then these should
     just silently return NULL */
  context->default_gl_texture_3d_tex =
    cogl_texture_3d_new_from_bitmap (default_texture_bitmap,
                                     1, /* height */
                                     1, /* depth */
                                     COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                     NULL);
  context->default_gl_texture_rect_tex =
    cogl_texture_rectangle_new_from_bitmap (default_texture_bitmap,
                                            COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                            NULL);

  cogl_object_unref (default_texture_bitmap);

  context->atlases = NULL;
  g_hook_list_init (&context->atlas_reorganize_callbacks, sizeof (GHook));

  _context->buffer_map_fallback_array = g_byte_array_new ();
  _context->buffer_map_fallback_in_use = FALSE;

  /* As far as I can tell, GL_POINT_SPRITE doesn't have any effect
     unless GL_COORD_REPLACE is enabled for an individual
     layer. Therefore it seems like it should be ok to just leave it
     enabled all the time instead of having to have a set property on
     each pipeline to track whether any layers have point sprite
     coords enabled. We don't need to do this for GLES2 because point
     sprites are handled using a builtin varying in the shader. */
  if (_context->driver != COGL_DRIVER_GLES2 &&
      cogl_has_feature (context, COGL_FEATURE_ID_POINT_SPRITE))
    GE (context, glEnable (GL_POINT_SPRITE));

  return context;
}