sna.h revision 03b705cf
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#ifdef HAVE_CONFIG_H
4103b705cfSriastradh#include "config.h"
4203b705cfSriastradh#endif
4303b705cfSriastradh
4403b705cfSriastradh#include <stdint.h>
4503b705cfSriastradh
4603b705cfSriastradh#include "compiler.h"
4703b705cfSriastradh
4803b705cfSriastradh#include <xorg-server.h>
4903b705cfSriastradh
5003b705cfSriastradh#include <xf86Crtc.h>
5103b705cfSriastradh#if XF86_CRTC_VERSION >= 5
5203b705cfSriastradh#define HAS_PIXMAP_SHARING 1
5303b705cfSriastradh#endif
5403b705cfSriastradh
5503b705cfSriastradh#include <xf86str.h>
5603b705cfSriastradh#include <windowstr.h>
5703b705cfSriastradh#include <glyphstr.h>
5803b705cfSriastradh#include <picturestr.h>
5903b705cfSriastradh#include <gcstruct.h>
6003b705cfSriastradh#include <xvdix.h>
6103b705cfSriastradh
6203b705cfSriastradh#include <pciaccess.h>
6303b705cfSriastradh
6403b705cfSriastradh#include <xf86drmMode.h>
6503b705cfSriastradh
6603b705cfSriastradh#include "../compat-api.h"
6703b705cfSriastradh#include <drm.h>
6803b705cfSriastradh#include <i915_drm.h>
6903b705cfSriastradh
7003b705cfSriastradh#ifdef HAVE_DRI2_H
7103b705cfSriastradh#include <dri2.h>
7203b705cfSriastradh#endif
7303b705cfSriastradh
7403b705cfSriastradh#if HAVE_UDEV
7503b705cfSriastradh#include <libudev.h>
7603b705cfSriastradh#endif
7703b705cfSriastradh
7803b705cfSriastradh#if HAS_DEBUG_FULL
7903b705cfSriastradh#define DBG(x) ErrorF x
8003b705cfSriastradh#else
8103b705cfSriastradh#define DBG(x)
8203b705cfSriastradh#endif
8303b705cfSriastradh
8403b705cfSriastradh#define DEBUG_NO_BLT 0
8503b705cfSriastradh
8603b705cfSriastradh#define DEBUG_FLUSH_BATCH 0
8703b705cfSriastradh
8803b705cfSriastradh#define TEST_ALL 0
8903b705cfSriastradh#define TEST_ACCEL (TEST_ALL || 0)
9003b705cfSriastradh#define TEST_BATCH (TEST_ALL || 0)
9103b705cfSriastradh#define TEST_BLT (TEST_ALL || 0)
9203b705cfSriastradh#define TEST_COMPOSITE (TEST_ALL || 0)
9303b705cfSriastradh#define TEST_DAMAGE (TEST_ALL || 0)
9403b705cfSriastradh#define TEST_GRADIENT (TEST_ALL || 0)
9503b705cfSriastradh#define TEST_GLYPHS (TEST_ALL || 0)
9603b705cfSriastradh#define TEST_IO (TEST_ALL || 0)
9703b705cfSriastradh#define TEST_KGEM (TEST_ALL || 0)
9803b705cfSriastradh#define TEST_RENDER (TEST_ALL || 0)
9903b705cfSriastradh
10003b705cfSriastradh#include "intel_driver.h"
10103b705cfSriastradh#include "intel_list.h"
10203b705cfSriastradh#include "kgem.h"
10303b705cfSriastradh#include "sna_damage.h"
10403b705cfSriastradh#include "sna_render.h"
10503b705cfSriastradh#include "fb/fb.h"
10603b705cfSriastradh
10703b705cfSriastradh#define SNA_CURSOR_X			64
10803b705cfSriastradh#define SNA_CURSOR_Y			SNA_CURSOR_X
10903b705cfSriastradh
11003b705cfSriastradhstruct sna_client {
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
13503b705cfSriastradh	struct list flush_list;
13603b705cfSriastradh	struct list cow_list;
13703b705cfSriastradh
13803b705cfSriastradh	uint32_t stride;
13903b705cfSriastradh	uint32_t clear_color;
14003b705cfSriastradh
14103b705cfSriastradh#define SOURCE_BIAS 4
14203b705cfSriastradh	uint16_t source_count;
14303b705cfSriastradh	uint8_t pinned :3;
14403b705cfSriastradh#define PIN_SCANOUT 0x1
14503b705cfSriastradh#define PIN_DRI 0x2
14603b705cfSriastradh#define PIN_PRIME 0x4
14703b705cfSriastradh	uint8_t create :4;
14803b705cfSriastradh	uint8_t mapped :1;
14903b705cfSriastradh	uint8_t flush :1;
15003b705cfSriastradh	uint8_t shm :1;
15103b705cfSriastradh	uint8_t clear :1;
15203b705cfSriastradh	uint8_t header :1;
15303b705cfSriastradh	uint8_t cpu :1;
15403b705cfSriastradh};
15503b705cfSriastradh
15603b705cfSriastradhstruct sna_glyph {
15703b705cfSriastradh	PicturePtr atlas;
15803b705cfSriastradh	struct sna_coordinate coordinate;
15903b705cfSriastradh	uint16_t size, pos;
16003b705cfSriastradh	pixman_image_t *image;
16103b705cfSriastradh};
16203b705cfSriastradh
16303b705cfSriastradhstatic inline WindowPtr get_root_window(ScreenPtr screen)
16403b705cfSriastradh{
16503b705cfSriastradh#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,10,0,0,0)
16603b705cfSriastradh	return screen->root;
16703b705cfSriastradh#else
16803b705cfSriastradh	return WindowTable[screen->myNum];
16903b705cfSriastradh#endif
17003b705cfSriastradh}
17103b705cfSriastradh
17203b705cfSriastradhstatic inline PixmapPtr get_window_pixmap(WindowPtr window)
17303b705cfSriastradh{
17403b705cfSriastradh	return fbGetWindowPixmap(window);
17503b705cfSriastradh}
17603b705cfSriastradh
17703b705cfSriastradhstatic inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
17803b705cfSriastradh{
17903b705cfSriastradh	if (drawable->type == DRAWABLE_PIXMAP)
18003b705cfSriastradh		return (PixmapPtr)drawable;
18103b705cfSriastradh	else
18203b705cfSriastradh		return get_window_pixmap((WindowPtr)drawable);
18303b705cfSriastradh}
18403b705cfSriastradh
18503b705cfSriastradhextern DevPrivateKeyRec sna_pixmap_key;
18603b705cfSriastradh
18703b705cfSriastradhpure static inline struct sna_pixmap *sna_pixmap(PixmapPtr pixmap)
18803b705cfSriastradh{
18903b705cfSriastradh	return ((void **)__get_private(pixmap, sna_pixmap_key))[1];
19003b705cfSriastradh}
19103b705cfSriastradh
19203b705cfSriastradhstatic inline struct sna_pixmap *sna_pixmap_from_drawable(DrawablePtr drawable)
19303b705cfSriastradh{
19403b705cfSriastradh	return sna_pixmap(get_drawable_pixmap(drawable));
19503b705cfSriastradh}
19603b705cfSriastradh
19703b705cfSriastradhstruct sna_gc {
19803b705cfSriastradh	long changes;
19903b705cfSriastradh	long serial;
20003b705cfSriastradh
20103b705cfSriastradh	GCFuncs *old_funcs;
20203b705cfSriastradh	void *priv;
20303b705cfSriastradh};
20403b705cfSriastradh
20503b705cfSriastradhstatic inline struct sna_gc *sna_gc(GCPtr gc)
20603b705cfSriastradh{
20703b705cfSriastradh	return (struct sna_gc *)__get_private(gc, sna_gc_key);
20803b705cfSriastradh}
20903b705cfSriastradh
21003b705cfSriastradhenum {
21103b705cfSriastradh	FLUSH_TIMER = 0,
21203b705cfSriastradh	THROTTLE_TIMER,
21303b705cfSriastradh	EXPIRE_TIMER,
21403b705cfSriastradh#if DEBUG_MEMORY
21503b705cfSriastradh	DEBUG_MEMORY_TIMER,
21603b705cfSriastradh#endif
21703b705cfSriastradh	NUM_TIMERS
21803b705cfSriastradh};
21903b705cfSriastradh
22003b705cfSriastradhstruct sna {
22103b705cfSriastradh	struct kgem kgem;
22203b705cfSriastradh
22303b705cfSriastradh	ScrnInfoPtr scrn;
22403b705cfSriastradh
22503b705cfSriastradh	unsigned flags;
22603b705cfSriastradh#define SNA_NO_WAIT		0x1
22703b705cfSriastradh#define SNA_NO_FLIP		0x2
22803b705cfSriastradh#define SNA_TRIPLE_BUFFER	0x4
22903b705cfSriastradh#define SNA_TEAR_FREE		0x10
23003b705cfSriastradh#define SNA_FORCE_SHADOW	0x20
23103b705cfSriastradh#define SNA_FLUSH_GTT		0x40
23203b705cfSriastradh#define SNA_IS_HOSTED		0x80
23303b705cfSriastradh#define SNA_REPROBE		0x80000000
23403b705cfSriastradh
23503b705cfSriastradh	unsigned cpu_features;
23603b705cfSriastradh#define MMX 0x1
23703b705cfSriastradh#define SSE 0x2
23803b705cfSriastradh#define SSE2 0x4
23903b705cfSriastradh#define SSE3 0x8
24003b705cfSriastradh#define SSSE3 0x10
24103b705cfSriastradh#define SSE4_1 0x20
24203b705cfSriastradh#define SSE4_2 0x40
24303b705cfSriastradh#define AVX 0x80
24403b705cfSriastradh#define AVX2 0x100
24503b705cfSriastradh
24603b705cfSriastradh	unsigned watch_flush;
24703b705cfSriastradh
24803b705cfSriastradh	struct timeval timer_tv;
24903b705cfSriastradh	uint32_t timer_expire[NUM_TIMERS];
25003b705cfSriastradh	uint16_t timer_active;
25103b705cfSriastradh
25203b705cfSriastradh	int vblank_interval;
25303b705cfSriastradh
25403b705cfSriastradh	struct list flush_pixmaps;
25503b705cfSriastradh	struct list active_pixmaps;
25603b705cfSriastradh
25703b705cfSriastradh	PixmapPtr front;
25803b705cfSriastradh	PixmapPtr freed_pixmap;
25903b705cfSriastradh
26003b705cfSriastradh	struct sna_mode {
26103b705cfSriastradh		drmModeResPtr kmode;
26203b705cfSriastradh
26303b705cfSriastradh		int shadow_active;
26403b705cfSriastradh		DamagePtr shadow_damage;
26503b705cfSriastradh		struct kgem_bo *shadow;
26603b705cfSriastradh		int shadow_flip;
26703b705cfSriastradh	} mode;
26803b705cfSriastradh
26903b705cfSriastradh	struct sna_dri {
27003b705cfSriastradh		void *flip_pending;
27103b705cfSriastradh	} dri;
27203b705cfSriastradh
27303b705cfSriastradh	struct sna_xv {
27403b705cfSriastradh		XvAdaptorPtr adaptors;
27503b705cfSriastradh		int num_adaptors;
27603b705cfSriastradh	} xv;
27703b705cfSriastradh
27803b705cfSriastradh	unsigned int tiling;
27903b705cfSriastradh#define SNA_TILING_FB		0x1
28003b705cfSriastradh#define SNA_TILING_2D		0x2
28103b705cfSriastradh#define SNA_TILING_ALL (~0)
28203b705cfSriastradh
28303b705cfSriastradh	EntityInfoPtr pEnt;
28403b705cfSriastradh	struct pci_device *PciInfo;
28503b705cfSriastradh	const struct intel_device_info *info;
28603b705cfSriastradh
28703b705cfSriastradh	ScreenBlockHandlerProcPtr BlockHandler;
28803b705cfSriastradh	ScreenWakeupHandlerProcPtr WakeupHandler;
28903b705cfSriastradh	CloseScreenProcPtr CloseScreen;
29003b705cfSriastradh
29103b705cfSriastradh	PicturePtr clear;
29203b705cfSriastradh	struct {
29303b705cfSriastradh		uint32_t fill_bo;
29403b705cfSriastradh		uint32_t fill_pixel;
29503b705cfSriastradh		uint32_t fill_alu;
29603b705cfSriastradh	} blt_state;
29703b705cfSriastradh	union {
29803b705cfSriastradh		struct gen2_render_state gen2;
29903b705cfSriastradh		struct gen3_render_state gen3;
30003b705cfSriastradh		struct gen4_render_state gen4;
30103b705cfSriastradh		struct gen5_render_state gen5;
30203b705cfSriastradh		struct gen6_render_state gen6;
30303b705cfSriastradh		struct gen7_render_state gen7;
30403b705cfSriastradh	} render_state;
30503b705cfSriastradh
30603b705cfSriastradh	bool dri_available;
30703b705cfSriastradh	bool dri_open;
30803b705cfSriastradh
30903b705cfSriastradh	/* Broken-out options. */
31003b705cfSriastradh	OptionInfoPtr Options;
31103b705cfSriastradh
31203b705cfSriastradh	/* Driver phase/state information */
31303b705cfSriastradh	bool suspended;
31403b705cfSriastradh
31503b705cfSriastradh#if HAVE_UDEV
31603b705cfSriastradh	struct udev_monitor *uevent_monitor;
31703b705cfSriastradh	InputHandlerProc uevent_handler;
31803b705cfSriastradh#endif
31903b705cfSriastradh
32003b705cfSriastradh	struct sna_render render;
32103b705cfSriastradh
32203b705cfSriastradh#if DEBUG_MEMORY
32303b705cfSriastradh	struct {
32403b705cfSriastradh		int pixmap_allocs;
32503b705cfSriastradh		int cpu_bo_allocs;
32603b705cfSriastradh		size_t shadow_pixels_bytes;
32703b705cfSriastradh		size_t cpu_bo_bytes;
32803b705cfSriastradh	} debug_memory;
32903b705cfSriastradh#endif
33003b705cfSriastradh};
33103b705cfSriastradh
33203b705cfSriastradhbool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna);
33303b705cfSriastradhbool sna_mode_fake_init(struct sna *sna);
33403b705cfSriastradhvoid sna_mode_adjust_frame(struct sna *sna, int x, int y);
33503b705cfSriastradhextern void sna_mode_update(struct sna *sna);
33603b705cfSriastradhextern void sna_mode_wakeup(struct sna *sna);
33703b705cfSriastradhextern void sna_mode_redisplay(struct sna *sna);
33803b705cfSriastradhextern void sna_mode_close(struct sna *sna);
33903b705cfSriastradhextern void sna_mode_fini(struct sna *sna);
34003b705cfSriastradh
34103b705cfSriastradhextern int sna_page_flip(struct sna *sna,
34203b705cfSriastradh			 struct kgem_bo *bo,
34303b705cfSriastradh			 void *data,
34403b705cfSriastradh			 int ref_crtc_hw_id);
34503b705cfSriastradh
34603b705cfSriastradhpure static inline struct sna *
34703b705cfSriastradhto_sna(ScrnInfoPtr scrn)
34803b705cfSriastradh{
34903b705cfSriastradh	return (struct sna *)(scrn->driverPrivate);
35003b705cfSriastradh}
35103b705cfSriastradh
35203b705cfSriastradhpure static inline struct sna *
35303b705cfSriastradhto_sna_from_screen(ScreenPtr screen)
35403b705cfSriastradh{
35503b705cfSriastradh	return to_sna(xf86ScreenToScrn(screen));
35603b705cfSriastradh}
35703b705cfSriastradh
35803b705cfSriastradhpure static inline struct sna *
35903b705cfSriastradhto_sna_from_pixmap(PixmapPtr pixmap)
36003b705cfSriastradh{
36103b705cfSriastradh	return ((void **)__get_private(pixmap, sna_pixmap_key))[0];
36203b705cfSriastradh}
36303b705cfSriastradh
36403b705cfSriastradhpure static inline struct sna *
36503b705cfSriastradhto_sna_from_drawable(DrawablePtr drawable)
36603b705cfSriastradh{
36703b705cfSriastradh	return to_sna_from_screen(drawable->pScreen);
36803b705cfSriastradh}
36903b705cfSriastradh
37003b705cfSriastradhstatic inline struct sna *
37103b705cfSriastradhto_sna_from_kgem(struct kgem *kgem)
37203b705cfSriastradh{
37303b705cfSriastradh	return container_of(kgem, struct sna, kgem);
37403b705cfSriastradh}
37503b705cfSriastradh
37603b705cfSriastradh#ifndef ARRAY_SIZE
37703b705cfSriastradh#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
37803b705cfSriastradh#endif
37903b705cfSriastradh
38003b705cfSriastradh#ifndef ALIGN
38103b705cfSriastradh#define ALIGN(i,m)	(((i) + (m) - 1) & ~((m) - 1))
38203b705cfSriastradh#endif
38303b705cfSriastradh
38403b705cfSriastradh#ifndef MIN
38503b705cfSriastradh#define MIN(a,b)	((a) <= (b) ? (a) : (b))
38603b705cfSriastradh#endif
38703b705cfSriastradh
38803b705cfSriastradh#ifndef MAX
38903b705cfSriastradh#define MAX(a,b)	((a) >= (b) ? (a) : (b))
39003b705cfSriastradh#endif
39103b705cfSriastradh
39203b705cfSriastradhextern xf86CrtcPtr sna_covering_crtc(ScrnInfoPtr scrn,
39303b705cfSriastradh				     const BoxRec *box,
39403b705cfSriastradh				     xf86CrtcPtr desired);
39503b705cfSriastradh
39603b705cfSriastradhextern bool sna_wait_for_scanline(struct sna *sna, PixmapPtr pixmap,
39703b705cfSriastradh				  xf86CrtcPtr crtc, const BoxRec *clip);
39803b705cfSriastradh
39903b705cfSriastradh#if HAVE_DRI2_H
40003b705cfSriastradhbool sna_dri_open(struct sna *sna, ScreenPtr pScreen);
40103b705cfSriastradhvoid sna_dri_page_flip_handler(struct sna *sna, struct drm_event_vblank *event);
40203b705cfSriastradhvoid sna_dri_vblank_handler(struct sna *sna, struct drm_event_vblank *event);
40303b705cfSriastradhvoid sna_dri_destroy_window(WindowPtr win);
40403b705cfSriastradhvoid sna_dri_close(struct sna *sna, ScreenPtr pScreen);
40503b705cfSriastradh#else
40603b705cfSriastradhstatic inline bool sna_dri_open(struct sna *sna, ScreenPtr pScreen) { return false; }
40703b705cfSriastradhstatic inline void sna_dri_page_flip_handler(struct sna *sna, struct drm_event_vblank *event) { }
40803b705cfSriastradhstatic inline void sna_dri_vblank_handler(struct sna *sna, struct drm_event_vblank *event) { }
40903b705cfSriastradhstatic inline void sna_dri_destroy_window(WindowPtr win) { }
41003b705cfSriastradhstatic inline void sna_dri_close(struct sna *sna, ScreenPtr pScreen) { }
41103b705cfSriastradh#endif
41203b705cfSriastradhvoid sna_dri_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap);
41303b705cfSriastradh
41403b705cfSriastradhextern int sna_crtc_to_pipe(xf86CrtcPtr crtc);
41503b705cfSriastradhextern uint32_t sna_crtc_to_plane(xf86CrtcPtr crtc);
41603b705cfSriastradhextern uint32_t sna_crtc_id(xf86CrtcPtr crtc);
41703b705cfSriastradh
41803b705cfSriastradhCARD32 sna_format_for_depth(int depth);
41903b705cfSriastradhCARD32 sna_render_format_for_depth(int depth);
42003b705cfSriastradh
42103b705cfSriastradhvoid sna_debug_flush(struct sna *sna);
42203b705cfSriastradh
42303b705cfSriastradhstatic inline bool
42403b705cfSriastradhget_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int16_t *x, int16_t *y)
42503b705cfSriastradh{
42603b705cfSriastradh#ifdef COMPOSITE
42703b705cfSriastradh	if (drawable->type == DRAWABLE_WINDOW) {
42803b705cfSriastradh		*x = -pixmap->screen_x;
42903b705cfSriastradh		*y = -pixmap->screen_y;
43003b705cfSriastradh		return pixmap->screen_x | pixmap->screen_y;
43103b705cfSriastradh	}
43203b705cfSriastradh#endif
43303b705cfSriastradh	*x = *y = 0;
43403b705cfSriastradh	return false;
43503b705cfSriastradh}
43603b705cfSriastradh
43703b705cfSriastradhstatic inline int
43803b705cfSriastradhget_drawable_dx(DrawablePtr drawable)
43903b705cfSriastradh{
44003b705cfSriastradh#ifdef COMPOSITE
44103b705cfSriastradh	if (drawable->type == DRAWABLE_WINDOW)
44203b705cfSriastradh		return -get_drawable_pixmap(drawable)->screen_x;
44303b705cfSriastradh#endif
44403b705cfSriastradh	return 0;
44503b705cfSriastradh}
44603b705cfSriastradh
44703b705cfSriastradhstatic inline int
44803b705cfSriastradhget_drawable_dy(DrawablePtr drawable)
44903b705cfSriastradh{
45003b705cfSriastradh#ifdef COMPOSITE
45103b705cfSriastradh	if (drawable->type == DRAWABLE_WINDOW)
45203b705cfSriastradh		return -get_drawable_pixmap(drawable)->screen_y;
45303b705cfSriastradh#endif
45403b705cfSriastradh	return 0;
45503b705cfSriastradh}
45603b705cfSriastradh
45703b705cfSriastradhbool sna_pixmap_attach_to_bo(PixmapPtr pixmap, struct kgem_bo *bo);
45803b705cfSriastradhstatic inline bool sna_pixmap_is_scanout(struct sna *sna, PixmapPtr pixmap)
45903b705cfSriastradh{
46003b705cfSriastradh	return (pixmap == sna->front &&
46103b705cfSriastradh		!sna->mode.shadow_active &&
46203b705cfSriastradh		(sna->flags & SNA_NO_WAIT) == 0);
46303b705cfSriastradh}
46403b705cfSriastradh
46503b705cfSriastradhPixmapPtr sna_pixmap_create_upload(ScreenPtr screen,
46603b705cfSriastradh				   int width, int height, int depth,
46703b705cfSriastradh				   unsigned flags);
46803b705cfSriastradhPixmapPtr sna_pixmap_create_unattached(ScreenPtr screen,
46903b705cfSriastradh				       int width, int height, int depth);
47003b705cfSriastradhvoid sna_pixmap_destroy(PixmapPtr pixmap);
47103b705cfSriastradh
47203b705cfSriastradhbool
47303b705cfSriastradhsna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags);
47403b705cfSriastradh
47503b705cfSriastradh#define MOVE_WRITE 0x1
47603b705cfSriastradh#define MOVE_READ 0x2
47703b705cfSriastradh#define MOVE_INPLACE_HINT 0x4
47803b705cfSriastradh#define MOVE_ASYNC_HINT 0x8
47903b705cfSriastradh#define MOVE_SOURCE_HINT 0x10
48003b705cfSriastradh#define MOVE_WHOLE_HINT 0x20
48103b705cfSriastradh#define __MOVE_FORCE 0x40
48203b705cfSriastradh#define __MOVE_DRI 0x80
48303b705cfSriastradh
48403b705cfSriastradhbool
48503b705cfSriastradhsna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int flags);
48603b705cfSriastradh
48703b705cfSriastradhstruct sna_pixmap *sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags);
48803b705cfSriastradhstatic inline struct sna_pixmap *
48903b705cfSriastradhsna_pixmap_force_to_gpu(PixmapPtr pixmap, unsigned flags)
49003b705cfSriastradh{
49103b705cfSriastradh	/* Unlike move-to-gpu, we ignore wedged and always create the GPU bo */
49203b705cfSriastradh	DBG(("%s(pixmap=%p, flags=%x)\n", __FUNCTION__, pixmap, flags));
49303b705cfSriastradh	return sna_pixmap_move_to_gpu(pixmap, flags | __MOVE_FORCE);
49403b705cfSriastradh}
49503b705cfSriastradhbool must_check _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags);
49603b705cfSriastradhstatic inline bool must_check sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags)
49703b705cfSriastradh{
49803b705cfSriastradh	if (flags == MOVE_READ) {
49903b705cfSriastradh		struct sna_pixmap *priv = sna_pixmap(pixmap);
50003b705cfSriastradh		if (priv == NULL)
50103b705cfSriastradh			return true;
50203b705cfSriastradh	}
50303b705cfSriastradh
50403b705cfSriastradh	return _sna_pixmap_move_to_cpu(pixmap, flags);
50503b705cfSriastradh}
50603b705cfSriastradhbool must_check sna_drawable_move_region_to_cpu(DrawablePtr drawable,
50703b705cfSriastradh						RegionPtr region,
50803b705cfSriastradh						unsigned flags);
50903b705cfSriastradh
51003b705cfSriastradhbool must_check sna_drawable_move_to_cpu(DrawablePtr drawable, unsigned flags);
51103b705cfSriastradh
51203b705cfSriastradhstatic inline bool must_check
51303b705cfSriastradhsna_drawable_move_to_gpu(DrawablePtr drawable, unsigned flags)
51403b705cfSriastradh{
51503b705cfSriastradh	return sna_pixmap_move_to_gpu(get_drawable_pixmap(drawable), flags) != NULL;
51603b705cfSriastradh}
51703b705cfSriastradh
51803b705cfSriastradhvoid sna_add_flush_pixmap(struct sna *sna,
51903b705cfSriastradh			  struct sna_pixmap *priv,
52003b705cfSriastradh			  struct kgem_bo *bo);
52103b705cfSriastradh
52203b705cfSriastradhstruct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling);
52303b705cfSriastradh
52403b705cfSriastradh#define PREFER_GPU	0x1
52503b705cfSriastradh#define FORCE_GPU	0x2
52603b705cfSriastradh#define RENDER_GPU	0x4
52703b705cfSriastradh#define IGNORE_CPU	0x8
52803b705cfSriastradh#define REPLACES	0x10
52903b705cfSriastradhstruct kgem_bo *
53003b705cfSriastradhsna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box,
53103b705cfSriastradh		    struct sna_damage ***damage);
53203b705cfSriastradh
53303b705cfSriastradhinline static int16_t bound(int16_t a, uint16_t b)
53403b705cfSriastradh{
53503b705cfSriastradh	int v = (int)a + (int)b;
53603b705cfSriastradh	if (v > MAXSHORT)
53703b705cfSriastradh		return MAXSHORT;
53803b705cfSriastradh	return v;
53903b705cfSriastradh}
54003b705cfSriastradh
54103b705cfSriastradhinline static int16_t clamp(int16_t a, int16_t b)
54203b705cfSriastradh{
54303b705cfSriastradh	int v = (int)a + (int)b;
54403b705cfSriastradh	if (v > MAXSHORT)
54503b705cfSriastradh		return MAXSHORT;
54603b705cfSriastradh	if (v < MINSHORT)
54703b705cfSriastradh		return MINSHORT;
54803b705cfSriastradh	return v;
54903b705cfSriastradh}
55003b705cfSriastradh
55103b705cfSriastradhstatic inline bool box_empty(const BoxRec *box)
55203b705cfSriastradh{
55303b705cfSriastradh	return box->x2 <= box->x1 || box->y2 <= box->y1;
55403b705cfSriastradh}
55503b705cfSriastradh
55603b705cfSriastradhstatic inline bool
55703b705cfSriastradhbox_inplace(PixmapPtr pixmap, const BoxRec *box)
55803b705cfSriastradh{
55903b705cfSriastradh	struct sna *sna = to_sna_from_pixmap(pixmap);
56003b705cfSriastradh	return ((int)(box->x2 - box->x1) * (int)(box->y2 - box->y1) * pixmap->drawable.bitsPerPixel >> 12) >= sna->kgem.half_cpu_cache_pages;
56103b705cfSriastradh}
56203b705cfSriastradh
56303b705cfSriastradhstatic inline bool
56403b705cfSriastradhregion_subsumes_drawable(RegionPtr region, DrawablePtr drawable)
56503b705cfSriastradh{
56603b705cfSriastradh	const BoxRec *extents;
56703b705cfSriastradh
56803b705cfSriastradh	if (region->data)
56903b705cfSriastradh		return false;
57003b705cfSriastradh
57103b705cfSriastradh	extents = RegionExtents(region);
57203b705cfSriastradh	return  extents->x1 <= 0 && extents->y1 <= 0 &&
57303b705cfSriastradh		extents->x2 >= drawable->width &&
57403b705cfSriastradh		extents->y2 >= drawable->height;
57503b705cfSriastradh}
57603b705cfSriastradh
57703b705cfSriastradhstatic inline bool
57803b705cfSriastradhregion_subsumes_damage(const RegionRec *region, struct sna_damage *damage)
57903b705cfSriastradh{
58003b705cfSriastradh	const BoxRec *re, *de;
58103b705cfSriastradh
58203b705cfSriastradh	DBG(("%s?\n", __FUNCTION__));
58303b705cfSriastradh	assert(damage);
58403b705cfSriastradh
58503b705cfSriastradh	re = &region->extents;
58603b705cfSriastradh	de = &DAMAGE_PTR(damage)->extents;
58703b705cfSriastradh	DBG(("%s: region (%d, %d), (%d, %d), damage (%d, %d), (%d, %d)\n",
58803b705cfSriastradh	     __FUNCTION__,
58903b705cfSriastradh	     re->x1, re->y1, re->x2, re->y2,
59003b705cfSriastradh	     de->x1, de->y1, de->x2, de->y2));
59103b705cfSriastradh
59203b705cfSriastradh	if (re->x2 < de->x2 || re->x1 > de->x1 ||
59303b705cfSriastradh	    re->y2 < de->y2 || re->y1 > de->y1) {
59403b705cfSriastradh		DBG(("%s: not contained\n", __FUNCTION__));
59503b705cfSriastradh		return false;
59603b705cfSriastradh	}
59703b705cfSriastradh
59803b705cfSriastradh	if (region->data == NULL) {
59903b705cfSriastradh		DBG(("%s: singular region contains damage\n", __FUNCTION__));
60003b705cfSriastradh		return true;
60103b705cfSriastradh	}
60203b705cfSriastradh
60303b705cfSriastradh	return pixman_region_contains_rectangle((RegionPtr)region,
60403b705cfSriastradh						(BoxPtr)de) == PIXMAN_REGION_IN;
60503b705cfSriastradh}
60603b705cfSriastradh
60703b705cfSriastradh
60803b705cfSriastradhstatic inline bool
60903b705cfSriastradhsna_drawable_is_clear(DrawablePtr d)
61003b705cfSriastradh{
61103b705cfSriastradh	struct sna_pixmap *priv = sna_pixmap(get_drawable_pixmap(d));
61203b705cfSriastradh	return priv && priv->clear && priv->clear_color == 0;
61303b705cfSriastradh}
61403b705cfSriastradh
61503b705cfSriastradhstatic inline struct kgem_bo *__sna_pixmap_get_bo(PixmapPtr pixmap)
61603b705cfSriastradh{
61703b705cfSriastradh	return sna_pixmap(pixmap)->gpu_bo;
61803b705cfSriastradh}
61903b705cfSriastradh
62003b705cfSriastradhstatic inline struct kgem_bo *__sna_drawable_peek_bo(DrawablePtr d)
62103b705cfSriastradh{
62203b705cfSriastradh	return sna_pixmap(get_drawable_pixmap(d))->gpu_bo;
62303b705cfSriastradh}
62403b705cfSriastradh
62503b705cfSriastradhstatic inline struct kgem_bo *sna_pixmap_pin(PixmapPtr pixmap, unsigned flags)
62603b705cfSriastradh{
62703b705cfSriastradh	struct sna_pixmap *priv;
62803b705cfSriastradh
62903b705cfSriastradh	priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_WRITE);
63003b705cfSriastradh	if (!priv)
63103b705cfSriastradh		return NULL;
63203b705cfSriastradh
63303b705cfSriastradh	priv->pinned |= flags;
63403b705cfSriastradh	return priv->gpu_bo;
63503b705cfSriastradh}
63603b705cfSriastradh
63703b705cfSriastradh
63803b705cfSriastradhstatic inline bool
63903b705cfSriastradh_sna_transform_point(const PictTransform *transform,
64003b705cfSriastradh		     int64_t x, int64_t y, int64_t result[3])
64103b705cfSriastradh{
64203b705cfSriastradh	int j;
64303b705cfSriastradh
64403b705cfSriastradh	for (j = 0; j < 3; j++)
64503b705cfSriastradh		result[j] = (transform->matrix[j][0] * x +
64603b705cfSriastradh			     transform->matrix[j][1] * y +
64703b705cfSriastradh			     transform->matrix[j][2]);
64803b705cfSriastradh
64903b705cfSriastradh	return result[2] != 0;
65003b705cfSriastradh}
65103b705cfSriastradh
65203b705cfSriastradhstatic inline void
65303b705cfSriastradh_sna_get_transformed_coordinates(int x, int y,
65403b705cfSriastradh				 const PictTransform *transform,
65503b705cfSriastradh				 float *x_out, float *y_out)
65603b705cfSriastradh{
65703b705cfSriastradh
65803b705cfSriastradh	int64_t result[3];
65903b705cfSriastradh
66003b705cfSriastradh	_sna_transform_point(transform, x, y, result);
66103b705cfSriastradh	*x_out = result[0] / (double)result[2];
66203b705cfSriastradh	*y_out = result[1] / (double)result[2];
66303b705cfSriastradh}
66403b705cfSriastradh
66503b705cfSriastradhstatic inline void
66603b705cfSriastradh_sna_get_transformed_scaled(int x, int y,
66703b705cfSriastradh			    const PictTransform *transform, const float *sf,
66803b705cfSriastradh			    float *x_out, float *y_out)
66903b705cfSriastradh{
67003b705cfSriastradh	*x_out = sf[0] * (transform->matrix[0][0] * x +
67103b705cfSriastradh			  transform->matrix[0][1] * y +
67203b705cfSriastradh			  transform->matrix[0][2]);
67303b705cfSriastradh
67403b705cfSriastradh	*y_out = sf[1] * (transform->matrix[1][0] * x +
67503b705cfSriastradh			  transform->matrix[1][1] * y +
67603b705cfSriastradh			  transform->matrix[1][2]);
67703b705cfSriastradh}
67803b705cfSriastradh
67903b705cfSriastradhvoid
68003b705cfSriastradhsna_get_transformed_coordinates(int x, int y,
68103b705cfSriastradh				const PictTransform *transform,
68203b705cfSriastradh				float *x_out, float *y_out);
68303b705cfSriastradh
68403b705cfSriastradhvoid
68503b705cfSriastradhsna_get_transformed_coordinates_3d(int x, int y,
68603b705cfSriastradh				   const PictTransform *transform,
68703b705cfSriastradh				   float *x_out, float *y_out, float *z_out);
68803b705cfSriastradh
68903b705cfSriastradhbool sna_transform_is_affine(const PictTransform *t);
69003b705cfSriastradhbool sna_transform_is_integer_translation(const PictTransform *t,
69103b705cfSriastradh					  int16_t *tx, int16_t *ty);
69203b705cfSriastradhbool sna_transform_is_translation(const PictTransform *t,
69303b705cfSriastradh				  pixman_fixed_t *tx, pixman_fixed_t *ty);
69403b705cfSriastradhstatic inline bool
69503b705cfSriastradhsna_affine_transform_is_rotation(const PictTransform *t)
69603b705cfSriastradh{
69703b705cfSriastradh	assert(sna_transform_is_affine(t));
69803b705cfSriastradh	return t->matrix[0][1] | t->matrix[1][0];
69903b705cfSriastradh}
70003b705cfSriastradh
70103b705cfSriastradhstatic inline bool
70203b705cfSriastradhsna_transform_equal(const PictTransform *a, const PictTransform *b)
70303b705cfSriastradh{
70403b705cfSriastradh	if (a == b)
70503b705cfSriastradh		return true;
70603b705cfSriastradh
70703b705cfSriastradh	if (a == NULL || b == NULL)
70803b705cfSriastradh		return false;
70903b705cfSriastradh
71003b705cfSriastradh	return memcmp(a, b, sizeof(*a)) == 0;
71103b705cfSriastradh}
71203b705cfSriastradh
71303b705cfSriastradhstatic inline bool
71403b705cfSriastradhsna_picture_alphamap_equal(PicturePtr a, PicturePtr b)
71503b705cfSriastradh{
71603b705cfSriastradh	if (a->alphaMap != b->alphaMap)
71703b705cfSriastradh		return false;
71803b705cfSriastradh
71903b705cfSriastradh	if (a->alphaMap)
72003b705cfSriastradh		return false;
72103b705cfSriastradh
72203b705cfSriastradh	return (a->alphaOrigin.x == b->alphaOrigin.x &&
72303b705cfSriastradh		a->alphaOrigin.y == b->alphaOrigin.y);
72403b705cfSriastradh}
72503b705cfSriastradh
72603b705cfSriastradhstatic inline bool wedged(struct sna *sna)
72703b705cfSriastradh{
72803b705cfSriastradh	return unlikely(sna->kgem.wedged);
72903b705cfSriastradh}
73003b705cfSriastradh
73103b705cfSriastradhstatic inline bool can_render(struct sna *sna)
73203b705cfSriastradh{
73303b705cfSriastradh	return likely(!sna->kgem.wedged && sna->render.prefer_gpu & PREFER_GPU_RENDER);
73403b705cfSriastradh}
73503b705cfSriastradh
73603b705cfSriastradhstatic inline uint32_t pixmap_size(PixmapPtr pixmap)
73703b705cfSriastradh{
73803b705cfSriastradh	return (pixmap->drawable.height - 1) * pixmap->devKind +
73903b705cfSriastradh		pixmap->drawable.width * pixmap->drawable.bitsPerPixel/8;
74003b705cfSriastradh}
74103b705cfSriastradh
74203b705cfSriastradhbool sna_accel_init(ScreenPtr sreen, struct sna *sna);
74303b705cfSriastradhvoid sna_accel_create(struct sna *sna);
74403b705cfSriastradhvoid sna_accel_block_handler(struct sna *sna, struct timeval **tv);
74503b705cfSriastradhvoid sna_accel_wakeup_handler(struct sna *sna);
74603b705cfSriastradhvoid sna_accel_watch_flush(struct sna *sna, int enable);
74703b705cfSriastradhvoid sna_accel_close(struct sna *sna);
74803b705cfSriastradhvoid sna_accel_free(struct sna *sna);
74903b705cfSriastradh
75003b705cfSriastradhvoid sna_copy_fbcon(struct sna *sna);
75103b705cfSriastradh
75203b705cfSriastradhbool sna_composite_create(struct sna *sna);
75303b705cfSriastradhvoid sna_composite_close(struct sna *sna);
75403b705cfSriastradh
75503b705cfSriastradhvoid sna_composite(CARD8 op,
75603b705cfSriastradh		   PicturePtr src,
75703b705cfSriastradh		   PicturePtr mask,
75803b705cfSriastradh		   PicturePtr dst,
75903b705cfSriastradh		   INT16 src_x,  INT16 src_y,
76003b705cfSriastradh		   INT16 mask_x, INT16 mask_y,
76103b705cfSriastradh		   INT16 dst_x,  INT16 dst_y,
76203b705cfSriastradh		   CARD16 width, CARD16 height);
76303b705cfSriastradhvoid sna_composite_fb(CARD8 op,
76403b705cfSriastradh		      PicturePtr src,
76503b705cfSriastradh		      PicturePtr mask,
76603b705cfSriastradh		      PicturePtr dst,
76703b705cfSriastradh		      RegionPtr region,
76803b705cfSriastradh		      INT16 src_x,  INT16 src_y,
76903b705cfSriastradh		      INT16 mask_x, INT16 mask_y,
77003b705cfSriastradh		      INT16 dst_x,  INT16 dst_y,
77103b705cfSriastradh		      CARD16 width, CARD16 height);
77203b705cfSriastradhvoid sna_composite_rectangles(CARD8		 op,
77303b705cfSriastradh			      PicturePtr		 dst,
77403b705cfSriastradh			      xRenderColor	*color,
77503b705cfSriastradh			      int			 num_rects,
77603b705cfSriastradh			      xRectangle		*rects);
77703b705cfSriastradhvoid sna_composite_trapezoids(CARD8 op,
77803b705cfSriastradh			      PicturePtr src,
77903b705cfSriastradh			      PicturePtr dst,
78003b705cfSriastradh			      PictFormatPtr maskFormat,
78103b705cfSriastradh			      INT16 xSrc, INT16 ySrc,
78203b705cfSriastradh			      int ntrap, xTrapezoid *traps);
78303b705cfSriastradhvoid sna_add_traps(PicturePtr picture, INT16 x, INT16 y, int n, xTrap *t);
78403b705cfSriastradh
78503b705cfSriastradhvoid sna_composite_triangles(CARD8 op,
78603b705cfSriastradh			     PicturePtr src,
78703b705cfSriastradh			     PicturePtr dst,
78803b705cfSriastradh			     PictFormatPtr maskFormat,
78903b705cfSriastradh			     INT16 xSrc, INT16 ySrc,
79003b705cfSriastradh			     int ntri, xTriangle *tri);
79103b705cfSriastradh
79203b705cfSriastradhvoid sna_composite_tristrip(CARD8 op,
79303b705cfSriastradh			    PicturePtr src,
79403b705cfSriastradh			    PicturePtr dst,
79503b705cfSriastradh			    PictFormatPtr maskFormat,
79603b705cfSriastradh			    INT16 xSrc, INT16 ySrc,
79703b705cfSriastradh			    int npoints, xPointFixed *points);
79803b705cfSriastradh
79903b705cfSriastradhvoid sna_composite_trifan(CARD8 op,
80003b705cfSriastradh			  PicturePtr src,
80103b705cfSriastradh			  PicturePtr dst,
80203b705cfSriastradh			  PictFormatPtr maskFormat,
80303b705cfSriastradh			  INT16 xSrc, INT16 ySrc,
80403b705cfSriastradh			  int npoints, xPointFixed *points);
80503b705cfSriastradh
80603b705cfSriastradhbool sna_gradients_create(struct sna *sna);
80703b705cfSriastradhvoid sna_gradients_close(struct sna *sna);
80803b705cfSriastradh
80903b705cfSriastradhbool sna_glyphs_create(struct sna *sna);
81003b705cfSriastradhvoid sna_glyphs(CARD8 op,
81103b705cfSriastradh		PicturePtr src,
81203b705cfSriastradh		PicturePtr dst,
81303b705cfSriastradh		PictFormatPtr mask,
81403b705cfSriastradh		INT16 xSrc, INT16 ySrc,
81503b705cfSriastradh		int nlist,
81603b705cfSriastradh		GlyphListPtr list,
81703b705cfSriastradh		GlyphPtr *glyphs);
81803b705cfSriastradhvoid sna_glyphs__shared(CARD8 op,
81903b705cfSriastradh			PicturePtr src,
82003b705cfSriastradh			PicturePtr dst,
82103b705cfSriastradh			PictFormatPtr mask,
82203b705cfSriastradh			INT16 src_x, INT16 src_y,
82303b705cfSriastradh			int nlist, GlyphListPtr list, GlyphPtr *glyphs);
82403b705cfSriastradhvoid sna_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
82503b705cfSriastradhvoid sna_glyphs_close(struct sna *sna);
82603b705cfSriastradh
82703b705cfSriastradhvoid sna_read_boxes(struct sna *sna, PixmapPtr dst, struct kgem_bo *src_bo,
82803b705cfSriastradh		    const BoxRec *box, int n);
82903b705cfSriastradhbool sna_write_boxes(struct sna *sna, PixmapPtr dst,
83003b705cfSriastradh		     struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
83103b705cfSriastradh		     const void *src, int stride, int16_t src_dx, int16_t src_dy,
83203b705cfSriastradh		     const BoxRec *box, int n);
83303b705cfSriastradhvoid sna_write_boxes__xor(struct sna *sna, PixmapPtr dst,
83403b705cfSriastradh			  struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
83503b705cfSriastradh			  const void *src, int stride, int16_t src_dx, int16_t src_dy,
83603b705cfSriastradh			  const BoxRec *box, int nbox,
83703b705cfSriastradh			  uint32_t and, uint32_t or);
83803b705cfSriastradh
83903b705cfSriastradhbool sna_replace(struct sna *sna,
84003b705cfSriastradh		 PixmapPtr pixmap,
84103b705cfSriastradh		 struct kgem_bo **bo,
84203b705cfSriastradh		 const void *src, int stride);
84303b705cfSriastradhstruct kgem_bo *sna_replace__xor(struct sna *sna,
84403b705cfSriastradh				 PixmapPtr pixmap,
84503b705cfSriastradh				 struct kgem_bo *bo,
84603b705cfSriastradh				 const void *src, int stride,
84703b705cfSriastradh				 uint32_t and, uint32_t or);
84803b705cfSriastradh
84903b705cfSriastradhbool
85003b705cfSriastradhsna_compute_composite_extents(BoxPtr extents,
85103b705cfSriastradh			      PicturePtr src, PicturePtr mask, PicturePtr dst,
85203b705cfSriastradh			      INT16 src_x,  INT16 src_y,
85303b705cfSriastradh			      INT16 mask_x, INT16 mask_y,
85403b705cfSriastradh			      INT16 dst_x,  INT16 dst_y,
85503b705cfSriastradh			      CARD16 width, CARD16 height);
85603b705cfSriastradhbool
85703b705cfSriastradhsna_compute_composite_region(RegionPtr region,
85803b705cfSriastradh			     PicturePtr src, PicturePtr mask, PicturePtr dst,
85903b705cfSriastradh			     INT16 src_x,  INT16 src_y,
86003b705cfSriastradh			     INT16 mask_x, INT16 mask_y,
86103b705cfSriastradh			     INT16 dst_x,  INT16 dst_y,
86203b705cfSriastradh			     CARD16 width, CARD16 height);
86303b705cfSriastradh
86403b705cfSriastradhvoid
86503b705cfSriastradhmemcpy_blt(const void *src, void *dst, int bpp,
86603b705cfSriastradh	   int32_t src_stride, int32_t dst_stride,
86703b705cfSriastradh	   int16_t src_x, int16_t src_y,
86803b705cfSriastradh	   int16_t dst_x, int16_t dst_y,
86903b705cfSriastradh	   uint16_t width, uint16_t height);
87003b705cfSriastradh
87103b705cfSriastradhvoid
87203b705cfSriastradhmemmove_box(const void *src, void *dst,
87303b705cfSriastradh	    int bpp, int32_t stride,
87403b705cfSriastradh	    const BoxRec *box,
87503b705cfSriastradh	    int dx, int dy);
87603b705cfSriastradh
87703b705cfSriastradhvoid
87803b705cfSriastradhmemcpy_xor(const void *src, void *dst, int bpp,
87903b705cfSriastradh	   int32_t src_stride, int32_t dst_stride,
88003b705cfSriastradh	   int16_t src_x, int16_t src_y,
88103b705cfSriastradh	   int16_t dst_x, int16_t dst_y,
88203b705cfSriastradh	   uint16_t width, uint16_t height,
88303b705cfSriastradh	   uint32_t and, uint32_t or);
88403b705cfSriastradh
88503b705cfSriastradh#define SNA_CREATE_FB 0x10
88603b705cfSriastradh#define SNA_CREATE_SCRATCH 0x11
88703b705cfSriastradh#define SNA_CREATE_GLYPHS 0x12
88803b705cfSriastradh
88903b705cfSriastradhinline static bool is_power_of_two(unsigned x)
89003b705cfSriastradh{
89103b705cfSriastradh	return (x & (x-1)) == 0;
89203b705cfSriastradh}
89303b705cfSriastradh
89403b705cfSriastradhinline static bool is_clipped(const RegionRec *r,
89503b705cfSriastradh			      const DrawableRec *d)
89603b705cfSriastradh{
89703b705cfSriastradh	return (r->data ||
89803b705cfSriastradh		r->extents.x2 - r->extents.x1 != d->width ||
89903b705cfSriastradh		r->extents.y2 - r->extents.y1 != d->height);
90003b705cfSriastradh}
90103b705cfSriastradh
90203b705cfSriastradhinline static bool
90303b705cfSriastradhbox_intersect(BoxPtr a, const BoxRec *b)
90403b705cfSriastradh{
90503b705cfSriastradh	if (a->x1 < b->x1)
90603b705cfSriastradh		a->x1 = b->x1;
90703b705cfSriastradh	if (a->x2 > b->x2)
90803b705cfSriastradh		a->x2 = b->x2;
90903b705cfSriastradh	if (a->x1 >= a->x2)
91003b705cfSriastradh		return false;
91103b705cfSriastradh
91203b705cfSriastradh	if (a->y1 < b->y1)
91303b705cfSriastradh		a->y1 = b->y1;
91403b705cfSriastradh	if (a->y2 > b->y2)
91503b705cfSriastradh		a->y2 = b->y2;
91603b705cfSriastradh	if (a->y1 >= a->y2)
91703b705cfSriastradh		return false;
91803b705cfSriastradh
91903b705cfSriastradh	return true;
92003b705cfSriastradh}
92103b705cfSriastradh
92203b705cfSriastradhunsigned sna_cpu_detect(void);
92303b705cfSriastradhchar *sna_cpu_features_to_string(unsigned features, char *line);
92403b705cfSriastradh
92503b705cfSriastradhvoid sna_threads_init(void);
92603b705cfSriastradhint sna_use_threads (int width, int height, int threshold);
92703b705cfSriastradhvoid sna_threads_run(void (*func)(void *arg), void *arg);
92803b705cfSriastradhvoid sna_threads_wait(void);
92903b705cfSriastradh
93003b705cfSriastradhvoid sna_image_composite(pixman_op_t        op,
93103b705cfSriastradh			 pixman_image_t    *src,
93203b705cfSriastradh			 pixman_image_t    *mask,
93303b705cfSriastradh			 pixman_image_t    *dst,
93403b705cfSriastradh			 int16_t            src_x,
93503b705cfSriastradh			 int16_t            src_y,
93603b705cfSriastradh			 int16_t            mask_x,
93703b705cfSriastradh			 int16_t            mask_y,
93803b705cfSriastradh			 int16_t            dst_x,
93903b705cfSriastradh			 int16_t            dst_y,
94003b705cfSriastradh			 uint16_t           width,
94103b705cfSriastradh			 uint16_t           height);
94203b705cfSriastradh
94303b705cfSriastradh#endif /* _SNA_H */
944