OSDN Git Service

auto import from //depot/cupcake/@135843
[android-x86/hardware-libhardware.git] / modules / overlay / overlay.cpp
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     
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:
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }