sna.h revision 63ef14f0
103b705cfSriastradh/************************************************************************** 203b705cfSriastradh 303b705cfSriastradhCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 403b705cfSriastradhCopyright © 2002 David Dawes 503b705cfSriastradh 603b705cfSriastradhAll Rights Reserved. 703b705cfSriastradh 803b705cfSriastradhPermission is hereby granted, free of charge, to any person obtaining a 903b705cfSriastradhcopy of this software and associated documentation files (the 1003b705cfSriastradh"Software"), to deal in the Software without restriction, including 1103b705cfSriastradhwithout limitation the rights to use, copy, modify, merge, publish, 1203b705cfSriastradhdistribute, sub license, and/or sell copies of the Software, and to 1303b705cfSriastradhpermit persons to whom the Software is furnished to do so, subject to 1403b705cfSriastradhthe following conditions: 1503b705cfSriastradh 1603b705cfSriastradhThe above copyright notice and this permission notice (including the 1703b705cfSriastradhnext paragraph) shall be included in all copies or substantial portions 1803b705cfSriastradhof the Software. 1903b705cfSriastradh 2003b705cfSriastradhTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2103b705cfSriastradhOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2203b705cfSriastradhMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2303b705cfSriastradhIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 2403b705cfSriastradhANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2503b705cfSriastradhTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2603b705cfSriastradhSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2703b705cfSriastradh 2803b705cfSriastradh**************************************************************************/ 2903b705cfSriastradh 3003b705cfSriastradh/* 3103b705cfSriastradh * Authors: 3203b705cfSriastradh * Keith Whitwell <keith@tungstengraphics.com> 3303b705cfSriastradh * David Dawes <dawes@xfree86.org> 3403b705cfSriastradh * 3503b705cfSriastradh */ 3603b705cfSriastradh 3703b705cfSriastradh#ifndef _SNA_H_ 3803b705cfSriastradh#define _SNA_H_ 3903b705cfSriastradh 4003b705cfSriastradh#include <stdint.h> 4103b705cfSriastradh 4203b705cfSriastradh#include <xorg-server.h> 4342542f5fSchristos#include <xf86str.h> 4403b705cfSriastradh 4503b705cfSriastradh#include <xf86Crtc.h> 4603b705cfSriastradh#if XF86_CRTC_VERSION >= 5 4703b705cfSriastradh#define HAS_PIXMAP_SHARING 1 4803b705cfSriastradh#endif 4903b705cfSriastradh 5003b705cfSriastradh#include <windowstr.h> 5103b705cfSriastradh#include <glyphstr.h> 5203b705cfSriastradh#include <picturestr.h> 5303b705cfSriastradh#include <gcstruct.h> 5403b705cfSriastradh#include <xvdix.h> 5503b705cfSriastradh 5603b705cfSriastradh#include <pciaccess.h> 5703b705cfSriastradh 5803b705cfSriastradh#include <xf86drmMode.h> 5903b705cfSriastradh 6003b705cfSriastradh#include "../compat-api.h" 6103b705cfSriastradh#include <drm.h> 6203b705cfSriastradh#include <i915_drm.h> 6303b705cfSriastradh 6442542f5fSchristos#if HAVE_DRI2 6503b705cfSriastradh#include <dri2.h> 6603b705cfSriastradh#endif 6703b705cfSriastradh 6842542f5fSchristos#if HAVE_DRI3 6942542f5fSchristos#include <misync.h> 7042542f5fSchristos#endif 7142542f5fSchristos 7203b705cfSriastradh#if HAVE_UDEV 7303b705cfSriastradh#include <libudev.h> 7403b705cfSriastradh#endif 7503b705cfSriastradh 7642542f5fSchristos#include <signal.h> 7742542f5fSchristos#include <setjmp.h> 7842542f5fSchristos 7913496ba1Ssnj#include "xassert.h" 8042542f5fSchristos#include "compiler.h" 8113496ba1Ssnj#include "debug.h" 8203b705cfSriastradh 8303b705cfSriastradh#define DEBUG_NO_BLT 0 8403b705cfSriastradh 8503b705cfSriastradh#define DEBUG_FLUSH_BATCH 0 8603b705cfSriastradh 8703b705cfSriastradh#define TEST_ALL 0 8803b705cfSriastradh#define TEST_ACCEL (TEST_ALL || 0) 8903b705cfSriastradh#define TEST_BATCH (TEST_ALL || 0) 9003b705cfSriastradh#define TEST_BLT (TEST_ALL || 0) 9103b705cfSriastradh#define TEST_COMPOSITE (TEST_ALL || 0) 9203b705cfSriastradh#define TEST_DAMAGE (TEST_ALL || 0) 9303b705cfSriastradh#define TEST_GRADIENT (TEST_ALL || 0) 9403b705cfSriastradh#define TEST_GLYPHS (TEST_ALL || 0) 9503b705cfSriastradh#define TEST_IO (TEST_ALL || 0) 9603b705cfSriastradh#define TEST_KGEM (TEST_ALL || 0) 9703b705cfSriastradh#define TEST_RENDER (TEST_ALL || 0) 9803b705cfSriastradh 9903b705cfSriastradh#include "intel_driver.h" 10003b705cfSriastradh#include "intel_list.h" 10103b705cfSriastradh#include "kgem.h" 10203b705cfSriastradh#include "sna_damage.h" 10303b705cfSriastradh#include "sna_render.h" 10403b705cfSriastradh#include "fb/fb.h" 10503b705cfSriastradh 10642542f5fSchristosstruct sna_cursor; 10742542f5fSchristosstruct sna_crtc; 10803b705cfSriastradh 10903b705cfSriastradhstruct sna_client { 11042542f5fSchristos struct list events; 11103b705cfSriastradh int is_compositor; /* only 4 bits used */ 11203b705cfSriastradh}; 11303b705cfSriastradh 11403b705cfSriastradhextern DevPrivateKeyRec sna_client_key; 11503b705cfSriastradh 11603b705cfSriastradhpure static inline struct sna_client *sna_client(ClientPtr client) 11703b705cfSriastradh{ 11803b705cfSriastradh return __get_private(client, sna_client_key); 11903b705cfSriastradh} 12003b705cfSriastradh 12103b705cfSriastradhstruct sna_cow { 12203b705cfSriastradh struct kgem_bo *bo; 12303b705cfSriastradh struct list list; 12403b705cfSriastradh int refcnt; 12503b705cfSriastradh}; 12603b705cfSriastradh 12703b705cfSriastradhstruct sna_pixmap { 12803b705cfSriastradh PixmapPtr pixmap; 12903b705cfSriastradh struct kgem_bo *gpu_bo, *cpu_bo; 13003b705cfSriastradh struct sna_damage *gpu_damage, *cpu_damage; 13103b705cfSriastradh struct sna_cow *cow; 13203b705cfSriastradh void *ptr; 13303b705cfSriastradh#define PTR(ptr) ((void*)((uintptr_t)(ptr) & ~1)) 13403b705cfSriastradh 13542542f5fSchristos bool (*move_to_gpu)(struct sna *, struct sna_pixmap *, unsigned); 13642542f5fSchristos void *move_to_gpu_data; 13742542f5fSchristos 13803b705cfSriastradh struct list flush_list; 13903b705cfSriastradh struct list cow_list; 14003b705cfSriastradh 14103b705cfSriastradh uint32_t stride; 14203b705cfSriastradh uint32_t clear_color; 14303b705cfSriastradh 14403b705cfSriastradh#define SOURCE_BIAS 4 14542542f5fSchristos uint8_t source_count; 14642542f5fSchristos uint8_t pinned :4; 14703b705cfSriastradh#define PIN_SCANOUT 0x1 14842542f5fSchristos#define PIN_DRI2 0x2 14942542f5fSchristos#define PIN_DRI3 0x4 15042542f5fSchristos#define PIN_PRIME 0x8 15103b705cfSriastradh uint8_t create :4; 15242542f5fSchristos uint8_t mapped :2; 15342542f5fSchristos#define MAPPED_NONE 0 15442542f5fSchristos#define MAPPED_GTT 1 15542542f5fSchristos#define MAPPED_CPU 2 15642542f5fSchristos uint8_t flush :2; 15763ef14f0Smrg#define FLUSH_READ 1 15863ef14f0Smrg#define FLUSH_WRITE 2 15903b705cfSriastradh uint8_t shm :1; 16003b705cfSriastradh uint8_t clear :1; 16103b705cfSriastradh uint8_t header :1; 16203b705cfSriastradh uint8_t cpu :1; 16303b705cfSriastradh}; 16403b705cfSriastradh 16542542f5fSchristos#define IS_STATIC_PTR(ptr) ((uintptr_t)(ptr) & 1) 16642542f5fSchristos#define MAKE_STATIC_PTR(ptr) ((void*)((uintptr_t)(ptr) | 1)) 16742542f5fSchristos 16803b705cfSriastradhstruct sna_glyph { 16903b705cfSriastradh PicturePtr atlas; 17003b705cfSriastradh struct sna_coordinate coordinate; 17103b705cfSriastradh uint16_t size, pos; 17203b705cfSriastradh pixman_image_t *image; 17303b705cfSriastradh}; 17403b705cfSriastradh 17503b705cfSriastradhstatic inline WindowPtr get_root_window(ScreenPtr screen) 17603b705cfSriastradh{ 17703b705cfSriastradh#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,10,0,0,0) 17803b705cfSriastradh return screen->root; 17903b705cfSriastradh#else 18003b705cfSriastradh return WindowTable[screen->myNum]; 18103b705cfSriastradh#endif 18203b705cfSriastradh} 18303b705cfSriastradh 18463ef14f0Smrg#if !NDEBUG 18563ef14f0Smrgstatic PixmapPtr check_pixmap(PixmapPtr pixmap) 18663ef14f0Smrg{ 18763ef14f0Smrg if (pixmap != NULL) { 18863ef14f0Smrg assert(pixmap->refcnt >= 1); 18963ef14f0Smrg assert(pixmap->devKind != 0xdeadbeef); 19063ef14f0Smrg } 19163ef14f0Smrg return pixmap; 19263ef14f0Smrg} 19363ef14f0Smrg#else 19463ef14f0Smrg#define check_pixmap(p) p 19563ef14f0Smrg#endif 19663ef14f0Smrg 19703b705cfSriastradhstatic inline PixmapPtr get_window_pixmap(WindowPtr window) 19803b705cfSriastradh{ 19942542f5fSchristos assert(window); 20042542f5fSchristos assert(window->drawable.type != DRAWABLE_PIXMAP); 20163ef14f0Smrg return check_pixmap(fbGetWindowPixmap(window)); 20203b705cfSriastradh} 20303b705cfSriastradh 20403b705cfSriastradhstatic inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable) 20503b705cfSriastradh{ 20642542f5fSchristos assert(drawable); 20703b705cfSriastradh if (drawable->type == DRAWABLE_PIXMAP) 20863ef14f0Smrg return check_pixmap((PixmapPtr)drawable); 20903b705cfSriastradh else 21003b705cfSriastradh return get_window_pixmap((WindowPtr)drawable); 21103b705cfSriastradh} 21203b705cfSriastradh 21303b705cfSriastradhextern DevPrivateKeyRec sna_pixmap_key; 21403b705cfSriastradh 21503b705cfSriastradhpure static inline struct sna_pixmap *sna_pixmap(PixmapPtr pixmap) 21603b705cfSriastradh{ 21703b705cfSriastradh return ((void **)__get_private(pixmap, sna_pixmap_key))[1]; 21803b705cfSriastradh} 21903b705cfSriastradh 22003b705cfSriastradhstatic inline struct sna_pixmap *sna_pixmap_from_drawable(DrawablePtr drawable) 22103b705cfSriastradh{ 22203b705cfSriastradh return sna_pixmap(get_drawable_pixmap(drawable)); 22303b705cfSriastradh} 22403b705cfSriastradh 22503b705cfSriastradhstruct sna_gc { 22603b705cfSriastradh long changes; 22703b705cfSriastradh long serial; 22803b705cfSriastradh 22942542f5fSchristos const GCFuncs *old_funcs; 23003b705cfSriastradh void *priv; 23103b705cfSriastradh}; 23203b705cfSriastradh 23303b705cfSriastradhstatic inline struct sna_gc *sna_gc(GCPtr gc) 23403b705cfSriastradh{ 23503b705cfSriastradh return (struct sna_gc *)__get_private(gc, sna_gc_key); 23603b705cfSriastradh} 23703b705cfSriastradh 23803b705cfSriastradhenum { 23903b705cfSriastradh FLUSH_TIMER = 0, 24003b705cfSriastradh THROTTLE_TIMER, 24103b705cfSriastradh EXPIRE_TIMER, 24203b705cfSriastradh#if DEBUG_MEMORY 24303b705cfSriastradh DEBUG_MEMORY_TIMER, 24403b705cfSriastradh#endif 24503b705cfSriastradh NUM_TIMERS 24603b705cfSriastradh}; 24703b705cfSriastradh 24803b705cfSriastradhstruct sna { 24903b705cfSriastradh struct kgem kgem; 25003b705cfSriastradh 25103b705cfSriastradh ScrnInfoPtr scrn; 25213496ba1Ssnj struct intel_device *dev; 25303b705cfSriastradh 25403b705cfSriastradh unsigned flags; 25542542f5fSchristos#define SNA_IS_SLAVED 0x1 25642542f5fSchristos#define SNA_IS_HOSTED 0x2 25742542f5fSchristos#define SNA_NO_WAIT 0x10 25842542f5fSchristos#define SNA_NO_FLIP 0x20 25942542f5fSchristos#define SNA_NO_VSYNC 0x40 26042542f5fSchristos#define SNA_TRIPLE_BUFFER 0x80 26142542f5fSchristos#define SNA_TEAR_FREE 0x100 26263ef14f0Smrg#define SNA_WANT_TEAR_FREE 0x200 26363ef14f0Smrg#define SNA_FORCE_SHADOW 0x400 26463ef14f0Smrg#define SNA_FLUSH_GTT 0x800 26542542f5fSchristos#define SNA_PERFORMANCE 0x1000 26642542f5fSchristos#define SNA_POWERSAVE 0x2000 26763ef14f0Smrg#define SNA_NO_DPMS 0x4000 26842542f5fSchristos#define SNA_HAS_FLIP 0x10000 26942542f5fSchristos#define SNA_HAS_ASYNC_FLIP 0x20000 27042542f5fSchristos#define SNA_LINEAR_FB 0x40000 27103b705cfSriastradh#define SNA_REPROBE 0x80000000 27203b705cfSriastradh 27303b705cfSriastradh unsigned cpu_features; 27403b705cfSriastradh#define MMX 0x1 27503b705cfSriastradh#define SSE 0x2 27603b705cfSriastradh#define SSE2 0x4 27703b705cfSriastradh#define SSE3 0x8 27803b705cfSriastradh#define SSSE3 0x10 27903b705cfSriastradh#define SSE4_1 0x20 28003b705cfSriastradh#define SSE4_2 0x40 28103b705cfSriastradh#define AVX 0x80 28203b705cfSriastradh#define AVX2 0x100 28303b705cfSriastradh 28463ef14f0Smrg bool ignore_copy_area : 1; 28563ef14f0Smrg 28663ef14f0Smrg unsigned watch_shm_flush; 28763ef14f0Smrg unsigned watch_dri_flush; 28863ef14f0Smrg unsigned damage_event; 28963ef14f0Smrg bool needs_shm_flush; 29063ef14f0Smrg bool needs_dri_flush; 29103b705cfSriastradh 29203b705cfSriastradh struct timeval timer_tv; 29303b705cfSriastradh uint32_t timer_expire[NUM_TIMERS]; 29403b705cfSriastradh uint16_t timer_active; 29503b705cfSriastradh 29603b705cfSriastradh int vblank_interval; 29703b705cfSriastradh 29803b705cfSriastradh struct list flush_pixmaps; 29903b705cfSriastradh struct list active_pixmaps; 30003b705cfSriastradh 30103b705cfSriastradh PixmapPtr front; 30203b705cfSriastradh PixmapPtr freed_pixmap; 30303b705cfSriastradh 30403b705cfSriastradh struct sna_mode { 30503b705cfSriastradh DamagePtr shadow_damage; 30603b705cfSriastradh struct kgem_bo *shadow; 30742542f5fSchristos unsigned front_active; 30842542f5fSchristos unsigned shadow_active; 30963ef14f0Smrg unsigned rr_active; 31042542f5fSchristos unsigned flip_active; 31163ef14f0Smrg unsigned hidden; 31263ef14f0Smrg bool shadow_enabled; 31342542f5fSchristos bool dirty; 31442542f5fSchristos 31563ef14f0Smrg struct drm_event_vblank *shadow_events; 31663ef14f0Smrg int shadow_nevent; 31763ef14f0Smrg int shadow_size; 31863ef14f0Smrg 31942542f5fSchristos int max_crtc_width, max_crtc_height; 32042542f5fSchristos RegionRec shadow_region; 32142542f5fSchristos RegionRec shadow_cancel; 32242542f5fSchristos struct list shadow_crtc; 32342542f5fSchristos bool shadow_dirty; 32442542f5fSchristos 32542542f5fSchristos unsigned num_real_crtc; 32642542f5fSchristos unsigned num_real_output; 32742542f5fSchristos unsigned num_real_encoder; 32842542f5fSchristos unsigned num_fake; 32942542f5fSchristos unsigned serial; 33042542f5fSchristos 33142542f5fSchristos uint32_t *encoders; 33242542f5fSchristos 33342542f5fSchristos#if HAVE_UDEV 33442542f5fSchristos struct udev_monitor *backlight_monitor; 33542542f5fSchristos pointer backlight_handler; 33642542f5fSchristos#endif 33713496ba1Ssnj 33813496ba1Ssnj Bool (*rrGetInfo)(ScreenPtr, Rotation *); 33903b705cfSriastradh } mode; 34003b705cfSriastradh 34142542f5fSchristos struct { 34242542f5fSchristos struct sna_cursor *cursors; 34342542f5fSchristos xf86CursorInfoPtr info; 34442542f5fSchristos CursorPtr ref; 34542542f5fSchristos 34642542f5fSchristos unsigned serial; 34742542f5fSchristos uint32_t fg, bg; 34842542f5fSchristos int size; 34942542f5fSchristos 35063ef14f0Smrg bool disable; 35163ef14f0Smrg bool active; 35242542f5fSchristos int last_x; 35342542f5fSchristos int last_y; 35442542f5fSchristos 35542542f5fSchristos unsigned max_size; 35642542f5fSchristos bool use_gtt; 35742542f5fSchristos 35842542f5fSchristos int num_stash; 35942542f5fSchristos struct sna_cursor *stash; 36042542f5fSchristos void *scratch; 36142542f5fSchristos } cursor; 36242542f5fSchristos 36342542f5fSchristos struct sna_dri2 { 36463ef14f0Smrg bool available : 1; 36563ef14f0Smrg bool enable : 1; 36663ef14f0Smrg bool open : 1; 36742542f5fSchristos 36842542f5fSchristos#if HAVE_DRI2 36903b705cfSriastradh void *flip_pending; 37042542f5fSchristos unsigned client_count; 37142542f5fSchristos#endif 37242542f5fSchristos } dri2; 37342542f5fSchristos 37442542f5fSchristos struct sna_dri3 { 37563ef14f0Smrg bool available :1; 37663ef14f0Smrg bool override : 1; 37763ef14f0Smrg bool enable : 1; 37863ef14f0Smrg bool open :1; 37963ef14f0Smrg 38042542f5fSchristos#if HAVE_DRI3 38142542f5fSchristos SyncScreenCreateFenceFunc create_fence; 38242542f5fSchristos struct list pixmaps; 38342542f5fSchristos#endif 38442542f5fSchristos } dri3; 38542542f5fSchristos 38642542f5fSchristos struct sna_present { 38742542f5fSchristos bool available; 38842542f5fSchristos bool open; 38942542f5fSchristos#if HAVE_PRESENT 39063ef14f0Smrg struct list vblank_queue; 39163ef14f0Smrg uint64_t unflip; 39263ef14f0Smrg void *freed_info; 39342542f5fSchristos#endif 39442542f5fSchristos } present; 39503b705cfSriastradh 39603b705cfSriastradh struct sna_xv { 39703b705cfSriastradh XvAdaptorPtr adaptors; 39803b705cfSriastradh int num_adaptors; 39903b705cfSriastradh } xv; 40003b705cfSriastradh 40103b705cfSriastradh EntityInfoPtr pEnt; 40203b705cfSriastradh const struct intel_device_info *info; 40303b705cfSriastradh 40463ef14f0Smrg#if !HAVE_NOTIFY_FD 40503b705cfSriastradh ScreenBlockHandlerProcPtr BlockHandler; 40603b705cfSriastradh ScreenWakeupHandlerProcPtr WakeupHandler; 40763ef14f0Smrg#endif 40803b705cfSriastradh CloseScreenProcPtr CloseScreen; 40903b705cfSriastradh 41003b705cfSriastradh PicturePtr clear; 41103b705cfSriastradh struct { 41203b705cfSriastradh uint32_t fill_bo; 41303b705cfSriastradh uint32_t fill_pixel; 41403b705cfSriastradh uint32_t fill_alu; 41503b705cfSriastradh } blt_state; 41603b705cfSriastradh union { 41742542f5fSchristos unsigned gt; 41803b705cfSriastradh struct gen2_render_state gen2; 41903b705cfSriastradh struct gen3_render_state gen3; 42003b705cfSriastradh struct gen4_render_state gen4; 42103b705cfSriastradh struct gen5_render_state gen5; 42203b705cfSriastradh struct gen6_render_state gen6; 42303b705cfSriastradh struct gen7_render_state gen7; 42442542f5fSchristos struct gen8_render_state gen8; 42563ef14f0Smrg struct gen9_render_state gen9; 42603b705cfSriastradh } render_state; 42703b705cfSriastradh 42803b705cfSriastradh /* Broken-out options. */ 42903b705cfSriastradh OptionInfoPtr Options; 43003b705cfSriastradh 43103b705cfSriastradh /* Driver phase/state information */ 43203b705cfSriastradh bool suspended; 43303b705cfSriastradh 43403b705cfSriastradh#if HAVE_UDEV 43503b705cfSriastradh struct udev_monitor *uevent_monitor; 43642542f5fSchristos pointer uevent_handler; 43703b705cfSriastradh#endif 43803b705cfSriastradh 43942542f5fSchristos struct { 44042542f5fSchristos int fd; 44142542f5fSchristos uint8_t offset; 44242542f5fSchristos uint8_t remain; 44342542f5fSchristos char event[256]; 44442542f5fSchristos } acpi; 44542542f5fSchristos 44603b705cfSriastradh struct sna_render render; 44703b705cfSriastradh 44803b705cfSriastradh#if DEBUG_MEMORY 44903b705cfSriastradh struct { 45003b705cfSriastradh int pixmap_allocs; 45142542f5fSchristos int pixmap_cached; 45203b705cfSriastradh int cpu_bo_allocs; 45303b705cfSriastradh size_t shadow_pixels_bytes; 45403b705cfSriastradh size_t cpu_bo_bytes; 45503b705cfSriastradh } debug_memory; 45603b705cfSriastradh#endif 45703b705cfSriastradh}; 45803b705cfSriastradh 45903b705cfSriastradhbool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna); 46042542f5fSchristosbool sna_mode_fake_init(struct sna *sna, int num_fake); 46142542f5fSchristosbool sna_mode_wants_tear_free(struct sna *sna); 46203b705cfSriastradhvoid sna_mode_adjust_frame(struct sna *sna, int x, int y); 46363ef14f0Smrgextern void sna_mode_discover(struct sna *sna, bool tell); 46442542f5fSchristosextern void sna_mode_check(struct sna *sna); 46513496ba1Ssnjextern bool sna_mode_disable(struct sna *sna); 46613496ba1Ssnjextern void sna_mode_enable(struct sna *sna); 46742542f5fSchristosextern void sna_mode_reset(struct sna *sna); 46813496ba1Ssnjextern int sna_mode_wakeup(struct sna *sna); 46903b705cfSriastradhextern void sna_mode_redisplay(struct sna *sna); 47042542f5fSchristosextern void sna_shadow_set_crtc(struct sna *sna, xf86CrtcPtr crtc, struct kgem_bo *bo); 47113496ba1Ssnjextern void sna_shadow_steal_crtcs(struct sna *sna, struct list *list); 47213496ba1Ssnjextern void sna_shadow_unsteal_crtcs(struct sna *sna, struct list *list); 47342542f5fSchristosextern void sna_shadow_unset_crtc(struct sna *sna, xf86CrtcPtr crtc); 47442542f5fSchristosextern bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv, 47542542f5fSchristos const RegionRec *region); 47642542f5fSchristosextern void sna_mode_set_primary(struct sna *sna); 47763ef14f0Smrgextern bool sna_mode_find_hotplug_connector(struct sna *sna, unsigned id); 47803b705cfSriastradhextern void sna_mode_close(struct sna *sna); 47903b705cfSriastradhextern void sna_mode_fini(struct sna *sna); 48003b705cfSriastradh 48142542f5fSchristosextern void sna_crtc_config_notify(ScreenPtr screen); 48242542f5fSchristos 48342542f5fSchristosextern bool sna_cursors_init(ScreenPtr screen, struct sna *sna); 48442542f5fSchristos 48563ef14f0Smrgextern CARD32 sna_mode_coldplug(OsTimerPtr timer, CARD32 now, void *data); 48663ef14f0Smrg#define COLDPLUG_DELAY_MS 2000 48763ef14f0Smrg 48813496ba1Ssnjtypedef void (*sna_flip_handler_t)(struct drm_event_vblank *e, 48942542f5fSchristos void *data); 49042542f5fSchristos 49163ef14f0Smrgextern bool sna_needs_page_flip(struct sna *sna, struct kgem_bo *bo); 49203b705cfSriastradhextern int sna_page_flip(struct sna *sna, 49303b705cfSriastradh struct kgem_bo *bo, 49442542f5fSchristos sna_flip_handler_t handler, 49542542f5fSchristos void *data); 49603b705cfSriastradh 49703b705cfSriastradhpure static inline struct sna * 49803b705cfSriastradhto_sna(ScrnInfoPtr scrn) 49903b705cfSriastradh{ 50063ef14f0Smrg struct sna *sna = scrn->driverPrivate; 50163ef14f0Smrg assert(sna->scrn == scrn); 50263ef14f0Smrg return sna; 50303b705cfSriastradh} 50403b705cfSriastradh 50503b705cfSriastradhpure static inline struct sna * 50603b705cfSriastradhto_sna_from_screen(ScreenPtr screen) 50703b705cfSriastradh{ 50803b705cfSriastradh return to_sna(xf86ScreenToScrn(screen)); 50903b705cfSriastradh} 51003b705cfSriastradh 51163ef14f0Smrgpure static inline ScreenPtr to_screen_from_sna(struct sna *sna) 51263ef14f0Smrg{ 51363ef14f0Smrg ScreenPtr screen = xf86ScrnToScreen(sna->scrn); 51463ef14f0Smrg assert(!screen || sna == to_sna_from_screen(screen)); 51563ef14f0Smrg return screen; 51663ef14f0Smrg} 51763ef14f0Smrg 51803b705cfSriastradhpure static inline struct sna * 51903b705cfSriastradhto_sna_from_pixmap(PixmapPtr pixmap) 52003b705cfSriastradh{ 52103b705cfSriastradh return ((void **)__get_private(pixmap, sna_pixmap_key))[0]; 52203b705cfSriastradh} 52303b705cfSriastradh 52403b705cfSriastradhpure static inline struct sna * 52503b705cfSriastradhto_sna_from_drawable(DrawablePtr drawable) 52603b705cfSriastradh{ 52703b705cfSriastradh return to_sna_from_screen(drawable->pScreen); 52803b705cfSriastradh} 52903b705cfSriastradh 53003b705cfSriastradhstatic inline struct sna * 53103b705cfSriastradhto_sna_from_kgem(struct kgem *kgem) 53203b705cfSriastradh{ 53303b705cfSriastradh return container_of(kgem, struct sna, kgem); 53403b705cfSriastradh} 53503b705cfSriastradh 53603b705cfSriastradh#ifndef ARRAY_SIZE 53703b705cfSriastradh#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) 53803b705cfSriastradh#endif 53903b705cfSriastradh 54003b705cfSriastradh#ifndef ALIGN 54103b705cfSriastradh#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) 54203b705cfSriastradh#endif 54303b705cfSriastradh 54403b705cfSriastradh#ifndef MIN 54503b705cfSriastradh#define MIN(a,b) ((a) <= (b) ? (a) : (b)) 54603b705cfSriastradh#endif 54703b705cfSriastradh 54803b705cfSriastradh#ifndef MAX 54903b705cfSriastradh#define MAX(a,b) ((a) >= (b) ? (a) : (b)) 55003b705cfSriastradh#endif 55103b705cfSriastradh 55242542f5fSchristosextern xf86CrtcPtr sna_covering_crtc(struct sna *sna, 55303b705cfSriastradh const BoxRec *box, 55403b705cfSriastradh xf86CrtcPtr desired); 55563ef14f0Smrgextern xf86CrtcPtr sna_primary_crtc(struct sna *sna); 55603b705cfSriastradh 55703b705cfSriastradhextern bool sna_wait_for_scanline(struct sna *sna, PixmapPtr pixmap, 55803b705cfSriastradh xf86CrtcPtr crtc, const BoxRec *clip); 55903b705cfSriastradh 56042542f5fSchristosconst struct ust_msc { 56142542f5fSchristos uint64_t msc; 56242542f5fSchristos int tv_sec; 56342542f5fSchristos int tv_usec; 56442542f5fSchristos} *sna_crtc_last_swap(xf86CrtcPtr crtc); 56542542f5fSchristos 56642542f5fSchristosuint64_t sna_crtc_record_swap(xf86CrtcPtr crtc, 56742542f5fSchristos int tv_sec, int tv_usec, unsigned seq); 56842542f5fSchristos 56942542f5fSchristosstatic inline uint64_t sna_crtc_record_vblank(xf86CrtcPtr crtc, 57042542f5fSchristos const union drm_wait_vblank *vbl) 57142542f5fSchristos{ 57242542f5fSchristos return sna_crtc_record_swap(crtc, 57342542f5fSchristos vbl->reply.tval_sec, 57442542f5fSchristos vbl->reply.tval_usec, 57542542f5fSchristos vbl->reply.sequence); 57642542f5fSchristos} 57742542f5fSchristos 57842542f5fSchristosstatic inline uint64_t sna_crtc_record_event(xf86CrtcPtr crtc, 57942542f5fSchristos struct drm_event_vblank *event) 58042542f5fSchristos{ 58142542f5fSchristos return sna_crtc_record_swap(crtc, 58242542f5fSchristos event->tv_sec, 58342542f5fSchristos event->tv_usec, 58442542f5fSchristos event->sequence); 58542542f5fSchristos} 58642542f5fSchristos 58742542f5fSchristosstatic inline uint64_t ust64(int tv_sec, int tv_usec) 58842542f5fSchristos{ 58942542f5fSchristos return (uint64_t)tv_sec * 1000000 + tv_usec; 59042542f5fSchristos} 59142542f5fSchristos 59263ef14f0Smrgstatic inline uint64_t swap_ust(const struct ust_msc *swap) 59363ef14f0Smrg{ 59463ef14f0Smrg return ust64(swap->tv_sec, swap->tv_usec); 59563ef14f0Smrg} 59663ef14f0Smrg 59742542f5fSchristos#if HAVE_DRI2 59842542f5fSchristosbool sna_dri2_open(struct sna *sna, ScreenPtr pScreen); 59942542f5fSchristosvoid sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event); 60013496ba1Ssnjvoid sna_dri2_vblank_handler(struct drm_event_vblank *event); 60142542f5fSchristosvoid sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo); 60213496ba1Ssnjvoid sna_dri2_decouple_window(WindowPtr win); 60342542f5fSchristosvoid sna_dri2_destroy_window(WindowPtr win); 60442542f5fSchristosvoid sna_dri2_close(struct sna *sna, ScreenPtr pScreen); 60542542f5fSchristos#else 60642542f5fSchristosstatic inline bool sna_dri2_open(struct sna *sna, ScreenPtr pScreen) { return false; } 60742542f5fSchristosstatic inline void sna_dri2_page_flip_handler(struct sna *sna, struct drm_event_vblank *event) { } 60813496ba1Ssnjstatic inline void sna_dri2_vblank_handler(struct drm_event_vblank *event) { } 60942542f5fSchristosstatic inline void sna_dri2_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap, struct kgem_bo *bo) { } 61013496ba1Ssnjstatic inline void sna_dri2_decouple_window(WindowPtr win) { } 61142542f5fSchristosstatic inline void sna_dri2_destroy_window(WindowPtr win) { } 61242542f5fSchristosstatic inline void sna_dri2_close(struct sna *sna, ScreenPtr pScreen) { } 61342542f5fSchristos#endif 61442542f5fSchristos 61542542f5fSchristos#if HAVE_DRI3 61642542f5fSchristosbool sna_dri3_open(struct sna *sna, ScreenPtr pScreen); 61742542f5fSchristosvoid sna_dri3_close(struct sna *sna, ScreenPtr pScreen); 61842542f5fSchristos#else 61942542f5fSchristosstatic inline bool sna_dri3_open(struct sna *sna, ScreenPtr pScreen) { return false; } 62042542f5fSchristosstatic inline void sna_dri3_close(struct sna *sna, ScreenPtr pScreen) { } 62142542f5fSchristos#endif 62242542f5fSchristos 62342542f5fSchristos#if HAVE_PRESENT 62442542f5fSchristosbool sna_present_open(struct sna *sna, ScreenPtr pScreen); 62542542f5fSchristosvoid sna_present_update(struct sna *sna); 62642542f5fSchristosvoid sna_present_close(struct sna *sna, ScreenPtr pScreen); 62713496ba1Ssnjvoid sna_present_vblank_handler(struct drm_event_vblank *event); 62863ef14f0Smrgvoid sna_present_cancel_flip(struct sna *sna); 62903b705cfSriastradh#else 63042542f5fSchristosstatic inline bool sna_present_open(struct sna *sna, ScreenPtr pScreen) { return false; } 63142542f5fSchristosstatic inline void sna_present_update(struct sna *sna) { } 63242542f5fSchristosstatic inline void sna_present_close(struct sna *sna, ScreenPtr pScreen) { } 63313496ba1Ssnjstatic inline void sna_present_vblank_handler(struct drm_event_vblank *event) { } 63463ef14f0Smrgstatic inline void sna_present_cancel_flip(struct sna *sna) { } 63503b705cfSriastradh#endif 63603b705cfSriastradh 63763ef14f0Smrgextern unsigned sna_crtc_count_sprites(xf86CrtcPtr crtc); 63863ef14f0Smrgextern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, unsigned idx, uint32_t rotation); 63963ef14f0Smrgextern void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc, unsigned idx, int colorspace); 64063ef14f0Smrgextern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx); 64142542f5fSchristosextern bool sna_crtc_is_transformed(xf86CrtcPtr crtc); 64263ef14f0Smrgbool sna_has_sprite_format(struct sna *sna, uint32_t format); 64363ef14f0Smrg 64463ef14f0Smrg#define CRTC_VBLANK 0x7 64563ef14f0Smrg#define CRTC_ON 0x80000000 64663ef14f0Smrg 64763ef14f0Smrguint32_t sna_crtc_id(xf86CrtcPtr crtc); 64863ef14f0Smrg 64963ef14f0Smrgstruct sna_crtc_public { 65063ef14f0Smrg unsigned long flags; 65163ef14f0Smrg struct list vblank_queue; 65263ef14f0Smrg}; 65363ef14f0Smrg 65463ef14f0Smrgstatic inline unsigned long *sna_crtc_flags(xf86CrtcPtr crtc) 65563ef14f0Smrg{ 65663ef14f0Smrg struct sna_crtc_public *pub = crtc->driver_private; 65763ef14f0Smrg assert(pub); 65863ef14f0Smrg return &pub->flags; 65963ef14f0Smrg} 66063ef14f0Smrg 66163ef14f0Smrgstatic inline struct list *sna_crtc_vblank_queue(xf86CrtcPtr crtc) 66263ef14f0Smrg{ 66363ef14f0Smrg struct sna_crtc_public *pub = crtc->driver_private; 66463ef14f0Smrg assert(pub); 66563ef14f0Smrg return &pub->vblank_queue; 66663ef14f0Smrg} 66763ef14f0Smrg 66863ef14f0Smrgstatic inline unsigned sna_crtc_pipe(xf86CrtcPtr crtc) 66963ef14f0Smrg{ 67063ef14f0Smrg return *sna_crtc_flags(crtc) >> 8 & 0xff; 67163ef14f0Smrg} 67263ef14f0Smrg 67363ef14f0Smrgstatic inline bool sna_crtc_is_on(xf86CrtcPtr crtc) 67463ef14f0Smrg{ 67563ef14f0Smrg return *sna_crtc_flags(crtc) & CRTC_ON; 67663ef14f0Smrg} 67763ef14f0Smrg 67863ef14f0Smrgstatic inline void sna_crtc_set_vblank(xf86CrtcPtr crtc) 67963ef14f0Smrg{ 68063ef14f0Smrg DBG(("%s: current vblank count: %d\n", __FUNCTION__, *sna_crtc_flags(crtc) & CRTC_VBLANK)); 68163ef14f0Smrg assert((*sna_crtc_flags(crtc) & CRTC_VBLANK) < CRTC_VBLANK); 68263ef14f0Smrg ++*sna_crtc_flags(crtc); 68363ef14f0Smrg} 68463ef14f0Smrg 68563ef14f0Smrgstatic inline void sna_crtc_clear_vblank(xf86CrtcPtr crtc) 68663ef14f0Smrg{ 68763ef14f0Smrg DBG(("%s: current vblank count: %d\n", __FUNCTION__, *sna_crtc_flags(crtc) & CRTC_VBLANK)); 68863ef14f0Smrg assert(*sna_crtc_flags(crtc) & CRTC_VBLANK); 68963ef14f0Smrg --*sna_crtc_flags(crtc); 69063ef14f0Smrg} 69163ef14f0Smrg 69263ef14f0Smrgstatic inline bool sna_crtc_has_vblank(xf86CrtcPtr crtc) 69363ef14f0Smrg{ 69463ef14f0Smrg return *sna_crtc_flags(crtc) & CRTC_VBLANK; 69563ef14f0Smrg} 69603b705cfSriastradh 69703b705cfSriastradhCARD32 sna_format_for_depth(int depth); 69803b705cfSriastradhCARD32 sna_render_format_for_depth(int depth); 69903b705cfSriastradh 70003b705cfSriastradhvoid sna_debug_flush(struct sna *sna); 70103b705cfSriastradh 70242542f5fSchristosstatic inline bool 70342542f5fSchristosget_window_deltas(PixmapPtr pixmap, int16_t *x, int16_t *y) 70442542f5fSchristos{ 70542542f5fSchristos#ifdef COMPOSITE 70642542f5fSchristos *x = -pixmap->screen_x; 70742542f5fSchristos *y = -pixmap->screen_y; 70842542f5fSchristos return pixmap->screen_x | pixmap->screen_y; 70942542f5fSchristos#else 71042542f5fSchristos *x = *y = 0; 71142542f5fSchristos return false; 71242542f5fSchristos#endif 71342542f5fSchristos} 71442542f5fSchristos 71503b705cfSriastradhstatic inline bool 71603b705cfSriastradhget_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int16_t *x, int16_t *y) 71703b705cfSriastradh{ 71803b705cfSriastradh#ifdef COMPOSITE 71942542f5fSchristos if (drawable->type == DRAWABLE_WINDOW) 72042542f5fSchristos return get_window_deltas(pixmap, x, y); 72103b705cfSriastradh#endif 72203b705cfSriastradh *x = *y = 0; 72303b705cfSriastradh return false; 72403b705cfSriastradh} 72503b705cfSriastradh 72603b705cfSriastradhstatic inline int 72703b705cfSriastradhget_drawable_dx(DrawablePtr drawable) 72803b705cfSriastradh{ 72903b705cfSriastradh#ifdef COMPOSITE 73003b705cfSriastradh if (drawable->type == DRAWABLE_WINDOW) 73103b705cfSriastradh return -get_drawable_pixmap(drawable)->screen_x; 73203b705cfSriastradh#endif 73303b705cfSriastradh return 0; 73403b705cfSriastradh} 73503b705cfSriastradh 73603b705cfSriastradhstatic inline int 73703b705cfSriastradhget_drawable_dy(DrawablePtr drawable) 73803b705cfSriastradh{ 73903b705cfSriastradh#ifdef COMPOSITE 74003b705cfSriastradh if (drawable->type == DRAWABLE_WINDOW) 74103b705cfSriastradh return -get_drawable_pixmap(drawable)->screen_y; 74203b705cfSriastradh#endif 74303b705cfSriastradh return 0; 74403b705cfSriastradh} 74503b705cfSriastradh 74642542f5fSchristosstruct sna_pixmap *sna_pixmap_attach_to_bo(PixmapPtr pixmap, struct kgem_bo *bo); 74703b705cfSriastradhstatic inline bool sna_pixmap_is_scanout(struct sna *sna, PixmapPtr pixmap) 74803b705cfSriastradh{ 74903b705cfSriastradh return (pixmap == sna->front && 75003b705cfSriastradh !sna->mode.shadow_active && 75103b705cfSriastradh (sna->flags & SNA_NO_WAIT) == 0); 75203b705cfSriastradh} 75303b705cfSriastradh 75442542f5fSchristosstatic inline int sna_max_tile_copy_size(struct sna *sna, struct kgem_bo *src, struct kgem_bo *dst) 75542542f5fSchristos{ 75642542f5fSchristos int min_object; 75742542f5fSchristos int max_size; 75842542f5fSchristos 75942542f5fSchristos max_size = sna->kgem.aperture_high * PAGE_SIZE; 76042542f5fSchristos max_size -= MAX(kgem_bo_size(src), kgem_bo_size(dst)); 76142542f5fSchristos if (max_size <= 0) { 76242542f5fSchristos DBG(("%s: tiles cannot fit into aperture\n", __FUNCTION__)); 76342542f5fSchristos return 0; 76442542f5fSchristos } 76542542f5fSchristos 76642542f5fSchristos if (max_size > sna->kgem.max_copy_tile_size) 76742542f5fSchristos max_size = sna->kgem.max_copy_tile_size; 76842542f5fSchristos 76942542f5fSchristos min_object = MIN(kgem_bo_size(src), kgem_bo_size(dst)) / 2; 77042542f5fSchristos if (max_size > min_object) 77142542f5fSchristos max_size = min_object; 77242542f5fSchristos if (max_size <= 4096) 77342542f5fSchristos max_size = 0; 77442542f5fSchristos 77542542f5fSchristos DBG(("%s: using max tile size of %d\n", __FUNCTION__, max_size)); 77642542f5fSchristos return max_size; 77742542f5fSchristos} 77842542f5fSchristos 77903b705cfSriastradhPixmapPtr sna_pixmap_create_upload(ScreenPtr screen, 78003b705cfSriastradh int width, int height, int depth, 78103b705cfSriastradh unsigned flags); 78203b705cfSriastradhPixmapPtr sna_pixmap_create_unattached(ScreenPtr screen, 78303b705cfSriastradh int width, int height, int depth); 78403b705cfSriastradhvoid sna_pixmap_destroy(PixmapPtr pixmap); 78503b705cfSriastradh 78642542f5fSchristos#define assert_pixmap_map(pixmap, priv) do { \ 78742542f5fSchristos assert(priv->mapped != MAPPED_NONE || pixmap->devPrivate.ptr == PTR(priv->ptr)); \ 78813496ba1Ssnj assert(priv->mapped != MAPPED_CPU || pixmap->devPrivate.ptr == MAP(priv->gpu_bo->map__cpu)); \ 78913496ba1Ssnj assert(priv->mapped != MAPPED_GTT || pixmap->devPrivate.ptr == priv->gpu_bo->map__gtt || pixmap->devPrivate.ptr == priv->gpu_bo->map__wc); \ 79042542f5fSchristos} while (0) 79142542f5fSchristos 79242542f5fSchristosstatic inline void sna_pixmap_unmap(PixmapPtr pixmap, struct sna_pixmap *priv) 79342542f5fSchristos{ 79442542f5fSchristos if (priv->mapped == MAPPED_NONE) { 79542542f5fSchristos assert(pixmap->devPrivate.ptr == PTR(priv->ptr)); 79642542f5fSchristos return; 79742542f5fSchristos } 79842542f5fSchristos 79942542f5fSchristos DBG(("%s: pixmap=%ld dropping %s mapping\n", 80042542f5fSchristos __FUNCTION__, pixmap->drawable.serialNumber, 80142542f5fSchristos priv->mapped == MAPPED_CPU ? "cpu" : "gtt")); 80242542f5fSchristos 80342542f5fSchristos assert_pixmap_map(pixmap, priv); 80442542f5fSchristos 80542542f5fSchristos pixmap->devPrivate.ptr = PTR(priv->ptr); 80642542f5fSchristos pixmap->devKind = priv->stride; 80742542f5fSchristos 80842542f5fSchristos priv->mapped = MAPPED_NONE; 80942542f5fSchristos} 81042542f5fSchristos 81103b705cfSriastradhbool 81203b705cfSriastradhsna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags); 81303b705cfSriastradh 81403b705cfSriastradh#define MOVE_WRITE 0x1 81503b705cfSriastradh#define MOVE_READ 0x2 81603b705cfSriastradh#define MOVE_INPLACE_HINT 0x4 81703b705cfSriastradh#define MOVE_ASYNC_HINT 0x8 81803b705cfSriastradh#define MOVE_SOURCE_HINT 0x10 81903b705cfSriastradh#define MOVE_WHOLE_HINT 0x20 82003b705cfSriastradh#define __MOVE_FORCE 0x40 82103b705cfSriastradh#define __MOVE_DRI 0x80 82242542f5fSchristos#define __MOVE_SCANOUT 0x100 82342542f5fSchristos#define __MOVE_TILED 0x200 82413496ba1Ssnj#define __MOVE_PRIME 0x400 82503b705cfSriastradh 82642542f5fSchristosstruct sna_pixmap * 82703b705cfSriastradhsna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int flags); 82803b705cfSriastradh 82903b705cfSriastradhstruct sna_pixmap *sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags); 83003b705cfSriastradhstatic inline struct sna_pixmap * 83103b705cfSriastradhsna_pixmap_force_to_gpu(PixmapPtr pixmap, unsigned flags) 83203b705cfSriastradh{ 83303b705cfSriastradh /* Unlike move-to-gpu, we ignore wedged and always create the GPU bo */ 83442542f5fSchristos DBG(("%s(pixmap=%ld, flags=%x)\n", __FUNCTION__, pixmap->drawable.serialNumber, flags)); 83503b705cfSriastradh return sna_pixmap_move_to_gpu(pixmap, flags | __MOVE_FORCE); 83603b705cfSriastradh} 83703b705cfSriastradhbool must_check _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags); 83803b705cfSriastradhstatic inline bool must_check sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags) 83903b705cfSriastradh{ 84003b705cfSriastradh if (flags == MOVE_READ) { 84103b705cfSriastradh struct sna_pixmap *priv = sna_pixmap(pixmap); 84203b705cfSriastradh if (priv == NULL) 84303b705cfSriastradh return true; 84403b705cfSriastradh } 84503b705cfSriastradh 84603b705cfSriastradh return _sna_pixmap_move_to_cpu(pixmap, flags); 84703b705cfSriastradh} 84803b705cfSriastradhbool must_check sna_drawable_move_region_to_cpu(DrawablePtr drawable, 84903b705cfSriastradh RegionPtr region, 85003b705cfSriastradh unsigned flags); 85103b705cfSriastradh 85203b705cfSriastradhbool must_check sna_drawable_move_to_cpu(DrawablePtr drawable, unsigned flags); 85303b705cfSriastradh 85403b705cfSriastradhstatic inline bool must_check 85503b705cfSriastradhsna_drawable_move_to_gpu(DrawablePtr drawable, unsigned flags) 85603b705cfSriastradh{ 85703b705cfSriastradh return sna_pixmap_move_to_gpu(get_drawable_pixmap(drawable), flags) != NULL; 85803b705cfSriastradh} 85903b705cfSriastradh 86003b705cfSriastradhvoid sna_add_flush_pixmap(struct sna *sna, 86103b705cfSriastradh struct sna_pixmap *priv, 86203b705cfSriastradh struct kgem_bo *bo); 86303b705cfSriastradh 86403b705cfSriastradhstruct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling); 86503b705cfSriastradh 86603b705cfSriastradh#define PREFER_GPU 0x1 86703b705cfSriastradh#define FORCE_GPU 0x2 86803b705cfSriastradh#define RENDER_GPU 0x4 86942542f5fSchristos#define IGNORE_DAMAGE 0x8 87003b705cfSriastradh#define REPLACES 0x10 87103b705cfSriastradhstruct kgem_bo * 87203b705cfSriastradhsna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box, 87303b705cfSriastradh struct sna_damage ***damage); 87403b705cfSriastradh 87503b705cfSriastradhinline static int16_t bound(int16_t a, uint16_t b) 87603b705cfSriastradh{ 87703b705cfSriastradh int v = (int)a + (int)b; 87803b705cfSriastradh if (v > MAXSHORT) 87903b705cfSriastradh return MAXSHORT; 88003b705cfSriastradh return v; 88103b705cfSriastradh} 88203b705cfSriastradh 88303b705cfSriastradhinline static int16_t clamp(int16_t a, int16_t b) 88403b705cfSriastradh{ 88503b705cfSriastradh int v = (int)a + (int)b; 88603b705cfSriastradh if (v > MAXSHORT) 88703b705cfSriastradh return MAXSHORT; 88803b705cfSriastradh if (v < MINSHORT) 88903b705cfSriastradh return MINSHORT; 89003b705cfSriastradh return v; 89103b705cfSriastradh} 89203b705cfSriastradh 89303b705cfSriastradhstatic inline bool box_empty(const BoxRec *box) 89403b705cfSriastradh{ 89503b705cfSriastradh return box->x2 <= box->x1 || box->y2 <= box->y1; 89603b705cfSriastradh} 89703b705cfSriastradh 89842542f5fSchristosstatic inline bool 89942542f5fSchristosbox_covers_pixmap(PixmapPtr pixmap, const BoxRec *box) 90042542f5fSchristos{ 90142542f5fSchristos int w = box->x2 - box->x1; 90242542f5fSchristos int h = box->y2 - box->y1; 90342542f5fSchristos return pixmap->drawable.width <= w && pixmap->drawable.height <= h; 90442542f5fSchristos} 90542542f5fSchristos 90603b705cfSriastradhstatic inline bool 90703b705cfSriastradhbox_inplace(PixmapPtr pixmap, const BoxRec *box) 90803b705cfSriastradh{ 90903b705cfSriastradh struct sna *sna = to_sna_from_pixmap(pixmap); 91003b705cfSriastradh return ((int)(box->x2 - box->x1) * (int)(box->y2 - box->y1) * pixmap->drawable.bitsPerPixel >> 12) >= sna->kgem.half_cpu_cache_pages; 91103b705cfSriastradh} 91203b705cfSriastradh 91342542f5fSchristosstatic inline bool 91442542f5fSchristoswhole_pixmap_inplace(PixmapPtr pixmap) 91542542f5fSchristos{ 91642542f5fSchristos struct sna *sna = to_sna_from_pixmap(pixmap); 91742542f5fSchristos return ((int)pixmap->drawable.width * (int)pixmap->drawable.height * pixmap->drawable.bitsPerPixel >> 12) >= sna->kgem.half_cpu_cache_pages; 91842542f5fSchristos} 91942542f5fSchristos 92003b705cfSriastradhstatic inline bool 92103b705cfSriastradhregion_subsumes_drawable(RegionPtr region, DrawablePtr drawable) 92203b705cfSriastradh{ 92303b705cfSriastradh const BoxRec *extents; 92403b705cfSriastradh 92503b705cfSriastradh if (region->data) 92603b705cfSriastradh return false; 92703b705cfSriastradh 92803b705cfSriastradh extents = RegionExtents(region); 92903b705cfSriastradh return extents->x1 <= 0 && extents->y1 <= 0 && 93003b705cfSriastradh extents->x2 >= drawable->width && 93103b705cfSriastradh extents->y2 >= drawable->height; 93203b705cfSriastradh} 93303b705cfSriastradh 93442542f5fSchristosstatic inline bool 93542542f5fSchristosregion_subsumes_pixmap(const RegionRec *region, PixmapPtr pixmap) 93642542f5fSchristos{ 93742542f5fSchristos if (region->data) 93842542f5fSchristos return false; 93942542f5fSchristos 94042542f5fSchristos return (region->extents.x2 - region->extents.x1 >= pixmap->drawable.width && 94142542f5fSchristos region->extents.y2 - region->extents.y1 >= pixmap->drawable.height); 94242542f5fSchristos} 94342542f5fSchristos 94403b705cfSriastradhstatic inline bool 94503b705cfSriastradhregion_subsumes_damage(const RegionRec *region, struct sna_damage *damage) 94603b705cfSriastradh{ 94703b705cfSriastradh const BoxRec *re, *de; 94803b705cfSriastradh 94903b705cfSriastradh DBG(("%s?\n", __FUNCTION__)); 95003b705cfSriastradh assert(damage); 95103b705cfSriastradh 95203b705cfSriastradh re = ®ion->extents; 95303b705cfSriastradh de = &DAMAGE_PTR(damage)->extents; 95403b705cfSriastradh DBG(("%s: region (%d, %d), (%d, %d), damage (%d, %d), (%d, %d)\n", 95503b705cfSriastradh __FUNCTION__, 95603b705cfSriastradh re->x1, re->y1, re->x2, re->y2, 95703b705cfSriastradh de->x1, de->y1, de->x2, de->y2)); 95803b705cfSriastradh 95903b705cfSriastradh if (re->x2 < de->x2 || re->x1 > de->x1 || 96003b705cfSriastradh re->y2 < de->y2 || re->y1 > de->y1) { 96103b705cfSriastradh DBG(("%s: not contained\n", __FUNCTION__)); 96203b705cfSriastradh return false; 96303b705cfSriastradh } 96403b705cfSriastradh 96503b705cfSriastradh if (region->data == NULL) { 96603b705cfSriastradh DBG(("%s: singular region contains damage\n", __FUNCTION__)); 96703b705cfSriastradh return true; 96803b705cfSriastradh } 96903b705cfSriastradh 97003b705cfSriastradh return pixman_region_contains_rectangle((RegionPtr)region, 97103b705cfSriastradh (BoxPtr)de) == PIXMAN_REGION_IN; 97203b705cfSriastradh} 97303b705cfSriastradh 97403b705cfSriastradhstatic inline bool 97503b705cfSriastradhsna_drawable_is_clear(DrawablePtr d) 97603b705cfSriastradh{ 97703b705cfSriastradh struct sna_pixmap *priv = sna_pixmap(get_drawable_pixmap(d)); 97803b705cfSriastradh return priv && priv->clear && priv->clear_color == 0; 97903b705cfSriastradh} 98003b705cfSriastradh 98103b705cfSriastradhstatic inline struct kgem_bo *__sna_pixmap_get_bo(PixmapPtr pixmap) 98203b705cfSriastradh{ 98303b705cfSriastradh return sna_pixmap(pixmap)->gpu_bo; 98403b705cfSriastradh} 98503b705cfSriastradh 98603b705cfSriastradhstatic inline struct kgem_bo *__sna_drawable_peek_bo(DrawablePtr d) 98703b705cfSriastradh{ 98842542f5fSchristos struct sna_pixmap *priv = sna_pixmap(get_drawable_pixmap(d)); 98942542f5fSchristos return priv ? priv->gpu_bo : NULL; 99003b705cfSriastradh} 99103b705cfSriastradh 99203b705cfSriastradhstatic inline struct kgem_bo *sna_pixmap_pin(PixmapPtr pixmap, unsigned flags) 99303b705cfSriastradh{ 99403b705cfSriastradh struct sna_pixmap *priv; 99503b705cfSriastradh 99642542f5fSchristos priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ); 99703b705cfSriastradh if (!priv) 99803b705cfSriastradh return NULL; 99903b705cfSriastradh 100003b705cfSriastradh priv->pinned |= flags; 100103b705cfSriastradh return priv->gpu_bo; 100203b705cfSriastradh} 100303b705cfSriastradh 100403b705cfSriastradh 100503b705cfSriastradhstatic inline bool 100603b705cfSriastradh_sna_transform_point(const PictTransform *transform, 100703b705cfSriastradh int64_t x, int64_t y, int64_t result[3]) 100803b705cfSriastradh{ 100903b705cfSriastradh int j; 101003b705cfSriastradh 101103b705cfSriastradh for (j = 0; j < 3; j++) 101203b705cfSriastradh result[j] = (transform->matrix[j][0] * x + 101303b705cfSriastradh transform->matrix[j][1] * y + 101403b705cfSriastradh transform->matrix[j][2]); 101503b705cfSriastradh 101603b705cfSriastradh return result[2] != 0; 101703b705cfSriastradh} 101803b705cfSriastradh 101903b705cfSriastradhstatic inline void 102003b705cfSriastradh_sna_get_transformed_coordinates(int x, int y, 102103b705cfSriastradh const PictTransform *transform, 102203b705cfSriastradh float *x_out, float *y_out) 102303b705cfSriastradh{ 102403b705cfSriastradh 102503b705cfSriastradh int64_t result[3]; 102603b705cfSriastradh 102703b705cfSriastradh _sna_transform_point(transform, x, y, result); 102803b705cfSriastradh *x_out = result[0] / (double)result[2]; 102903b705cfSriastradh *y_out = result[1] / (double)result[2]; 103003b705cfSriastradh} 103103b705cfSriastradh 103203b705cfSriastradhstatic inline void 103303b705cfSriastradh_sna_get_transformed_scaled(int x, int y, 103403b705cfSriastradh const PictTransform *transform, const float *sf, 103503b705cfSriastradh float *x_out, float *y_out) 103603b705cfSriastradh{ 103703b705cfSriastradh *x_out = sf[0] * (transform->matrix[0][0] * x + 103803b705cfSriastradh transform->matrix[0][1] * y + 103903b705cfSriastradh transform->matrix[0][2]); 104003b705cfSriastradh 104103b705cfSriastradh *y_out = sf[1] * (transform->matrix[1][0] * x + 104203b705cfSriastradh transform->matrix[1][1] * y + 104303b705cfSriastradh transform->matrix[1][2]); 104403b705cfSriastradh} 104503b705cfSriastradh 104603b705cfSriastradhvoid 104703b705cfSriastradhsna_get_transformed_coordinates(int x, int y, 104803b705cfSriastradh const PictTransform *transform, 104903b705cfSriastradh float *x_out, float *y_out); 105003b705cfSriastradh 105103b705cfSriastradhvoid 105203b705cfSriastradhsna_get_transformed_coordinates_3d(int x, int y, 105303b705cfSriastradh const PictTransform *transform, 105403b705cfSriastradh float *x_out, float *y_out, float *z_out); 105503b705cfSriastradh 105603b705cfSriastradhbool sna_transform_is_affine(const PictTransform *t); 105703b705cfSriastradhbool sna_transform_is_translation(const PictTransform *t, 105803b705cfSriastradh pixman_fixed_t *tx, pixman_fixed_t *ty); 105942542f5fSchristosbool sna_transform_is_integer_translation(const PictTransform *t, 106042542f5fSchristos int16_t *tx, int16_t *ty); 106142542f5fSchristosbool sna_transform_is_imprecise_integer_translation(const PictTransform *t, 106242542f5fSchristos int filter, bool precise, 106342542f5fSchristos int16_t *tx, int16_t *ty); 106403b705cfSriastradhstatic inline bool 106503b705cfSriastradhsna_affine_transform_is_rotation(const PictTransform *t) 106603b705cfSriastradh{ 106703b705cfSriastradh assert(sna_transform_is_affine(t)); 106803b705cfSriastradh return t->matrix[0][1] | t->matrix[1][0]; 106903b705cfSriastradh} 107003b705cfSriastradh 107103b705cfSriastradhstatic inline bool 107203b705cfSriastradhsna_transform_equal(const PictTransform *a, const PictTransform *b) 107303b705cfSriastradh{ 107403b705cfSriastradh if (a == b) 107503b705cfSriastradh return true; 107603b705cfSriastradh 107703b705cfSriastradh if (a == NULL || b == NULL) 107803b705cfSriastradh return false; 107903b705cfSriastradh 108003b705cfSriastradh return memcmp(a, b, sizeof(*a)) == 0; 108103b705cfSriastradh} 108203b705cfSriastradh 108303b705cfSriastradhstatic inline bool 108403b705cfSriastradhsna_picture_alphamap_equal(PicturePtr a, PicturePtr b) 108503b705cfSriastradh{ 108603b705cfSriastradh if (a->alphaMap != b->alphaMap) 108703b705cfSriastradh return false; 108803b705cfSriastradh 108903b705cfSriastradh if (a->alphaMap) 109003b705cfSriastradh return false; 109103b705cfSriastradh 109203b705cfSriastradh return (a->alphaOrigin.x == b->alphaOrigin.x && 109303b705cfSriastradh a->alphaOrigin.y == b->alphaOrigin.y); 109403b705cfSriastradh} 109503b705cfSriastradh 109603b705cfSriastradhstatic inline bool wedged(struct sna *sna) 109703b705cfSriastradh{ 109803b705cfSriastradh return unlikely(sna->kgem.wedged); 109903b705cfSriastradh} 110003b705cfSriastradh 110103b705cfSriastradhstatic inline bool can_render(struct sna *sna) 110203b705cfSriastradh{ 110303b705cfSriastradh return likely(!sna->kgem.wedged && sna->render.prefer_gpu & PREFER_GPU_RENDER); 110403b705cfSriastradh} 110503b705cfSriastradh 110603b705cfSriastradhstatic inline uint32_t pixmap_size(PixmapPtr pixmap) 110703b705cfSriastradh{ 110803b705cfSriastradh return (pixmap->drawable.height - 1) * pixmap->devKind + 110903b705cfSriastradh pixmap->drawable.width * pixmap->drawable.bitsPerPixel/8; 111003b705cfSriastradh} 111103b705cfSriastradh 111203b705cfSriastradhbool sna_accel_init(ScreenPtr sreen, struct sna *sna); 111303b705cfSriastradhvoid sna_accel_create(struct sna *sna); 111463ef14f0Smrgvoid sna_accel_block(struct sna *sna, struct timeval **tv); 111542542f5fSchristosvoid sna_accel_flush(struct sna *sna); 111642542f5fSchristosvoid sna_accel_enter(struct sna *sna); 111742542f5fSchristosvoid sna_accel_leave(struct sna *sna); 111803b705cfSriastradhvoid sna_accel_close(struct sna *sna); 111903b705cfSriastradhvoid sna_accel_free(struct sna *sna); 112003b705cfSriastradh 112163ef14f0Smrgvoid sna_watch_flush(struct sna *sna, int enable); 112203b705cfSriastradhvoid sna_copy_fbcon(struct sna *sna); 112303b705cfSriastradh 112403b705cfSriastradhbool sna_composite_create(struct sna *sna); 112503b705cfSriastradhvoid sna_composite_close(struct sna *sna); 112603b705cfSriastradh 112703b705cfSriastradhvoid sna_composite(CARD8 op, 112803b705cfSriastradh PicturePtr src, 112903b705cfSriastradh PicturePtr mask, 113003b705cfSriastradh PicturePtr dst, 113103b705cfSriastradh INT16 src_x, INT16 src_y, 113203b705cfSriastradh INT16 mask_x, INT16 mask_y, 113303b705cfSriastradh INT16 dst_x, INT16 dst_y, 113403b705cfSriastradh CARD16 width, CARD16 height); 113503b705cfSriastradhvoid sna_composite_fb(CARD8 op, 113603b705cfSriastradh PicturePtr src, 113703b705cfSriastradh PicturePtr mask, 113803b705cfSriastradh PicturePtr dst, 113903b705cfSriastradh RegionPtr region, 114003b705cfSriastradh INT16 src_x, INT16 src_y, 114103b705cfSriastradh INT16 mask_x, INT16 mask_y, 114203b705cfSriastradh INT16 dst_x, INT16 dst_y, 114303b705cfSriastradh CARD16 width, CARD16 height); 114403b705cfSriastradhvoid sna_composite_rectangles(CARD8 op, 114503b705cfSriastradh PicturePtr dst, 114603b705cfSriastradh xRenderColor *color, 114703b705cfSriastradh int num_rects, 114803b705cfSriastradh xRectangle *rects); 114903b705cfSriastradhvoid sna_composite_trapezoids(CARD8 op, 115003b705cfSriastradh PicturePtr src, 115103b705cfSriastradh PicturePtr dst, 115203b705cfSriastradh PictFormatPtr maskFormat, 115303b705cfSriastradh INT16 xSrc, INT16 ySrc, 115403b705cfSriastradh int ntrap, xTrapezoid *traps); 115503b705cfSriastradhvoid sna_add_traps(PicturePtr picture, INT16 x, INT16 y, int n, xTrap *t); 115603b705cfSriastradh 115703b705cfSriastradhvoid sna_composite_triangles(CARD8 op, 115803b705cfSriastradh PicturePtr src, 115903b705cfSriastradh PicturePtr dst, 116003b705cfSriastradh PictFormatPtr maskFormat, 116103b705cfSriastradh INT16 xSrc, INT16 ySrc, 116203b705cfSriastradh int ntri, xTriangle *tri); 116303b705cfSriastradh 116403b705cfSriastradhvoid sna_composite_tristrip(CARD8 op, 116503b705cfSriastradh PicturePtr src, 116603b705cfSriastradh PicturePtr dst, 116703b705cfSriastradh PictFormatPtr maskFormat, 116803b705cfSriastradh INT16 xSrc, INT16 ySrc, 116903b705cfSriastradh int npoints, xPointFixed *points); 117003b705cfSriastradh 117103b705cfSriastradhvoid sna_composite_trifan(CARD8 op, 117203b705cfSriastradh PicturePtr src, 117303b705cfSriastradh PicturePtr dst, 117403b705cfSriastradh PictFormatPtr maskFormat, 117503b705cfSriastradh INT16 xSrc, INT16 ySrc, 117603b705cfSriastradh int npoints, xPointFixed *points); 117703b705cfSriastradh 117803b705cfSriastradhbool sna_gradients_create(struct sna *sna); 117903b705cfSriastradhvoid sna_gradients_close(struct sna *sna); 118003b705cfSriastradh 118103b705cfSriastradhbool sna_glyphs_create(struct sna *sna); 118203b705cfSriastradhvoid sna_glyphs(CARD8 op, 118303b705cfSriastradh PicturePtr src, 118403b705cfSriastradh PicturePtr dst, 118503b705cfSriastradh PictFormatPtr mask, 118603b705cfSriastradh INT16 xSrc, INT16 ySrc, 118703b705cfSriastradh int nlist, 118803b705cfSriastradh GlyphListPtr list, 118903b705cfSriastradh GlyphPtr *glyphs); 119003b705cfSriastradhvoid sna_glyphs__shared(CARD8 op, 119103b705cfSriastradh PicturePtr src, 119203b705cfSriastradh PicturePtr dst, 119303b705cfSriastradh PictFormatPtr mask, 119403b705cfSriastradh INT16 src_x, INT16 src_y, 119503b705cfSriastradh int nlist, GlyphListPtr list, GlyphPtr *glyphs); 119603b705cfSriastradhvoid sna_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph); 119703b705cfSriastradhvoid sna_glyphs_close(struct sna *sna); 119803b705cfSriastradh 119903b705cfSriastradhvoid sna_read_boxes(struct sna *sna, PixmapPtr dst, struct kgem_bo *src_bo, 120003b705cfSriastradh const BoxRec *box, int n); 120103b705cfSriastradhbool sna_write_boxes(struct sna *sna, PixmapPtr dst, 120203b705cfSriastradh struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, 120303b705cfSriastradh const void *src, int stride, int16_t src_dx, int16_t src_dy, 120403b705cfSriastradh const BoxRec *box, int n); 120542542f5fSchristosbool sna_write_boxes__xor(struct sna *sna, PixmapPtr dst, 120603b705cfSriastradh struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy, 120703b705cfSriastradh const void *src, int stride, int16_t src_dx, int16_t src_dy, 120803b705cfSriastradh const BoxRec *box, int nbox, 120903b705cfSriastradh uint32_t and, uint32_t or); 121003b705cfSriastradh 121103b705cfSriastradhbool sna_replace(struct sna *sna, 121203b705cfSriastradh PixmapPtr pixmap, 121303b705cfSriastradh const void *src, int stride); 121442542f5fSchristosbool sna_replace__xor(struct sna *sna, 121542542f5fSchristos PixmapPtr pixmap, 121642542f5fSchristos const void *src, int stride, 121742542f5fSchristos uint32_t and, uint32_t or); 121803b705cfSriastradh 121903b705cfSriastradhbool 122003b705cfSriastradhsna_compute_composite_extents(BoxPtr extents, 122103b705cfSriastradh PicturePtr src, PicturePtr mask, PicturePtr dst, 122203b705cfSriastradh INT16 src_x, INT16 src_y, 122303b705cfSriastradh INT16 mask_x, INT16 mask_y, 122403b705cfSriastradh INT16 dst_x, INT16 dst_y, 122503b705cfSriastradh CARD16 width, CARD16 height); 122603b705cfSriastradhbool 122703b705cfSriastradhsna_compute_composite_region(RegionPtr region, 122803b705cfSriastradh PicturePtr src, PicturePtr mask, PicturePtr dst, 122903b705cfSriastradh INT16 src_x, INT16 src_y, 123003b705cfSriastradh INT16 mask_x, INT16 mask_y, 123103b705cfSriastradh INT16 dst_x, INT16 dst_y, 123203b705cfSriastradh CARD16 width, CARD16 height); 123303b705cfSriastradh 123403b705cfSriastradhvoid 123503b705cfSriastradhmemcpy_blt(const void *src, void *dst, int bpp, 123603b705cfSriastradh int32_t src_stride, int32_t dst_stride, 123703b705cfSriastradh int16_t src_x, int16_t src_y, 123803b705cfSriastradh int16_t dst_x, int16_t dst_y, 123903b705cfSriastradh uint16_t width, uint16_t height); 124003b705cfSriastradh 124163ef14f0Smrgvoid 124263ef14f0Smrgaffine_blt(const void *src, void *dst, int bpp, 124363ef14f0Smrg int16_t src_x, int16_t src_y, 124463ef14f0Smrg int16_t src_width, int16_t src_height, 124563ef14f0Smrg int32_t src_stride, 124663ef14f0Smrg int16_t dst_x, int16_t dst_y, 124763ef14f0Smrg uint16_t dst_width, uint16_t dst_height, 124863ef14f0Smrg int32_t dst_stride, 124963ef14f0Smrg const struct pixman_f_transform *t); 125063ef14f0Smrg 125103b705cfSriastradhvoid 125203b705cfSriastradhmemmove_box(const void *src, void *dst, 125303b705cfSriastradh int bpp, int32_t stride, 125403b705cfSriastradh const BoxRec *box, 125503b705cfSriastradh int dx, int dy); 125603b705cfSriastradh 125703b705cfSriastradhvoid 125803b705cfSriastradhmemcpy_xor(const void *src, void *dst, int bpp, 125903b705cfSriastradh int32_t src_stride, int32_t dst_stride, 126003b705cfSriastradh int16_t src_x, int16_t src_y, 126103b705cfSriastradh int16_t dst_x, int16_t dst_y, 126203b705cfSriastradh uint16_t width, uint16_t height, 126303b705cfSriastradh uint32_t and, uint32_t or); 126403b705cfSriastradh 126503b705cfSriastradh#define SNA_CREATE_FB 0x10 126603b705cfSriastradh#define SNA_CREATE_SCRATCH 0x11 126703b705cfSriastradh 126803b705cfSriastradhinline static bool is_power_of_two(unsigned x) 126903b705cfSriastradh{ 127003b705cfSriastradh return (x & (x-1)) == 0; 127103b705cfSriastradh} 127203b705cfSriastradh 127303b705cfSriastradhinline static bool is_clipped(const RegionRec *r, 127403b705cfSriastradh const DrawableRec *d) 127503b705cfSriastradh{ 127642542f5fSchristos DBG(("%s: region[%d]x(%d, %d),(%d, %d) against drawable %dx%d\n", 127742542f5fSchristos __FUNCTION__, 127842542f5fSchristos region_num_rects(r), 127942542f5fSchristos r->extents.x1, r->extents.y1, 128042542f5fSchristos r->extents.x2, r->extents.y2, 128142542f5fSchristos d->width, d->height)); 128203b705cfSriastradh return (r->data || 128303b705cfSriastradh r->extents.x2 - r->extents.x1 != d->width || 128403b705cfSriastradh r->extents.y2 - r->extents.y1 != d->height); 128503b705cfSriastradh} 128603b705cfSriastradh 128703b705cfSriastradhinline static bool 128803b705cfSriastradhbox_intersect(BoxPtr a, const BoxRec *b) 128903b705cfSriastradh{ 129003b705cfSriastradh if (a->x1 < b->x1) 129103b705cfSriastradh a->x1 = b->x1; 129203b705cfSriastradh if (a->x2 > b->x2) 129303b705cfSriastradh a->x2 = b->x2; 129403b705cfSriastradh if (a->x1 >= a->x2) 129503b705cfSriastradh return false; 129603b705cfSriastradh 129703b705cfSriastradh if (a->y1 < b->y1) 129803b705cfSriastradh a->y1 = b->y1; 129903b705cfSriastradh if (a->y2 > b->y2) 130003b705cfSriastradh a->y2 = b->y2; 130103b705cfSriastradh if (a->y1 >= a->y2) 130203b705cfSriastradh return false; 130303b705cfSriastradh 130403b705cfSriastradh return true; 130503b705cfSriastradh} 130603b705cfSriastradh 130763ef14f0Smrgconst BoxRec * 130863ef14f0Smrg__find_clip_box_for_y(const BoxRec *begin, const BoxRec *end, int16_t y); 130963ef14f0Smrginline static const BoxRec * 131063ef14f0Smrgfind_clip_box_for_y(const BoxRec *begin, const BoxRec *end, int16_t y) 131163ef14f0Smrg{ 131263ef14f0Smrg /* Special case for incremental trapezoid clipping */ 131363ef14f0Smrg if (begin == end) 131463ef14f0Smrg return end; 131563ef14f0Smrg 131663ef14f0Smrg /* Quick test if scanline is within range of clip boxes */ 131763ef14f0Smrg if (begin->y2 > y) { 131863ef14f0Smrg assert(end == begin + 1 || 131963ef14f0Smrg __find_clip_box_for_y(begin, end, y) == begin); 132063ef14f0Smrg return begin; 132163ef14f0Smrg } 132263ef14f0Smrg if (y >= end[-1].y2) { 132363ef14f0Smrg assert(end == begin + 1 || 132463ef14f0Smrg __find_clip_box_for_y(begin, end, y) == end); 132563ef14f0Smrg return end; 132663ef14f0Smrg } 132763ef14f0Smrg 132863ef14f0Smrg /* Otherwise bisect to find the first box crossing y */ 132963ef14f0Smrg return __find_clip_box_for_y(begin, end, y); 133063ef14f0Smrg} 133163ef14f0Smrg 133203b705cfSriastradhunsigned sna_cpu_detect(void); 133303b705cfSriastradhchar *sna_cpu_features_to_string(unsigned features, char *line); 133403b705cfSriastradh 133542542f5fSchristos/* sna_acpi.c */ 133642542f5fSchristosint sna_acpi_open(void); 133742542f5fSchristosvoid sna_acpi_init(struct sna *sna); 133842542f5fSchristosvoid _sna_acpi_wakeup(struct sna *sna); 1339fe196524Smrgstatic inline void sna_acpi_wakeup(struct sna *sna) 134042542f5fSchristos{ 1341fe196524Smrg _sna_acpi_wakeup(sna); 134242542f5fSchristos} 134342542f5fSchristosvoid sna_acpi_fini(struct sna *sna); 134442542f5fSchristos 134503b705cfSriastradhvoid sna_threads_init(void); 134603b705cfSriastradhint sna_use_threads (int width, int height, int threshold); 134742542f5fSchristosvoid sna_threads_run(int id, void (*func)(void *arg), void *arg); 134842542f5fSchristosvoid sna_threads_trap(int sig); 134903b705cfSriastradhvoid sna_threads_wait(void); 135042542f5fSchristosvoid sna_threads_kill(void); 135103b705cfSriastradh 135203b705cfSriastradhvoid sna_image_composite(pixman_op_t op, 135303b705cfSriastradh pixman_image_t *src, 135403b705cfSriastradh pixman_image_t *mask, 135503b705cfSriastradh pixman_image_t *dst, 135603b705cfSriastradh int16_t src_x, 135703b705cfSriastradh int16_t src_y, 135803b705cfSriastradh int16_t mask_x, 135903b705cfSriastradh int16_t mask_y, 136003b705cfSriastradh int16_t dst_x, 136103b705cfSriastradh int16_t dst_y, 136203b705cfSriastradh uint16_t width, 136303b705cfSriastradh uint16_t height); 136403b705cfSriastradh 136542542f5fSchristosextern jmp_buf sigjmp[4]; 136642542f5fSchristosextern volatile sig_atomic_t sigtrap; 136742542f5fSchristos 136842542f5fSchristos#define sigtrap_assert_inactive() assert(sigtrap == 0) 136942542f5fSchristos#define sigtrap_assert_active() assert(sigtrap > 0 && sigtrap <= ARRAY_SIZE(sigjmp)) 137042542f5fSchristos#define sigtrap_get() sigsetjmp(sigjmp[sigtrap++], 1) 137142542f5fSchristos 137242542f5fSchristosstatic inline void sigtrap_put(void) 137342542f5fSchristos{ 137442542f5fSchristos sigtrap_assert_active(); 137542542f5fSchristos --sigtrap; 137642542f5fSchristos} 137742542f5fSchristos 137842542f5fSchristos#define RR_Rotate_All (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270) 137942542f5fSchristos#define RR_Reflect_All (RR_Reflect_X | RR_Reflect_Y) 138042542f5fSchristos 138142542f5fSchristos#ifndef HAVE_GETLINE 138242542f5fSchristos#include <stdio.h> 138342542f5fSchristosextern int getline(char **line, size_t *len, FILE *file); 138442542f5fSchristos#endif 138542542f5fSchristos 138663ef14f0Smrgstatic inline void add_shm_flush(struct sna *sna, struct sna_pixmap *priv) 138763ef14f0Smrg{ 138863ef14f0Smrg if (!priv->shm) 138963ef14f0Smrg return; 139063ef14f0Smrg 139163ef14f0Smrg DBG(("%s: marking handle=%d for SHM flush\n", 139263ef14f0Smrg __FUNCTION__, priv->cpu_bo->handle)); 139363ef14f0Smrg 139463ef14f0Smrg assert(!priv->flush); 139563ef14f0Smrg sna_add_flush_pixmap(sna, priv, priv->cpu_bo); 139663ef14f0Smrg sna->needs_shm_flush = true; 139763ef14f0Smrg} 139863ef14f0Smrg 139903b705cfSriastradh#endif /* _SNA_H */ 1400