sna.h revision 63ef14f0
1/************************************************************************** 2 3Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 4Copyright © 2002 David Dawes 5 6All Rights Reserved. 7 8Permission is hereby granted, free of charge, to any person obtaining a 9copy of this software and associated documentation files (the 10"Software"), to deal in the Software without restriction, including 11without limitation the rights to use, copy, modify, merge, publish, 12distribute, sub license, and/or sell copies of the Software, and to 13permit persons to whom the Software is furnished to do so, subject to 14the following conditions: 15 16The above copyright notice and this permission notice (including the 17next paragraph) shall be included in all copies or substantial portions 18of the Software. 19 20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 23IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 24ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 26SOFTWARE 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 106struct sna_cursor; 107struct sna_crtc; 108 109struct sna_client { 110 struct list events; 111 int is_compositor; /* only 4 bits used */ 112}; 113 114extern DevPrivateKeyRec sna_client_key; 115 116pure static inline struct sna_client *sna_client(ClientPtr client) 117{ 118 return __get_private(client, sna_client_key); 119} 120 121struct sna_cow { 122 struct kgem_bo *bo; 123 struct list list; 124 int refcnt; 125}; 126 127struct 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 168struct sna_glyph { 169 PicturePtr atlas; 170 struct sna_coordinate coordinate; 171 uint16_t size, pos; 172 pixman_image_t *image; 173}; 174 175static 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 185static 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 197static 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 204static 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 213extern DevPrivateKeyRec sna_pixmap_key; 214 215pure static inline struct sna_pixmap *sna_pixmap(PixmapPtr pixmap) 216{ 217 return ((void **)__get_private(pixmap, sna_pixmap_key))[1]; 218} 219 220static inline struct sna_pixmap *sna_pixmap_from_drawable(DrawablePtr drawable) 221{ 222 return sna_pixmap(get_drawable_pixmap(drawable)); 223} 224 225struct sna_gc { 226 long changes; 227 long serial; 228 229 const GCFuncs *old_funcs; 230 void *priv; 231}; 232 233static inline struct sna_gc *sna_gc(GCPtr gc) 234{ 235 return (struct sna_gc *)__get_private(gc, sna_gc_key); 236} 237 238enum { 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 248struct 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 459bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna); 460bool sna_mode_fake_init(struct sna *sna, int num_fake); 461bool sna_mode_wants_tear_free(struct sna *sna); 462void sna_mode_adjust_frame(struct sna *sna, int x, int y); 463extern void sna_mode_discover(struct sna *sna, bool tell); 464extern void sna_mode_check(struct sna *sna); 465extern bool sna_mode_disable(struct sna *sna); 466extern void sna_mode_enable(struct sna *sna); 467extern void sna_mode_reset(struct sna *sna); 468extern int sna_mode_wakeup(struct sna *sna); 469extern void sna_mode_redisplay(struct sna *sna); 470extern void sna_shadow_set_crtc(struct sna *sna, xf86CrtcPtr crtc, struct kgem_bo *bo); 471extern void sna_shadow_steal_crtcs(struct sna *sna, struct list *list); 472extern void sna_shadow_unsteal_crtcs(struct sna *sna, struct list *list); 473extern void sna_shadow_unset_crtc(struct sna *sna, xf86CrtcPtr crtc); 474extern bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv, 475 const RegionRec *region); 476extern void sna_mode_set_primary(struct sna *sna); 477extern bool sna_mode_find_hotplug_connector(struct sna *sna, unsigned id); 478extern void sna_mode_close(struct sna *sna); 479extern void sna_mode_fini(struct sna *sna); 480 481extern void sna_crtc_config_notify(ScreenPtr screen); 482 483extern bool sna_cursors_init(ScreenPtr screen, struct sna *sna); 484 485extern CARD32 sna_mode_coldplug(OsTimerPtr timer, CARD32 now, void *data); 486#define COLDPLUG_DELAY_MS 2000 487 488typedef void (*sna_flip_handler_t)(struct drm_event_vblank *e, 489 void *data); 490 491extern bool sna_needs_page_flip(struct sna *sna, struct kgem_bo *bo); 492extern int sna_page_flip(struct sna *sna, 493 struct kgem_bo *bo, 494 sna_flip_handler_t handler, 495 void *data); 496 497pure static inline struct sna * 498to_sna(ScrnInfoPtr scrn) 499{ 500 struct sna *sna = scrn->driverPrivate; 501 assert(sna->scrn == scrn); 502 return sna; 503} 504 505pure static inline struct sna * 506to_sna_from_screen(ScreenPtr screen) 507{ 508 return to_sna(xf86ScreenToScrn(screen)); 509} 510 511pure 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 518pure static inline struct sna * 519to_sna_from_pixmap(PixmapPtr pixmap) 520{ 521 return ((void **)__get_private(pixmap, sna_pixmap_key))[0]; 522} 523 524pure static inline struct sna * 525to_sna_from_drawable(DrawablePtr drawable) 526{ 527 return to_sna_from_screen(drawable->pScreen); 528} 529 530static inline struct sna * 531to_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 552extern xf86CrtcPtr sna_covering_crtc(struct sna *sna, 553 const BoxRec *box, 554 xf86CrtcPtr desired); 555extern xf86CrtcPtr sna_primary_crtc(struct sna *sna); 556 557extern bool sna_wait_for_scanline(struct sna *sna, PixmapPtr pixmap, 558 xf86CrtcPtr crtc, const BoxRec *clip); 559 560const struct ust_msc { 561 uint64_t msc; 562 int tv_sec; 563 int tv_usec; 564} *sna_crtc_last_swap(xf86CrtcPtr crtc); 565 566uint64_t sna_crtc_record_swap(xf86CrtcPtr crtc, 567 int tv_sec, int tv_usec, unsigned seq); 568 569static 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 578static 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 587static inline uint64_t ust64(int tv_sec, int tv_usec) 588{ 589 return (uint64_t)tv_sec * 1000000 + tv_usec; 590} 591 592static 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 598bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen); 599void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event); 600void sna_dri2_vblank_handler(struct drm_event_vblank *event); 601void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo); 602void sna_dri2_decouple_window(WindowPtr win); 603void sna_dri2_destroy_window(WindowPtr win); 604void sna_dri2_close(struct sna *sna, ScreenPtr pScreen); 605#else 606static inline bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen) { return false; } 607static inline void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event) { } 608static inline void sna_dri2_vblank_handler(struct drm_event_vblank *event) { } 609static inline void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo) { } 610static inline void sna_dri2_decouple_window(WindowPtr win) { } 611static inline void sna_dri2_destroy_window(WindowPtr win) { } 612static inline void sna_dri2_close(struct sna *sna, ScreenPtr pScreen) { } 613#endif 614 615#if HAVE_DRI3 616bool sna_dri3_open(struct sna *sna, ScreenPtr pScreen); 617void sna_dri3_close(struct sna *sna, ScreenPtr pScreen); 618#else 619static inline bool sna_dri3_open(struct sna *sna, ScreenPtr pScreen) { return false; } 620static inline void sna_dri3_close(struct sna *sna, ScreenPtr pScreen) { } 621#endif 622 623#if HAVE_PRESENT 624bool sna_present_open(struct sna *sna, ScreenPtr pScreen); 625void sna_present_update(struct sna *sna); 626void sna_present_close(struct sna *sna, ScreenPtr pScreen); 627void sna_present_vblank_handler(struct drm_event_vblank *event); 628void sna_present_cancel_flip(struct sna *sna); 629#else 630static inline bool sna_present_open(struct sna *sna, ScreenPtr pScreen) { return false; } 631static inline void sna_present_update(struct sna *sna) { } 632static inline void sna_present_close(struct sna *sna, ScreenPtr pScreen) { } 633static inline void sna_present_vblank_handler(struct drm_event_vblank *event) { } 634static inline void sna_present_cancel_flip(struct sna *sna) { } 635#endif 636 637extern unsigned sna_crtc_count_sprites(xf86CrtcPtr crtc); 638extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, unsigned idx, uint32_t rotation); 639extern void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc, unsigned idx, int colorspace); 640extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx); 641extern bool sna_crtc_is_transformed(xf86CrtcPtr crtc); 642bool sna_has_sprite_format(struct sna *sna, uint32_t format); 643 644#define CRTC_VBLANK 0x7 645#define CRTC_ON 0x80000000 646 647uint32_t sna_crtc_id(xf86CrtcPtr crtc); 648 649struct sna_crtc_public { 650 unsigned long flags; 651 struct list vblank_queue; 652}; 653 654static 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 661static 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 668static inline unsigned sna_crtc_pipe(xf86CrtcPtr crtc) 669{ 670 return *sna_crtc_flags(crtc) >> 8 & 0xff; 671} 672 673static inline bool sna_crtc_is_on(xf86CrtcPtr crtc) 674{ 675 return *sna_crtc_flags(crtc) & CRTC_ON; 676} 677 678static 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 685static 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 692static inline bool sna_crtc_has_vblank(xf86CrtcPtr crtc) 693{ 694 return *sna_crtc_flags(crtc) & CRTC_VBLANK; 695} 696 697CARD32 sna_format_for_depth(int depth); 698CARD32 sna_render_format_for_depth(int depth); 699 700void sna_debug_flush(struct sna *sna); 701 702static inline bool 703get_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 715static inline bool 716get_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 726static inline int 727get_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 736static inline int 737get_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 746struct sna_pixmap *sna_pixmap_attach_to_bo(PixmapPtr pixmap, struct kgem_bo *bo); 747static 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 754static 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 779PixmapPtr sna_pixmap_create_upload(ScreenPtr screen, 780 int width, int height, int depth, 781 unsigned flags); 782PixmapPtr sna_pixmap_create_unattached(ScreenPtr screen, 783 int width, int height, int depth); 784void 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 792static 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 811bool 812sna_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 826struct sna_pixmap * 827sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int flags); 828 829struct sna_pixmap *sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags); 830static inline struct sna_pixmap * 831sna_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} 837bool must_check _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags); 838static 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} 848bool must_check sna_drawable_move_region_to_cpu(DrawablePtr drawable, 849 RegionPtr region, 850 unsigned flags); 851 852bool must_check sna_drawable_move_to_cpu(DrawablePtr drawable, unsigned flags); 853 854static inline bool must_check 855sna_drawable_move_to_gpu(DrawablePtr drawable, unsigned flags) 856{ 857 return sna_pixmap_move_to_gpu(get_drawable_pixmap(drawable), flags) != NULL; 858} 859 860void sna_add_flush_pixmap(struct sna *sna, 861 struct sna_pixmap *priv, 862 struct kgem_bo *bo); 863 864struct 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 871struct kgem_bo * 872sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box, 873 struct sna_damage ***damage); 874 875inline 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 883inline 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 893static inline bool box_empty(const BoxRec *box) 894{ 895 return box->x2 <= box->x1 || box->y2 <= box->y1; 896} 897 898static inline bool 899box_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 906static inline bool 907box_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 913static inline bool 914whole_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 920static inline bool 921region_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 934static inline bool 935region_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 944static inline bool 945region_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 974static inline bool 975sna_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 981static inline struct kgem_bo *__sna_pixmap_get_bo(PixmapPtr pixmap) 982{ 983 return sna_pixmap(pixmap)->gpu_bo; 984} 985 986static 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 992static 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 1005static inline bool 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 1019static inline void 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 1032static inline void 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 1046void 1047sna_get_transformed_coordinates(int x, int y, 1048 const PictTransform *transform, 1049 float *x_out, float *y_out); 1050 1051void 1052sna_get_transformed_coordinates_3d(int x, int y, 1053 const PictTransform *transform, 1054 float *x_out, float *y_out, float *z_out); 1055 1056bool sna_transform_is_affine(const PictTransform *t); 1057bool sna_transform_is_translation(const PictTransform *t, 1058 pixman_fixed_t *tx, pixman_fixed_t *ty); 1059bool sna_transform_is_integer_translation(const PictTransform *t, 1060 int16_t *tx, int16_t *ty); 1061bool sna_transform_is_imprecise_integer_translation(const PictTransform *t, 1062 int filter, bool precise, 1063 int16_t *tx, int16_t *ty); 1064static inline bool 1065sna_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 1071static inline bool 1072sna_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 1083static inline bool 1084sna_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 1096static inline bool wedged(struct sna *sna) 1097{ 1098 return unlikely(sna->kgem.wedged); 1099} 1100 1101static inline bool can_render(struct sna *sna) 1102{ 1103 return likely(!sna->kgem.wedged && sna->render.prefer_gpu & PREFER_GPU_RENDER); 1104} 1105 1106static 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 1112bool sna_accel_init(ScreenPtr sreen, struct sna *sna); 1113void sna_accel_create(struct sna *sna); 1114void sna_accel_block(struct sna *sna, struct timeval **tv); 1115void sna_accel_flush(struct sna *sna); 1116void sna_accel_enter(struct sna *sna); 1117void sna_accel_leave(struct sna *sna); 1118void sna_accel_close(struct sna *sna); 1119void sna_accel_free(struct sna *sna); 1120 1121void sna_watch_flush(struct sna *sna, int enable); 1122void sna_copy_fbcon(struct sna *sna); 1123 1124bool sna_composite_create(struct sna *sna); 1125void sna_composite_close(struct sna *sna); 1126 1127void 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); 1135void 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); 1144void sna_composite_rectangles(CARD8 op, 1145 PicturePtr dst, 1146 xRenderColor *color, 1147 int num_rects, 1148 xRectangle *rects); 1149void sna_composite_trapezoids(CARD8 op, 1150 PicturePtr src, 1151 PicturePtr dst, 1152 PictFormatPtr maskFormat, 1153 INT16 xSrc, INT16 ySrc, 1154 int ntrap, xTrapezoid *traps); 1155void sna_add_traps(PicturePtr picture, INT16 x, INT16 y, int n, xTrap *t); 1156 1157void 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 1164void 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 1171void 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 1178bool sna_gradients_create(struct sna *sna); 1179void sna_gradients_close(struct sna *sna); 1180 1181bool sna_glyphs_create(struct sna *sna); 1182void 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); 1190void 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); 1196void sna_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph); 1197void sna_glyphs_close(struct sna *sna); 1198 1199void sna_read_boxes(struct sna *sna, PixmapPtr dst, struct kgem_bo *src_bo, 1200 const BoxRec *box, int n); 1201bool 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); 1205bool 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 1211bool sna_replace(struct sna *sna, 1212 PixmapPtr pixmap, 1213 const void *src, int stride); 1214bool sna_replace__xor(struct sna *sna, 1215 PixmapPtr pixmap, 1216 const void *src, int stride, 1217 uint32_t and, uint32_t or); 1218 1219bool 1220sna_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); 1226bool 1227sna_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 1234void 1235memcpy_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 1241void 1242affine_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 1251void 1252memmove_box(const void *src, void *dst, 1253 int bpp, int32_t stride, 1254 const BoxRec *box, 1255 int dx, int dy); 1256 1257void 1258memcpy_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 1268inline static bool is_power_of_two(unsigned x) 1269{ 1270 return (x & (x-1)) == 0; 1271} 1272 1273inline 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 1287inline static bool 1288box_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 1307const BoxRec * 1308__find_clip_box_for_y(const BoxRec *begin, const BoxRec *end, int16_t y); 1309inline static const BoxRec * 1310find_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 1332unsigned sna_cpu_detect(void); 1333char *sna_cpu_features_to_string(unsigned features, char *line); 1334 1335/* sna_acpi.c */ 1336int sna_acpi_open(void); 1337void sna_acpi_init(struct sna *sna); 1338void _sna_acpi_wakeup(struct sna *sna); 1339static inline void sna_acpi_wakeup(struct sna *sna) 1340{ 1341 _sna_acpi_wakeup(sna); 1342} 1343void sna_acpi_fini(struct sna *sna); 1344 1345void sna_threads_init(void); 1346int sna_use_threads (int width, int height, int threshold); 1347void sna_threads_run(int id, void (*func)(void *arg), void *arg); 1348void sna_threads_trap(int sig); 1349void sna_threads_wait(void); 1350void sna_threads_kill(void); 1351 1352void sna_image_composite(pixman_op_t op, 1353 pixman_image_t *src, 1354 pixman_image_t *mask, 1355 pixman_image_t *dst, 1356 int16_t src_x, 1357 int16_t src_y, 1358 int16_t mask_x, 1359 int16_t mask_y, 1360 int16_t dst_x, 1361 int16_t dst_y, 1362 uint16_t width, 1363 uint16_t height); 1364 1365extern jmp_buf sigjmp[4]; 1366extern volatile sig_atomic_t sigtrap; 1367 1368#define sigtrap_assert_inactive() assert(sigtrap == 0) 1369#define sigtrap_assert_active() assert(sigtrap > 0 && sigtrap <= ARRAY_SIZE(sigjmp)) 1370#define sigtrap_get() sigsetjmp(sigjmp[sigtrap++], 1) 1371 1372static inline void sigtrap_put(void) 1373{ 1374 sigtrap_assert_active(); 1375 --sigtrap; 1376} 1377 1378#define RR_Rotate_All (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270) 1379#define RR_Reflect_All (RR_Reflect_X | RR_Reflect_Y) 1380 1381#ifndef HAVE_GETLINE 1382#include <stdio.h> 1383extern int getline(char **line, size_t *len, FILE *file); 1384#endif 1385 1386static inline void add_shm_flush(struct sna *sna, struct sna_pixmap *priv) 1387{ 1388 if (!priv->shm) 1389 return; 1390 1391 DBG(("%s: marking handle=%d for SHM flush\n", 1392 __FUNCTION__, priv->cpu_bo->handle)); 1393 1394 assert(!priv->flush); 1395 sna_add_flush_pixmap(sna, priv, priv->cpu_bo); 1396 sna->needs_shm_flush = true; 1397} 1398 1399#endif /* _SNA_H */ 1400