hwc.cpp revision 5d0935531842ab9cf01775a77e92f204e6d40971
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include <fcntl.h>
19#include <errno.h>
20
21#include <cutils/log.h>
22#include <cutils/atomic.h>
23#include <EGL/egl.h>
24
25#include <overlay.h>
26#include <fb_priv.h>
27#include <mdp_version.h>
28#include "hwc_utils.h"
29#include "hwc_qbuf.h"
30#include "hwc_video.h"
31#include "hwc_uimirror.h"
32#include "hwc_copybit.h"
33#include "hwc_external.h"
34#include "hwc_mdpcomp.h"
35#include "hwc_extonly.h"
36
37using namespace qhwc;
38
39static int hwc_device_open(const struct hw_module_t* module,
40                           const char* name,
41                           struct hw_device_t** device);
42
43static struct hw_module_methods_t hwc_module_methods = {
44    open: hwc_device_open
45};
46
47hwc_module_t HAL_MODULE_INFO_SYM = {
48    common: {
49        tag: HARDWARE_MODULE_TAG,
50        version_major: 2,
51        version_minor: 0,
52        id: HWC_HARDWARE_MODULE_ID,
53        name: "Qualcomm Hardware Composer Module",
54        author: "CodeAurora Forum",
55        methods: &hwc_module_methods,
56        dso: 0,
57        reserved: {0},
58    }
59};
60
61/*
62 * Save callback functions registered to HWC
63 */
64static void hwc_registerProcs(struct hwc_composer_device* dev,
65                              hwc_procs_t const* procs)
66{
67    hwc_context_t* ctx = (hwc_context_t*)(dev);
68    if(!ctx) {
69        ALOGE("%s: Invalid context", __FUNCTION__);
70        return;
71    }
72    ctx->device.reserved_proc[0] = (void*)procs;
73}
74
75static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
76{
77    hwc_context_t* ctx = (hwc_context_t*)(dev);
78    ctx->overlayInUse = false;
79
80    //Prepare is called after a vsync, so unlock previous buffers here.
81    ctx->qbuf->unlockAllPrevious();
82    return 0;
83
84    if (LIKELY(list)) {
85        //reset for this draw round
86        VideoOverlay::reset();
87        ExtOnly::reset();
88
89        getLayerStats(ctx, list);
90        if(VideoOverlay::prepare(ctx, list)) {
91            ctx->overlayInUse = true;
92            //Nothing here
93        } else if(ExtOnly::prepare(ctx, list)) {
94            ctx->overlayInUse = true;
95        } else if(UIMirrorOverlay::prepare(ctx, list)) {
96            ctx->overlayInUse = true;
97        } else if(MDPComp::configure(dev, list)) {
98            ctx->overlayInUse = true;
99        } else if (0) {
100            //Other features
101            ctx->overlayInUse = true;
102        } else { // Else set this flag to false, otherwise video cases
103                 // fail in non-overlay targets.
104            ctx->overlayInUse = false;
105        }
106        CopyBit::prepare(ctx, list);
107    }
108
109    return 0;
110}
111
112static int hwc_eventControl(struct hwc_composer_device* dev,
113                             int event, int enabled)
114{
115    int ret = 0;
116    hwc_context_t* ctx = (hwc_context_t*)(dev);
117    private_module_t* m = reinterpret_cast<private_module_t*>(
118                ctx->mFbDev->common.module);
119    switch(event) {
120        case HWC_EVENT_VSYNC:
121            if(ioctl(m->framebuffer->fd, MSMFB_OVERLAY_VSYNC_CTRL, &enabled) < 0)
122                ret = -errno;
123
124            if(ctx->mExtDisplay->getExternalDisplay()) {
125                ret = ctx->mExtDisplay->enableHDMIVsync(enabled);
126            }
127           break;
128        default:
129            ret = -EINVAL;
130    }
131    return ret;
132}
133
134static int hwc_query(struct hwc_composer_device* dev,
135                     int param, int* value)
136{
137    hwc_context_t* ctx = (hwc_context_t*)(dev);
138    private_module_t* m = reinterpret_cast<private_module_t*>(
139        ctx->mFbDev->common.module);
140
141    switch (param) {
142    case HWC_BACKGROUND_LAYER_SUPPORTED:
143        // Not supported for now
144        value[0] = 0;
145        break;
146    case HWC_VSYNC_PERIOD:
147        value[0] = 1000000000.0 / m->fps;
148        ALOGI("fps: %d", value[0]);
149        break;
150    default:
151        return -EINVAL;
152    }
153    return 0;
154
155}
156
157static int hwc_set(hwc_composer_device_t *dev,
158                   hwc_display_t dpy,
159                   hwc_surface_t sur,
160                   hwc_layer_list_t* list)
161{
162    int ret = 0;
163    hwc_context_t* ctx = (hwc_context_t*)(dev);
164    if (LIKELY(list)) {
165        VideoOverlay::draw(ctx, list);
166        ExtOnly::draw(ctx, list);
167        CopyBit::draw(ctx, list, (EGLDisplay)dpy, (EGLSurface)sur);
168        MDPComp::draw(ctx, list);
169        EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur);
170        UIMirrorOverlay::draw(ctx);
171        if(ctx->mExtDisplay->getExternalDisplay())
172           ctx->mExtDisplay->commit();
173    } else {
174        ctx->mOverlay->setState(ovutils::OV_CLOSED);
175        ctx->qbuf->unlockAllPrevious();
176    }
177
178    if(!ctx->overlayInUse)
179        ctx->mOverlay->setState(ovutils::OV_CLOSED);
180
181    return ret;
182}
183
184static int hwc_device_close(struct hw_device_t *dev)
185{
186    if(!dev) {
187        ALOGE("%s: NULL device pointer", __FUNCTION__);
188        return -1;
189    }
190    closeContext((hwc_context_t*)dev);
191    free(dev);
192
193    return 0;
194}
195
196static int hwc_device_open(const struct hw_module_t* module, const char* name,
197                           struct hw_device_t** device)
198{
199    int status = -EINVAL;
200
201    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
202        struct hwc_context_t *dev;
203        dev = (hwc_context_t*)malloc(sizeof(*dev));
204        memset(dev, 0, sizeof(*dev));
205
206        //Initialize hwc context
207        initContext(dev);
208
209        //Setup HWC methods
210        hwc_methods_t *methods;
211        methods = (hwc_methods_t *)malloc(sizeof(*methods));
212        memset(methods, 0, sizeof(*methods));
213        methods->eventControl = hwc_eventControl;
214
215        dev->device.common.tag     = HARDWARE_DEVICE_TAG;
216        dev->device.common.version = HWC_DEVICE_API_VERSION_0_3;
217        dev->device.common.module  = const_cast<hw_module_t*>(module);
218        dev->device.common.close   = hwc_device_close;
219        dev->device.prepare        = hwc_prepare;
220        dev->device.set            = hwc_set;
221        dev->device.registerProcs  = hwc_registerProcs;
222        dev->device.query          = hwc_query;
223        dev->device.methods        = methods;
224        *device                    = &dev->device.common;
225        status = 0;
226    }
227    return status;
228}
229