hwc.cpp revision 1ef881ceed7b39b4034adba23368c2006bfd074c
129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Copyright (C) 2010 The Android Open Source Project
356f610dd235b577725198e9341caae92379fdf23Saurabh Shah * Copyright (C) 2012, The Linux Foundation. All rights reserved.
429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License");
629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * you may not use this file except in compliance with the License.
729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * You may obtain a copy of the License at
829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *      http://www.apache.org/licenses/LICENSE-2.0
1029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
1129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Unless required by applicable law or agreed to in writing, software
1229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS,
1329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * See the License for the specific language governing permissions and
1529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * limitations under the License.
1629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
1729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
1829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <fcntl.h>
1929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <errno.h>
2029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <cutils/log.h>
2229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <cutils/atomic.h>
2372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed#include <EGL/egl.h>
2429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed#include <overlay.h>
2672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed#include <fb_priv.h>
2796c4c95d48dc075196c601b30a8798a262df9720Naseer Ahmed#include <mdp_version.h>
2829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include "hwc_utils.h"
29f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed#include "hwc_video.h"
3086623d7d5106cd568a64be4e51be7ee77f078e08Saurabh Shah#include "hwc_uimirror.h"
3156f610dd235b577725198e9341caae92379fdf23Saurabh Shah#include "external.h"
327c958d445fe88a82eedbd1b887cd1e474a7526b1Naseer Ahmed#include "hwc_mdpcomp.h"
3329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
34ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed#define VSYNC_DEBUG 0
3529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedusing namespace qhwc;
3629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module,
3829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           const char* name,
3929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           struct hw_device_t** device);
4029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic struct hw_module_methods_t hwc_module_methods = {
4229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    open: hwc_device_open
4329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
4429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedhwc_module_t HAL_MODULE_INFO_SYM = {
4629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    common: {
4729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        tag: HARDWARE_MODULE_TAG,
4829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        version_major: 2,
4929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        version_minor: 0,
5029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        id: HWC_HARDWARE_MODULE_ID,
5129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        name: "Qualcomm Hardware Composer Module",
5229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        author: "CodeAurora Forum",
5329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        methods: &hwc_module_methods,
5429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dso: 0,
5529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        reserved: {0},
5629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
5729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
5829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
6029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Save callback functions registered to HWC
6129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
625b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic void hwc_registerProcs(struct hwc_composer_device_1* dev,
6329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              hwc_procs_t const* procs)
6429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
6529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
6629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(!ctx) {
6729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: Invalid context", __FUNCTION__);
6829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return;
6929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
703be78d9816da84e48a40232165189f9deb16808fJesse Hall    ctx->proc = procs;
713be78d9816da84e48a40232165189f9deb16808fJesse Hall
72ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed    // Now that we have the functions needed, kick off
73ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed    // the uevent & vsync threads
743be78d9816da84e48a40232165189f9deb16808fJesse Hall    init_uevent_thread(ctx);
75ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed    init_vsync_thread(ctx);
7629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
7729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
78649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah//Helper
793e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic void reset(hwc_context_t *ctx, int numDisplays) {
803e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    memset(ctx->listStats, 0, sizeof(ctx->listStats));
813e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    for(int i = 0; i < numDisplays; i++){
823e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        ctx->listStats[i].yuvIndex = -1;
833e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
843e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
853e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
863e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_prepare_primary(hwc_composer_device_1 *dev,
873e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        hwc_display_contents_1_t *list) {
883e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
89c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = false;
903e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    if (LIKELY(list && list->numHwLayers)) {
9186623d7d5106cd568a64be4e51be7ee77f078e08Saurabh Shah        uint32_t last = list->numHwLayers - 1;
9286623d7d5106cd568a64be4e51be7ee77f078e08Saurabh Shah        hwc_layer_1_t *fblayer = &list->hwLayers[last];
933e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        setListStats(ctx, list, HWC_DISPLAY_PRIMARY);
943e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        if(VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY)) {
95c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = true;
963e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        } else if(MDPComp::configure(ctx, list)) {
97c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = true;
983e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        } else {
99c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = false;
1003e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
1013e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
1023e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
1033e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
1043e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
1053e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_prepare_external(hwc_composer_device_1 *dev,
1063e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        hwc_display_contents_1_t *list) {
1073e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
1083e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
109c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    ctx->overlayInUse[HWC_DISPLAY_EXTERNAL] = false;
110c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
111c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    if (LIKELY(list && list->numHwLayers) &&
112c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive &&
113c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
114c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
115c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        setListStats(ctx, list, HWC_DISPLAY_EXTERNAL);
116c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
117c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        uint32_t last = list->numHwLayers - 1;
118c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_layer_1_t *fblayer = &list->hwLayers[last];
119c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        if(UIMirrorOverlay::prepare(ctx, fblayer)) {
120c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ctx->overlayInUse[HWC_DISPLAY_EXTERNAL] = true;
121c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        }
122c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
123c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        if(VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL)) {
124c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ctx->overlayInUse[HWC_DISPLAY_EXTERNAL] = true;
125c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        } else {
126c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->setState(ovutils::OV_UI_MIRROR);
127c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        }
1283e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
1293e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
130649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah}
131649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah
1325b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
1335b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                       hwc_display_contents_1_t** displays)
13429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
1353e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
13629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
137f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed
1383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    reset(ctx, numDisplays);
13956f610dd235b577725198e9341caae92379fdf23Saurabh Shah
14056f610dd235b577725198e9341caae92379fdf23Saurabh Shah    //If securing of h/w in progress skip comp using overlay.
14156f610dd235b577725198e9341caae92379fdf23Saurabh Shah    if(ctx->mSecuring == true) return 0;
14256f610dd235b577725198e9341caae92379fdf23Saurabh Shah
1439171ec698c218df6eec5c91fe438f8b5ae4ff79fSaurabh Shah    for (uint32_t i = 0; i < numDisplays; i++) {
1449171ec698c218df6eec5c91fe438f8b5ae4ff79fSaurabh Shah        hwc_display_contents_1_t *list = displays[i];
1456282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed        if(list && list->numHwLayers) {
1466282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed            uint32_t last = list->numHwLayers - 1;
1476282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed            if(list->hwLayers[last].handle != NULL) {
1486282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed                switch(i) {
1496282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed                case HWC_DISPLAY_PRIMARY:
1506282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed                    ret = hwc_prepare_primary(dev, list);
1516282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed                    break;
1526282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed                case HWC_DISPLAY_EXTERNAL:
1536282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed                    ret = hwc_prepare_external(dev, list);
1546282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed                    break;
1556282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed                default:
1566282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed                    ret = -EINVAL;
1576282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed                }
1586282c956456d0d6ca74fe009f196426637d4d4eeNaseer Ahmed            }
15929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
16029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
1613e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return ret;
16229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
16329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
1645b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
16572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                             int event, int enabled)
16672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed{
16772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    int ret = 0;
168ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed    static int prev_value;
169ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed
17072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
17172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
17272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                ctx->mFbDev->common.module);
17372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    switch(event) {
17472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        case HWC_EVENT_VSYNC:
1751ef881ceed7b39b4034adba23368c2006bfd074cOmprakash Dhyade            if (ctx->vstate.enable == enabled)
1761ef881ceed7b39b4034adba23368c2006bfd074cOmprakash Dhyade                break;
1773e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            if(ioctl(ctx->dpyAttr[dpy].fd, MSMFB_OVERLAY_VSYNC_CTRL,
178ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed                     &enabled) < 0) {
1793e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ALOGE("%s: vsync control failed. Dpy=%d, enabled=%d : %s",
180ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed                      __FUNCTION__, dpy, enabled, strerror(errno));
181ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed
18272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                ret = -errno;
183f8ec162999478a3f96dd945831f7c2913a4d3cffNaseer Ahmed            }
184ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed            /* vsync state change logic */
185ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed            if (enabled == 1) {
186ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed                //unblock vsync thread
187ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed                pthread_mutex_lock(&ctx->vstate.lock);
188ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed                ctx->vstate.enable = true;
189ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed                pthread_cond_signal(&ctx->vstate.cond);
190ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed                pthread_mutex_unlock(&ctx->vstate.lock);
191ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed            } else if (enabled == 0 && ctx->vstate.enable) {
192ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed                //vsync thread will block
193ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed                pthread_mutex_lock(&ctx->vstate.lock);
194ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed                ctx->vstate.enable = false;
195ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed                pthread_mutex_unlock(&ctx->vstate.lock);
196ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed            }
197ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed from %s to %s",
198ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed              (prev_value)?"ENABLED":"DISABLED", (enabled)?"ENABLED":"DISABLED");
199ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed            prev_value = enabled;
200ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed            /* vsync state change logic - end*/
201ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed           break;
20272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        default:
20372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed            ret = -EINVAL;
20472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    }
20572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    return ret;
20672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed}
20772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
2085b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
2095b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed{
210934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
211934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
212934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed        ctx->mFbDev->common.module);
2133e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
2143e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2153e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    switch(dpy) {
2163e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_PRIMARY:
2173e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            if(blank) {
21832ff225e6d77baeb38925faba4b6b8457fab6b7bNaseer Ahmed                Locker::Autolock _l(ctx->mBlankLock);
219c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                ctx->mOverlay[dpy]->setState(ovutils::OV_CLOSED);
2203e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN);
2213e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            } else {
2223e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK);
2233e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            }
2243e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
2253e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_EXTERNAL:
2263e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            if(blank) {
2273e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                //TODO actual
2283e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            } else {
2293e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            }
2303e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
2313e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        default:
2323e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            return -EINVAL;
2333e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
2343e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
2353e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    if(ret < 0) {
2363e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        ALOGE("%s: failed. Dpy=%d, blank=%d : %s",
2373e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                __FUNCTION__, dpy, blank, strerror(errno));
2383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        return ret;
2395b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    }
2403e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ALOGD("%s: Done Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2413e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ctx->dpyAttr[dpy].isActive = !blank;
2425b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    return 0;
2435b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed}
2445b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed
2455b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_query(struct hwc_composer_device_1* dev,
24672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                     int param, int* value)
24772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed{
24872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
24972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
25072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ctx->mFbDev->common.module);
2513e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int supported = HWC_DISPLAY_PRIMARY_BIT;
25272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
25372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    switch (param) {
25472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    case HWC_BACKGROUND_LAYER_SUPPORTED:
25572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        // Not supported for now
25672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        value[0] = 0;
25772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        break;
2583e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    case HWC_VSYNC_PERIOD: //Not used for hwc > 1.1
2592e2798c71ad66cef2bd82967058c88f85d3501a8Saurabh Shah        value[0] = m->fps;
26072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ALOGI("fps: %d", value[0]);
26172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        break;
2623e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    case HWC_DISPLAY_TYPES_SUPPORTED:
263c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        if(ctx->mMDP.hasOverlay)
264c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            supported |= HWC_DISPLAY_EXTERNAL_BIT;
2653e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        value[0] = supported;
2663e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        break;
26772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    default:
26872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        return -EINVAL;
26972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    }
27072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    return 0;
27172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
27272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed}
27372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
2743e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
275c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    if(!ctx->overlayInUse[HWC_DISPLAY_PRIMARY])
276c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        ctx->mOverlay[HWC_DISPLAY_PRIMARY]->setState(ovutils::OV_CLOSED);
277c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
2783e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    if (LIKELY(list && list->numHwLayers)) {
279c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        uint32_t last = list->numHwLayers - 1;
280c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
281c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
2828c8bfd2f827946ad88ea181d7f952d41ca4938feSaurabh Shah        hwc_sync(ctx, list, HWC_DISPLAY_PRIMARY);
2838c8bfd2f827946ad88ea181d7f952d41ca4938feSaurabh Shah
2843e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        VideoOverlay::draw(ctx, list, HWC_DISPLAY_PRIMARY);
2853e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        MDPComp::draw(ctx, list);
286c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
2873e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        //TODO We dont check for SKIP flag on this layer because we need PAN
2883e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        //always. Last layer is always FB
2893e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        if(list->hwLayers[last].compositionType == HWC_FRAMEBUFFER_TARGET) {
290c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle);
2913e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
2923e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
2933e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
2943e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
2953e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
2963e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_set_external(hwc_context_t *ctx,
2973e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        hwc_display_contents_1_t* list) {
298c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
299c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    if(!ctx->overlayInUse[HWC_DISPLAY_EXTERNAL])
300c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->setState(ovutils::OV_CLOSED);
301c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
302c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    if (LIKELY(list && list->numHwLayers) &&
303c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive &&
304c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
3053e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t last = list->numHwLayers - 1;
306c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
307c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
308c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_sync(ctx, list, HWC_DISPLAY_EXTERNAL);
309c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
310c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        VideoOverlay::draw(ctx, list, HWC_DISPLAY_EXTERNAL);
311c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
312c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
313c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
314c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            UIMirrorOverlay::draw(ctx, fbLayer);
315c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ctx->mExtDisplay->post();
3163e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
3173e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
3183e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
3193e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
3203e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
321c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shahstatic bool isGpuUsed(hwc_context_t *ctx,
322c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        size_t numDisplays,
323c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_display_contents_1_t** displays)
324c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah{
325c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    bool isUsed = false;
326c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    for (uint32_t i = 0; i < numDisplays; i++) {
327c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_display_contents_1_t* list = displays[i];
328c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        if (list && list->numHwLayers) {
329c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            uint32_t last = list->numHwLayers - 1;
330c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            hwc_layer_1_t *fbLayer = &list->hwLayers[last];
331c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            if(!(fbLayer->flags & HWC_SKIP_LAYER)) {
332c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                isUsed = true;
333c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                break;
334c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            }
335c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
336c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        }
337c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    }
338c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    return isUsed;
339c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah}
340c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
3415b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_set(hwc_composer_device_1 *dev,
3425b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                   size_t numDisplays,
3435b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                   hwc_display_contents_1_t** displays)
34429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
34529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int ret = 0;
34629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
34732ff225e6d77baeb38925faba4b6b8457fab6b7bNaseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
348c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
349c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    if(isGpuUsed(ctx, numDisplays, displays)) {
350c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        //Call glFinish, only if gpu is used
351c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        ctx->mFbDev->compositionComplete(ctx->mFbDev);
352c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    }
353aee5e6eccae9b5d51a836a1d05accccf927e5597Naseer Ahmed
3543e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    for (uint32_t i = 0; i < numDisplays; i++) {
3555b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed        hwc_display_contents_1_t* list = displays[i];
3563e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        switch(i) {
3573e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            case HWC_DISPLAY_PRIMARY:
3583e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = hwc_set_primary(ctx, list);
359c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                break;
3603e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            case HWC_DISPLAY_EXTERNAL:
3613e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = hwc_set_external(ctx, list);
362c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                break;
3633e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            default:
3643e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = -EINVAL;
3655b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed        }
3663e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
3673e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return ret;
3683e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
369f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed
3703e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahint hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
3713e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t* configs, size_t* numConfigs) {
3723e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
373c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
3743e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //in 1.1 there is no way to choose a config, report as config id # 0
3753e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //This config is passed to getDisplayAttributes. Ignore for now.
3763e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    switch(disp) {
3773e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_PRIMARY:
378c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            if(*numConfigs > 0) {
379c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                configs[0] = 0;
380c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                *numConfigs = 1;
381c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            }
382c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ret = 0; //NO_ERROR
3833e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
3843e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_EXTERNAL:
385c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ret = -1; //Not connected
386c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
387c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                ret = 0; //NO_ERROR
388c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                if(*numConfigs > 0) {
389c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    configs[0] = 0;
390c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    *numConfigs = 1;
391c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                }
392c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            }
3933e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
3945b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    }
39529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return ret;
39629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
39729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3983e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahint hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
3993e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t config, const uint32_t* attributes, int32_t* values) {
4003e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4013e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
402c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    //If hotpluggable displays are inactive return error
403c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
404c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        return -1;
405c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    }
406c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
4073e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //From HWComposer
4083e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    static const uint32_t DISPLAY_ATTRIBUTES[] = {
4093e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_VSYNC_PERIOD,
4103e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_WIDTH,
4113e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_HEIGHT,
4123e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_DPI_X,
4133e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_DPI_Y,
4143e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_NO_ATTRIBUTE,
4153e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    };
4163e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4173e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
4183e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            sizeof(DISPLAY_ATTRIBUTES)[0]);
4193e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4203e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
4213e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        switch (attributes[i]) {
4223e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_VSYNC_PERIOD:
4233e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].vsync_period;
4243e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4253e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_WIDTH:
4263e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].xres;
427c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
428c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    ctx->dpyAttr[disp].xres);
4293e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4303e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_HEIGHT:
4313e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].yres;
432c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
433c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    ctx->dpyAttr[disp].yres);
4343e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4353e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_DPI_X:
4367b80d9c8cb345f7020093e0afb691bf3a72deec6Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
4373e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_DPI_Y:
4397b80d9c8cb345f7020093e0afb691bf3a72deec6Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
4403e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4413e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        default:
4423e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            ALOGE("Unknown display attribute %d",
4433e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                    attributes[i]);
4443e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            return -EINVAL;
4453e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
4463e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
4473e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
4483e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
4493e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
45029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_close(struct hw_device_t *dev)
45129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
45229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(!dev) {
45372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ALOGE("%s: NULL device pointer", __FUNCTION__);
45429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -1;
45529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
45629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    closeContext((hwc_context_t*)dev);
45729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    free(dev);
45829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
45929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
46029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
46129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
46229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module, const char* name,
46329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           struct hw_device_t** device)
46429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
46529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = -EINVAL;
46629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
46729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
46829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct hwc_context_t *dev;
46929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dev = (hwc_context_t*)malloc(sizeof(*dev));
47029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        memset(dev, 0, sizeof(*dev));
47172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
47272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        //Initialize hwc context
47329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        initContext(dev);
47472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
47572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        //Setup HWC methods
4763e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
4773e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_1;
4783e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.module       = const_cast<hw_module_t*>(module);
4793e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.close        = hwc_device_close;
4803e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.prepare             = hwc_prepare;
4813e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.set                 = hwc_set;
4823e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.eventControl        = hwc_eventControl;
4833e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.blank               = hwc_blank;
4843e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.query               = hwc_query;
4853e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.registerProcs       = hwc_registerProcs;
4863e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.dump                = NULL;
4873e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
4883e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
4893e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        *device = &dev->device.common;
49029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = 0;
49129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
49229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
49329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
494