0f6a061cb22be88806dfc5342c867a94bd5b7e0a
[profile/ivi/mesa.git] / src / mesa / drivers / dri / common / dri_util.h
1 /*
2  * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
3  * All Rights Reserved.
4  * 
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  * 
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial portions
15  * of the Software.
16  * 
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25
26 /**
27  * \file dri_util.h
28  * DRI utility functions definitions.
29  *
30  * This module acts as glue between GLX and the actual hardware driver.  A DRI
31  * driver doesn't really \e have to use any of this - it's optional.  But, some
32  * useful stuff is done here that otherwise would have to be duplicated in most
33  * drivers.
34  * 
35  * Basically, these utility functions take care of some of the dirty details of
36  * screen initialization, context creation, context binding, DRM setup, etc.
37  *
38  * These functions are compiled into each DRI driver so libGL.so knows nothing
39  * about them.
40  *
41  * \sa dri_util.c.
42  * 
43  * \author Kevin E. Martin <kevin@precisioninsight.com>
44  * \author Brian Paul <brian@precisioninsight.com>
45  */
46
47 #ifndef _DRI_UTIL_H_
48 #define _DRI_UTIL_H_
49
50 #include <GL/gl.h>
51 #include <drm.h>
52 #include <drm_sarea.h>
53 #include <xf86drm.h>
54 #include "xmlconfig.h"
55 #include "main/glheader.h"
56 #include "main/mtypes.h"
57 #include "GL/internal/dri_interface.h"
58
59 #define GLX_BAD_CONTEXT                    5
60
61 typedef struct __DRIswapInfoRec        __DRIswapInfo;
62
63 /**
64  * Extensions.
65  */
66 extern const __DRIcoreExtension driCoreExtension;
67 extern const __DRIdri2Extension driDRI2Extension;
68 extern const __DRIextension driReadDrawableExtension;
69 extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
70 extern const __DRIswapControlExtension driSwapControlExtension;
71 extern const __DRImediaStreamCounterExtension driMediaStreamCounterExtension;
72 extern const __DRI2configQueryExtension dri2ConfigQueryExtension;
73
74 /**
75  * Used by DRI_VALIDATE_DRAWABLE_INFO
76  */
77 #define DRI_VALIDATE_DRAWABLE_INFO_ONCE(pDrawPriv)              \
78     do {                                                        \
79         if (*(pDrawPriv->pStamp) != pDrawPriv->lastStamp) {     \
80             __driUtilUpdateDrawableInfo(pDrawPriv);             \
81         }                                                       \
82     } while (0)
83
84
85 /**
86  * Utility macro to validate the drawable information.
87  *
88  * See __DRIdrawable::pStamp and __DRIdrawable::lastStamp.
89  */
90 #define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp)                            \
91 do {                                                                    \
92     while (*(pdp->pStamp) != pdp->lastStamp) {                          \
93         register unsigned int hwContext = psp->pSAREA->lock.lock &      \
94                      ~(DRM_LOCK_HELD | DRM_LOCK_CONT);                  \
95         DRM_UNLOCK(psp->fd, &psp->pSAREA->lock, hwContext);             \
96                                                                         \
97         DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);     \
98         DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp);                           \
99         DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);   \
100                                                                         \
101         DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock, hwContext);         \
102     }                                                                   \
103 } while (0)
104
105 /**
106  * Same as above, but for two drawables simultaneously.
107  *
108  */
109
110 #define DRI_VALIDATE_TWO_DRAWABLES_INFO(psp, pdp, prp)                  \
111 do {                                                            \
112     while (*((pdp)->pStamp) != (pdp)->lastStamp ||                      \
113            *((prp)->pStamp) != (prp)->lastStamp) {                      \
114         register unsigned int hwContext = (psp)->pSAREA->lock.lock &    \
115             ~(DRM_LOCK_HELD | DRM_LOCK_CONT);                           \
116         DRM_UNLOCK((psp)->fd, &(psp)->pSAREA->lock, hwContext);         \
117                                                                         \
118         DRM_SPINLOCK(&(psp)->pSAREA->drawable_lock, (psp)->drawLockID); \
119         DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp);                           \
120         DRI_VALIDATE_DRAWABLE_INFO_ONCE(prp);                           \
121         DRM_SPINUNLOCK(&(psp)->pSAREA->drawable_lock, (psp)->drawLockID); \
122                                                                         \
123         DRM_LIGHT_LOCK((psp)->fd, &(psp)->pSAREA->lock, hwContext);     \
124     }                                                                   \
125 } while (0)
126
127
128 /**
129  * Driver callback functions.
130  *
131  * Each DRI driver must have one of these structures with all the pointers set
132  * to appropriate functions within the driver.
133  * 
134  * When glXCreateContext() is called, for example, it'll call a helper function
135  * dri_util.c which in turn will jump through the \a CreateContext pointer in
136  * this structure.
137  */
138 struct __DriverAPIRec {
139     const __DRIconfig **(*InitScreen) (__DRIscreen * priv);
140
141     /**
142      * Screen destruction callback
143      */
144     void (*DestroyScreen)(__DRIscreen *driScrnPriv);
145
146     /**
147      * Context creation callback
148      */             
149     GLboolean (*CreateContext)(gl_api api,
150                                const struct gl_config *glVis,
151                                __DRIcontext *driContextPriv,
152                                void *sharedContextPrivate);
153
154     /**
155      * Context destruction callback
156      */
157     void (*DestroyContext)(__DRIcontext *driContextPriv);
158
159     /**
160      * Buffer (drawable) creation callback
161      */
162     GLboolean (*CreateBuffer)(__DRIscreen *driScrnPriv,
163                               __DRIdrawable *driDrawPriv,
164                               const struct gl_config *glVis,
165                               GLboolean pixmapBuffer);
166     
167     /**
168      * Buffer (drawable) destruction callback
169      */
170     void (*DestroyBuffer)(__DRIdrawable *driDrawPriv);
171
172     /**
173      * Buffer swapping callback 
174      */
175     void (*SwapBuffers)(__DRIdrawable *driDrawPriv);
176
177     /**
178      * Context activation callback
179      */
180     GLboolean (*MakeCurrent)(__DRIcontext *driContextPriv,
181                              __DRIdrawable *driDrawPriv,
182                              __DRIdrawable *driReadPriv);
183
184     /**
185      * Context unbinding callback
186      */
187     GLboolean (*UnbindContext)(__DRIcontext *driContextPriv);
188   
189     /**
190      * Retrieves statistics about buffer swap operations.  Required if
191      * GLX_OML_sync_control or GLX_MESA_swap_frame_usage is supported.
192      */
193     int (*GetSwapInfo)( __DRIdrawable *dPriv, __DRIswapInfo * sInfo );
194
195
196     /**
197      * These are required if GLX_OML_sync_control is supported.
198      */
199     /*@{*/
200     int (*WaitForMSC)( __DRIdrawable *priv, int64_t target_msc, 
201                        int64_t divisor, int64_t remainder,
202                        int64_t * msc );
203     int (*WaitForSBC)( __DRIdrawable *priv, int64_t target_sbc,
204                        int64_t * msc, int64_t * sbc );
205
206     int64_t (*SwapBuffersMSC)( __DRIdrawable *priv, int64_t target_msc,
207                                int64_t divisor, int64_t remainder );
208     /*@}*/
209     void (*CopySubBuffer)(__DRIdrawable *driDrawPriv,
210                           int x, int y, int w, int h);
211
212     /**
213      * New version of GetMSC so we can pass drawable data to the low
214      * level DRM driver (e.g. pipe info).  Required if
215      * GLX_SGI_video_sync or GLX_OML_sync_control is supported.
216      */
217     int (*GetDrawableMSC) ( __DRIscreen * priv,
218                             __DRIdrawable *drawablePrivate,
219                             int64_t *count);
220
221
222
223     /* DRI2 Entry point */
224     const __DRIconfig **(*InitScreen2) (__DRIscreen * priv);
225
226     __DRIbuffer *(*AllocateBuffer) (__DRIscreen *screenPrivate,
227                                     unsigned int attachment,
228                                     unsigned int format,
229                                     int width, int height);
230     void (*ReleaseBuffer) (__DRIscreen *screenPrivate, __DRIbuffer *buffer);
231 };
232
233 extern const struct __DriverAPIRec driDriverAPI;
234
235
236 struct __DRIswapInfoRec {
237     /** 
238      * Number of swapBuffers operations that have been *completed*. 
239      */
240     uint64_t swap_count;
241
242     /**
243      * Unadjusted system time of the last buffer swap.  This is the time
244      * when the swap completed, not the time when swapBuffers was called.
245      */
246     int64_t   swap_ust;
247
248     /**
249      * Number of swap operations that occurred after the swap deadline.  That
250      * is if a swap happens more than swap_interval frames after the previous
251      * swap, it has missed its deadline.  If swap_interval is 0, then the
252      * swap deadline is 1 frame after the previous swap.
253      */
254     uint64_t swap_missed_count;
255
256     /**
257      * Amount of time used by the last swap that missed its deadline.  This
258      * is calculated as (__glXGetUST() - swap_ust) / (swap_interval * 
259      * time_for_single_vrefresh)).  If the actual value of swap_interval is
260      * 0, then 1 is used instead.  If swap_missed_count is non-zero, this
261      * should be greater-than 1.0.
262      */
263     float     swap_missed_usage;
264 };
265
266
267 /**
268  * Per-drawable private DRI driver information.
269  */
270 struct __DRIdrawableRec {
271     /**
272      * Kernel drawable handle
273      */
274     drm_drawable_t hHWDrawable;
275
276     /**
277      * Driver's private drawable information.  
278      *
279      * This structure is opaque.
280      */
281     void *driverPrivate;
282
283     /**
284      * Private data from the loader.  We just hold on to it and pass
285      * it back when calling into loader provided functions.
286      */
287     void *loaderPrivate;
288
289     /**
290      * Reference count for number of context's currently bound to this
291      * drawable.  
292      *
293      * Once it reaches zero, the drawable can be destroyed.
294      *
295      * \note This behavior will change with GLX 1.3.
296      */
297     int refcount;
298
299     /**
300      * Index of this drawable information in the SAREA.
301      */
302     unsigned int index;
303
304     /**
305      * Pointer to the "drawable has changed ID" stamp in the SAREA (or
306      * to dri2.stamp if DRI2 is being used).
307      */
308     unsigned int *pStamp;
309
310     /**
311      * Last value of the stamp.
312      *
313      * If this differs from the value stored at __DRIdrawable::pStamp,
314      * then the drawable information has been modified by the X server, and the
315      * drawable information (below) should be retrieved from the X server.
316      */
317     unsigned int lastStamp;
318
319     /**
320      * \name Drawable 
321      *
322      * Drawable information used in software fallbacks.
323      */
324     /*@{*/
325     int x;
326     int y;
327     int w;
328     int h;
329     int numClipRects;
330     drm_clip_rect_t *pClipRects;
331     /*@}*/
332
333     /**
334      * \name Back and depthbuffer
335      *
336      * Information about the back and depthbuffer where different from above.
337      */
338     /*@{*/
339     int backX;
340     int backY;
341     int backClipRectType;
342     int numBackClipRects;
343     drm_clip_rect_t *pBackClipRects;
344     /*@}*/
345
346     /**
347      * \name Vertical blank tracking information
348      * Used for waiting on vertical blank events.
349      */
350     /*@{*/
351     unsigned int vblSeq;
352     unsigned int vblFlags;
353     /*@}*/
354
355     /**
356      * \name Monotonic MSC tracking
357      *
358      * Low level driver is responsible for updating msc_base and
359      * vblSeq values so that higher level code can calculate
360      * a new msc value or msc target for a WaitMSC call.  The new value
361      * will be:
362      *   msc = msc_base + get_vblank_count() - vblank_base;
363      *
364      * And for waiting on a value, core code will use:
365      *   actual_target = target_msc - msc_base + vblank_base;
366      */
367     /*@{*/
368     int64_t vblank_base;
369     int64_t msc_base;
370     /*@}*/
371
372     /**
373      * Pointer to context to which this drawable is currently bound.
374      */
375     __DRIcontext *driContextPriv;
376
377     /**
378      * Pointer to screen on which this drawable was created.
379      */
380     __DRIscreen *driScreenPriv;
381
382     /**
383      * Controls swap interval as used by GLX_SGI_swap_control and
384      * GLX_MESA_swap_control.
385      */
386     unsigned int swap_interval;
387
388     struct {
389         unsigned int stamp;
390         drm_clip_rect_t clipRect;
391     } dri2;
392 };
393
394 /**
395  * Per-context private driver information.
396  */
397 struct __DRIcontextRec {
398     /**
399      * Kernel context handle used to access the device lock.
400      */
401     drm_context_t hHWContext;
402
403     /**
404      * Device driver's private context data.  This structure is opaque.
405      */
406     void *driverPrivate;
407
408     /**
409      * Pointer to drawable currently bound to this context for drawing.
410      */
411     __DRIdrawable *driDrawablePriv;
412
413     /**
414      * Pointer to drawable currently bound to this context for reading.
415      */
416     __DRIdrawable *driReadablePriv;
417
418     /**
419      * Pointer to screen on which this context was created.
420      */
421     __DRIscreen *driScreenPriv;
422
423     /**
424      * The loaders's private context data.  This structure is opaque.
425      */
426     void *loaderPrivate;
427
428     struct {
429         int draw_stamp;
430         int read_stamp;
431     } dri2;
432 };
433
434 /**
435  * Per-screen private driver information.
436  */
437 struct __DRIscreenRec {
438     /**
439      * Current screen's number
440      */
441     int myNum;
442
443     /**
444      * Callback functions into the hardware-specific DRI driver code.
445      */
446     struct __DriverAPIRec DriverAPI;
447
448     const __DRIextension **extensions;
449     /**
450      * DDX / 2D driver version information.
451      */
452     __DRIversion ddx_version;
453
454     /**
455      * DRI X extension version information.
456      */
457     __DRIversion dri_version;
458
459     /**
460      * DRM (kernel module) version information.
461      */
462     __DRIversion drm_version;
463
464     /**
465      * ID used when the client sets the drawable lock.
466      *
467      * The X server uses this value to detect if the client has died while
468      * holding the drawable lock.
469      */
470     int drawLockID;
471
472     /**
473      * File descriptor returned when the kernel device driver is opened.
474      * 
475      * Used to:
476      *   - authenticate client to kernel
477      *   - map the frame buffer, SAREA, etc.
478      *   - close the kernel device driver
479      */
480     int fd;
481
482     /**
483      * SAREA pointer 
484      *
485      * Used to access:
486      *   - the device lock
487      *   - the device-independent per-drawable and per-context(?) information
488      */
489     drm_sarea_t *pSAREA;
490
491     /**
492      * \name Direct frame buffer access information 
493      * Used for software fallbacks.
494      */
495     /*@{*/
496     unsigned char *pFB;
497     int fbSize;
498     int fbOrigin;
499     int fbStride;
500     int fbWidth;
501     int fbHeight;
502     int fbBPP;
503     /*@}*/
504
505     /**
506      * \name Device-dependent private information (stored in the SAREA).
507      *
508      * This data is accessed by the client driver only.
509      */
510     /*@{*/
511     void *pDevPriv;
512     int devPrivSize;
513     /*@}*/
514
515     /**
516      * Device-dependent private information (not stored in the SAREA).
517      * 
518      * This pointer is never touched by the DRI layer.
519      */
520 #ifdef __cplusplus
521     void *priv;
522 #else
523     void *private;
524 #endif
525
526     /* Extensions provided by the loader. */
527     const __DRIgetDrawableInfoExtension *getDrawableInfo;
528     const __DRIsystemTimeExtension *systemTime;
529     const __DRIdamageExtension *damage;
530
531     struct {
532         /* Flag to indicate that this is a DRI2 screen.  Many of the above
533          * fields will not be valid or initializaed in that case. */
534         int enabled;
535         __DRIdri2LoaderExtension *loader;
536         __DRIimageLookupExtension *image;
537         __DRIuseInvalidateExtension *useInvalidate;
538     } dri2;
539
540     /* The lock actually in use, old sarea or DRI2 */
541     drmLock *lock;
542
543     driOptionCache optionInfo;
544     driOptionCache optionCache;
545    unsigned int api_mask;
546    void *loaderPrivate;
547 };
548
549 extern void
550 __driUtilUpdateDrawableInfo(__DRIdrawable *pdp);
551
552 extern float
553 driCalculateSwapUsage( __DRIdrawable *dPriv,
554                        int64_t last_swap_ust, int64_t current_ust );
555
556 extern GLint
557 driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 );
558
559 extern void
560 dri2InvalidateDrawable(__DRIdrawable *drawable);
561
562 #endif /* _DRI_UTIL_H_ */