SDL  2.0
SDL_kmsdrmmouse.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
4  Atomic KMSDRM backend by Manuel Alfayate Corchete <redwindwanderer@gmail.com>
5 
6  This software is provided 'as-is', without any express or implied
7  warranty. In no event will the authors be held liable for any damages
8  arising from the use of this software.
9 
10  Permission is granted to anyone to use this software for any purpose,
11  including commercial applications, and to alter it and redistribute it
12  freely, subject to the following restrictions:
13 
14  1. The origin of this software must not be misrepresented; you must not
15  claim that you wrote the original software. If you use this software
16  in a product, an acknowledgment in the product documentation would be
17  appreciated but is not required.
18  2. Altered source versions must be plainly marked as such, and must not be
19  misrepresented as being the original software.
20  3. This notice may not be removed or altered from any source distribution.
21 */
22 
23 #include "../../SDL_internal.h"
24 
25 #if SDL_VIDEO_DRIVER_KMSDRM
26 
27 #include "SDL_kmsdrmvideo.h"
28 #include "SDL_kmsdrmmouse.h"
29 #include "SDL_kmsdrmdyn.h"
30 #include "SDL_assert.h"
31 
32 #include "../../events/SDL_mouse_c.h"
33 #include "../../events/default_cursor.h"
34 
35 static SDL_Cursor *KMSDRM_CreateDefaultCursor(void);
36 static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y);
37 static int KMSDRM_ShowCursor(SDL_Cursor * cursor);
38 static void KMSDRM_MoveCursor(SDL_Cursor * cursor);
39 static void KMSDRM_FreeCursor(SDL_Cursor * cursor);
40 static void KMSDRM_WarpMouse(SDL_Window * window, int x, int y);
41 static int KMSDRM_WarpMouseGlobal(int x, int y);
42 
43 /**********************************/
44 /* Atomic helper functions block. */
45 /**********************************/
46 
47 int
48 drm_atomic_movecursor(KMSDRM_CursorData *curdata, uint16_t x, uint16_t y)
49 {
51 
52  if (!dispdata->cursor_plane) /* We can't move a non-existing cursor, but that's ok. */
53  return 0;
54 
55  /* Do we have a set of changes already in the making? If not, allocate a new one. */
56  if (!dispdata->atomic_req)
57  dispdata->atomic_req = KMSDRM_drmModeAtomicAlloc();
58 
60  dispdata->cursor_plane, "CRTC_X", x - curdata->hot_x);
62  dispdata->cursor_plane, "CRTC_Y", y - curdata->hot_y);
63 
64  return 0;
65 }
66 
67 /***************************************/
68 /* Atomic helper functions block ends. */
69 /***************************************/
70 
71 /* Converts a pixel from straight-alpha [AA, RR, GG, BB], which the SDL cursor surface has,
72  to premultiplied-alpha [AA. AA*RR, AA*GG, AA*BB].
73  These multiplications have to be done with floats instead of uint32_t's,
74  and the resulting values have to be converted to be relative to the 0-255 interval,
75  where 255 is 1.00 and anything between 0 and 255 is 0.xx. */
76 void alpha_premultiply_ARGB8888 (uint32_t *pixel) {
77 
78  uint32_t A, R, G, B;
79 
80  /* Component bytes extraction. */
81  A = (*pixel >> (3 << 3)) & 0xFF;
82  R = (*pixel >> (2 << 3)) & 0xFF;
83  G = (*pixel >> (1 << 3)) & 0xFF;
84  B = (*pixel >> (0 << 3)) & 0xFF;
85 
86  /* Alpha pre-multiplication of each component. */
87  R = (float)A * ((float)R /255);
88  G = (float)A * ((float)G /255);
89  B = (float)A * ((float)B /255);
90 
91  /* ARGB8888 pixel recomposition. */
92  (*pixel) = (((uint32_t)A << 24) | ((uint32_t)R << 16) | ((uint32_t)G << 8)) | ((uint32_t)B << 0);
93 }
94 
95 static SDL_Cursor *
96 KMSDRM_CreateDefaultCursor(void)
97 {
99 }
100 
101 /* This simply gets the cursor soft-buffer ready. We don't copy it to a GBO BO until ShowCursor()
102  because the cusor GBM BO (living in dispata) is destroyed and recreated when we recreate windows, etc. */
103 static SDL_Cursor *
104 KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
105 {
106  KMSDRM_CursorData *curdata;
107  SDL_Cursor *cursor, *ret;
108 
109  curdata = NULL;
110  ret = NULL;
111 
112  /* All code below assumes ARGB8888 format for the cursor surface,
113  like other backends do. Also, the GBM BO pixels have to be
114  alpha-premultiplied, but the SDL surface we receive has
115  straight-alpha pixels, so we always have to convert. */
116  SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
117  SDL_assert(surface->pitch == surface->w * 4);
118 
119  cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
120  if (!cursor) {
121  SDL_OutOfMemory();
122  goto cleanup;
123  }
124  curdata = (KMSDRM_CursorData *) SDL_calloc(1, sizeof(*curdata));
125  if (!curdata) {
126  SDL_OutOfMemory();
127  goto cleanup;
128  }
129 
130  /* hox_x and hot_y are the coordinates of the "tip of the cursor" from it's base. */
131  curdata->hot_x = hot_x;
132  curdata->hot_y = hot_y;
133  curdata->w = surface->w;
134  curdata->h = surface->h;
135  curdata->buffer = NULL;
136 
137  /* Configure the cursor buffer info.
138  This buffer has the original size of the cursor surface we are given. */
139  curdata->buffer_pitch = surface->pitch;
140  curdata->buffer_size = surface->pitch * surface->h;
141  curdata->buffer = (uint32_t*)SDL_malloc(curdata->buffer_size);
142 
143  if (!curdata->buffer) {
144  SDL_OutOfMemory();
145  goto cleanup;
146  }
147 
148  if (SDL_MUSTLOCK(surface)) {
149  if (SDL_LockSurface(surface) < 0) {
150  /* Could not lock surface */
151  goto cleanup;
152  }
153  }
154 
155  /* Copy the surface pixels to the cursor buffer, for future use in ShowCursor() */
156  SDL_memcpy(curdata->buffer, surface->pixels, curdata->buffer_size);
157 
158  if (SDL_MUSTLOCK(surface)) {
160  }
161 
162  cursor->driverdata = curdata;
163 
164  ret = cursor;
165 
166 cleanup:
167  if (ret == NULL) {
168  if (curdata) {
169  if (curdata->buffer) {
170  SDL_free(curdata->buffer);
171  }
172  SDL_free(curdata);
173  }
174  if (cursor) {
175  SDL_free(cursor);
176  }
177  }
178 
179  return ret;
180 }
181 
182 /* When we create a window, we have to test if we have to show the cursor,
183  and explicily do so if necessary.
184  This is because when we destroy a window, we take the cursor away from the
185  cursor plane, and destroy the cusror GBM BO. So we have to re-show it,
186  so to say. */
187 void
189 {
190  SDL_Mouse *mouse = NULL;
191  mouse = SDL_GetMouse();
192 
193  if (!mouse) {
194  return;
195  }
196  if (!(mouse->cur_cursor)) {
197  return;
198  }
199 
200  if (!(mouse->cursor_shown)) {
201  return;
202  }
203 
204  KMSDRM_ShowCursor(mouse->cur_cursor);
205 }
206 
207 /* Show the specified cursor, or hide if cursor is NULL.
208  cur_cursor is the current cursor, and cursor is the new cursor.
209  A cursor is displayed on a display, so we have to add a pointer to dispdata
210  to the driverdata
211  */
212 static int
213 KMSDRM_ShowCursor(SDL_Cursor * cursor)
214 {
215  SDL_VideoDevice *video_device = SDL_GetVideoDevice();
216  //SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata);
217  SDL_Mouse *mouse;
218  KMSDRM_CursorData *curdata;
219  SDL_VideoDisplay *display = NULL;
220  SDL_DisplayData *dispdata = NULL;
221  KMSDRM_FBInfo *fb;
222  KMSDRM_PlaneInfo info = {0};
223 
224  size_t bo_stride;
225  size_t bufsize;
226  uint32_t *ready_buffer = NULL;
227  uint32_t pixel;
228 
229  int i,j;
230  int ret;
231 
232  mouse = SDL_GetMouse();
233  if (!mouse) {
234  return SDL_SetError("No mouse.");
235  }
236 
237  if (mouse->focus) {
238  display = SDL_GetDisplayForWindow(mouse->focus);
239  if (display) {
240  dispdata = (SDL_DisplayData*) display->driverdata;
241  }
242  }
243 
244  /**********************************/
245  /* if cursor == NULL, HIDE cursor */
246  /**********************************/
247  if (!cursor) {
248  /* Hide CURRENT cursor, a cursor that is already on screen
249  and SDL is stored in mouse->cur_cursor. */
250  if (mouse->cur_cursor && mouse->cur_cursor->driverdata) {
251  if (dispdata && dispdata->cursor_plane) {
252  info.plane = dispdata->cursor_plane;
253  /* The rest of the members are zeroed. */
255  if (drm_atomic_commit(display->device, SDL_TRUE))
256  return SDL_SetError("Failed atomic commit in KMSDRM_ShowCursor.");
257  }
258  return 0;
259  }
260  return SDL_SetError("Couldn't find cursor to hide.");
261  }
262 
263  /************************************************/
264  /* If cursor != NULL, DO show cursor on display */
265  /************************************************/
266  if (!display) {
267  return SDL_SetError("Could not get display for mouse.");
268  }
269  if (!dispdata) {
270  return SDL_SetError("Could not get display driverdata.");
271  }
272  if (!dispdata->cursor_plane) {
273  return SDL_SetError("Hardware cursor plane not initialized.");
274  }
275 
276  curdata = (KMSDRM_CursorData *) cursor->driverdata;
277 
278  if (!curdata || !dispdata->cursor_bo) {
279  return SDL_SetError("Cursor not initialized properly.");
280  }
281 
282  /* Prepare a buffer we can dump to our GBM BO (different size, alpha premultiplication...) */
283  bo_stride = KMSDRM_gbm_bo_get_stride(dispdata->cursor_bo);
284  bufsize = bo_stride * curdata->h;
285 
286  ready_buffer = (uint32_t*)SDL_malloc(bufsize);
287  if (!ready_buffer) {
288  ret = SDL_OutOfMemory();
289  goto cleanup;
290  }
291 
292  /* Clean the whole buffer we are preparing. */
293  SDL_memset(ready_buffer, 0x00, bo_stride * curdata->h);
294 
295  /* Copy from the cursor buffer to a buffer that we can dump to the GBM BO,
296  pre-multiplying by alpha each pixel as we go. */
297  for (i = 0; i < curdata->h; i++) {
298  for (j = 0; j < curdata->w; j++) {
299  pixel = ((uint32_t*)curdata->buffer)[i * curdata->w + j];
300  alpha_premultiply_ARGB8888 (&pixel);
301  SDL_memcpy(ready_buffer + (i * dispdata->cursor_w) + j, &pixel, 4);
302  }
303  }
304 
305  /* Dump the cursor buffer to our GBM BO. */
306  if (KMSDRM_gbm_bo_write(dispdata->cursor_bo, ready_buffer, bufsize)) {
307  ret = SDL_SetError("Could not write to GBM cursor BO");
308  goto cleanup;
309  }
310 
311  /* Get the fb_id for the GBM BO so we can show it on the cursor plane. */
312  fb = KMSDRM_FBFromBO(video_device, dispdata->cursor_bo);
313 
314  /* Show the GBM BO buffer on the cursor plane. */
315  info.plane = dispdata->cursor_plane;
316  info.crtc_id = dispdata->crtc->crtc->crtc_id;
317  info.fb_id = fb->fb_id;
318  info.src_w = curdata->w;
319  info.src_h = curdata->h;
320  info.crtc_x = mouse->x - curdata->hot_x;
321  info.crtc_y = mouse->y - curdata->hot_y;
322  info.crtc_w = curdata->w;
323  info.crtc_h = curdata->h;
324 
326 
327  if (drm_atomic_commit(display->device, SDL_TRUE)) {
328  ret = SDL_SetError("Failed atomic commit in KMSDRM_ShowCursor.");
329  goto cleanup;
330  }
331 
332  ret = 0;
333 
334 cleanup:
335 
336  if (ready_buffer) {
337  SDL_free(ready_buffer);
338  }
339  return ret;
340 }
341 
342 /* We have destroyed the cursor by now, in KMSDRM_DestroyCursor.
343  This is only for freeing the SDL_cursor.*/
344 static void
345 KMSDRM_FreeCursor(SDL_Cursor * cursor)
346 {
347  KMSDRM_CursorData *curdata;
348 
349  /* Even if the cursor is not ours, free it. */
350  if (cursor) {
351  curdata = (KMSDRM_CursorData *) cursor->driverdata;
352  /* Free cursor buffer */
353  if (curdata->buffer) {
354  SDL_free(curdata->buffer);
355  curdata->buffer = NULL;
356  }
357  /* Free cursor itself */
358  if (cursor->driverdata) {
360  }
361  SDL_free(cursor);
362  }
363 }
364 
365 /* Warp the mouse to (x,y) */
366 static void
367 KMSDRM_WarpMouse(SDL_Window * window, int x, int y)
368 {
369  /* Only one global/fullscreen window is supported */
370  KMSDRM_WarpMouseGlobal(x, y);
371 }
372 
373 /* Warp the mouse to (x,y) */
374 static int
375 KMSDRM_WarpMouseGlobal(int x, int y)
376 {
377  KMSDRM_CursorData *curdata;
378  SDL_Mouse *mouse = SDL_GetMouse();
380 
381  if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata) {
382  /* Update internal mouse position. */
383  SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
384 
385  /* And now update the cursor graphic position on screen. */
386  curdata = (KMSDRM_CursorData *) mouse->cur_cursor->driverdata;
387  if (dispdata->cursor_bo) {
388  if (drm_atomic_movecursor(curdata, x, y)) {
389  return SDL_SetError("drm_atomic_movecursor() failed.");
390  }
391  } else {
392  return SDL_SetError("Cursor not initialized properly.");
393  }
394  } else {
395  return SDL_SetError("No mouse or current cursor.");
396  }
397 
398  return 0;
399 }
400 
401 void
403 {
404  /* FIXME: Using UDEV it should be possible to scan all mice
405  * but there's no point in doing so as there's no multimice support...yet!
406  */
407 
409  SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata);
411  SDL_Mouse *mouse = SDL_GetMouse();
412  uint64_t usable_cursor_w, usable_cursor_h;
413 
414  mouse->CreateCursor = KMSDRM_CreateCursor;
415  mouse->ShowCursor = KMSDRM_ShowCursor;
416  mouse->MoveCursor = KMSDRM_MoveCursor;
417  mouse->FreeCursor = KMSDRM_FreeCursor;
418  mouse->WarpMouse = KMSDRM_WarpMouse;
419  mouse->WarpMouseGlobal = KMSDRM_WarpMouseGlobal;
420 
421  /***************************************************************************/
422  /* REMEMBER TO BE SURE OF UNDOING ALL THESE STEPS PROPERLY BEFORE CALLING */
423  /* gbm_device_destroy, OR YOU WON'T BE ABLE TO CREATE A NEW ONE (ERROR -13 */
424  /* ON gbm_create_device). */
425  /***************************************************************************/
426 
427  /* 1- Init cursor plane, if we haven't yet. */
428  if (!dispdata->cursor_plane) {
429  setup_plane(_this, &(dispdata->cursor_plane), DRM_PLANE_TYPE_CURSOR);
430  }
431 
432  /* 2- Create the cursor GBM BO, if we haven't yet. */
433  if (!dispdata->cursor_bo) {
434 
435  if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev, GBM_FORMAT_ARGB8888,
436  GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
437  {
438  SDL_SetError("Unsupported pixel format for cursor");
439  return;
440  }
441 
442  if (KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_WIDTH, &usable_cursor_w) ||
443  KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_HEIGHT, &usable_cursor_h))
444  {
445  SDL_SetError("Could not get the recommended GBM cursor size");
446  goto cleanup;
447  }
448 
449  if (usable_cursor_w == 0 || usable_cursor_h == 0) {
450  SDL_SetError("Could not get an usable GBM cursor size");
451  goto cleanup;
452  }
453 
454  dispdata->cursor_w = usable_cursor_w;
455  dispdata->cursor_h = usable_cursor_h;
456 
457  dispdata->cursor_bo = KMSDRM_gbm_bo_create(viddata->gbm_dev,
458  usable_cursor_w, usable_cursor_h,
459  GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
460 
461  if (!dispdata->cursor_bo) {
462  SDL_SetError("Could not create GBM cursor BO");
463  goto cleanup;
464  }
465  }
466 
467  /* SDL expects to set the default cursor on screen when we init the mouse. */
468  SDL_SetDefaultCursor(KMSDRM_CreateDefaultCursor());
469 
470  return;
471 
472 cleanup:
473  if (dispdata->cursor_bo) {
474  KMSDRM_gbm_bo_destroy(dispdata->cursor_bo);
475  dispdata->cursor_bo = NULL;
476  }
477 }
478 
479 void
481 {
482  SDL_VideoDevice *video_device = SDL_GetVideoDevice();
484  KMSDRM_PlaneInfo info = {0};
485 
486  /*******************************************/
487  /* UNDO WHAT WE DID IN KMSDRM_InitMouse(). */
488  /*******************************************/
489 
490  /* 1- Destroy the curso GBM BO. */
491  if (video_device && dispdata->cursor_bo) {
492  /* Unsethe the cursor BO from the cursor plane.
493  (The other members of the plane info are zeroed). */
494  info.plane = dispdata->cursor_plane;
496  /* Wait until the cursor is unset from the cursor plane
497  before destroying it's BO. */
498  if (drm_atomic_commit(video_device, SDL_TRUE)) {
499  SDL_SetError("Failed atomic commit in KMSDRM_DenitMouse.");
500  }
501  /* ..and finally destroy the cursor DRM BO! */
502  KMSDRM_gbm_bo_destroy(dispdata->cursor_bo);
503  dispdata->cursor_bo = NULL;
504  }
505 
506  /* 2- Free the cursor plane, on which the cursor was being shown. */
507  if (dispdata->cursor_plane) {
508  free_plane(&dispdata->cursor_plane);
509  }
510 
511 }
512 
513 /* This is called when a mouse motion event occurs */
514 static void
515 KMSDRM_MoveCursor(SDL_Cursor * cursor)
516 {
517  SDL_Mouse *mouse = SDL_GetMouse();
518  KMSDRM_CursorData *curdata;
519 
520  /* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity!
521  That's why we move the cursor graphic ONLY. */
522  if (mouse && mouse->cur_cursor && mouse->cur_cursor->driverdata) {
523  curdata = (KMSDRM_CursorData *) mouse->cur_cursor->driverdata;
524 
525  /* Some programs expect cursor movement even while they don't do SwapWindow() calls,
526  and since we ride on the atomic_commit() in SwapWindow() for cursor movement,
527  cursor won't move in these situations. We could do an atomic_commit() here
528  for each cursor movement request, but it cripples the movement to 30FPS,
529  so a future solution is needed. SDLPoP "QUIT?" menu is an example of this
530  situation. */
531 
532  if (drm_atomic_movecursor(curdata, mouse->x, mouse->y)) {
533  SDL_SetError("drm_atomic_movecursor() failed.");
534  }
535  }
536 }
537 
538 #endif /* SDL_VIDEO_DRIVER_KMSDRM */
539 
540 /* vi: set ts=4 sw=4 expandtab: */
#define _THIS
#define SDL_assert(condition)
Definition: SDL_assert.h:171
unsigned short uint16_t
unsigned int uint32_t
unsigned long long uint64_t
#define SDL_SetError
#define SDL_memset
#define SDL_CreateCursor
#define SDL_malloc
#define SDL_UnlockSurface
#define SDL_free
#define SDL_LockSurface
#define SDL_memcpy
#define SDL_calloc
#define SDL_OutOfMemory()
Definition: SDL_error.h:88
int uint32_t uint32_t uint32_t uint32_t uint32_t int drmModeModeInfoPtr mode int uint32_t uint32_t uint32_t uint32_t int32_t hot_x
void KMSDRM_InitCursor()
void KMSDRM_DeinitMouse(_THIS)
void KMSDRM_InitMouse(_THIS)
int setup_plane(_THIS, struct plane **plane, uint32_t plane_type)
int drm_atomic_commit(_THIS, SDL_bool blocking)
void drm_atomic_set_plane_props(struct KMSDRM_PlaneInfo *info)
int add_plane_property(drmModeAtomicReq *req, struct plane *plane, const char *name, uint64_t value)
KMSDRM_FBInfo * KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo)
void free_plane(struct plane **plane)
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:175
void SDL_SetDefaultCursor(SDL_Cursor *cursor)
Definition: SDL_mouse.c:164
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
Definition: SDL_mouse.c:298
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLenum GLuint GLsizei bufsize
@ SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:257
@ SDL_TRUE
Definition: SDL_stdinc.h:170
#define SDL_MUSTLOCK(S)
Definition: SDL_surface.h:62
void * SDL_GetDisplayDriverData(int displayIndex)
Definition: SDL_video.c:680
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:587
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1130
#define G(x, y, z)
Definition: SDL_test_md5.c:74
static SDL_VideoDevice * _this
Definition: SDL_video.c:126
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:163
#define DEFAULT_CHOTY
static const unsigned char default_cdata[]
#define DEFAULT_CHEIGHT
#define DEFAULT_CHOTX
#define DEFAULT_CWIDTH
static const unsigned char default_cmask[]
EGLSurface surface
Definition: eglext.h:248
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld cleanup[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head if pixblock_size cache_preload_simple endif process_pixblock_tail pixinterleave dst_w_basereg irp if pixblock_size chunk_size tst beq if DST_W else pixst DST_W else mov ORIG_W endif add lsl if lsl endif if lsl endif lsl endif lsl endif lsl endif subs mov DST_W if regs_shortage str endif bge start_of_loop_label endm macro generate_composite_function
struct plane * plane
void * driverdata
Definition: SDL_mouse_c.h:33
drmModeAtomicReq * atomic_req
struct gbm_bo * cursor_bo
SDL_MouseID mouseID
Definition: SDL_mouse_c.h:76
SDL_Cursor * cur_cursor
Definition: SDL_mouse_c.h:105
void(* WarpMouse)(SDL_Window *window, int x, int y)
Definition: SDL_mouse_c.h:61
SDL_Cursor *(* CreateCursor)(SDL_Surface *surface, int hot_x, int hot_y)
Definition: SDL_mouse_c.h:46
void(* FreeCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:58
int(* ShowCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:52
SDL_Window * focus
Definition: SDL_mouse_c.h:77
SDL_bool cursor_shown
Definition: SDL_mouse_c.h:106
int(* WarpMouseGlobal)(int x, int y)
Definition: SDL_mouse_c.h:64
void(* MoveCursor)(SDL_Cursor *cursor)
Definition: SDL_mouse_c.h:55
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71
struct gbm_device * gbm_dev
SDL_VideoDevice * device
Definition: SDL_sysvideo.h:138
The type used to identify a window.
Definition: SDL_sysvideo.h:75
drmModeCrtc * crtc
SDL_Cursor * cursor
Definition: testwm2.c:40