• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
3  * Copyright (C) 2010-2011 LunarG Inc.
4  * Copyright (C) 2016 Linaro, Ltd., Rob Herring <robh@kernel.org>
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 #define LOG_TAG "GRALLOC-GBM"
26 
27 #include <log/log.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <string.h>
31 #include <pthread.h>
32 #include <errno.h>
33 
34 #include <hardware/gralloc.h>
35 #include <system/graphics.h>
36 
37 #include <gbm.h>
38 
39 #include "gralloc_drm.h"
40 #include "gralloc_gbm_priv.h"
41 
42 struct gbm_module_t {
43 	gralloc_module_t base;
44 
45 	pthread_mutex_t mutex;
46 	struct gbm_device *gbm;
47 };
48 
49 /*
50  * Initialize the DRM device object
51  */
gbm_init(struct gbm_module_t * dmod)52 static int gbm_init(struct gbm_module_t *dmod)
53 {
54 	int err = 0;
55 
56 	pthread_mutex_lock(&dmod->mutex);
57 	if (!dmod->gbm) {
58 		dmod->gbm = gbm_dev_create();
59 		if (!dmod->gbm)
60 			err = -EINVAL;
61 	}
62 	pthread_mutex_unlock(&dmod->mutex);
63 
64 	return err;
65 }
66 
gbm_mod_perform(const struct gralloc_module_t * mod,int op,...)67 static int gbm_mod_perform(const struct gralloc_module_t *mod, int op, ...)
68 {
69 	struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
70 	va_list args;
71 	int err;
72 	uint32_t uop = static_cast<uint32_t>(op);
73 
74 	err = gbm_init(dmod);
75 	if (err)
76 		return err;
77 
78 	va_start(args, op);
79 	switch (uop) {
80 	case GRALLOC_MODULE_PERFORM_GET_DRM_FD:
81 		{
82 			int *fd = va_arg(args, int *);
83 			*fd = gbm_device_get_fd(dmod->gbm);
84 			err = 0;
85 		}
86 		break;
87 	default:
88 		err = -EINVAL;
89 		break;
90 	}
91 	va_end(args);
92 
93 	return err;
94 }
95 
gbm_mod_register_buffer(const gralloc_module_t * mod,buffer_handle_t handle)96 static int gbm_mod_register_buffer(const gralloc_module_t *mod,
97 		buffer_handle_t handle)
98 {
99 	struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
100 	int err;
101 
102 	err = gbm_init(dmod);
103 	if (err)
104 		return err;
105 
106 	pthread_mutex_lock(&dmod->mutex);
107 	err = gralloc_gbm_handle_register(handle, dmod->gbm);
108 	pthread_mutex_unlock(&dmod->mutex);
109 
110 	return err;
111 }
112 
gbm_mod_unregister_buffer(const gralloc_module_t * mod,buffer_handle_t handle)113 static int gbm_mod_unregister_buffer(const gralloc_module_t *mod,
114 		buffer_handle_t handle)
115 {
116 	struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
117 	int err;
118 
119 	pthread_mutex_lock(&dmod->mutex);
120 	err = gralloc_gbm_handle_unregister(handle);
121 	pthread_mutex_unlock(&dmod->mutex);
122 
123 	return err;
124 }
125 
gbm_mod_lock(const gralloc_module_t * mod,buffer_handle_t handle,int usage,int x,int y,int w,int h,void ** ptr)126 static int gbm_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 gbm_module_t *dmod = (struct gbm_module_t *) mod;
130 	int err;
131 
132 	pthread_mutex_lock(&dmod->mutex);
133 
134 	err = gralloc_gbm_bo_lock(handle, usage, x, y, w, h, ptr);
135 	ALOGV("buffer %p lock usage = %08x", handle, usage);
136 
137 	pthread_mutex_unlock(&dmod->mutex);
138 	return err;
139 }
140 
gbm_mod_unlock(const gralloc_module_t * mod,buffer_handle_t handle)141 static int gbm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle)
142 {
143 	struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
144 	int err;
145 
146 	pthread_mutex_lock(&dmod->mutex);
147 	err = gralloc_gbm_bo_unlock(handle);
148 	pthread_mutex_unlock(&dmod->mutex);
149 
150 	return err;
151 }
152 
gbm_mod_lock_ycbcr(gralloc_module_t const * mod,buffer_handle_t handle,int usage,int x,int y,int w,int h,struct android_ycbcr * ycbcr)153 static int gbm_mod_lock_ycbcr(gralloc_module_t const *mod, buffer_handle_t handle,
154 		int usage, int x, int y, int w, int h, struct android_ycbcr *ycbcr)
155 {
156 	struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
157 	int err;
158 
159 	pthread_mutex_lock(&dmod->mutex);
160 	err = gralloc_gbm_bo_lock_ycbcr(handle, usage, x, y, w, h, ycbcr);
161 	pthread_mutex_unlock(&dmod->mutex);
162 
163 	return err;
164 }
165 
gbm_mod_close_gpu0(struct hw_device_t * dev)166 static int gbm_mod_close_gpu0(struct hw_device_t *dev)
167 {
168 	struct gbm_module_t *dmod = (struct gbm_module_t *)dev->module;
169 	struct alloc_device_t *alloc = (struct alloc_device_t *) dev;
170 
171 	gbm_dev_destroy(dmod->gbm);
172 	delete alloc;
173 
174 	return 0;
175 }
176 
gbm_mod_free_gpu0(alloc_device_t * dev,buffer_handle_t handle)177 static int gbm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle)
178 {
179 	struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
180 
181 	pthread_mutex_lock(&dmod->mutex);
182 	gbm_free(handle);
183 	native_handle_close(handle);
184 	delete handle;
185 
186 	pthread_mutex_unlock(&dmod->mutex);
187 	return 0;
188 }
189 
gbm_mod_alloc_gpu0(alloc_device_t * dev,int w,int h,int format,int usage,buffer_handle_t * handle,int * stride)190 static int gbm_mod_alloc_gpu0(alloc_device_t *dev,
191 		int w, int h, int format, int usage,
192 		buffer_handle_t *handle, int *stride)
193 {
194 	struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
195 	int err = 0;
196 
197 	pthread_mutex_lock(&dmod->mutex);
198 
199 	*handle = gralloc_gbm_bo_create(dmod->gbm, w, h, format, usage, stride);
200 	if (!*handle)
201 		err = -errno;
202 
203 	ALOGV("buffer %p usage = %08x", *handle, usage);
204 	pthread_mutex_unlock(&dmod->mutex);
205 	return err;
206 }
207 
gbm_mod_open_gpu0(struct gbm_module_t * dmod,hw_device_t ** dev)208 static int gbm_mod_open_gpu0(struct gbm_module_t *dmod, hw_device_t **dev)
209 {
210 	struct alloc_device_t *alloc;
211 	int err;
212 
213 	err = gbm_init(dmod);
214 	if (err)
215 		return err;
216 
217 	alloc = new alloc_device_t();
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 = gbm_mod_close_gpu0;
225 
226 	alloc->alloc = gbm_mod_alloc_gpu0;
227 	alloc->free = gbm_mod_free_gpu0;
228 
229 	*dev = &alloc->common;
230 
231 	return 0;
232 }
233 
gbm_mod_open(const struct hw_module_t * mod,const char * name,struct hw_device_t ** dev)234 static int gbm_mod_open(const struct hw_module_t *mod,
235 		const char *name, struct hw_device_t **dev)
236 {
237 	struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
238 	int err;
239 
240 	if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0)
241 		err = gbm_mod_open_gpu0(dmod, dev);
242 	else
243 		err = -EINVAL;
244 
245 	return err;
246 }
247 
248 static struct hw_module_methods_t gbm_mod_methods = {
249 	.open = gbm_mod_open
250 };
251 
252 struct gbm_module_t HAL_MODULE_INFO_SYM = {
253 	.base = {
254 		.common = {
255 			.tag = HARDWARE_MODULE_TAG,
256 			.version_major = 1,
257 			.version_minor = 0,
258 			.id = GRALLOC_HARDWARE_MODULE_ID,
259 			.name = "GBM Memory Allocator",
260 			.author = "Rob Herring - Linaro",
261 			.methods = &gbm_mod_methods
262 		},
263 		.registerBuffer = gbm_mod_register_buffer,
264 		.unregisterBuffer = gbm_mod_unregister_buffer,
265 		.lock = gbm_mod_lock,
266 		.unlock = gbm_mod_unlock,
267 		.lock_ycbcr = gbm_mod_lock_ycbcr,
268 		.perform = gbm_mod_perform
269 	},
270 
271 	.mutex = PTHREAD_MUTEX_INITIALIZER,
272 	.gbm = NULL,
273 };
274