static gboolean _cogl_texture_pixmap_x11_can_hardware_repeat (CoglTexture *tex) { CoglTexturePixmapX11 *tex_pixmap = COGL_TEXTURE_PIXMAP_X11 (tex); CoglTexture *child_tex = _cogl_texture_pixmap_x11_get_texture (tex_pixmap); return _cogl_texture_can_hardware_repeat (child_tex); }
static CoglBool _cogl_sub_texture_can_hardware_repeat (CoglTexture *tex) { CoglSubTexture *sub_tex = COGL_SUB_TEXTURE (tex); /* We can hardware repeat if the subtexture actually represents all of the of the full texture */ return (tex->width == cogl_texture_get_width (sub_tex->full_texture) && tex->height == cogl_texture_get_height (sub_tex->full_texture) && _cogl_texture_can_hardware_repeat (sub_tex->full_texture)); }
static CoglBool validate_layer_cb (CoglPipelineLayer *layer, void *user_data) { CoglBool *needs_fallback = user_data; CoglTexture *texture = _cogl_pipeline_layer_get_texture (layer); /* If any of the layers of the current pipeline contain sliced * textures or textures with waste then it won't work to draw the * path directly. Instead we fallback to pushing the path as a clip * on the clip-stack and drawing the path's bounding rectangle * instead. */ if (texture != NULL && (cogl_texture_is_sliced (texture) || !_cogl_texture_can_hardware_repeat (texture))) *needs_fallback = TRUE; return !*needs_fallback; }
static CoglBool _cogl_rectangles_validate_layer_cb (CoglPipeline *pipeline, int layer_index, void *user_data) { ValidateLayerState *state = user_data; CoglTexture *texture; state->i++; /* We need to ensure the mipmaps are ready before deciding * anything else about the texture because the texture storage * could completely change if it needs to be migrated out of the * atlas and will affect how we validate the layer. * * FIXME: this needs to be generalized. There could be any * number of things that might require a shuffling of the * underlying texture storage. We could add two mechanisms to * generalize this a bit... * * 1) add a _cogl_pipeline_layer_update_storage() function that * would for instance consider if mipmapping is necessary and * potentially migrate the texture from an atlas. * * 2) allow setting of transient primitive-flags on a pipeline * that may affect the outcome of _update_storage(). One flag * could indicate that we expect to sample beyond the bounds of * the texture border. * * flags = COGL_PIPELINE_PRIMITIVE_FLAG_VALID_BORDERS; * _cogl_pipeline_layer_assert_primitive_flags (layer, flags) * _cogl_pipeline_layer_update_storage (layer) * enqueue primitive in journal * * when the primitive is dequeued and drawn we should: * _cogl_pipeline_flush_gl_state (pipeline) * draw primitive * _cogl_pipeline_unassert_primitive_flags (layer, flags); * * _cogl_pipeline_layer_update_storage should take into * consideration all the asserted primitive requirements. (E.g. * there could be multiple primitives in the journal - or in a * renderlist in the future - that need mipmaps or that need * valid contents beyond their borders (for cogl_polygon) * meaning they can't work with textures in an atas, so * _cogl_pipeline_layer_update_storage would pass on these * requirements to the texture atlas backend which would make * sure the referenced texture is migrated out of the atlas and * mipmaps are generated.) */ _cogl_pipeline_pre_paint_for_layer (pipeline, layer_index); texture = cogl_pipeline_get_layer_texture (pipeline, layer_index); /* NULL textures are handled by * _cogl_pipeline_flush_gl_state */ if (texture == NULL) return TRUE; if (state->i == 0) state->first_layer = layer_index; /* XXX: * For now, if the first layer is sliced then all other layers are * ignored since we currently don't support multi-texturing with * sliced textures. If the first layer is not sliced then any other * layers found to be sliced will be skipped. (with a warning) * * TODO: Add support for multi-texturing rectangles with sliced * textures if no texture matrices are in use. */ if (cogl_texture_is_sliced (texture)) { if (state->i == 0) { if (cogl_pipeline_get_n_layers (pipeline) > 1) { static CoglBool warning_seen = FALSE; if (!state->override_source) state->override_source = cogl_pipeline_copy (pipeline); _cogl_pipeline_prune_to_n_layers (state->override_source, 1); if (!warning_seen) g_warning ("Skipping layers 1..n of your pipeline since " "the first layer is sliced. We don't currently " "support any multi-texturing with sliced " "textures but assume layer 0 is the most " "important to keep"); warning_seen = TRUE; } state->all_use_sliced_quad_fallback = TRUE; return FALSE; } else { static CoglBool warning_seen = FALSE; CoglTexture2D *tex_2d; if (!warning_seen) g_warning ("Skipping layer %d of your pipeline consisting of " "a sliced texture (unsuported for multi texturing)", state->i); warning_seen = TRUE; /* Note: currently only 2D textures can be sliced. */ tex_2d = state->ctx->default_gl_texture_2d_tex; cogl_pipeline_set_layer_texture (pipeline, layer_index, COGL_TEXTURE (tex_2d)); return TRUE; } } #ifdef COGL_ENABLE_DEBUG /* If the texture can't be repeated with the GPU (e.g. because it has * waste or if using GL_TEXTURE_RECTANGLE_ARB) then if a texture matrix * is also in use we don't know if the result will end up trying * to texture from the waste area. * * Note: we check can_hardware_repeat() first since it's cheaper. * * Note: cases where the texture coordinates will require repeating * will be caught by later validation. */ if (!_cogl_texture_can_hardware_repeat (texture) && _cogl_pipeline_layer_has_user_matrix (pipeline, layer_index)) { static CoglBool warning_seen = FALSE; if (!warning_seen) g_warning ("layer %d of your pipeline uses a custom " "texture matrix but because the texture doesn't " "support hardware repeating you may see artefacts " "due to sampling beyond the texture's bounds.", state->i); warning_seen = TRUE; } #endif return TRUE; }