static CoglBool _cogl_texture_3d_can_create (CoglContext *ctx, int width, int height, int depth, CoglPixelFormat internal_format, CoglError **error) { GLenum gl_intformat; GLenum gl_type; /* This should only happen on GLES */ if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_3D)) { _cogl_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, "3D textures are not supported by the GPU"); return FALSE; } /* If NPOT textures aren't supported then the size must be a power of two */ if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_NPOT) && (!_cogl_util_is_pot (width) || !_cogl_util_is_pot (height) || !_cogl_util_is_pot (depth))) { _cogl_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, "A non-power-of-two size was requested but this is not " "supported by the GPU"); return FALSE; } ctx->driver_vtable->pixel_format_to_gl (ctx, internal_format, &gl_intformat, NULL, &gl_type); /* Check that the driver can create a texture with that size */ if (!ctx->texture_driver->size_supported_3d (ctx, GL_TEXTURE_3D, gl_intformat, gl_type, width, height, depth)) { _cogl_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, "The requested dimensions are not supported by the GPU"); return FALSE; } return TRUE; }
static CoglBool _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen, EGLConfig egl_config, CoglError **error) { CoglOnscreenEGL *egl_onscreen = onscreen->winsys; CoglOnscreenWayland *wayland_onscreen; CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglContext *context = framebuffer->context; CoglRenderer *renderer = context->display->renderer; CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererWayland *wayland_renderer = egl_renderer->platform; wayland_onscreen = g_slice_new0 (CoglOnscreenWayland); egl_onscreen->platform = wayland_onscreen; _cogl_list_init (&wayland_onscreen->frame_callbacks); if (onscreen->foreign_surface) wayland_onscreen->wayland_surface = onscreen->foreign_surface; else wayland_onscreen->wayland_surface = wl_compositor_create_surface (wayland_renderer->wayland_compositor); if (!wayland_onscreen->wayland_surface) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_ONSCREEN, "Error while creating wayland surface for CoglOnscreen"); return FALSE; } wayland_onscreen->wayland_egl_native_window = wl_egl_window_create (wayland_onscreen->wayland_surface, cogl_framebuffer_get_width (framebuffer), cogl_framebuffer_get_height (framebuffer)); if (!wayland_onscreen->wayland_egl_native_window) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_ONSCREEN, "Error while creating wayland egl native window " "for CoglOnscreen"); return FALSE; } egl_onscreen->egl_surface = eglCreateWindowSurface (egl_renderer->edpy, egl_config, (EGLNativeWindowType) wayland_onscreen->wayland_egl_native_window, NULL); if (!onscreen->foreign_surface) wayland_onscreen->wayland_shell_surface = wl_shell_get_shell_surface (wayland_renderer->wayland_shell, wayland_onscreen->wayland_surface); return TRUE; }
static CoglBool _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, CoglError **error) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglContext *context = framebuffer->context; CoglDisplay *display = context->display; CoglDisplayEGL *egl_display = display->winsys; CoglDisplayKMS *kms_display = egl_display->platform; CoglRenderer *renderer = display->renderer; CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererKMS *kms_renderer = egl_renderer->platform; CoglOnscreenEGL *egl_onscreen; CoglOnscreenKMS *kms_onscreen; _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE); onscreen->winsys = g_slice_new0 (CoglOnscreenEGL); egl_onscreen = onscreen->winsys; kms_onscreen = g_slice_new0 (CoglOnscreenKMS); egl_onscreen->platform = kms_onscreen; kms_onscreen->surface = gbm_surface_create (kms_renderer->gbm, kms_display->width, kms_display->height, GBM_BO_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); if (!kms_onscreen->surface) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_ONSCREEN, "Failed to allocate surface"); return FALSE; } egl_onscreen->egl_surface = eglCreateWindowSurface (egl_renderer->edpy, egl_display->egl_config, (NativeWindowType) kms_onscreen->surface, NULL); if (egl_onscreen->egl_surface == EGL_NO_SURFACE) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_ONSCREEN, "Failed to allocate surface"); return FALSE; } _cogl_framebuffer_winsys_update_size (framebuffer, kms_display->width, kms_display->height); return TRUE; }
static CoglBool _cogl_winsys_renderer_connect (CoglRenderer *renderer, CoglError **error) { CoglRendererEGL *egl_renderer; CoglRendererGDL *gdl_renderer; gdl_ret_t rc = GDL_SUCCESS; gdl_display_info_t gdl_display_info; renderer->winsys = g_slice_new0 (CoglRendererEGL); egl_renderer = renderer->winsys; gdl_renderer = g_slice_new0 (CoglRendererGDL); egl_renderer->platform = gdl_renderer; egl_renderer->platform_vtable = &_cogl_winsys_egl_vtable; egl_renderer->edpy = eglGetDisplay (EGL_DEFAULT_DISPLAY); if (!_cogl_winsys_egl_renderer_connect_common (renderer, error)) goto error; /* Check we can talk to the GDL library */ rc = gdl_init (NULL); if (rc != GDL_SUCCESS) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, "GDL initialize failed. %s", gdl_get_error_string (rc)); goto error; } rc = gdl_get_display_info (GDL_DISPLAY_ID_0, &gdl_display_info); if (rc != GDL_SUCCESS) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, "GDL failed to get display information: %s", gdl_get_error_string (rc)); gdl_close (); goto error; } gdl_close (); return TRUE; error: _cogl_winsys_renderer_disconnect (renderer); return FALSE; }
static CoglBool _cogl_winsys_egl_context_created (CoglDisplay *display, CoglError **error) { CoglDisplayEGL *egl_display = display->winsys; CoglDisplayKMS *kms_display = egl_display->platform; CoglRenderer *renderer = display->renderer; CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererKMS *kms_renderer = egl_renderer->platform; kms_display->dummy_gbm_surface = gbm_surface_create (kms_renderer->gbm, 16, 16, GBM_FORMAT_XRGB8888, GBM_BO_USE_RENDERING); if (!kms_display->dummy_gbm_surface) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, "Failed to create dummy GBM surface"); return FALSE; } egl_display->dummy_surface = eglCreateWindowSurface (egl_renderer->edpy, egl_display->egl_config, (NativeWindowType) kms_display->dummy_gbm_surface, NULL); if (egl_display->dummy_surface == EGL_NO_SURFACE) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, "Failed to create dummy EGL surface"); return FALSE; } if (!_cogl_winsys_egl_make_current (display, egl_display->dummy_surface, egl_display->dummy_surface, egl_display->egl_context)) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, "Failed to make context current"); return FALSE; } return TRUE; }
/* NB: The reason we require the width, height and format to be passed * even though they may seem redundant is because GLES 1/2 don't * provide a way to query these properties. */ CoglTexture2D * _cogl_egl_texture_2d_new_from_image (CoglContext *ctx, int width, int height, CoglPixelFormat format, EGLImageKHR image, CoglError **error) { _COGL_RETURN_VAL_IF_FAIL (_cogl_context_get_winsys (ctx)->constraints & COGL_RENDERER_CONSTRAINT_USES_EGL, NULL); _COGL_RETURN_VAL_IF_FAIL (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_TEXTURE_2D_FROM_EGL_IMAGE), NULL); if (ctx->driver_vtable->egl_texture_2d_new_from_image) return ctx->driver_vtable->egl_texture_2d_new_from_image (ctx, width, height, format, image, error); else { _cogl_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, "Creating 2D textures from EGL images is not " "supported by the current driver"); return NULL; } }
static CoglBool _cogl_winsys_set_gles2_context (CoglGLES2Context *gles2_ctx, CoglError **error) { CoglContext *ctx = gles2_ctx->context; CoglDisplayEGL *egl_display = ctx->display->winsys; CoglBool status; if (gles2_ctx->write_buffer && cogl_is_onscreen (gles2_ctx->write_buffer)) status = bind_onscreen_with_context (COGL_ONSCREEN (gles2_ctx->write_buffer), gles2_ctx->winsys); else status = _cogl_winsys_egl_make_current (ctx->display, egl_display->dummy_surface, egl_display->dummy_surface, gles2_ctx->winsys); if (!status) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_MAKE_CURRENT, "Failed to make gles2 context current"); return FALSE; } return TRUE; }
static void * _cogl_winsys_context_create_gles2_context (CoglContext *ctx, CoglError **error) { CoglRendererEGL *egl_renderer = ctx->display->renderer->winsys; CoglDisplayEGL *egl_display = ctx->display->winsys; EGLint attribs[3]; EGLContext egl_context; attribs[0] = EGL_CONTEXT_CLIENT_VERSION; attribs[1] = 2; attribs[2] = EGL_NONE; egl_context = eglCreateContext (egl_renderer->edpy, egl_display->egl_config, egl_display->egl_context, attribs); if (egl_context == EGL_NO_CONTEXT) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_GLES2_CONTEXT, "%s", get_error_string ()); return NULL; } return (void *)egl_context; }
CoglBitmap * _cogl_bitmap_new_with_malloc_buffer (CoglContext *context, unsigned int width, unsigned int height, CoglPixelFormat format, CoglError **error) { static CoglUserDataKey bitmap_free_key; int bpp = _cogl_pixel_format_get_bytes_per_pixel (format); int rowstride = ((width * bpp) + 3) & ~3; uint8_t *data = g_try_malloc (rowstride * height); CoglBitmap *bitmap; if (!data) { _cogl_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_NO_MEMORY, "Failed to allocate memory for bitmap"); return NULL; } bitmap = cogl_bitmap_new_for_data (context, width, height, format, rowstride, data); cogl_object_set_user_data (COGL_OBJECT (bitmap), &bitmap_free_key, data, g_free); return bitmap; }
CoglBool _cogl_gl_util_catch_out_of_memory (CoglContext *ctx, CoglError **error) { GLenum gl_error; CoglBool out_of_memory = FALSE; while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) { if (gl_error == GL_OUT_OF_MEMORY) out_of_memory = TRUE; #ifdef COGL_GL_DEBUG else { g_warning ("%s: GL error (%d): %s\n", G_STRLOC, gl_error, _cogl_gl_error_to_string (gl_error)); } #endif } if (out_of_memory) { _cogl_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_NO_MEMORY, "Out of memory"); return TRUE; } return FALSE; }
static CoglBool _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen, EGLConfig egl_config, CoglError **error) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglContext *context = framebuffer->context; CoglDisplay *display = context->display; CoglDisplayEGL *egl_display = display->winsys; CoglDisplayGDL *gdl_display = egl_display->platform; CoglOnscreenEGL *egl_onscreen = onscreen->winsys; if (gdl_display->have_onscreen) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_ONSCREEN, "EGL platform only supports a single onscreen window"); return FALSE; } egl_onscreen->egl_surface = egl_display->egl_surface; _cogl_framebuffer_winsys_update_size (framebuffer, gdl_display->egl_surface_width, gdl_display->egl_surface_height); gdl_display->have_onscreen = TRUE; return TRUE; }
static CoglBool connect_custom_winsys (CoglRenderer *renderer, CoglError **error) { const CoglWinsysVtable *winsys = renderer->custom_winsys_vtable_getter(); CoglError *tmp_error = NULL; GString *error_message; renderer->winsys_vtable = winsys; error_message = g_string_new (""); if (!winsys->renderer_connect (renderer, &tmp_error)) { g_string_append_c (error_message, '\n'); g_string_append (error_message, tmp_error->message); cogl_error_free (tmp_error); } else { renderer->connected = TRUE; g_string_free (error_message, TRUE); return TRUE; } renderer->winsys_vtable = NULL; _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, "Failed to connected to any renderer: %s", error_message->str); g_string_free (error_message, TRUE); return FALSE; }
CoglTexture2D * _cogl_texture_2d_new_from_bitmap (CoglBitmap *bmp, CoglPixelFormat internal_format, CoglBool can_convert_in_place, CoglError **error) { CoglContext *ctx; _COGL_RETURN_VAL_IF_FAIL (bmp != NULL, NULL); ctx = _cogl_bitmap_get_context (bmp); internal_format = _cogl_texture_determine_internal_format (cogl_bitmap_get_format (bmp), internal_format); if (!_cogl_texture_2d_can_create (ctx, cogl_bitmap_get_width (bmp), cogl_bitmap_get_height (bmp), internal_format)) { _cogl_set_error (error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE, "Failed to create texture 2d due to size/format" " constraints"); return NULL; } return ctx->driver_vtable->texture_2d_new_from_bitmap (bmp, internal_format, can_convert_in_place, error); }
static CoglBool _cogl_winsys_egl_context_created (CoglDisplay *display, CoglError **error) { CoglRenderer *renderer = display->renderer; CoglRendererEGL *egl_renderer = renderer->winsys; CoglDisplayEGL *egl_display = display->winsys; if ((egl_renderer->private_features & COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) == 0 && !make_dummy_surface(display, error)) return FALSE; if (!_cogl_winsys_egl_make_current (display, egl_display->dummy_surface, egl_display->dummy_surface, egl_display->egl_context)) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, "%s", "Unable to eglMakeCurrent with dummy surface"); } return TRUE; }
static Display * assert_xlib_display (CoglRenderer *renderer, CoglError **error) { Display *xdpy = cogl_xlib_renderer_get_foreign_display (renderer); CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (renderer); /* A foreign display may have already been set... */ if (xdpy) { xlib_renderer->xdpy = xdpy; return xdpy; } xdpy = XOpenDisplay (_cogl_x11_display_name); if (xdpy == NULL) { _cogl_set_error (error, COGL_RENDERER_ERROR, COGL_RENDERER_ERROR_XLIB_DISPLAY_OPEN, "Failed to open X Display %s", _cogl_x11_display_name); return NULL; } xlib_renderer->xdpy = xdpy; return xdpy; }
static CoglBool check_gl_version (CoglContext *ctx, char **gl_extensions, CoglError **error) { int major, minor; if (!_cogl_get_gl_version (ctx, &major, &minor)) { _cogl_set_error (error, COGL_DRIVER_ERROR, COGL_DRIVER_ERROR_UNKNOWN_VERSION, "The OpenGL version could not be determined"); return FALSE; } /* GL 1.3 supports all of the required functionality in core */ if (COGL_CHECK_GL_VERSION (major, minor, 1, 3)) return TRUE; /* OpenGL 1.2 is only supported if we have the multitexturing extension */ if (!_cogl_check_extension ("GL_ARB_multitexture", gl_extensions)) { _cogl_set_error (error, COGL_DRIVER_ERROR, COGL_DRIVER_ERROR_INVALID_VERSION, "The OpenGL driver is missing " "the GL_ARB_multitexture extension"); return FALSE; } /* OpenGL 1.2 is required */ if (!COGL_CHECK_GL_VERSION (major, minor, 1, 2)) { _cogl_set_error (error, COGL_DRIVER_ERROR, COGL_DRIVER_ERROR_INVALID_VERSION, "The OpenGL version of your driver (%i.%i) " "is not compatible with Cogl", major, minor); return FALSE; } return TRUE; }
static CoglBool _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, CoglError **error) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglContext *context = framebuffer->context; CoglDisplay *display = context->display; CoglDisplayEGL *egl_display = display->winsys; CoglRenderer *renderer = display->renderer; CoglRendererEGL *egl_renderer = renderer->winsys; EGLint attributes[MAX_EGL_CONFIG_ATTRIBS]; EGLConfig egl_config; EGLint config_count = 0; EGLBoolean status; _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE); egl_attributes_from_framebuffer_config (display, &framebuffer->config, attributes); status = eglChooseConfig (egl_renderer->edpy, attributes, &egl_config, 1, &config_count); if (status != EGL_TRUE || config_count == 0) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_ONSCREEN, "Failed to find a suitable EGL configuration"); return FALSE; } /* Update the real number of samples_per_pixel now that we have * found an egl_config... */ if (framebuffer->config.samples_per_pixel) { EGLint samples; status = eglGetConfigAttrib (egl_renderer->edpy, egl_config, EGL_SAMPLES, &samples); g_return_val_if_fail (status == EGL_TRUE, TRUE); framebuffer->samples_per_pixel = samples; } onscreen->winsys = g_slice_new0 (CoglOnscreenEGL); if (egl_renderer->platform_vtable->onscreen_init && !egl_renderer->platform_vtable->onscreen_init (onscreen, egl_config, error)) { g_slice_free (CoglOnscreenEGL, onscreen->winsys); return FALSE; } return TRUE; }
static CoglBool _cogl_texture_rectangle_can_create (CoglContext *ctx, unsigned int width, unsigned int height, CoglPixelFormat internal_format, CoglError **error) { GLenum gl_intformat; GLenum gl_format; GLenum gl_type; if (!cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_RECTANGLE)) { _cogl_set_error (error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_TYPE, "The CoglTextureRectangle feature isn't available"); return FALSE; } ctx->driver_vtable->pixel_format_to_gl (ctx, internal_format, &gl_intformat, &gl_format, &gl_type); /* Check that the driver can create a texture with that size */ if (!ctx->texture_driver->size_supported (ctx, GL_TEXTURE_RECTANGLE_ARB, gl_intformat, gl_format, gl_type, width, height)) { _cogl_set_error (error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_SIZE, "The requested texture size + format is unsupported"); return FALSE; } return TRUE; }
static gboolean allocate_custom_egl_image_external (CoglTexture2D *tex_2d, CoglTextureLoader *loader, CoglError **error) { CoglTexture *tex = COGL_TEXTURE (tex_2d); CoglContext *ctx = tex->context; CoglPixelFormat external_format; CoglPixelFormat internal_format; external_format = loader->src.egl_image_external.format; internal_format = _cogl_texture_determine_internal_format (tex, external_format); _cogl_gl_util_clear_gl_errors (ctx); GE (ctx, glActiveTexture (GL_TEXTURE0)); GE (ctx, glGenTextures (1, &tex_2d->gl_texture)); GE (ctx, glBindTexture (GL_TEXTURE_EXTERNAL_OES, tex_2d->gl_texture)); if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR) { _cogl_set_error (error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_BAD_PARAMETER, "Could not create a CoglTexture2D from a given " "EGLImage"); GE( ctx, glDeleteTextures (1, &tex_2d->gl_texture) ); return FALSE; } GE (ctx, glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); GE (ctx, glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); if (!loader->src.egl_image_external.alloc (tex_2d, tex_2d->egl_image_external.user_data, error)) { GE (ctx, glBindTexture (GL_TEXTURE_EXTERNAL_OES, 0)); GE (ctx, glDeleteTextures (1, &tex_2d->gl_texture)); return FALSE; } GE (ctx, glBindTexture (GL_TEXTURE_EXTERNAL_OES, 0)); tex_2d->internal_format = internal_format; tex_2d->gl_target = GL_TEXTURE_EXTERNAL_OES; return TRUE; }
static CoglBool make_dummy_surface (CoglDisplay *display, CoglError **error) { CoglRenderer *renderer = display->renderer; CoglRendererEGL *egl_renderer = renderer->winsys; CoglRendererWayland *wayland_renderer = egl_renderer->platform; CoglDisplayEGL *egl_display = display->winsys; CoglDisplayWayland *wayland_display = egl_display->platform; const char *error_message; wayland_display->dummy_wayland_surface = wl_compositor_create_surface (wayland_renderer->wayland_compositor); if (!wayland_display->dummy_wayland_surface) { error_message= "Failed to create a dummy wayland surface"; goto fail; } wayland_display->dummy_wayland_egl_native_window = wl_egl_window_create (wayland_display->dummy_wayland_surface, 1, 1); if (!wayland_display->dummy_wayland_egl_native_window) { error_message= "Failed to create a dummy wayland native egl surface"; goto fail; } egl_display->dummy_surface = eglCreateWindowSurface (egl_renderer->edpy, egl_display->egl_config, (EGLNativeWindowType) wayland_display->dummy_wayland_egl_native_window, NULL); if (egl_display->dummy_surface == EGL_NO_SURFACE) { error_message= "Unable to create dummy window surface"; goto fail; } return TRUE; fail: _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, "%s", error_message); return FALSE; }
CoglBool cogl_pipeline_set_depth_state (CoglPipeline *pipeline, const CoglDepthState *depth_state, CoglError **error) { CoglPipelineState state = COGL_PIPELINE_STATE_DEPTH; CoglPipeline *authority; CoglDepthState *orig_state; _COGL_GET_CONTEXT (ctx, FALSE); _COGL_RETURN_VAL_IF_FAIL (cogl_is_pipeline (pipeline), FALSE); _COGL_RETURN_VAL_IF_FAIL (depth_state->magic == COGL_DEPTH_STATE_MAGIC, FALSE); authority = _cogl_pipeline_get_authority (pipeline, state); orig_state = &authority->big_state->depth_state; if (orig_state->test_enabled == depth_state->test_enabled && orig_state->write_enabled == depth_state->write_enabled && orig_state->test_function == depth_state->test_function && orig_state->range_near == depth_state->range_near && orig_state->range_far == depth_state->range_far) return TRUE; if (ctx->driver == COGL_DRIVER_GLES1 && (depth_state->range_near != 0 || depth_state->range_far != 1)) { _cogl_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, "glDepthRange not available on GLES 1"); return FALSE; } /* - Flush journal primitives referencing the current state. * - Make sure the pipeline has no dependants so it may be modified. * - If the pipeline isn't currently an authority for the state being * changed, then initialize that state from the current authority. */ _cogl_pipeline_pre_change_notify (pipeline, state, NULL, FALSE); pipeline->big_state->depth_state = *depth_state; _cogl_pipeline_update_authority (pipeline, authority, state, _cogl_pipeline_depth_state_equal); return TRUE; }
static CoglBool _cogl_winsys_egl_context_created (CoglDisplay *display, CoglError **error) { CoglRenderer *renderer = display->renderer; CoglRendererEGL *egl_renderer = renderer->winsys; CoglDisplayEGL *egl_display = display->winsys; CoglDisplayGDL *gdl_display = egl_display->platform; const char *error_message; egl_display->egl_surface = eglCreateWindowSurface (egl_renderer->edpy, egl_display->egl_config, (NativeWindowType) display->gdl_plane, NULL); if (egl_display->egl_surface == EGL_NO_SURFACE) { error_message = "Unable to create EGL window surface"; goto fail; } if (!_cogl_winsys_egl_make_current (display, egl_display->egl_surface, egl_display->egl_surface, egl_display->egl_context)) { error_message = "Unable to eglMakeCurrent with egl surface"; goto fail; } eglQuerySurface (egl_renderer->edpy, egl_display->egl_surface, EGL_WIDTH, &gdl_display->egl_surface_width); eglQuerySurface (egl_renderer->edpy, egl_display->egl_surface, EGL_HEIGHT, &gdl_display->egl_surface_height); return TRUE; fail: _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, "%s", error_message); return FALSE; }
static CoglBool validate_statements_for_context (CoglBlendStringStatement *statements, int n_statements, CoglBlendStringContext context, CoglError **error) { const char *error_string; if (n_statements == 1) { if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_ALPHA) { error_string = "You need to also give a blend statement for the RGB" "channels"; goto error; } else if (statements[0].mask == COGL_BLEND_STRING_CHANNEL_MASK_RGB) { error_string = "You need to also give a blend statement for the " "Alpha channel"; goto error; } } if (context == COGL_BLEND_STRING_CONTEXT_BLENDING) return validate_blend_statements (statements, n_statements, error); else return validate_tex_combine_statements (statements, n_statements, error); error: _cogl_set_error (error, COGL_BLEND_STRING_ERROR, COGL_BLEND_STRING_ERROR_INVALID_ERROR, "Invalid %s string: %s", context == COGL_BLEND_STRING_CONTEXT_BLENDING ? "blend" : "texture combine", error_string); if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) { g_debug ("Invalid %s string: %s", context == COGL_BLEND_STRING_CONTEXT_BLENDING ? "blend" : "texture combine", error_string); } return FALSE; }
static CoglBool _cogl_winsys_renderer_connect (CoglRenderer *renderer, CoglError **error) { if (SDL_VideoInit (NULL) < 0) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, "SDL_Init failed: %s", SDL_GetError ()); return FALSE; } renderer->winsys = g_slice_new0 (CoglRendererSdl2); return TRUE; }
static CoglBool validate_tex_combine_statements (CoglBlendStringStatement *statements, int n_statements, CoglError **error) { int i, j; const char *error_string; CoglBlendStringError detail = COGL_BLEND_STRING_ERROR_INVALID_ERROR; for (i = 0; i < n_statements; i++) { for (j = 0; j < statements[i].function->argc; j++) { CoglBlendStringArgument *arg = &statements[i].args[j]; if (arg->source.is_zero) { error_string = "You can't use the constant '0' as a texture " "combine argument"; goto error; } if (!arg->factor.is_one) { error_string = "Argument factors are only relevant to blending " "not texture combining"; goto error; } } } return TRUE; error: _cogl_set_error (error, COGL_BLEND_STRING_ERROR, detail, "Invalid texture combine string: %s", error_string); if (COGL_DEBUG_ENABLED (COGL_DEBUG_BLEND_STRINGS)) { g_debug ("Invalid texture combine string: %s", error_string); } return FALSE; }
static CoglBool _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, CoglError **error) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglOnscreenSdl2 *sdl_onscreen; SDL_Window *window; int width, height; SDL_WindowFlags flags; width = cogl_framebuffer_get_width (framebuffer); height = cogl_framebuffer_get_height (framebuffer); flags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN; /* The resizable property on SDL window apparently can only be set * on creation */ if (onscreen->resizable) flags |= SDL_WINDOW_RESIZABLE; window = SDL_CreateWindow ("" /* title */, 0, 0, /* x/y */ width, height, flags); if (window == NULL) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_ONSCREEN, "SDL_CreateWindow failed: %s", SDL_GetError ()); return FALSE; } SDL_SetWindowData (window, COGL_SDL_WINDOW_DATA_KEY, onscreen); onscreen->winsys = g_slice_new (CoglOnscreenSdl2); sdl_onscreen = onscreen->winsys; sdl_onscreen->window = window; return TRUE; }
CoglBool _cogl_winsys_egl_renderer_connect_common (CoglRenderer *renderer, CoglError **error) { CoglRendererEGL *egl_renderer = renderer->winsys; if (!eglInitialize (egl_renderer->edpy, &egl_renderer->egl_version_major, &egl_renderer->egl_version_minor)) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_INIT, "Couldn't initialize EGL"); return FALSE; } check_egl_extensions (renderer); return TRUE; }
static gboolean _cogl_texture_pixmap_x11_set_region (CoglTexture *tex, int src_x, int src_y, int dst_x, int dst_y, int dst_width, int dst_height, int level, CoglBitmap *bmp, CoglError **error) { /* This doesn't make much sense for texture from pixmap so it's not supported */ _cogl_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, "Explicitly setting a region of a TFP texture unsupported"); return FALSE; }
static CoglBool _cogl_texture_3d_set_region (CoglTexture *tex, int src_x, int src_y, int dst_x, int dst_y, int dst_width, int dst_height, int level, CoglBitmap *bmp, CoglError **error) { /* This function doesn't really make sense for 3D textures because it can't specify which image to upload to */ _cogl_set_error (error, COGL_SYSTEM_ERROR, COGL_SYSTEM_ERROR_UNSUPPORTED, "Setting a 2D region on a 3D texture isn't " "currently supported"); return FALSE; }
static gboolean allocate_from_egl_image (CoglTexture2D *tex_2d, CoglTextureLoader *loader, CoglError **error) { CoglTexture *tex = COGL_TEXTURE (tex_2d); CoglContext *ctx = tex->context; CoglPixelFormat internal_format = loader->src.egl_image.format; tex_2d->gl_texture = ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format); _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, tex_2d->gl_texture, FALSE); _cogl_gl_util_clear_gl_errors (ctx); ctx->glEGLImageTargetTexture2D (GL_TEXTURE_2D, loader->src.egl_image.image); if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR) { _cogl_set_error (error, COGL_TEXTURE_ERROR, COGL_TEXTURE_ERROR_BAD_PARAMETER, "Could not create a CoglTexture2D from a given " "EGLImage"); GE( ctx, glDeleteTextures (1, &tex_2d->gl_texture) ); return FALSE; } tex_2d->internal_format = internal_format; _cogl_texture_set_allocated (tex, internal_format, loader->src.egl_image.width, loader->src.egl_image.height); return TRUE; }