sna.h revision 13496ba1
11.1.1.5Sjmcneill/************************************************************************** 21.1Sjmcneill 31.1SjmcneillCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 41.1SjmcneillCopyright © 2002 David Dawes 51.1Sjmcneill 61.1SjmcneillAll Rights Reserved. 71.1Sjmcneill 81.1.1.8SskrllPermission is hereby granted, free of charge, to any person obtaining a 91.1.1.8Sskrllcopy of this software and associated documentation files (the 101.1Sjmcneill"Software"), to deal in the Software without restriction, including 111.1Sjmcneillwithout limitation the rights to use, copy, modify, merge, publish, 121.1Sjmcneilldistribute, sub license, and/or sell copies of the Software, and to 131.1Sjmcneillpermit persons to whom the Software is furnished to do so, subject to 141.1.1.8Sskrllthe following conditions: 151.1.1.6Sjmcneill 161.1.1.8SskrllThe above copyright notice and this permission notice (including the 171.1.1.8Sskrllnext paragraph) shall be included in all copies or substantial portions 181.1.1.8Sskrllof the Software. 191.1.1.8Sskrll 201.1SjmcneillTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 211.1.1.8SskrllOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 221.1.1.6SjmcneillMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 231.1.1.8SskrllIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 241.1.1.8SskrllANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 251.1.1.8SskrllTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 261.1.1.8SskrllSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 271.1.1.8Sskrll 281.1.1.8Sskrll**************************************************************************/ 291.1.1.6Sjmcneill 301.1Sjmcneill/* 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 uint8_t shm :1; 158 uint8_t clear :1; 159 uint8_t header :1; 160 uint8_t cpu :1; 161}; 162 163#define IS_STATIC_PTR(ptr) ((uintptr_t)(ptr) & 1) 164#define MAKE_STATIC_PTR(ptr) ((void*)((uintptr_t)(ptr) | 1)) 165 166struct sna_glyph { 167 PicturePtr atlas; 168 struct sna_coordinate coordinate; 169 uint16_t size, pos; 170 pixman_image_t *image; 171}; 172 173static inline WindowPtr get_root_window(ScreenPtr screen) 174{ 175#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,10,0,0,0) 176 return screen->root; 177#else 178 return WindowTable[screen->myNum]; 179#endif 180} 181 182static inline PixmapPtr get_window_pixmap(WindowPtr window) 183{ 184 assert(window); 185 assert(window->drawable.type != DRAWABLE_PIXMAP); 186 return fbGetWindowPixmap(window); 187} 188 189static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable) 190{ 191 assert(drawable); 192 if (drawable->type == DRAWABLE_PIXMAP) 193 return (PixmapPtr)drawable; 194 else 195 return get_window_pixmap((WindowPtr)drawable); 196} 197 198extern DevPrivateKeyRec sna_pixmap_key; 199 200pure static inline struct sna_pixmap *sna_pixmap(PixmapPtr pixmap) 201{ 202 return ((void **)__get_private(pixmap, sna_pixmap_key))[1]; 203} 204 205static inline struct sna_pixmap *sna_pixmap_from_drawable(DrawablePtr drawable) 206{ 207 return sna_pixmap(get_drawable_pixmap(drawable)); 208} 209 210struct sna_gc { 211 long changes; 212 long serial; 213 214 const GCFuncs *old_funcs; 215 void *priv; 216}; 217 218static inline struct sna_gc *sna_gc(GCPtr gc) 219{ 220 return (struct sna_gc *)__get_private(gc, sna_gc_key); 221} 222 223enum { 224 FLUSH_TIMER = 0, 225 THROTTLE_TIMER, 226 EXPIRE_TIMER, 227#if DEBUG_MEMORY 228 DEBUG_MEMORY_TIMER, 229#endif 230 NUM_TIMERS 231}; 232 233struct sna { 234 struct kgem kgem; 235 236 ScrnInfoPtr scrn; 237 struct intel_device *dev; 238 239 unsigned flags; 240#define SNA_IS_SLAVED 0x1 241#define SNA_IS_HOSTED 0x2 242#define SNA_NO_WAIT 0x10 243#define SNA_NO_FLIP 0x20 244#define SNA_NO_VSYNC 0x40 245#define SNA_TRIPLE_BUFFER 0x80 246#define SNA_TEAR_FREE 0x100 247#define SNA_FORCE_SHADOW 0x200 248#define SNA_FLUSH_GTT 0x400 249#define SNA_PERFORMANCE 0x1000 250#define SNA_POWERSAVE 0x2000 251#define SNA_REMOVE_OUTPUTS 0x4000 252#define SNA_HAS_FLIP 0x10000 253#define SNA_HAS_ASYNC_FLIP 0x20000 254#define SNA_LINEAR_FB 0x40000 255#define SNA_REPROBE 0x80000000 256 257 unsigned cpu_features; 258#define MMX 0x1 259#define SSE 0x2 260#define SSE2 0x4 261#define SSE3 0x8 262#define SSSE3 0x10 263#define SSE4_1 0x20 264#define SSE4_2 0x40 265#define AVX 0x80 266#define AVX2 0x100 267 268 unsigned watch_flush; 269 270 struct timeval timer_tv; 271 uint32_t timer_expire[NUM_TIMERS]; 272 uint16_t timer_active; 273 274 int vblank_interval; 275 276 struct list flush_pixmaps; 277 struct list active_pixmaps; 278 279 PixmapPtr front; 280 PixmapPtr freed_pixmap; 281 282 struct sna_mode { 283 DamagePtr shadow_damage; 284 struct kgem_bo *shadow; 285 unsigned front_active; 286 unsigned shadow_active; 287 unsigned flip_active; 288 bool dirty; 289 290 int max_crtc_width, max_crtc_height; 291 RegionRec shadow_region; 292 RegionRec shadow_cancel; 293 struct list shadow_crtc; 294 bool shadow_dirty; 295 296 unsigned num_real_crtc; 297 unsigned num_real_output; 298 unsigned num_real_encoder; 299 unsigned num_fake; 300 unsigned serial; 301 302 uint32_t *encoders; 303 304#if HAVE_UDEV 305 struct udev_monitor *backlight_monitor; 306 pointer backlight_handler; 307#endif 308 309 Bool (*rrGetInfo)(ScreenPtr, Rotation *); 310 } mode; 311 312 struct { 313 struct sna_cursor *cursors; 314 xf86CursorInfoPtr info; 315 CursorPtr ref; 316 317 unsigned serial; 318 uint32_t fg, bg; 319 int size; 320 321 int active; 322 int last_x; 323 int last_y; 324 325 unsigned max_size; 326 bool use_gtt; 327 328 int num_stash; 329 struct sna_cursor *stash; 330 void *scratch; 331 } cursor; 332 333 struct sna_dri2 { 334 bool available; 335 bool open; 336 337#if HAVE_DRI2 338 void *flip_pending; 339 unsigned client_count; 340#endif 341 } dri2; 342 343 struct sna_dri3 { 344 bool available; 345 bool open; 346#if HAVE_DRI3 347 SyncScreenCreateFenceFunc create_fence; 348 struct list pixmaps; 349#endif 350 } dri3; 351 352 struct sna_present { 353 bool available; 354 bool open; 355#if HAVE_PRESENT 356#endif 357 } present; 358 359 struct sna_xv { 360 XvAdaptorPtr adaptors; 361 int num_adaptors; 362 } xv; 363 364 EntityInfoPtr pEnt; 365 const struct intel_device_info *info; 366 367 ScreenBlockHandlerProcPtr BlockHandler; 368 ScreenWakeupHandlerProcPtr WakeupHandler; 369 CloseScreenProcPtr CloseScreen; 370 371 PicturePtr clear; 372 struct { 373 uint32_t fill_bo; 374 uint32_t fill_pixel; 375 uint32_t fill_alu; 376 } blt_state; 377 union { 378 unsigned gt; 379 struct gen2_render_state gen2; 380 struct gen3_render_state gen3; 381 struct gen4_render_state gen4; 382 struct gen5_render_state gen5; 383 struct gen6_render_state gen6; 384 struct gen7_render_state gen7; 385 struct gen8_render_state gen8; 386 } render_state; 387 388 /* Broken-out options. */ 389 OptionInfoPtr Options; 390 391 /* Driver phase/state information */ 392 bool suspended; 393 394#if HAVE_UDEV 395 struct udev_monitor *uevent_monitor; 396 pointer uevent_handler; 397#endif 398 399 struct { 400 int fd; 401 uint8_t offset; 402 uint8_t remain; 403 char event[256]; 404 } acpi; 405 406 struct sna_render render; 407 408#if DEBUG_MEMORY 409 struct { 410 int pixmap_allocs; 411 int pixmap_cached; 412 int cpu_bo_allocs; 413 size_t shadow_pixels_bytes; 414 size_t cpu_bo_bytes; 415 } debug_memory; 416#endif 417}; 418 419bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna); 420bool sna_mode_fake_init(struct sna *sna, int num_fake); 421bool sna_mode_wants_tear_free(struct sna *sna); 422void sna_mode_adjust_frame(struct sna *sna, int x, int y); 423extern void sna_mode_discover(struct sna *sna); 424extern void sna_mode_check(struct sna *sna); 425extern bool sna_mode_disable(struct sna *sna); 426extern void sna_mode_enable(struct sna *sna); 427extern void sna_mode_reset(struct sna *sna); 428extern int sna_mode_wakeup(struct sna *sna); 429extern void sna_mode_redisplay(struct sna *sna); 430extern void sna_shadow_set_crtc(struct sna *sna, xf86CrtcPtr crtc, struct kgem_bo *bo); 431extern void sna_shadow_steal_crtcs(struct sna *sna, struct list *list); 432extern void sna_shadow_unsteal_crtcs(struct sna *sna, struct list *list); 433extern void sna_shadow_unset_crtc(struct sna *sna, xf86CrtcPtr crtc); 434extern bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv, 435 const RegionRec *region); 436extern void sna_mode_set_primary(struct sna *sna); 437extern void sna_mode_close(struct sna *sna); 438extern void sna_mode_fini(struct sna *sna); 439 440extern void sna_crtc_config_notify(ScreenPtr screen); 441 442extern bool sna_cursors_init(ScreenPtr screen, struct sna *sna); 443 444typedef void (*sna_flip_handler_t)(struct drm_event_vblank *e, 445 void *data); 446 447extern int sna_page_flip(struct sna *sna, 448 struct kgem_bo *bo, 449 sna_flip_handler_t handler, 450 void *data); 451 452pure static inline struct sna * 453to_sna(ScrnInfoPtr scrn) 454{ 455 return (struct sna *)(scrn->driverPrivate); 456} 457 458pure static inline struct sna * 459to_sna_from_screen(ScreenPtr screen) 460{ 461 return to_sna(xf86ScreenToScrn(screen)); 462} 463 464pure static inline struct sna * 465to_sna_from_pixmap(PixmapPtr pixmap) 466{ 467 return ((void **)__get_private(pixmap, sna_pixmap_key))[0]; 468} 469 470pure static inline struct sna * 471to_sna_from_drawable(DrawablePtr drawable) 472{ 473 return to_sna_from_screen(drawable->pScreen); 474} 475 476static inline struct sna * 477to_sna_from_kgem(struct kgem *kgem) 478{ 479 return container_of(kgem, struct sna, kgem); 480} 481 482#ifndef ARRAY_SIZE 483#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) 484#endif 485 486#ifndef ALIGN 487#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) 488#endif 489 490#ifndef MIN 491#define MIN(a,b) ((a) <= (b) ? (a) : (b)) 492#endif 493 494#ifndef MAX 495#define MAX(a,b) ((a) >= (b) ? (a) : (b)) 496#endif 497 498extern xf86CrtcPtr sna_covering_crtc(struct sna *sna, 499 const BoxRec *box, 500 xf86CrtcPtr desired); 501 502extern bool sna_wait_for_scanline(struct sna *sna, PixmapPtr pixmap, 503 xf86CrtcPtr crtc, const BoxRec *clip); 504 505xf86CrtcPtr sna_mode_first_crtc(struct sna *sna); 506 507const struct ust_msc { 508 uint64_t msc; 509 int tv_sec; 510 int tv_usec; 511} *sna_crtc_last_swap(xf86CrtcPtr crtc); 512 513uint64_t sna_crtc_record_swap(xf86CrtcPtr crtc, 514 int tv_sec, int tv_usec, unsigned seq); 515 516static inline uint64_t sna_crtc_record_vblank(xf86CrtcPtr crtc, 517 const union drm_wait_vblank *vbl) 518{ 519 return sna_crtc_record_swap(crtc, 520 vbl->reply.tval_sec, 521 vbl->reply.tval_usec, 522 vbl->reply.sequence); 523} 524 525static inline uint64_t sna_crtc_record_event(xf86CrtcPtr crtc, 526 struct drm_event_vblank *event) 527{ 528 return sna_crtc_record_swap(crtc, 529 event->tv_sec, 530 event->tv_usec, 531 event->sequence); 532} 533 534static inline uint64_t ust64(int tv_sec, int tv_usec) 535{ 536 return (uint64_t)tv_sec * 1000000 + tv_usec; 537} 538 539#if HAVE_DRI2 540bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen); 541void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event); 542void sna_dri2_vblank_handler(struct drm_event_vblank *event); 543void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo); 544void sna_dri2_decouple_window(WindowPtr win); 545void sna_dri2_destroy_window(WindowPtr win); 546void sna_dri2_close(struct sna *sna, ScreenPtr pScreen); 547#else 548static inline bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen) { return false; } 549static inline void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event) { } 550static inline void sna_dri2_vblank_handler(struct drm_event_vblank *event) { } 551static inline void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo) { } 552static inline void sna_dri2_decouple_window(WindowPtr win) { } 553static inline void sna_dri2_destroy_window(WindowPtr win) { } 554static inline void sna_dri2_close(struct sna *sna, ScreenPtr pScreen) { } 555#endif 556 557#if HAVE_DRI3 558bool sna_dri3_open(struct sna *sna, ScreenPtr pScreen); 559void sna_dri3_close(struct sna *sna, ScreenPtr pScreen); 560#else 561static inline bool sna_dri3_open(struct sna *sna, ScreenPtr pScreen) { return false; } 562static inline void sna_dri3_close(struct sna *sna, ScreenPtr pScreen) { } 563#endif 564 565#if HAVE_PRESENT 566bool sna_present_open(struct sna *sna, ScreenPtr pScreen); 567void sna_present_update(struct sna *sna); 568void sna_present_close(struct sna *sna, ScreenPtr pScreen); 569void sna_present_vblank_handler(struct drm_event_vblank *event); 570#else 571static inline bool sna_present_open(struct sna *sna, ScreenPtr pScreen) { return false; } 572static inline void sna_present_update(struct sna *sna) { } 573static inline void sna_present_close(struct sna *sna, ScreenPtr pScreen) { } 574static inline void sna_present_vblank_handler(struct drm_event_vblank *event) { } 575#endif 576 577extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation); 578extern int sna_crtc_to_pipe(xf86CrtcPtr crtc); 579extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc); 580extern uint32_t sna_crtc_id(xf86CrtcPtr crtc); 581extern bool sna_crtc_is_on(xf86CrtcPtr crtc); 582extern bool sna_crtc_is_transformed(xf86CrtcPtr crtc); 583 584CARD32 sna_format_for_depth(int depth); 585CARD32 sna_render_format_for_depth(int depth); 586 587void sna_debug_flush(struct sna *sna); 588 589static inline bool 590get_window_deltas(PixmapPtr pixmap, int16_t *x, int16_t *y) 591{ 592#ifdef COMPOSITE 593 *x = -pixmap->screen_x; 594 *y = -pixmap->screen_y; 595 return pixmap->screen_x | pixmap->screen_y; 596#else 597 *x = *y = 0; 598 return false; 599#endif 600} 601 602static inline bool 603get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int16_t *x, int16_t *y) 604{ 605#ifdef COMPOSITE 606 if (drawable->type == DRAWABLE_WINDOW) 607 return get_window_deltas(pixmap, x, y); 608#endif 609 *x = *y = 0; 610 return false; 611} 612 613static inline int 614get_drawable_dx(DrawablePtr drawable) 615{ 616#ifdef COMPOSITE 617 if (drawable->type == DRAWABLE_WINDOW) 618 return -get_drawable_pixmap(drawable)->screen_x; 619#endif 620 return 0; 621} 622 623static inline int 624get_drawable_dy(DrawablePtr drawable) 625{ 626#ifdef COMPOSITE 627 if (drawable->type == DRAWABLE_WINDOW) 628 return -get_drawable_pixmap(drawable)->screen_y; 629#endif 630 return 0; 631} 632 633struct sna_pixmap *sna_pixmap_attach_to_bo(PixmapPtr pixmap, struct kgem_bo *bo); 634static inline bool sna_pixmap_is_scanout(struct sna *sna, PixmapPtr pixmap) 635{ 636 return (pixmap == sna->front && 637 !sna->mode.shadow_active && 638 (sna->flags & SNA_NO_WAIT) == 0); 639} 640 641static inline int sna_max_tile_copy_size(struct sna *sna, struct kgem_bo *src, struct kgem_bo *dst) 642{ 643 int min_object; 644 int max_size; 645 646 max_size = sna->kgem.aperture_high * PAGE_SIZE; 647 max_size -= MAX(kgem_bo_size(src), kgem_bo_size(dst)); 648 if (max_size <= 0) { 649 DBG(("%s: tiles cannot fit into aperture\n", __FUNCTION__)); 650 return 0; 651 } 652 653 if (max_size > sna->kgem.max_copy_tile_size) 654 max_size = sna->kgem.max_copy_tile_size; 655 656 min_object = MIN(kgem_bo_size(src), kgem_bo_size(dst)) / 2; 657 if (max_size > min_object) 658 max_size = min_object; 659 if (max_size <= 4096) 660 max_size = 0; 661 662 DBG(("%s: using max tile size of %d\n", __FUNCTION__, max_size)); 663 return max_size; 664} 665 666PixmapPtr sna_pixmap_create_upload(ScreenPtr screen, 667 int width, int height, int depth, 668 unsigned flags); 669PixmapPtr sna_pixmap_create_unattached(ScreenPtr screen, 670 int width, int height, int depth); 671void sna_pixmap_destroy(PixmapPtr pixmap); 672 673#define assert_pixmap_map(pixmap, priv) do { \ 674 assert(priv->mapped != MAPPED_NONE || pixmap->devPrivate.ptr == PTR(priv->ptr)); \ 675 assert(priv->mapped != MAPPED_CPU || pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map__cpu)); \ 676 assert(priv->mapped != MAPPED_GTT || pixmap->devPrivate.ptr == priv->gpu_bo->map__gtt || pixmap->devPrivate.ptr == priv->gpu_bo->map__wc); \ 677} while (0) 678 679static inline void sna_pixmap_unmap(PixmapPtr pixmap, struct sna_pixmap *priv) 680{ 681 if (priv->mapped == MAPPED_NONE) { 682 assert(pixmap->devPrivate.ptr == PTR(priv->ptr)); 683 return; 684 } 685 686 DBG(("%s: pixmap=%ld dropping %s mapping\n", 687 __FUNCTION__, pixmap->drawable.serialNumber, 688 priv->mapped == MAPPED_CPU ? "cpu" : "gtt")); 689 690 assert_pixmap_map(pixmap, priv); 691 692 pixmap->devPrivate.ptr = PTR(priv->ptr); 693 pixmap->devKind = priv->stride; 694 695 priv->mapped = MAPPED_NONE; 696} 697 698bool 699sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags); 700 701#define MOVE_WRITE 0x1 702#define MOVE_READ 0x2 703#define MOVE_INPLACE_HINT 0x4 704#define MOVE_ASYNC_HINT 0x8 705#define MOVE_SOURCE_HINT 0x10 706#define MOVE_WHOLE_HINT 0x20 707#define __MOVE_FORCE 0x40 708#define __MOVE_DRI 0x80 709#define __MOVE_SCANOUT 0x100 710#define __MOVE_TILED 0x200 711#define __MOVE_PRIME 0x400 712 713struct sna_pixmap * 714sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int flags); 715 716struct sna_pixmap *sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags); 717static inline struct sna_pixmap * 718sna_pixmap_force_to_gpu(PixmapPtr pixmap, unsigned flags) 719{ 720 /* Unlike move-to-gpu, we ignore wedged and always create the GPU bo */ 721 DBG(("%s(pixmap=%ld, flags=%x)\n", __FUNCTION__, pixmap->drawable.serialNumber, flags)); 722 return sna_pixmap_move_to_gpu(pixmap, flags | __MOVE_FORCE); 723} 724bool must_check _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags); 725static inline bool must_check sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags) 726{ 727 if (flags == MOVE_READ) { 728 struct sna_pixmap *priv = sna_pixmap(pixmap); 729 if (priv == NULL) 730 return true; 731 } 732 733 return _sna_pixmap_move_to_cpu(pixmap, flags); 734} 735bool must_check sna_drawable_move_region_to_cpu(DrawablePtr drawable, 736 RegionPtr region, 737 unsigned flags); 738 739bool must_check sna_drawable_move_to_cpu(DrawablePtr drawable, unsigned flags); 740 741static inline bool must_check 742sna_drawable_move_to_gpu(DrawablePtr drawable, unsigned flags) 743{ 744 return sna_pixmap_move_to_gpu(get_drawable_pixmap(drawable), flags) != NULL; 745} 746 747void sna_add_flush_pixmap(struct sna *sna, 748 struct sna_pixmap *priv, 749 struct kgem_bo *bo); 750 751struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling); 752 753#define PREFER_GPU 0x1 754#define FORCE_GPU 0x2 755#define RENDER_GPU 0x4 756#define IGNORE_DAMAGE 0x8 757#define REPLACES 0x10 758struct kgem_bo * 759sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box, 760 struct sna_damage ***damage); 761 762inline static int16_t bound(int16_t a, uint16_t b) 763{ 764 int v = (int)a + (int)b; 765 if (v > MAXSHORT) 766 return MAXSHORT; 767 return v; 768} 769 770inline static int16_t clamp(int16_t a, int16_t b) 771{ 772 int v = (int)a + (int)b; 773 if (v > MAXSHORT) 774 return MAXSHORT; 775 if (v < MINSHORT) 776 return MINSHORT; 777 return v; 778} 779 780static inline bool box_empty(const BoxRec *box) 781{ 782 return box->x2 <= box->x1 || box->y2 <= box->y1; 783} 784 785static inline bool 786box_covers_pixmap(PixmapPtr pixmap, const BoxRec *box) 787{ 788 int w = box->x2 - box->x1; 789 int h = box->y2 - box->y1; 790 return pixmap->drawable.width <= w && pixmap->drawable.height <= h; 791} 792 793static inline bool 794box_inplace(PixmapPtr pixmap, const BoxRec *box) 795{ 796 struct sna *sna = to_sna_from_pixmap(pixmap); 797 return ((int)(box->x2 - box->x1) * (int)(box->y2 - box->y1) * pixmap->drawable.bitsPerPixel >> 12) >= sna->kgem.half_cpu_cache_pages; 798} 799 800static inline bool 801whole_pixmap_inplace(PixmapPtr pixmap) 802{ 803 struct sna *sna = to_sna_from_pixmap(pixmap); 804 return ((int)pixmap->drawable.width * (int)pixmap->drawable.height * pixmap->drawable.bitsPerPixel >> 12) >= sna->kgem.half_cpu_cache_pages; 805} 806 807static inline bool 808region_subsumes_drawable(RegionPtr region, DrawablePtr drawable) 809{ 810 const BoxRec *extents; 811 812 if (region->data) 813 return false; 814 815 extents = RegionExtents(region); 816 return extents->x1 <= 0 && extents->y1 <= 0 && 817 extents->x2 >= drawable->width && 818 extents->y2 >= drawable->height; 819} 820 821static inline bool 822region_subsumes_pixmap(const RegionRec *region, PixmapPtr pixmap) 823{ 824 if (region->data) 825 return false; 826 827 return (region->extents.x2 - region->extents.x1 >= pixmap->drawable.width && 828 region->extents.y2 - region->extents.y1 >= pixmap->drawable.height); 829} 830 831static inline bool 832region_subsumes_damage(const RegionRec *region, struct sna_damage *damage) 833{ 834 const BoxRec *re, *de; 835 836 DBG(("%s?\n", __FUNCTION__)); 837 assert(damage); 838 839 re = ®ion->extents; 840 de = &DAMAGE_PTR(damage)->extents; 841 DBG(("%s: region (%d, %d), (%d, %d), damage (%d, %d), (%d, %d)\n", 842 __FUNCTION__, 843 re->x1, re->y1, re->x2, re->y2, 844 de->x1, de->y1, de->x2, de->y2)); 845 846 if (re->x2 < de->x2 || re->x1 > de->x1 || 847 re->y2 < de->y2 || re->y1 > de->y1) { 848 DBG(("%s: not contained\n", __FUNCTION__)); 849 return false; 850 } 851 852 if (region->data == NULL) { 853 DBG(("%s: singular region contains damage\n", __FUNCTION__)); 854 return true; 855 } 856 857 return pixman_region_contains_rectangle((RegionPtr)region, 858 (BoxPtr)de) == PIXMAN_REGION_IN; 859} 860 861static inline bool 862sna_drawable_is_clear(DrawablePtr d) 863{ 864 struct sna_pixmap *priv = sna_pixmap(get_drawable_pixmap(d)); 865 return priv && priv->clear && priv->clear_color == 0; 866} 867 868static inline struct kgem_bo *__sna_pixmap_get_bo(PixmapPtr pixmap) 869{ 870 return sna_pixmap(pixmap)->gpu_bo; 871} 872 873static inline struct kgem_bo *__sna_drawable_peek_bo(DrawablePtr d) 874{ 875 struct sna_pixmap *priv = sna_pixmap(get_drawable_pixmap(d)); 876 return priv ? priv->gpu_bo : NULL; 877} 878 879static inline struct kgem_bo *sna_pixmap_pin(PixmapPtr pixmap, unsigned flags) 880{ 881 struct sna_pixmap *priv; 882 883 priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ); 884 if (!priv) 885 return NULL; 886 887 priv->pinned |= flags; 888 return priv->gpu_bo; 889} 890 891 892static inline bool 893_sna_transform_point(const PictTransform *transform, 894 int64_t x, int64_t y, int64_t result[3]) 895{ 896 int j; 897 898 for (j = 0; j < 3; j++) 899 result[j] = (transform->matrix[j][0] * x + 900 transform->matrix[j][1] * y + 901 transform->matrix[j][2]); 902 903 return result[2] != 0; 904} 905 906static inline void 907_sna_get_transformed_coordinates(int x, int y, 908 const PictTransform *transform, 909 float *x_out, float *y_out) 910{ 911 912 int64_t result[3]; 913 914 _sna_transform_point(transform, x, y, result); 915 *x_out = result[0] / (double)result[2]; 916 *y_out = result[1] / (double)result[2]; 917} 918 919static inline void 920_sna_get_transformed_scaled(int x, int y, 921 const PictTransform *transform, const float *sf, 922 float *x_out, float *y_out) 923{ 924 *x_out = sf[0] * (transform->matrix[0][0] * x + 925 transform->matrix[0][1] * y + 926 transform->matrix[0][2]); 927 928 *y_out = sf[1] * (transform->matrix[1][0] * x + 929 transform->matrix[1][1] * y + 930 transform->matrix[1][2]); 931} 932 933void 934sna_get_transformed_coordinates(int x, int y, 935 const PictTransform *transform, 936 float *x_out, float *y_out); 937 938void 939sna_get_transformed_coordinates_3d(int x, int y, 940 const PictTransform *transform, 941 float *x_out, float *y_out, float *z_out); 942 943bool sna_transform_is_affine(const PictTransform *t); 944bool sna_transform_is_translation(const PictTransform *t, 945 pixman_fixed_t *tx, pixman_fixed_t *ty); 946bool sna_transform_is_integer_translation(const PictTransform *t, 947 int16_t *tx, int16_t *ty); 948bool sna_transform_is_imprecise_integer_translation(const PictTransform *t, 949 int filter, bool precise, 950 int16_t *tx, int16_t *ty); 951static inline bool 952sna_affine_transform_is_rotation(const PictTransform *t) 953{ 954 assert(sna_transform_is_affine(t)); 955 return t->matrix[0][1] | t->matrix[1][0]; 956} 957 958static inline bool 959sna_transform_equal(const PictTransform *a, const PictTransform *b) 960{ 961 if (a == b) 962 return true; 963 964 if (a == NULL || b == NULL) 965 return false; 966 967 return memcmp(a, b, sizeof(*a)) == 0; 968} 969 970static inline bool 971sna_picture_alphamap_equal(PicturePtr a, PicturePtr b) 972{ 973 if (a->alphaMap != b->alphaMap) 974 return false; 975 976 if (a->alphaMap) 977 return false; 978 979 return (a->alphaOrigin.x == b->alphaOrigin.x && 980 a->alphaOrigin.y == b->alphaOrigin.y); 981} 982 983static inline bool wedged(struct sna *sna) 984{ 985 return unlikely(sna->kgem.wedged); 986} 987 988static inline bool can_render(struct sna *sna) 989{ 990 return likely(!sna->kgem.wedged && sna->render.prefer_gpu & PREFER_GPU_RENDER); 991} 992 993static inline uint32_t pixmap_size(PixmapPtr pixmap) 994{ 995 return (pixmap->drawable.height - 1) * pixmap->devKind + 996 pixmap->drawable.width * pixmap->drawable.bitsPerPixel/8; 997} 998 999bool sna_accel_init(ScreenPtr sreen, struct sna *sna); 1000void sna_accel_create(struct sna *sna); 1001void sna_accel_block_handler(struct sna *sna, struct timeval **tv); 1002void sna_accel_wakeup_handler(struct sna *sna); 1003void sna_accel_watch_flush(struct sna *sna, int enable); 1004void sna_accel_flush(struct sna *sna); 1005void sna_accel_enter(struct sna *sna); 1006void sna_accel_leave(struct sna *sna); 1007void sna_accel_close(struct sna *sna); 1008void sna_accel_free(struct sna *sna); 1009 1010void sna_copy_fbcon(struct sna *sna); 1011 1012bool sna_composite_create(struct sna *sna); 1013void sna_composite_close(struct sna *sna); 1014 1015void sna_composite(CARD8 op, 1016 PicturePtr src, 1017 PicturePtr mask, 1018 PicturePtr dst, 1019 INT16 src_x, INT16 src_y, 1020 INT16 mask_x, INT16 mask_y, 1021 INT16 dst_x, INT16 dst_y, 1022 CARD16 width, CARD16 height); 1023void sna_composite_fb(CARD8 op, 1024 PicturePtr src, 1025 PicturePtr mask, 1026 PicturePtr dst, 1027 RegionPtr region, 1028 INT16 src_x, INT16 src_y, 1029 INT16 mask_x, INT16 mask_y, 1030 INT16 dst_x, INT16 dst_y, 1031 CARD16 width, CARD16 height); 1032void sna_composite_rectangles(CARD8 op, 1033 PicturePtr dst, 1034 xRenderColor *color, 1035 int num_rects, 1036 xRectangle *rects); 1037void sna_composite_trapezoids(CARD8 op, 1038 PicturePtr src, 1039 PicturePtr dst, 1040 PictFormatPtr maskFormat, 1041 INT16 xSrc, INT16 ySrc, 1042 int ntrap, xTrapezoid *traps); 1043void sna_add_traps(PicturePtr picture, INT16 x, INT16 y, int n, xTrap *t); 1044 1045void sna_composite_triangles(CARD8 op, 1046 PicturePtr src, 1047 PicturePtr dst, 1048 PictFormatPtr maskFormat, 1049 INT16 xSrc, INT16 ySrc, 1050 int ntri, xTriangle *tri); 1051 1052void sna_composite_tristrip(CARD8 op, 1053 PicturePtr src, 1054 PicturePtr dst, 1055 PictFormatPtr maskFormat, 1056 INT16 xSrc, INT16 ySrc, 1057 int npoints, xPointFixed *points); 1058 1059void sna_composite_trifan(CARD8 op, 1060 PicturePtr src, 1061 PicturePtr dst, 1062 PictFormatPtr maskFormat, 1063 INT16 xSrc, INT16 ySrc, 1064 int npoints, xPointFixed *points); 1065 1066bool sna_gradients_create(struct sna *sna); 1067void sna_gradients_close(struct sna *sna); 1068 1069bool sna_glyphs_create(struct sna *sna); 1070void sna_glyphs(CARD8 op, 1071 PicturePtr src, 1072 PicturePtr dst, 1073 PictFormatPtr mask, 1074 INT16 xSrc, INT16 ySrc, 1075 int nlist, 1076 GlyphListPtr list, 1077 GlyphPtr *glyphs); 1078void sna_glyphs__shared(CARD8 op, 1079 PicturePtr src, 1080 PicturePtr dst, 1081 PictFormatPtr mask, 1082 INT16 src_x, INT16 src_y, 1083 int nlist, GlyphListPtr list, GlyphPtr *glyphs); 1084void sna_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph); 1085void sna_glyphs_close(struct sna *sna); 1086 1087void sna_read_boxes(struct sna *sna, PixmapPtr dst, struct kgem_bo *src_bo, 1088 const BoxRec *box, int n); 1089bool sna_write_boxes(struct sna *sna, PixmapPtr dst, 1090 struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, 1091 const void *src, int stride, int16_t src_dx, int16_t src_dy, 1092 const BoxRec *box, int n); 1093bool sna_write_boxes__xor(struct sna *sna, PixmapPtr dst, 1094 struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, 1095 const void *src, int stride, int16_t src_dx, int16_t src_dy, 1096 const BoxRec *box, int nbox, 1097 uint32_t and, uint32_t or); 1098 1099bool sna_replace(struct sna *sna, 1100 PixmapPtr pixmap, 1101 const void *src, int stride); 1102bool sna_replace__xor(struct sna *sna, 1103 PixmapPtr pixmap, 1104 const void *src, int stride, 1105 uint32_t and, uint32_t or); 1106 1107bool 1108sna_compute_composite_extents(BoxPtr extents, 1109 PicturePtr src, PicturePtr mask, PicturePtr dst, 1110 INT16 src_x, INT16 src_y, 1111 INT16 mask_x, INT16 mask_y, 1112 INT16 dst_x, INT16 dst_y, 1113 CARD16 width, CARD16 height); 1114bool 1115sna_compute_composite_region(RegionPtr region, 1116 PicturePtr src, PicturePtr mask, PicturePtr dst, 1117 INT16 src_x, INT16 src_y, 1118 INT16 mask_x, INT16 mask_y, 1119 INT16 dst_x, INT16 dst_y, 1120 CARD16 width, CARD16 height); 1121 1122void 1123memcpy_blt(const void *src, void *dst, int bpp, 1124 int32_t src_stride, int32_t dst_stride, 1125 int16_t src_x, int16_t src_y, 1126 int16_t dst_x, int16_t dst_y, 1127 uint16_t width, uint16_t height); 1128 1129void 1130memmove_box(const void *src, void *dst, 1131 int bpp, int32_t stride, 1132 const BoxRec *box, 1133 int dx, int dy); 1134 1135void 1136memcpy_xor(const void *src, void *dst, int bpp, 1137 int32_t src_stride, int32_t dst_stride, 1138 int16_t src_x, int16_t src_y, 1139 int16_t dst_x, int16_t dst_y, 1140 uint16_t width, uint16_t height, 1141 uint32_t and, uint32_t or); 1142 1143#define SNA_CREATE_FB 0x10 1144#define SNA_CREATE_SCRATCH 0x11 1145 1146inline static bool is_power_of_two(unsigned x) 1147{ 1148 return (x & (x-1)) == 0; 1149} 1150 1151inline static bool is_clipped(const RegionRec *r, 1152 const DrawableRec *d) 1153{ 1154 DBG(("%s: region[%d]x(%d, %d),(%d, %d) against drawable %dx%d\n", 1155 __FUNCTION__, 1156 region_num_rects(r), 1157 r->extents.x1, r->extents.y1, 1158 r->extents.x2, r->extents.y2, 1159 d->width, d->height)); 1160 return (r->data || 1161 r->extents.x2 - r->extents.x1 != d->width || 1162 r->extents.y2 - r->extents.y1 != d->height); 1163} 1164 1165inline static bool 1166box_intersect(BoxPtr a, const BoxRec *b) 1167{ 1168 if (a->x1 < b->x1) 1169 a->x1 = b->x1; 1170 if (a->x2 > b->x2) 1171 a->x2 = b->x2; 1172 if (a->x1 >= a->x2) 1173 return false; 1174 1175 if (a->y1 < b->y1) 1176 a->y1 = b->y1; 1177 if (a->y2 > b->y2) 1178 a->y2 = b->y2; 1179 if (a->y1 >= a->y2) 1180 return false; 1181 1182 return true; 1183} 1184 1185unsigned sna_cpu_detect(void); 1186char *sna_cpu_features_to_string(unsigned features, char *line); 1187 1188/* sna_acpi.c */ 1189int sna_acpi_open(void); 1190void sna_acpi_init(struct sna *sna); 1191void _sna_acpi_wakeup(struct sna *sna); 1192static inline void sna_acpi_wakeup(struct sna *sna, void *read_mask) 1193{ 1194 if (sna->acpi.fd >= 0 && FD_ISSET(sna->acpi.fd, (fd_set*)read_mask)) 1195 _sna_acpi_wakeup(sna); 1196} 1197void sna_acpi_fini(struct sna *sna); 1198 1199void sna_threads_init(void); 1200int sna_use_threads (int width, int height, int threshold); 1201void sna_threads_run(int id, void (*func)(void *arg), void *arg); 1202void sna_threads_trap(int sig); 1203void sna_threads_wait(void); 1204void sna_threads_kill(void); 1205 1206void sna_image_composite(pixman_op_t op, 1207 pixman_image_t *src, 1208 pixman_image_t *mask, 1209 pixman_image_t *dst, 1210 int16_t src_x, 1211 int16_t src_y, 1212 int16_t mask_x, 1213 int16_t mask_y, 1214 int16_t dst_x, 1215 int16_t dst_y, 1216 uint16_t width, 1217 uint16_t height); 1218 1219extern jmp_buf sigjmp[4]; 1220extern volatile sig_atomic_t sigtrap; 1221 1222#define sigtrap_assert_inactive() assert(sigtrap == 0) 1223#define sigtrap_assert_active() assert(sigtrap > 0 && sigtrap <= ARRAY_SIZE(sigjmp)) 1224#define sigtrap_get() sigsetjmp(sigjmp[sigtrap++], 1) 1225 1226static inline void sigtrap_put(void) 1227{ 1228 sigtrap_assert_active(); 1229 --sigtrap; 1230} 1231 1232#define RR_Rotate_All (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270) 1233#define RR_Reflect_All (RR_Reflect_X | RR_Reflect_Y) 1234 1235#ifndef HAVE_GETLINE 1236#include <stdio.h> 1237extern int getline(char **line, size_t *len, FILE *file); 1238#endif 1239 1240#endif /* _SNA_H */ 1241