Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/*
2
 * Copyright © 2011 Intel Corporation
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice (including the next
12
 * paragraph) shall be included in all copies or substantial portions of the
13
 * Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
23
 *
24
 * Authors:
25
 *    Benjamin Franzke 
26
 */
27
 
28
#define _BSD_SOURCE
29
 
30
#include 
31
#include 
32
#include 
33
#include 
34
#include 
35
 
36
#include 
37
#include 
38
#include 
39
 
40
#include "gbm.h"
41
#include "gbmint.h"
42
#include "common.h"
43
#include "backend.h"
44
 
45
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
46
 
47
struct gbm_device *devices[16];
48
 
49
static int device_num = 0;
50
 
51
/** Returns the file description for the gbm device
52
 *
53
 * \return The fd that the struct gbm_device was created with
54
 */
55
GBM_EXPORT int
56
gbm_device_get_fd(struct gbm_device *gbm)
57
{
58
   return gbm->fd;
59
}
60
 
61
/* FIXME: maybe superfluous, use udev subclass from the fd? */
62
/** Get the backend name for the given gbm device
63
 *
64
 * \return The backend name string - this belongs to the device and must not
65
 * be freed
66
 */
67
GBM_EXPORT const char *
68
gbm_device_get_backend_name(struct gbm_device *gbm)
69
{
70
   return gbm->name;
71
}
72
 
73
/** Test if a format is supported for a given set of usage flags.
74
 *
75
 * \param gbm The created buffer manager
76
 * \param format The format to test
77
 * \param usage A bitmask of the usages to test the format against
78
 * \return 1 if the format is supported otherwise 0
79
 *
80
 * \sa enum gbm_bo_flags for the list of flags that the format can be
81
 * tested against
82
 *
83
 * \sa enum gbm_bo_format for the list of formats
84
 */
85
int
86
gbm_device_is_format_supported(struct gbm_device *gbm,
87
                               uint32_t format, uint32_t usage)
88
{
89
   return gbm->is_format_supported(gbm, format, usage);
90
}
91
 
92
/** Destroy the gbm device and free all resources associated with it.
93
 *
94
 * \param gbm The device created using gbm_create_device()
95
 */
96
GBM_EXPORT void
97
gbm_device_destroy(struct gbm_device *gbm)
98
{
99
   gbm->refcount--;
100
   if (gbm->refcount == 0)
101
      gbm->destroy(gbm);
102
}
103
 
104
#if 0
105
GBM_EXPORT struct gbm_device *
106
_gbm_mesa_get_device(int fd)
107
{
108
   struct gbm_device *gbm = NULL;
109
   struct stat buf;
110
   dev_t dev;
111
   int i;
112
 
113
    for (i = 0; i < device_num; ++i) {
114
      dev = devices[i]->stat.st_rdev;
115
      if (major(dev) == major(buf.st_rdev) &&
116
          minor(dev) == minor(buf.st_rdev)) {
117
         gbm = devices[i];
118
         gbm->refcount++;
119
         break;
120
      }
121
   }
122
 
123
   return gbm;
124
}
125
#endif
126
 
127
/** Create a gbm device for allocating buffers
128
 *
129
 * The file descriptor passed in is used by the backend to communicate with
130
 * platform for allocating the memory. For allocations using DRI this would be
131
 * the file descriptor returned when opening a device such as \c
132
 * /dev/dri/card0
133
 *
134
 * \param fd The file descriptor for an backend specific device
135
 * \return The newly created struct gbm_device. The resources associated with
136
 * the device should be freed with gbm_device_destroy() when it is no longer
137
 * needed. If the creation of the device failed NULL will be returned.
138
 */
139
GBM_EXPORT struct gbm_device *
140
gbm_create_device(int fd)
141
{
142
   struct gbm_device *gbm = NULL;
143
   struct stat buf;
144
 
145
   if (fd == 0) {
146
      fprintf(stderr, "gbm_create_device: invalid fd: %d\n", fd);
147
      return NULL;
148
   }
149
 
150
   if (device_num == 0)
151
      memset(devices, 0, sizeof devices);
152
 
153
   gbm = _gbm_create_device(fd);
154
   if (gbm == NULL)
155
      return NULL;
156
 
157
   gbm->dummy = gbm_create_device;
158
   gbm->stat = buf;
159
   gbm->refcount = 1;
160
 
161
   if (device_num < ARRAY_SIZE(devices)-1)
162
      devices[device_num++] = gbm;
163
 
164
   return gbm;
165
}
166
 
167
/** Get the width of the buffer object
168
 *
169
 * \param bo The buffer object
170
 * \return The width of the allocated buffer object
171
 *
172
 */
173
GBM_EXPORT unsigned int
174
gbm_bo_get_width(struct gbm_bo *bo)
175
{
176
   return bo->width;
177
}
178
 
179
/** Get the height of the buffer object
180
 *
181
 * \param bo The buffer object
182
 * \return The height of the allocated buffer object
183
 */
184
GBM_EXPORT unsigned int
185
gbm_bo_get_height(struct gbm_bo *bo)
186
{
187
   return bo->height;
188
}
189
 
190
/** Get the stride of the buffer object
191
 *
192
 * This is calculated by the backend when it does the allocation in
193
 * gbm_bo_create()
194
 *
195
 * \param bo The buffer object
196
 * \return The stride of the allocated buffer object in bytes
197
 */
198
GBM_EXPORT uint32_t
199
gbm_bo_get_stride(struct gbm_bo *bo)
200
{
201
   return bo->stride;
202
}
203
 
204
/** Get the format of the buffer object
205
 *
206
 * The format of the pixels in the buffer.
207
 *
208
 * \param bo The buffer object
209
 * \return The format of buffer object, on of the GBM_FORMAT_* codes
210
 */
211
GBM_EXPORT uint32_t
212
gbm_bo_get_format(struct gbm_bo *bo)
213
{
214
   return bo->format;
215
}
216
 
217
/** Get the handle of the buffer object
218
 *
219
 * This is stored in the platform generic union gbm_bo_handle type. However
220
 * the format of this handle is platform specific.
221
 *
222
 * \param bo The buffer object
223
 * \return Returns the handle of the allocated buffer object
224
 */
225
GBM_EXPORT union gbm_bo_handle
226
gbm_bo_get_handle(struct gbm_bo *bo)
227
{
228
   return bo->handle;
229
}
230
 
231
/** Write data into the buffer object
232
 *
233
 * If the buffer object was created with the GBM_BO_USE_WRITE flag,
234
 * this function can used to write data into the buffer object.  The
235
 * data is copied directly into the object and it's the responsiblity
236
 * of the caller to make sure the data represents valid pixel data,
237
 * according to the width, height, stride and format of the buffer object.
238
 *
239
 * \param bo The buffer object
240
 * \param buf The data to write
241
 * \param count The number of bytes to write
242
 * \return Returns -1 on error, 0 otherwise
243
 */
244
GBM_EXPORT int
245
gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count)
246
{
247
   return bo->gbm->bo_write(bo, buf, count);
248
}
249
 
250
/** Get the gbm device used to create the buffer object
251
 *
252
 * \param bo The buffer object
253
 * \return Returns the gbm device with which the buffer object was created
254
 */
255
GBM_EXPORT struct gbm_device *
256
gbm_bo_get_device(struct gbm_bo *bo)
257
{
258
	return bo->gbm;
259
}
260
 
261
/** Set the user data associated with a buffer object
262
 *
263
 * \param bo The buffer object
264
 * \param data The data to associate to the buffer object
265
 * \param destroy_user_data A callback (which may be %NULL) that will be
266
 * called prior to the buffer destruction
267
 */
268
GBM_EXPORT void
269
gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
270
		     void (*destroy_user_data)(struct gbm_bo *, void *))
271
{
272
   bo->user_data = data;
273
   bo->destroy_user_data = destroy_user_data;
274
}
275
 
276
/** Get the user data associated with a buffer object
277
 *
278
 * \param bo The buffer object
279
 * \return Returns the user data associated with the buffer object or %NULL
280
 * if no data was associated with it
281
 *
282
 * \sa gbm_bo_set_user_data()
283
 */
284
GBM_EXPORT void *
285
gbm_bo_get_user_data(struct gbm_bo *bo)
286
{
287
   return bo->user_data;
288
}
289
 
290
/**
291
 * Destroys the given buffer object and frees all resources associated with
292
 * it.
293
 *
294
 * \param bo The buffer object
295
 */
296
GBM_EXPORT void
297
gbm_bo_destroy(struct gbm_bo *bo)
298
{
299
   if (bo->destroy_user_data)
300
      bo->destroy_user_data(bo, bo->user_data);
301
 
302
   bo->gbm->bo_destroy(bo);
303
}
304
 
305
/**
306
 * Allocate a buffer object for the given dimensions
307
 *
308
 * \param gbm The gbm device returned from gbm_create_device()
309
 * \param width The width for the buffer
310
 * \param height The height for the buffer
311
 * \param format The format to use for the buffer
312
 * \param usage The union of the usage flags for this buffer
313
 *
314
 * \return A newly allocated buffer that should be freed with gbm_bo_destroy()
315
 * when no longer needed. If an error occurs during allocation %NULL will be
316
 * returned.
317
 *
318
 * \sa enum gbm_bo_format for the list of formats
319
 * \sa enum gbm_bo_flags for the list of usage flags
320
 */
321
GBM_EXPORT struct gbm_bo *
322
gbm_bo_create(struct gbm_device *gbm,
323
              uint32_t width, uint32_t height,
324
              uint32_t format, uint32_t usage)
325
{
326
   if (width == 0 || height == 0)
327
      return NULL;
328
 
329
   if (usage & GBM_BO_USE_CURSOR_64X64 &&
330
       (width != 64 || height != 64))
331
      return NULL;
332
 
333
   return gbm->bo_create(gbm, width, height, format, usage);
334
}
335
 
336
/**
337
 * Create a gbm buffer object from an foreign object
338
 *
339
 * This function imports a foreign object and creates a new gbm bo for it.
340
 * This enabled using the foreign object with a display API such as KMS.
341
 * Currently two types of foreign objects are supported, indicated by the type
342
 * argument:
343
 *
344
 *   GBM_BO_IMPORT_WL_BUFFER
345
 *   GBM_BO_IMPORT_EGL_IMAGE
346
 *
347
 * The the gbm bo shares the underlying pixels but its life-time is
348
 * independent of the foreign object.
349
 *
350
 * \param gbm The gbm device returned from gbm_create_device()
351
 * \param gbm The type of object we're importing
352
 * \param gbm Pointer to the external object
353
 * \param usage The union of the usage flags for this buffer
354
 *
355
 * \return A newly allocated buffer object that should be freed with
356
 * gbm_bo_destroy() when no longer needed.
357
 *
358
 * \sa enum gbm_bo_flags for the list of usage flags
359
 */
360
GBM_EXPORT struct gbm_bo *
361
gbm_bo_import(struct gbm_device *gbm,
362
              uint32_t type, void *buffer, uint32_t usage)
363
{
364
   return gbm->bo_import(gbm, type, buffer, usage);
365
}
366
 
367
/**
368
 * Allocate a surface object
369
 *
370
 * \param gbm The gbm device returned from gbm_create_device()
371
 * \param width The width for the surface
372
 * \param height The height for the surface
373
 * \param format The format to use for the surface
374
 *
375
 * \return A newly allocated surface that should be freed with
376
 * gbm_surface_destroy() when no longer needed. If an error occurs
377
 * during allocation %NULL will be returned.
378
 *
379
 * \sa enum gbm_bo_format for the list of formats
380
 */
381
GBM_EXPORT struct gbm_surface *
382
gbm_surface_create(struct gbm_device *gbm,
383
                   uint32_t width, uint32_t height,
384
		   uint32_t format, uint32_t flags)
385
{
386
   return gbm->surface_create(gbm, width, height, format, flags);
387
}
388
 
389
/**
390
 * Destroys the given surface and frees all resources associated with
391
 * it.
392
 *
393
 * All buffers locked with gbm_surface_lock_front_buffer() should be
394
 * released prior to calling this function.
395
 *
396
 * \param surf The surface
397
 */
398
GBM_EXPORT void
399
gbm_surface_destroy(struct gbm_surface *surf)
400
{
401
   surf->gbm->surface_destroy(surf);
402
}
403
 
404
/**
405
 * Lock the surface's current front buffer
406
 *
407
 * Lock rendering to the surface's current front buffer until it is
408
 * released with gbm_surface_release_buffer().
409
 *
410
 * This function must be called exactly once after calling
411
 * eglSwapBuffers.  Calling it before any eglSwapBuffer has happened
412
 * on the surface or two or more times after eglSwapBuffers is an
413
 * error.  A new bo representing the new front buffer is returned.  On
414
 * multiple invocations, all the returned bos must be released in
415
 * order to release the actual surface buffer.
416
 *
417
 * \param surf The surface
418
 *
419
 * \return A buffer object that should be released with
420
 * gbm_surface_release_buffer() when no longer needed.  The implementation
421
 * is free to reuse buffers released with gbm_surface_release_buffer() so
422
 * this bo should not be destroyed using gbm_bo_destroy().  If an error
423
 * occurs this function returns %NULL.
424
 */
425
GBM_EXPORT struct gbm_bo *
426
gbm_surface_lock_front_buffer(struct gbm_surface *surf)
427
{
428
   return surf->gbm->surface_lock_front_buffer(surf);
429
}
430
 
431
/**
432
 * Release a locked buffer obtained with gbm_surface_lock_front_buffer()
433
 *
434
 * Returns the underlying buffer to the gbm surface.  Releasing a bo
435
 * will typically make gbm_surface_has_free_buffer() return 1 and thus
436
 * allow rendering the next frame, but not always. The implementation
437
 * may choose to destroy the bo immediately or reuse it, in which case
438
 * the user data associated with it is unchanged.
439
 *
440
 * \param surf The surface
441
 * \param bo The buffer object
442
 */
443
GBM_EXPORT void
444
gbm_surface_release_buffer(struct gbm_surface *surf, struct gbm_bo *bo)
445
{
446
   surf->gbm->surface_release_buffer(surf, bo);
447
}
448
 
449
/**
450
 * Return whether or not a surface has free (non-locked) buffers
451
 *
452
 * Before starting a new frame, the surface must have a buffer
453
 * available for rendering.  Initially, a gbm surface will have a free
454
 * buffer, but after one of more buffers have been locked (\sa
455
 * gbm_surface_lock_front_buffer()), the application must check for a
456
 * free buffer before rendering.
457
 *
458
 * If a surface doesn't have a free buffer, the application must
459
 * return a buffer to the surface using gbm_surface_release_buffer()
460
 * and after that, the application can query for free buffers again.
461
 *
462
 * \param surf The surface
463
 * \return 1 if the surface has free buffers, 0 otherwise
464
 */
465
GBM_EXPORT int
466
gbm_surface_has_free_buffers(struct gbm_surface *surf)
467
{
468
   return surf->gbm->surface_has_free_buffers(surf);
469
}