blob: 4ef7659cd5ecd870358d68c002bbb3e57993d5bf [file] [log] [blame]
The Android Open Source Project51704be2008-12-17 18:05:50 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "Overlay"
18
19#include <hardware/hardware.h>
20#include <hardware/overlay.h>
21
22#include <fcntl.h>
23#include <errno.h>
24
25#include <cutils/log.h>
26#include <cutils/atomic.h>
27
28/*****************************************************************************/
29
The Android Open Source Project699d24a2009-01-09 17:51:24 -080030struct overlay_control_context_t {
31 struct overlay_control_device_t device;
The Android Open Source Project51704be2008-12-17 18:05:50 -080032 /* our private state goes below here */
33};
34
The Android Open Source Project699d24a2009-01-09 17:51:24 -080035struct overlay_data_context_t {
36 struct overlay_data_device_t device;
37 /* our private state goes below here */
38};
The Android Open Source Project51704be2008-12-17 18:05:50 -080039
40static int overlay_device_open(const struct hw_module_t* module, const char* name,
41 struct hw_device_t** device);
42
43static struct hw_module_methods_t overlay_module_methods = {
44 open: overlay_device_open
45};
46
47const struct overlay_module_t HAL_MODULE_INFO_SYM = {
48 common: {
49 tag: HARDWARE_MODULE_TAG,
50 version_major: 1,
51 version_minor: 0,
52 id: OVERLAY_HARDWARE_MODULE_ID,
53 name: "Sample Overlay module",
54 author: "The Android Open Source Project",
55 methods: &overlay_module_methods,
56 }
57};
58
59/*****************************************************************************/
60
61/*
62 * This is the overlay_t object, it is returned to the user and represents
63 * an overlay. here we use a subclass, where we can store our own state.
64 * Notice the use of "overlay_handle_t", which is an "opaque" marshallable
65 * handle, it can contains any number of ints and up to 4 filedescriptors.
66 * In this example we store no fd and 2 ints.
67 * This handles will be passed across processes and possibly given to other
68 * HAL modules (for instance video decode modules).
69 */
70
71class overlay_object : public overlay_t {
72
73 struct handle_t : public overlay_handle_t {
74 /* add the data fields we need here, for instance: */
75 int width;
76 int height;
77 };
78
79 handle_t mHandle;
80
81 static overlay_handle_t const* getHandleRef(struct overlay_t* overlay) {
82 /* returns a reference to the handle, caller doesn't take ownership */
83 return &(static_cast<overlay_object *>(overlay)->mHandle);
84 }
85
86public:
87 overlay_object() {
88 this->overlay_t::getHandleRef = getHandleRef;
89 mHandle.numFds = 0;
90 mHandle.numInts = 2; // extra ints we have in our handle
91 }
92};
93
The Android Open Source Project699d24a2009-01-09 17:51:24 -080094// ****************************************************************************
95// Control module
96// ****************************************************************************
The Android Open Source Project51704be2008-12-17 18:05:50 -080097
The Android Open Source Project699d24a2009-01-09 17:51:24 -080098static int overlay_get(struct overlay_control_device_t *dev, int name) {
The Android Open Source Project51704be2008-12-17 18:05:50 -080099 int result = -1;
100 switch (name) {
101 case OVERLAY_MINIFICATION_LIMIT:
102 result = 0; // 0 = no limit
103 break;
104 case OVERLAY_MAGNIFICATION_LIMIT:
105 result = 0; // 0 = no limit
106 break;
107 case OVERLAY_SCALING_FRAC_BITS:
108 result = 0; // 0 = infinite
109 break;
110 case OVERLAY_ROTATION_STEP_DEG:
111 result = 90; // 90 rotation steps (for instance)
112 break;
113 case OVERLAY_HORIZONTAL_ALIGNMENT:
114 result = 1; // 1-pixel alignment
115 break;
116 case OVERLAY_VERTICAL_ALIGNMENT:
117 result = 1; // 1-pixel alignment
118 break;
119 case OVERLAY_WIDTH_ALIGNMENT:
120 result = 1; // 1-pixel alignment
121 break;
122 case OVERLAY_HEIGHT_ALIGNMENT:
123 result = 1; // 1-pixel alignment
124 break;
125 }
126 return result;
127}
128
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800129static overlay_t* overlay_createOverlay(struct overlay_control_device_t *dev,
The Android Open Source Project51704be2008-12-17 18:05:50 -0800130 uint32_t w, uint32_t h, int32_t format)
131{
132 /* check the input params, reject if not supported or invalid */
133 switch (format) {
134 case OVERLAY_FORMAT_RGBA_8888:
135 case OVERLAY_FORMAT_RGB_565:
136 case OVERLAY_FORMAT_BGRA_8888:
137 case OVERLAY_FORMAT_YCbCr_422_SP:
138 case OVERLAY_FORMAT_YCbCr_420_SP:
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800139 case OVERLAY_FORMAT_YCbCr_422_I:
140 case OVERLAY_FORMAT_YCbCr_420_I:
The Android Open Source Project51704be2008-12-17 18:05:50 -0800141 break;
142 default:
143 return NULL;
144 }
145
146 /* Create overlay object. Talk to the h/w here and adjust to what it can
147 * do. the overlay_t returned can be a C++ object, subclassing overlay_t
148 * if needed.
149 *
150 * we probably want to keep a list of the overlay_t created so they can
151 * all be cleaned up in overlay_close().
152 */
153 return new overlay_object( /* pass needed params here*/ );
154}
155
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800156static void overlay_destroyOverlay(struct overlay_control_device_t *dev,
The Android Open Source Project51704be2008-12-17 18:05:50 -0800157 overlay_t* overlay)
158{
159 /* free resources associated with this overlay_t */
160 delete overlay;
161}
162
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800163static int overlay_setPosition(struct overlay_control_device_t *dev,
The Android Open Source Project51704be2008-12-17 18:05:50 -0800164 overlay_t* overlay,
165 int x, int y, uint32_t w, uint32_t h) {
166 /* set this overlay's position (talk to the h/w) */
167 return -EINVAL;
168}
169
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800170static int overlay_getPosition(struct overlay_control_device_t *dev,
The Android Open Source Project51704be2008-12-17 18:05:50 -0800171 overlay_t* overlay,
172 int* x, int* y, uint32_t* w, uint32_t* h) {
173 /* get this overlay's position */
174 return -EINVAL;
175}
176
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800177static int overlay_setParameter(struct overlay_control_device_t *dev,
The Android Open Source Project51704be2008-12-17 18:05:50 -0800178 overlay_t* overlay, int param, int value) {
179
180 int result = 0;
181 /* set this overlay's parameter (talk to the h/w) */
182 switch (param) {
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800183 case OVERLAY_ROTATION_DEG:
184 /* if only 90 rotations are supported, the call fails
185 * for other values */
The Android Open Source Project51704be2008-12-17 18:05:50 -0800186 break;
187 case OVERLAY_DITHER:
188 break;
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800189 case OVERLAY_TRANSFORM:
190 // see OVERLAY_TRANSFORM_*
191 break;
The Android Open Source Project51704be2008-12-17 18:05:50 -0800192 default:
193 result = -EINVAL;
194 break;
195 }
196 return result;
197}
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800198
199static int overlay_control_close(struct hw_device_t *dev)
200{
201 struct overlay_control_context_t* ctx = (struct overlay_control_context_t*)dev;
202 if (ctx) {
203 /* free all resources associated with this device here
204 * in particular the overlay_handle_t, outstanding overlay_t, etc...
205 */
206 free(ctx);
207 }
The Android Open Source Project51704be2008-12-17 18:05:50 -0800208 return 0;
209}
210
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800211// ****************************************************************************
212// Data module
213// ****************************************************************************
214
215int overlay_initialize(struct overlay_data_device_t *dev,
216 overlay_handle_t const* handle)
217{
218 /*
219 * overlay_handle_t should contain all the information to "inflate" this
220 * overlay. Typically it'll have a file descriptor, informations about
221 * how many buffers are there, etc...
222 * It is also the place to mmap all buffers associated with this overlay
223 * (see getBufferAddress).
224 *
225 * NOTE: this function doesn't take ownership of overlay_handle_t
226 *
227 */
228
The Android Open Source Project51704be2008-12-17 18:05:50 -0800229 return -EINVAL;
230}
231
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800232overlay_buffer_t overlay_dequeueBuffer(struct overlay_data_device_t *dev)
The Android Open Source Project51704be2008-12-17 18:05:50 -0800233{
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800234 /* blocks until a buffer is available and return an opaque structure
235 * representing this buffer.
236 */
237 return NULL;
238}
239
240int overlay_queueBuffer(struct overlay_data_device_t *dev,
241 overlay_buffer_t buffer)
242{
243 /* Mark this buffer for posting and recycle or free overlay_buffer_t. */
244 return -EINVAL;
245}
246
247void *overlay_getBufferAddress(struct overlay_data_device_t *dev,
248 overlay_buffer_t buffer)
249{
250 /* this may fail (NULL) if this feature is not supported. In that case,
251 * presumably, there is some other HAL module that can fill the buffer,
252 * using a DSP for instance */
253 return NULL;
254}
255
256static int overlay_data_close(struct hw_device_t *dev)
257{
258 struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
The Android Open Source Project51704be2008-12-17 18:05:50 -0800259 if (ctx) {
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800260 /* free all resources associated with this device here
261 * in particular all pending overlay_buffer_t if needed.
262 *
263 * NOTE: overlay_handle_t passed in initialize() is NOT freed and
264 * its file descriptors are not closed (this is the responsibility
265 * of the caller).
266 */
The Android Open Source Project51704be2008-12-17 18:05:50 -0800267 free(ctx);
268 }
269 return 0;
270}
271
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800272/*****************************************************************************/
The Android Open Source Project51704be2008-12-17 18:05:50 -0800273
274static int overlay_device_open(const struct hw_module_t* module, const char* name,
275 struct hw_device_t** device)
276{
277 int status = -EINVAL;
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800278 if (!strcmp(name, OVERLAY_HARDWARE_CONTROL)) {
279 struct overlay_control_context_t *dev;
280 dev = (overlay_control_context_t*)malloc(sizeof(*dev));
The Android Open Source Project51704be2008-12-17 18:05:50 -0800281
282 /* initialize our state here */
283 memset(dev, 0, sizeof(*dev));
284
285 /* initialize the procs */
286 dev->device.common.tag = HARDWARE_DEVICE_TAG;
287 dev->device.common.version = 0;
288 dev->device.common.module = const_cast<hw_module_t*>(module);
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800289 dev->device.common.close = overlay_control_close;
The Android Open Source Project51704be2008-12-17 18:05:50 -0800290
291 dev->device.get = overlay_get;
292 dev->device.createOverlay = overlay_createOverlay;
293 dev->device.destroyOverlay = overlay_destroyOverlay;
294 dev->device.setPosition = overlay_setPosition;
295 dev->device.getPosition = overlay_getPosition;
296 dev->device.setParameter = overlay_setParameter;
The Android Open Source Project51704be2008-12-17 18:05:50 -0800297
298 *device = &dev->device.common;
299 status = 0;
The Android Open Source Project699d24a2009-01-09 17:51:24 -0800300 } else if (!strcmp(name, OVERLAY_HARDWARE_DATA)) {
301 struct overlay_data_context_t *dev;
302 dev = (overlay_data_context_t*)malloc(sizeof(*dev));
303
304 /* initialize our state here */
305 memset(dev, 0, sizeof(*dev));
306
307 /* initialize the procs */
308 dev->device.common.tag = HARDWARE_DEVICE_TAG;
309 dev->device.common.version = 0;
310 dev->device.common.module = const_cast<hw_module_t*>(module);
311 dev->device.common.close = overlay_data_close;
312
313 dev->device.initialize = overlay_initialize;
314 dev->device.dequeueBuffer = overlay_dequeueBuffer;
315 dev->device.queueBuffer = overlay_queueBuffer;
316 dev->device.getBufferAddress = overlay_getBufferAddress;
317
318 *device = &dev->device.common;
319 status = 0;
The Android Open Source Project51704be2008-12-17 18:05:50 -0800320 }
321 return status;
322}