5959
6060#include "driver.h"
6161
62+ #define MIN (a ,b ) ((a) < (b) ? (a) : (b))
6263#define MAX (a ,b ) ((a) > (b) ? (a) : (b))
6364
6465static Bool drmmode_xf86crtc_resize (ScrnInfoPtr scrn , int width , int height );
@@ -1889,6 +1890,11 @@ drmmode_paint_cursor(struct dumb_bo *cursor_bo, int cursor_pitch, int cursor_wid
18891890
18901891 CARD32 * cursor = cursor_bo -> ptr ;
18911892
1893+ /*
1894+ * The image buffer can be smaller than the cursor buffer.
1895+ * This means that we can't clear the cursor by copying '\0' bytes
1896+ * from the image buffer, because we might read out of bounds.
1897+ */
18921898 if (drmmode_crtc -> cursor_glyph_width == 0 &&
18931899 drmmode_crtc -> cursor_glyph_height == 0 ) {
18941900 /* If this is the first time we paint the cursor, assume the entire cursor buffer is dirty */
@@ -1911,18 +1917,6 @@ drmmode_paint_cursor(struct dumb_bo *cursor_bo, int cursor_pitch, int cursor_wid
19111917
19121918static void drmmode_hide_cursor (xf86CrtcPtr crtc );
19131919
1914- static inline int
1915- get_maximum_cursor_width (drmmode_cursor_rec cursor )
1916- {
1917- return cursor .dimensions [cursor .num_dimensions - 1 ].width ;
1918- }
1919-
1920- static inline int
1921- get_maximum_cursor_height (drmmode_cursor_rec cursor )
1922- {
1923- return cursor .dimensions [cursor .num_dimensions - 1 ].height ;
1924- }
1925-
19261920/*
19271921 * The load_cursor_argb_check driver hook.
19281922 *
@@ -1934,14 +1928,10 @@ static Bool
19341928drmmode_load_cursor_argb_check (xf86CrtcPtr crtc , CARD32 * image )
19351929{
19361930 drmmode_crtc_private_ptr drmmode_crtc = crtc -> driver_private ;
1931+ modesettingPtr ms = modesettingPTR (crtc -> scrn );
19371932 CursorPtr cursor = xf86CurrentCursor (crtc -> scrn -> pScreen );
19381933 drmmode_cursor_rec drmmode_cursor = drmmode_crtc -> cursor ;
1939- int width , height , i ;
1940- int max_width , max_height ;
1941-
1942- /* We need to know what our limit is for HW cursors. */
1943- max_width = get_maximum_cursor_width (drmmode_cursor );
1944- max_height = get_maximum_cursor_height (drmmode_cursor );
1934+ int i ;
19451935
19461936 /* Find the most compatiable size. */
19471937 for (i = 0 ; i < drmmode_cursor .num_dimensions ; i ++ )
@@ -1952,34 +1942,28 @@ drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image)
19521942 dimensions .height >= cursor -> bits -> height ) {
19531943 break ;
19541944 }
1955-
1956- if (dimensions .width > max_width ||
1957- dimensions .height > max_height ) {
1958-
1959- /* If this ever happens, i should not be 0, but check for good measure */
1960- if (i > 0 ) {
1961- i -- ;
1962- }
1963- break ;
1964- }
19651945 }
19661946
1947+ const int cursor_pitch = drmmode_cursor_get_pitch (drmmode_crtc , i );
1948+
19671949 /* Get the resolution of the cursor. */
1968- width = drmmode_cursor .dimensions [i ].width ;
1969- height = drmmode_cursor .dimensions [i ].height ;
1950+ int cursor_width = drmmode_cursor .dimensions [i ].width ;
1951+ int cursor_height = drmmode_cursor .dimensions [i ].height ;
19701952
1971- const int cursor_pitch = drmmode_cursor_get_pitch (drmmode_crtc , i );
1953+ /* Get the size of the cursor image buffer */
1954+ int image_width = ms -> cursor_image_width ;
1955+ int image_height = ms -> cursor_image_height ;
19721956
19731957 /* cursor should be mapped already */
1974- drmmode_paint_cursor (drmmode_cursor .bo , cursor_pitch , width , height ,
1975- image , max_width , max_height ,
1958+ drmmode_paint_cursor (drmmode_cursor .bo , cursor_pitch , cursor_width , cursor_height ,
1959+ image , image_width , image_height ,
19761960 drmmode_crtc , cursor -> bits -> width , cursor -> bits -> height );
19771961
19781962 /* set cursor width and height here for drmmode_show_cursor */
1979- drmmode_crtc -> cursor_width = width ;
1980- drmmode_crtc -> cursor_height = height ;
1963+ drmmode_crtc -> cursor_width = cursor_width ;
1964+ drmmode_crtc -> cursor_height = cursor_height ;
19811965
1982- return drmmode_crtc -> cursor_up ? drmmode_set_cursor (crtc , width , height ) : TRUE;
1966+ return drmmode_crtc -> cursor_up ? drmmode_set_cursor (crtc , cursor_width , cursor_height ) : TRUE;
19831967}
19841968
19851969static void
@@ -4659,22 +4643,20 @@ drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
46594643{
46604644 modesettingPtr ms = modesettingPTR (pScrn );
46614645 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR (pScrn );
4662- int width ;
4663- int height ;
46644646 int bpp = ms -> drmmode .kbpp ;
4665- int i ;
46664647 int cpp = (bpp + 7 ) / 8 ;
46674648
4649+ int width , height ;
4650+ uint32_t min_width = 1 << 30 , min_height = 1 << 30 ;
4651+
46684652 width = pScrn -> virtualX ;
46694653 height = pScrn -> virtualY ;
46704654
46714655 if (!drmmode_create_bo (drmmode , & drmmode -> front_bo , width , height , bpp ))
46724656 return FALSE;
46734657 pScrn -> displayWidth = drmmode_bo_get_pitch (& drmmode -> front_bo ) / cpp ;
46744658
4675- bpp = 32 ;
4676-
4677- for (i = 0 ; i < xf86_config -> num_crtc ; i ++ ) {
4659+ for (int i = 0 ; i < xf86_config -> num_crtc ; i ++ ) {
46784660 xf86CrtcPtr crtc = xf86_config -> crtc [i ];
46794661 drmmode_crtc_private_ptr drmmode_crtc = crtc -> driver_private ;
46804662 drmmode_cursor_rec cursor = drmmode_crtc -> cursor ;
@@ -4683,13 +4665,22 @@ drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
46834665 * something has gone terribly wrong. */
46844666 assert (cursor .num_dimensions );
46854667
4686- /* Use the maximum available size. */
4687- width = get_maximum_cursor_width (cursor );
4688- height = get_maximum_cursor_height (cursor );
4668+ /* Use the minimum available size. */
4669+ width = cursor .dimensions [0 ].width ;
4670+ height = cursor .dimensions [0 ].height ;
4671+
4672+ /* We take the minimum of the sizes here
4673+ * so that we don't get a cursor glyph larger
4674+ * that a crtc's cursor buffer */
4675+ min_width = MIN (width , min_width );
4676+ min_height = MIN (height , min_height );
46894677
46904678 drmmode_crtc -> cursor .bo = dumb_bo_create (drmmode -> fd , width , height , bpp );
46914679 }
46924680
4681+ ms -> cursor_image_width = min_width ;
4682+ ms -> cursor_image_height = min_height ;
4683+
46934684 return TRUE;
46944685}
46954686
@@ -4824,37 +4815,6 @@ drmmode_crtc_set_vrr(xf86CrtcPtr crtc, Bool enabled)
48244815 drmmode_crtc -> vrr_enabled = enabled ;
48254816}
48264817
4827- Bool drmmode_get_largest_cursor (ScrnInfoPtr pScrn , drmmode_cursor_dim_ptr cursor_lim )
4828- {
4829- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR (pScrn );
4830-
4831- int max_width = 0 , max_height = 0 ;
4832-
4833- if (!cursor_lim )
4834- return FALSE;
4835-
4836- for (int i = 0 ; i < xf86_config -> num_crtc ; i ++ ) {
4837- xf86CrtcPtr crtc = xf86_config -> crtc [i ];
4838- drmmode_crtc_private_ptr drmmode_crtc = crtc -> driver_private ;
4839- drmmode_cursor_rec cursor = drmmode_crtc -> cursor ;
4840-
4841- /* Get the largest cursor available. */
4842- drmmode_cursor_dim_rec largest = cursor .dimensions [cursor .num_dimensions - 1 ];
4843-
4844- int width = largest .width ;
4845- int height = largest .height ;
4846-
4847- /* Future work:
4848- * - We should only let sizes that all CRTCs support. */
4849- max_width = MAX (width , max_width );
4850- max_height = MAX (height , max_height );
4851- }
4852-
4853- cursor_lim -> width = max_width ;
4854- cursor_lim -> height = max_height ;
4855- return TRUE;
4856- }
4857-
48584818/*
48594819 * We hook the screen's cursor-sprite (swcursor) functions to see if a swcursor
48604820 * is active. When a swcursor is active we disable page-flipping.
0 commit comments