OSDN Git Service

get rid of HAL pixelformats 5551 and 4444
[android-x86/external-drm_gralloc.git] / gralloc.c
1 /*
2  * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
3  * Copyright (C) 2010-2011 LunarG Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23
24 #define LOG_TAG "GRALLOC-MOD"
25
26 #include <cutils/log.h>
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <pthread.h>
30 #include <errno.h>
31
32 #include "gralloc_drm.h"
33 #include "gralloc_drm_priv.h"
34
35 /*
36  * Initialize the DRM device object, optionally with KMS.
37  */
38 static int drm_init(struct drm_module_t *dmod, int kms)
39 {
40         int err = 0;
41
42         pthread_mutex_lock(&dmod->mutex);
43         if (!dmod->drm) {
44                 dmod->drm = gralloc_drm_create();
45                 if (!dmod->drm)
46                         err = -EINVAL;
47         }
48         if (!err && kms)
49                 err = gralloc_drm_init_kms(dmod->drm);
50         pthread_mutex_unlock(&dmod->mutex);
51
52         return err;
53 }
54
55 static int drm_mod_perform(const struct gralloc_module_t *mod, int op, ...)
56 {
57         struct drm_module_t *dmod = (struct drm_module_t *) mod;
58         va_list args;
59         int err;
60
61         err = drm_init(dmod, 0);
62         if (err)
63                 return err;
64
65         va_start(args, op);
66         switch (op) {
67         case GRALLOC_MODULE_PERFORM_GET_DRM_FD:
68                 {
69                         int *fd = va_arg(args, int *);
70                         *fd = gralloc_drm_get_fd(dmod->drm);
71                         err = 0;
72                 }
73                 break;
74         /* should we remove this and next ops, and make it transparent? */
75         case GRALLOC_MODULE_PERFORM_GET_DRM_MAGIC:
76                 {
77                         int32_t *magic = va_arg(args, int32_t *);
78                         err = gralloc_drm_get_magic(dmod->drm, magic);
79                 }
80                 break;
81         case GRALLOC_MODULE_PERFORM_AUTH_DRM_MAGIC:
82                 {
83                         int32_t magic = va_arg(args, int32_t);
84                         err = gralloc_drm_auth_magic(dmod->drm, magic);
85                 }
86                 break;
87         case GRALLOC_MODULE_PERFORM_ENTER_VT:
88                 {
89                         err = gralloc_drm_set_master(dmod->drm);
90                 }
91                 break;
92         case GRALLOC_MODULE_PERFORM_LEAVE_VT:
93                 {
94                         gralloc_drm_drop_master(dmod->drm);
95                         err = 0;
96                 }
97                 break;
98         default:
99                 err = -EINVAL;
100                 break;
101         }
102         va_end(args);
103
104         return err;
105 }
106
107 static int drm_mod_register_buffer(const gralloc_module_t *mod,
108                 buffer_handle_t handle)
109 {
110         struct drm_module_t *dmod = (struct drm_module_t *) mod;
111         int err;
112
113         err = drm_init(dmod, 0);
114         if (err)
115                 return err;
116
117         return gralloc_drm_handle_register(handle, dmod->drm);
118 }
119
120 static int drm_mod_unregister_buffer(const gralloc_module_t *mod,
121                 buffer_handle_t handle)
122 {
123         return gralloc_drm_handle_unregister(handle);
124 }
125
126 static int drm_mod_lock(const gralloc_module_t *mod, buffer_handle_t handle,
127                 int usage, int x, int y, int w, int h, void **ptr)
128 {
129         struct gralloc_drm_bo_t *bo;
130         int err;
131
132         bo = gralloc_drm_bo_from_handle(handle);
133         if (!bo)
134                 return -EINVAL;
135
136         return gralloc_drm_bo_lock(bo, usage, x, y, w, h, ptr);
137 }
138
139 static int drm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle)
140 {
141         struct drm_module_t *dmod = (struct drm_module_t *) mod;
142         struct gralloc_drm_bo_t *bo;
143
144         bo = gralloc_drm_bo_from_handle(handle);
145         if (!bo)
146                 return -EINVAL;
147
148         gralloc_drm_bo_unlock(bo);
149
150         return 0;
151 }
152
153 static int drm_mod_close_gpu0(struct hw_device_t *dev)
154 {
155         struct alloc_device_t *alloc = (struct alloc_device_t *) dev;
156
157         free(alloc);
158
159         return 0;
160 }
161
162 static int drm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle)
163 {
164         struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module;
165         struct gralloc_drm_bo_t *bo;
166
167         bo = gralloc_drm_bo_from_handle(handle);
168         if (!bo)
169                 return -EINVAL;
170
171         gralloc_drm_bo_decref(bo);
172
173         return 0;
174 }
175
176 static int drm_mod_alloc_gpu0(alloc_device_t *dev,
177                 int w, int h, int format, int usage,
178                 buffer_handle_t *handle, int *stride)
179 {
180         struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module;
181         struct gralloc_drm_bo_t *bo;
182         int size, bpp, err;
183
184         bpp = gralloc_drm_get_bpp(format);
185         if (!bpp)
186                 return -EINVAL;
187
188         bo = gralloc_drm_bo_create(dmod->drm, w, h, format, usage);
189         if (!bo)
190                 return -ENOMEM;
191
192         if (gralloc_drm_bo_need_fb(bo)) {
193                 err = gralloc_drm_bo_add_fb(bo);
194                 if (err) {
195                         ALOGE("failed to add fb");
196                         gralloc_drm_bo_decref(bo);
197                         return err;
198                 }
199         }
200
201         *handle = gralloc_drm_bo_get_handle(bo, stride);
202         /* in pixels */
203         *stride /= bpp;
204
205         return 0;
206 }
207
208 static int drm_mod_open_gpu0(struct drm_module_t *dmod, hw_device_t **dev)
209 {
210         struct alloc_device_t *alloc;
211         int err;
212
213         err = drm_init(dmod, 0);
214         if (err)
215                 return err;
216
217         alloc = calloc(1, sizeof(*alloc));
218         if (!alloc)
219                 return -EINVAL;
220
221         alloc->common.tag = HARDWARE_DEVICE_TAG;
222         alloc->common.version = 0;
223         alloc->common.module = &dmod->base.common;
224         alloc->common.close = drm_mod_close_gpu0;
225
226         alloc->alloc = drm_mod_alloc_gpu0;
227         alloc->free = drm_mod_free_gpu0;
228
229         *dev = &alloc->common;
230
231         return 0;
232 }
233
234 static int drm_mod_close_fb0(struct hw_device_t *dev)
235 {
236         struct framebuffer_device_t *fb = (struct framebuffer_device_t *) dev;
237
238         free(fb);
239
240         return 0;
241 }
242
243 static int drm_mod_set_swap_interval_fb0(struct framebuffer_device_t *fb,
244                 int interval)
245 {
246         if (interval < fb->minSwapInterval || interval > fb->maxSwapInterval)
247                 return -EINVAL;
248         return 0;
249 }
250
251 static int drm_mod_post_fb0(struct framebuffer_device_t *fb,
252                 buffer_handle_t handle)
253 {
254         struct drm_module_t *dmod = (struct drm_module_t *) fb->common.module;
255         struct gralloc_drm_bo_t *bo;
256
257         bo = gralloc_drm_bo_from_handle(handle);
258         if (!bo)
259                 return -EINVAL;
260
261         return gralloc_drm_bo_post(bo);
262 }
263
264 #include <GLES/gl.h>
265 static int drm_mod_composition_complete_fb0(struct framebuffer_device_t *fb)
266 {
267         struct drm_module_t *dmod = (struct drm_module_t *) fb->common.module;
268
269         if (gralloc_drm_is_kms_pipelined(dmod->drm))
270                 glFlush();
271         else
272                 glFinish();
273
274         return 0;
275 }
276
277 static int drm_mod_open_fb0(struct drm_module_t *dmod, struct hw_device_t **dev)
278 {
279         struct framebuffer_device_t *fb;
280         int err;
281
282         err = drm_init(dmod, 1);
283         if (err)
284                 return err;
285
286         fb = calloc(1, sizeof(*fb));
287         if (!fb)
288                 return -ENOMEM;
289
290         fb->common.tag = HARDWARE_DEVICE_TAG;
291         fb->common.version = 0;
292         fb->common.module = &dmod->base.common;
293         fb->common.close = drm_mod_close_fb0;
294
295         fb->setSwapInterval = drm_mod_set_swap_interval_fb0;
296         fb->post = drm_mod_post_fb0;
297         fb->compositionComplete = drm_mod_composition_complete_fb0;
298
299         gralloc_drm_get_kms_info(dmod->drm, fb);
300
301         *dev = &fb->common;
302
303         ALOGI("mode.hdisplay %d\n"
304              "mode.vdisplay %d\n"
305              "mode.vrefresh %f\n"
306              "format 0x%x\n"
307              "xdpi %f\n"
308              "ydpi %f\n",
309              fb->width,
310              fb->height,
311              fb->fps,
312              fb->format,
313              fb->xdpi, fb->ydpi);
314
315         return 0;
316 }
317
318 static int drm_mod_open(const struct hw_module_t *mod,
319                 const char *name, struct hw_device_t **dev)
320 {
321         struct drm_module_t *dmod = (struct drm_module_t *) mod;
322         int err;
323
324         if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0)
325                 err = drm_mod_open_gpu0(dmod, dev);
326         else if (strcmp(name, GRALLOC_HARDWARE_FB0) == 0)
327                 err = drm_mod_open_fb0(dmod, dev);
328         else
329                 err = -EINVAL;
330
331         return err;
332 }
333
334 static struct hw_module_methods_t drm_mod_methods = {
335         .open = drm_mod_open
336 };
337
338 struct drm_module_t HAL_MODULE_INFO_SYM = {
339         .base = {
340                 .common = {
341                         .tag = HARDWARE_MODULE_TAG,
342                         .version_major = 1,
343                         .version_minor = 0,
344                         .id = GRALLOC_HARDWARE_MODULE_ID,
345                         .name = "DRM Memory Allocator",
346                         .author = "Chia-I Wu",
347                         .methods = &drm_mod_methods
348                 },
349                 .registerBuffer = drm_mod_register_buffer,
350                 .unregisterBuffer = drm_mod_unregister_buffer,
351                 .lock = drm_mod_lock,
352                 .unlock = drm_mod_unlock,
353                 .perform = drm_mod_perform
354         },
355         .hwc_reserve_plane = gralloc_drm_reserve_plane,
356         .hwc_disable_planes = gralloc_drm_disable_planes,
357         .hwc_set_plane_handle = gralloc_drm_set_plane_handle,
358
359         .mutex = PTHREAD_MUTEX_INITIALIZER,
360         .drm = NULL
361 };