hwc.cpp revision 6457316fc7ae8ea29d763edce3fc1ffc78dd7387
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"
30d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed#include "hwc_fbupdate.h"
3165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed#include "hwc_mdpcomp.h"
3256f610dd235b577725198e9341caae92379fdf23Saurabh Shah#include "external.h"
3329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedusing namespace qhwc;
35d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed#define VSYNC_DEBUG 0
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{
650f9c397181604f28d15c9273de42f97ae2b4c613Iliyan Malchev    ALOGI("%s", __FUNCTION__);
6629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
6729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(!ctx) {
6829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: Invalid context", __FUNCTION__);
6929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return;
7029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
713be78d9816da84e48a40232165189f9deb16808fJesse Hall    ctx->proc = procs;
723be78d9816da84e48a40232165189f9deb16808fJesse Hall
73ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed    // Now that we have the functions needed, kick off
74ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed    // the uevent & vsync threads
753be78d9816da84e48a40232165189f9deb16808fJesse Hall    init_uevent_thread(ctx);
76ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed    init_vsync_thread(ctx);
7729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
7829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
79649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah//Helper
8089f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmedstatic void reset(hwc_context_t *ctx, int numDisplays,
8189f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed                  hwc_display_contents_1_t** displays) {
823e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    memset(ctx->listStats, 0, sizeof(ctx->listStats));
831a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah    for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++){
843e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        ctx->listStats[i].yuvIndex = -1;
8589f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        hwc_display_contents_1_t *list = displays[i];
8689f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        // XXX:SurfaceFlinger no longer guarantees that this
8789f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        // value is reset on every prepare. However, for the layer
8889f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        // cache we need to reset it.
8989f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        // We can probably rethink that later on
9089f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        if (LIKELY(list && list->numHwLayers > 1)) {
9189f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed            for(uint32_t j = 0; j < list->numHwLayers; j++) {
9289f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed                if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
9389f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed                    list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
9489f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed            }
9589f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        }
966457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah
976457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        if(ctx->mFBUpdate[i])
986457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            ctx->mFBUpdate[i]->reset();
993e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
100d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    VideoOverlay::reset();
1013e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
1023e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
10365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed//clear prev layer prop flags and realloc for current frame
10465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmedstatic void reset_layer_prop(hwc_context_t* ctx, int dpy) {
10565bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    int layer_count = ctx->listStats[dpy].numAppLayers;
10665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
10765bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    if(ctx->layerProp[dpy]) {
10865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed       delete[] ctx->layerProp[dpy];
10965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed       ctx->layerProp[dpy] = NULL;
11065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    }
11165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
11265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    if(layer_count) {
11365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed       ctx->layerProp[dpy] = new LayerProp[layer_count];
11465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    }
11565bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed}
11665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
1173e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_prepare_primary(hwc_composer_device_1 *dev,
1183e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        hwc_display_contents_1_t *list) {
1193e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
1206457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    const int dpy = HWC_DISPLAY_PRIMARY;
1211a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah
1221a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
1236457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].isActive) {
1241a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah
12586623d7d5106cd568a64be4e51be7ee77f078e08Saurabh Shah        uint32_t last = list->numHwLayers - 1;
1261a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
1271a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah        if(fbLayer->handle) {
1286457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            setListStats(ctx, list, dpy);
1296457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            reset_layer_prop(ctx, dpy);
13065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            if(!MDPComp::configure(ctx, list)) {
1316457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah                VideoOverlay::prepare(ctx, list, dpy);
1326457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah                ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
13365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            }
1346457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            ctx->mLayerCache[dpy]->updateLayerCache(list);
1353e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
1363e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
1373e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
1383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
1393e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
1403e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_prepare_external(hwc_composer_device_1 *dev,
1413e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        hwc_display_contents_1_t *list) {
1423e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
1436457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    const int dpy = HWC_DISPLAY_EXTERNAL;
144c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
145ae823e773536ee9b6cf97c575463f1a9902370d9Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
1466457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].isActive &&
1476457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].connected) {
148c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
149c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        uint32_t last = list->numHwLayers - 1;
1501a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
1511a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah        if(fbLayer->handle) {
1526457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            setListStats(ctx, list, dpy);
1536457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            reset_layer_prop(ctx, dpy);
1546457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            VideoOverlay::prepare(ctx, list, dpy);
1556457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
1566457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            ctx->mLayerCache[dpy]->updateLayerCache(list);
157c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        }
1583e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
1593e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
160649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah}
161649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah
1625b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
1635b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                       hwc_display_contents_1_t** displays)
16429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
1653e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
16629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
167d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
16889f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed    reset(ctx, numDisplays, displays);
16956f610dd235b577725198e9341caae92379fdf23Saurabh Shah
170d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    ctx->mOverlay->configBegin();
17156f610dd235b577725198e9341caae92379fdf23Saurabh Shah
17265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    for (int32_t i = numDisplays - 1; i >= 0; i--) {
17365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        hwc_display_contents_1_t *list = displays[i];
17465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        switch(i) {
17565bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            case HWC_DISPLAY_PRIMARY:
17665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                ret = hwc_prepare_primary(dev, list);
17765bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                break;
17865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            case HWC_DISPLAY_EXTERNAL:
17965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                ret = hwc_prepare_external(dev, list);
18065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                break;
18165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            default:
18265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                ret = -EINVAL;
18329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
18429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
185d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
1866457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    ctx->mOverlay->configDone();
1873e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return ret;
18829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
18929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
1905b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
19172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                             int event, int enabled)
19272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed{
19372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    int ret = 0;
194ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed
19572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
19672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
19772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                ctx->mFbDev->common.module);
198eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev    pthread_mutex_lock(&ctx->vstate.lock);
19972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    switch(event) {
20072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        case HWC_EVENT_VSYNC:
2011ef881ceed7b39b4034adba23368c2006bfd074cOmprakash Dhyade            if (ctx->vstate.enable == enabled)
2021ef881ceed7b39b4034adba23368c2006bfd074cOmprakash Dhyade                break;
203eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            ctx->vstate.enable = !!enabled;
204c7faa70f4a92f020f9d5df20a4ae4bb80be7a022Naseer Ahmed            pthread_cond_signal(&ctx->vstate.cond);
205eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
206eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev                      (enabled)?"ENABLED":"DISABLED");
207eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            break;
20872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        default:
20972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed            ret = -EINVAL;
21072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    }
211eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev    pthread_mutex_unlock(&ctx->vstate.lock);
21272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    return ret;
21372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed}
21472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
2155b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
2165b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed{
217934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
218934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
219934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed        ctx->mFbDev->common.module);
220d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
2213e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
2223e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2233e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    switch(dpy) {
2243e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_PRIMARY:
2253e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            if(blank) {
226d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                ctx->mOverlay->configBegin();
227d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                ctx->mOverlay->configDone();
2283e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN);
2293e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            } else {
2303e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK);
2313e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            }
2323e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
2333e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_EXTERNAL:
2343e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            if(blank) {
2353e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                //TODO actual
2363e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            } else {
2373e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            }
2383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
2393e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        default:
2403e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            return -EINVAL;
2413e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
242abc785f17cdec8760e948f5691e435de8760f368Arun Kumar K.R    // Enable HPD here, as during bootup unblank is called
243abc785f17cdec8760e948f5691e435de8760f368Arun Kumar K.R    // when SF is completely initialized
244abc785f17cdec8760e948f5691e435de8760f368Arun Kumar K.R    ctx->mExtDisplay->setHPD(1);
2453e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
2463e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    if(ret < 0) {
2473e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        ALOGE("%s: failed. Dpy=%d, blank=%d : %s",
2483e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                __FUNCTION__, dpy, blank, strerror(errno));
2493e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        return ret;
2505b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    }
2513e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ALOGD("%s: Done Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2523e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ctx->dpyAttr[dpy].isActive = !blank;
2535b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    return 0;
2545b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed}
2555b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed
2565b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_query(struct hwc_composer_device_1* dev,
25772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                     int param, int* value)
25872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed{
25972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
26072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
26172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ctx->mFbDev->common.module);
2623e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int supported = HWC_DISPLAY_PRIMARY_BIT;
26372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
26472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    switch (param) {
26572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    case HWC_BACKGROUND_LAYER_SUPPORTED:
26672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        // Not supported for now
26772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        value[0] = 0;
26872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        break;
2693e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    case HWC_VSYNC_PERIOD: //Not used for hwc > 1.1
2702e2798c71ad66cef2bd82967058c88f85d3501a8Saurabh Shah        value[0] = m->fps;
27172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ALOGI("fps: %d", value[0]);
27272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        break;
2733e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    case HWC_DISPLAY_TYPES_SUPPORTED:
274c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        if(ctx->mMDP.hasOverlay)
275c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            supported |= HWC_DISPLAY_EXTERNAL_BIT;
2763e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        value[0] = supported;
2773e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        break;
27872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    default:
27972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        return -EINVAL;
28072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    }
28172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    return 0;
28272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
28372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed}
28472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
2853e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
286eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    int ret = 0;
2876457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    const int dpy = HWC_DISPLAY_PRIMARY;
288eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah
289ae823e773536ee9b6cf97c575463f1a9902370d9Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
2906457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].isActive) {
291c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        uint32_t last = list->numHwLayers - 1;
292c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
293c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
2946457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        hwc_sync(ctx, list, dpy);
2956457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        if (!VideoOverlay::draw(ctx, list, dpy)) {
296eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
297eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ret = -1;
298eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
29965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        if (!MDPComp::draw(ctx, list)) {
30065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            ALOGE("%s: MDPComp::draw fail!", __FUNCTION__);
30165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            ret = -1;
30265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        }
30365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
3043e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        //TODO We dont check for SKIP flag on this layer because we need PAN
3053e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        //always. Last layer is always FB
30665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
30765bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
30865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            if(!(fbLayer->flags & HWC_SKIP_LAYER)) {
3096457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah                if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
31065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                    ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
31165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                    ret = -1;
31265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                }
31365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            }
314eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) {
315eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah                ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__);
316eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah                return -1;
317eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            }
3183e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
3193e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
320eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    return ret;
3213e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
3223e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
3233e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_set_external(hwc_context_t *ctx,
3243e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        hwc_display_contents_1_t* list) {
325eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    int ret = 0;
3266457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    const int dpy = HWC_DISPLAY_EXTERNAL;
3276457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah
328f83d4480f2c7e37374c4516750aae79c6b12eb79Kinjal Bhavsar    Locker::Autolock _l(ctx->mExtSetLock);
329c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
330ae823e773536ee9b6cf97c575463f1a9902370d9Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
3316457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].isActive &&
3326457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].connected) {
3333e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t last = list->numHwLayers - 1;
334c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
335c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
3366457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        hwc_sync(ctx, list, dpy);
337c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
3386457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        if (!VideoOverlay::draw(ctx, list, dpy)) {
339eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
340eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ret = -1;
341eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
342c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
343c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
344150806ae0ed82d1d26fa144a6950031570b06bfbSaurabh Shah        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
345150806ae0ed82d1d26fa144a6950031570b06bfbSaurabh Shah                !(fbLayer->flags & HWC_SKIP_LAYER) && hnd) {
3466457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
347d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
348eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah                ret = -1;
349eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            }
350eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
351eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        if (!ctx->mExtDisplay->post()) {
352eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ALOGE("%s: ctx->mExtDisplay->post fail!", __FUNCTION__);
353eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            return -1;
3543e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
3553e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
356eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    return ret;
3573e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
3583e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
3595b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_set(hwc_composer_device_1 *dev,
3605b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                   size_t numDisplays,
3615b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                   hwc_display_contents_1_t** displays)
36229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
36329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int ret = 0;
36429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
36532ff225e6d77baeb38925faba4b6b8457fab6b7bNaseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
366c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
3673e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    for (uint32_t i = 0; i < numDisplays; i++) {
3685b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed        hwc_display_contents_1_t* list = displays[i];
3693e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        switch(i) {
3703e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            case HWC_DISPLAY_PRIMARY:
3713e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = hwc_set_primary(ctx, list);
372c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                break;
3733e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            case HWC_DISPLAY_EXTERNAL:
3743e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = hwc_set_external(ctx, list);
375c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                break;
3763e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            default:
3773e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = -EINVAL;
3785b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed        }
3793e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
3803e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return ret;
3813e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
382f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed
3833e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahint hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
3843e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t* configs, size_t* numConfigs) {
3853e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
386c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
3873e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //in 1.1 there is no way to choose a config, report as config id # 0
3883e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //This config is passed to getDisplayAttributes. Ignore for now.
3893e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    switch(disp) {
3903e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_PRIMARY:
391c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            if(*numConfigs > 0) {
392c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                configs[0] = 0;
393c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                *numConfigs = 1;
394c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            }
395c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ret = 0; //NO_ERROR
3963e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
3973e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_EXTERNAL:
398c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ret = -1; //Not connected
399c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
400c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                ret = 0; //NO_ERROR
401c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                if(*numConfigs > 0) {
402c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    configs[0] = 0;
403c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    *numConfigs = 1;
404c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                }
405c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            }
4063e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4075b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    }
40829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return ret;
40929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
41029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4113e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahint hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
4123e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t config, const uint32_t* attributes, int32_t* values) {
4133e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4143e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
415c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    //If hotpluggable displays are inactive return error
416c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
417c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        return -1;
418c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    }
419c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
4203e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //From HWComposer
4213e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    static const uint32_t DISPLAY_ATTRIBUTES[] = {
4223e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_VSYNC_PERIOD,
4233e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_WIDTH,
4243e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_HEIGHT,
4253e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_DPI_X,
4263e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_DPI_Y,
4273e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_NO_ATTRIBUTE,
4283e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    };
4293e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4303e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
4313e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            sizeof(DISPLAY_ATTRIBUTES)[0]);
4323e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4333e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
4343e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        switch (attributes[i]) {
4353e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_VSYNC_PERIOD:
4363e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].vsync_period;
4373e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_WIDTH:
4393e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].xres;
440c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
441c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    ctx->dpyAttr[disp].xres);
4423e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4433e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_HEIGHT:
4443e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].yres;
445c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
446c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    ctx->dpyAttr[disp].yres);
4473e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4483e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_DPI_X:
4497b80d9c8cb345f7020093e0afb691bf3a72deec6Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
4503e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4513e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_DPI_Y:
4527b80d9c8cb345f7020093e0afb691bf3a72deec6Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
4533e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4543e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        default:
4553e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            ALOGE("Unknown display attribute %d",
4563e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                    attributes[i]);
4573e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            return -EINVAL;
4583e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
4593e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
4603e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
4613e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
4623e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4633b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmedvoid hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
4643b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed{
4653b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
4663b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    android::String8 buf("");
4673b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    dumpsys_log(buf, "Qualcomm HWC state:\n");
4683b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    dumpsys_log(buf, "  MDPVersion=%d\n", ctx->mMDP.version);
4693b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    dumpsys_log(buf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
4703b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    MDPComp::dump(buf);
4713b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    //XXX: Call Other dump functions
4723b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    strlcpy(buff, buf.string(), buff_len);
4733b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed}
4743b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed
47529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_close(struct hw_device_t *dev)
47629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
47729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(!dev) {
47872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ALOGE("%s: NULL device pointer", __FUNCTION__);
47929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -1;
48029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
48129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    closeContext((hwc_context_t*)dev);
48229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    free(dev);
48329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
48429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
48529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
48629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
48729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module, const char* name,
48829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           struct hw_device_t** device)
48929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
49029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = -EINVAL;
49129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
49229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
49329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct hwc_context_t *dev;
49429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dev = (hwc_context_t*)malloc(sizeof(*dev));
49529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        memset(dev, 0, sizeof(*dev));
49672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
49772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        //Initialize hwc context
49829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        initContext(dev);
49972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
50072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        //Setup HWC methods
5013e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
5023e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_1;
5033e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.module       = const_cast<hw_module_t*>(module);
5043e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.close        = hwc_device_close;
5053e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.prepare             = hwc_prepare;
5063e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.set                 = hwc_set;
5073e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.eventControl        = hwc_eventControl;
5083e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.blank               = hwc_blank;
5093e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.query               = hwc_query;
5103e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.registerProcs       = hwc_registerProcs;
5113b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed        dev->device.dump                = hwc_dump;
5123e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
5133e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
5143e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        *device = &dev->device.common;
51529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = 0;
51629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
51729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
51829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
519