1 /*
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
30 struct overlay_control_context_t {
31 struct overlay_control_device_t device;
32 /* our private state goes below here */
33 };
34
35 struct overlay_data_context_t {
36 struct overlay_data_device_t device;
37 /* our private state goes below here */
38 };
39
40 static int overlay_device_open(const struct hw_module_t* module, const char* name,
41 struct hw_device_t** device);
42
43 static struct hw_module_methods_t overlay_module_methods = {
44 open: overlay_device_open
45 };
46
47 const 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.
64 * This handles will be passed across processes and possibly given to other
65 * HAL modules (for instance video decode modules).
66 */
67
68 class overlay_object : public overlay_t {
69
70 struct handle_t : public native_handle {
71 /* add the data fields we need here, for instance: */
72 int width;
73 int height;
74 };
75
76 handle_t mHandle;
77
getHandleRef(struct overlay_t * overlay)78 static overlay_handle_t getHandleRef(struct overlay_t* overlay) {
79 /* returns a reference to the handle, caller doesn't take ownership */
80 return &(static_cast<overlay_object *>(overlay)->mHandle);
81 }
82
83 public:
overlay_object()84 overlay_object() {
85 this->overlay_t::getHandleRef = getHandleRef;
86 mHandle.version = sizeof(native_handle);
87 mHandle.numFds = 0;
88 mHandle.numInts = 2; // extra ints we have in our handle
89 }
90 };
91
92 // ****************************************************************************
93 // Control module
94 // ****************************************************************************
95
overlay_get(struct overlay_control_device_t * dev,int name)96 static int overlay_get(struct overlay_control_device_t *dev, int name) {
97 int result = -1;
98 switch (name) {
99 case OVERLAY_MINIFICATION_LIMIT:
100 result = 0; // 0 = no limit
101 break;
102 case OVERLAY_MAGNIFICATION_LIMIT:
103 result = 0; // 0 = no limit
104 break;
105 case OVERLAY_SCALING_FRAC_BITS:
106 result = 0; // 0 = infinite
107 break;
108 case OVERLAY_ROTATION_STEP_DEG:
109 result = 90; // 90 rotation steps (for instance)
110 break;
111 case OVERLAY_HORIZONTAL_ALIGNMENT:
112 result = 1; // 1-pixel alignment
113 break;
114 case OVERLAY_VERTICAL_ALIGNMENT:
115 result = 1; // 1-pixel alignment
116 break;
117 case OVERLAY_WIDTH_ALIGNMENT:
118 result = 1; // 1-pixel alignment
119 break;
120 case OVERLAY_HEIGHT_ALIGNMENT:
121 result = 1; // 1-pixel alignment
122 break;
123 }
124 return result;
125 }
126
overlay_createOverlay(struct overlay_control_device_t * dev,uint32_t w,uint32_t h,int32_t format)127 static overlay_t* overlay_createOverlay(struct overlay_control_device_t *dev,
128 uint32_t w, uint32_t h, int32_t format)
129 {
130 /* check the input params, reject if not supported or invalid */
131 switch (format) {
132 case OVERLAY_FORMAT_RGBA_8888:
133 case OVERLAY_FORMAT_RGB_565:
134 case OVERLAY_FORMAT_BGRA_8888:
135 case OVERLAY_FORMAT_YCbCr_422_SP:
136 case OVERLAY_FORMAT_YCbCr_420_SP:
137 case OVERLAY_FORMAT_YCbCr_422_I:
138 case OVERLAY_FORMAT_YCbCr_420_I:
139 break;
140 default:
141 return NULL;
142 }
143
144 /* Create overlay object. Talk to the h/w here and adjust to what it can
145 * do. the overlay_t returned can be a C++ object, subclassing overlay_t
146 * if needed.
147 *
148 * we probably want to keep a list of the overlay_t created so they can
149 * all be cleaned up in overlay_close().
150 */
151 return new overlay_object( /* pass needed params here*/ );
152 }
153
overlay_destroyOverlay(struct overlay_control_device_t * dev,overlay_t * overlay)154 static void overlay_destroyOverlay(struct overlay_control_device_t *dev,
155 overlay_t* overlay)
156 {
157 /* free resources associated with this overlay_t */
158 delete overlay;
159 }
160
overlay_setPosition(struct overlay_control_device_t * dev,overlay_t * overlay,int x,int y,uint32_t w,uint32_t h)161 static int overlay_setPosition(struct overlay_control_device_t *dev,
162 overlay_t* overlay,
163 int x, int y, uint32_t w, uint32_t h) {
164 /* set this overlay's position (talk to the h/w) */
165 return -EINVAL;
166 }
167
overlay_getPosition(struct overlay_control_device_t * dev,overlay_t * overlay,int * x,int * y,uint32_t * w,uint32_t * h)168 static int overlay_getPosition(struct overlay_control_device_t *dev,
169 overlay_t* overlay,
170 int* x, int* y, uint32_t* w, uint32_t* h) {
171 /* get this overlay's position */
172 return -EINVAL;
173 }
174
overlay_setParameter(struct overlay_control_device_t * dev,overlay_t * overlay,int param,int value)175 static int overlay_setParameter(struct overlay_control_device_t *dev,
176 overlay_t* overlay, int param, int value) {
177
178 int result = 0;
179 /* set this overlay's parameter (talk to the h/w) */
180 switch (param) {
181 case OVERLAY_ROTATION_DEG:
182 /* if only 90 rotations are supported, the call fails
183 * for other values */
184 break;
185 case OVERLAY_DITHER:
186 break;
187 case OVERLAY_TRANSFORM:
188 // see OVERLAY_TRANSFORM_*
189 break;
190 default:
191 result = -EINVAL;
192 break;
193 }
194 return result;
195 }
196
overlay_control_close(struct hw_device_t * dev)197 static int overlay_control_close(struct hw_device_t *dev)
198 {
199 struct overlay_control_context_t* ctx = (struct overlay_control_context_t*)dev;
200 if (ctx) {
201 /* free all resources associated with this device here
202 * in particular the overlay_handle_t, outstanding overlay_t, etc...
203 */
204 free(ctx);
205 }
206 return 0;
207 }
208
209 // ****************************************************************************
210 // Data module
211 // ****************************************************************************
212
overlay_initialize(struct overlay_data_device_t * dev,overlay_handle_t handle)213 int overlay_initialize(struct overlay_data_device_t *dev,
214 overlay_handle_t handle)
215 {
216 /*
217 * overlay_handle_t should contain all the information to "inflate" this
218 * overlay. Typically it'll have a file descriptor, informations about
219 * how many buffers are there, etc...
220 * It is also the place to mmap all buffers associated with this overlay
221 * (see getBufferAddress).
222 *
223 * NOTE: this function doesn't take ownership of overlay_handle_t
224 *
225 */
226
227 return -EINVAL;
228 }
229
overlay_dequeueBuffer(struct overlay_data_device_t * dev,overlay_buffer_t * buf)230 int overlay_dequeueBuffer(struct overlay_data_device_t *dev,
231 overlay_buffer_t* buf)
232 {
233 /* blocks until a buffer is available and return an opaque structure
234 * representing this buffer.
235 */
236 return -EINVAL;
237 }
238
overlay_queueBuffer(struct overlay_data_device_t * dev,overlay_buffer_t buffer)239 int overlay_queueBuffer(struct overlay_data_device_t *dev,
240 overlay_buffer_t buffer)
241 {
242 /* Mark this buffer for posting and recycle or free overlay_buffer_t. */
243 return -EINVAL;
244 }
245
overlay_getBufferAddress(struct overlay_data_device_t * dev,overlay_buffer_t buffer)246 void *overlay_getBufferAddress(struct overlay_data_device_t *dev,
247 overlay_buffer_t buffer)
248 {
249 /* this may fail (NULL) if this feature is not supported. In that case,
250 * presumably, there is some other HAL module that can fill the buffer,
251 * using a DSP for instance */
252 return NULL;
253 }
254
overlay_data_close(struct hw_device_t * dev)255 static int overlay_data_close(struct hw_device_t *dev)
256 {
257 struct overlay_data_context_t* ctx = (struct overlay_data_context_t*)dev;
258 if (ctx) {
259 /* free all resources associated with this device here
260 * in particular all pending overlay_buffer_t if needed.
261 *
262 * NOTE: overlay_handle_t passed in initialize() is NOT freed and
263 * its file descriptors are not closed (this is the responsibility
264 * of the caller).
265 */
266 free(ctx);
267 }
268 return 0;
269 }
270
271 /*****************************************************************************/
272
overlay_device_open(const struct hw_module_t * module,const char * name,struct hw_device_t ** device)273 static int overlay_device_open(const struct hw_module_t* module, const char* name,
274 struct hw_device_t** device)
275 {
276 int status = -EINVAL;
277 if (!strcmp(name, OVERLAY_HARDWARE_CONTROL)) {
278 struct overlay_control_context_t *dev;
279 dev = (overlay_control_context_t*)malloc(sizeof(*dev));
280
281 /* initialize our state here */
282 memset(dev, 0, sizeof(*dev));
283
284 /* initialize the procs */
285 dev->device.common.tag = HARDWARE_DEVICE_TAG;
286 dev->device.common.version = 0;
287 dev->device.common.module = const_cast<hw_module_t*>(module);
288 dev->device.common.close = overlay_control_close;
289
290 dev->device.get = overlay_get;
291 dev->device.createOverlay = overlay_createOverlay;
292 dev->device.destroyOverlay = overlay_destroyOverlay;
293 dev->device.setPosition = overlay_setPosition;
294 dev->device.getPosition = overlay_getPosition;
295 dev->device.setParameter = overlay_setParameter;
296
297 *device = &dev->device.common;
298 status = 0;
299 } else if (!strcmp(name, OVERLAY_HARDWARE_DATA)) {
300 struct overlay_data_context_t *dev;
301 dev = (overlay_data_context_t*)malloc(sizeof(*dev));
302
303 /* initialize our state here */
304 memset(dev, 0, sizeof(*dev));
305
306 /* initialize the procs */
307 dev->device.common.tag = HARDWARE_DEVICE_TAG;
308 dev->device.common.version = 0;
309 dev->device.common.module = const_cast<hw_module_t*>(module);
310 dev->device.common.close = overlay_data_close;
311
312 dev->device.initialize = overlay_initialize;
313 dev->device.dequeueBuffer = overlay_dequeueBuffer;
314 dev->device.queueBuffer = overlay_queueBuffer;
315 dev->device.getBufferAddress = overlay_getBufferAddress;
316
317 *device = &dev->device.common;
318 status = 0;
319 }
320 return status;
321 }
322