mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-08 10:08:00 +02:00
gl-renderer: Add texture parameters utilities
Cache and update texture parameters only when changed by storing minification/magnification filters, wrap modes and their target into a dedicated gl_texture_parameters structure and by calling new utility functions to create and flush parameters. This structure is itself stored into the buffer state for each texture of a surface and into the output state for border and shadow textures. The shader config filled before emitting a draw call now just takes a pointer to the array of texture ids, a pointer to the array of parameters and the number of textures. This allows to simplify the logic in gl-renderer.c, to minimise GL state changes and to let the utility wrapper validate the parameters. Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
This commit is contained in:
parent
acc40ce2bb
commit
5342945bb8
5 changed files with 237 additions and 77 deletions
|
|
@ -299,6 +299,26 @@ static_assert(sizeof(struct gl_shader_requirements) ==
|
|||
4 /* total bitfield size in bytes */,
|
||||
"struct gl_shader_requirements must not contain implicit padding");
|
||||
|
||||
enum gl_texture_flag {
|
||||
TEXTURE_FILTERS_DIRTY = 1 << 0,
|
||||
TEXTURE_WRAP_MODES_DIRTY = 1 << 1,
|
||||
TEXTURE_ALL_DIRTY = (TEXTURE_FILTERS_DIRTY |
|
||||
TEXTURE_WRAP_MODES_DIRTY),
|
||||
};
|
||||
|
||||
struct gl_texture_parameters {
|
||||
GLenum target;
|
||||
union {
|
||||
struct { GLint min, mag; };
|
||||
GLint array[2];
|
||||
} filters;
|
||||
union {
|
||||
struct { GLint s, t, r; };
|
||||
GLint array[3];
|
||||
} wrap_modes;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct gl_shader;
|
||||
struct weston_color_transform;
|
||||
struct dmabuf_allocator;
|
||||
|
|
@ -311,8 +331,11 @@ struct gl_shader_config {
|
|||
float view_alpha;
|
||||
GLfloat unicolor[4];
|
||||
GLfloat tint[4];
|
||||
GLint input_tex_filter; /* GL_NEAREST or GL_LINEAR */
|
||||
GLuint input_tex[SHADER_INPUT_TEX_MAX];
|
||||
|
||||
struct gl_texture_parameters *input_param;
|
||||
GLuint *input_tex;
|
||||
int input_num;
|
||||
|
||||
GLuint wireframe_tex;
|
||||
|
||||
union {
|
||||
|
|
@ -589,6 +612,18 @@ gl_texture_3d_store(struct gl_renderer *gr,
|
|||
void
|
||||
gl_texture_fini(GLuint *tex);
|
||||
|
||||
void
|
||||
gl_texture_parameters_init(struct gl_renderer *gr,
|
||||
struct gl_texture_parameters *parameters,
|
||||
GLenum target,
|
||||
const GLint *filters,
|
||||
const GLint *wrap_modes,
|
||||
bool flush);
|
||||
|
||||
void
|
||||
gl_texture_parameters_flush(struct gl_renderer *gr,
|
||||
struct gl_texture_parameters *parameters);
|
||||
|
||||
bool
|
||||
gl_fbo_is_format_supported(struct gl_renderer *gr,
|
||||
GLenum format);
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ struct gl_output_state {
|
|||
struct gl_border_image borders_pending[4];
|
||||
struct gl_border_image borders_current[4];
|
||||
enum gl_border_status border_status;
|
||||
struct gl_texture_parameters borders_param[4];
|
||||
GLuint borders_tex[4];
|
||||
|
||||
struct weston_matrix output_matrix;
|
||||
|
|
@ -156,6 +157,7 @@ struct gl_output_state {
|
|||
struct wl_list timeline_render_point_list;
|
||||
|
||||
const struct pixel_format_info *shadow_format;
|
||||
struct gl_texture_parameters shadow_param;
|
||||
GLuint shadow_tex;
|
||||
GLuint shadow_fb;
|
||||
|
||||
|
|
@ -243,6 +245,7 @@ struct gl_buffer_state {
|
|||
enum gl_shader_texture_variant shader_variant;
|
||||
|
||||
struct gl_format_info texture_format[3];
|
||||
struct gl_texture_parameters parameters[3];
|
||||
GLuint textures[3];
|
||||
int num_textures;
|
||||
|
||||
|
|
@ -1338,13 +1341,11 @@ prepare_placeholder(struct gl_shader_config *sconf,
|
|||
|
||||
*sconf = alt;
|
||||
}
|
||||
|
||||
static void
|
||||
gl_shader_config_set_input_textures(struct gl_shader_config *sconf,
|
||||
struct gl_surface_state *gs)
|
||||
struct gl_buffer_state *gb)
|
||||
{
|
||||
struct gl_buffer_state *gb = gs->buffer;
|
||||
int i;
|
||||
|
||||
sconf->req.variant = gb->shader_variant;
|
||||
sconf->req.color_channel_order = gb->gl_channel_order;
|
||||
sconf->req.input_is_premult =
|
||||
|
|
@ -1352,22 +1353,22 @@ gl_shader_config_set_input_textures(struct gl_shader_config *sconf,
|
|||
|
||||
copy_uniform4f(sconf->unicolor, gb->color);
|
||||
|
||||
assert(gb->num_textures <= SHADER_INPUT_TEX_MAX);
|
||||
for (i = 0; i < gb->num_textures; i++)
|
||||
sconf->input_tex[i] = gb->textures[i];
|
||||
for (; i < SHADER_INPUT_TEX_MAX; i++)
|
||||
sconf->input_tex[i] = 0;
|
||||
sconf->input_param = gb->parameters;
|
||||
sconf->input_tex = gb->textures;
|
||||
sconf->input_num = gb->num_textures;
|
||||
}
|
||||
|
||||
static bool
|
||||
gl_shader_config_init_for_paint_node(struct gl_shader_config *sconf,
|
||||
struct weston_paint_node *pnode,
|
||||
GLint filter)
|
||||
struct weston_paint_node *pnode)
|
||||
{
|
||||
struct gl_renderer *gr = get_renderer(pnode->surface->compositor);
|
||||
struct gl_surface_state *gs = get_surface_state(pnode->surface);
|
||||
struct gl_buffer_state *gb = gs->buffer;
|
||||
struct gl_output_state *go = get_output_state(pnode->output);
|
||||
struct weston_buffer *buffer = gs->buffer_ref.buffer;
|
||||
GLint filter;
|
||||
int i;
|
||||
|
||||
if (!pnode->surf_xform_valid)
|
||||
return false;
|
||||
|
|
@ -1378,7 +1379,6 @@ gl_shader_config_init_for_paint_node(struct gl_shader_config *sconf,
|
|||
.surface_to_buffer =
|
||||
pnode->view->surface->surface_to_buffer_matrix,
|
||||
.view_alpha = pnode->view->alpha,
|
||||
.input_tex_filter = filter,
|
||||
};
|
||||
|
||||
weston_matrix_multiply(&sconf->projection, &go->output_matrix);
|
||||
|
|
@ -1394,7 +1394,16 @@ gl_shader_config_init_for_paint_node(struct gl_shader_config *sconf,
|
|||
weston_matrix_translate(&sconf->surface_to_buffer, 0, 1, 0);
|
||||
}
|
||||
|
||||
gl_shader_config_set_input_textures(sconf, gs);
|
||||
gl_shader_config_set_input_textures(sconf, gb);
|
||||
|
||||
filter = pnode->needs_filtering ? GL_LINEAR : GL_NEAREST;
|
||||
for (i = 0; i < gb->num_textures; i++) {
|
||||
if (filter != gb->parameters[i].filters.min) {
|
||||
gb->parameters[i].filters.min = filter;
|
||||
gb->parameters[i].filters.mag = filter;
|
||||
gb->parameters[i].flags |= TEXTURE_FILTERS_DIRTY;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gl_shader_config_set_color_transform(gr, sconf, pnode->surf_xform.transform)) {
|
||||
weston_log("GL-renderer: failed to generate a color transformation.\n");
|
||||
|
|
@ -1754,7 +1763,6 @@ draw_paint_node(struct weston_paint_node *pnode,
|
|||
pixman_region32_t surface_opaque;
|
||||
/* non-opaque region in surface coordinates: */
|
||||
pixman_region32_t surface_blend;
|
||||
GLint filter;
|
||||
struct gl_shader_config sconf;
|
||||
struct clipper_quad *quads = NULL;
|
||||
int nquads;
|
||||
|
|
@ -1772,12 +1780,7 @@ draw_paint_node(struct weston_paint_node *pnode,
|
|||
if (!pnode->draw_solid && ensure_surface_buffer_is_ready(gr, gs) < 0)
|
||||
goto out;
|
||||
|
||||
if (pnode->needs_filtering)
|
||||
filter = GL_LINEAR;
|
||||
else
|
||||
filter = GL_NEAREST;
|
||||
|
||||
if (!gl_shader_config_init_for_paint_node(&sconf, pnode, filter))
|
||||
if (!gl_shader_config_init_for_paint_node(&sconf, pnode))
|
||||
goto out;
|
||||
|
||||
/* XXX: Should we be using ev->transform.opaque here? */
|
||||
|
|
@ -1947,6 +1950,8 @@ static void
|
|||
update_wireframe_tex(struct gl_renderer *gr,
|
||||
const struct weston_geometry *area)
|
||||
{
|
||||
GLint filters[] = { GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR };
|
||||
struct gl_texture_parameters params;
|
||||
int new_size, i;
|
||||
uint8_t *buffer;
|
||||
|
||||
|
|
@ -1972,9 +1977,8 @@ update_wireframe_tex(struct gl_renderer *gr,
|
|||
glActiveTexture(GL_TEXTURE0 + TEX_UNIT_WIREFRAME);
|
||||
gl_texture_2d_init(gr, (int) log2(new_size) + 1, GL_R8, new_size, 1,
|
||||
&gr->wireframe_tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
GL_LINEAR_MIPMAP_LINEAR);
|
||||
gl_texture_parameters_init(gr, ¶ms, GL_TEXTURE_2D, filters, NULL,
|
||||
true);
|
||||
gr->wireframe_size = new_size;
|
||||
|
||||
/* Store mip chain with a wireframe thickness of 1.0. */
|
||||
|
|
@ -2010,12 +2014,9 @@ update_borders_tex(struct gl_renderer *gr,
|
|||
gl_texture_2d_init(
|
||||
gr, 1, GL_BGRA8_EXT, pending->tex_width,
|
||||
pending->height, &go->borders_tex[i]);
|
||||
glTexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_S,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_T,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
gl_texture_parameters_init(
|
||||
gr, &go->borders_param[i],
|
||||
GL_TEXTURE_2D, NULL, NULL, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2043,8 +2044,9 @@ draw_output_border_texture(struct gl_renderer *gr,
|
|||
/* An empty border image (as allowed by output_set_borders) would use
|
||||
* the default (incomplete) OpenGL ES texture which, per spec, returns
|
||||
* (0, 0, 0, 1) in the fragment shader. */
|
||||
sconf->input_tex_filter = GL_NEAREST;
|
||||
sconf->input_tex[0] = go->borders_tex[side];
|
||||
sconf->input_tex = &go->borders_tex[side];
|
||||
sconf->input_param = &go->borders_param[side];
|
||||
sconf->input_num = 1;
|
||||
gl_renderer_use_program(gr, sconf);
|
||||
|
||||
GLfloat texcoord[] = {
|
||||
|
|
@ -2278,8 +2280,9 @@ blit_shadow_to_output(struct weston_output *output,
|
|||
WESTON_MATRIX_TRANSFORM_TRANSLATE,
|
||||
},
|
||||
.view_alpha = 1.0f,
|
||||
.input_tex_filter = GL_NEAREST,
|
||||
.input_tex[0] = go->shadow_tex,
|
||||
.input_tex = &go->shadow_tex,
|
||||
.input_param = &go->shadow_param,
|
||||
.input_num = 1,
|
||||
};
|
||||
struct gl_renderer *gr = get_renderer(output->compositor);
|
||||
double width = go->area.width;
|
||||
|
|
@ -2736,14 +2739,12 @@ ensure_textures(struct gl_buffer_state *gb, GLenum target, int num_textures)
|
|||
|
||||
assert(gb->num_textures == 0);
|
||||
|
||||
for (i = 0; i < num_textures; i++) {
|
||||
glGenTextures(1, &gb->textures[i]);
|
||||
glBindTexture(target, gb->textures[i]);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
glGenTextures(num_textures, gb->textures);
|
||||
gb->num_textures = num_textures;
|
||||
glBindTexture(target, 0);
|
||||
|
||||
for (i = 0; i < num_textures; i++)
|
||||
gl_texture_parameters_init(gb->gr, &gb->parameters[i], target,
|
||||
NULL, NULL, false);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2874,10 +2875,8 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer)
|
|||
gl_texture_2d_init(gr, 1, texture_format[i].internal,
|
||||
buffer->width / hsub, buffer->height / vsub,
|
||||
&gb->textures[i]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
|
||||
GL_CLAMP_TO_EDGE);
|
||||
gl_texture_parameters_init(gr, &gb->parameters[i],
|
||||
GL_TEXTURE_2D, NULL, NULL, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3524,7 +3523,6 @@ gl_renderer_attach_buffer(struct weston_surface *surface,
|
|||
struct gl_renderer *gr = get_renderer(surface->compositor);
|
||||
struct gl_surface_state *gs = get_surface_state(surface);
|
||||
struct gl_buffer_state *gb;
|
||||
GLenum target;
|
||||
int i;
|
||||
|
||||
assert(buffer->renderer_private);
|
||||
|
|
@ -3535,14 +3533,14 @@ gl_renderer_attach_buffer(struct weston_surface *surface,
|
|||
if (gb->specified)
|
||||
return;
|
||||
|
||||
target = gl_shader_texture_variant_get_target(gb->shader_variant);
|
||||
for (i = 0; i < gb->num_images; ++i) {
|
||||
glBindTexture(target, gb->textures[i]);
|
||||
glBindTexture(gb->parameters[i].target, gb->textures[i]);
|
||||
if (gl_extensions_has(gr, EXTENSION_EXT_EGL_IMAGE_STORAGE))
|
||||
gr->image_target_tex_storage(target, gb->images[i],
|
||||
NULL);
|
||||
gr->image_target_tex_storage(gb->parameters[i].target,
|
||||
gb->images[i], NULL);
|
||||
else
|
||||
gr->image_target_texture_2d(target, gb->images[i]);
|
||||
gr->image_target_texture_2d(gb->parameters[i].target,
|
||||
gb->images[i]);
|
||||
}
|
||||
|
||||
gb->specified = true;
|
||||
|
|
@ -3763,7 +3761,6 @@ gl_renderer_surface_copy_content(struct weston_surface *surface,
|
|||
};
|
||||
struct gl_shader_config sconf = {
|
||||
.view_alpha = 1.0f,
|
||||
.input_tex_filter = GL_NEAREST,
|
||||
};
|
||||
const pixman_format_code_t format = PIXMAN_a8b8g8r8;
|
||||
struct gl_renderer *gr = get_renderer(surface->compositor);
|
||||
|
|
@ -3794,7 +3791,7 @@ gl_renderer_surface_copy_content(struct weston_surface *surface,
|
|||
break;
|
||||
}
|
||||
|
||||
gl_shader_config_set_input_textures(&sconf, gs);
|
||||
gl_shader_config_set_input_textures(&sconf, gb);
|
||||
|
||||
if (!gl_fbo_init(gr, GL_RGBA8, cw, ch, &fbo, &rb)) {
|
||||
weston_log("Failed to init FBO\n");
|
||||
|
|
@ -4037,6 +4034,8 @@ gl_renderer_resize_output(struct weston_output *output,
|
|||
ret = gl_fbo_texture_init(gr, shfmt->gl.internal, area->width,
|
||||
area->height, &go->shadow_fb,
|
||||
&go->shadow_tex);
|
||||
gl_texture_parameters_init(gr, &go->shadow_param, GL_TEXTURE_2D, NULL,
|
||||
NULL, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -181,8 +181,10 @@ gl_color_curve_lut_3x1d(struct gl_renderer *gr,
|
|||
const struct weston_color_curve *curve,
|
||||
struct weston_color_transform *xform)
|
||||
{
|
||||
GLint filters[] = { GL_LINEAR, GL_LINEAR };
|
||||
const unsigned lut_len = curve->u.lut_3x1d.optimal_len;
|
||||
const unsigned nr_rows = 4;
|
||||
struct gl_texture_parameters params;
|
||||
GLuint tex;
|
||||
float *lut;
|
||||
|
||||
|
|
@ -199,12 +201,10 @@ gl_color_curve_lut_3x1d(struct gl_renderer *gr,
|
|||
curve->u.lut_3x1d.fill_in(xform, lut, lut_len);
|
||||
|
||||
gl_texture_2d_init(gr, 1, GL_R32F, lut_len, nr_rows, &tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
gl_texture_2d_store(gr, 0, 0, 0, lut_len, nr_rows, GL_RED, GL_FLOAT,
|
||||
lut);
|
||||
gl_texture_parameters_init(gr, ¶ms, GL_TEXTURE_2D, filters, NULL,
|
||||
true);
|
||||
|
||||
free(lut);
|
||||
|
||||
|
|
@ -222,7 +222,8 @@ gl_3d_lut(struct gl_renderer *gr,
|
|||
struct gl_renderer_color_transform *gl_xform,
|
||||
struct weston_color_transform *xform)
|
||||
{
|
||||
|
||||
GLint filters[] = { GL_LINEAR, GL_LINEAR };
|
||||
struct gl_texture_parameters params;
|
||||
GLuint tex3d;
|
||||
float *lut;
|
||||
const unsigned dim_size = xform->mapping.u.lut3d.optimal_len;
|
||||
|
|
@ -235,13 +236,10 @@ gl_3d_lut(struct gl_renderer *gr,
|
|||
|
||||
gl_texture_3d_init(gr, 1, GL_RGB32F, dim_size, dim_size, dim_size,
|
||||
&tex3d);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
gl_texture_3d_store(gr, 0, 0, 0, 0, dim_size, dim_size, dim_size,
|
||||
GL_RGB, GL_FLOAT, lut);
|
||||
gl_texture_parameters_init(gr, ¶ms, GL_TEXTURE_3D, filters, NULL,
|
||||
true);
|
||||
|
||||
glBindTexture(GL_TEXTURE_3D, 0);
|
||||
gl_xform->mapping.type = SHADER_COLOR_MAPPING_3DLUT;
|
||||
|
|
|
|||
|
|
@ -657,11 +657,10 @@ gl_shader_texture_variant_get_target(enum gl_shader_texture_variant v)
|
|||
}
|
||||
|
||||
static void
|
||||
gl_shader_load_config(struct gl_shader *shader,
|
||||
gl_shader_load_config(struct gl_renderer *gr,
|
||||
struct gl_shader *shader,
|
||||
const struct gl_shader_config *sconf)
|
||||
{
|
||||
GLint in_filter = sconf->input_tex_filter;
|
||||
GLenum in_tgt;
|
||||
GLsizei n_params;
|
||||
int i;
|
||||
|
||||
|
|
@ -679,18 +678,15 @@ gl_shader_load_config(struct gl_shader *shader,
|
|||
|
||||
glUniform1f(shader->view_alpha_uniform, sconf->view_alpha);
|
||||
|
||||
in_tgt = gl_shader_texture_variant_get_target(sconf->req.variant);
|
||||
for (i = 0; i < SHADER_INPUT_TEX_MAX; i++) {
|
||||
if (sconf->input_tex[i] == 0)
|
||||
continue;
|
||||
|
||||
assert(sconf->input_num <= SHADER_INPUT_TEX_MAX);
|
||||
for (i = 0; i < sconf->input_num; i++) {
|
||||
assert(shader->tex_uniforms[i] != -1);
|
||||
glUniform1i(shader->tex_uniforms[i], TEX_UNIT_IMAGES + i);
|
||||
glActiveTexture(GL_TEXTURE0 + TEX_UNIT_IMAGES + i);
|
||||
|
||||
glBindTexture(in_tgt, sconf->input_tex[i]);
|
||||
glTexParameteri(in_tgt, GL_TEXTURE_MIN_FILTER, in_filter);
|
||||
glTexParameteri(in_tgt, GL_TEXTURE_MAG_FILTER, in_filter);
|
||||
glBindTexture(sconf->input_param[i].target,
|
||||
sconf->input_tex[i]);
|
||||
if (sconf->input_tex[i])
|
||||
gl_texture_parameters_flush(gr, &sconf->input_param[i]);
|
||||
}
|
||||
|
||||
/* Fixed texture unit for color_pre_curve LUT if it is available */
|
||||
|
|
@ -809,7 +805,7 @@ gl_renderer_use_program(struct gl_renderer *gr,
|
|||
gr->current_shader = shader;
|
||||
}
|
||||
|
||||
gl_shader_load_config(shader, sconf);
|
||||
gl_shader_load_config(gr, shader, sconf);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -579,6 +579,63 @@ is_valid_combination_es2(struct gl_renderer *gr,
|
|||
}
|
||||
}
|
||||
|
||||
/* Validate texture parameters.
|
||||
*/
|
||||
static bool
|
||||
are_valid_texture_parameters(struct gl_renderer *gr,
|
||||
struct gl_texture_parameters *parameters)
|
||||
{
|
||||
GLint tex = 0;
|
||||
int i;
|
||||
|
||||
if (parameters->target == GL_TEXTURE_2D)
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);
|
||||
else if (parameters->target == GL_TEXTURE_3D)
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_3D, &tex);
|
||||
else if (parameters->target == GL_TEXTURE_EXTERNAL_OES)
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_EXTERNAL_OES, &tex);
|
||||
if (tex == 0)
|
||||
return false;
|
||||
|
||||
/* Filters. */
|
||||
for (i = 0; i < 2; i++) {
|
||||
switch (parameters->filters.array[i]) {
|
||||
case GL_NEAREST:
|
||||
case GL_LINEAR:
|
||||
break;
|
||||
|
||||
case GL_NEAREST_MIPMAP_NEAREST:
|
||||
case GL_NEAREST_MIPMAP_LINEAR:
|
||||
case GL_LINEAR_MIPMAP_NEAREST:
|
||||
case GL_LINEAR_MIPMAP_LINEAR:
|
||||
/* Minification filter only. */
|
||||
if (parameters->target == GL_TEXTURE_EXTERNAL_OES ||
|
||||
¶meters->filters.array[i] == ¶meters->filters.mag)
|
||||
return false;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
/* Wrap modes. OpenGL ES 3.2 (and extensions) has GL_CLAMP_TO_BORDER but
|
||||
* Weston doesn't need it. */
|
||||
for (i = 0; i < 3; i++) {
|
||||
switch (parameters->wrap_modes.array[i]) {
|
||||
case GL_CLAMP_TO_EDGE:
|
||||
case GL_REPEAT:
|
||||
case GL_MIRRORED_REPEAT:
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* !defined(NDEBUG) */
|
||||
|
||||
/* Get the supported BGRA8 texture creation method. This is needed to correctly
|
||||
|
|
@ -1214,6 +1271,81 @@ gl_texture_fini(GLuint *tex)
|
|||
*tex = 0;
|
||||
}
|
||||
|
||||
/* Initialise texture parameters. 'target' is either a 2D, a 3D or an external
|
||||
* texture target. 'filters' points to an array of 2 values for respectively the
|
||||
* texture minification and magnification filters. 'wrap_modes' points to an
|
||||
* array of 3 values for the S, T and R texture wrap modes. The texture object
|
||||
* bound to the given texture target (of the active texture) is updated if
|
||||
* 'flush' is true, make sure it's properly bound in that case. The parameters
|
||||
* and the flags bitfield can then directly be set and flushed when needed.
|
||||
*
|
||||
* filters are set to GL_NEAREST if 'filters' is NULL and wrap modes are set to
|
||||
* GL_CLAMP_TO_EDGE if 'wrap_modes' is NULL.
|
||||
*
|
||||
* See gl_texture_parameters_flush().
|
||||
*/
|
||||
void
|
||||
gl_texture_parameters_init(struct gl_renderer *gr,
|
||||
struct gl_texture_parameters *parameters,
|
||||
GLenum target,
|
||||
const GLint *filters,
|
||||
const GLint *wrap_modes,
|
||||
bool flush)
|
||||
{
|
||||
GLint default_filters[] = { GL_NEAREST, GL_NEAREST };
|
||||
GLint default_wrap_modes[] = { GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE,
|
||||
GL_CLAMP_TO_EDGE };
|
||||
|
||||
assert(target == GL_TEXTURE_2D ||
|
||||
target == GL_TEXTURE_3D ||
|
||||
target == GL_TEXTURE_EXTERNAL_OES);
|
||||
assert(target != GL_TEXTURE_3D ||
|
||||
gl_features_has(gr, FEATURE_TEXTURE_3D));
|
||||
assert(target != GL_TEXTURE_EXTERNAL_OES ||
|
||||
gl_extensions_has(gr, EXTENSION_OES_EGL_IMAGE_EXTERNAL));
|
||||
|
||||
parameters->target = target;
|
||||
memcpy(¶meters->filters, filters ? filters : default_filters,
|
||||
sizeof default_filters);
|
||||
memcpy(¶meters->wrap_modes, wrap_modes ? wrap_modes :
|
||||
default_wrap_modes, sizeof default_wrap_modes);
|
||||
parameters->flags = TEXTURE_ALL_DIRTY;
|
||||
|
||||
if (flush)
|
||||
gl_texture_parameters_flush(gr, parameters);
|
||||
}
|
||||
|
||||
/* Flush texture parameters to the texture object currently bound to the texture
|
||||
* target (of the active texture) set at initialisation.
|
||||
*
|
||||
* See gl_texture_parameters_init().
|
||||
*/
|
||||
void
|
||||
gl_texture_parameters_flush(struct gl_renderer *gr,
|
||||
struct gl_texture_parameters *parameters)
|
||||
{
|
||||
assert(are_valid_texture_parameters(gr, parameters));
|
||||
|
||||
if (parameters->flags & TEXTURE_FILTERS_DIRTY) {
|
||||
glTexParameteri(parameters->target, GL_TEXTURE_MIN_FILTER,
|
||||
parameters->filters.min);
|
||||
glTexParameteri(parameters->target, GL_TEXTURE_MAG_FILTER,
|
||||
parameters->filters.mag);
|
||||
}
|
||||
|
||||
if (parameters->flags & TEXTURE_WRAP_MODES_DIRTY) {
|
||||
glTexParameteri(parameters->target, GL_TEXTURE_WRAP_S,
|
||||
parameters->wrap_modes.s);
|
||||
glTexParameteri(parameters->target, GL_TEXTURE_WRAP_T,
|
||||
parameters->wrap_modes.t);
|
||||
if (parameters->target == GL_TEXTURE_3D)
|
||||
glTexParameteri(parameters->target, GL_TEXTURE_WRAP_R,
|
||||
parameters->wrap_modes.r);
|
||||
}
|
||||
|
||||
parameters->flags = 0;
|
||||
}
|
||||
|
||||
/* Check whether gl_fbo_init() supports FBO creation for a given
|
||||
* colour-renderable sized internal 'format' or not.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue