Fix the problem of memory leak in gradient pixmap generating.
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: Zhigang Gong <zhigang.gong@linux.intel.com>
This commit is contained in:
parent
05da99106b
commit
3d96929596
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
@ -228,8 +235,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;
|
||||
|
@ -729,7 +741,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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1412,11 +1412,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;
|
||||
|
@ -1564,12 +1565,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,
|
||||
|
@ -1580,8 +1604,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);
|
||||
|
@ -1594,16 +1618,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;
|
||||
|
@ -1757,7 +1795,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();
|
||||
|
@ -1773,8 +1835,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);
|
||||
|
@ -1787,26 +1849,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
|
||||
|
@ -1814,14 +1906,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);
|
||||
}
|
||||
|
@ -2053,8 +2175,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;
|
||||
|
@ -2110,15 +2232,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 .*/
|
||||
|
@ -2141,7 +2265,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 =
|
||||
|
@ -2204,7 +2328,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");
|
||||
|
@ -2224,7 +2348,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]);
|
||||
|
@ -2309,7 +2433,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);
|
||||
}
|
||||
|
@ -2321,9 +2445,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;
|
||||
|
||||
|
@ -2332,7 +2453,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)
|
||||
|
@ -2345,8 +2466,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;
|
||||
}
|
||||
|
@ -2381,8 +2500,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;
|
||||
|
@ -2438,16 +2557,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 .*/
|
||||
|
@ -2472,7 +2593,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 =
|
||||
|
@ -2555,7 +2676,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");
|
||||
|
@ -2575,7 +2696,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]);
|
||||
|
@ -2670,7 +2791,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);
|
||||
}
|
||||
|
@ -2682,9 +2803,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;
|
||||
|
||||
|
@ -2693,7 +2811,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)
|
||||
|
@ -2706,8 +2824,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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user