Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5362 serge 1
/*
2
 * Copyright (c) 2012 Intel Corporation. All Rights Reserved.
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the
6
 * "Software"), to deal in the Software without restriction, including
7
 * without limitation the rights to use, copy, modify, merge, publish,
8
 * distribute, sub license, and/or sell copies of the Software, and to
9
 * permit persons to whom the Software is furnished to do so, subject to
10
 * the following conditions:
11
 *
12
 * The above copyright notice and this permission notice (including the
13
 * next paragraph) shall be included in all copies or substantial portions
14
 * of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
 */
24
#include 
25
#include 
26
#include 
27
#include 
28
 
29
#include 
30
 
31
#include 
32
#include 
33
#include "va.h"
34
#include "va_backend.h"
35
 
36
#include "va_dri2.h"
37
#include "va_dri2tokens.h"
38
#include "va_dricommon.h"
39
 
40
#define __DRI_BUFFER_FRONT_LEFT         0
41
#define __DRI_BUFFER_BACK_LEFT          1
42
#define __DRI_BUFFER_FRONT_RIGHT        2
43
#define __DRI_BUFFER_BACK_RIGHT         3
44
#define __DRI_BUFFER_DEPTH              4
45
#define __DRI_BUFFER_STENCIL            5
46
#define __DRI_BUFFER_ACCUM              6
47
#define __DRI_BUFFER_FAKE_FRONT_LEFT    7
48
#define __DRI_BUFFER_FAKE_FRONT_RIGHT   8
49
 
50
struct dri2_drawable
51
{
52
    struct dri_drawable base;
53
    union dri_buffer buffers[5];
54
    int width;
55
    int height;
56
    int has_backbuffer;
57
    int back_index;
58
    int front_index;
59
};
60
 
61
static int gsDRI2SwapAvailable;
62
 
63
static struct dri_drawable *
64
dri2CreateDrawable(VADriverContextP ctx, XID x_drawable)
65
{
66
    struct dri2_drawable *dri2_drawable;
67
 
68
    dri2_drawable = calloc(1, sizeof(*dri2_drawable));
69
 
70
    if (!dri2_drawable)
71
        return NULL;
72
 
73
    dri2_drawable->base.x_drawable = x_drawable;
74
    dri2_drawable->base.x = 0;
75
    dri2_drawable->base.y = 0;
76
    VA_DRI2CreateDrawable(ctx->native_dpy, x_drawable);
77
 
78
    return &dri2_drawable->base;
79
}
80
 
81
static void
82
dri2DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable)
83
{
84
    VA_DRI2DestroyDrawable(ctx->native_dpy, dri_drawable->x_drawable);
85
    free(dri_drawable);
86
}
87
 
88
static void
89
dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
90
{
91
    struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
92
    XRectangle xrect;
93
    XserverRegion region;
94
 
95
    if (dri2_drawable->has_backbuffer) {
96
        if (gsDRI2SwapAvailable) {
97
            CARD64 ret;
98
            VA_DRI2SwapBuffers(ctx->native_dpy, dri_drawable->x_drawable, 0, 0,
99
                               0, &ret);
100
        } else {
101
            xrect.x = 0;
102
            xrect.y = 0;
103
            xrect.width = dri2_drawable->width;
104
            xrect.height = dri2_drawable->height;
105
 
106
            region = XFixesCreateRegion(ctx->native_dpy, &xrect, 1);
107
            VA_DRI2CopyRegion(ctx->native_dpy, dri_drawable->x_drawable, region,
108
                              DRI2BufferFrontLeft, DRI2BufferBackLeft);
109
            XFixesDestroyRegion(ctx->native_dpy, region);
110
        }
111
    }
112
}
113
 
114
static union dri_buffer *
115
dri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
116
{
117
    struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable;
118
    int i;
119
    int count;
120
    unsigned int attachments[5];
121
    VA_DRI2Buffer *buffers;
122
 
123
    i = 0;
124
    if (dri_drawable->is_window)
125
        attachments[i++] = __DRI_BUFFER_BACK_LEFT;
126
    else
127
        attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
128
 
129
    buffers = VA_DRI2GetBuffers(ctx->native_dpy, dri_drawable->x_drawable,
130
			     &dri2_drawable->width, &dri2_drawable->height,
131
                             attachments, i, &count);
132
    assert(buffers);
133
    if (buffers == NULL)
134
        return NULL;
135
 
136
    dri2_drawable->has_backbuffer = 0;
137
 
138
    for (i = 0; i < count; i++) {
139
        dri2_drawable->buffers[i].dri2.attachment = buffers[i].attachment;
140
        dri2_drawable->buffers[i].dri2.name = buffers[i].name;
141
        dri2_drawable->buffers[i].dri2.pitch = buffers[i].pitch;
142
        dri2_drawable->buffers[i].dri2.cpp = buffers[i].cpp;
143
        dri2_drawable->buffers[i].dri2.flags = buffers[i].flags;
144
 
145
        if (buffers[i].attachment == __DRI_BUFFER_BACK_LEFT) {
146
            dri2_drawable->has_backbuffer = 1;
147
            dri2_drawable->back_index = i;
148
        }
149
 
150
        if (buffers[i].attachment == __DRI_BUFFER_FRONT_LEFT)
151
            dri2_drawable->front_index = i;
152
    }
153
 
154
    dri_drawable->width = dri2_drawable->width;
155
    dri_drawable->height = dri2_drawable->height;
156
    Xfree(buffers);
157
 
158
    if (dri2_drawable->has_backbuffer)
159
        return &dri2_drawable->buffers[dri2_drawable->back_index];
160
 
161
    return &dri2_drawable->buffers[dri2_drawable->front_index];
162
}
163
 
164
void
165
dri2Close(VADriverContextP ctx)
166
{
167
    struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
168
 
169
    free_drawable_hashtable(ctx);
170
 
171
    if (dri_state->base.fd >= 0);
172
	close(dri_state->base.fd);
173
}
174
 
175
Bool
176
isDRI2Connected(VADriverContextP ctx, char **driver_name)
177
{
178
    struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
179
    int major, minor;
180
    int error_base;
181
    int event_base;
182
    char *device_name = NULL;
183
    drm_magic_t magic;
184
    *driver_name = NULL;
185
    dri_state->base.fd = -1;
186
    dri_state->base.auth_type = VA_NONE;
187
    if (!VA_DRI2QueryExtension(ctx->native_dpy, &event_base, &error_base))
188
        goto err_out;
189
 
190
    if (!VA_DRI2QueryVersion(ctx->native_dpy, &major, &minor))
191
        goto err_out;
192
 
193
 
194
    if (!VA_DRI2Connect(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen),
195
                     driver_name, &device_name))
196
        goto err_out;
197
 
198
    dri_state->base.fd = open(device_name, O_RDWR);
199
    assert(dri_state->base.fd >= 0);
200
 
201
    if (dri_state->base.fd < 0)
202
        goto err_out;
203
 
204
    if (drmGetMagic(dri_state->base.fd, &magic))
205
        goto err_out;
206
 
207
    if (!VA_DRI2Authenticate(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen),
208
                          magic))
209
        goto err_out;
210
 
211
    dri_state->base.auth_type = VA_DRI2;
212
    dri_state->createDrawable = dri2CreateDrawable;
213
    dri_state->destroyDrawable = dri2DestroyDrawable;
214
    dri_state->swapBuffer = dri2SwapBuffer;
215
    dri_state->getRenderingBuffer = dri2GetRenderingBuffer;
216
    dri_state->close = dri2Close;
217
    gsDRI2SwapAvailable = (minor >= 2);
218
 
219
    if (device_name)
220
        Xfree(device_name);
221
 
222
    return True;
223
 
224
err_out:
225
    if (device_name)
226
        Xfree(device_name);
227
 
228
    if (*driver_name)
229
        Xfree(*driver_name);
230
 
231
    if (dri_state->base.fd >= 0)
232
        close(dri_state->base.fd);
233
 
234
    *driver_name = NULL;
235
    dri_state->base.fd = -1;
236
 
237
    return False;
238
}
239