[Glamor] [PATCH 2/2] Add the feature of generating linear gradient picture using shader

He Junyan junyan.he at linux.intel.com
Wed Mar 7 22:26:37 PST 2012


Hi Chris:


> On Wed,  7 Mar 2012 02:44:08 +0800, junyan.he at linux.intel.com wrote:
>>   Add the feature of generating linear gradient picture by
>>   using shader. This logic will replace the original
>>   gradient picture generating manner in glamor which
>>   firstly use pixman and then upload to GPU. Compare it
>>   to the result generated by pixman, the difference of
>>   each color of each pixel is normally 0, sometimes
>>   1/255, and 2/255 at most. The pixman use fix int but
>>   shader use float, so may have difference. There is just
>>   one case that we will fallback. When the picture has
>>   transform matrix and the matrix is a projective
>>   matrix(which has non 0 at the third column and row.),
>>   the shader's coordinate has been normalized and so it
>>   is hard to work as what the pixman do. Some logic of
>>   pixmap compare has been added to for easing the debug
>>   of the pixmap generated by shader.
>
> One thing to mention here is the benefit of using a linear shader rather
> pixman, some evidence to justify the work. Do you have any performance
> figures that you can share?

OK, I will use cairo-perf-trace to test the case of 
firefox-planet-gnome.trace
and give you a feedback later.

>
>> @@ -1290,21 +1827,34 @@ glamor_convert_gradient_picture(ScreenPtr screen,
>>   	else
>>   		format = source->format;
>>
>> +	if (source->pSourcePict->type == SourcePictTypeLinear) {
>> +		dst = _glamor_generate_linear_gradient_picture(screen,
>> +		        source, x_source, y_source, width, height, format);
>> +
>
> source->pSourcePict may be NULL as glamor_convert_gradient_picture() may
> also be called for an unattached picture->pDrawable. (wtf!)
>

Really a potential problem. this case has been ignored, Very thanks to 
notify me.

>> +		for (r = 0; r<  3; r++) {
>> +			for (c = 0; c<  3; c++) {
>> +				if ((r>= 2 || c>= 2)&&  r != c) {
>> +					if (transform_mat[r][c]) {
>> +						ErrorF("Project matrix change for"
>> +						       "linear gradient, FallBack\n");
>> +						goto GRADIENT_FAIL;
>> +					}
>> +				}
>
> This test is wrong, it misclassifies a translation matrix as a
> projection matrix.
>
Yeah, it should be Projective Matrix(different to a affine matrix).
The logic in pixman to handle this is some difficult to duplicate in shader.
I just fallback it now, and will improve it.

>> +	switch (src_picture->repeatType) {
>> +#define REPEAT_FILL_STOPS(m, n) \
>> +		stop_colors[(m)*4 + 0] = stop_colors[(n)*4 + 0]; \
>> +		stop_colors[(m)*4 + 1] = stop_colors[(n)*4 + 1]; \
>> +		stop_colors[(m)*4 + 2] = stop_colors[(n)*4 + 2]; \
>> +		stop_colors[(m)*4 + 3] = stop_colors[(n)*4 + 3];
>> +
>> +		default:
>> +		case PIXMAN_REPEAT_NONE:
>> +			stop_colors[0] = 0.0;      //R
>> +			stop_colors[1] = 0.0;      //G
>> +			stop_colors[2] = 0.0;      //B
>> +			stop_colors[3] = 0.0;      //Alpha
>> +			n_stops[0] = -(float)INT_MAX;  //should be small enough.
>> +
>> +			stop_colors[0 + (count-1)*4] = 0.0;      //R
>> +			stop_colors[1 + (count-1)*4] = 0.0;      //G
>> +			stop_colors[2 + (count-1)*4] = 0.0;      //B
>> +			stop_colors[3 + (count-1)*4] = 0.0;      //Alpha
>> +			n_stops[count-1] = (float)INT_MAX;  //should be large enough.
> This falls foul of the "pixman overflow emulation" in the shader. And
> it needs to handle a subrange where the linear gradient is only defined
> between, for example, [0.4, 0.6]. The expected behaviour is that the end
> stops are then extrapolated out to 0.0 and 1.0 before the repeat mode is
> then applied. The other repeat modes also appear not to handle subranges
> either.
> -Chris
>
Here I have some confused.
I tested several cases, such as stops at 0.1(red), 0.5(green), 0.7(blue).
I compare the result with pixman's result in all four repeat modes, and do
not find difference bigger than 2/255 per color per pixel.
subrange like [0.4(red), 0,6(blue)] do not expand to [0.0(red), 
1.0(blue)] in pixman.
if you use RepeatNone to draw the gradient, the pixel < 0.4 is always 
not drawn and pixel
> 0.6 always use 0.6 stop's color.
Of course, the pixman is not the standard, do you means we should not 
follow it?















More information about the Glamor mailing list