hwc.cpp revision f48c59032a351cda58b2057423b2646423acd7c7
129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Copyright (C) 2010 The Android Open Source Project
30e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
56c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R * Not a Contribution, Apache license notifications and license are retained
66c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R * for attribution purposes only.
76c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R *
829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License");
929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * you may not use this file except in compliance with the License.
1029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * You may obtain a copy of the License at
1129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
1229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *      http://www.apache.org/licenses/LICENSE-2.0
1329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
1429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Unless required by applicable law or agreed to in writing, software
1529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS,
1629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * See the License for the specific language governing permissions and
1829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * limitations under the License.
1929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
2029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <fcntl.h>
2229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <errno.h>
2329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <cutils/log.h>
2529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <cutils/atomic.h>
2672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed#include <EGL/egl.h>
2729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed#include <overlay.h>
2972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed#include <fb_priv.h>
3096c4c95d48dc075196c601b30a8798a262df9720Naseer Ahmed#include <mdp_version.h>
3129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include "hwc_utils.h"
32f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed#include "hwc_video.h"
33d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed#include "hwc_fbupdate.h"
3465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed#include "hwc_mdpcomp.h"
3556f610dd235b577725198e9341caae92379fdf23Saurabh Shah#include "external.h"
366c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R#include "hwc_copybit.h"
3729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedusing namespace qhwc;
39d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed#define VSYNC_DEBUG 0
4029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module,
4229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           const char* name,
4329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           struct hw_device_t** device);
4429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic struct hw_module_methods_t hwc_module_methods = {
4629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    open: hwc_device_open
4729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
4829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedhwc_module_t HAL_MODULE_INFO_SYM = {
5029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    common: {
5129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        tag: HARDWARE_MODULE_TAG,
5229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        version_major: 2,
5329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        version_minor: 0,
5429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        id: HWC_HARDWARE_MODULE_ID,
5529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        name: "Qualcomm Hardware Composer Module",
5629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        author: "CodeAurora Forum",
5729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        methods: &hwc_module_methods,
5829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dso: 0,
5929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        reserved: {0},
6029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
6129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
6229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
6429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Save callback functions registered to HWC
6529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
665b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic void hwc_registerProcs(struct hwc_composer_device_1* dev,
6729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              hwc_procs_t const* procs)
6829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
690f9c397181604f28d15c9273de42f97ae2b4c613Iliyan Malchev    ALOGI("%s", __FUNCTION__);
7029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
7129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(!ctx) {
7229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: Invalid context", __FUNCTION__);
7329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return;
7429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
753be78d9816da84e48a40232165189f9deb16808fJesse Hall    ctx->proc = procs;
763be78d9816da84e48a40232165189f9deb16808fJesse Hall
77ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed    // Now that we have the functions needed, kick off
78ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed    // the uevent & vsync threads
793be78d9816da84e48a40232165189f9deb16808fJesse Hall    init_uevent_thread(ctx);
80ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed    init_vsync_thread(ctx);
8129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
8229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
83649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah//Helper
8489f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmedstatic void reset(hwc_context_t *ctx, int numDisplays,
8589f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed                  hwc_display_contents_1_t** displays) {
863e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    memset(ctx->listStats, 0, sizeof(ctx->listStats));
871a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah    for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++){
8889f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        hwc_display_contents_1_t *list = displays[i];
8989f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        // XXX:SurfaceFlinger no longer guarantees that this
9089f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        // value is reset on every prepare. However, for the layer
9189f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        // cache we need to reset it.
9289f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        // We can probably rethink that later on
9389f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        if (LIKELY(list && list->numHwLayers > 1)) {
9489f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed            for(uint32_t j = 0; j < list->numHwLayers; j++) {
9589f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed                if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
9689f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed                    list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
9789f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed            }
9889f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        }
996457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah
1006457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        if(ctx->mFBUpdate[i])
1016457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            ctx->mFBUpdate[i]->reset();
1026c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R
1036c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        if(ctx->mCopyBit[i])
1046c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R            ctx->mCopyBit[i]->reset();
1053e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
106d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    VideoOverlay::reset();
1073e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
1083e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
10965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed//clear prev layer prop flags and realloc for current frame
11065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmedstatic void reset_layer_prop(hwc_context_t* ctx, int dpy) {
11165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    int layer_count = ctx->listStats[dpy].numAppLayers;
11265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
11365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    if(ctx->layerProp[dpy]) {
11465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed       delete[] ctx->layerProp[dpy];
11565bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed       ctx->layerProp[dpy] = NULL;
11665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    }
11765bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
11865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    if(layer_count) {
11965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed       ctx->layerProp[dpy] = new LayerProp[layer_count];
12065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    }
12165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed}
12265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
1233e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_prepare_primary(hwc_composer_device_1 *dev,
1243e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        hwc_display_contents_1_t *list) {
1253e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
1266457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    const int dpy = HWC_DISPLAY_PRIMARY;
1271a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
1286457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].isActive) {
1291a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah
13086623d7d5106cd568a64be4e51be7ee77f078e08Saurabh Shah        uint32_t last = list->numHwLayers - 1;
1311a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
1321a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah        if(fbLayer->handle) {
1336457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            setListStats(ctx, list, dpy);
1346457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            reset_layer_prop(ctx, dpy);
1356c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R            int ret = ctx->mMDPComp->prepare(ctx, list);
1366c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R            if(!ret) {
1376c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R                // IF MDPcomp fails use this route
1386457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah                VideoOverlay::prepare(ctx, list, dpy);
1396457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah                ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
14065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            }
1416457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            ctx->mLayerCache[dpy]->updateLayerCache(list);
1426c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R            // Use Copybit, when MDP comp fails
1436c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R            if(!ret && ctx->mCopyBit[dpy])
1446c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
1453e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
1463e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
1473e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
1483e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
1493e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
1503e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_prepare_external(hwc_composer_device_1 *dev,
1513e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        hwc_display_contents_1_t *list) {
1523e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
1536457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    const int dpy = HWC_DISPLAY_EXTERNAL;
154c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
155ae823e773536ee9b6cf97c575463f1a9902370d9Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
1566457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].isActive &&
1576457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].connected) {
158c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
159c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        uint32_t last = list->numHwLayers - 1;
1601a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
1611a8cda0b2cb535656eb18bf5dc07a02fcddec9abSaurabh Shah        if(fbLayer->handle) {
1626457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            setListStats(ctx, list, dpy);
1636457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            reset_layer_prop(ctx, dpy);
1646457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            VideoOverlay::prepare(ctx, list, dpy);
1656457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
1666457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            ctx->mLayerCache[dpy]->updateLayerCache(list);
1676c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R            if(ctx->mCopyBit[dpy])
1686c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
169f3db354f47d3d6b7f42374ea7b4e3b8e06df8592Amara Venkata Mastan Manoj Kumar            ctx->mExtDispConfiguring = false;
170c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        }
1713e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
1723e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
173649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah}
174649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah
1755b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
1765b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                       hwc_display_contents_1_t** displays)
17729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
1783e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
17929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
180d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
18189f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed    reset(ctx, numDisplays, displays);
18256f610dd235b577725198e9341caae92379fdf23Saurabh Shah
183d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    ctx->mOverlay->configBegin();
18456f610dd235b577725198e9341caae92379fdf23Saurabh Shah
18565bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    for (int32_t i = numDisplays - 1; i >= 0; i--) {
18665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        hwc_display_contents_1_t *list = displays[i];
18765bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        switch(i) {
18865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            case HWC_DISPLAY_PRIMARY:
18965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                ret = hwc_prepare_primary(dev, list);
19065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                break;
19165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            case HWC_DISPLAY_EXTERNAL:
19265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                ret = hwc_prepare_external(dev, list);
19365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                break;
19465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            default:
19565bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                ret = -EINVAL;
19629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
19729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
198d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
1996457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    ctx->mOverlay->configDone();
2003e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return ret;
20129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
20229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2035b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
20472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                             int event, int enabled)
20572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed{
20672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    int ret = 0;
207ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed
20872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
20972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
21072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                ctx->mFbDev->common.module);
211eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev    pthread_mutex_lock(&ctx->vstate.lock);
21272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    switch(event) {
21372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        case HWC_EVENT_VSYNC:
2141ef881ceed7b39b4034adba23368c2006bfd074cOmprakash Dhyade            if (ctx->vstate.enable == enabled)
2151ef881ceed7b39b4034adba23368c2006bfd074cOmprakash Dhyade                break;
216eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            ctx->vstate.enable = !!enabled;
217c7faa70f4a92f020f9d5df20a4ae4bb80be7a022Naseer Ahmed            pthread_cond_signal(&ctx->vstate.cond);
218eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
219eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev                      (enabled)?"ENABLED":"DISABLED");
220eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            break;
22172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        default:
22272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed            ret = -EINVAL;
22372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    }
224eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev    pthread_mutex_unlock(&ctx->vstate.lock);
22572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    return ret;
22672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed}
22772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
2285b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
2295b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed{
230934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
231934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
232934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed        ctx->mFbDev->common.module);
233d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
2343e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
2353e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2363e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    switch(dpy) {
2373e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_PRIMARY:
2383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            if(blank) {
239d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                ctx->mOverlay->configBegin();
240d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                ctx->mOverlay->configDone();
2413e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN);
2423e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            } else {
2433e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK);
2443e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            }
2453e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
2463e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_EXTERNAL:
2473e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            if(blank) {
2480e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R                // External Display post commits the changes to display
2490e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R                // Call this on blank, so that any pipe unsets gets committed
2500e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R                if (!ctx->mExtDisplay->post()) {
2510e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R                    ret = -1;
2520e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R                    ALOGE("%s:ctx->mExtDisplay->post fail!! ", __FUNCTION__);
2530e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R                }
2543e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            } else {
2553e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            }
2563e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
2573e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        default:
2583e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            return -EINVAL;
2593e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
260abc785f17cdec8760e948f5691e435de8760f368Arun Kumar K.R    // Enable HPD here, as during bootup unblank is called
261abc785f17cdec8760e948f5691e435de8760f368Arun Kumar K.R    // when SF is completely initialized
262abc785f17cdec8760e948f5691e435de8760f368Arun Kumar K.R    ctx->mExtDisplay->setHPD(1);
2633e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
2643e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    if(ret < 0) {
2653e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        ALOGE("%s: failed. Dpy=%d, blank=%d : %s",
2663e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                __FUNCTION__, dpy, blank, strerror(errno));
2673e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        return ret;
2685b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    }
2693e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ALOGD("%s: Done Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2703e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ctx->dpyAttr[dpy].isActive = !blank;
2715b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    return 0;
2725b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed}
2735b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed
2745b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_query(struct hwc_composer_device_1* dev,
27572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                     int param, int* value)
27672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed{
27772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
27872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
27972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ctx->mFbDev->common.module);
2803e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int supported = HWC_DISPLAY_PRIMARY_BIT;
28172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
28272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    switch (param) {
28372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    case HWC_BACKGROUND_LAYER_SUPPORTED:
28472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        // Not supported for now
28572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        value[0] = 0;
28672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        break;
2873e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    case HWC_VSYNC_PERIOD: //Not used for hwc > 1.1
2882e2798c71ad66cef2bd82967058c88f85d3501a8Saurabh Shah        value[0] = m->fps;
28972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ALOGI("fps: %d", value[0]);
29072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        break;
2913e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    case HWC_DISPLAY_TYPES_SUPPORTED:
292c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        if(ctx->mMDP.hasOverlay)
293c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            supported |= HWC_DISPLAY_EXTERNAL_BIT;
2943e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        value[0] = supported;
2953e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        break;
29672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    default:
29772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        return -EINVAL;
29872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    }
29972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    return 0;
30072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
30172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed}
30272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
3033e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
304eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    int ret = 0;
3056457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    const int dpy = HWC_DISPLAY_PRIMARY;
306eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah
307a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
308c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        uint32_t last = list->numHwLayers - 1;
309c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
3106c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        int fd = -1; //FenceFD from the Copybit(valid in async mode)
3116c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        if(ctx->mCopyBit[dpy])
3126c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R            ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
313a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar        if(list->numHwLayers > 1)
314a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar            hwc_sync(ctx, list, dpy, fd);
3156457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        if (!VideoOverlay::draw(ctx, list, dpy)) {
316eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
317eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ret = -1;
318eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
319bfa005e8c51529d99b9c360a444d351ebe0885f7Saurabh Shah        if (!ctx->mMDPComp->draw(ctx, list)) {
32065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            ALOGE("%s: MDPComp::draw fail!", __FUNCTION__);
32165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            ret = -1;
32265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        }
32365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
3243e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        //TODO We dont check for SKIP flag on this layer because we need PAN
3253e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        //always. Last layer is always FB
32665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
32765bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
328a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar            if(!(fbLayer->flags & HWC_SKIP_LAYER) &&
329a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar                (list->numHwLayers > 1)) {
3306457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah                if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
33165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                    ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
33265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                    ret = -1;
33365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                }
33465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            }
335677311f0bc4a8716e86880d29a6b8051e4389da1Saurabh Shah        }
336677311f0bc4a8716e86880d29a6b8051e4389da1Saurabh Shah        if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) {
337677311f0bc4a8716e86880d29a6b8051e4389da1Saurabh Shah            ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__);
338677311f0bc4a8716e86880d29a6b8051e4389da1Saurabh Shah            return -1;
3393e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
3403e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
341eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    return ret;
3423e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
3433e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
3443e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_set_external(hwc_context_t *ctx,
3453e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        hwc_display_contents_1_t* list) {
346eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    int ret = 0;
3476457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    const int dpy = HWC_DISPLAY_EXTERNAL;
3486457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah
349f83d4480f2c7e37374c4516750aae79c6b12eb79Kinjal Bhavsar    Locker::Autolock _l(ctx->mExtSetLock);
350c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
351a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
3526457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].connected) {
3533e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t last = list->numHwLayers - 1;
354c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
3556c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        int fd = -1; //FenceFD from the Copybit(valid in async mode)
3566c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        if(ctx->mCopyBit[dpy])
3576c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R            ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
358c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
359a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar        if(list->numHwLayers > 1)
360a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar            hwc_sync(ctx, list, dpy, fd);
361c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
3626457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        if (!VideoOverlay::draw(ctx, list, dpy)) {
363eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
364eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ret = -1;
365eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
366c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
367c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
368150806ae0ed82d1d26fa144a6950031570b06bfbSaurabh Shah        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
369a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar                !(fbLayer->flags & HWC_SKIP_LAYER) && hnd &&
370a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar                (list->numHwLayers > 1)) {
3716457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
372d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
373eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah                ret = -1;
374eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            }
375eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
376eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        if (!ctx->mExtDisplay->post()) {
377eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ALOGE("%s: ctx->mExtDisplay->post fail!", __FUNCTION__);
378eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            return -1;
3793e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
3803e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
381eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    return ret;
3823e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
3833e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
3845b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_set(hwc_composer_device_1 *dev,
3855b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                   size_t numDisplays,
3865b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                   hwc_display_contents_1_t** displays)
38729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
38829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int ret = 0;
38929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
39032ff225e6d77baeb38925faba4b6b8457fab6b7bNaseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
3913e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    for (uint32_t i = 0; i < numDisplays; i++) {
3925b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed        hwc_display_contents_1_t* list = displays[i];
3933e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        switch(i) {
3943e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            case HWC_DISPLAY_PRIMARY:
3953e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = hwc_set_primary(ctx, list);
396c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                break;
3973e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            case HWC_DISPLAY_EXTERNAL:
3983e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = hwc_set_external(ctx, list);
399c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                break;
4003e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            default:
4013e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = -EINVAL;
4025b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed        }
4033e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
4043e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return ret;
4053e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
406f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed
4073e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahint hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
4083e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t* configs, size_t* numConfigs) {
4093e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
410c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
4113e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //in 1.1 there is no way to choose a config, report as config id # 0
4123e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //This config is passed to getDisplayAttributes. Ignore for now.
4133e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    switch(disp) {
4143e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_PRIMARY:
415c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            if(*numConfigs > 0) {
416c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                configs[0] = 0;
417c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                *numConfigs = 1;
418c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            }
419c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ret = 0; //NO_ERROR
4203e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4213e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_EXTERNAL:
422c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ret = -1; //Not connected
423c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
424c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                ret = 0; //NO_ERROR
425c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                if(*numConfigs > 0) {
426c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    configs[0] = 0;
427c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    *numConfigs = 1;
428c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                }
429c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            }
4303e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4315b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    }
43229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return ret;
43329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
43429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4353e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahint hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
4363e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t config, const uint32_t* attributes, int32_t* values) {
4373e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
439c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    //If hotpluggable displays are inactive return error
440c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
441c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        return -1;
442c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    }
443c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
4443e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //From HWComposer
4453e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    static const uint32_t DISPLAY_ATTRIBUTES[] = {
4463e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_VSYNC_PERIOD,
4473e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_WIDTH,
4483e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_HEIGHT,
4493e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_DPI_X,
4503e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_DPI_Y,
4513e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_NO_ATTRIBUTE,
4523e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    };
4533e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4543e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
4553e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            sizeof(DISPLAY_ATTRIBUTES)[0]);
4563e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4573e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
4583e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        switch (attributes[i]) {
4593e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_VSYNC_PERIOD:
4603e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].vsync_period;
4613e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4623e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_WIDTH:
4633e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].xres;
464c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
465c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    ctx->dpyAttr[disp].xres);
4663e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4673e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_HEIGHT:
4683e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].yres;
469c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
470c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    ctx->dpyAttr[disp].yres);
4713e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4723e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_DPI_X:
4737b80d9c8cb345f7020093e0afb691bf3a72deec6Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
4743e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4753e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_DPI_Y:
4767b80d9c8cb345f7020093e0afb691bf3a72deec6Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
4773e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4783e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        default:
4793e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            ALOGE("Unknown display attribute %d",
4803e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                    attributes[i]);
4813e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            return -EINVAL;
4823e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
4833e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
4843e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
4853e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
4863e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4873b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmedvoid hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
4883b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed{
4893b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
490f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    android::String8 aBuf("");
491f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    dumpsys_log(aBuf, "Qualcomm HWC state:\n");
492f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
493f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
494f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    ctx->mMDPComp->dump(aBuf);
495f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    char ovDump[2048] = {'\0'};
496f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    ctx->mOverlay->getDump(ovDump, 2048);
497f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    dumpsys_log(aBuf, ovDump);
498f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    strlcpy(buff, aBuf.string(), buff_len);
4993b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed}
5003b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed
50129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_close(struct hw_device_t *dev)
50229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
50329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(!dev) {
50472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ALOGE("%s: NULL device pointer", __FUNCTION__);
50529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -1;
50629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
50729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    closeContext((hwc_context_t*)dev);
50829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    free(dev);
50929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
51029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
51129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
51229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
51329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module, const char* name,
51429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           struct hw_device_t** device)
51529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
51629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = -EINVAL;
51729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
51829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
51929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct hwc_context_t *dev;
52029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dev = (hwc_context_t*)malloc(sizeof(*dev));
52129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        memset(dev, 0, sizeof(*dev));
52272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
52372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        //Initialize hwc context
52429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        initContext(dev);
52572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
52672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        //Setup HWC methods
5273e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
5283e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_1;
5293e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.module       = const_cast<hw_module_t*>(module);
5303e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.close        = hwc_device_close;
5313e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.prepare             = hwc_prepare;
5323e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.set                 = hwc_set;
5333e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.eventControl        = hwc_eventControl;
5343e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.blank               = hwc_blank;
5353e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.query               = hwc_query;
5363e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.registerProcs       = hwc_registerProcs;
5373b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed        dev->device.dump                = hwc_dump;
5383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
5393e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
5403e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        *device = &dev->device.common;
54129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = 0;
54229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
54329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
54429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
545