• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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