hwc.cpp revision ade7461cd279f0ca3806e35a38862f2ef4fe8563
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
84ade7461cd279f0ca3806e35a38862f2ef4fe8563Saurabh Shah    for (uint32_t i = 0; i < numDisplays; i++) {
85ade7461cd279f0ca3806e35a38862f2ef4fe8563Saurabh Shah        hwc_display_contents_1_t *list = displays[i];
86660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        //XXX: Actually handle the multiple displays
87ade7461cd279f0ca3806e35a38862f2ef4fe8563Saurabh Shah        if (LIKELY(list && list->numHwLayers)) {
88ade7461cd279f0ca3806e35a38862f2ef4fe8563Saurabh Shah            ctx->dpys[i] = list->dpy;
89660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            //reset for this draw round
90660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            VideoOverlay::reset();
91660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            ExtOnly::reset();
92660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed
93ade7461cd279f0ca3806e35a38862f2ef4fe8563Saurabh Shah            if(ctx->isPoweredDown)
94ade7461cd279f0ca3806e35a38862f2ef4fe8563Saurabh Shah                ALOGW("SF called %s after a POWERDOWN", __FUNCTION__);
95ade7461cd279f0ca3806e35a38862f2ef4fe8563Saurabh Shah
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();
1511e396eddac16f39d5bd09dc9f6f8a704b468c2d3Saurabh Shah        ALOGD("HWC Calling POWERDOWN ...");
1521ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed        ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN);
1531e396eddac16f39d5bd09dc9f6f8a704b468c2d3Saurabh Shah        ctx->isPoweredDown = true;
1541ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed    } else {
1551e396eddac16f39d5bd09dc9f6f8a704b468c2d3Saurabh Shah        ALOGD("HWC Calling UNBLANK ...");
1561ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed        ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK);
1571e396eddac16f39d5bd09dc9f6f8a704b468c2d3Saurabh Shah        ctx->isPoweredDown = false;
158660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    }
159660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    return 0;
160660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed}
161660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed
162660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_query(struct hwc_composer_device_1* dev,
1631589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                     int param, int* value)
1641589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed{
1651589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
1661589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
1671589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ctx->mFbDev->common.module);
1681589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
1691589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    switch (param) {
1701589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    case HWC_BACKGROUND_LAYER_SUPPORTED:
1711589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        // Not supported for now
1721589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        value[0] = 0;
1731589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        break;
1741589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    case HWC_VSYNC_PERIOD:
17521fe85b5b8212ac43d81f5db4b2b30f71ac048e2Saurabh Shah        value[0] = m->fps;
1761589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ALOGI("fps: %d", value[0]);
1771589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        break;
1781589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    default:
1791589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        return -EINVAL;
1801589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    }
1811589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    return 0;
1821589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
1831589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed}
1841589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
185660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_set(hwc_composer_device_1 *dev,
186660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                   size_t numDisplays,
187660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                   hwc_display_contents_1_t** displays)
188befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
189befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int ret = 0;
190befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
191660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    for (uint32_t i = 0; i <numDisplays; i++) {
192660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        hwc_display_contents_1_t* list = displays[i];
193660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        //XXX: Actually handle the multiple displays
194660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        if (LIKELY(list)) {
195660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            VideoOverlay::draw(ctx, list);
196660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            ExtOnly::draw(ctx, list);
197660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            MDPComp::draw(ctx, list);
198660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            EGLBoolean success = eglSwapBuffers((EGLDisplay)list->dpy,
199660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                                                (EGLSurface)list->sur);
200a71a7ecd0323a16fe7728271474f8b7056c679d8Saurabh Shah            wait4fbPost(ctx);
201a71a7ecd0323a16fe7728271474f8b7056c679d8Saurabh Shah            //Can draw to HDMI only when fb_post is reached
202660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            UIMirrorOverlay::draw(ctx);
203a71a7ecd0323a16fe7728271474f8b7056c679d8Saurabh Shah            //HDMI commit and primary commit (PAN) happening in parallel
204660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            if(ctx->mExtDisplay->getExternalDisplay())
205660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                ctx->mExtDisplay->commit();
206a71a7ecd0323a16fe7728271474f8b7056c679d8Saurabh Shah            //Virtual barrier for threads to finish
207a71a7ecd0323a16fe7728271474f8b7056c679d8Saurabh Shah            wait4Pan(ctx);
208660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        } else {
209660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            ctx->mOverlay->setState(ovutils::OV_CLOSED);
2107eab0d105a7e7a83294bbf119d337b9246eb6979Saurabh Shah            ctx->qbuf->unlockAll();
211660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        }
212ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed
213660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        if(!ctx->overlayInUse)
214660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed            ctx->mOverlay->setState(ovutils::OV_CLOSED);
215660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    }
21693fc2181d524746e8681e9c2b75d1a12f69351f6Saurabh Shah    ctx->qbuf->unlockAllPrevious();
217befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return ret;
218befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
219befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
220befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int hwc_device_close(struct hw_device_t *dev)
221befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
222befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!dev) {
2231589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ALOGE("%s: NULL device pointer", __FUNCTION__);
224befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -1;
225befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
226befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    closeContext((hwc_context_t*)dev);
227befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    free(dev);
228befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
229befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return 0;
230befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
231befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
232befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module, const char* name,
233befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                           struct hw_device_t** device)
234befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
235befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = -EINVAL;
236befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
237befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
238befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        struct hwc_context_t *dev;
239befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev = (hwc_context_t*)malloc(sizeof(*dev));
240befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memset(dev, 0, sizeof(*dev));
2411589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
2421589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        //Initialize hwc context
243befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        initContext(dev);
2441589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
2451589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        //Setup HWC methods
246befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.common.tag     = HARDWARE_DEVICE_TAG;
247660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        dev->device.common.version = HWC_DEVICE_API_VERSION_1_0;
248befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.common.module  = const_cast<hw_module_t*>(module);
249befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.common.close   = hwc_device_close;
250befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.prepare        = hwc_prepare;
251befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev->device.set            = hwc_set;
252359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall        dev->device.eventControl   = hwc_eventControl;
253359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall        dev->device.blank          = hwc_blank;
2541589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        dev->device.query          = hwc_query;
255359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall        dev->device.registerProcs  = hwc_registerProcs;
256befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        *device                    = &dev->device.common;
257befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = 0;
258befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
259befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
260befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
261