Skip to content
Commits on Source (6)
......@@ -26,6 +26,19 @@
* SOFTWARE.
*/
/*
* GL renderer best practices:
*
* 1. Texture units
* 1. Fixed allocation using the gl_tex_unit enumeration.
* 2. Any functions changing the active unit must restore it to 0 before
* return so that other functions can assume a default value.
*
* 1. Pixel storage modes
* 1. Any functions changing modes must restore them to their default values
* before return so that other functions can assume default values.
*/
#ifndef GL_RENDERER_INTERNAL_H
#define GL_RENDERER_INTERNAL_H
......@@ -38,6 +51,9 @@
#include "shared/weston-egl-ext.h" /* for PFN* stuff */
#include "shared/helpers.h"
/* Max number of images per buffer. */
#define SHADER_INPUT_TEX_MAX 3
/* Keep the following in sync with vertex.glsl. */
enum gl_shader_texcoord_input {
SHADER_TEXCOORD_INPUT_ATTRIB = 0,
......@@ -78,6 +94,19 @@ enum gl_shader_attrib_loc {
SHADER_ATTRIB_LOC_BARYCENTRIC,
};
enum gl_tex_unit {
TEX_UNIT_IMAGES = 0,
TEX_UNIT_COLOR_PRE_CURVE = SHADER_INPUT_TEX_MAX,
TEX_UNIT_COLOR_MAPPING,
TEX_UNIT_COLOR_POST_CURVE,
TEX_UNIT_WIREFRAME,
TEX_UNIT_LAST,
};
static_assert(TEX_UNIT_LAST < 8, "OpenGL ES 2.0 requires at least 8 texture "
"units. Consider replacing this assert with a "
"GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS check at display creation "
"to require more.");
/** GL shader requirements key
*
* This structure is used as a binary blob key for building and searching
......@@ -115,9 +144,6 @@ struct gl_shader;
struct weston_color_transform;
struct dmabuf_allocator;
#define GL_SHADER_INPUT_TEX_MAX 3
#define GL_SHADER_WIREFRAME_TEX_UNIT GL_SHADER_INPUT_TEX_MAX
struct gl_shader_config {
struct gl_shader_requirements req;
......@@ -127,7 +153,7 @@ struct gl_shader_config {
GLfloat unicolor[4];
GLfloat tint[4];
GLint input_tex_filter; /* GL_NEAREST or GL_LINEAR */
GLuint input_tex[GL_SHADER_INPUT_TEX_MAX];
GLuint input_tex[SHADER_INPUT_TEX_MAX];
GLuint wireframe_tex;
union {
......
......@@ -574,7 +574,6 @@ gl_fbo_texture_init(struct gl_fbo_texture *fbotex,
GLuint shadow_fbo;
GLuint shadow_tex;
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &shadow_tex);
glBindTexture(GL_TEXTURE_2D, shadow_tex);
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0,
......@@ -1198,10 +1197,10 @@ gl_shader_config_set_input_textures(struct gl_shader_config *sconf,
copy_uniform4f(sconf->unicolor, gb->color);
assert(gb->num_textures <= GL_SHADER_INPUT_TEX_MAX);
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 < GL_SHADER_INPUT_TEX_MAX; i++)
for (; i < SHADER_INPUT_TEX_MAX; i++)
sconf->input_tex[i] = 0;
}
......@@ -1812,6 +1811,7 @@ update_wireframe_tex(struct gl_renderer *gr,
if (new_size <= gr->wireframe_size)
return;
glActiveTexture(GL_TEXTURE0 + TEX_UNIT_WIREFRAME);
if (gr->wireframe_size == 0) {
glGenTextures(1, &gr->wireframe_tex);
glBindTexture(GL_TEXTURE_2D, gr->wireframe_tex);
......@@ -1833,6 +1833,8 @@ update_wireframe_tex(struct gl_renderer *gr,
glTexImage2D(GL_TEXTURE_2D, i, GL_LUMINANCE, new_size, 1, 0,
GL_LUMINANCE, GL_UNSIGNED_BYTE, buffer);
free(buffer);
glActiveTexture(GL_TEXTURE0);
}
static void
......@@ -1985,7 +1987,6 @@ draw_output_borders(struct weston_output *output,
weston_matrix_scale(&sconf.projection,
2.0 / fb->width, go->y_flip * 2.0 / fb->height, 1);
glActiveTexture(GL_TEXTURE0);
glEnableVertexAttribArray(SHADER_ATTRIB_LOC_POSITION);
glEnableVertexAttribArray(SHADER_ATTRIB_LOC_TEXCOORD);
......@@ -2546,8 +2547,6 @@ gl_renderer_flush_damage(struct weston_paint_node *pnode)
data = wl_shm_buffer_get_data(buffer->shm_buffer);
glActiveTexture(GL_TEXTURE0);
if (gb->needs_full_upload || quirks->gl_force_full_upload) {
wl_shm_buffer_begin_access(buffer->shm_buffer);
......@@ -2649,8 +2648,6 @@ ensure_textures(struct gl_buffer_state *gb, GLenum target, int num_textures)
assert(gb->num_textures == 0);
glActiveTexture(GL_TEXTURE0);
for (i = 0; i < num_textures; i++) {
glGenTextures(1, &gb->textures[i]);
glBindTexture(target, gb->textures[i]);
......@@ -2933,28 +2930,6 @@ err_free:
return false;
}
static void
gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer)
{
struct weston_compositor *ec = es->compositor;
struct gl_renderer *gr = get_renderer(ec);
struct gl_surface_state *gs = get_surface_state(es);
struct gl_buffer_state *gb = buffer->renderer_private;
GLenum target;
int i;
assert(gb);
gs->buffer = gb;
target = gl_shader_texture_variant_get_target(gb->shader_variant);
for (i = 0; i < gb->num_images; i++) {
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(target, gb->textures[i]);
gr->image_target_texture_2d(target, gb->images[i]);
}
}
static void
gl_renderer_destroy_dmabuf(struct linux_dmabuf_buffer *dmabuf)
{
......@@ -3458,9 +3433,8 @@ attach_direct_display_placeholder(struct weston_paint_node *pnode)
gb->shader_variant = SHADER_VARIANT_SOLID;
}
static bool
gl_renderer_attach_dmabuf(struct weston_surface *surface,
static void
gl_renderer_attach_buffer(struct weston_surface *surface,
struct weston_buffer *buffer)
{
struct gl_renderer *gr = get_renderer(surface->compositor);
......@@ -3480,8 +3454,7 @@ gl_renderer_attach_dmabuf(struct weston_surface *surface,
glBindTexture(target, gb->textures[i]);
gr->image_target_texture_2d(target, gb->images[i]);
}
return true;
glActiveTexture(GL_TEXTURE0);
}
static const struct weston_drm_format_array *
......@@ -3607,10 +3580,8 @@ gl_renderer_attach(struct weston_paint_node *pnode)
gl_renderer_attach_shm(es, buffer);
break;
case WESTON_BUFFER_DMABUF:
gl_renderer_attach_dmabuf(es, buffer);
break;
case WESTON_BUFFER_RENDERER_OPAQUE:
gl_renderer_attach_egl(es, buffer);
gl_renderer_attach_buffer(es, buffer);
break;
case WESTON_BUFFER_SOLID:
gl_renderer_attach_solid(es, buffer);
......@@ -3736,7 +3707,6 @@ gl_renderer_surface_copy_content(struct weston_surface *surface,
gl_shader_config_set_input_textures(&sconf, gs);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cw, ch,
......
......@@ -201,7 +201,6 @@ gl_color_curve_lut_3x1d(struct gl_renderer *gr,
curve->u.lut_3x1d.fill_in(xform, lut, lut_len);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
......@@ -238,7 +237,6 @@ gl_3d_lut(struct gl_renderer *gr,
xform->mapping.u.lut3d.fill_in(xform, lut, dim_size);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &tex3d);
glBindTexture(GL_TEXTURE_3D, tex3d);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
......
......@@ -681,13 +681,13 @@ 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 < GL_SHADER_INPUT_TEX_MAX; i++) {
for (i = 0; i < SHADER_INPUT_TEX_MAX; i++) {
if (sconf->input_tex[i] == 0)
continue;
assert(shader->tex_uniforms[i] != -1);
glUniform1i(shader->tex_uniforms[i], i);
glActiveTexture(GL_TEXTURE0 + i);
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);
......@@ -695,7 +695,6 @@ gl_shader_load_config(struct gl_shader *shader,
}
/* Fixed texture unit for color_pre_curve LUT if it is available */
i = GL_SHADER_INPUT_TEX_MAX;
switch (sconf->req.color_pre_curve) {
case SHADER_COLOR_CURVE_IDENTITY:
break;
......@@ -703,10 +702,10 @@ gl_shader_load_config(struct gl_shader *shader,
assert(sconf->color_pre_curve.lut_3x1d.tex != 0);
assert(shader->color_pre_curve.lut_3x1d.tex_2d_uniform != -1);
assert(shader->color_pre_curve.lut_3x1d.scale_offset_uniform != -1);
glActiveTexture(GL_TEXTURE0 + i);
glActiveTexture(GL_TEXTURE0 + TEX_UNIT_COLOR_PRE_CURVE);
glBindTexture(GL_TEXTURE_2D, sconf->color_pre_curve.lut_3x1d.tex);
glUniform1i(shader->color_pre_curve.lut_3x1d.tex_2d_uniform, i);
i++;
glUniform1i(shader->color_pre_curve.lut_3x1d.tex_2d_uniform,
TEX_UNIT_COLOR_PRE_CURVE);
glUniform2fv(shader->color_pre_curve.lut_3x1d.scale_offset_uniform,
1, sconf->color_pre_curve.lut_3x1d.scale_offset);
break;
......@@ -727,10 +726,10 @@ gl_shader_load_config(struct gl_shader *shader,
assert(shader->color_mapping.lut3d.tex_uniform != -1);
assert(sconf->color_mapping.lut3d.tex != 0);
assert(shader->color_mapping.lut3d.scale_offset_uniform != -1);
glActiveTexture(GL_TEXTURE0 + i);
glActiveTexture(GL_TEXTURE0 + TEX_UNIT_COLOR_MAPPING);
glBindTexture(GL_TEXTURE_3D, sconf->color_mapping.lut3d.tex);
glUniform1i(shader->color_mapping.lut3d.tex_uniform, i);
i++;
glUniform1i(shader->color_mapping.lut3d.tex_uniform,
TEX_UNIT_COLOR_MAPPING);
glUniform2fv(shader->color_mapping.lut3d.scale_offset_uniform,
1, sconf->color_mapping.lut3d.scale_offset);
break;
......@@ -749,10 +748,10 @@ gl_shader_load_config(struct gl_shader *shader,
assert(sconf->color_post_curve.lut_3x1d.tex != 0);
assert(shader->color_post_curve.lut_3x1d.tex_2d_uniform != -1);
assert(shader->color_post_curve.lut_3x1d.scale_offset_uniform != -1);
glActiveTexture(GL_TEXTURE0 + i);
glActiveTexture(GL_TEXTURE0 + TEX_UNIT_COLOR_POST_CURVE);
glBindTexture(GL_TEXTURE_2D, sconf->color_post_curve.lut_3x1d.tex);
glUniform1i(shader->color_post_curve.lut_3x1d.tex_2d_uniform, i);
i++;
glUniform1i(shader->color_post_curve.lut_3x1d.tex_2d_uniform,
TEX_UNIT_COLOR_POST_CURVE);
glUniform2fv(shader->color_post_curve.lut_3x1d.scale_offset_uniform,
1, sconf->color_post_curve.lut_3x1d.scale_offset);
break;
......@@ -766,12 +765,10 @@ gl_shader_load_config(struct gl_shader *shader,
break;
}
if (sconf->req.wireframe) {
assert(sconf->wireframe_tex != 0);
glUniform1i(shader->tex_uniform_wireframe, GL_SHADER_WIREFRAME_TEX_UNIT);
glActiveTexture(GL_TEXTURE0 + GL_SHADER_WIREFRAME_TEX_UNIT);
glBindTexture(GL_TEXTURE_2D, sconf->wireframe_tex);
}
if (sconf->req.wireframe)
glUniform1i(shader->tex_uniform_wireframe, TEX_UNIT_WIREFRAME);
glActiveTexture(GL_TEXTURE0);
}
bool
......