blob: 421aeb540a2afc6e5c56d20bee98b40976582f75 [file] [log] [blame]
Chia-I Wu2ec32d42011-06-12 16:21:30 +08001/*
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"
Tapani Pälli25d22512013-02-18 12:35:42 +020033#include "gralloc_drm_priv.h"
Chia-I Wu2ec32d42011-06-12 16:21:30 +080034
35/*
Sean Pauld81a9372015-01-21 15:12:57 -050036 * Initialize the DRM device object
Chia-I Wu2ec32d42011-06-12 16:21:30 +080037 */
Sean Pauld81a9372015-01-21 15:12:57 -050038static int drm_init(struct drm_module_t *dmod)
Chia-I Wu2ec32d42011-06-12 16:21:30 +080039{
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 }
Chia-I Wu2ec32d42011-06-12 16:21:30 +080048 pthread_mutex_unlock(&dmod->mutex);
49
50 return err;
51}
52
53static int drm_mod_perform(const struct gralloc_module_t *mod, int op, ...)
54{
55 struct drm_module_t *dmod = (struct drm_module_t *) mod;
56 va_list args;
57 int err;
58
Sean Pauld81a9372015-01-21 15:12:57 -050059 err = drm_init(dmod);
Chia-I Wu2ec32d42011-06-12 16:21:30 +080060 if (err)
61 return err;
62
63 va_start(args, op);
64 switch (op) {
Stephen Hinescda66b82016-02-08 23:22:29 -080065 case static_cast<int>(GRALLOC_MODULE_PERFORM_GET_DRM_FD):
Chia-I Wu2ec32d42011-06-12 16:21:30 +080066 {
67 int *fd = va_arg(args, int *);
68 *fd = gralloc_drm_get_fd(dmod->drm);
69 err = 0;
70 }
71 break;
Chia-I Wu2ec32d42011-06-12 16:21:30 +080072 default:
73 err = -EINVAL;
74 break;
75 }
76 va_end(args);
77
78 return err;
79}
80
81static int drm_mod_register_buffer(const gralloc_module_t *mod,
82 buffer_handle_t handle)
83{
Chia-I Wu2fc5da42011-07-29 19:57:04 +090084 struct drm_module_t *dmod = (struct drm_module_t *) mod;
Chia-I Wu1db54032011-07-30 16:31:24 +090085 int err;
86
Sean Pauld81a9372015-01-21 15:12:57 -050087 err = drm_init(dmod);
Chia-I Wu1db54032011-07-30 16:31:24 +090088 if (err)
89 return err;
Chia-I Wu2fc5da42011-07-29 19:57:04 +090090
Chia-I Wu8542de32011-07-31 16:35:21 +090091 return gralloc_drm_handle_register(handle, dmod->drm);
Chia-I Wu2ec32d42011-06-12 16:21:30 +080092}
93
94static int drm_mod_unregister_buffer(const gralloc_module_t *mod,
95 buffer_handle_t handle)
96{
Chia-I Wu8542de32011-07-31 16:35:21 +090097 return gralloc_drm_handle_unregister(handle);
Chia-I Wu2ec32d42011-06-12 16:21:30 +080098}
99
100static int drm_mod_lock(const gralloc_module_t *mod, buffer_handle_t handle,
101 int usage, int x, int y, int w, int h, void **ptr)
102{
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800103 struct gralloc_drm_bo_t *bo;
104 int err;
105
Chia-I Wu8542de32011-07-31 16:35:21 +0900106 bo = gralloc_drm_bo_from_handle(handle);
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800107 if (!bo)
108 return -EINVAL;
109
Chia-I Wu25e04132011-07-29 20:43:12 +0900110 return gralloc_drm_bo_lock(bo, usage, x, y, w, h, ptr);
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800111}
112
Tomasz Figaa43d9522015-09-08 15:19:37 +0900113static int drm_mod_lock_ycbcr(const gralloc_module_t *mod, buffer_handle_t bhandle,
114 int usage, int x, int y, int w, int h, struct android_ycbcr *ycbcr)
115{
116 struct gralloc_drm_handle_t *handle;
117 struct gralloc_drm_bo_t *bo;
118 void *ptr;
119 int err;
120
121 bo = gralloc_drm_bo_from_handle(bhandle);
122 if (!bo)
123 return -EINVAL;
124 handle = bo->handle;
125
126 switch(handle->format) {
127 case HAL_PIXEL_FORMAT_YCbCr_420_888:
128 break;
129 default:
130 return -EINVAL;
131 }
132
133 err = gralloc_drm_bo_lock(bo, usage, x, y, w, h, &ptr);
134 if (err)
135 return err;
136
137 switch(handle->format) {
138 case HAL_PIXEL_FORMAT_YCbCr_420_888:
139 ycbcr->y = ptr;
140 ycbcr->cb = (uint8_t *)ptr + handle->stride * handle->height;
141 ycbcr->cr = (uint8_t *)ycbcr->cb + 1;
142 ycbcr->ystride = handle->stride;
143 ycbcr->cstride = handle->stride;
144 ycbcr->chroma_step = 2;
145 break;
146 default:
147 break;
148 }
149
150 return 0;
151}
152
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800153static int drm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle)
154{
155 struct drm_module_t *dmod = (struct drm_module_t *) mod;
156 struct gralloc_drm_bo_t *bo;
157
Chia-I Wu8542de32011-07-31 16:35:21 +0900158 bo = gralloc_drm_bo_from_handle(handle);
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800159 if (!bo)
160 return -EINVAL;
161
Chia-I Wu25e04132011-07-29 20:43:12 +0900162 gralloc_drm_bo_unlock(bo);
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800163
164 return 0;
165}
166
167static int drm_mod_close_gpu0(struct hw_device_t *dev)
168{
Sean Paul879cc4e2015-02-09 02:39:09 -0500169 struct drm_module_t *dmod = (struct drm_module_t *)dev->module;
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800170 struct alloc_device_t *alloc = (struct alloc_device_t *) dev;
171
Sean Paul879cc4e2015-02-09 02:39:09 -0500172 gralloc_drm_destroy(dmod->drm);
Sean Pauld225ab02015-02-09 02:31:58 -0500173 delete alloc;
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800174
175 return 0;
176}
177
178static int drm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle)
179{
180 struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module;
181 struct gralloc_drm_bo_t *bo;
182
Chia-I Wu8542de32011-07-31 16:35:21 +0900183 bo = gralloc_drm_bo_from_handle(handle);
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800184 if (!bo)
185 return -EINVAL;
186
Tapani Pällia86ecd92012-08-01 16:06:00 +0300187 gralloc_drm_bo_decref(bo);
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800188
189 return 0;
190}
191
192static int drm_mod_alloc_gpu0(alloc_device_t *dev,
193 int w, int h, int format, int usage,
194 buffer_handle_t *handle, int *stride)
195{
196 struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module;
197 struct gralloc_drm_bo_t *bo;
198 int size, bpp, err;
199
200 bpp = gralloc_drm_get_bpp(format);
201 if (!bpp)
202 return -EINVAL;
203
204 bo = gralloc_drm_bo_create(dmod->drm, w, h, format, usage);
205 if (!bo)
206 return -ENOMEM;
207
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800208 *handle = gralloc_drm_bo_get_handle(bo, stride);
209 /* in pixels */
210 *stride /= bpp;
211
212 return 0;
213}
214
215static int drm_mod_open_gpu0(struct drm_module_t *dmod, hw_device_t **dev)
216{
217 struct alloc_device_t *alloc;
218 int err;
219
Sean Pauld81a9372015-01-21 15:12:57 -0500220 err = drm_init(dmod);
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800221 if (err)
222 return err;
223
Sean Pauld225ab02015-02-09 02:31:58 -0500224 alloc = new alloc_device_t;
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800225 if (!alloc)
226 return -EINVAL;
227
228 alloc->common.tag = HARDWARE_DEVICE_TAG;
229 alloc->common.version = 0;
230 alloc->common.module = &dmod->base.common;
231 alloc->common.close = drm_mod_close_gpu0;
232
233 alloc->alloc = drm_mod_alloc_gpu0;
234 alloc->free = drm_mod_free_gpu0;
235
236 *dev = &alloc->common;
237
238 return 0;
239}
240
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800241static int drm_mod_open(const struct hw_module_t *mod,
242 const char *name, struct hw_device_t **dev)
243{
244 struct drm_module_t *dmod = (struct drm_module_t *) mod;
245 int err;
246
247 if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0)
248 err = drm_mod_open_gpu0(dmod, dev);
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800249 else
250 err = -EINVAL;
251
252 return err;
253}
254
255static struct hw_module_methods_t drm_mod_methods = {
256 .open = drm_mod_open
257};
258
259struct drm_module_t HAL_MODULE_INFO_SYM = {
260 .base = {
261 .common = {
262 .tag = HARDWARE_MODULE_TAG,
263 .version_major = 1,
264 .version_minor = 0,
265 .id = GRALLOC_HARDWARE_MODULE_ID,
266 .name = "DRM Memory Allocator",
267 .author = "Chia-I Wu",
268 .methods = &drm_mod_methods
269 },
270 .registerBuffer = drm_mod_register_buffer,
271 .unregisterBuffer = drm_mod_unregister_buffer,
272 .lock = drm_mod_lock,
273 .unlock = drm_mod_unlock,
Tomasz Figaa43d9522015-09-08 15:19:37 +0900274 .perform = drm_mod_perform,
275 .lock_ycbcr = drm_mod_lock_ycbcr,
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800276 },
Tapani Pällib201e982013-04-15 09:10:09 +0300277
Chia-I Wu2ec32d42011-06-12 16:21:30 +0800278 .mutex = PTHREAD_MUTEX_INITIALIZER,
279 .drm = NULL
280};