hwc.cpp revision a71a7ecd0323a16fe7728271474f8b7056c679d8
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    }
72359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall    ctx->proc = procs;
73359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall
74359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall    // don't start listening for events until we can do something with them
75359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall    init_uevent_thread(ctx);
76befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
77befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
78660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
79660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                       hwc_display_contents_1_t** displays)
80befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
81befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
82ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed    ctx->overlayInUse = false;
83ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed
84ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed    //Prepare is called after a vsync, so unlock previous buffers here.
85ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed    ctx->qbuf->unlockAllPrevious();
86ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed
87660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    for (uint32_t i = 0; i <numDisplays; i++) {
88660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        hwc_display_contents_1_t* list = displays[i];
89660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        ctx->dpys[i] = list->dpy;
90660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        //XXX: Actually handle the multiple displays
91660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        if (LIKELY(list)) {
92660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            //reset for this draw round
93660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            VideoOverlay::reset();
94660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            ExtOnly::reset();
95660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed
96660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            getLayerStats(ctx, list);
97660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            if(VideoOverlay::prepare(ctx, list)) {
98660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->overlayInUse = true;
99660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                //Nothing here
100660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            } else if(ExtOnly::prepare(ctx, list)) {
101660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->overlayInUse = true;
102660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            } else if(UIMirrorOverlay::prepare(ctx, list)) {
103660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->overlayInUse = true;
104660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            } else if(MDPComp::configure(dev, list)) {
105660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->overlayInUse = true;
106660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            } else if (0) {
107660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                //Other features
108660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->overlayInUse = true;
109660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            } else { // Else set this flag to false, otherwise video cases
110660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                // fail in non-overlay targets.
111660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->overlayInUse = false;
112660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            }
113befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
114befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
115ccf943e44f9e9d615a6019459625148830039f8dNaseer Ahmed
116befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return 0;
117befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
118befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
119660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
1201589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                             int event, int enabled)
1211589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed{
1221589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    int ret = 0;
1231589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
1241589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
1251589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                ctx->mFbDev->common.module);
126660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    //XXX: Handle dpy
1271589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    switch(event) {
1281589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        case HWC_EVENT_VSYNC:
1291589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed            if(ioctl(m->framebuffer->fd, MSMFB_OVERLAY_VSYNC_CTRL, &enabled) < 0)
1301589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                ret = -errno;
131080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed
132080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed            if(ctx->mExtDisplay->getExternalDisplay()) {
133080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed                ret = ctx->mExtDisplay->enableHDMIVsync(enabled);
134080cfcaf2e972513fc09a0207d034ef5dcc975d8Naseer Ahmed            }
1351589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed           break;
1361589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        default:
1371589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed            ret = -EINVAL;
1381589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    }
1391589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    return ret;
1401589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed}
1411589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
142660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
143660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed{
144660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    //XXX: Handle based on dpy
1451ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
1461ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
1471ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed        ctx->mFbDev->common.module);
148660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    if(blank) {
149660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        ctx->mOverlay->setState(ovutils::OV_CLOSED);
150660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        ctx->qbuf->unlockAllPrevious();
1511ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed        ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN);
1521ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed    } else {
1531ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed        ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK);
154660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    }
155660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    return 0;
156660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed}
157660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed
158660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_query(struct hwc_composer_device_1* dev,
1591589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                     int param, int* value)
1601589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed{
1611589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
1621589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
1631589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ctx->mFbDev->common.module);
1641589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
1651589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    switch (param) {
1661589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    case HWC_BACKGROUND_LAYER_SUPPORTED:
1671589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        // Not supported for now
1681589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        value[0] = 0;
1691589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        break;
1701589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    case HWC_VSYNC_PERIOD:
1711589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        value[0] = 1000000000.0 / m->fps;
1721589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ALOGI("fps: %d", value[0]);
1731589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        break;
1741589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    default:
1751589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        return -EINVAL;
1761589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    }
1771589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    return 0;
1781589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
1791589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed}
1801589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
181660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_set(hwc_composer_device_1 *dev,
182660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                   size_t numDisplays,
183660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                   hwc_display_contents_1_t** displays)
184befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
185befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int ret = 0;
186befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
187660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    for (uint32_t i = 0; i <numDisplays; i++) {
188660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        hwc_display_contents_1_t* list = displays[i];
189660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        //XXX: Actually handle the multiple displays
190660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        if (LIKELY(list)) {
191660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            VideoOverlay::draw(ctx, list);
192660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            ExtOnly::draw(ctx, list);
193660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            MDPComp::draw(ctx, list);
194660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            EGLBoolean success = eglSwapBuffers((EGLDisplay)list->dpy,
195660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                                                (EGLSurface)list->sur);
196a71a7ecd0323a16fe7728271474f8b7056c679d8Saurabh Shah            wait4fbPost(ctx);
197a71a7ecd0323a16fe7728271474f8b7056c679d8Saurabh Shah            //Can draw to HDMI only when fb_post is reached
198660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            UIMirrorOverlay::draw(ctx);
199a71a7ecd0323a16fe7728271474f8b7056c679d8Saurabh Shah            //HDMI commit and primary commit (PAN) happening in parallel
200660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            if(ctx->mExtDisplay->getExternalDisplay())
201660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->mExtDisplay->commit();
202a71a7ecd0323a16fe7728271474f8b7056c679d8Saurabh Shah            //Virtual barrier for threads to finish
203a71a7ecd0323a16fe7728271474f8b7056c679d8Saurabh Shah            wait4Pan(ctx);
204660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        } else {
205660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            ctx->mOverlay->setState(ovutils::OV_CLOSED);
2067eab0d105a7e7a83294bbf119d337b9246eb6979Saurabh Shah            ctx->qbuf->unlockAll();
207660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        }
208ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed
209660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        if(!ctx->overlayInUse)
210660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            ctx->mOverlay->setState(ovutils::OV_CLOSED);
211660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    }
212befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return ret;
213befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
214befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
215befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int hwc_device_close(struct hw_device_t *dev)
216befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
217befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!dev) {
2181589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ALOGE("%s: NULL device pointer", __FUNCTION__);
219befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -1;
220befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
221befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    closeContext((hwc_context_t*)dev);
222befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    free(dev);
223befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
224befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return 0;
225befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
226befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
227befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module, const char* name,
228befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                           struct hw_device_t** device)
229befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
230befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = -EINVAL;
231befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
232befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
233befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        struct hwc_context_t *dev;
234befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev = (hwc_context_t*)malloc(sizeof(*dev));
235befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memset(dev, 0, sizeof(*dev));
2361589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
2371589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        //Initialize hwc context
238befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        initContext(dev);
2391589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
2401589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        //Setup HWC methods
241befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.common.tag     = HARDWARE_DEVICE_TAG;
242660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        dev->device.common.version = HWC_DEVICE_API_VERSION_1_0;
243befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.common.module  = const_cast<hw_module_t*>(module);
244befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.common.close   = hwc_device_close;
245befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.prepare        = hwc_prepare;
246befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.set            = hwc_set;
247359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall        dev->device.eventControl   = hwc_eventControl;
248359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall        dev->device.blank          = hwc_blank;
2491589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        dev->device.query          = hwc_query;
250359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall        dev->device.registerProcs  = hwc_registerProcs;
251befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        *device                    = &dev->device.common;
252befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = 0;
253befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
254befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
255befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
256