nouveau: use dri state tracker for dri1
[mesa.git] / src / gallium / winsys / drm / nouveau / dri / nouveau_swapbuffers.c
1 #include <main/glheader.h>
2 #include <glapi/glthread.h>
3 #include <GL/internal/glcore.h>
4
5 #include <pipe/p_context.h>
6 #include <state_tracker/st_public.h>
7 #include <state_tracker/st_context.h>
8 #include <state_tracker/st_cb_fbo.h>
9
10 #include "nouveau_context.h"
11 #include "nouveau_screen.h"
12 #include "nouveau_swapbuffers.h"
13
14 #include "nouveau_pushbuf.h"
15
16 void
17 nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
18 const drm_clip_rect_t *rect)
19 {
20 struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate;
21 struct nouveau_screen *nv_screen = nv->dri_screen->private;
22 struct pipe_context *pipe = nv->st->pipe;
23 drm_clip_rect_t *pbox;
24 int nbox, i;
25
26 LOCK_HARDWARE(nv);
27 if (!dPriv->numClipRects) {
28 UNLOCK_HARDWARE(nv);
29 return;
30 }
31 pbox = dPriv->pClipRects;
32 nbox = dPriv->numClipRects;
33
34 for (i = 0; i < nbox; i++, pbox++) {
35 int sx, sy, dx, dy, w, h;
36
37 sx = pbox->x1 - dPriv->x;
38 sy = pbox->y1 - dPriv->y;
39 dx = pbox->x1;
40 dy = pbox->y1;
41 w = pbox->x2 - pbox->x1;
42 h = pbox->y2 - pbox->y1;
43
44 pipe->surface_copy(pipe, nv_screen->fb, dx, dy, surf,
45 sx, sy, w, h);
46 }
47
48 pipe->flush(pipe, 0, NULL);
49 UNLOCK_HARDWARE(nv);
50
51 if (nv->last_stamp != dPriv->lastStamp) {
52 struct nouveau_framebuffer *nvfb = dPriv->driverPrivate;
53 st_resize_framebuffer(nvfb->stfb, dPriv->w, dPriv->h);
54 nv->last_stamp = dPriv->lastStamp;
55 }
56 }
57
58 void
59 nouveau_copy_sub_buffer(__DRIdrawablePrivate *dPriv, int x, int y, int w, int h)
60 {
61 struct nouveau_framebuffer *nvfb = dPriv->driverPrivate;
62 struct pipe_surface *surf;
63
64 st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT, &surf);
65 if (surf) {
66 drm_clip_rect_t rect;
67 rect.x1 = x;
68 rect.y1 = y;
69 rect.x2 = x + w;
70 rect.y2 = y + h;
71
72 st_notify_swapbuffers(nvfb->stfb);
73 nouveau_copy_buffer(dPriv, surf, &rect);
74 }
75 }
76
77 void
78 nouveau_swap_buffers(__DRIdrawablePrivate *dPriv)
79 {
80 struct nouveau_framebuffer *nvfb = dPriv->driverPrivate;
81 struct pipe_surface *surf;
82
83 st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT, &surf);
84 if (surf) {
85 st_notify_swapbuffers(nvfb->stfb);
86 nouveau_copy_buffer(dPriv, surf, NULL);
87 }
88 }
89
90 void
91 nouveau_flush_frontbuffer(struct pipe_screen *pscreen, struct pipe_surface *ps,
92 void *context_private)
93 {
94 struct nouveau_context *nv = context_private;
95 __DRIdrawablePrivate *dPriv = nv->dri_drawable;
96
97 nouveau_copy_buffer(dPriv, ps, NULL);
98 }
99
100 void
101 nouveau_contended_lock(struct nouveau_context *nv)
102 {
103 struct nouveau_context *nv_sub = (struct nouveau_context*)nv;
104 __DRIdrawablePrivate *dPriv = nv_sub->dri_drawable;
105 __DRIscreenPrivate *sPriv = nv_sub->dri_screen;
106
107 /* If the window moved, may need to set a new cliprect now.
108 *
109 * NOTE: This releases and regains the hw lock, so all state
110 * checking must be done *after* this call:
111 */
112 if (dPriv)
113 DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
114 }
115