hwc.cpp revision 3a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1a
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));
873a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar    for(int i = 0; i < MAX_DISPLAYS; 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,
1513a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar        hwc_display_contents_1_t *list, int dpy) {
1523e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
153c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
154ae823e773536ee9b6cf97c575463f1a9902370d9Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
1556457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].isActive &&
1566457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].connected) {
157c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        uint32_t last = list->numHwLayers - 1;
1583a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar        if(!ctx->dpyAttr[dpy].isPause) {
1593a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            hwc_layer_1_t *fbLayer = &list->hwLayers[last];
1603a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            if(fbLayer->handle) {
1613a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar                setListStats(ctx, list, dpy);
1623a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar                reset_layer_prop(ctx, dpy);
1633a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar                VideoOverlay::prepare(ctx, list, dpy);
1643a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar                ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
1653a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar                ctx->mLayerCache[dpy]->updateLayerCache(list);
1663a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar                if(ctx->mCopyBit[dpy])
1673a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar                    ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
1683a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar                ctx->mExtDispConfiguring = false;
1693a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            }
1703a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar        } else {
1713a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            // External Display is in Pause state.
1723a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            // ToDo:
1733a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            // Mark all application layers as OVERLAY so that
1743a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            // GPU will not compose. This is done for power
1753a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            // optimization
176c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        }
1773e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
1783e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
179649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah}
180649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah
1815b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
1825b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                       hwc_display_contents_1_t** displays)
18329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
1843e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
18529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
186d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
18789f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed    reset(ctx, numDisplays, displays);
18856f610dd235b577725198e9341caae92379fdf23Saurabh Shah
189d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    ctx->mOverlay->configBegin();
19056f610dd235b577725198e9341caae92379fdf23Saurabh Shah
1913a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar    for (int32_t i = numDisplays; i >= 0; i--) {
19265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        hwc_display_contents_1_t *list = displays[i];
19365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        switch(i) {
19465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            case HWC_DISPLAY_PRIMARY:
19565bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                ret = hwc_prepare_primary(dev, list);
19665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                break;
19765bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            case HWC_DISPLAY_EXTERNAL:
1983a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            case HWC_DISPLAY_VIRTUAL:
1993a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar                ret = hwc_prepare_external(dev, list, i);
20065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                break;
20165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            default:
20265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                ret = -EINVAL;
20329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
20429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
205d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
2066457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    ctx->mOverlay->configDone();
2073e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return ret;
20829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
20929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2105b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
21172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                             int event, int enabled)
21272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed{
21372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    int ret = 0;
214ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed
21572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
21672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
21772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                ctx->mFbDev->common.module);
218eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev    pthread_mutex_lock(&ctx->vstate.lock);
21972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    switch(event) {
22072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        case HWC_EVENT_VSYNC:
2211ef881ceed7b39b4034adba23368c2006bfd074cOmprakash Dhyade            if (ctx->vstate.enable == enabled)
2221ef881ceed7b39b4034adba23368c2006bfd074cOmprakash Dhyade                break;
223eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            ctx->vstate.enable = !!enabled;
224c7faa70f4a92f020f9d5df20a4ae4bb80be7a022Naseer Ahmed            pthread_cond_signal(&ctx->vstate.cond);
225eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
226eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev                      (enabled)?"ENABLED":"DISABLED");
227eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            break;
22872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        default:
22972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed            ret = -EINVAL;
23072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    }
231eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev    pthread_mutex_unlock(&ctx->vstate.lock);
23272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    return ret;
23372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed}
23472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
2355b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
2365b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed{
237934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
238934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
239934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed        ctx->mFbDev->common.module);
240d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
2413e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
2423e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2433e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    switch(dpy) {
2443e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_PRIMARY:
2453e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            if(blank) {
246d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                ctx->mOverlay->configBegin();
247d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                ctx->mOverlay->configDone();
2483e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN);
2493e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            } else {
2503e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK);
2513e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            }
2523e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
2533e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_EXTERNAL:
2543a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar        case HWC_DISPLAY_VIRTUAL:
2553e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            if(blank) {
2563a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar                // External/Virtual Display post commits the changes to display
2570e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R                // Call this on blank, so that any pipe unsets gets committed
2580e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R                if (!ctx->mExtDisplay->post()) {
2590e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R                    ret = -1;
2600e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R                    ALOGE("%s:ctx->mExtDisplay->post fail!! ", __FUNCTION__);
2610e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R                }
2623e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            } else {
2633e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            }
2643e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
2653e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        default:
2663e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            return -EINVAL;
2673e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
268abc785f17cdec8760e948f5691e435de8760f368Arun Kumar K.R    // Enable HPD here, as during bootup unblank is called
269abc785f17cdec8760e948f5691e435de8760f368Arun Kumar K.R    // when SF is completely initialized
270abc785f17cdec8760e948f5691e435de8760f368Arun Kumar K.R    ctx->mExtDisplay->setHPD(1);
2713e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
2723e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    if(ret < 0) {
2733e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        ALOGE("%s: failed. Dpy=%d, blank=%d : %s",
2743e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                __FUNCTION__, dpy, blank, strerror(errno));
2753e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        return ret;
2765b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    }
2773e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ALOGD("%s: Done Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2783e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    ctx->dpyAttr[dpy].isActive = !blank;
2795b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    return 0;
2805b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed}
2815b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed
2825b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_query(struct hwc_composer_device_1* dev,
28372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                     int param, int* value)
28472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed{
28572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
28672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
28772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ctx->mFbDev->common.module);
2883e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int supported = HWC_DISPLAY_PRIMARY_BIT;
28972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
29072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    switch (param) {
29172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    case HWC_BACKGROUND_LAYER_SUPPORTED:
29272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        // Not supported for now
29372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        value[0] = 0;
29472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        break;
2953e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    case HWC_VSYNC_PERIOD: //Not used for hwc > 1.1
2962e2798c71ad66cef2bd82967058c88f85d3501a8Saurabh Shah        value[0] = m->fps;
29772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ALOGI("fps: %d", value[0]);
29872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        break;
2993e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    case HWC_DISPLAY_TYPES_SUPPORTED:
300c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        if(ctx->mMDP.hasOverlay)
301c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            supported |= HWC_DISPLAY_EXTERNAL_BIT;
3023e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        value[0] = supported;
3033e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        break;
30472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    default:
30572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        return -EINVAL;
30672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    }
30772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    return 0;
30872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
30972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed}
31072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
3113e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
312eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    int ret = 0;
3136457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    const int dpy = HWC_DISPLAY_PRIMARY;
314eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah
315a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
316c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        uint32_t last = list->numHwLayers - 1;
317c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
3186c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        int fd = -1; //FenceFD from the Copybit(valid in async mode)
3196c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        if(ctx->mCopyBit[dpy])
3206c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R            ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
321a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar        if(list->numHwLayers > 1)
322a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar            hwc_sync(ctx, list, dpy, fd);
3236457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        if (!VideoOverlay::draw(ctx, list, dpy)) {
324eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
325eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ret = -1;
326eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
327bfa005e8c51529d99b9c360a444d351ebe0885f7Saurabh Shah        if (!ctx->mMDPComp->draw(ctx, list)) {
32865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            ALOGE("%s: MDPComp::draw fail!", __FUNCTION__);
32965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            ret = -1;
33065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        }
33165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
3323e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        //TODO We dont check for SKIP flag on this layer because we need PAN
3333e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        //always. Last layer is always FB
33465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
33565bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
336a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar            if(!(fbLayer->flags & HWC_SKIP_LAYER) &&
337a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar                (list->numHwLayers > 1)) {
3386457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah                if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
33965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                    ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
34065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                    ret = -1;
34165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                }
34265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            }
343677311f0bc4a8716e86880d29a6b8051e4389da1Saurabh Shah        }
344677311f0bc4a8716e86880d29a6b8051e4389da1Saurabh Shah        if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) {
345677311f0bc4a8716e86880d29a6b8051e4389da1Saurabh Shah            ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__);
346677311f0bc4a8716e86880d29a6b8051e4389da1Saurabh Shah            return -1;
3473e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
3483e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
349eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    return ret;
3503e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
3513e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
3523e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_set_external(hwc_context_t *ctx,
3533a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar        hwc_display_contents_1_t* list, int dpy) {
354eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    int ret = 0;
355f83d4480f2c7e37374c4516750aae79c6b12eb79Kinjal Bhavsar    Locker::Autolock _l(ctx->mExtSetLock);
356c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
357a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
3583a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar        !ctx->dpyAttr[dpy].isPause &&
3596457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].connected) {
3603e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t last = list->numHwLayers - 1;
361c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
3626c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        int fd = -1; //FenceFD from the Copybit(valid in async mode)
3636c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        if(ctx->mCopyBit[dpy])
3646c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R            ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
365c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
366a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar        if(list->numHwLayers > 1)
367a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar            hwc_sync(ctx, list, dpy, fd);
368c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
3696457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        if (!VideoOverlay::draw(ctx, list, dpy)) {
370eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
371eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ret = -1;
372eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
373c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
374c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
375150806ae0ed82d1d26fa144a6950031570b06bfbSaurabh Shah        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
376a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar                !(fbLayer->flags & HWC_SKIP_LAYER) && hnd &&
377a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar                (list->numHwLayers > 1)) {
3786457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
379d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
380eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah                ret = -1;
381eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            }
382eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
383eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        if (!ctx->mExtDisplay->post()) {
384eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ALOGE("%s: ctx->mExtDisplay->post fail!", __FUNCTION__);
385eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            return -1;
3863e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
3873e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
388eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    return ret;
3893e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
3903e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
3915b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_set(hwc_composer_device_1 *dev,
3925b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                   size_t numDisplays,
3935b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                   hwc_display_contents_1_t** displays)
39429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
39529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int ret = 0;
39629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
39732ff225e6d77baeb38925faba4b6b8457fab6b7bNaseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
3983a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar    for (uint32_t i = 0; i <= numDisplays; i++) {
3995b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed        hwc_display_contents_1_t* list = displays[i];
4003e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        switch(i) {
4013e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            case HWC_DISPLAY_PRIMARY:
4023e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = hwc_set_primary(ctx, list);
403c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                break;
4043e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            case HWC_DISPLAY_EXTERNAL:
4053a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            case HWC_DISPLAY_VIRTUAL:
4063a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            /* ToDo: We are using hwc_set_external path for both External and
4073a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar                     Virtual displays on HWC1.1. Eventually, we will have
4083a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar                     separate functions when we move to HWC1.2
4093a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            */
4103a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar                ret = hwc_set_external(ctx, list, i);
411c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                break;
4123e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            default:
4133e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = -EINVAL;
4145b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed        }
4153e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
4163e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return ret;
4173e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
418f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed
4193e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahint hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
4203e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t* configs, size_t* numConfigs) {
4213e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
422c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
4233e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //in 1.1 there is no way to choose a config, report as config id # 0
4243e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //This config is passed to getDisplayAttributes. Ignore for now.
4253e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    switch(disp) {
4263e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_PRIMARY:
427c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            if(*numConfigs > 0) {
428c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                configs[0] = 0;
429c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                *numConfigs = 1;
430c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            }
431c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ret = 0; //NO_ERROR
4323e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4333e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_EXTERNAL:
434c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ret = -1; //Not connected
435c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
436c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                ret = 0; //NO_ERROR
437c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                if(*numConfigs > 0) {
438c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    configs[0] = 0;
439c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    *numConfigs = 1;
440c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                }
441c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            }
4423e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4435b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    }
44429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return ret;
44529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
44629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4473e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahint hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
4483e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t config, const uint32_t* attributes, int32_t* values) {
4493e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4503e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
451c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    //If hotpluggable displays are inactive return error
452c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
453c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        return -1;
454c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    }
455c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
4563e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //From HWComposer
4573e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    static const uint32_t DISPLAY_ATTRIBUTES[] = {
4583e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_VSYNC_PERIOD,
4593e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_WIDTH,
4603e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_HEIGHT,
4613e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_DPI_X,
4623e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_DPI_Y,
4633e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_NO_ATTRIBUTE,
4643e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    };
4653e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4663e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
4673e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            sizeof(DISPLAY_ATTRIBUTES)[0]);
4683e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4693e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
4703e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        switch (attributes[i]) {
4713e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_VSYNC_PERIOD:
4723e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].vsync_period;
4733e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4743e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_WIDTH:
4753e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].xres;
476c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
477c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    ctx->dpyAttr[disp].xres);
4783e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4793e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_HEIGHT:
4803e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].yres;
481c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
482c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    ctx->dpyAttr[disp].yres);
4833e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4843e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_DPI_X:
4857b80d9c8cb345f7020093e0afb691bf3a72deec6Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
4863e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4873e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_DPI_Y:
4887b80d9c8cb345f7020093e0afb691bf3a72deec6Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
4893e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
4903e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        default:
4913e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            ALOGE("Unknown display attribute %d",
4923e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                    attributes[i]);
4933e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            return -EINVAL;
4943e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
4953e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
4963e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
4973e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
4983e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4993b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmedvoid hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
5003b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed{
5013b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
502f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    android::String8 aBuf("");
503f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    dumpsys_log(aBuf, "Qualcomm HWC state:\n");
504f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
505f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
506f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    ctx->mMDPComp->dump(aBuf);
507f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    char ovDump[2048] = {'\0'};
508f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    ctx->mOverlay->getDump(ovDump, 2048);
509f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    dumpsys_log(aBuf, ovDump);
510f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    strlcpy(buff, aBuf.string(), buff_len);
5113b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed}
5123b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed
51329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_close(struct hw_device_t *dev)
51429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
51529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(!dev) {
51672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ALOGE("%s: NULL device pointer", __FUNCTION__);
51729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -1;
51829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
51929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    closeContext((hwc_context_t*)dev);
52029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    free(dev);
52129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
52229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
52329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
52429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
52529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module, const char* name,
52629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           struct hw_device_t** device)
52729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
52829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = -EINVAL;
52929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
53029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
53129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct hwc_context_t *dev;
53229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dev = (hwc_context_t*)malloc(sizeof(*dev));
53329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        memset(dev, 0, sizeof(*dev));
53472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
53572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        //Initialize hwc context
53629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        initContext(dev);
53772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
53872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        //Setup HWC methods
5393e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
5403e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_1;
5413e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.module       = const_cast<hw_module_t*>(module);
5423e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.close        = hwc_device_close;
5433e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.prepare             = hwc_prepare;
5443e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.set                 = hwc_set;
5453e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.eventControl        = hwc_eventControl;
5463e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.blank               = hwc_blank;
5473e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.query               = hwc_query;
5483e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.registerProcs       = hwc_registerProcs;
5493b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed        dev->device.dump                = hwc_dump;
5503e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
5513e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
5523e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        *device = &dev->device.common;
55329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = 0;
55429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
55529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
55629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
557