xfree86/modes: Adapt xf86Randr12CrtcComputeGamma() for depth 30. (v2)
At screen depths > 24 bit, the color palettes passed into
xf86Randr12CrtcComputeGamma() can have a larger number of slots
than the crtc's hardware lut. E.g., at depth 30, 1024 palette
slots vs. 256 hw lut slots. This palette size > crtc gamma size
case is not handled yet and leads to silent failure, so gamma
table updates do not happen.
Add a new subsampling path for this case.
This makes lut updates work again, as tested with the xgamma
utility (uses XF86VidMode extension) and some RandR based
gamma ramp animation.
v2: Better resampling when subsampling the palette, as
    proposed by Ville. Now reaches the max index of the
    palette and deals with non-power-of-two sizes. Thanks.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: Antoine Martin <antoine@nagafix.co.uk> (v1)
Cc: <ville.syrjala@linux.intel.com>
			
			
This commit is contained in:
		
							parent
							
								
									125201408d
								
							
						
					
					
						commit
						b5f9fcd50a
					
				|  | @ -1258,40 +1258,82 @@ xf86RandR12CrtcComputeGamma(xf86CrtcPtr crtc, LOCO *palette, | |||
| 
 | ||||
|     for (shift = 0; (gamma_size << shift) < (1 << 16); shift++); | ||||
| 
 | ||||
|     gamma_slots = crtc->gamma_size / palette_red_size; | ||||
|     for (i = 0; i < palette_red_size; i++) { | ||||
|         value = palette[i].red; | ||||
|         if (gamma_red) | ||||
|             value = gamma_red[value]; | ||||
|         else | ||||
|             value <<= shift; | ||||
|     if (crtc->gamma_size >= palette_red_size) { | ||||
|         /* Upsampling of smaller palette to larger hw lut size */ | ||||
|         gamma_slots = crtc->gamma_size / palette_red_size; | ||||
|         for (i = 0; i < palette_red_size; i++) { | ||||
|             value = palette[i].red; | ||||
|             if (gamma_red) | ||||
|                 value = gamma_red[value]; | ||||
|             else | ||||
|                 value <<= shift; | ||||
| 
 | ||||
|         for (j = 0; j < gamma_slots; j++) | ||||
|             crtc->gamma_red[i * gamma_slots + j] = value; | ||||
|             for (j = 0; j < gamma_slots; j++) | ||||
|                 crtc->gamma_red[i * gamma_slots + j] = value; | ||||
|         } | ||||
|     } else { | ||||
|         /* Downsampling of larger palette to smaller hw lut size */ | ||||
|         for (i = 0; i < crtc->gamma_size; i++) { | ||||
|             value = palette[i * (palette_red_size - 1) / (crtc->gamma_size - 1)].red; | ||||
|             if (gamma_red) | ||||
|                 value = gamma_red[value]; | ||||
|             else | ||||
|                 value <<= shift; | ||||
| 
 | ||||
|             crtc->gamma_red[i] = value; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     gamma_slots = crtc->gamma_size / palette_green_size; | ||||
|     for (i = 0; i < palette_green_size; i++) { | ||||
|         value = palette[i].green; | ||||
|         if (gamma_green) | ||||
|             value = gamma_green[value]; | ||||
|         else | ||||
|             value <<= shift; | ||||
|     if (crtc->gamma_size >= palette_green_size) { | ||||
|         /* Upsampling of smaller palette to larger hw lut size */ | ||||
|         gamma_slots = crtc->gamma_size / palette_green_size; | ||||
|         for (i = 0; i < palette_green_size; i++) { | ||||
|             value = palette[i].green; | ||||
|             if (gamma_green) | ||||
|                 value = gamma_green[value]; | ||||
|             else | ||||
|                 value <<= shift; | ||||
| 
 | ||||
|         for (j = 0; j < gamma_slots; j++) | ||||
|             crtc->gamma_green[i * gamma_slots + j] = value; | ||||
|             for (j = 0; j < gamma_slots; j++) | ||||
|                 crtc->gamma_green[i * gamma_slots + j] = value; | ||||
|         } | ||||
|     } else { | ||||
|         /* Downsampling of larger palette to smaller hw lut size */ | ||||
|         for (i = 0; i < crtc->gamma_size; i++) { | ||||
|             value = palette[i * (palette_green_size - 1) / (crtc->gamma_size - 1)].green; | ||||
|             if (gamma_green) | ||||
|                 value = gamma_green[value]; | ||||
|             else | ||||
|                 value <<= shift; | ||||
| 
 | ||||
|             crtc->gamma_green[i] = value; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     gamma_slots = crtc->gamma_size / palette_blue_size; | ||||
|     for (i = 0; i < palette_blue_size; i++) { | ||||
|         value = palette[i].blue; | ||||
|         if (gamma_blue) | ||||
|             value = gamma_blue[value]; | ||||
|         else | ||||
|             value <<= shift; | ||||
|     if (crtc->gamma_size >= palette_blue_size) { | ||||
|         /* Upsampling of smaller palette to larger hw lut size */ | ||||
|         gamma_slots = crtc->gamma_size / palette_blue_size; | ||||
|         for (i = 0; i < palette_blue_size; i++) { | ||||
|             value = palette[i].blue; | ||||
|             if (gamma_blue) | ||||
|                 value = gamma_blue[value]; | ||||
|             else | ||||
|                 value <<= shift; | ||||
| 
 | ||||
|         for (j = 0; j < gamma_slots; j++) | ||||
|             crtc->gamma_blue[i * gamma_slots + j] = value; | ||||
|             for (j = 0; j < gamma_slots; j++) | ||||
|                 crtc->gamma_blue[i * gamma_slots + j] = value; | ||||
|         } | ||||
|     } else { | ||||
|         /* Downsampling of larger palette to smaller hw lut size */ | ||||
|         for (i = 0; i < crtc->gamma_size; i++) { | ||||
|             value = palette[i * (palette_blue_size - 1) / (crtc->gamma_size - 1)].blue; | ||||
|             if (gamma_blue) | ||||
|                 value = gamma_blue[value]; | ||||
|             else | ||||
|                 value <<= shift; | ||||
| 
 | ||||
|             crtc->gamma_blue[i] = value; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue