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 */
20b53fd3580ca9bd45e980c320daeb112e5d4f922aNaseer Ahmed#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
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>
276195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed#include <utils/Trace.h>
2893393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran#include <sys/ioctl.h>
2972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed#include <overlay.h>
3036963690317abceae79621f14ba41ff62b3ff489Saurabh Shah#include <overlayRotator.h>
315ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah#include <overlayWriteback.h>
3296c4c95d48dc075196c601b30a8798a262df9720Naseer Ahmed#include <mdp_version.h>
3329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include "hwc_utils.h"
34d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed#include "hwc_fbupdate.h"
3565bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed#include "hwc_mdpcomp.h"
3656f610dd235b577725198e9341caae92379fdf23Saurabh Shah#include "external.h"
376c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R#include "hwc_copybit.h"
38d80659c540b719660c7af9f530445268bc409db6Saurabh Shah#include "hwc_ad.h"
3916292d0097fa8f455a2a7b10b6af5144b7def9ddNaseer Ahmed#include "profiler.h"
4029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedusing namespace qhwc;
425fe3925fe5a04f1fe519f64e973a1e5da4932d03Saurabh Shahusing namespace overlay;
435fe3925fe5a04f1fe519f64e973a1e5da4932d03Saurabh Shah
44d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed#define VSYNC_DEBUG 0
45e156621d50bb4d064da7ad914414d3bf33545930Ramkumar Radhakrishnan#define BLANK_DEBUG 1
4629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module,
4829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           const char* name,
4929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           struct hw_device_t** device);
5029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic struct hw_module_methods_t hwc_module_methods = {
5229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    open: hwc_device_open
5329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
5429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedhwc_module_t HAL_MODULE_INFO_SYM = {
5629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    common: {
5729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        tag: HARDWARE_MODULE_TAG,
5829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        version_major: 2,
5929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        version_minor: 0,
6029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        id: HWC_HARDWARE_MODULE_ID,
6129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        name: "Qualcomm Hardware Composer Module",
6229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        author: "CodeAurora Forum",
6329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        methods: &hwc_module_methods,
6429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dso: 0,
6529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        reserved: {0},
6629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
6729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
6829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
7029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Save callback functions registered to HWC
7129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
725b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic void hwc_registerProcs(struct hwc_composer_device_1* dev,
7329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              hwc_procs_t const* procs)
7429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
750f9c397181604f28d15c9273de42f97ae2b4c613Iliyan Malchev    ALOGI("%s", __FUNCTION__);
7629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
7729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(!ctx) {
7829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: Invalid context", __FUNCTION__);
7929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return;
8029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
813be78d9816da84e48a40232165189f9deb16808fJesse Hall    ctx->proc = procs;
823be78d9816da84e48a40232165189f9deb16808fJesse Hall
83ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed    // Now that we have the functions needed, kick off
84ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed    // the uevent & vsync threads
853be78d9816da84e48a40232165189f9deb16808fJesse Hall    init_uevent_thread(ctx);
86ff4f0254be575a264504687c407e0db2fd5573d7Naseer Ahmed    init_vsync_thread(ctx);
8729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
8829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
89649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah//Helper
9089f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmedstatic void reset(hwc_context_t *ctx, int numDisplays,
9189f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed                  hwc_display_contents_1_t** displays) {
923a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar    for(int i = 0; i < MAX_DISPLAYS; i++) {
9389f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        hwc_display_contents_1_t *list = displays[i];
9489f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        // XXX:SurfaceFlinger no longer guarantees that this
9589f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        // value is reset on every prepare. However, for the layer
9689f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        // cache we need to reset it.
9789f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        // We can probably rethink that later on
9889f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        if (LIKELY(list && list->numHwLayers > 1)) {
9989f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed            for(uint32_t j = 0; j < list->numHwLayers; j++) {
10089f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed                if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
10189f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed                    list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
10289f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed            }
10389f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed        }
1046457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah
1056457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        if(ctx->mFBUpdate[i])
1066457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah            ctx->mFBUpdate[i]->reset();
107b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        if(ctx->mMDPComp[i])
108b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            ctx->mMDPComp[i]->reset();
1096c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        if(ctx->mCopyBit[i])
1106c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R            ctx->mCopyBit[i]->reset();
1111e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah        if(ctx->mLayerRotMap[i])
1121e2af0f047ca851e6063729239bc82c6b4a78b42Saurabh Shah            ctx->mLayerRotMap[i]->reset();
1133e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
114d80659c540b719660c7af9f530445268bc409db6Saurabh Shah
115d80659c540b719660c7af9f530445268bc409db6Saurabh Shah    ctx->mAD->reset();
1163e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
1173e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
11865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed//clear prev layer prop flags and realloc for current frame
1196ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shahstatic void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers) {
12065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    if(ctx->layerProp[dpy]) {
12165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed       delete[] ctx->layerProp[dpy];
12265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed       ctx->layerProp[dpy] = NULL;
12365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed    }
1246ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah    ctx->layerProp[dpy] = new LayerProp[numAppLayers];
12565bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed}
12665bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
1274f4c03bfb459159490795165a191e01c564e5788Saurabh Shahstatic void handleGeomChange(hwc_context_t *ctx, int dpy,
1284f4c03bfb459159490795165a191e01c564e5788Saurabh Shah        hwc_display_contents_1_t *list) {
1294f4c03bfb459159490795165a191e01c564e5788Saurabh Shah    if(list->flags & HWC_GEOMETRY_CHANGED) {
1304f4c03bfb459159490795165a191e01c564e5788Saurabh Shah        ctx->mOverlay->forceSet(dpy);
1314f4c03bfb459159490795165a191e01c564e5788Saurabh Shah    }
1324f4c03bfb459159490795165a191e01c564e5788Saurabh Shah}
1334f4c03bfb459159490795165a191e01c564e5788Saurabh Shah
13493393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaranstatic int display_commit(hwc_context_t *ctx, int dpy) {
13593393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran    int fbFd = ctx->dpyAttr[dpy].fd;
13693393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran    if(fbFd == -1) {
13793393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran        ALOGE("%s: Invalid FB fd for display: %d", __FUNCTION__, dpy);
13893393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran        return -1;
13993393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran    }
14093393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran
14193393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran    struct mdp_display_commit commit_info;
14293393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran    memset(&commit_info, 0, sizeof(struct mdp_display_commit));
14393393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran    commit_info.flags = MDP_DISPLAY_COMMIT_OVERLAY;
14493393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran    if(ioctl(fbFd, MSMFB_DISPLAY_COMMIT, &commit_info) == -1) {
14593393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran       ALOGE("%s: MSMFB_DISPLAY_COMMIT for primary failed", __FUNCTION__);
14693393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran       return -errno;
14793393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran    }
14893393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran    return 0;
14993393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran}
15093393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran
1513e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_prepare_primary(hwc_composer_device_1 *dev,
1523e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        hwc_display_contents_1_t *list) {
153d79de9b08a0d1affb272dcfb37062bd42c6540e8Naseer Ahmed    ATRACE_CALL();
1543e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
1556457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    const int dpy = HWC_DISPLAY_PRIMARY;
1566ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
1576ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah            ctx->dpyAttr[dpy].isActive) {
1586ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
1594f4c03bfb459159490795165a191e01c564e5788Saurabh Shah        handleGeomChange(ctx, dpy, list);
16030f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah        setListStats(ctx, list, dpy);
16130f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah        if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
16230f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah            const int fbZ = 0;
16330f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah            ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZ);
16430f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah        }
16530f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah        if (ctx->mMDP.version < qdutils::MDP_V4_0) {
16630f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah            if(ctx->mCopyBit[dpy])
16730f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
1683e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
1693e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
1703e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
1713e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
1723e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
1733e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_prepare_external(hwc_composer_device_1 *dev,
174b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        hwc_display_contents_1_t *list) {
175843b225b518ca5495aab3a4a5eddba5fb60381ecRaj kamal
176d79de9b08a0d1affb272dcfb37062bd42c6540e8Naseer Ahmed    ATRACE_CALL();
1773e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
178b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    const int dpy = HWC_DISPLAY_EXTERNAL;
179c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
1806ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
1816ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah            ctx->dpyAttr[dpy].isActive &&
1826ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah            ctx->dpyAttr[dpy].connected) {
1836ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
1844f4c03bfb459159490795165a191e01c564e5788Saurabh Shah        handleGeomChange(ctx, dpy, list);
1853a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar        if(!ctx->dpyAttr[dpy].isPause) {
18630f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah            ctx->dpyAttr[dpy].isConfiguring = false;
18730f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah            setListStats(ctx, list, dpy);
18830f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah            if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
18930f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah                const int fbZ = 0;
19030f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah                ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZ);
19130f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah            }
19285530ac7d0a1a8961320ca9c7de6adafcff3be08Saurabh Shah
19330f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah            /* Temporarily commenting out C2D until we support partial
19430f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah               copybit composition for mixed mode MDP
19585530ac7d0a1a8961320ca9c7de6adafcff3be08Saurabh Shah
19630f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah               if((fbZOrder >= 0) && ctx->mCopyBit[dpy])
19730f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah               ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
19830f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah             */
1993a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar        } else {
2003a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            // External Display is in Pause state.
2013a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            // ToDo:
2023a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            // Mark all application layers as OVERLAY so that
2033a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            // GPU will not compose. This is done for power
2043a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar            // optimization
205c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        }
2063e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
2073e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
208649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah}
209649cda6710c01fbc4259f8ab61aff2cdb05b242cSaurabh Shah
2102ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmedstatic int hwc_prepare_virtual(hwc_composer_device_1 *dev,
211b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        hwc_display_contents_1_t *list) {
212d79de9b08a0d1affb272dcfb37062bd42c6540e8Naseer Ahmed    ATRACE_CALL();
213b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
214b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    const int dpy = HWC_DISPLAY_VIRTUAL;
215b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah
2162cacc353e699139eb7966576fe33f48e74c09e26Jesse Hall    if (list && list->outbuf && list->numHwLayers > 0) {
217b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
218b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        uint32_t last = list->numHwLayers - 1;
219b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
22030f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah        int fbWidth = 0, fbHeight = 0;
22130f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah        getLayerResolution(fbLayer, fbWidth, fbHeight);
22230f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah        ctx->dpyAttr[dpy].xres = fbWidth;
22330f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah        ctx->dpyAttr[dpy].yres = fbHeight;
22430f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah
22530f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah        if(ctx->dpyAttr[dpy].connected == false) {
22630f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah            ctx->dpyAttr[dpy].connected = true;
22730f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah            setupSecondaryObjs(ctx, dpy);
22830f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah        }
229b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah
23030f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah        ctx->dpyAttr[dpy].fd = Writeback::getInstance()->getFbFd();
2318f1c93c4d5c2feb515cde2a6ecc2309188002cbeSaurabh Shah        private_handle_t *ohnd = (private_handle_t *)list->outbuf;
2328f1c93c4d5c2feb515cde2a6ecc2309188002cbeSaurabh Shah        Writeback::getInstance()->configureDpyInfo(ohnd->width, ohnd->height);
23330f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah        setListStats(ctx, list, dpy);
234b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah
23530f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah        if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
23630f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah            const int fbZ = 0;
23730f8aae831920b8bbdca1fbb199ac88973bf9af4Saurabh Shah            ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZ);
238b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        }
239b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    }
2402ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmed    return 0;
2412ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmed}
2422ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmed
2435b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
2445b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                       hwc_display_contents_1_t** displays)
24529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
2463e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
24729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
2480ddfa307452987336b5ec22967ba701c221f8402Saurabh Shah    //Will be unlocked at the end of set
24901f9a13e06f5b25788dfb042d20583ce2f974579Saurabh Shah    ctx->mDrawLock.lock();
25089f9d5d65dc4f3ef2bea3d3b091069cb6af0fc38Naseer Ahmed    reset(ctx, numDisplays, displays);
25156f610dd235b577725198e9341caae92379fdf23Saurabh Shah
252d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed    ctx->mOverlay->configBegin();
25336963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    ctx->mRotMgr->configBegin();
2545ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    overlay::Writeback::configBegin();
2555ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah
2565fe3925fe5a04f1fe519f64e973a1e5da4932d03Saurabh Shah    Overlay::setDMAMode(Overlay::DMA_LINE_MODE);
25756f610dd235b577725198e9341caae92379fdf23Saurabh Shah
258b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    //Cleanup virtual display objs, since there is no explicit disconnect
259b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected &&
260b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        (numDisplays <= HWC_NUM_PHYSICAL_DISPLAY_TYPES ||
261b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        displays[HWC_DISPLAY_VIRTUAL] == NULL)) {
262b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected = false;
263b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        clearSecondaryObjs(ctx, HWC_DISPLAY_VIRTUAL);
264b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    }
265b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah
2662ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmed    for (int32_t i = numDisplays - 1; i >= 0; i--) {
26765bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        hwc_display_contents_1_t *list = displays[i];
26865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        switch(i) {
26965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            case HWC_DISPLAY_PRIMARY:
27065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                ret = hwc_prepare_primary(dev, list);
27165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                break;
27265bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            case HWC_DISPLAY_EXTERNAL:
273b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                ret = hwc_prepare_external(dev, list);
27465bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                break;
2752ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmed            case HWC_DISPLAY_VIRTUAL:
276b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                ret = hwc_prepare_virtual(dev, list);
2772ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmed                break;
27865bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            default:
27965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed                ret = -EINVAL;
28029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
28129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
282d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed
2836457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    ctx->mOverlay->configDone();
28436963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    ctx->mRotMgr->configDone();
2855ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah    overlay::Writeback::configDone();
28636963690317abceae79621f14ba41ff62b3ff489Saurabh Shah
2873e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return ret;
28829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
28929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2905b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
29105207f5a7575e59e5f22bb9de46f3b6b6ce2cb8dNaseer Ahmed                             int event, int enable)
29272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed{
293d79de9b08a0d1affb272dcfb37062bd42c6540e8Naseer Ahmed    ATRACE_CALL();
29472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    int ret = 0;
29572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
29672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    switch(event) {
29772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        case HWC_EVENT_VSYNC:
298742ad624e555511b687879e1b3256ee21bf7f9bfNaseer Ahmed            if(!ctx->dpyAttr[dpy].isActive) {
299742ad624e555511b687879e1b3256ee21bf7f9bfNaseer Ahmed                ALOGE("Display is blanked - Cannot %s vsync",
300742ad624e555511b687879e1b3256ee21bf7f9bfNaseer Ahmed                        enable ? "enable" : "disable");
301742ad624e555511b687879e1b3256ee21bf7f9bfNaseer Ahmed                return -EINVAL;
302742ad624e555511b687879e1b3256ee21bf7f9bfNaseer Ahmed            }
303742ad624e555511b687879e1b3256ee21bf7f9bfNaseer Ahmed
30405207f5a7575e59e5f22bb9de46f3b6b6ce2cb8dNaseer Ahmed            if (ctx->vstate.enable == enable)
3051ef881ceed7b39b4034adba23368c2006bfd074cOmprakash Dhyade                break;
30605207f5a7575e59e5f22bb9de46f3b6b6ce2cb8dNaseer Ahmed            ret = hwc_vsync_control(ctx, dpy, enable);
307c2f61ab1d7cc647126b30c4793d700299e90f192Naseer Ahmed            if(ret == 0)
30805207f5a7575e59e5f22bb9de46f3b6b6ce2cb8dNaseer Ahmed                ctx->vstate.enable = !!enable;
309eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
31005207f5a7575e59e5f22bb9de46f3b6b6ce2cb8dNaseer Ahmed                      (enable)?"ENABLED":"DISABLED");
311eac8965bf481a17c6bca291c0864d0eb3c0eac07Iliyan Malchev            break;
31272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        default:
31372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed            ret = -EINVAL;
31472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    }
31572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    return ret;
31672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed}
31772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
3185b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
3195b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed{
3206195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed    ATRACE_CALL();
321934790c2fc35a02925f7abd872f16d3baa628712Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
32293393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran
32301f9a13e06f5b25788dfb042d20583ce2f974579Saurabh Shah    Locker::Autolock _l(ctx->mDrawLock);
3243e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
325814812663bf173ab5aecd06a228b4a3afcce9798Naseer Ahmed    ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__,
32605207f5a7575e59e5f22bb9de46f3b6b6ce2cb8dNaseer Ahmed          blank==1 ? "Blanking":"Unblanking", dpy);
3276d1d1d5fe4f4ae7f6ba558f17904aa13b3f0da16Naseer Ahmed    if (blank || (dpy == HWC_DISPLAY_PRIMARY &&
3286d1d1d5fe4f4ae7f6ba558f17904aa13b3f0da16Naseer Ahmed        !ctx->dpyAttr[dpy].isActive )) {
3297538c70d6707dbe6acfdf621d5abf2ae4ff8f9b8Arun Kumar K.R        // free up all the overlay pipes in use
3307538c70d6707dbe6acfdf621d5abf2ae4ff8f9b8Arun Kumar K.R        // when we get a blank for either display
3317538c70d6707dbe6acfdf621d5abf2ae4ff8f9b8Arun Kumar K.R        // makes sure that all pipes are freed
3327538c70d6707dbe6acfdf621d5abf2ae4ff8f9b8Arun Kumar K.R        ctx->mOverlay->configBegin();
3337538c70d6707dbe6acfdf621d5abf2ae4ff8f9b8Arun Kumar K.R        ctx->mOverlay->configDone();
3347538c70d6707dbe6acfdf621d5abf2ae4ff8f9b8Arun Kumar K.R        ctx->mRotMgr->clear();
3355ceb9c6a763418d5e0cf5da4e74b7a7c733fb4b1Saurabh Shah        overlay::Writeback::clear();
3367538c70d6707dbe6acfdf621d5abf2ae4ff8f9b8Arun Kumar K.R    }
3373e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    switch(dpy) {
3383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_PRIMARY:
3393e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            if(blank) {
3407538c70d6707dbe6acfdf621d5abf2ae4ff8f9b8Arun Kumar K.R                ret = ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK,
3417538c70d6707dbe6acfdf621d5abf2ae4ff8f9b8Arun Kumar K.R                            FB_BLANK_POWERDOWN);
3423e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            } else {
34393393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran                ret = ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK,FB_BLANK_UNBLANK);
3443e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            }
3453e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
3463e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_EXTERNAL:
3473a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar        case HWC_DISPLAY_VIRTUAL:
3483e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            if(blank) {
34993393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran                // call external framebuffer commit on blank,
35093393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran                // so that any pipe unsets gets committed
35193393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran                if (display_commit(ctx, dpy) < 0) {
3520e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R                    ret = -1;
353b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                    ALOGE("%s:post failed for dpy %d",
354b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                          __FUNCTION__, dpy);
3550e1c2eacd284d16c49908c11187ad3703b227cafArun Kumar K.R                }
3563e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            } else {
3573e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            }
3583e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
3593e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        default:
3603e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            return -EINVAL;
3613e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
36205207f5a7575e59e5f22bb9de46f3b6b6ce2cb8dNaseer Ahmed    if(ret == 0){
36305207f5a7575e59e5f22bb9de46f3b6b6ce2cb8dNaseer Ahmed        ctx->dpyAttr[dpy].isActive = !blank;
36405207f5a7575e59e5f22bb9de46f3b6b6ce2cb8dNaseer Ahmed    } else {
36505207f5a7575e59e5f22bb9de46f3b6b6ce2cb8dNaseer Ahmed        ALOGE("%s: Failed in %s display: %d error:%s", __FUNCTION__,
36605207f5a7575e59e5f22bb9de46f3b6b6ce2cb8dNaseer Ahmed              blank==1 ? "blanking":"unblanking", dpy, strerror(errno));
3673e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        return ret;
3685b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    }
36905207f5a7575e59e5f22bb9de46f3b6b6ce2cb8dNaseer Ahmed
370814812663bf173ab5aecd06a228b4a3afcce9798Naseer Ahmed    ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__,
37105207f5a7575e59e5f22bb9de46f3b6b6ce2cb8dNaseer Ahmed          blank==1 ? "blanking":"unblanking", dpy);
3725b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    return 0;
3735b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed}
3745b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed
3755b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_query(struct hwc_composer_device_1* dev,
37672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed                     int param, int* value)
37772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed{
37872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
3793e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int supported = HWC_DISPLAY_PRIMARY_BIT;
38072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
38172cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    switch (param) {
38272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    case HWC_BACKGROUND_LAYER_SUPPORTED:
38372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        // Not supported for now
38472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        value[0] = 0;
38572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        break;
386b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    case HWC_DISPLAY_TYPES_SUPPORTED: //Unused by f/w
387b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        if(ctx->mMDP.hasOverlay) {
388b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            supported |= HWC_DISPLAY_VIRTUAL_BIT;
389b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            if(!qdutils::MDPVersion::getInstance().is8x26())
390b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                supported |= HWC_DISPLAY_EXTERNAL_BIT;
391b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        }
3923e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        value[0] = supported;
3933e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        break;
39472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    default:
39572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        return -EINVAL;
39672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    }
39772cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed    return 0;
39872cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
39972cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed}
40072cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
40193393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran
4023e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
4036195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed    ATRACE_CALL();
404eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    int ret = 0;
4056457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah    const int dpy = HWC_DISPLAY_PRIMARY;
406eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah
407a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
408c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        uint32_t last = list->numHwLayers - 1;
409c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
4106c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        int fd = -1; //FenceFD from the Copybit(valid in async mode)
4116195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed        bool copybitDone = false;
4126c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        if(ctx->mCopyBit[dpy])
4136195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
414a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar        if(list->numHwLayers > 1)
415a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar            hwc_sync(ctx, list, dpy, fd);
41685530ac7d0a1a8961320ca9c7de6adafcff3be08Saurabh Shah
41785530ac7d0a1a8961320ca9c7de6adafcff3be08Saurabh Shah        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
41836963690317abceae79621f14ba41ff62b3ff489Saurabh Shah            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
41965bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            ret = -1;
42065bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed        }
42165bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed
4223e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        //TODO We dont check for SKIP flag on this layer because we need PAN
4233e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        //always. Last layer is always FB
4246ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
4256195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed        if(copybitDone) {
4266195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
4276195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed        }
4286ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah
4296ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah        if(hnd) {
4306ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
4316ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah                ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
4326ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah                ret = -1;
43365bb464dab7f1b35ffd4dda11a3d16885bbadf2dNaseer Ahmed            }
434677311f0bc4a8716e86880d29a6b8051e4389da1Saurabh Shah        }
43593393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran
43693393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran        if (display_commit(ctx, dpy) < 0) {
43793393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran            ALOGE("%s: display commit fail!", __FUNCTION__);
43876739f6c3dc9867ff6374c18c96a4eb056678238Ramkumar Radhakrishnan            ret = -1;
4393e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
4403e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
4410859ab4be38e5874f6990c6d8b41b2576a7375a3Saurabh Shah
442b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    closeAcquireFds(list, dpy);
443eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    return ret;
4443e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
4453e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4463e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahstatic int hwc_set_external(hwc_context_t *ctx,
447b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        hwc_display_contents_1_t* list)
4486195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed{
4496195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed    ATRACE_CALL();
450eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    int ret = 0;
451b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    const int dpy = HWC_DISPLAY_EXTERNAL;
452c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
453a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
4543a85d3e5b8f689cb3a3ef7ef1ce50c1e01afae1aAmara Venkata Mastan Manoj Kumar        !ctx->dpyAttr[dpy].isPause &&
4556457316fc7ae8ea29d763edce3fc1ffc78dd7387Saurabh Shah        ctx->dpyAttr[dpy].connected) {
4563e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t last = list->numHwLayers - 1;
457c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
4586c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        int fd = -1; //FenceFD from the Copybit(valid in async mode)
4596195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed        bool copybitDone = false;
4606c43ebed229c5d1e00c6d41638cd2f8e3cb979b7Arun Kumar K.R        if(ctx->mCopyBit[dpy])
4616195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
462c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
463a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar        if(list->numHwLayers > 1)
464a6a534a85c27f23f74d12da1423c7dfacdc90662Amara Venkata Mastan Manoj Kumar            hwc_sync(ctx, list, dpy, fd);
465c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
46685530ac7d0a1a8961320ca9c7de6adafcff3be08Saurabh Shah        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
46785530ac7d0a1a8961320ca9c7de6adafcff3be08Saurabh Shah            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
468eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            ret = -1;
469eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
470c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
4716ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
4726195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed        if(copybitDone) {
4736195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
4746195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed        }
4756195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed
4766ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah        if(hnd) {
4776195b7af4c83ba34d713d8e2dd5b075a8896f61eNaseer Ahmed            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
478d551ebe2cb65d9da47d3e25f6004b8870afec8b4Naseer Ahmed                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
479eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah                ret = -1;
480eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah            }
481eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah        }
48293393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran
48393393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran        if (display_commit(ctx, dpy) < 0) {
48493393d36207ef501e851c98491befd9e528b6b1aJeykumar Sankaran            ALOGE("%s: display commit fail!", __FUNCTION__);
4856ff21c1cb103978d544227d64577ce230696a3d7Saurabh Shah            ret = -1;
4863e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
4873e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
4880859ab4be38e5874f6990c6d8b41b2576a7375a3Saurabh Shah
489b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    closeAcquireFds(list, dpy);
490eaf679142b75c55735e33bdd9ddd26d8294c4070Saurabh Shah    return ret;
4913e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
4923e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
4932ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmedstatic int hwc_set_virtual(hwc_context_t *ctx,
494b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        hwc_display_contents_1_t* list) {
495b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    ATRACE_CALL();
496b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    int ret = 0;
497b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    const int dpy = HWC_DISPLAY_VIRTUAL;
498b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah
4992cacc353e699139eb7966576fe33f48e74c09e26Jesse Hall    if (list && list->outbuf && list->numHwLayers > 0) {
500b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        uint32_t last = list->numHwLayers - 1;
501b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
502b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah
503b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        if(fbLayer->handle && ctx->dpyAttr[dpy].connected
504b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah#ifndef FORCE_HWC_FOR_VIRTUAL_DISPLAYS
505b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                //XXX: If we're not forcing virtual via HWC,
506b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                //full GLES compositions will not be routed through here.
507b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                && !isGLESOnlyComp(ctx, dpy)
508b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah#endif
509b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        ) {
510b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah
511b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            private_handle_t *ohnd = (private_handle_t *)list->outbuf;
5122d3fc4ca3f32c5621b15cc7f7b7f895e29f9a09bNaseer Ahmed            int format = ohnd->format;
5132d3fc4ca3f32c5621b15cc7f7b7f895e29f9a09bNaseer Ahmed            if (format == HAL_PIXEL_FORMAT_RGBA_8888)
5142d3fc4ca3f32c5621b15cc7f7b7f895e29f9a09bNaseer Ahmed                format = HAL_PIXEL_FORMAT_RGBX_8888;
515b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            Writeback::getInstance()->setOutputFormat(
5162d3fc4ca3f32c5621b15cc7f7b7f895e29f9a09bNaseer Ahmed                    utils::getMdpFormat(format));
517b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah
518b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            int fd = -1; //FenceFD from the Copybit
519b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            hwc_sync(ctx, list, dpy, fd);
520b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah
521b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
522b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                ALOGE("%s: MDPComp draw failed", __FUNCTION__);
523b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                ret = -1;
524b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            }
525b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah
526b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            if (!ctx->mFBUpdate[dpy]->draw(ctx,
527b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                        (private_handle_t *)fbLayer->handle)) {
528b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
529b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                ret = -1;
530b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            }
531b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah
532b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            Writeback::getInstance()->queueBuffer(ohnd->fd, ohnd->offset);
533b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            if (display_commit(ctx, dpy) < 0) {
534b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                ALOGE("%s: display commit fail!", __FUNCTION__);
535b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                ret = -1;
536b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            }
537b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        } else if(list->outbufAcquireFenceFd >= 0) {
538b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            //If we dont handle the frame, set retireFenceFd to outbufFenceFd,
539b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            //which will make sure, the framework waits on it and closes it.
540b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            //The other way is to wait on outbufFenceFd ourselves, close it and
541b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            //set retireFenceFd to -1. Since we want hwc to be async, choosing
542b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            //the former.
543b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            //Also dup because, the closeAcquireFds() will close the outbufFence
544b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah            list->retireFenceFd = dup(list->outbufAcquireFenceFd);
545b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah        }
546665dfb63994cc0a0040e685ed750673e2bc5ed0dJesse Hall    }
547b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah
548b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    closeAcquireFds(list, dpy);
549b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah    return ret;
5502ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmed}
5512ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmed
5522ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmed
5535b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmedstatic int hwc_set(hwc_composer_device_1 *dev,
5545b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                   size_t numDisplays,
5555b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed                   hwc_display_contents_1_t** displays)
55629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
55729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int ret = 0;
55829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
5592ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmed    for (uint32_t i = 0; i < numDisplays; i++) {
5605b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed        hwc_display_contents_1_t* list = displays[i];
5613e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        switch(i) {
5623e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            case HWC_DISPLAY_PRIMARY:
5633e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = hwc_set_primary(ctx, list);
564c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                break;
5653e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            case HWC_DISPLAY_EXTERNAL:
566b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                ret = hwc_set_external(ctx, list);
567c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                break;
5682ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmed            case HWC_DISPLAY_VIRTUAL:
569b434b98715e4bfe9b8bfb0ac34f33e695aa9891dSaurabh Shah                ret = hwc_set_virtual(ctx, list);
5702ab5edab12c720e4ba4317d1cae9e6370ccb2067Naseer Ahmed                break;
5713e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            default:
5723e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                ret = -EINVAL;
5735b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed        }
5743e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
57516292d0097fa8f455a2a7b10b6af5144b7def9ddNaseer Ahmed    // This is only indicative of how many times SurfaceFlinger posts
57616292d0097fa8f455a2a7b10b6af5144b7def9ddNaseer Ahmed    // frames to the display.
57716292d0097fa8f455a2a7b10b6af5144b7def9ddNaseer Ahmed    CALC_FPS();
5784e9a6fcae996778da1343e41693788f27af450faSaurabh Shah    MDPComp::resetIdleFallBack();
57904af919f7d16572b16a91d8b681afe42386fb4e1Saurabh Shah    ctx->mVideoTransFlag = false;
5800ddfa307452987336b5ec22967ba701c221f8402Saurabh Shah    //Was locked at the beginning of prepare
58101f9a13e06f5b25788dfb042d20583ce2f974579Saurabh Shah    ctx->mDrawLock.unlock();
5823e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return ret;
5833e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
584f48aef64b218d42bd2ede62dcb03a3d7831ebbf9Naseer Ahmed
5853e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahint hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
5863e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t* configs, size_t* numConfigs) {
5873e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    int ret = 0;
588c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
5893e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //in 1.1 there is no way to choose a config, report as config id # 0
5903e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //This config is passed to getDisplayAttributes. Ignore for now.
5913e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    switch(disp) {
5923e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_PRIMARY:
593c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            if(*numConfigs > 0) {
594c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                configs[0] = 0;
595c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                *numConfigs = 1;
596c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            }
597c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ret = 0; //NO_ERROR
5983e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
5993e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_EXTERNAL:
600c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ret = -1; //Not connected
601c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
602c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                ret = 0; //NO_ERROR
603c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                if(*numConfigs > 0) {
604c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    configs[0] = 0;
605c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    *numConfigs = 1;
606c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                }
607c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            }
6083e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
6095b6708ac87dc9681b3dd142b82702a8b995c6e22Naseer Ahmed    }
61029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return ret;
61129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
61229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6133e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shahint hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
6143e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        uint32_t config, const uint32_t* attributes, int32_t* values) {
6153e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
6163e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
617c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    //If hotpluggable displays are inactive return error
618c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
619c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah        return -1;
620c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah    }
621c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah
6223e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    //From HWComposer
6233e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    static const uint32_t DISPLAY_ATTRIBUTES[] = {
6243e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_VSYNC_PERIOD,
6253e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_WIDTH,
6263e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_HEIGHT,
6273e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_DPI_X,
6283e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_DPI_Y,
6293e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        HWC_DISPLAY_NO_ATTRIBUTE,
6303e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    };
6313e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
6323e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
6333e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            sizeof(DISPLAY_ATTRIBUTES)[0]);
6343e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
6353e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
6363e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        switch (attributes[i]) {
6373e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_VSYNC_PERIOD:
6383e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].vsync_period;
6393e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
6403e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_WIDTH:
6413e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].xres;
642c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
643c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    ctx->dpyAttr[disp].xres);
6443e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
6453e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_HEIGHT:
6463e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            values[i] = ctx->dpyAttr[disp].yres;
647c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
648c4d034f4b8d12953632907d30c0b78856d829579Saurabh Shah                    ctx->dpyAttr[disp].yres);
6493e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
6503e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_DPI_X:
6517b80d9c8cb345f7020093e0afb691bf3a72deec6Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
6523e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
6533e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        case HWC_DISPLAY_DPI_Y:
6547b80d9c8cb345f7020093e0afb691bf3a72deec6Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
6553e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            break;
6563e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        default:
6573e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            ALOGE("Unknown display attribute %d",
6583e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah                    attributes[i]);
6593e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah            return -EINVAL;
6603e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        }
6613e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    }
6623e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah    return 0;
6633e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah}
6643e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah
6653b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmedvoid hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
6663b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed{
6673b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
66801f9a13e06f5b25788dfb042d20583ce2f974579Saurabh Shah    Locker::Autolock _l(ctx->mDrawLock);
669f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    android::String8 aBuf("");
670f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    dumpsys_log(aBuf, "Qualcomm HWC state:\n");
671f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
672f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
67385530ac7d0a1a8961320ca9c7de6adafcff3be08Saurabh Shah    for(int dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
67485530ac7d0a1a8961320ca9c7de6adafcff3be08Saurabh Shah        if(ctx->mMDPComp[dpy])
67585530ac7d0a1a8961320ca9c7de6adafcff3be08Saurabh Shah            ctx->mMDPComp[dpy]->dump(aBuf);
67685530ac7d0a1a8961320ca9c7de6adafcff3be08Saurabh Shah    }
677f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    char ovDump[2048] = {'\0'};
678f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    ctx->mOverlay->getDump(ovDump, 2048);
679f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    dumpsys_log(aBuf, ovDump);
68036963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    ovDump[0] = '\0';
68189cadba6f59425c741d9f376a1f407fcb3bae675Saurabh Shah    ctx->mRotMgr->getDump(ovDump, 1024);
68236963690317abceae79621f14ba41ff62b3ff489Saurabh Shah    dumpsys_log(aBuf, ovDump);
683103c736926cace1ff5a6d154715b375ff1018f8eSaurabh Shah    ovDump[0] = '\0';
68422af1a294d360a5e92cf3e2e3626b5f332166bbeSaurabh Shah    if(Writeback::getDump(ovDump, 1024)) {
68522af1a294d360a5e92cf3e2e3626b5f332166bbeSaurabh Shah        dumpsys_log(aBuf, ovDump);
68622af1a294d360a5e92cf3e2e3626b5f332166bbeSaurabh Shah        ovDump[0] = '\0';
68722af1a294d360a5e92cf3e2e3626b5f332166bbeSaurabh Shah    }
688f48c59032a351cda58b2057423b2646423acd7c7Saurabh Shah    strlcpy(buff, aBuf.string(), buff_len);
6893b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed}
6903b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed
69129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_close(struct hw_device_t *dev)
69229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
69329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(!dev) {
69472cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        ALOGE("%s: NULL device pointer", __FUNCTION__);
69529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -1;
69629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
69729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    closeContext((hwc_context_t*)dev);
69829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    free(dev);
69929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
70029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
70129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
70229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
70329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module, const char* name,
70429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           struct hw_device_t** device)
70529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
70629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = -EINVAL;
70729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
70829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
70929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct hwc_context_t *dev;
71029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dev = (hwc_context_t*)malloc(sizeof(*dev));
71129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        memset(dev, 0, sizeof(*dev));
71272cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
71372cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        //Initialize hwc context
71429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        initContext(dev);
71572cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed
71672cf9762f84aab07faab86e35fe830b63ec54d72Naseer Ahmed        //Setup HWC methods
7173e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
71883f9f73c45da200a06244749e4f21a632ecc01baJesse Hall        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_3;
7193e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.module       = const_cast<hw_module_t*>(module);
7203e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.common.close        = hwc_device_close;
7213e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.prepare             = hwc_prepare;
7223e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.set                 = hwc_set;
7233e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.eventControl        = hwc_eventControl;
7243e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.blank               = hwc_blank;
7253e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.query               = hwc_query;
7263e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.registerProcs       = hwc_registerProcs;
7273b21dd5bc0f86209d9ea134523a494cfe9da601cNaseer Ahmed        dev->device.dump                = hwc_dump;
7283e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
7293e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
7303e858ebde3f2b4e762af8f7f2808d45ba59b890dSaurabh Shah        *device = &dev->device.common;
73129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = 0;
73229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
73329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
73429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
735