hwc.cpp revision abc785f17cdec8760e948f5691e435de8760f368
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        }
963e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
97d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    VideoOverlay::reset();
98d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    FBUpdate::reset();
993e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
1003e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
10165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed//clear prev layer prop flags and realloc for current frame
10265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmedstatic void reset_layer_prop(hwc_context_t* ctx, int dpy) {
10365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    int layer_count = ctx->listStats[dpy].numAppLayers;
10465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
10565bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    if(ctx->layerProp[dpy]) {
10665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed       delete[] ctx->layerProp[dpy];
10765bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed       ctx->layerProp[dpy] = NULL;
10865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    }
10965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
11065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    if(layer_count) {
11165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed       ctx->layerProp[dpy] = new LayerProp[layer_count];
11265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    }
11365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed}
11465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
1153e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_prepare_primary(hwc_composer_device_1 *dev,
1163e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        hwc_display_contents_1_t *list) {
1173e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
1181a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah
1191a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
1201a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah        ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
1211a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah
12286623d7d5106cd568a64be4e51be7ee77f078e08Saurabh Shah        uint32_t last = list->numHwLayers - 1;
1231a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
1241a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah        if(fbLayer->handle) {
1251a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah            setListStats(ctx, list, HWC_DISPLAY_PRIMARY);
12665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            reset_layer_prop(ctx, HWC_DISPLAY_PRIMARY);
12765bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            if(!MDPComp::configure(ctx, list)) {
12865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY);
12965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_PRIMARY);
13065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            }
1311d21f7344157c4d0b1730faede5cf19e7253939fNaseer Ahmed            ctx->mLayerCache[HWC_DISPLAY_PRIMARY]->updateLayerCache(list);
1323e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
1333e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
1343e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
1353e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
1363e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
1373e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_prepare_external(hwc_composer_device_1 *dev,
1383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        hwc_display_contents_1_t *list) {
1393e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
140c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
141ae823e773536ee9b6cf97c575463f1a9902370d9Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
142c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive &&
143c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
144c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
145c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        uint32_t last = list->numHwLayers - 1;
1461a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
1471a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah        if(fbLayer->handle) {
14865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            setListStats(ctx, list, HWC_DISPLAY_EXTERNAL);
14965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            reset_layer_prop(ctx, HWC_DISPLAY_EXTERNAL);
15065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
151d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed            VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL);
15265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_EXTERNAL);
15333ecf33ed4881d0b76ceffb8a6f34dc8fa775ed2Naseer Ahmed            ctx->mLayerCache[HWC_DISPLAY_EXTERNAL]->updateLayerCache(list);
154c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        }
1553e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
1563e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
157649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah}
158649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah
1595b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
1605b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                       hwc_display_contents_1_t** displays)
16129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
1623e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
16329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
164d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
16589f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed    reset(ctx, numDisplays, displays);
16656f610dd235b577725198e9341caae92379fdf23Saurabh Shah
167d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    ctx->mOverlay->configBegin();
16856f610dd235b577725198e9341caae92379fdf23Saurabh Shah
16965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    for (int32_t i = numDisplays - 1; i >= 0; i--) {
17065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        hwc_display_contents_1_t *list = displays[i];
17165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        switch(i) {
17265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            case HWC_DISPLAY_PRIMARY:
17365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                ret = hwc_prepare_primary(dev, list);
17465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                break;
17565bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            case HWC_DISPLAY_EXTERNAL:
17665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
17765bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                ret = hwc_prepare_external(dev, list);
17865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                break;
17965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            default:
18065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                ret = -EINVAL;
18129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
18229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
183d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    ctx->mOverlay->configDone();
184d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
1853e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return ret;
18629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
18729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
1885b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
18972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                             int event, int enabled)
19072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed{
19172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    int ret = 0;
192ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed
19372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
19472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
19572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                ctx->mFbDev->common.module);
196eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev    pthread_mutex_lock(&ctx->vstate.lock);
19772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    switch(event) {
19872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        case HWC_EVENT_VSYNC:
1991ef881ceed7b39b4034adba23368c2006bfd074cOmprakash Dhyade            if (ctx->vstate.enable == enabled)
2001ef881ceed7b39b4034adba23368c2006bfd074cOmprakash Dhyade                break;
201eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            ctx->vstate.enable = !!enabled;
202c7faa70f4a92f020f9d5df20a4ae4bb80be7a022Naseer Ahmed            pthread_cond_signal(&ctx->vstate.cond);
203eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
204eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev                      (enabled)?"ENABLED":"DISABLED");
205eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            break;
20672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        default:
20772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed            ret = -EINVAL;
20872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    }
209eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev    pthread_mutex_unlock(&ctx->vstate.lock);
21072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    return ret;
21172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed}
21272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
2135b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
2145b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed{
215934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
216934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
217934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed        ctx->mFbDev->common.module);
218d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
2193e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
2203e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2213e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    switch(dpy) {
2223e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_PRIMARY:
2233e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            if(blank) {
224d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                ctx->mOverlay->configBegin();
225d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                ctx->mOverlay->configDone();
2263e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN);
2273e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            } else {
2283e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK);
2293e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            }
2303e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
2313e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_EXTERNAL:
2323e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            if(blank) {
2333e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                //TODO actual
2343e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            } else {
2353e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            }
2363e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
2373e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        default:
2383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            return -EINVAL;
2393e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
240abc785f17cdec8760e948f5691e435de8760f368Arun Kumar K.R    // Enable HPD here, as during bootup unblank is called
241abc785f17cdec8760e948f5691e435de8760f368Arun Kumar K.R    // when SF is completely initialized
242abc785f17cdec8760e948f5691e435de8760f368Arun Kumar K.R    ctx->mExtDisplay->setHPD(1);
2433e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
2443e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    if(ret < 0) {
2453e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        ALOGE("%s: failed. Dpy=%d, blank=%d : %s",
2463e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                __FUNCTION__, dpy, blank, strerror(errno));
2473e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        return ret;
2485b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    }
2493e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ALOGD("%s: Done Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2503e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ctx->dpyAttr[dpy].isActive = !blank;
2515b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    return 0;
2525b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed}
2535b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed
2545b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_query(struct hwc_composer_device_1* dev,
25572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                     int param, int* value)
25672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed{
25772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
25872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
25972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ctx->mFbDev->common.module);
2603e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int supported = HWC_DISPLAY_PRIMARY_BIT;
26172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
26272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    switch (param) {
26372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    case HWC_BACKGROUND_LAYER_SUPPORTED:
26472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        // Not supported for now
26572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        value[0] = 0;
26672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        break;
2673e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    case HWC_VSYNC_PERIOD: //Not used for hwc > 1.1
2682e2798c71ad66cef2bd82967058c88f85d3501a8Saurabh Shah        value[0] = m->fps;
26972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ALOGI("fps: %d", value[0]);
27072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        break;
2713e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    case HWC_DISPLAY_TYPES_SUPPORTED:
272c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        if(ctx->mMDP.hasOverlay)
273c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            supported |= HWC_DISPLAY_EXTERNAL_BIT;
2743e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        value[0] = supported;
2753e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        break;
27672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    default:
27772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        return -EINVAL;
27872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    }
27972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    return 0;
28072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
28172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed}
28272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
2833e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
284eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    int ret = 0;
285eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah
286ae823e773536ee9b6cf97c575463f1a9902370d9Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
287ae823e773536ee9b6cf97c575463f1a9902370d9Saurabh Shah        ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
288c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        uint32_t last = list->numHwLayers - 1;
289c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
290c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
2918c8bfd2f827946ad88ea181d7f952d41ca4938feSaurabh Shah        hwc_sync(ctx, list, HWC_DISPLAY_PRIMARY);
292eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        if (!VideoOverlay::draw(ctx, list, HWC_DISPLAY_PRIMARY)) {
293eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
294eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ret = -1;
295eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
29665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        if (!MDPComp::draw(ctx, list)) {
29765bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            ALOGE("%s: MDPComp::draw fail!", __FUNCTION__);
29865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            ret = -1;
29965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        }
30065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
3013e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        //TODO We dont check for SKIP flag on this layer because we need PAN
3023e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        //always. Last layer is always FB
30365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
30465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
30565bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            if(!(fbLayer->flags & HWC_SKIP_LAYER)) {
30665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                if (!FBUpdate::draw(ctx, fbLayer, HWC_DISPLAY_PRIMARY)) {
30765bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                    ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
30865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                    ret = -1;
30965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                }
31065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            }
311eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) {
312eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah                ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__);
313eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah                return -1;
314eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            }
3153e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
3163e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
317eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    return ret;
3183e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
3193e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
3203e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_set_external(hwc_context_t *ctx,
3213e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        hwc_display_contents_1_t* list) {
322eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    int ret = 0;
323f83d4480f2c7e37374c4516750aae79c6b12eb79Kinjal Bhavsar    Locker::Autolock _l(ctx->mExtSetLock);
324c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
325ae823e773536ee9b6cf97c575463f1a9902370d9Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
326c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive &&
327c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
3283e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t last = list->numHwLayers - 1;
329c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
330c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
331c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_sync(ctx, list, HWC_DISPLAY_EXTERNAL);
332c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
333eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        if (!VideoOverlay::draw(ctx, list, HWC_DISPLAY_EXTERNAL)) {
334eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
335eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ret = -1;
336eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
337c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
338c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
339150806ae0ed82d1d26fa144a6950031570b06bfbSaurabh Shah        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
340150806ae0ed82d1d26fa144a6950031570b06bfbSaurabh Shah                !(fbLayer->flags & HWC_SKIP_LAYER) && hnd) {
341d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed            if (!FBUpdate::draw(ctx, fbLayer, HWC_DISPLAY_EXTERNAL)) {
342d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
343eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah                ret = -1;
344eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            }
345eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
346eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        if (!ctx->mExtDisplay->post()) {
347eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ALOGE("%s: ctx->mExtDisplay->post fail!", __FUNCTION__);
348eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            return -1;
3493e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
3503e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
351eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    return ret;
3523e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
3533e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
3545b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_set(hwc_composer_device_1 *dev,
3555b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                   size_t numDisplays,
3565b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                   hwc_display_contents_1_t** displays)
35729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
35829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int ret = 0;
35929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
36032ff225e6d77baeb38925faba4b6b8457fab6b7bNaseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
361c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
3623e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    for (uint32_t i = 0; i < numDisplays; i++) {
3635b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed        hwc_display_contents_1_t* list = displays[i];
3643e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        switch(i) {
3653e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            case HWC_DISPLAY_PRIMARY:
3663e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = hwc_set_primary(ctx, list);
367c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                break;
3683e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            case HWC_DISPLAY_EXTERNAL:
3693e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = hwc_set_external(ctx, list);
370c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                break;
3713e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            default:
3723e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = -EINVAL;
3735b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed        }
3743e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
3753e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return ret;
3763e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
377f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed
3783e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahint hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
3793e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t* configs, size_t* numConfigs) {
3803e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
381c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
3823e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //in 1.1 there is no way to choose a config, report as config id # 0
3833e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //This config is passed to getDisplayAttributes. Ignore for now.
3843e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    switch(disp) {
3853e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_PRIMARY:
386c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            if(*numConfigs > 0) {
387c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                configs[0] = 0;
388c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                *numConfigs = 1;
389c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            }
390c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ret = 0; //NO_ERROR
3913e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
3923e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_EXTERNAL:
393c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ret = -1; //Not connected
394c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
395c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                ret = 0; //NO_ERROR
396c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                if(*numConfigs > 0) {
397c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    configs[0] = 0;
398c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    *numConfigs = 1;
399c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                }
400c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            }
4013e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4025b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    }
40329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return ret;
40429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
40529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4063e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahint hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
4073e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t config, const uint32_t* attributes, int32_t* values) {
4083e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4093e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
410c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    //If hotpluggable displays are inactive return error
411c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
412c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        return -1;
413c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    }
414c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
4153e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //From HWComposer
4163e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    static const uint32_t DISPLAY_ATTRIBUTES[] = {
4173e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_VSYNC_PERIOD,
4183e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_WIDTH,
4193e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_HEIGHT,
4203e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_DPI_X,
4213e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_DPI_Y,
4223e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_NO_ATTRIBUTE,
4233e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    };
4243e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4253e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
4263e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            sizeof(DISPLAY_ATTRIBUTES)[0]);
4273e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4283e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
4293e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        switch (attributes[i]) {
4303e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_VSYNC_PERIOD:
4313e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].vsync_period;
4323e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4333e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_WIDTH:
4343e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].xres;
435c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
436c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    ctx->dpyAttr[disp].xres);
4373e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_HEIGHT:
4393e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].yres;
440c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
441c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    ctx->dpyAttr[disp].yres);
4423e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4433e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_DPI_X:
4447b80d9c8cb345f7020093e0afb691bf3a72deec6Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
4453e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4463e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_DPI_Y:
4477b80d9c8cb345f7020093e0afb691bf3a72deec6Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
4483e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4493e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        default:
4503e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            ALOGE("Unknown display attribute %d",
4513e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                    attributes[i]);
4523e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            return -EINVAL;
4533e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
4543e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
4553e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
4563e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
4573e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4583b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmedvoid hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
4593b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed{
4603b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
4613b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    android::String8 buf("");
4623b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    dumpsys_log(buf, "Qualcomm HWC state:\n");
4633b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    dumpsys_log(buf, "  MDPVersion=%d\n", ctx->mMDP.version);
4643b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    dumpsys_log(buf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
4653b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    MDPComp::dump(buf);
4663b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    //XXX: Call Other dump functions
4673b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    strlcpy(buff, buf.string(), buff_len);
4683b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed}
4693b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed
47029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_close(struct hw_device_t *dev)
47129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
47229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(!dev) {
47372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ALOGE("%s: NULL device pointer", __FUNCTION__);
47429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -1;
47529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
47629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    closeContext((hwc_context_t*)dev);
47729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    free(dev);
47829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
47929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
48029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
48129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
48229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module, const char* name,
48329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           struct hw_device_t** device)
48429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
48529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = -EINVAL;
48629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
48729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
48829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct hwc_context_t *dev;
48929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dev = (hwc_context_t*)malloc(sizeof(*dev));
49029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        memset(dev, 0, sizeof(*dev));
49172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
49272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        //Initialize hwc context
49329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        initContext(dev);
49472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
49572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        //Setup HWC methods
4963e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
4973e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_1;
4983e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.module       = const_cast<hw_module_t*>(module);
4993e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.close        = hwc_device_close;
5003e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.prepare             = hwc_prepare;
5013e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.set                 = hwc_set;
5023e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.eventControl        = hwc_eventControl;
5033e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.blank               = hwc_blank;
5043e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.query               = hwc_query;
5053e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.registerProcs       = hwc_registerProcs;
5063b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed        dev->device.dump                = hwc_dump;
5073e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
5083e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
5093e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        *device = &dev->device.common;
51029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = 0;
51129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
51229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
51329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
514