[Glamor] [PATCH] Fix the problem of memory leak in gradient pixmap generating.
junyan.he at linux.intel.com
junyan.he at linux.intel.com
Sun Apr 15 18:26:45 PDT 2012
From: Junyan He <junyan.he at linux.intel.com>
Fix the problem of memory leak in gradient pixmap
generating. The problem caused by we do not call
glDeleteShader when destroy a shader program. This patch
will split the gradient pixmap generating to three
category. If nstops < 6, we will use the no array version
of the shader, which has the best performance. Else if
nstops < 16, we use array version of the shader, which is
compiled and linked at screen init stage. Else if nstops >
16, we dynamically create a new shader program, and this
program will be cached until bigger nstops.
Signed-off-by: Junyan He <junyan.he at linux.intel.com>
---
src/glamor_gl_dispatch.c | 1 +
src/glamor_gl_dispatch.h | 1 +
src/glamor_priv.h | 28 ++++--
src/glamor_render.c | 238 ++++++++++++++++++++++++++++++++++------------
4 files changed, 199 insertions(+), 69 deletions(-)
diff --git a/src/glamor_gl_dispatch.c b/src/glamor_gl_dispatch.c
index fc3c5c0..e6da94d
--- a/src/glamor_gl_dispatch.c
+++ b/src/glamor_gl_dispatch.c
@@ -76,6 +76,7 @@ glamor_gl_dispatch_init_impl(struct glamor_gl_dispatch *dispatch,
INIT_FUNC(dispatch, glCreateShader, get_proc_address);
INIT_FUNC(dispatch, glCompileShader, get_proc_address);
INIT_FUNC(dispatch, glAttachShader, get_proc_address);
+ INIT_FUNC(dispatch, glDeleteShader, get_proc_address);
INIT_FUNC(dispatch, glGetShaderiv, get_proc_address);
INIT_FUNC(dispatch, glGetShaderInfoLog, get_proc_address);
INIT_FUNC(dispatch, glGetProgramiv, get_proc_address);
diff --git a/src/glamor_gl_dispatch.h b/src/glamor_gl_dispatch.h
index 6adbde9..b3fc3a6
--- a/src/glamor_gl_dispatch.h
+++ b/src/glamor_gl_dispatch.h
@@ -108,6 +108,7 @@ typedef struct glamor_gl_dispatch {
GLuint (*glCreateShader) (GLenum type);
void (*glCompileShader) (GLuint shader);
void (*glAttachShader) (GLuint program, GLuint shader);
+ void (*glDeleteShader) (GLuint shader);
void (*glGetShaderiv) (GLuint shader, GLenum pname,
GLint * params);
void (*glGetShaderInfoLog) (GLuint shader, GLsizei bufSize,
diff --git a/src/glamor_priv.h b/src/glamor_priv.h
index 961af47..dce9dd1
--- a/src/glamor_priv.h
+++ b/src/glamor_priv.h
@@ -123,11 +123,18 @@ enum shader_in {
SHADER_IN_COUNT,
};
-enum gradient_shader_type {
- GRADIENT_SHADER_LINEAR,
- GRADIENT_SHADER_RADIAL,
- GRADIENT_SHADER_CONICAL,
- GRADIENT_SHADER_COUNT,
+enum gradient_shader {
+ SHADER_GRADIENT_LINEAR,
+ SHADER_GRADIENT_RADIAL,
+ SHADER_GRADIENT_CONICAL,
+ SHADER_GRADIENT_COUNT,
+};
+
+enum gradient_shader_prog {
+ SHADER_GRADIENT_VS_PROG,
+ SHADER_GRADIENT_FS_MAIN_PROG,
+ SHADER_GRADIENT_FS_GETCOLOR_PROG,
+ SHADER_GRADIENT_PROG_COUNT,
};
struct glamor_screen_private;
@@ -233,8 +240,13 @@ typedef struct glamor_screen_private {
GLint tile_prog;
GLint tile_wh;
- /* glamor gradient */
- GLint gradient_prog[GRADIENT_SHADER_COUNT];
+ /* glamor gradient, 0 for small nstops, 1 for
+ large nstops and 2 for dynamic generate. */
+ GLint gradient_prog[SHADER_GRADIENT_COUNT][3];
+ GLint linear_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3];
+ int linear_max_nstops;
+ GLint radial_gradient_shaders[SHADER_GRADIENT_PROG_COUNT][3];
+ int radial_max_nstops;
/* glamor_putimage */
GLint put_image_xybitmap_prog;
@@ -747,7 +759,7 @@ glamor_poly_line(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
#define GLAMOR_PIXMAP_DYNAMIC_UPLOAD
//#define GLAMOR_DELAYED_FILLING
-//#define GLAMOR_GRADIENT_SHADER
+#define GLAMOR_GRADIENT_SHADER
diff --git a/src/glamor_render.c b/src/glamor_render.c
index 9410adf..0421d42
--- a/src/glamor_render.c
+++ b/src/glamor_render.c
@@ -1425,11 +1425,12 @@ _glamor_create_getcolor_fs_program(ScreenPtr screen, int stops_count, int use_ar
return fs_getcolor_prog;
}
-static GLint
-_glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int use_array)
+static void
+_glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen)
{
glamor_screen_private *glamor_priv;
glamor_gl_dispatch *dispatch;
+ int index;
GLint gradient_prog = 0;
char *gradient_fs = NULL;
@@ -1577,12 +1578,35 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int us
"}\n";
glamor_priv = glamor_get_screen_private(screen);
+
+ if ((glamor_priv->radial_max_nstops >= stops_count) && (dyn_gen)) {
+ /* Very Good, not to generate again. */
+ return;
+ }
+
+ if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]) {
+ dispatch->glDeleteShader(
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]);
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
+
+ dispatch->glDeleteShader(
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2]);
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = 0;
+
+ dispatch->glDeleteShader(
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
+
+ dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2]);
+ glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2] = 0;
+ }
+
dispatch = glamor_get_dispatch(glamor_priv);
gradient_prog = dispatch->glCreateProgram();
vs_prog = glamor_compile_glsl_prog(dispatch,
- GL_VERTEX_SHADER, gradient_vs);
+ GL_VERTEX_SHADER, gradient_vs);
XNFasprintf(&gradient_fs,
gradient_fs_template,
@@ -1593,8 +1617,8 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int us
free(gradient_fs);
- fs_getcolor_prog = _glamor_create_getcolor_fs_program(screen,
- stops_count, use_array);
+ fs_getcolor_prog =
+ _glamor_create_getcolor_fs_program(screen, stops_count, (stops_count > 0));
dispatch->glAttachShader(gradient_prog, vs_prog);
dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
@@ -1607,16 +1631,30 @@ _glamor_create_radial_gradient_program(ScreenPtr screen, int stops_count, int us
dispatch->glUseProgram(0);
+ if (dyn_gen) {
+ index = 2;
+ glamor_priv->radial_max_nstops = stops_count;
+ } else if (stops_count) {
+ index = 1;
+ } else {
+ index = 0;
+ }
+
+ glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][index] = gradient_prog;
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = vs_prog;
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = fs_main_prog;
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = fs_getcolor_prog;
+
glamor_put_dispatch(glamor_priv);
- return gradient_prog;
}
-static GLint
-_glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int use_array)
+static void
+_glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int dyn_gen)
{
glamor_screen_private *glamor_priv;
glamor_gl_dispatch *dispatch;
+ int index = 0;
GLint gradient_prog = 0;
char *gradient_fs = NULL;
GLint fs_main_prog, fs_getcolor_prog, vs_prog;
@@ -1770,7 +1808,31 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
" gl_FragColor = get_color(stop_len);\n"
"}\n";
+
glamor_priv = glamor_get_screen_private(screen);
+
+ if ((glamor_priv->linear_max_nstops >= stops_count) && (dyn_gen)) {
+ /* Very Good, not to generate again. */
+ return;
+ }
+
+ if (dyn_gen && glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]) {
+ dispatch->glDeleteShader(
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2]);
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][2] = 0;
+
+ dispatch->glDeleteShader(
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2]);
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][2] = 0;
+
+ dispatch->glDeleteShader(
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2]);
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][2] = 0;
+
+ dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2]);
+ glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2] = 0;
+ }
+
dispatch = glamor_get_dispatch(glamor_priv);
gradient_prog = dispatch->glCreateProgram();
@@ -1786,8 +1848,8 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
GL_FRAGMENT_SHADER, gradient_fs);
free(gradient_fs);
- fs_getcolor_prog = _glamor_create_getcolor_fs_program(screen,
- stops_count, use_array);
+ fs_getcolor_prog =
+ _glamor_create_getcolor_fs_program(screen, stops_count, (stops_count > 0));
dispatch->glAttachShader(gradient_prog, vs_prog);
dispatch->glAttachShader(gradient_prog, fs_getcolor_prog);
@@ -1800,26 +1862,56 @@ _glamor_create_linear_gradient_program(ScreenPtr screen, int stops_count, int us
dispatch->glUseProgram(0);
+ if (dyn_gen) {
+ index = 2;
+ glamor_priv->linear_max_nstops = stops_count;
+ } else if (stops_count) {
+ index = 1;
+ } else {
+ index = 0;
+ }
+
+ glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][index] = gradient_prog;
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][index] = vs_prog;
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][index] = fs_main_prog;
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][index] = fs_getcolor_prog;
+
glamor_put_dispatch(glamor_priv);
- return gradient_prog;
}
-#define LINEAR_DEFAULT_STOPS 6 + 2
-#define RADIAL_DEFAULT_STOPS 6 + 2
+#define LINEAR_SMALL_STOPS 6 + 2
+#define LINEAR_LARGE_STOPS 16 + 2
+
+#define RADIAL_SMALL_STOPS 6 + 2
+#define RADIAL_LARGE_STOPS 16 + 2
void
glamor_init_gradient_shader(ScreenPtr screen)
{
glamor_screen_private *glamor_priv;
+ int i;
glamor_priv = glamor_get_screen_private(screen);
- glamor_priv->gradient_prog[GRADIENT_SHADER_LINEAR] =
- _glamor_create_linear_gradient_program(screen,
- LINEAR_DEFAULT_STOPS, 0);
- glamor_priv->gradient_prog[GRADIENT_SHADER_RADIAL] =
- _glamor_create_radial_gradient_program(screen,
- RADIAL_DEFAULT_STOPS, 0);
+ for (i = 0; i < 3; i++) {
+ glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i] = 0;
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = 0;
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
+
+ glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i] = 0;
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i] = 0;
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i] = 0;
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i] = 0;
+ }
+ glamor_priv->linear_max_nstops = 0;
+ glamor_priv->radial_max_nstops = 0;
+
+ _glamor_create_linear_gradient_program(screen, 0, 0);
+ _glamor_create_linear_gradient_program(screen, LINEAR_LARGE_STOPS, 0);
+
+ _glamor_create_radial_gradient_program(screen, 0, 0);
+ _glamor_create_radial_gradient_program(screen, RADIAL_LARGE_STOPS, 0);
}
void
@@ -1827,14 +1919,44 @@ glamor_fini_gradient_shader(ScreenPtr screen)
{
glamor_screen_private *glamor_priv;
glamor_gl_dispatch *dispatch;
+ int i = 0;
glamor_priv = glamor_get_screen_private(screen);
dispatch = glamor_get_dispatch(glamor_priv);
- dispatch->glDeleteProgram(
- glamor_priv->gradient_prog[GRADIENT_SHADER_LINEAR]);
- dispatch->glDeleteProgram(
- glamor_priv->gradient_prog[GRADIENT_SHADER_RADIAL]);
+ for (i = 0; i < 3; i++) {
+ /* Linear Gradient */
+ if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
+ dispatch->glDeleteShader(
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]);
+
+ if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
+ dispatch->glDeleteShader(
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]);
+
+ if (glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
+ dispatch->glDeleteShader(
+ glamor_priv->linear_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
+
+ if (glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i])
+ dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][i]);
+
+ /* Radial Gradient */
+ if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i])
+ dispatch->glDeleteShader(
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_VS_PROG][i]);
+
+ if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i])
+ dispatch->glDeleteShader(
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_MAIN_PROG][i]);
+
+ if (glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i])
+ dispatch->glDeleteShader(
+ glamor_priv->radial_gradient_shaders[SHADER_GRADIENT_FS_GETCOLOR_PROG][i]);
+
+ if (glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i])
+ dispatch->glDeleteProgram(glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][i]);
+ }
glamor_put_dispatch(glamor_priv);
}
@@ -2066,8 +2188,8 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, 0.0, 1.0}};
- GLfloat stop_colors_st[RADIAL_DEFAULT_STOPS*4];
- GLfloat n_stops_st[RADIAL_DEFAULT_STOPS];
+ GLfloat stop_colors_st[RADIAL_SMALL_STOPS*4];
+ GLfloat n_stops_st[RADIAL_SMALL_STOPS];
GLfloat A_value;
GLfloat cxy[4];
float c1x, c1y, c2x, c2y, r1, r2;
@@ -2123,15 +2245,17 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
ValidatePicture(dst_picture);
- stops_count = src_picture->pSourcePict->radial.nstops + 2 > RADIAL_DEFAULT_STOPS ?
- src_picture->pSourcePict->radial.nstops + 2 : RADIAL_DEFAULT_STOPS;
+ stops_count = src_picture->pSourcePict->radial.nstops + 2;
- /* Because the max value of nstops is unkown, so create a programwhen nstops > default.*/
- if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_DEFAULT_STOPS) {
- gradient_prog = glamor_priv->gradient_prog[GRADIENT_SHADER_RADIAL];
+ /* Because the max value of nstops is unkown, so create a program
+ when nstops > LINEAR_LARGE_STOPS.*/
+ if (stops_count <= RADIAL_SMALL_STOPS) {
+ gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][0];
+ } else if (stops_count <= RADIAL_LARGE_STOPS) {
+ gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][1];
} else {
- gradient_prog = _glamor_create_radial_gradient_program(screen,
- src_picture->pSourcePict->radial.nstops + 2, 1);
+ _glamor_create_radial_gradient_program(screen, src_picture->pSourcePict->linear.nstops + 2, 1);
+ gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_RADIAL][2];
}
/* Bind all the uniform vars .*/
@@ -2154,7 +2278,7 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
r2_uniform_location =
dispatch->glGetUniformLocation(gradient_prog, "r2");
- if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_DEFAULT_STOPS) {
+ if (src_picture->pSourcePict->radial.nstops + 2 <= RADIAL_SMALL_STOPS) {
stop0_uniform_location =
dispatch->glGetUniformLocation(gradient_prog, "stop0");
stop1_uniform_location =
@@ -2217,7 +2341,7 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
goto GRADIENT_FAIL;
/* Set all the stops and colors to shader. */
- if (stops_count > RADIAL_DEFAULT_STOPS) {
+ if (stops_count > RADIAL_SMALL_STOPS) {
stop_colors = malloc(4 * stops_count * sizeof(float));
if (stop_colors == NULL) {
ErrorF("Failed to allocate stop_colors memory.\n");
@@ -2237,7 +2361,7 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient,
stop_colors, n_stops);
- if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_DEFAULT_STOPS) {
+ if (src_picture->pSourcePict->linear.nstops + 2 <= RADIAL_SMALL_STOPS) {
int j = 0;
dispatch->glUniform4f(stop_color0_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
stop_colors[4*j+2], stop_colors[4*j+3]);
@@ -2322,7 +2446,7 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
/* Do the clear logic.*/
- if (stops_count > RADIAL_DEFAULT_STOPS) {
+ if (stops_count > RADIAL_SMALL_STOPS) {
free(n_stops);
free(stop_colors);
}
@@ -2334,9 +2458,6 @@ _glamor_generate_radial_gradient_picture(ScreenPtr screen,
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
dispatch->glUseProgram(0);
- if (src_picture->pSourcePict->radial.nstops + 2 > RADIAL_DEFAULT_STOPS)
- dispatch->glDeleteProgram(gradient_prog);
-
glamor_put_dispatch(glamor_priv);
return dst_picture;
@@ -2345,7 +2466,7 @@ GRADIENT_FAIL:
FreePicture(dst_picture, 0);
}
- if (stops_count > RADIAL_DEFAULT_STOPS) {
+ if (stops_count > RADIAL_SMALL_STOPS) {
if (n_stops)
free(n_stops);
if (stop_colors)
@@ -2358,8 +2479,6 @@ GRADIENT_FAIL:
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
dispatch->glUseProgram(0);
- if (src_picture->pSourcePict->radial.nstops + 2 > RADIAL_DEFAULT_STOPS)
- dispatch->glDeleteProgram(gradient_prog);
glamor_put_dispatch(glamor_priv);
return NULL;
}
@@ -2394,8 +2513,8 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
static const float identity_mat[3][3] = {{1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, 0.0, 1.0}};
- GLfloat stop_colors_st[LINEAR_DEFAULT_STOPS*4];
- GLfloat n_stops_st[LINEAR_DEFAULT_STOPS];
+ GLfloat stop_colors_st[LINEAR_SMALL_STOPS*4];
+ GLfloat n_stops_st[LINEAR_SMALL_STOPS];
GLint transform_mat_uniform_location;
GLint pt1_uniform_location;
@@ -2451,16 +2570,18 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
ValidatePicture(dst_picture);
- stops_count = src_picture->pSourcePict->linear.nstops + 2 > LINEAR_DEFAULT_STOPS ?
- src_picture->pSourcePict->linear.nstops + 2 : LINEAR_DEFAULT_STOPS;
+ stops_count = src_picture->pSourcePict->linear.nstops + 2;
/* Because the max value of nstops is unkown, so create a program
- when nstops > default.*/
- if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_DEFAULT_STOPS) {
- gradient_prog = glamor_priv->gradient_prog[GRADIENT_SHADER_LINEAR];
+ when nstops > LINEAR_LARGE_STOPS.*/
+ if (stops_count <= LINEAR_SMALL_STOPS) {
+ gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][0];
+ } else if (stops_count <= LINEAR_LARGE_STOPS) {
+ gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][1];
} else {
- gradient_prog = _glamor_create_linear_gradient_program(screen,
- src_picture->pSourcePict->linear.nstops + 2, 1);
+ _glamor_create_linear_gradient_program(screen,
+ src_picture->pSourcePict->linear.nstops + 2, 1);
+ gradient_prog = glamor_priv->gradient_prog[SHADER_GRADIENT_LINEAR][2];
}
/* Bind all the uniform vars .*/
@@ -2485,7 +2606,7 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
pt_distance_uniform_location =
dispatch->glGetUniformLocation(gradient_prog, "pt_distance");
- if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_DEFAULT_STOPS) {
+ if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
stop0_uniform_location =
dispatch->glGetUniformLocation(gradient_prog, "stop0");
stop1_uniform_location =
@@ -2568,7 +2689,7 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
DEBUGF("pt2:(%f %f)\n", pt2[0], pt2[1]);
/* Set all the stops and colors to shader. */
- if (stops_count > LINEAR_DEFAULT_STOPS) {
+ if (stops_count > LINEAR_SMALL_STOPS) {
stop_colors = malloc(4 * stops_count * sizeof(float));
if (stop_colors == NULL) {
ErrorF("Failed to allocate stop_colors memory.\n");
@@ -2588,7 +2709,7 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
count = _glamor_gradient_set_stops(src_picture, &src_picture->pSourcePict->gradient,
stop_colors, n_stops);
- if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_DEFAULT_STOPS) {
+ if (src_picture->pSourcePict->linear.nstops + 2 <= LINEAR_SMALL_STOPS) {
int j = 0;
dispatch->glUniform4f(stop_color0_uniform_location, stop_colors[4*j+0], stop_colors[4*j+1],
stop_colors[4*j+2], stop_colors[4*j+3]);
@@ -2683,7 +2804,7 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
}
/* Do the clear logic.*/
- if (stops_count > LINEAR_DEFAULT_STOPS) {
+ if (stops_count > LINEAR_SMALL_STOPS) {
free(n_stops);
free(stop_colors);
}
@@ -2695,9 +2816,6 @@ _glamor_generate_linear_gradient_picture(ScreenPtr screen,
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
dispatch->glUseProgram(0);
- if (src_picture->pSourcePict->linear.nstops + 2 > LINEAR_DEFAULT_STOPS)
- dispatch->glDeleteProgram(gradient_prog);
-
glamor_put_dispatch(glamor_priv);
return dst_picture;
@@ -2706,7 +2824,7 @@ GRADIENT_FAIL:
FreePicture(dst_picture, 0);
}
- if (stops_count > LINEAR_DEFAULT_STOPS) {
+ if (stops_count > LINEAR_SMALL_STOPS) {
if (n_stops)
free(n_stops);
if (stop_colors)
@@ -2719,8 +2837,6 @@ GRADIENT_FAIL:
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_POS);
dispatch->glDisableVertexAttribArray(GLAMOR_VERTEX_SOURCE);
dispatch->glUseProgram(0);
- if (src_picture->pSourcePict->linear.nstops + 2 > LINEAR_DEFAULT_STOPS)
- dispatch->glDeleteProgram(gradient_prog);
glamor_put_dispatch(glamor_priv);
return NULL;
}
--
1.7.7.6
More information about the Glamor
mailing list