1 /**************************************************************************
2
3 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4 Copyright © 2002 David Dawes
5
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sub license, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial portions
18 of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
24 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 **************************************************************************/
29
30 /*
31 * Authors:
32 * Keith Whitwell <keith@tungstengraphics.com>
33 * David Dawes <dawes@xfree86.org>
34 *
35 */
36
37 #ifndef _SNA_H_
38 #define _SNA_H_
39
40 #include <stdint.h>
41
42 #include <xorg-server.h>
43 #include <xf86str.h>
44
45 #include <xf86Crtc.h>
46 #if XF86_CRTC_VERSION >= 5
47 #define HAS_PIXMAP_SHARING 1
48 #endif
49
50 #include <windowstr.h>
51 #include <glyphstr.h>
52 #include <picturestr.h>
53 #include <gcstruct.h>
54 #include <xvdix.h>
55
56 #include <pciaccess.h>
57
58 #include <xf86drmMode.h>
59
60 #include "../compat-api.h"
61 #include <drm.h>
62 #include <i915_drm.h>
63
64 #if HAVE_DRI2
65 #include <dri2.h>
66 #endif
67
68 #if HAVE_DRI3
69 #include <misync.h>
70 #endif
71
72 #if HAVE_UDEV
73 #include <libudev.h>
74 #endif
75
76 #include <signal.h>
77 #include <setjmp.h>
78
79 #include "xassert.h"
80 #include "compiler.h"
81 #include "debug.h"
82
83 #define DEBUG_NO_BLT 0
84
85 #define DEBUG_FLUSH_BATCH 0
86
87 #define TEST_ALL 0
88 #define TEST_ACCEL (TEST_ALL || 0)
89 #define TEST_BATCH (TEST_ALL || 0)
90 #define TEST_BLT (TEST_ALL || 0)
91 #define TEST_COMPOSITE (TEST_ALL || 0)
92 #define TEST_DAMAGE (TEST_ALL || 0)
93 #define TEST_GRADIENT (TEST_ALL || 0)
94 #define TEST_GLYPHS (TEST_ALL || 0)
95 #define TEST_IO (TEST_ALL || 0)
96 #define TEST_KGEM (TEST_ALL || 0)
97 #define TEST_RENDER (TEST_ALL || 0)
98
99 #include "intel_driver.h"
100 #include "intel_list.h"
101 #include "kgem.h"
102 #include "sna_damage.h"
103 #include "sna_render.h"
104 #include "fb/fb.h"
105
106 struct sna_cursor;
107 struct sna_crtc;
108
109 struct sna_client {
110 struct list events;
111 int is_compositor; /* only 4 bits used */
112 };
113
114 extern DevPrivateKeyRec sna_client_key;
115
sna_client(ClientPtr client)116 pure static inline struct sna_client *sna_client(ClientPtr client)
117 {
118 return __get_private(client, sna_client_key);
119 }
120
121 struct sna_cow {
122 struct kgem_bo *bo;
123 struct list list;
124 int refcnt;
125 };
126
127 struct sna_pixmap {
128 PixmapPtr pixmap;
129 struct kgem_bo *gpu_bo, *cpu_bo;
130 struct sna_damage *gpu_damage, *cpu_damage;
131 struct sna_cow *cow;
132 void *ptr;
133 #define PTR(ptr) ((void*)((uintptr_t)(ptr) & ~1))
134
135 bool (*move_to_gpu)(struct sna *, struct sna_pixmap *, unsigned);
136 void *move_to_gpu_data;
137
138 struct list flush_list;
139 struct list cow_list;
140
141 uint32_t stride;
142 uint32_t clear_color;
143
144 #define SOURCE_BIAS 4
145 uint8_t source_count;
146 uint8_t pinned :4;
147 #define PIN_SCANOUT 0x1
148 #define PIN_DRI2 0x2
149 #define PIN_DRI3 0x4
150 #define PIN_PRIME 0x8
151 uint8_t create :4;
152 uint8_t mapped :2;
153 #define MAPPED_NONE 0
154 #define MAPPED_GTT 1
155 #define MAPPED_CPU 2
156 uint8_t flush :2;
157 #define FLUSH_READ 1
158 #define FLUSH_WRITE 2
159 uint8_t shm :1;
160 uint8_t clear :1;
161 uint8_t header :1;
162 uint8_t cpu :1;
163 };
164
165 #define IS_STATIC_PTR(ptr) ((uintptr_t)(ptr) & 1)
166 #define MAKE_STATIC_PTR(ptr) ((void*)((uintptr_t)(ptr) | 1))
167
168 struct sna_glyph {
169 PicturePtr atlas;
170 struct sna_coordinate coordinate;
171 uint16_t size, pos;
172 pixman_image_t *image;
173 };
174
get_root_window(ScreenPtr screen)175 static inline WindowPtr get_root_window(ScreenPtr screen)
176 {
177 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,10,0,0,0)
178 return screen->root;
179 #else
180 return WindowTable[screen->myNum];
181 #endif
182 }
183
184 #if !NDEBUG
check_pixmap(PixmapPtr pixmap)185 static PixmapPtr check_pixmap(PixmapPtr pixmap)
186 {
187 if (pixmap != NULL) {
188 assert(pixmap->refcnt >= 1);
189 assert(pixmap->devKind != 0xdeadbeef);
190 }
191 return pixmap;
192 }
193 #else
194 #define check_pixmap(p) p
195 #endif
196
get_window_pixmap(WindowPtr window)197 static inline PixmapPtr get_window_pixmap(WindowPtr window)
198 {
199 assert(window);
200 assert(window->drawable.type != DRAWABLE_PIXMAP);
201 return check_pixmap(fbGetWindowPixmap(window));
202 }
203
get_drawable_pixmap(DrawablePtr drawable)204 static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
205 {
206 assert(drawable);
207 if (drawable->type == DRAWABLE_PIXMAP)
208 return check_pixmap((PixmapPtr)drawable);
209 else
210 return get_window_pixmap((WindowPtr)drawable);
211 }
212
213 extern DevPrivateKeyRec sna_pixmap_key;
214
sna_pixmap(PixmapPtr pixmap)215 pure static inline struct sna_pixmap *sna_pixmap(PixmapPtr pixmap)
216 {
217 return ((void **)__get_private(pixmap, sna_pixmap_key))[1];
218 }
219
sna_pixmap_from_drawable(DrawablePtr drawable)220 static inline struct sna_pixmap *sna_pixmap_from_drawable(DrawablePtr drawable)
221 {
222 return sna_pixmap(get_drawable_pixmap(drawable));
223 }
224
225 struct sna_gc {
226 long changes;
227 long serial;
228
229 const GCFuncs *old_funcs;
230 void *priv;
231 };
232
sna_gc(GCPtr gc)233 static inline struct sna_gc *sna_gc(GCPtr gc)
234 {
235 return (struct sna_gc *)__get_private(gc, sna_gc_key);
236 }
237
238 enum {
239 FLUSH_TIMER = 0,
240 THROTTLE_TIMER,
241 EXPIRE_TIMER,
242 #if DEBUG_MEMORY
243 DEBUG_MEMORY_TIMER,
244 #endif
245 NUM_TIMERS
246 };
247
248 struct sna {
249 struct kgem kgem;
250
251 ScrnInfoPtr scrn;
252 struct intel_device *dev;
253
254 unsigned flags;
255 #define SNA_IS_SLAVED 0x1
256 #define SNA_IS_HOSTED 0x2
257 #define SNA_NO_WAIT 0x10
258 #define SNA_NO_FLIP 0x20
259 #define SNA_NO_VSYNC 0x40
260 #define SNA_TRIPLE_BUFFER 0x80
261 #define SNA_TEAR_FREE 0x100
262 #define SNA_WANT_TEAR_FREE 0x200
263 #define SNA_FORCE_SHADOW 0x400
264 #define SNA_FLUSH_GTT 0x800
265 #define SNA_PERFORMANCE 0x1000
266 #define SNA_POWERSAVE 0x2000
267 #define SNA_NO_DPMS 0x4000
268 #define SNA_HAS_FLIP 0x10000
269 #define SNA_HAS_ASYNC_FLIP 0x20000
270 #define SNA_LINEAR_FB 0x40000
271 #define SNA_REPROBE 0x80000000
272
273 unsigned cpu_features;
274 #define MMX 0x1
275 #define SSE 0x2
276 #define SSE2 0x4
277 #define SSE3 0x8
278 #define SSSE3 0x10
279 #define SSE4_1 0x20
280 #define SSE4_2 0x40
281 #define AVX 0x80
282 #define AVX2 0x100
283
284 bool ignore_copy_area : 1;
285
286 unsigned watch_shm_flush;
287 unsigned watch_dri_flush;
288 unsigned damage_event;
289 bool needs_shm_flush;
290 bool needs_dri_flush;
291
292 struct timeval timer_tv;
293 uint32_t timer_expire[NUM_TIMERS];
294 uint16_t timer_active;
295
296 int vblank_interval;
297
298 struct list flush_pixmaps;
299 struct list active_pixmaps;
300
301 PixmapPtr front;
302 PixmapPtr freed_pixmap;
303
304 struct sna_mode {
305 DamagePtr shadow_damage;
306 struct kgem_bo *shadow;
307 unsigned front_active;
308 unsigned shadow_active;
309 unsigned rr_active;
310 unsigned flip_active;
311 unsigned hidden;
312 bool shadow_enabled;
313 bool dirty;
314
315 struct drm_event_vblank *shadow_events;
316 int shadow_nevent;
317 int shadow_size;
318
319 int max_crtc_width, max_crtc_height;
320 RegionRec shadow_region;
321 RegionRec shadow_cancel;
322 struct list shadow_crtc;
323 bool shadow_dirty;
324
325 unsigned num_real_crtc;
326 unsigned num_real_output;
327 unsigned num_real_encoder;
328 unsigned num_fake;
329 unsigned serial;
330
331 uint32_t *encoders;
332
333 #if HAVE_UDEV
334 struct udev_monitor *backlight_monitor;
335 pointer backlight_handler;
336 #endif
337
338 Bool (*rrGetInfo)(ScreenPtr, Rotation *);
339 } mode;
340
341 struct {
342 struct sna_cursor *cursors;
343 xf86CursorInfoPtr info;
344 CursorPtr ref;
345
346 unsigned serial;
347 uint32_t fg, bg;
348 int size;
349
350 bool disable;
351 bool active;
352 int last_x;
353 int last_y;
354
355 unsigned max_size;
356 bool use_gtt;
357
358 int num_stash;
359 struct sna_cursor *stash;
360 void *scratch;
361 } cursor;
362
363 struct sna_dri2 {
364 bool available : 1;
365 bool enable : 1;
366 bool open : 1;
367
368 #if HAVE_DRI2
369 void *flip_pending;
370 unsigned client_count;
371 #endif
372 } dri2;
373
374 struct sna_dri3 {
375 bool available :1;
376 bool override : 1;
377 bool enable : 1;
378 bool open :1;
379
380 #if HAVE_DRI3
381 SyncScreenCreateFenceFunc create_fence;
382 struct list pixmaps;
383 #endif
384 } dri3;
385
386 struct sna_present {
387 bool available;
388 bool open;
389 #if HAVE_PRESENT
390 struct list vblank_queue;
391 uint64_t unflip;
392 void *freed_info;
393 #endif
394 } present;
395
396 struct sna_xv {
397 XvAdaptorPtr adaptors;
398 int num_adaptors;
399 } xv;
400
401 EntityInfoPtr pEnt;
402 const struct intel_device_info *info;
403
404 #if !HAVE_NOTIFY_FD
405 ScreenBlockHandlerProcPtr BlockHandler;
406 ScreenWakeupHandlerProcPtr WakeupHandler;
407 #endif
408 CloseScreenProcPtr CloseScreen;
409
410 PicturePtr clear;
411 struct {
412 uint32_t fill_bo;
413 uint32_t fill_pixel;
414 uint32_t fill_alu;
415 } blt_state;
416 union {
417 unsigned gt;
418 struct gen2_render_state gen2;
419 struct gen3_render_state gen3;
420 struct gen4_render_state gen4;
421 struct gen5_render_state gen5;
422 struct gen6_render_state gen6;
423 struct gen7_render_state gen7;
424 struct gen8_render_state gen8;
425 struct gen9_render_state gen9;
426 } render_state;
427
428 /* Broken-out options. */
429 OptionInfoPtr Options;
430
431 /* Driver phase/state information */
432 bool suspended;
433
434 #if HAVE_UDEV
435 struct udev_monitor *uevent_monitor;
436 pointer uevent_handler;
437 #endif
438
439 struct {
440 int fd;
441 uint8_t offset;
442 uint8_t remain;
443 char event[256];
444 } acpi;
445
446 struct sna_render render;
447
448 #if DEBUG_MEMORY
449 struct {
450 int pixmap_allocs;
451 int pixmap_cached;
452 int cpu_bo_allocs;
453 size_t shadow_pixels_bytes;
454 size_t cpu_bo_bytes;
455 } debug_memory;
456 #endif
457 };
458
459 bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna);
460 bool sna_mode_fake_init(struct sna *sna, int num_fake);
461 bool sna_mode_wants_tear_free(struct sna *sna);
462 void sna_mode_adjust_frame(struct sna *sna, int x, int y);
463 extern void sna_mode_discover(struct sna *sna, bool tell);
464 extern void sna_mode_check(struct sna *sna);
465 extern bool sna_mode_disable(struct sna *sna);
466 extern void sna_mode_enable(struct sna *sna);
467 extern void sna_mode_reset(struct sna *sna);
468 extern int sna_mode_wakeup(struct sna *sna);
469 extern void sna_mode_redisplay(struct sna *sna);
470 extern void sna_shadow_set_crtc(struct sna *sna, xf86CrtcPtr crtc, struct kgem_bo *bo);
471 extern void sna_shadow_steal_crtcs(struct sna *sna, struct list *list);
472 extern void sna_shadow_unsteal_crtcs(struct sna *sna, struct list *list);
473 extern void sna_shadow_unset_crtc(struct sna *sna, xf86CrtcPtr crtc);
474 extern bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv,
475 const RegionRec *region);
476 extern void sna_mode_set_primary(struct sna *sna);
477 extern bool sna_mode_find_hotplug_connector(struct sna *sna, unsigned id);
478 extern void sna_mode_close(struct sna *sna);
479 extern void sna_mode_fini(struct sna *sna);
480
481 extern void sna_crtc_config_notify(ScreenPtr screen);
482
483 extern bool sna_cursors_init(ScreenPtr screen, struct sna *sna);
484
485 extern CARD32 sna_mode_coldplug(OsTimerPtr timer, CARD32 now, void *data);
486 #define COLDPLUG_DELAY_MS 2000
487
488 typedef void (*sna_flip_handler_t)(struct drm_event_vblank *e,
489 void *data);
490
491 extern bool sna_needs_page_flip(struct sna *sna, struct kgem_bo *bo);
492 extern int sna_page_flip(struct sna *sna,
493 struct kgem_bo *bo,
494 sna_flip_handler_t handler,
495 void *data);
496
497 pure static inline struct sna *
to_sna(ScrnInfoPtr scrn)498 to_sna(ScrnInfoPtr scrn)
499 {
500 struct sna *sna = scrn->driverPrivate;
501 assert(sna->scrn == scrn);
502 return sna;
503 }
504
505 pure static inline struct sna *
to_sna_from_screen(ScreenPtr screen)506 to_sna_from_screen(ScreenPtr screen)
507 {
508 return to_sna(xf86ScreenToScrn(screen));
509 }
510
to_screen_from_sna(struct sna * sna)511 pure static inline ScreenPtr to_screen_from_sna(struct sna *sna)
512 {
513 ScreenPtr screen = xf86ScrnToScreen(sna->scrn);
514 assert(!screen || sna == to_sna_from_screen(screen));
515 return screen;
516 }
517
518 pure static inline struct sna *
to_sna_from_pixmap(PixmapPtr pixmap)519 to_sna_from_pixmap(PixmapPtr pixmap)
520 {
521 return ((void **)__get_private(pixmap, sna_pixmap_key))[0];
522 }
523
524 pure static inline struct sna *
to_sna_from_drawable(DrawablePtr drawable)525 to_sna_from_drawable(DrawablePtr drawable)
526 {
527 return to_sna_from_screen(drawable->pScreen);
528 }
529
530 static inline struct sna *
to_sna_from_kgem(struct kgem * kgem)531 to_sna_from_kgem(struct kgem *kgem)
532 {
533 return container_of(kgem, struct sna, kgem);
534 }
535
536 #ifndef ARRAY_SIZE
537 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
538 #endif
539
540 #ifndef ALIGN
541 #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1))
542 #endif
543
544 #ifndef MIN
545 #define MIN(a,b) ((a) <= (b) ? (a) : (b))
546 #endif
547
548 #ifndef MAX
549 #define MAX(a,b) ((a) >= (b) ? (a) : (b))
550 #endif
551
552 extern xf86CrtcPtr sna_covering_crtc(struct sna *sna,
553 const BoxRec *box,
554 xf86CrtcPtr desired);
555 extern xf86CrtcPtr sna_primary_crtc(struct sna *sna);
556
557 extern bool sna_wait_for_scanline(struct sna *sna, PixmapPtr pixmap,
558 xf86CrtcPtr crtc, const BoxRec *clip);
559
560 const struct ust_msc {
561 uint64_t msc;
562 int tv_sec;
563 int tv_usec;
564 } *sna_crtc_last_swap(xf86CrtcPtr crtc);
565
566 uint64_t sna_crtc_record_swap(xf86CrtcPtr crtc,
567 int tv_sec, int tv_usec, unsigned seq);
568
sna_crtc_record_vblank(xf86CrtcPtr crtc,const union drm_wait_vblank * vbl)569 static inline uint64_t sna_crtc_record_vblank(xf86CrtcPtr crtc,
570 const union drm_wait_vblank *vbl)
571 {
572 return sna_crtc_record_swap(crtc,
573 vbl->reply.tval_sec,
574 vbl->reply.tval_usec,
575 vbl->reply.sequence);
576 }
577
sna_crtc_record_event(xf86CrtcPtr crtc,struct drm_event_vblank * event)578 static inline uint64_t sna_crtc_record_event(xf86CrtcPtr crtc,
579 struct drm_event_vblank *event)
580 {
581 return sna_crtc_record_swap(crtc,
582 event->tv_sec,
583 event->tv_usec,
584 event->sequence);
585 }
586
ust64(int tv_sec,int tv_usec)587 static inline uint64_t ust64(int tv_sec, int tv_usec)
588 {
589 return (uint64_t)tv_sec * 1000000 + tv_usec;
590 }
591
swap_ust(const struct ust_msc * swap)592 static inline uint64_t swap_ust(const struct ust_msc *swap)
593 {
594 return ust64(swap->tv_sec, swap->tv_usec);
595 }
596
597 #if HAVE_DRI2
598 bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen);
599 void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event);
600 void sna_dri2_vblank_handler(struct drm_event_vblank *event);
601 void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo);
602 void sna_dri2_decouple_window(WindowPtr win);
603 void sna_dri2_destroy_window(WindowPtr win);
604 void sna_dri2_close(struct sna *sna, ScreenPtr pScreen);
605 #else
sna_dri2_open(struct sna * sna,ScreenPtr pScreen)606 static inline bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen) { return false; }
sna_dri2_page_flip_handler(struct sna * sna,struct drm_event_vblank * event)607 static inline void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event) { }
sna_dri2_vblank_handler(struct drm_event_vblank * event)608 static inline void sna_dri2_vblank_handler(struct drm_event_vblank *event) { }
sna_dri2_pixmap_update_bo(struct sna * sna,PixmapPtr pixmap,struct kgem_bo * bo)609 static inline void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo) { }
sna_dri2_decouple_window(WindowPtr win)610 static inline void sna_dri2_decouple_window(WindowPtr win) { }
sna_dri2_destroy_window(WindowPtr win)611 static inline void sna_dri2_destroy_window(WindowPtr win) { }
sna_dri2_close(struct sna * sna,ScreenPtr pScreen)612 static inline void sna_dri2_close(struct sna *sna, ScreenPtr pScreen) { }
613 #endif
614
615 #if HAVE_DRI3
616 bool sna_dri3_open(struct sna *sna, ScreenPtr pScreen);
617 void sna_dri3_close(struct sna *sna, ScreenPtr pScreen);
618 #else
sna_dri3_open(struct sna * sna,ScreenPtr pScreen)619 static inline bool sna_dri3_open(struct sna *sna, ScreenPtr pScreen) { return false; }
sna_dri3_close(struct sna * sna,ScreenPtr pScreen)620 static inline void sna_dri3_close(struct sna *sna, ScreenPtr pScreen) { }
621 #endif
622
623 #if HAVE_PRESENT
624 bool sna_present_open(struct sna *sna, ScreenPtr pScreen);
625 void sna_present_update(struct sna *sna);
626 void sna_present_close(struct sna *sna, ScreenPtr pScreen);
627 void sna_present_vblank_handler(struct drm_event_vblank *event);
628 void sna_present_cancel_flip(struct sna *sna);
629 #else
sna_present_open(struct sna * sna,ScreenPtr pScreen)630 static inline bool sna_present_open(struct sna *sna, ScreenPtr pScreen) { return false; }
sna_present_update(struct sna * sna)631 static inline void sna_present_update(struct sna *sna) { }
sna_present_close(struct sna * sna,ScreenPtr pScreen)632 static inline void sna_present_close(struct sna *sna, ScreenPtr pScreen) { }
sna_present_vblank_handler(struct drm_event_vblank * event)633 static inline void sna_present_vblank_handler(struct drm_event_vblank *event) { }
sna_present_cancel_flip(struct sna * sna)634 static inline void sna_present_cancel_flip(struct sna *sna) { }
635 #endif
636
637 extern unsigned sna_crtc_count_sprites(xf86CrtcPtr crtc);
638 extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, unsigned idx, uint32_t rotation);
639 extern void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc, unsigned idx, int colorspace);
640 extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx);
641 extern bool sna_crtc_is_transformed(xf86CrtcPtr crtc);
642 bool sna_has_sprite_format(struct sna *sna, uint32_t format);
643
644 #define CRTC_VBLANK 0x7
645 #define CRTC_ON 0x80000000
646
647 uint32_t sna_crtc_id(xf86CrtcPtr crtc);
648
649 struct sna_crtc_public {
650 unsigned long flags;
651 struct list vblank_queue;
652 };
653
sna_crtc_flags(xf86CrtcPtr crtc)654 static inline unsigned long *sna_crtc_flags(xf86CrtcPtr crtc)
655 {
656 struct sna_crtc_public *pub = crtc->driver_private;
657 assert(pub);
658 return &pub->flags;
659 }
660
sna_crtc_vblank_queue(xf86CrtcPtr crtc)661 static inline struct list *sna_crtc_vblank_queue(xf86CrtcPtr crtc)
662 {
663 struct sna_crtc_public *pub = crtc->driver_private;
664 assert(pub);
665 return &pub->vblank_queue;
666 }
667
sna_crtc_pipe(xf86CrtcPtr crtc)668 static inline unsigned sna_crtc_pipe(xf86CrtcPtr crtc)
669 {
670 return *sna_crtc_flags(crtc) >> 8 & 0xff;
671 }
672
sna_crtc_is_on(xf86CrtcPtr crtc)673 static inline bool sna_crtc_is_on(xf86CrtcPtr crtc)
674 {
675 return *sna_crtc_flags(crtc) & CRTC_ON;
676 }
677
sna_crtc_set_vblank(xf86CrtcPtr crtc)678 static inline void sna_crtc_set_vblank(xf86CrtcPtr crtc)
679 {
680 DBG(("%s: current vblank count: %d\n", __FUNCTION__, *sna_crtc_flags(crtc) & CRTC_VBLANK));
681 assert((*sna_crtc_flags(crtc) & CRTC_VBLANK) < CRTC_VBLANK);
682 ++*sna_crtc_flags(crtc);
683 }
684
sna_crtc_clear_vblank(xf86CrtcPtr crtc)685 static inline void sna_crtc_clear_vblank(xf86CrtcPtr crtc)
686 {
687 DBG(("%s: current vblank count: %d\n", __FUNCTION__, *sna_crtc_flags(crtc) & CRTC_VBLANK));
688 assert(*sna_crtc_flags(crtc) & CRTC_VBLANK);
689 --*sna_crtc_flags(crtc);
690 }
691
sna_crtc_has_vblank(xf86CrtcPtr crtc)692 static inline bool sna_crtc_has_vblank(xf86CrtcPtr crtc)
693 {
694 return *sna_crtc_flags(crtc) & CRTC_VBLANK;
695 }
696
697 CARD32 sna_format_for_depth(int depth);
698 CARD32 sna_render_format_for_depth(int depth);
699
700 void sna_debug_flush(struct sna *sna);
701
702 static inline bool
get_window_deltas(PixmapPtr pixmap,int16_t * x,int16_t * y)703 get_window_deltas(PixmapPtr pixmap, int16_t *x, int16_t *y)
704 {
705 #ifdef COMPOSITE
706 *x = -pixmap->screen_x;
707 *y = -pixmap->screen_y;
708 return pixmap->screen_x | pixmap->screen_y;
709 #else
710 *x = *y = 0;
711 return false;
712 #endif
713 }
714
715 static inline bool
get_drawable_deltas(DrawablePtr drawable,PixmapPtr pixmap,int16_t * x,int16_t * y)716 get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int16_t *x, int16_t *y)
717 {
718 #ifdef COMPOSITE
719 if (drawable->type == DRAWABLE_WINDOW)
720 return get_window_deltas(pixmap, x, y);
721 #endif
722 *x = *y = 0;
723 return false;
724 }
725
726 static inline int
get_drawable_dx(DrawablePtr drawable)727 get_drawable_dx(DrawablePtr drawable)
728 {
729 #ifdef COMPOSITE
730 if (drawable->type == DRAWABLE_WINDOW)
731 return -get_drawable_pixmap(drawable)->screen_x;
732 #endif
733 return 0;
734 }
735
736 static inline int
get_drawable_dy(DrawablePtr drawable)737 get_drawable_dy(DrawablePtr drawable)
738 {
739 #ifdef COMPOSITE
740 if (drawable->type == DRAWABLE_WINDOW)
741 return -get_drawable_pixmap(drawable)->screen_y;
742 #endif
743 return 0;
744 }
745
746 struct sna_pixmap *sna_pixmap_attach_to_bo(PixmapPtr pixmap, struct kgem_bo *bo);
sna_pixmap_is_scanout(struct sna * sna,PixmapPtr pixmap)747 static inline bool sna_pixmap_is_scanout(struct sna *sna, PixmapPtr pixmap)
748 {
749 return (pixmap == sna->front &&
750 !sna->mode.shadow_active &&
751 (sna->flags & SNA_NO_WAIT) == 0);
752 }
753
sna_max_tile_copy_size(struct sna * sna,struct kgem_bo * src,struct kgem_bo * dst)754 static inline int sna_max_tile_copy_size(struct sna *sna, struct kgem_bo *src, struct kgem_bo *dst)
755 {
756 int min_object;
757 int max_size;
758
759 max_size = sna->kgem.aperture_high * PAGE_SIZE;
760 max_size -= MAX(kgem_bo_size(src), kgem_bo_size(dst));
761 if (max_size <= 0) {
762 DBG(("%s: tiles cannot fit into aperture\n", __FUNCTION__));
763 return 0;
764 }
765
766 if (max_size > sna->kgem.max_copy_tile_size)
767 max_size = sna->kgem.max_copy_tile_size;
768
769 min_object = MIN(kgem_bo_size(src), kgem_bo_size(dst)) / 2;
770 if (max_size > min_object)
771 max_size = min_object;
772 if (max_size <= 4096)
773 max_size = 0;
774
775 DBG(("%s: using max tile size of %d\n", __FUNCTION__, max_size));
776 return max_size;
777 }
778
779 PixmapPtr sna_pixmap_create_upload(ScreenPtr screen,
780 int width, int height, int depth,
781 unsigned flags);
782 PixmapPtr sna_pixmap_create_unattached(ScreenPtr screen,
783 int width, int height, int depth);
784 void sna_pixmap_destroy(PixmapPtr pixmap);
785
786 #define assert_pixmap_map(pixmap, priv) do { \
787 assert(priv->mapped != MAPPED_NONE || pixmap->devPrivate.ptr == PTR(priv->ptr)); \
788 assert(priv->mapped != MAPPED_CPU || pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map__cpu)); \
789 assert(priv->mapped != MAPPED_GTT || pixmap->devPrivate.ptr == priv->gpu_bo->map__gtt || pixmap->devPrivate.ptr == priv->gpu_bo->map__wc); \
790 } while (0)
791
sna_pixmap_unmap(PixmapPtr pixmap,struct sna_pixmap * priv)792 static inline void sna_pixmap_unmap(PixmapPtr pixmap, struct sna_pixmap *priv)
793 {
794 if (priv->mapped == MAPPED_NONE) {
795 assert(pixmap->devPrivate.ptr == PTR(priv->ptr));
796 return;
797 }
798
799 DBG(("%s: pixmap=%ld dropping %s mapping\n",
800 __FUNCTION__, pixmap->drawable.serialNumber,
801 priv->mapped == MAPPED_CPU ? "cpu" : "gtt"));
802
803 assert_pixmap_map(pixmap, priv);
804
805 pixmap->devPrivate.ptr = PTR(priv->ptr);
806 pixmap->devKind = priv->stride;
807
808 priv->mapped = MAPPED_NONE;
809 }
810
811 bool
812 sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags);
813
814 #define MOVE_WRITE 0x1
815 #define MOVE_READ 0x2
816 #define MOVE_INPLACE_HINT 0x4
817 #define MOVE_ASYNC_HINT 0x8
818 #define MOVE_SOURCE_HINT 0x10
819 #define MOVE_WHOLE_HINT 0x20
820 #define __MOVE_FORCE 0x40
821 #define __MOVE_DRI 0x80
822 #define __MOVE_SCANOUT 0x100
823 #define __MOVE_TILED 0x200
824 #define __MOVE_PRIME 0x400
825
826 struct sna_pixmap *
827 sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int flags);
828
829 struct sna_pixmap *sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags);
830 static inline struct sna_pixmap *
sna_pixmap_force_to_gpu(PixmapPtr pixmap,unsigned flags)831 sna_pixmap_force_to_gpu(PixmapPtr pixmap, unsigned flags)
832 {
833 /* Unlike move-to-gpu, we ignore wedged and always create the GPU bo */
834 DBG(("%s(pixmap=%ld, flags=%x)\n", __FUNCTION__, pixmap->drawable.serialNumber, flags));
835 return sna_pixmap_move_to_gpu(pixmap, flags | __MOVE_FORCE);
836 }
837 bool must_check _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags);
sna_pixmap_move_to_cpu(PixmapPtr pixmap,unsigned flags)838 static inline bool must_check sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags)
839 {
840 if (flags == MOVE_READ) {
841 struct sna_pixmap *priv = sna_pixmap(pixmap);
842 if (priv == NULL)
843 return true;
844 }
845
846 return _sna_pixmap_move_to_cpu(pixmap, flags);
847 }
848 bool must_check sna_drawable_move_region_to_cpu(DrawablePtr drawable,
849 RegionPtr region,
850 unsigned flags);
851
852 bool must_check sna_drawable_move_to_cpu(DrawablePtr drawable, unsigned flags);
853
854 static inline bool must_check
sna_drawable_move_to_gpu(DrawablePtr drawable,unsigned flags)855 sna_drawable_move_to_gpu(DrawablePtr drawable, unsigned flags)
856 {
857 return sna_pixmap_move_to_gpu(get_drawable_pixmap(drawable), flags) != NULL;
858 }
859
860 void sna_add_flush_pixmap(struct sna *sna,
861 struct sna_pixmap *priv,
862 struct kgem_bo *bo);
863
864 struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling);
865
866 #define PREFER_GPU 0x1
867 #define FORCE_GPU 0x2
868 #define RENDER_GPU 0x4
869 #define IGNORE_DAMAGE 0x8
870 #define REPLACES 0x10
871 struct kgem_bo *
872 sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box,
873 struct sna_damage ***damage);
874
bound(int16_t a,uint16_t b)875 inline static int16_t bound(int16_t a, uint16_t b)
876 {
877 int v = (int)a + (int)b;
878 if (v > MAXSHORT)
879 return MAXSHORT;
880 return v;
881 }
882
clamp(int16_t a,int16_t b)883 inline static int16_t clamp(int16_t a, int16_t b)
884 {
885 int v = (int)a + (int)b;
886 if (v > MAXSHORT)
887 return MAXSHORT;
888 if (v < MINSHORT)
889 return MINSHORT;
890 return v;
891 }
892
box_empty(const BoxRec * box)893 static inline bool box_empty(const BoxRec *box)
894 {
895 return box->x2 <= box->x1 || box->y2 <= box->y1;
896 }
897
898 static inline bool
box_covers_pixmap(PixmapPtr pixmap,const BoxRec * box)899 box_covers_pixmap(PixmapPtr pixmap, const BoxRec *box)
900 {
901 int w = box->x2 - box->x1;
902 int h = box->y2 - box->y1;
903 return pixmap->drawable.width <= w && pixmap->drawable.height <= h;
904 }
905
906 static inline bool
box_inplace(PixmapPtr pixmap,const BoxRec * box)907 box_inplace(PixmapPtr pixmap, const BoxRec *box)
908 {
909 struct sna *sna = to_sna_from_pixmap(pixmap);
910 return ((int)(box->x2 - box->x1) * (int)(box->y2 - box->y1) * pixmap->drawable.bitsPerPixel >> 12) >= sna->kgem.half_cpu_cache_pages;
911 }
912
913 static inline bool
whole_pixmap_inplace(PixmapPtr pixmap)914 whole_pixmap_inplace(PixmapPtr pixmap)
915 {
916 struct sna *sna = to_sna_from_pixmap(pixmap);
917 return ((int)pixmap->drawable.width * (int)pixmap->drawable.height * pixmap->drawable.bitsPerPixel >> 12) >= sna->kgem.half_cpu_cache_pages;
918 }
919
920 static inline bool
region_subsumes_drawable(RegionPtr region,DrawablePtr drawable)921 region_subsumes_drawable(RegionPtr region, DrawablePtr drawable)
922 {
923 const BoxRec *extents;
924
925 if (region->data)
926 return false;
927
928 extents = RegionExtents(region);
929 return extents->x1 <= 0 && extents->y1 <= 0 &&
930 extents->x2 >= drawable->width &&
931 extents->y2 >= drawable->height;
932 }
933
934 static inline bool
region_subsumes_pixmap(const RegionRec * region,PixmapPtr pixmap)935 region_subsumes_pixmap(const RegionRec *region, PixmapPtr pixmap)
936 {
937 if (region->data)
938 return false;
939
940 return (region->extents.x2 - region->extents.x1 >= pixmap->drawable.width &&
941 region->extents.y2 - region->extents.y1 >= pixmap->drawable.height);
942 }
943
944 static inline bool
region_subsumes_damage(const RegionRec * region,struct sna_damage * damage)945 region_subsumes_damage(const RegionRec *region, struct sna_damage *damage)
946 {
947 const BoxRec *re, *de;
948
949 DBG(("%s?\n", __FUNCTION__));
950 assert(damage);
951
952 re = ®ion->extents;
953 de = &DAMAGE_PTR(damage)->extents;
954 DBG(("%s: region (%d, %d), (%d, %d), damage (%d, %d), (%d, %d)\n",
955 __FUNCTION__,
956 re->x1, re->y1, re->x2, re->y2,
957 de->x1, de->y1, de->x2, de->y2));
958
959 if (re->x2 < de->x2 || re->x1 > de->x1 ||
960 re->y2 < de->y2 || re->y1 > de->y1) {
961 DBG(("%s: not contained\n", __FUNCTION__));
962 return false;
963 }
964
965 if (region->data == NULL) {
966 DBG(("%s: singular region contains damage\n", __FUNCTION__));
967 return true;
968 }
969
970 return pixman_region_contains_rectangle((RegionPtr)region,
971 (BoxPtr)de) == PIXMAN_REGION_IN;
972 }
973
974 static inline bool
sna_drawable_is_clear(DrawablePtr d)975 sna_drawable_is_clear(DrawablePtr d)
976 {
977 struct sna_pixmap *priv = sna_pixmap(get_drawable_pixmap(d));
978 return priv && priv->clear && priv->clear_color == 0;
979 }
980
__sna_pixmap_get_bo(PixmapPtr pixmap)981 static inline struct kgem_bo *__sna_pixmap_get_bo(PixmapPtr pixmap)
982 {
983 return sna_pixmap(pixmap)->gpu_bo;
984 }
985
__sna_drawable_peek_bo(DrawablePtr d)986 static inline struct kgem_bo *__sna_drawable_peek_bo(DrawablePtr d)
987 {
988 struct sna_pixmap *priv = sna_pixmap(get_drawable_pixmap(d));
989 return priv ? priv->gpu_bo : NULL;
990 }
991
sna_pixmap_pin(PixmapPtr pixmap,unsigned flags)992 static inline struct kgem_bo *sna_pixmap_pin(PixmapPtr pixmap, unsigned flags)
993 {
994 struct sna_pixmap *priv;
995
996 priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ);
997 if (!priv)
998 return NULL;
999
1000 priv->pinned |= flags;
1001 return priv->gpu_bo;
1002 }
1003
1004
1005 static inline bool
_sna_transform_point(const PictTransform * transform,int64_t x,int64_t y,int64_t result[3])1006 _sna_transform_point(const PictTransform *transform,
1007 int64_t x, int64_t y, int64_t result[3])
1008 {
1009 int j;
1010
1011 for (j = 0; j < 3; j++)
1012 result[j] = (transform->matrix[j][0] * x +
1013 transform->matrix[j][1] * y +
1014 transform->matrix[j][2]);
1015
1016 return result[2] != 0;
1017 }
1018
1019 static inline void
_sna_get_transformed_coordinates(int x,int y,const PictTransform * transform,float * x_out,float * y_out)1020 _sna_get_transformed_coordinates(int x, int y,
1021 const PictTransform *transform,
1022 float *x_out, float *y_out)
1023 {
1024
1025 int64_t result[3];
1026
1027 _sna_transform_point(transform, x, y, result);
1028 *x_out = result[0] / (double)result[2];
1029 *y_out = result[1] / (double)result[2];
1030 }
1031
1032 static inline void
_sna_get_transformed_scaled(int x,int y,const PictTransform * transform,const float * sf,float * x_out,float * y_out)1033 _sna_get_transformed_scaled(int x, int y,
1034 const PictTransform *transform, const float *sf,
1035 float *x_out, float *y_out)
1036 {
1037 *x_out = sf[0] * (transform->matrix[0][0] * x +
1038 transform->matrix[0][1] * y +
1039 transform->matrix[0][2]);
1040
1041 *y_out = sf[1] * (transform->matrix[1][0] * x +
1042 transform->matrix[1][1] * y +
1043 transform->matrix[1][2]);
1044 }
1045
1046 void
1047 sna_get_transformed_coordinates(int x, int y,
1048 const PictTransform *transform,
1049 float *x_out, float *y_out);
1050
1051 void
1052 sna_get_transformed_coordinates_3d(int x, int y,
1053 const PictTransform *transform,
1054 float *x_out, float *y_out, float *z_out);
1055
1056 bool sna_transform_is_affine(const PictTransform *t);
1057 bool sna_transform_is_translation(const PictTransform *t,
1058 pixman_fixed_t *tx, pixman_fixed_t *ty);
1059 bool sna_transform_is_integer_translation(const PictTransform *t,
1060 int16_t *tx, int16_t *ty);
1061 bool sna_transform_is_imprecise_integer_translation(const PictTransform *t,
1062 int filter, bool precise,
1063 int16_t *tx, int16_t *ty);
1064 static inline bool
sna_affine_transform_is_rotation(const PictTransform * t)1065 sna_affine_transform_is_rotation(const PictTransform *t)
1066 {
1067 assert(sna_transform_is_affine(t));
1068 return t->matrix[0][1] | t->matrix[1][0];
1069 }
1070
1071 static inline bool
sna_transform_equal(const PictTransform * a,const PictTransform * b)1072 sna_transform_equal(const PictTransform *a, const PictTransform *b)
1073 {
1074 if (a == b)
1075 return true;
1076
1077 if (a == NULL || b == NULL)
1078 return false;
1079
1080 return memcmp(a, b, sizeof(*a)) == 0;
1081 }
1082
1083 static inline bool
sna_picture_alphamap_equal(PicturePtr a,PicturePtr b)1084 sna_picture_alphamap_equal(PicturePtr a, PicturePtr b)
1085 {
1086 if (a->alphaMap != b->alphaMap)
1087 return false;
1088
1089 if (a->alphaMap)
1090 return false;
1091
1092 return (a->alphaOrigin.x == b->alphaOrigin.x &&
1093 a->alphaOrigin.y == b->alphaOrigin.y);
1094 }
1095
wedged(struct sna * sna)1096 static inline bool wedged(struct sna *sna)
1097 {
1098 return unlikely(sna->kgem.wedged);
1099 }
1100
can_render(struct sna * sna)1101 static inline bool can_render(struct sna *sna)
1102 {
1103 return likely(!sna->kgem.wedged && sna->render.prefer_gpu & PREFER_GPU_RENDER);
1104 }
1105
pixmap_size(PixmapPtr pixmap)1106 static inline uint32_t pixmap_size(PixmapPtr pixmap)
1107 {
1108 return (pixmap->drawable.height - 1) * pixmap->devKind +
1109 pixmap->drawable.width * pixmap->drawable.bitsPerPixel/8;
1110 }
1111
1112 bool sna_accel_init(ScreenPtr sreen, struct sna *sna);
1113 void sna_accel_create(struct sna *sna);
1114 void sna_accel_block(struct sna *sna, struct timeval **tv);
1115 void sna_accel_flush(struct sna *sna);
1116 void sna_accel_enter(struct sna *sna);
1117 void sna_accel_leave(struct sna *sna);
1118 void sna_accel_close(struct sna *sna);
1119 void sna_accel_free(struct sna *sna);
1120
1121 void sna_watch_flush(struct sna *sna, int enable);
1122 void sna_copy_fbcon(struct sna *sna);
1123
1124 bool sna_composite_create(struct sna *sna);
1125 void sna_composite_close(struct sna *sna);
1126
1127 void sna_composite(CARD8 op,
1128 PicturePtr src,
1129 PicturePtr mask,
1130 PicturePtr dst,
1131 INT16 src_x, INT16 src_y,
1132 INT16 mask_x, INT16 mask_y,
1133 INT16 dst_x, INT16 dst_y,
1134 CARD16 width, CARD16 height);
1135 void sna_composite_fb(CARD8 op,
1136 PicturePtr src,
1137 PicturePtr mask,
1138 PicturePtr dst,
1139 RegionPtr region,
1140 INT16 src_x, INT16 src_y,
1141 INT16 mask_x, INT16 mask_y,
1142 INT16 dst_x, INT16 dst_y,
1143 CARD16 width, CARD16 height);
1144 void sna_composite_rectangles(CARD8 op,
1145 PicturePtr dst,
1146 xRenderColor *color,
1147 int num_rects,
1148 xRectangle *rects);
1149 void sna_composite_trapezoids(CARD8 op,
1150 PicturePtr src,
1151 PicturePtr dst,
1152 PictFormatPtr maskFormat,
1153 INT16 xSrc, INT16 ySrc,
1154 int ntrap, xTrapezoid *traps);
1155 void sna_add_traps(PicturePtr picture, INT16 x, INT16 y, int n, xTrap *t);
1156
1157 void sna_composite_triangles(CARD8 op,
1158 PicturePtr src,
1159 PicturePtr dst,
1160 PictFormatPtr maskFormat,
1161 INT16 xSrc, INT16 ySrc,
1162 int ntri, xTriangle *tri);
1163
1164 void sna_composite_tristrip(CARD8 op,
1165 PicturePtr src,
1166 PicturePtr dst,
1167 PictFormatPtr maskFormat,
1168 INT16 xSrc, INT16 ySrc,
1169 int npoints, xPointFixed *points);
1170
1171 void sna_composite_trifan(CARD8 op,
1172 PicturePtr src,
1173 PicturePtr dst,
1174 PictFormatPtr maskFormat,
1175 INT16 xSrc, INT16 ySrc,
1176 int npoints, xPointFixed *points);
1177
1178 bool sna_gradients_create(struct sna *sna);
1179 void sna_gradients_close(struct sna *sna);
1180
1181 bool sna_glyphs_create(struct sna *sna);
1182 void sna_glyphs(CARD8 op,
1183 PicturePtr src,
1184 PicturePtr dst,
1185 PictFormatPtr mask,
1186 INT16 xSrc, INT16 ySrc,
1187 int nlist,
1188 GlyphListPtr list,
1189 GlyphPtr *glyphs);
1190 void sna_glyphs__shared(CARD8 op,
1191 PicturePtr src,
1192 PicturePtr dst,
1193 PictFormatPtr mask,
1194 INT16 src_x, INT16 src_y,
1195 int nlist, GlyphListPtr list, GlyphPtr *glyphs);
1196 void sna_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
1197 void sna_glyphs_close(struct sna *sna);
1198
1199 void sna_read_boxes(struct sna *sna, PixmapPtr dst, struct kgem_bo *src_bo,
1200 const BoxRec *box, int n);
1201 bool sna_write_boxes(struct sna *sna, PixmapPtr dst,
1202 struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
1203 const void *src, int stride, int16_t src_dx, int16_t src_dy,
1204 const BoxRec *box, int n);
1205 bool sna_write_boxes__xor(struct sna *sna, PixmapPtr dst,
1206 struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
1207 const void *src, int stride, int16_t src_dx, int16_t src_dy,
1208 const BoxRec *box, int nbox,
1209 uint32_t and, uint32_t or);
1210
1211 bool sna_replace(struct sna *sna,
1212 PixmapPtr pixmap,
1213 const void *src, int stride);
1214 bool sna_replace__xor(struct sna *sna,
1215 PixmapPtr pixmap,
1216 const void *src, int stride,
1217 uint32_t and, uint32_t or);
1218
1219 bool
1220 sna_compute_composite_extents(BoxPtr extents,
1221 PicturePtr src, PicturePtr mask, PicturePtr dst,
1222 INT16 src_x, INT16 src_y,
1223 INT16 mask_x, INT16 mask_y,
1224 INT16 dst_x, INT16 dst_y,
1225 CARD16 width, CARD16 height);
1226 bool
1227 sna_compute_composite_region(RegionPtr region,
1228 PicturePtr src, PicturePtr mask, PicturePtr dst,
1229 INT16 src_x, INT16 src_y,
1230 INT16 mask_x, INT16 mask_y,
1231 INT16 dst_x, INT16 dst_y,
1232 CARD16 width, CARD16 height);
1233
1234 void
1235 memcpy_blt(const void *src, void *dst, int bpp,
1236 int32_t src_stride, int32_t dst_stride,
1237 int16_t src_x, int16_t src_y,
1238 int16_t dst_x, int16_t dst_y,
1239 uint16_t width, uint16_t height);
1240
1241 void
1242 affine_blt(const void *src, void *dst, int bpp,
1243 int16_t src_x, int16_t src_y,
1244 int16_t src_width, int16_t src_height,
1245 int32_t src_stride,
1246 int16_t dst_x, int16_t dst_y,
1247 uint16_t dst_width, uint16_t dst_height,
1248 int32_t dst_stride,
1249 const struct pixman_f_transform *t);
1250
1251 void
1252 memmove_box(const void *src, void *dst,
1253 int bpp, int32_t stride,
1254 const BoxRec *box,
1255 int dx, int dy);
1256
1257 void
1258 memcpy_xor(const void *src, void *dst, int bpp,
1259 int32_t src_stride, int32_t dst_stride,
1260 int16_t src_x, int16_t src_y,
1261 int16_t dst_x, int16_t dst_y,
1262 uint16_t width, uint16_t height,
1263 uint32_t and, uint32_t or);
1264
1265 #define SNA_CREATE_FB 0x10
1266 #define SNA_CREATE_SCRATCH 0x11
1267
is_power_of_two(unsigned x)1268 inline static bool is_power_of_two(unsigned x)
1269 {
1270 return (x & (x-1)) == 0;
1271 }
1272
is_clipped(const RegionRec * r,const DrawableRec * d)1273 inline static bool is_clipped(const RegionRec *r,
1274 const DrawableRec *d)
1275 {
1276 DBG(("%s: region[%d]x(%d, %d),(%d, %d) against drawable %dx%d\n",
1277 __FUNCTION__,
1278 region_num_rects(r),
1279 r->extents.x1, r->extents.y1,
1280 r->extents.x2, r->extents.y2,
1281 d->width, d->height));
1282 return (r->data ||
1283 r->extents.x2 - r->extents.x1 != d->width ||
1284 r->extents.y2 - r->extents.y1 != d->height);
1285 }
1286
1287 inline static bool
box_intersect(BoxPtr a,const BoxRec * b)1288 box_intersect(BoxPtr a, const BoxRec *b)
1289 {
1290 if (a->x1 < b->x1)
1291 a->x1 = b->x1;
1292 if (a->x2 > b->x2)
1293 a->x2 = b->x2;
1294 if (a->x1 >= a->x2)
1295 return false;
1296
1297 if (a->y1 < b->y1)
1298 a->y1 = b->y1;
1299 if (a->y2 > b->y2)
1300 a->y2 = b->y2;
1301 if (a->y1 >= a->y2)
1302 return false;
1303
1304 return true;
1305 }
1306
1307 const BoxRec *
1308 __find_clip_box_for_y(const BoxRec *begin, const BoxRec *end, int16_t y);
1309 inline static const BoxRec *
find_clip_box_for_y(const BoxRec * begin,const BoxRec * end,int16_t y)1310 find_clip_box_for_y(const BoxRec *begin, const BoxRec *end, int16_t y)
1311 {
1312 /* Special case for incremental trapezoid clipping */
1313 if (begin == end)
1314 return end;
1315
1316 /* Quick test if scanline is within range of clip boxes */
1317 if (begin->y2 > y) {
1318 assert(end == begin + 1 ||
1319 __find_clip_box_for_y(begin, end, y) == begin);
1320 return begin;
1321 }
1322 if (y >= end[-1].y2) {
1323 assert(end == begin + 1 ||
1324 __find_clip_box_for_y(begin, end, y) == end);
1325 return end;
1326 }
1327
1328 /* Otherwise bisect to find the first box crossing y */
1329 return __find_clip_box_for_y(begin, end, y);
1330 }
1331
1332 unsigned sna_cpu_detect(void);
1333 char *sna_cpu_features_to_string(unsigned features, char *line);
1334
1335 /* sna_acpi.c */
1336 int sna_acpi_open(void);
1337 void sna_acpi_init(struct sna *sna);
1338 void _sna_acpi_wakeup(struct sna *sna);
sna_acpi_wakeup(struct sna * sna,void * read_mask)1339 static inline void sna_acpi_wakeup(struct sna *sna, void *read_mask)
1340 {
1341 if (sna->acpi.fd >= 0 && FD_ISSET(sna->acpi.fd, (fd_set*)read_mask))
1342 _sna_acpi_wakeup(sna);
1343 }
1344 void sna_acpi_fini(struct sna *sna);
1345
1346 void sna_threads_init(void);
1347 int sna_use_threads (int width, int height, int threshold);
1348 void sna_threads_run(int id, void (*func)(void *arg), void *arg);
1349 void sna_threads_trap(int sig);
1350 void sna_threads_wait(void);
1351 void sna_threads_kill(void);
1352
1353 void sna_image_composite(pixman_op_t op,
1354 pixman_image_t *src,
1355 pixman_image_t *mask,
1356 pixman_image_t *dst,
1357 int16_t src_x,
1358 int16_t src_y,
1359 int16_t mask_x,
1360 int16_t mask_y,
1361 int16_t dst_x,
1362 int16_t dst_y,
1363 uint16_t width,
1364 uint16_t height);
1365
1366 extern jmp_buf sigjmp[4];
1367 extern volatile sig_atomic_t sigtrap;
1368
1369 #define sigtrap_assert_inactive() assert(sigtrap == 0)
1370 #define sigtrap_assert_active() assert(sigtrap > 0 && sigtrap <= ARRAY_SIZE(sigjmp))
1371 #define sigtrap_get() sigsetjmp(sigjmp[sigtrap++], 1)
1372
sigtrap_put(void)1373 static inline void sigtrap_put(void)
1374 {
1375 sigtrap_assert_active();
1376 --sigtrap;
1377 }
1378
1379 #define RR_Rotate_All (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270)
1380 #define RR_Reflect_All (RR_Reflect_X | RR_Reflect_Y)
1381
1382 #ifndef HAVE_GETLINE
1383 #include <stdio.h>
1384 extern int getline(char **line, size_t *len, FILE *file);
1385 #endif
1386
add_shm_flush(struct sna * sna,struct sna_pixmap * priv)1387 static inline void add_shm_flush(struct sna *sna, struct sna_pixmap *priv)
1388 {
1389 if (!priv->shm)
1390 return;
1391
1392 DBG(("%s: marking handle=%d for SHM flush\n",
1393 __FUNCTION__, priv->cpu_bo->handle));
1394
1395 assert(!priv->flush);
1396 sna_add_flush_pixmap(sna, priv, priv->cpu_bo);
1397 sna->needs_shm_flush = true;
1398 }
1399
sna_br13_color_depth(int bpp)1400 static inline uint32_t sna_br13_color_depth(int bpp)
1401 {
1402 uint32_t br13 = 0;
1403
1404 switch (bpp) {
1405 default:
1406 assert(0);
1407 /* fall through */
1408 case 32:
1409 br13 |= 1 << 25; /* RGB8888 */
1410 /* fall through */
1411 case 16:
1412 br13 |= 1 << 24; /* RGB565 */
1413 /* fall through */
1414 case 8:
1415 return br13;
1416 }
1417 }
1418
1419 #endif /* _SNA_H */
1420