Subversion Repositories Kolibri OS

Rev

Rev 4401 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 2010 Chia-I Wu 
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included
14
 * in all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
23
 */
24
 
25
#include 
26
#include 
27
#include 
28
#include 
29
#include 
5080 serge 30
#include 
4358 Serge 31
 
32
#include "util/u_memory.h"
33
#include "egllog.h"
34
 
35
#include "native_drm.h"
36
 
37
#include "gbm_gallium_drmint.h"
38
 
39
#ifdef HAVE_LIBUDEV
40
#include 
41
#endif
42
 
4401 Serge 43
#ifdef HAVE_WAYLAND_BACKEND
44
#include "common/native_wayland_drm_bufmgr_helper.h"
45
#endif
46
 
4358 Serge 47
static boolean
48
drm_display_is_format_supported(struct native_display *ndpy,
49
                                enum pipe_format fmt, boolean is_color)
50
{
51
   return ndpy->screen->is_format_supported(ndpy->screen,
52
         fmt, PIPE_TEXTURE_2D, 0,
53
         (is_color) ? PIPE_BIND_RENDER_TARGET :
54
         PIPE_BIND_DEPTH_STENCIL);
55
}
56
 
57
static const struct native_config **
58
drm_display_get_configs(struct native_display *ndpy, int *num_configs)
59
{
60
   struct drm_display *drmdpy = drm_display(ndpy);
61
   const struct native_config **configs;
62
 
63
   /* first time */
64
   if (!drmdpy->config) {
65
      struct native_config *nconf;
66
      enum pipe_format format;
67
 
68
      drmdpy->config = CALLOC(1, sizeof(*drmdpy->config));
69
      if (!drmdpy->config)
70
         return NULL;
71
 
72
      nconf = &drmdpy->config->base;
73
 
74
      nconf->buffer_mask =
75
         (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
76
         (1 << NATIVE_ATTACHMENT_BACK_LEFT);
77
 
78
      format = PIPE_FORMAT_B8G8R8A8_UNORM;
79
      if (!drm_display_is_format_supported(&drmdpy->base, format, TRUE)) {
80
         format = PIPE_FORMAT_A8R8G8B8_UNORM;
81
         if (!drm_display_is_format_supported(&drmdpy->base, format, TRUE))
82
            format = PIPE_FORMAT_NONE;
83
      }
84
      if (format == PIPE_FORMAT_NONE) {
85
         FREE(drmdpy->config);
86
         drmdpy->config = NULL;
87
         return NULL;
88
      }
89
 
90
      nconf->color_format = format;
91
 
92
      /* support KMS */
93
      if (drmdpy->resources)
94
         nconf->scanout_bit = TRUE;
95
   }
96
 
97
   configs = MALLOC(sizeof(*configs));
98
   if (configs) {
99
      configs[0] = &drmdpy->config->base;
100
      if (num_configs)
101
         *num_configs = 1;
102
   }
103
 
104
   return configs;
105
}
106
 
107
static int
108
drm_display_get_param(struct native_display *ndpy,
109
                      enum native_param_type param)
110
{
111
   int val;
112
 
113
   switch (param) {
114
   case NATIVE_PARAM_USE_NATIVE_BUFFER:
115
   case NATIVE_PARAM_PRESERVE_BUFFER:
116
   case NATIVE_PARAM_MAX_SWAP_INTERVAL:
117
   default:
118
      val = 0;
119
      break;
120
   }
121
 
122
   return val;
123
}
124
 
125
static void
126
drm_display_destroy(struct native_display *ndpy)
127
{
128
   struct drm_display *drmdpy = drm_display(ndpy);
129
 
130
   FREE(drmdpy->config);
131
 
132
   drm_display_fini_modeset(&drmdpy->base);
133
 
134
   /* gbm owns screen */
135
   ndpy->screen = NULL;
136
   ndpy_uninit(ndpy);
137
 
138
   FREE(drmdpy->device_name);
139
 
140
   if (drmdpy->own_gbm) {
141
      gbm_device_destroy(&drmdpy->gbmdrm->base.base);
142
   }
143
 
144
   FREE(drmdpy);
145
}
146
 
147
static struct native_display_buffer drm_display_buffer = {
148
   /* use the helpers */
149
   drm_display_import_native_buffer,
150
   drm_display_export_native_buffer
151
};
152
 
153
static char *
154
drm_get_device_name(int fd)
155
{
156
   char *device_name = NULL;
157
#ifdef HAVE_LIBUDEV
158
#endif
159
   return device_name;
160
}
161
 
162
#ifdef HAVE_WAYLAND_BACKEND
163
 
164
static int
165
drm_display_authenticate(void *user_data, uint32_t magic)
166
{
167
   struct native_display *ndpy = user_data;
168
   struct drm_display *drmdpy = drm_display(ndpy);
169
 
170
   return drmAuthMagic(drmdpy->fd, magic);
171
}
172
 
173
static struct wayland_drm_callbacks wl_drm_callbacks = {
174
   drm_display_authenticate,
175
   egl_g3d_wl_drm_helper_reference_buffer,
176
   egl_g3d_wl_drm_helper_unreference_buffer
177
};
178
 
179
static boolean
180
drm_display_bind_wayland_display(struct native_display *ndpy,
181
                                  struct wl_display *wl_dpy)
182
{
183
   struct drm_display *drmdpy = drm_display(ndpy);
184
 
4401 Serge 185
   if (ndpy->wl_server_drm)
4358 Serge 186
      return FALSE;
187
 
4401 Serge 188
   ndpy->wl_server_drm = wayland_drm_init(wl_dpy,
4358 Serge 189
         drmdpy->device_name,
190
         &wl_drm_callbacks, ndpy, 0);
191
 
4401 Serge 192
   if (!ndpy->wl_server_drm)
4358 Serge 193
      return FALSE;
5080 serge 194
 
4358 Serge 195
   return TRUE;
196
}
197
 
198
static boolean
199
drm_display_unbind_wayland_display(struct native_display *ndpy,
200
                                    struct wl_display *wl_dpy)
201
{
4401 Serge 202
   if (!ndpy->wl_server_drm)
4358 Serge 203
      return FALSE;
204
 
4401 Serge 205
   wayland_drm_uninit(ndpy->wl_server_drm);
206
   ndpy->wl_server_drm = NULL;
4358 Serge 207
 
208
   return TRUE;
209
}
210
 
211
static struct native_display_wayland_bufmgr drm_display_wayland_bufmgr = {
212
   drm_display_bind_wayland_display,
213
   drm_display_unbind_wayland_display,
214
   egl_g3d_wl_drm_common_wl_buffer_get_resource,
215
   egl_g3d_wl_drm_common_query_buffer
216
};
217
 
218
#endif /* HAVE_WAYLAND_BACKEND */
219
 
220
static struct native_surface *
221
drm_create_pixmap_surface(struct native_display *ndpy,
222
                              EGLNativePixmapType pix,
223
                              const struct native_config *nconf)
224
{
225
   struct gbm_gallium_drm_bo *bo = (void *) pix;
226
 
227
   return drm_display_create_surface_from_resource(ndpy, bo->resource);
228
}
229
 
230
static boolean
231
drm_display_init_screen(struct native_display *ndpy)
232
{
233
   return TRUE;
234
}
235
 
236
static struct native_display *
237
drm_create_display(struct gbm_gallium_drm_device *gbmdrm, int own_gbm,
238
                   const struct native_event_handler *event_handler)
239
{
240
   struct drm_display *drmdpy;
241
 
242
   drmdpy = CALLOC_STRUCT(drm_display);
243
   if (!drmdpy)
244
      return NULL;
245
 
246
   drmdpy->gbmdrm = gbmdrm;
247
   drmdpy->own_gbm = own_gbm;
248
   drmdpy->fd = gbmdrm->base.base.fd;
249
   drmdpy->device_name = drm_get_device_name(drmdpy->fd);
250
 
251
   gbmdrm->lookup_egl_image = (struct pipe_resource *(*)(void *, void *))
252
      event_handler->lookup_egl_image;
253
   gbmdrm->lookup_egl_image_data = &drmdpy->base;
254
 
255
   drmdpy->event_handler = event_handler;
256
 
257
   drmdpy->base.screen = gbmdrm->screen;
258
 
259
   drmdpy->base.init_screen = drm_display_init_screen;
260
   drmdpy->base.destroy = drm_display_destroy;
261
   drmdpy->base.get_param = drm_display_get_param;
262
   drmdpy->base.get_configs = drm_display_get_configs;
263
 
264
   drmdpy->base.create_pixmap_surface = drm_create_pixmap_surface;
265
 
266
   drmdpy->base.buffer = &drm_display_buffer;
267
#ifdef HAVE_WAYLAND_BACKEND
268
   if (drmdpy->device_name)
269
      drmdpy->base.wayland_bufmgr = &drm_display_wayland_bufmgr;
270
#endif
271
   drm_display_init_modeset(&drmdpy->base);
272
 
273
   return &drmdpy->base;
274
}
275
 
276
static const struct native_event_handler *drm_event_handler;
277
 
278
static struct native_display *
279
native_create_display(void *dpy, boolean use_sw)
280
{
281
   struct gbm_gallium_drm_device *gbm;
282
   int fd;
283
   int own_gbm = 0;
284
 
285
   gbm = dpy;
286
 
287
   if (gbm == NULL) {
5080 serge 288
      fd = get_service("DISPLAY");
289
      if (fd == NULL)
290
        return NULL;
291
 
4358 Serge 292
      /* FIXME: Use an internal constructor to create a gbm
293
       * device with gallium backend directly, without setenv */
5080 serge 294
//      setenv("GBM_BACKEND", "gbm_gallium_drm.so", 1);
4358 Serge 295
      gbm = gbm_gallium_drm_device(gbm_create_device(fd));
296
      own_gbm = 1;
297
   }
298
 
299
   if (gbm == NULL)
300
      return NULL;
5080 serge 301
 
4358 Serge 302
   if (strcmp(gbm_device_get_backend_name(&gbm->base.base), "drm") != 0 ||
303
       gbm->base.type != GBM_DRM_DRIVER_TYPE_GALLIUM) {
304
      if (own_gbm)
305
         gbm_device_destroy(&gbm->base.base);
306
      return NULL;
307
   }
308
 
309
   return drm_create_display(gbm, own_gbm, drm_event_handler);
310
}
311
 
312
static const struct native_platform drm_platform = {
313
   "DRM", /* name */
314
   native_create_display
315
};
316
 
317
const struct native_platform *
318
native_get_drm_platform(const struct native_event_handler *event_handler)
319
{
320
   drm_event_handler = event_handler;
321
   return &drm_platform;
322
}