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
37 */
drm_init(struct drm_module_t * dmod)38 static int drm_init(struct drm_module_t *dmod)
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 pthread_mutex_unlock(&dmod->mutex);
49
50 return err;
51 }
52
drm_mod_perform(const struct gralloc_module_t * mod,int op,...)53 static 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
59 err = drm_init(dmod);
60 if (err)
61 return err;
62
63 va_start(args, op);
64 switch (op) {
65 case GRALLOC_MODULE_PERFORM_GET_DRM_FD:
66 {
67 int *fd = va_arg(args, int *);
68 *fd = gralloc_drm_get_fd(dmod->drm);
69 err = 0;
70 }
71 break;
72 default:
73 err = -EINVAL;
74 break;
75 }
76 va_end(args);
77
78 return err;
79 }
80
drm_mod_register_buffer(const gralloc_module_t * mod,buffer_handle_t handle)81 static int drm_mod_register_buffer(const gralloc_module_t *mod,
82 buffer_handle_t handle)
83 {
84 struct drm_module_t *dmod = (struct drm_module_t *) mod;
85 int err;
86
87 err = drm_init(dmod);
88 if (err)
89 return err;
90
91 return gralloc_drm_handle_register(handle, dmod->drm);
92 }
93
drm_mod_unregister_buffer(const gralloc_module_t * mod,buffer_handle_t handle)94 static int drm_mod_unregister_buffer(const gralloc_module_t *mod,
95 buffer_handle_t handle)
96 {
97 return gralloc_drm_handle_unregister(handle);
98 }
99
drm_mod_lock(const gralloc_module_t * mod,buffer_handle_t handle,int usage,int x,int y,int w,int h,void ** ptr)100 static 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 {
103 struct gralloc_drm_bo_t *bo;
104 int err;
105
106 bo = gralloc_drm_bo_from_handle(handle);
107 if (!bo)
108 return -EINVAL;
109
110 return gralloc_drm_bo_lock(bo, usage, x, y, w, h, ptr);
111 }
112
drm_mod_unlock(const gralloc_module_t * mod,buffer_handle_t handle)113 static int drm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle)
114 {
115 struct drm_module_t *dmod = (struct drm_module_t *) mod;
116 struct gralloc_drm_bo_t *bo;
117
118 bo = gralloc_drm_bo_from_handle(handle);
119 if (!bo)
120 return -EINVAL;
121
122 gralloc_drm_bo_unlock(bo);
123
124 return 0;
125 }
126
drm_mod_close_gpu0(struct hw_device_t * dev)127 static int drm_mod_close_gpu0(struct hw_device_t *dev)
128 {
129 struct drm_module_t *dmod = (struct drm_module_t *)dev->module;
130 struct alloc_device_t *alloc = (struct alloc_device_t *) dev;
131
132 gralloc_drm_destroy(dmod->drm);
133 delete alloc;
134
135 return 0;
136 }
137
drm_mod_free_gpu0(alloc_device_t * dev,buffer_handle_t handle)138 static int drm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle)
139 {
140 struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module;
141 struct gralloc_drm_bo_t *bo;
142
143 bo = gralloc_drm_bo_from_handle(handle);
144 if (!bo)
145 return -EINVAL;
146
147 gralloc_drm_bo_decref(bo);
148
149 return 0;
150 }
151
drm_mod_alloc_gpu0(alloc_device_t * dev,int w,int h,int format,int usage,buffer_handle_t * handle,int * stride)152 static int drm_mod_alloc_gpu0(alloc_device_t *dev,
153 int w, int h, int format, int usage,
154 buffer_handle_t *handle, int *stride)
155 {
156 struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module;
157 struct gralloc_drm_bo_t *bo;
158 int size, bpp, err;
159
160 bpp = gralloc_drm_get_bpp(format);
161 if (!bpp)
162 return -EINVAL;
163
164 bo = gralloc_drm_bo_create(dmod->drm, w, h, format, usage);
165 if (!bo)
166 return -ENOMEM;
167
168 *handle = gralloc_drm_bo_get_handle(bo, stride);
169 /* in pixels */
170 *stride /= bpp;
171
172 return 0;
173 }
174
drm_mod_open_gpu0(struct drm_module_t * dmod,hw_device_t ** dev)175 static int drm_mod_open_gpu0(struct drm_module_t *dmod, hw_device_t **dev)
176 {
177 struct alloc_device_t *alloc;
178 int err;
179
180 err = drm_init(dmod);
181 if (err)
182 return err;
183
184 alloc = new alloc_device_t;
185 if (!alloc)
186 return -EINVAL;
187
188 alloc->common.tag = HARDWARE_DEVICE_TAG;
189 alloc->common.version = 0;
190 alloc->common.module = &dmod->base.common;
191 alloc->common.close = drm_mod_close_gpu0;
192
193 alloc->alloc = drm_mod_alloc_gpu0;
194 alloc->free = drm_mod_free_gpu0;
195
196 *dev = &alloc->common;
197
198 return 0;
199 }
200
drm_mod_open(const struct hw_module_t * mod,const char * name,struct hw_device_t ** dev)201 static int drm_mod_open(const struct hw_module_t *mod,
202 const char *name, struct hw_device_t **dev)
203 {
204 struct drm_module_t *dmod = (struct drm_module_t *) mod;
205 int err;
206
207 if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0)
208 err = drm_mod_open_gpu0(dmod, dev);
209 else
210 err = -EINVAL;
211
212 return err;
213 }
214
215 static struct hw_module_methods_t drm_mod_methods = {
216 .open = drm_mod_open
217 };
218
219 struct drm_module_t HAL_MODULE_INFO_SYM = {
220 .base = {
221 .common = {
222 .tag = HARDWARE_MODULE_TAG,
223 .version_major = 1,
224 .version_minor = 0,
225 .id = GRALLOC_HARDWARE_MODULE_ID,
226 .name = "DRM Memory Allocator",
227 .author = "Chia-I Wu",
228 .methods = &drm_mod_methods
229 },
230 .registerBuffer = drm_mod_register_buffer,
231 .unregisterBuffer = drm_mod_unregister_buffer,
232 .lock = drm_mod_lock,
233 .unlock = drm_mod_unlock,
234 .perform = drm_mod_perform
235 },
236
237 .mutex = PTHREAD_MUTEX_INITIALIZER,
238 .drm = NULL
239 };
240