hwc.cpp revision 7eab0d105a7e7a83294bbf119d337b9246eb6979
1befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*
2befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Copyright (C) 2010 The Android Open Source Project
3befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
4befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
5befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License");
6befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * you may not use this file except in compliance with the License.
7befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * You may obtain a copy of the License at
8befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
9befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *      http://www.apache.org/licenses/LICENSE-2.0
10befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
11befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Unless required by applicable law or agreed to in writing, software
12befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS,
13befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * See the License for the specific language governing permissions and
15befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * limitations under the License.
16befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
17befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
18befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <fcntl.h>
19befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <errno.h>
20befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
21befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <cutils/log.h>
22befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <cutils/atomic.h>
231589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed#include <EGL/egl.h>
24befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
251589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed#include <overlay.h>
261589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed#include <fb_priv.h>
27b3c6e058ce1dbc689f27e7d7acbf1529d37307d8Naseer Ahmed#include <mdp_version.h>
28befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include "hwc_utils.h"
291589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed#include "hwc_qbuf.h"
30ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed#include "hwc_video.h"
31ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed#include "hwc_uimirror.h"
32bd4704d4b447bd4aa59e4894d68a7162ce4f99fdNaseer Ahmed#include "hwc_copybit.h"
33080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed#include "hwc_external.h"
34c85d6b7428ded41c74a9455f580f3ee8b451bbdeNaseer Ahmed#include "hwc_mdpcomp.h"
355d0935531842ab9cf01775a77e92f204e6d40971Naseer Ahmed#include "hwc_extonly.h"
36befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
37befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedusing namespace qhwc;
38befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
39befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module,
40befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                           const char* name,
41befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                           struct hw_device_t** device);
42befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
43befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic struct hw_module_methods_t hwc_module_methods = {
44befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    open: hwc_device_open
45befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
46befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
47befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedhwc_module_t HAL_MODULE_INFO_SYM = {
48befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    common: {
49befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        tag: HARDWARE_MODULE_TAG,
50befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        version_major: 2,
51befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        version_minor: 0,
52befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        id: HWC_HARDWARE_MODULE_ID,
53befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        name: "Qualcomm Hardware Composer Module",
54befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        author: "CodeAurora Forum",
55befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        methods: &hwc_module_methods,
56befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dso: 0,
57befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        reserved: {0},
58befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
59befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
60befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
61befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*
62befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Save callback functions registered to HWC
63befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
64660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic void hwc_registerProcs(struct hwc_composer_device_1* dev,
65befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              hwc_procs_t const* procs)
66befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
67befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
68befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!ctx) {
69befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: Invalid context", __FUNCTION__);
70befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return;
71befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
72befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.reserved_proc[0] = (void*)procs;
73befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
74befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
75660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
76660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                       hwc_display_contents_1_t** displays)
77befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
78befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
79ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed    ctx->overlayInUse = false;
80ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed
81ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed    //Prepare is called after a vsync, so unlock previous buffers here.
82ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed    ctx->qbuf->unlockAllPrevious();
83ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed
84660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    for (uint32_t i = 0; i <numDisplays; i++) {
85660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        hwc_display_contents_1_t* list = displays[i];
86660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        ctx->dpys[i] = list->dpy;
87660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        //XXX: Actually handle the multiple displays
88660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        if (LIKELY(list)) {
89660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            //reset for this draw round
90660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            VideoOverlay::reset();
91660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            ExtOnly::reset();
92660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed
93660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            getLayerStats(ctx, list);
94660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            if(VideoOverlay::prepare(ctx, list)) {
95660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->overlayInUse = true;
96660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                //Nothing here
97660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            } else if(ExtOnly::prepare(ctx, list)) {
98660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->overlayInUse = true;
99660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            } else if(UIMirrorOverlay::prepare(ctx, list)) {
100660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->overlayInUse = true;
101660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            } else if(MDPComp::configure(dev, list)) {
102660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->overlayInUse = true;
103660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            } else if (0) {
104660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                //Other features
105660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->overlayInUse = true;
106660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            } else { // Else set this flag to false, otherwise video cases
107660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                // fail in non-overlay targets.
108660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->overlayInUse = false;
109660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            }
110befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
111befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
112ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
113befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return 0;
114befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
115befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
116660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
1171589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                             int event, int enabled)
1181589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed{
1191589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    int ret = 0;
1201589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
1211589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
1221589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                ctx->mFbDev->common.module);
123660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    //XXX: Handle dpy
1241589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    switch(event) {
1251589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        case HWC_EVENT_VSYNC:
1261589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed            if(ioctl(m->framebuffer->fd, MSMFB_OVERLAY_VSYNC_CTRL, &enabled) < 0)
1271589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                ret = -errno;
128080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed
129080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed            if(ctx->mExtDisplay->getExternalDisplay()) {
130080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed                ret = ctx->mExtDisplay->enableHDMIVsync(enabled);
131080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed            }
1321589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed           break;
1331589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        default:
1341589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed            ret = -EINVAL;
1351589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    }
1361589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    return ret;
1371589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed}
1381589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
139660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
140660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed{
141660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    //XXX: Handle based on dpy
1421ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
1431ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
1441ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed        ctx->mFbDev->common.module);
145660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    if(blank) {
146660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        ctx->mOverlay->setState(ovutils::OV_CLOSED);
147660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        ctx->qbuf->unlockAllPrevious();
1481ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed        ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN);
1491ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed    } else {
1501ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed        ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK);
151660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    }
152660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    return 0;
153660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed}
154660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed
155660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_query(struct hwc_composer_device_1* dev,
1561589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                     int param, int* value)
1571589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed{
1581589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
1591589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
1601589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ctx->mFbDev->common.module);
1611589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
1621589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    switch (param) {
1631589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    case HWC_BACKGROUND_LAYER_SUPPORTED:
1641589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        // Not supported for now
1651589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        value[0] = 0;
1661589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        break;
1671589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    case HWC_VSYNC_PERIOD:
1681589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        value[0] = 1000000000.0 / m->fps;
1691589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ALOGI("fps: %d", value[0]);
1701589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        break;
1711589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    default:
1721589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        return -EINVAL;
1731589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    }
1741589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    return 0;
1751589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
1761589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed}
1771589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
178660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_set(hwc_composer_device_1 *dev,
179660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                   size_t numDisplays,
180660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                   hwc_display_contents_1_t** displays)
181befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
182befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int ret = 0;
183befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
184660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    for (uint32_t i = 0; i <numDisplays; i++) {
185660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        hwc_display_contents_1_t* list = displays[i];
186660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        //XXX: Actually handle the multiple displays
187660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        if (LIKELY(list)) {
188660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            VideoOverlay::draw(ctx, list);
189660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            ExtOnly::draw(ctx, list);
190660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            MDPComp::draw(ctx, list);
191660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            EGLBoolean success = eglSwapBuffers((EGLDisplay)list->dpy,
192660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                                                (EGLSurface)list->sur);
193660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            UIMirrorOverlay::draw(ctx);
194660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            if(ctx->mExtDisplay->getExternalDisplay())
195660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->mExtDisplay->commit();
196660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        } else {
197660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            ctx->mOverlay->setState(ovutils::OV_CLOSED);
1987eab0d105a7e7a83294bbf119d337b9246eb6979Saurabh Shah            ctx->qbuf->unlockAll();
199660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        }
200ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed
201660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        if(!ctx->overlayInUse)
202660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            ctx->mOverlay->setState(ovutils::OV_CLOSED);
203660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    }
204befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return ret;
205befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
206befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
207befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int hwc_device_close(struct hw_device_t *dev)
208befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
209befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!dev) {
2101589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ALOGE("%s: NULL device pointer", __FUNCTION__);
211befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -1;
212befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
213befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    closeContext((hwc_context_t*)dev);
214befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    free(dev);
215befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
216befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return 0;
217befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
218befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
219befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module, const char* name,
220befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                           struct hw_device_t** device)
221befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
222befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = -EINVAL;
223befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
224befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
225befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        struct hwc_context_t *dev;
226befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev = (hwc_context_t*)malloc(sizeof(*dev));
227befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memset(dev, 0, sizeof(*dev));
2281589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
2291589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        //Initialize hwc context
230befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        initContext(dev);
2311589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
2321589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        //Setup HWC methods
233660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        hwc_methods_1_t *methods;
234660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        methods = (hwc_methods_1_t *) malloc(sizeof(*methods));
2351589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        memset(methods, 0, sizeof(*methods));
2361589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        methods->eventControl = hwc_eventControl;
237660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        methods->blank = hwc_blank;
2381589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
239befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.common.tag     = HARDWARE_DEVICE_TAG;
240660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        dev->device.common.version = HWC_DEVICE_API_VERSION_1_0;
241befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.common.module  = const_cast<hw_module_t*>(module);
242befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.common.close   = hwc_device_close;
243befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.prepare        = hwc_prepare;
244befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.set            = hwc_set;
245befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.registerProcs  = hwc_registerProcs;
2461589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        dev->device.query          = hwc_query;
2471589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        dev->device.methods        = methods;
248befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        *device                    = &dev->device.common;
249befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = 0;
250befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
251befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
252befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
253