sna.h revision 03b705cf
1/**************************************************************************
2
3Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4Copyright © 2002 David Dawes
5
6All Rights Reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining a
9copy of this software and associated documentation files (the
10"Software"), to deal in the Software without restriction, including
11without limitation the rights to use, copy, modify, merge, publish,
12distribute, sub license, and/or sell copies of the Software, and to
13permit persons to whom the Software is furnished to do so, subject to
14the following conditions:
15
16The above copyright notice and this permission notice (including the
17next paragraph) shall be included in all copies or substantial portions
18of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
24ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28**************************************************************************/
29
30/*
31 * Authors:
32 *   Keith Whitwell <keith@tungstengraphics.com>
33 *   David Dawes <dawes@xfree86.org>
34 *
35 */
36
37#ifndef _SNA_H_
38#define _SNA_H_
39
40#ifdef HAVE_CONFIG_H
41#include "config.h"
42#endif
43
44#include <stdint.h>
45
46#include "compiler.h"
47
48#include <xorg-server.h>
49
50#include <xf86Crtc.h>
51#if XF86_CRTC_VERSION >= 5
52#define HAS_PIXMAP_SHARING 1
53#endif
54
55#include <xf86str.h>
56#include <windowstr.h>
57#include <glyphstr.h>
58#include <picturestr.h>
59#include <gcstruct.h>
60#include <xvdix.h>
61
62#include <pciaccess.h>
63
64#include <xf86drmMode.h>
65
66#include "../compat-api.h"
67#include <drm.h>
68#include <i915_drm.h>
69
70#ifdef HAVE_DRI2_H
71#include <dri2.h>
72#endif
73
74#if HAVE_UDEV
75#include <libudev.h>
76#endif
77
78#if HAS_DEBUG_FULL
79#define DBG(x) ErrorF x
80#else
81#define DBG(x)
82#endif
83
84#define DEBUG_NO_BLT 0
85
86#define DEBUG_FLUSH_BATCH 0
87
88#define TEST_ALL 0
89#define TEST_ACCEL (TEST_ALL || 0)
90#define TEST_BATCH (TEST_ALL || 0)
91#define TEST_BLT (TEST_ALL || 0)
92#define TEST_COMPOSITE (TEST_ALL || 0)
93#define TEST_DAMAGE (TEST_ALL || 0)
94#define TEST_GRADIENT (TEST_ALL || 0)
95#define TEST_GLYPHS (TEST_ALL || 0)
96#define TEST_IO (TEST_ALL || 0)
97#define TEST_KGEM (TEST_ALL || 0)
98#define TEST_RENDER (TEST_ALL || 0)
99
100#include "intel_driver.h"
101#include "intel_list.h"
102#include "kgem.h"
103#include "sna_damage.h"
104#include "sna_render.h"
105#include "fb/fb.h"
106
107#define SNA_CURSOR_X			64
108#define SNA_CURSOR_Y			SNA_CURSOR_X
109
110struct sna_client {
111	int is_compositor; /* only 4 bits used */
112};
113
114extern DevPrivateKeyRec sna_client_key;
115
116pure static inline struct sna_client *sna_client(ClientPtr client)
117{
118	return __get_private(client, sna_client_key);
119}
120
121struct sna_cow {
122	struct kgem_bo *bo;
123	struct list list;
124	int refcnt;
125};
126
127struct sna_pixmap {
128	PixmapPtr pixmap;
129	struct kgem_bo *gpu_bo, *cpu_bo;
130	struct sna_damage *gpu_damage, *cpu_damage;
131	struct sna_cow *cow;
132	void *ptr;
133#define PTR(ptr) ((void*)((uintptr_t)(ptr) & ~1))
134
135	struct list flush_list;
136	struct list cow_list;
137
138	uint32_t stride;
139	uint32_t clear_color;
140
141#define SOURCE_BIAS 4
142	uint16_t source_count;
143	uint8_t pinned :3;
144#define PIN_SCANOUT 0x1
145#define PIN_DRI 0x2
146#define PIN_PRIME 0x4
147	uint8_t create :4;
148	uint8_t mapped :1;
149	uint8_t flush :1;
150	uint8_t shm :1;
151	uint8_t clear :1;
152	uint8_t header :1;
153	uint8_t cpu :1;
154};
155
156struct sna_glyph {
157	PicturePtr atlas;
158	struct sna_coordinate coordinate;
159	uint16_t size, pos;
160	pixman_image_t *image;
161};
162
163static inline WindowPtr get_root_window(ScreenPtr screen)
164{
165#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,10,0,0,0)
166	return screen->root;
167#else
168	return WindowTable[screen->myNum];
169#endif
170}
171
172static inline PixmapPtr get_window_pixmap(WindowPtr window)
173{
174	return fbGetWindowPixmap(window);
175}
176
177static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
178{
179	if (drawable->type == DRAWABLE_PIXMAP)
180		return (PixmapPtr)drawable;
181	else
182		return get_window_pixmap((WindowPtr)drawable);
183}
184
185extern DevPrivateKeyRec sna_pixmap_key;
186
187pure static inline struct sna_pixmap *sna_pixmap(PixmapPtr pixmap)
188{
189	return ((void **)__get_private(pixmap, sna_pixmap_key))[1];
190}
191
192static inline struct sna_pixmap *sna_pixmap_from_drawable(DrawablePtr drawable)
193{
194	return sna_pixmap(get_drawable_pixmap(drawable));
195}
196
197struct sna_gc {
198	long changes;
199	long serial;
200
201	GCFuncs *old_funcs;
202	void *priv;
203};
204
205static inline struct sna_gc *sna_gc(GCPtr gc)
206{
207	return (struct sna_gc *)__get_private(gc, sna_gc_key);
208}
209
210enum {
211	FLUSH_TIMER = 0,
212	THROTTLE_TIMER,
213	EXPIRE_TIMER,
214#if DEBUG_MEMORY
215	DEBUG_MEMORY_TIMER,
216#endif
217	NUM_TIMERS
218};
219
220struct sna {
221	struct kgem kgem;
222
223	ScrnInfoPtr scrn;
224
225	unsigned flags;
226#define SNA_NO_WAIT		0x1
227#define SNA_NO_FLIP		0x2
228#define SNA_TRIPLE_BUFFER	0x4
229#define SNA_TEAR_FREE		0x10
230#define SNA_FORCE_SHADOW	0x20
231#define SNA_FLUSH_GTT		0x40
232#define SNA_IS_HOSTED		0x80
233#define SNA_REPROBE		0x80000000
234
235	unsigned cpu_features;
236#define MMX 0x1
237#define SSE 0x2
238#define SSE2 0x4
239#define SSE3 0x8
240#define SSSE3 0x10
241#define SSE4_1 0x20
242#define SSE4_2 0x40
243#define AVX 0x80
244#define AVX2 0x100
245
246	unsigned watch_flush;
247
248	struct timeval timer_tv;
249	uint32_t timer_expire[NUM_TIMERS];
250	uint16_t timer_active;
251
252	int vblank_interval;
253
254	struct list flush_pixmaps;
255	struct list active_pixmaps;
256
257	PixmapPtr front;
258	PixmapPtr freed_pixmap;
259
260	struct sna_mode {
261		drmModeResPtr kmode;
262
263		int shadow_active;
264		DamagePtr shadow_damage;
265		struct kgem_bo *shadow;
266		int shadow_flip;
267	} mode;
268
269	struct sna_dri {
270		void *flip_pending;
271	} dri;
272
273	struct sna_xv {
274		XvAdaptorPtr adaptors;
275		int num_adaptors;
276	} xv;
277
278	unsigned int tiling;
279#define SNA_TILING_FB		0x1
280#define SNA_TILING_2D		0x2
281#define SNA_TILING_ALL (~0)
282
283	EntityInfoPtr pEnt;
284	struct pci_device *PciInfo;
285	const struct intel_device_info *info;
286
287	ScreenBlockHandlerProcPtr BlockHandler;
288	ScreenWakeupHandlerProcPtr WakeupHandler;
289	CloseScreenProcPtr CloseScreen;
290
291	PicturePtr clear;
292	struct {
293		uint32_t fill_bo;
294		uint32_t fill_pixel;
295		uint32_t fill_alu;
296	} blt_state;
297	union {
298		struct gen2_render_state gen2;
299		struct gen3_render_state gen3;
300		struct gen4_render_state gen4;
301		struct gen5_render_state gen5;
302		struct gen6_render_state gen6;
303		struct gen7_render_state gen7;
304	} render_state;
305
306	bool dri_available;
307	bool dri_open;
308
309	/* Broken-out options. */
310	OptionInfoPtr Options;
311
312	/* Driver phase/state information */
313	bool suspended;
314
315#if HAVE_UDEV
316	struct udev_monitor *uevent_monitor;
317	InputHandlerProc uevent_handler;
318#endif
319
320	struct sna_render render;
321
322#if DEBUG_MEMORY
323	struct {
324		int pixmap_allocs;
325		int cpu_bo_allocs;
326		size_t shadow_pixels_bytes;
327		size_t cpu_bo_bytes;
328	} debug_memory;
329#endif
330};
331
332bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna);
333bool sna_mode_fake_init(struct sna *sna);
334void sna_mode_adjust_frame(struct sna *sna, int x, int y);
335extern void sna_mode_update(struct sna *sna);
336extern void sna_mode_wakeup(struct sna *sna);
337extern void sna_mode_redisplay(struct sna *sna);
338extern void sna_mode_close(struct sna *sna);
339extern void sna_mode_fini(struct sna *sna);
340
341extern int sna_page_flip(struct sna *sna,
342			 struct kgem_bo *bo,
343			 void *data,
344			 int ref_crtc_hw_id);
345
346pure static inline struct sna *
347to_sna(ScrnInfoPtr scrn)
348{
349	return (struct sna *)(scrn->driverPrivate);
350}
351
352pure static inline struct sna *
353to_sna_from_screen(ScreenPtr screen)
354{
355	return to_sna(xf86ScreenToScrn(screen));
356}
357
358pure static inline struct sna *
359to_sna_from_pixmap(PixmapPtr pixmap)
360{
361	return ((void **)__get_private(pixmap, sna_pixmap_key))[0];
362}
363
364pure static inline struct sna *
365to_sna_from_drawable(DrawablePtr drawable)
366{
367	return to_sna_from_screen(drawable->pScreen);
368}
369
370static inline struct sna *
371to_sna_from_kgem(struct kgem *kgem)
372{
373	return container_of(kgem, struct sna, kgem);
374}
375
376#ifndef ARRAY_SIZE
377#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
378#endif
379
380#ifndef ALIGN
381#define ALIGN(i,m)	(((i) + (m) - 1) & ~((m) - 1))
382#endif
383
384#ifndef MIN
385#define MIN(a,b)	((a) <= (b) ? (a) : (b))
386#endif
387
388#ifndef MAX
389#define MAX(a,b)	((a) >= (b) ? (a) : (b))
390#endif
391
392extern xf86CrtcPtr sna_covering_crtc(ScrnInfoPtr scrn,
393				     const BoxRec *box,
394				     xf86CrtcPtr desired);
395
396extern bool sna_wait_for_scanline(struct sna *sna, PixmapPtr pixmap,
397				  xf86CrtcPtr crtc, const BoxRec *clip);
398
399#if HAVE_DRI2_H
400bool sna_dri_open(struct sna *sna, ScreenPtr pScreen);
401void sna_dri_page_flip_handler(struct sna *sna, struct drm_event_vblank *event);
402void sna_dri_vblank_handler(struct sna *sna, struct drm_event_vblank *event);
403void sna_dri_destroy_window(WindowPtr win);
404void sna_dri_close(struct sna *sna, ScreenPtr pScreen);
405#else
406static inline bool sna_dri_open(struct sna *sna, ScreenPtr pScreen) { return false; }
407static inline void sna_dri_page_flip_handler(struct sna *sna, struct drm_event_vblank *event) { }
408static inline void sna_dri_vblank_handler(struct sna *sna, struct drm_event_vblank *event) { }
409static inline void sna_dri_destroy_window(WindowPtr win) { }
410static inline void sna_dri_close(struct sna *sna, ScreenPtr pScreen) { }
411#endif
412void sna_dri_pixmap_update_bo(struct sna *sna, PixmapPtr pixmap);
413
414extern int sna_crtc_to_pipe(xf86CrtcPtr crtc);
415extern uint32_t sna_crtc_to_plane(xf86CrtcPtr crtc);
416extern uint32_t sna_crtc_id(xf86CrtcPtr crtc);
417
418CARD32 sna_format_for_depth(int depth);
419CARD32 sna_render_format_for_depth(int depth);
420
421void sna_debug_flush(struct sna *sna);
422
423static inline bool
424get_drawable_deltas(DrawablePtr drawable, PixmapPtr pixmap, int16_t *x, int16_t *y)
425{
426#ifdef COMPOSITE
427	if (drawable->type == DRAWABLE_WINDOW) {
428		*x = -pixmap->screen_x;
429		*y = -pixmap->screen_y;
430		return pixmap->screen_x | pixmap->screen_y;
431	}
432#endif
433	*x = *y = 0;
434	return false;
435}
436
437static inline int
438get_drawable_dx(DrawablePtr drawable)
439{
440#ifdef COMPOSITE
441	if (drawable->type == DRAWABLE_WINDOW)
442		return -get_drawable_pixmap(drawable)->screen_x;
443#endif
444	return 0;
445}
446
447static inline int
448get_drawable_dy(DrawablePtr drawable)
449{
450#ifdef COMPOSITE
451	if (drawable->type == DRAWABLE_WINDOW)
452		return -get_drawable_pixmap(drawable)->screen_y;
453#endif
454	return 0;
455}
456
457bool sna_pixmap_attach_to_bo(PixmapPtr pixmap, struct kgem_bo *bo);
458static inline bool sna_pixmap_is_scanout(struct sna *sna, PixmapPtr pixmap)
459{
460	return (pixmap == sna->front &&
461		!sna->mode.shadow_active &&
462		(sna->flags & SNA_NO_WAIT) == 0);
463}
464
465PixmapPtr sna_pixmap_create_upload(ScreenPtr screen,
466				   int width, int height, int depth,
467				   unsigned flags);
468PixmapPtr sna_pixmap_create_unattached(ScreenPtr screen,
469				       int width, int height, int depth);
470void sna_pixmap_destroy(PixmapPtr pixmap);
471
472bool
473sna_pixmap_undo_cow(struct sna *sna, struct sna_pixmap *priv, unsigned flags);
474
475#define MOVE_WRITE 0x1
476#define MOVE_READ 0x2
477#define MOVE_INPLACE_HINT 0x4
478#define MOVE_ASYNC_HINT 0x8
479#define MOVE_SOURCE_HINT 0x10
480#define MOVE_WHOLE_HINT 0x20
481#define __MOVE_FORCE 0x40
482#define __MOVE_DRI 0x80
483
484bool
485sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, const BoxRec *box, unsigned int flags);
486
487struct sna_pixmap *sna_pixmap_move_to_gpu(PixmapPtr pixmap, unsigned flags);
488static inline struct sna_pixmap *
489sna_pixmap_force_to_gpu(PixmapPtr pixmap, unsigned flags)
490{
491	/* Unlike move-to-gpu, we ignore wedged and always create the GPU bo */
492	DBG(("%s(pixmap=%p, flags=%x)\n", __FUNCTION__, pixmap, flags));
493	return sna_pixmap_move_to_gpu(pixmap, flags | __MOVE_FORCE);
494}
495bool must_check _sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags);
496static inline bool must_check sna_pixmap_move_to_cpu(PixmapPtr pixmap, unsigned flags)
497{
498	if (flags == MOVE_READ) {
499		struct sna_pixmap *priv = sna_pixmap(pixmap);
500		if (priv == NULL)
501			return true;
502	}
503
504	return _sna_pixmap_move_to_cpu(pixmap, flags);
505}
506bool must_check sna_drawable_move_region_to_cpu(DrawablePtr drawable,
507						RegionPtr region,
508						unsigned flags);
509
510bool must_check sna_drawable_move_to_cpu(DrawablePtr drawable, unsigned flags);
511
512static inline bool must_check
513sna_drawable_move_to_gpu(DrawablePtr drawable, unsigned flags)
514{
515	return sna_pixmap_move_to_gpu(get_drawable_pixmap(drawable), flags) != NULL;
516}
517
518void sna_add_flush_pixmap(struct sna *sna,
519			  struct sna_pixmap *priv,
520			  struct kgem_bo *bo);
521
522struct kgem_bo *sna_pixmap_change_tiling(PixmapPtr pixmap, uint32_t tiling);
523
524#define PREFER_GPU	0x1
525#define FORCE_GPU	0x2
526#define RENDER_GPU	0x4
527#define IGNORE_CPU	0x8
528#define REPLACES	0x10
529struct kgem_bo *
530sna_drawable_use_bo(DrawablePtr drawable, unsigned flags, const BoxRec *box,
531		    struct sna_damage ***damage);
532
533inline static int16_t bound(int16_t a, uint16_t b)
534{
535	int v = (int)a + (int)b;
536	if (v > MAXSHORT)
537		return MAXSHORT;
538	return v;
539}
540
541inline static int16_t clamp(int16_t a, int16_t b)
542{
543	int v = (int)a + (int)b;
544	if (v > MAXSHORT)
545		return MAXSHORT;
546	if (v < MINSHORT)
547		return MINSHORT;
548	return v;
549}
550
551static inline bool box_empty(const BoxRec *box)
552{
553	return box->x2 <= box->x1 || box->y2 <= box->y1;
554}
555
556static inline bool
557box_inplace(PixmapPtr pixmap, const BoxRec *box)
558{
559	struct sna *sna = to_sna_from_pixmap(pixmap);
560	return ((int)(box->x2 - box->x1) * (int)(box->y2 - box->y1) * pixmap->drawable.bitsPerPixel >> 12) >= sna->kgem.half_cpu_cache_pages;
561}
562
563static inline bool
564region_subsumes_drawable(RegionPtr region, DrawablePtr drawable)
565{
566	const BoxRec *extents;
567
568	if (region->data)
569		return false;
570
571	extents = RegionExtents(region);
572	return  extents->x1 <= 0 && extents->y1 <= 0 &&
573		extents->x2 >= drawable->width &&
574		extents->y2 >= drawable->height;
575}
576
577static inline bool
578region_subsumes_damage(const RegionRec *region, struct sna_damage *damage)
579{
580	const BoxRec *re, *de;
581
582	DBG(("%s?\n", __FUNCTION__));
583	assert(damage);
584
585	re = &region->extents;
586	de = &DAMAGE_PTR(damage)->extents;
587	DBG(("%s: region (%d, %d), (%d, %d), damage (%d, %d), (%d, %d)\n",
588	     __FUNCTION__,
589	     re->x1, re->y1, re->x2, re->y2,
590	     de->x1, de->y1, de->x2, de->y2));
591
592	if (re->x2 < de->x2 || re->x1 > de->x1 ||
593	    re->y2 < de->y2 || re->y1 > de->y1) {
594		DBG(("%s: not contained\n", __FUNCTION__));
595		return false;
596	}
597
598	if (region->data == NULL) {
599		DBG(("%s: singular region contains damage\n", __FUNCTION__));
600		return true;
601	}
602
603	return pixman_region_contains_rectangle((RegionPtr)region,
604						(BoxPtr)de) == PIXMAN_REGION_IN;
605}
606
607
608static inline bool
609sna_drawable_is_clear(DrawablePtr d)
610{
611	struct sna_pixmap *priv = sna_pixmap(get_drawable_pixmap(d));
612	return priv && priv->clear && priv->clear_color == 0;
613}
614
615static inline struct kgem_bo *__sna_pixmap_get_bo(PixmapPtr pixmap)
616{
617	return sna_pixmap(pixmap)->gpu_bo;
618}
619
620static inline struct kgem_bo *__sna_drawable_peek_bo(DrawablePtr d)
621{
622	return sna_pixmap(get_drawable_pixmap(d))->gpu_bo;
623}
624
625static inline struct kgem_bo *sna_pixmap_pin(PixmapPtr pixmap, unsigned flags)
626{
627	struct sna_pixmap *priv;
628
629	priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_WRITE);
630	if (!priv)
631		return NULL;
632
633	priv->pinned |= flags;
634	return priv->gpu_bo;
635}
636
637
638static inline bool
639_sna_transform_point(const PictTransform *transform,
640		     int64_t x, int64_t y, int64_t result[3])
641{
642	int j;
643
644	for (j = 0; j < 3; j++)
645		result[j] = (transform->matrix[j][0] * x +
646			     transform->matrix[j][1] * y +
647			     transform->matrix[j][2]);
648
649	return result[2] != 0;
650}
651
652static inline void
653_sna_get_transformed_coordinates(int x, int y,
654				 const PictTransform *transform,
655				 float *x_out, float *y_out)
656{
657
658	int64_t result[3];
659
660	_sna_transform_point(transform, x, y, result);
661	*x_out = result[0] / (double)result[2];
662	*y_out = result[1] / (double)result[2];
663}
664
665static inline void
666_sna_get_transformed_scaled(int x, int y,
667			    const PictTransform *transform, const float *sf,
668			    float *x_out, float *y_out)
669{
670	*x_out = sf[0] * (transform->matrix[0][0] * x +
671			  transform->matrix[0][1] * y +
672			  transform->matrix[0][2]);
673
674	*y_out = sf[1] * (transform->matrix[1][0] * x +
675			  transform->matrix[1][1] * y +
676			  transform->matrix[1][2]);
677}
678
679void
680sna_get_transformed_coordinates(int x, int y,
681				const PictTransform *transform,
682				float *x_out, float *y_out);
683
684void
685sna_get_transformed_coordinates_3d(int x, int y,
686				   const PictTransform *transform,
687				   float *x_out, float *y_out, float *z_out);
688
689bool sna_transform_is_affine(const PictTransform *t);
690bool sna_transform_is_integer_translation(const PictTransform *t,
691					  int16_t *tx, int16_t *ty);
692bool sna_transform_is_translation(const PictTransform *t,
693				  pixman_fixed_t *tx, pixman_fixed_t *ty);
694static inline bool
695sna_affine_transform_is_rotation(const PictTransform *t)
696{
697	assert(sna_transform_is_affine(t));
698	return t->matrix[0][1] | t->matrix[1][0];
699}
700
701static inline bool
702sna_transform_equal(const PictTransform *a, const PictTransform *b)
703{
704	if (a == b)
705		return true;
706
707	if (a == NULL || b == NULL)
708		return false;
709
710	return memcmp(a, b, sizeof(*a)) == 0;
711}
712
713static inline bool
714sna_picture_alphamap_equal(PicturePtr a, PicturePtr b)
715{
716	if (a->alphaMap != b->alphaMap)
717		return false;
718
719	if (a->alphaMap)
720		return false;
721
722	return (a->alphaOrigin.x == b->alphaOrigin.x &&
723		a->alphaOrigin.y == b->alphaOrigin.y);
724}
725
726static inline bool wedged(struct sna *sna)
727{
728	return unlikely(sna->kgem.wedged);
729}
730
731static inline bool can_render(struct sna *sna)
732{
733	return likely(!sna->kgem.wedged && sna->render.prefer_gpu & PREFER_GPU_RENDER);
734}
735
736static inline uint32_t pixmap_size(PixmapPtr pixmap)
737{
738	return (pixmap->drawable.height - 1) * pixmap->devKind +
739		pixmap->drawable.width * pixmap->drawable.bitsPerPixel/8;
740}
741
742bool sna_accel_init(ScreenPtr sreen, struct sna *sna);
743void sna_accel_create(struct sna *sna);
744void sna_accel_block_handler(struct sna *sna, struct timeval **tv);
745void sna_accel_wakeup_handler(struct sna *sna);
746void sna_accel_watch_flush(struct sna *sna, int enable);
747void sna_accel_close(struct sna *sna);
748void sna_accel_free(struct sna *sna);
749
750void sna_copy_fbcon(struct sna *sna);
751
752bool sna_composite_create(struct sna *sna);
753void sna_composite_close(struct sna *sna);
754
755void sna_composite(CARD8 op,
756		   PicturePtr src,
757		   PicturePtr mask,
758		   PicturePtr dst,
759		   INT16 src_x,  INT16 src_y,
760		   INT16 mask_x, INT16 mask_y,
761		   INT16 dst_x,  INT16 dst_y,
762		   CARD16 width, CARD16 height);
763void sna_composite_fb(CARD8 op,
764		      PicturePtr src,
765		      PicturePtr mask,
766		      PicturePtr dst,
767		      RegionPtr region,
768		      INT16 src_x,  INT16 src_y,
769		      INT16 mask_x, INT16 mask_y,
770		      INT16 dst_x,  INT16 dst_y,
771		      CARD16 width, CARD16 height);
772void sna_composite_rectangles(CARD8		 op,
773			      PicturePtr		 dst,
774			      xRenderColor	*color,
775			      int			 num_rects,
776			      xRectangle		*rects);
777void sna_composite_trapezoids(CARD8 op,
778			      PicturePtr src,
779			      PicturePtr dst,
780			      PictFormatPtr maskFormat,
781			      INT16 xSrc, INT16 ySrc,
782			      int ntrap, xTrapezoid *traps);
783void sna_add_traps(PicturePtr picture, INT16 x, INT16 y, int n, xTrap *t);
784
785void sna_composite_triangles(CARD8 op,
786			     PicturePtr src,
787			     PicturePtr dst,
788			     PictFormatPtr maskFormat,
789			     INT16 xSrc, INT16 ySrc,
790			     int ntri, xTriangle *tri);
791
792void sna_composite_tristrip(CARD8 op,
793			    PicturePtr src,
794			    PicturePtr dst,
795			    PictFormatPtr maskFormat,
796			    INT16 xSrc, INT16 ySrc,
797			    int npoints, xPointFixed *points);
798
799void sna_composite_trifan(CARD8 op,
800			  PicturePtr src,
801			  PicturePtr dst,
802			  PictFormatPtr maskFormat,
803			  INT16 xSrc, INT16 ySrc,
804			  int npoints, xPointFixed *points);
805
806bool sna_gradients_create(struct sna *sna);
807void sna_gradients_close(struct sna *sna);
808
809bool sna_glyphs_create(struct sna *sna);
810void sna_glyphs(CARD8 op,
811		PicturePtr src,
812		PicturePtr dst,
813		PictFormatPtr mask,
814		INT16 xSrc, INT16 ySrc,
815		int nlist,
816		GlyphListPtr list,
817		GlyphPtr *glyphs);
818void sna_glyphs__shared(CARD8 op,
819			PicturePtr src,
820			PicturePtr dst,
821			PictFormatPtr mask,
822			INT16 src_x, INT16 src_y,
823			int nlist, GlyphListPtr list, GlyphPtr *glyphs);
824void sna_glyph_unrealize(ScreenPtr screen, GlyphPtr glyph);
825void sna_glyphs_close(struct sna *sna);
826
827void sna_read_boxes(struct sna *sna, PixmapPtr dst, struct kgem_bo *src_bo,
828		    const BoxRec *box, int n);
829bool sna_write_boxes(struct sna *sna, PixmapPtr dst,
830		     struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
831		     const void *src, int stride, int16_t src_dx, int16_t src_dy,
832		     const BoxRec *box, int n);
833void sna_write_boxes__xor(struct sna *sna, PixmapPtr dst,
834			  struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
835			  const void *src, int stride, int16_t src_dx, int16_t src_dy,
836			  const BoxRec *box, int nbox,
837			  uint32_t and, uint32_t or);
838
839bool sna_replace(struct sna *sna,
840		 PixmapPtr pixmap,
841		 struct kgem_bo **bo,
842		 const void *src, int stride);
843struct kgem_bo *sna_replace__xor(struct sna *sna,
844				 PixmapPtr pixmap,
845				 struct kgem_bo *bo,
846				 const void *src, int stride,
847				 uint32_t and, uint32_t or);
848
849bool
850sna_compute_composite_extents(BoxPtr extents,
851			      PicturePtr src, PicturePtr mask, PicturePtr dst,
852			      INT16 src_x,  INT16 src_y,
853			      INT16 mask_x, INT16 mask_y,
854			      INT16 dst_x,  INT16 dst_y,
855			      CARD16 width, CARD16 height);
856bool
857sna_compute_composite_region(RegionPtr region,
858			     PicturePtr src, PicturePtr mask, PicturePtr dst,
859			     INT16 src_x,  INT16 src_y,
860			     INT16 mask_x, INT16 mask_y,
861			     INT16 dst_x,  INT16 dst_y,
862			     CARD16 width, CARD16 height);
863
864void
865memcpy_blt(const void *src, void *dst, int bpp,
866	   int32_t src_stride, int32_t dst_stride,
867	   int16_t src_x, int16_t src_y,
868	   int16_t dst_x, int16_t dst_y,
869	   uint16_t width, uint16_t height);
870
871void
872memmove_box(const void *src, void *dst,
873	    int bpp, int32_t stride,
874	    const BoxRec *box,
875	    int dx, int dy);
876
877void
878memcpy_xor(const void *src, void *dst, int bpp,
879	   int32_t src_stride, int32_t dst_stride,
880	   int16_t src_x, int16_t src_y,
881	   int16_t dst_x, int16_t dst_y,
882	   uint16_t width, uint16_t height,
883	   uint32_t and, uint32_t or);
884
885#define SNA_CREATE_FB 0x10
886#define SNA_CREATE_SCRATCH 0x11
887#define SNA_CREATE_GLYPHS 0x12
888
889inline static bool is_power_of_two(unsigned x)
890{
891	return (x & (x-1)) == 0;
892}
893
894inline static bool is_clipped(const RegionRec *r,
895			      const DrawableRec *d)
896{
897	return (r->data ||
898		r->extents.x2 - r->extents.x1 != d->width ||
899		r->extents.y2 - r->extents.y1 != d->height);
900}
901
902inline static bool
903box_intersect(BoxPtr a, const BoxRec *b)
904{
905	if (a->x1 < b->x1)
906		a->x1 = b->x1;
907	if (a->x2 > b->x2)
908		a->x2 = b->x2;
909	if (a->x1 >= a->x2)
910		return false;
911
912	if (a->y1 < b->y1)
913		a->y1 = b->y1;
914	if (a->y2 > b->y2)
915		a->y2 = b->y2;
916	if (a->y1 >= a->y2)
917		return false;
918
919	return true;
920}
921
922unsigned sna_cpu_detect(void);
923char *sna_cpu_features_to_string(unsigned features, char *line);
924
925void sna_threads_init(void);
926int sna_use_threads (int width, int height, int threshold);
927void sna_threads_run(void (*func)(void *arg), void *arg);
928void sna_threads_wait(void);
929
930void sna_image_composite(pixman_op_t        op,
931			 pixman_image_t    *src,
932			 pixman_image_t    *mask,
933			 pixman_image_t    *dst,
934			 int16_t            src_x,
935			 int16_t            src_y,
936			 int16_t            mask_x,
937			 int16_t            mask_y,
938			 int16_t            dst_x,
939			 int16_t            dst_y,
940			 uint16_t           width,
941			 uint16_t           height);
942
943#endif /* _SNA_H */
944