hwc.cpp revision 3ffc467822ce99b148d842c13dc22e1889ba0241
1befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*
2befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Copyright (C) 2010 The Android Open Source Project
33ffc467822ce99b148d842c13dc22e1889ba0241Arun Kumar K.R * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
4befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
5befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License");
6befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * you may not use this file except in compliance with the License.
7befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * You may obtain a copy of the License at
8befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
9befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *      http://www.apache.org/licenses/LICENSE-2.0
10befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
11befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Unless required by applicable law or agreed to in writing, software
12befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS,
13befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * See the License for the specific language governing permissions and
15befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * limitations under the License.
16befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
17befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
18befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <fcntl.h>
19befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <errno.h>
20befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
21befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <cutils/log.h>
22befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <cutils/atomic.h>
231589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed#include <EGL/egl.h>
24befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
251589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed#include <overlay.h>
261589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed#include <fb_priv.h>
27b3c6e058ce1dbc689f27e7d7acbf1529d37307d8Naseer Ahmed#include <mdp_version.h>
28befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include "hwc_utils.h"
29ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed#include "hwc_video.h"
3047377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed#include "hwc_fbupdate.h"
3116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed#include "hwc_mdpcomp.h"
32bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah#include "external.h"
33befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
34befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedusing namespace qhwc;
3547377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed#define VSYNC_DEBUG 0
36befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
37befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module,
38befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                           const char* name,
39befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                           struct hw_device_t** device);
40befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
41befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic struct hw_module_methods_t hwc_module_methods = {
42befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    open: hwc_device_open
43befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
44befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
45befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedhwc_module_t HAL_MODULE_INFO_SYM = {
46befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    common: {
47befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        tag: HARDWARE_MODULE_TAG,
48befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        version_major: 2,
49befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        version_minor: 0,
50befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        id: HWC_HARDWARE_MODULE_ID,
51befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        name: "Qualcomm Hardware Composer Module",
52befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        author: "CodeAurora Forum",
53befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        methods: &hwc_module_methods,
54befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dso: 0,
55befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        reserved: {0},
56befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
57befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
58befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
59befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*
60befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Save callback functions registered to HWC
61befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
62660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic void hwc_registerProcs(struct hwc_composer_device_1* dev,
63befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              hwc_procs_t const* procs)
64befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
658eb66cfb97ccc186e9f4ae5f38e8d8f6087ae5b7Iliyan Malchev    ALOGI("%s", __FUNCTION__);
66befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
67befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!ctx) {
68befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: Invalid context", __FUNCTION__);
69befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return;
70befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
71359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall    ctx->proc = procs;
72359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall
73aff82051a79fbaf752d3769667d34828cee2841dNaseer Ahmed    // Now that we have the functions needed, kick off
74aff82051a79fbaf752d3769667d34828cee2841dNaseer Ahmed    // the uevent & vsync threads
75359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall    init_uevent_thread(ctx);
76aff82051a79fbaf752d3769667d34828cee2841dNaseer Ahmed    init_vsync_thread(ctx);
77befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
78befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
7925322c7f78dfeb2c9c441dc0720dba6c639b198cSaurabh Shah//Helper
809f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmedstatic void reset(hwc_context_t *ctx, int numDisplays,
819f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed                  hwc_display_contents_1_t** displays) {
822e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    memset(ctx->listStats, 0, sizeof(ctx->listStats));
836e458c9164c7891d0f869a58c0ea12280c23e9caSaurabh Shah    for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++){
842e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        ctx->listStats[i].yuvIndex = -1;
859f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        hwc_display_contents_1_t *list = displays[i];
869f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        // XXX:SurfaceFlinger no longer guarantees that this
879f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        // value is reset on every prepare. However, for the layer
889f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        // cache we need to reset it.
899f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        // We can probably rethink that later on
909f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        if (LIKELY(list && list->numHwLayers > 1)) {
919f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed            for(uint32_t j = 0; j < list->numHwLayers; j++) {
929f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed                if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
939f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed                    list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
949f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed            }
959f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        }
96640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah
97640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        if(ctx->mFBUpdate[i])
98640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            ctx->mFBUpdate[i]->reset();
992e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
10047377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed    VideoOverlay::reset();
1012e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah}
1022e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
10316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed//clear prev layer prop flags and realloc for current frame
10416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedstatic void reset_layer_prop(hwc_context_t* ctx, int dpy) {
10516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    int layer_count = ctx->listStats[dpy].numAppLayers;
10616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed
10716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    if(ctx->layerProp[dpy]) {
10816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed       delete[] ctx->layerProp[dpy];
10916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed       ctx->layerProp[dpy] = NULL;
11016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    }
11116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed
11216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    if(layer_count) {
11316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed       ctx->layerProp[dpy] = new LayerProp[layer_count];
11416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    }
11516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed}
11616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed
1172e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahstatic int hwc_prepare_primary(hwc_composer_device_1 *dev,
1182e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        hwc_display_contents_1_t *list) {
1192e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
120640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah    const int dpy = HWC_DISPLAY_PRIMARY;
1216e458c9164c7891d0f869a58c0ea12280c23e9caSaurabh Shah
1226e458c9164c7891d0f869a58c0ea12280c23e9caSaurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
123640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        ctx->dpyAttr[dpy].isActive) {
1246e458c9164c7891d0f869a58c0ea12280c23e9caSaurabh Shah
125074dab343c4cfc5c77511a77247d759b10089a94Saurabh Shah        uint32_t last = list->numHwLayers - 1;
1266e458c9164c7891d0f869a58c0ea12280c23e9caSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
1276e458c9164c7891d0f869a58c0ea12280c23e9caSaurabh Shah        if(fbLayer->handle) {
128640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            setListStats(ctx, list, dpy);
129640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            reset_layer_prop(ctx, dpy);
130c18b3a0ef41fe474fe37e2e1833ef1bb11c85b11Saurabh Shah            if(!ctx->mMDPComp->prepare(ctx, list)) {
131640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah                VideoOverlay::prepare(ctx, list, dpy);
132640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah                ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
13316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            }
134640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            ctx->mLayerCache[dpy]->updateLayerCache(list);
1352e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        }
1362e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
1372e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    return 0;
1382e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah}
1392e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
1402e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahstatic int hwc_prepare_external(hwc_composer_device_1 *dev,
1412e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        hwc_display_contents_1_t *list) {
1422e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
143640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah    const int dpy = HWC_DISPLAY_EXTERNAL;
14476443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
1458cc5d853c3125df5867ce35a10d7a01dd51d48c6Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
146640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        ctx->dpyAttr[dpy].isActive &&
147640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        ctx->dpyAttr[dpy].connected) {
14876443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
14976443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        uint32_t last = list->numHwLayers - 1;
1506e458c9164c7891d0f869a58c0ea12280c23e9caSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
1516e458c9164c7891d0f869a58c0ea12280c23e9caSaurabh Shah        if(fbLayer->handle) {
152640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            setListStats(ctx, list, dpy);
153640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            reset_layer_prop(ctx, dpy);
154640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            VideoOverlay::prepare(ctx, list, dpy);
155640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
156640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            ctx->mLayerCache[dpy]->updateLayerCache(list);
157413701aeb9879f1b9ae4401def52199c6950191eAmara Venkata Mastan Manoj Kumar            ctx->mExtDispConfiguring = false;
15876443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        }
1592e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
1602e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    return 0;
16125322c7f78dfeb2c9c441dc0720dba6c639b198cSaurabh Shah}
16225322c7f78dfeb2c9c441dc0720dba6c639b198cSaurabh Shah
163660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
164660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                       hwc_display_contents_1_t** displays)
165befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1662e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    int ret = 0;
167befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
16847377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
1699f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed    reset(ctx, numDisplays, displays);
170bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah
17147377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed    ctx->mOverlay->configBegin();
172bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah
17316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    for (int32_t i = numDisplays - 1; i >= 0; i--) {
17416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed        hwc_display_contents_1_t *list = displays[i];
17516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed        switch(i) {
17616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            case HWC_DISPLAY_PRIMARY:
17716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                ret = hwc_prepare_primary(dev, list);
17816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                break;
17916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            case HWC_DISPLAY_EXTERNAL:
18016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                ret = hwc_prepare_external(dev, list);
18116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                break;
18216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            default:
18316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                ret = -EINVAL;
184befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
185befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
18647377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed
187640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah    ctx->mOverlay->configDone();
1882e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    return ret;
189befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
190befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
191660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
1921589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                             int event, int enabled)
1931589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed{
1941589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    int ret = 0;
195aff82051a79fbaf752d3769667d34828cee2841dNaseer Ahmed
1961589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
1971589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
1981589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                ctx->mFbDev->common.module);
199dc8c69a5f00ed27acab3821541e2d41d13b777bcIliyan Malchev    pthread_mutex_lock(&ctx->vstate.lock);
2001589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    switch(event) {
2011589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        case HWC_EVENT_VSYNC:
2024267d405186dccc076536208c9f428761146bae4Omprakash Dhyade            if (ctx->vstate.enable == enabled)
2034267d405186dccc076536208c9f428761146bae4Omprakash Dhyade                break;
204dc8c69a5f00ed27acab3821541e2d41d13b777bcIliyan Malchev            ctx->vstate.enable = !!enabled;
2050f5d0c11aff663c047803afcc2cb30e33bad8051Naseer Ahmed            pthread_cond_signal(&ctx->vstate.cond);
206dc8c69a5f00ed27acab3821541e2d41d13b777bcIliyan Malchev            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
207dc8c69a5f00ed27acab3821541e2d41d13b777bcIliyan Malchev                      (enabled)?"ENABLED":"DISABLED");
208dc8c69a5f00ed27acab3821541e2d41d13b777bcIliyan Malchev            break;
2091589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        default:
2101589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed            ret = -EINVAL;
2111589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    }
212dc8c69a5f00ed27acab3821541e2d41d13b777bcIliyan Malchev    pthread_mutex_unlock(&ctx->vstate.lock);
2131589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    return ret;
2141589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed}
2151589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
216660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
217660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed{
2181ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
2191ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
2201ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed        ctx->mFbDev->common.module);
22147377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
2222e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    int ret = 0;
2232e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2242e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    switch(dpy) {
2252e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_PRIMARY:
2262e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            if(blank) {
22747377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed                ctx->mOverlay->configBegin();
22847377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed                ctx->mOverlay->configDone();
2292e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN);
2302e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            } else {
2312e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK);
2322e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            }
2332e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
2342e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_EXTERNAL:
2352e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            if(blank) {
2363ffc467822ce99b148d842c13dc22e1889ba0241Arun Kumar K.R                // External Display post commits the changes to display
2373ffc467822ce99b148d842c13dc22e1889ba0241Arun Kumar K.R                // Call this on blank, so that any pipe unsets gets committed
2383ffc467822ce99b148d842c13dc22e1889ba0241Arun Kumar K.R                if (!ctx->mExtDisplay->post()) {
2393ffc467822ce99b148d842c13dc22e1889ba0241Arun Kumar K.R                    ret = -1;
2403ffc467822ce99b148d842c13dc22e1889ba0241Arun Kumar K.R                    ALOGE("%s:ctx->mExtDisplay->post fail!! ", __FUNCTION__);
2413ffc467822ce99b148d842c13dc22e1889ba0241Arun Kumar K.R                }
2422e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            } else {
2432e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            }
2442e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
2452e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        default:
2462e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            return -EINVAL;
2472e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
24871005afe9fda149b1bdd2720d0aed1414dc5a455Arun Kumar K.R    // Enable HPD here, as during bootup unblank is called
24971005afe9fda149b1bdd2720d0aed1414dc5a455Arun Kumar K.R    // when SF is completely initialized
25071005afe9fda149b1bdd2720d0aed1414dc5a455Arun Kumar K.R    ctx->mExtDisplay->setHPD(1);
2512e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
2522e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    if(ret < 0) {
2532e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        ALOGE("%s: failed. Dpy=%d, blank=%d : %s",
2542e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah                __FUNCTION__, dpy, blank, strerror(errno));
2552e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        return ret;
256660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    }
2572e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    ALOGD("%s: Done Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2582e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    ctx->dpyAttr[dpy].isActive = !blank;
259660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    return 0;
260660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed}
261660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed
262660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_query(struct hwc_composer_device_1* dev,
2631589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                     int param, int* value)
2641589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed{
2651589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
2661589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
2671589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ctx->mFbDev->common.module);
2682e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    int supported = HWC_DISPLAY_PRIMARY_BIT;
2691589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
2701589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    switch (param) {
2711589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    case HWC_BACKGROUND_LAYER_SUPPORTED:
2721589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        // Not supported for now
2731589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        value[0] = 0;
2741589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        break;
2752e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    case HWC_VSYNC_PERIOD: //Not used for hwc > 1.1
27621fe85b5b8212ac43d81f5db4b2b30f71ac048e2Saurabh Shah        value[0] = m->fps;
2771589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ALOGI("fps: %d", value[0]);
2781589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        break;
2792e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    case HWC_DISPLAY_TYPES_SUPPORTED:
28076443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        if(ctx->mMDP.hasOverlay)
28176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            supported |= HWC_DISPLAY_EXTERNAL_BIT;
2822e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        value[0] = supported;
2832e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        break;
2841589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    default:
2851589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        return -EINVAL;
2861589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    }
2871589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    return 0;
2881589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
2891589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed}
2901589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
2912e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahstatic int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
2923475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah    int ret = 0;
293640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah    const int dpy = HWC_DISPLAY_PRIMARY;
2943475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah
2958cc5d853c3125df5867ce35a10d7a01dd51d48c6Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
296640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        ctx->dpyAttr[dpy].isActive) {
29776443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        uint32_t last = list->numHwLayers - 1;
29876443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
29976443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
300640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        hwc_sync(ctx, list, dpy);
301640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        if (!VideoOverlay::draw(ctx, list, dpy)) {
3023475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
3033475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            ret = -1;
3043475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah        }
305c18b3a0ef41fe474fe37e2e1833ef1bb11c85b11Saurabh Shah        if (!ctx->mMDPComp->draw(ctx, list)) {
30616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            ALOGE("%s: MDPComp::draw fail!", __FUNCTION__);
30716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            ret = -1;
30816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed        }
30916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed
3102e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        //TODO We dont check for SKIP flag on this layer because we need PAN
3112e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        //always. Last layer is always FB
31216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
31316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
31416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            if(!(fbLayer->flags & HWC_SKIP_LAYER)) {
315640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah                if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
31616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                    ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
31716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                    ret = -1;
31816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                }
31916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            }
3203475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) {
3213475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah                ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__);
3223475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah                return -1;
3233475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            }
3242e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        }
3252e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
3263475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah    return ret;
3272e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah}
3282e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
3292e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahstatic int hwc_set_external(hwc_context_t *ctx,
3302e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        hwc_display_contents_1_t* list) {
3313475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah    int ret = 0;
332640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah    const int dpy = HWC_DISPLAY_EXTERNAL;
333640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah
334f6205c18f4bbd23e7f39672f781498c34e6b7494Kinjal Bhavsar    Locker::Autolock _l(ctx->mExtSetLock);
33576443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
3368cc5d853c3125df5867ce35a10d7a01dd51d48c6Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
337640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        ctx->dpyAttr[dpy].isActive &&
338640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        ctx->dpyAttr[dpy].connected) {
3392e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        uint32_t last = list->numHwLayers - 1;
34076443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
34176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
342640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        hwc_sync(ctx, list, dpy);
34376443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
344640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        if (!VideoOverlay::draw(ctx, list, dpy)) {
3453475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
3463475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            ret = -1;
3473475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah        }
34876443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
34976443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
350a2bfc3940f0cbf6e3a8f25d397c0335efeb4721bSaurabh Shah        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
351a2bfc3940f0cbf6e3a8f25d397c0335efeb4721bSaurabh Shah                !(fbLayer->flags & HWC_SKIP_LAYER) && hnd) {
352640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
35347377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
3543475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah                ret = -1;
3553475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            }
3563475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah        }
3573475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah        if (!ctx->mExtDisplay->post()) {
3583475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            ALOGE("%s: ctx->mExtDisplay->post fail!", __FUNCTION__);
3593475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            return -1;
3602e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        }
3612e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
3623475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah    return ret;
3632e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah}
3642e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
365660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_set(hwc_composer_device_1 *dev,
366660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                   size_t numDisplays,
367660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                   hwc_display_contents_1_t** displays)
368befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
369befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int ret = 0;
370befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
37177d8f24cb4fece120f062f2f997f018372338b66Naseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
37276443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
3732e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    for (uint32_t i = 0; i < numDisplays; i++) {
374660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        hwc_display_contents_1_t* list = displays[i];
3752e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        switch(i) {
3762e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            case HWC_DISPLAY_PRIMARY:
3772e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah                ret = hwc_set_primary(ctx, list);
37876443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                break;
3792e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            case HWC_DISPLAY_EXTERNAL:
3802e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah                ret = hwc_set_external(ctx, list);
38176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                break;
3822e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            default:
3832e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah                ret = -EINVAL;
384660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        }
3852e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
3862e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    return ret;
3872e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah}
388ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed
3892e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahint hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
3902e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        uint32_t* configs, size_t* numConfigs) {
3912e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    int ret = 0;
39276443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
3932e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    //in 1.1 there is no way to choose a config, report as config id # 0
3942e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    //This config is passed to getDisplayAttributes. Ignore for now.
3952e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    switch(disp) {
3962e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_PRIMARY:
39776443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            if(*numConfigs > 0) {
39876443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                configs[0] = 0;
39976443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                *numConfigs = 1;
40076443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            }
40176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            ret = 0; //NO_ERROR
4022e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
4032e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_EXTERNAL:
40476443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            ret = -1; //Not connected
40576443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
40676443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                ret = 0; //NO_ERROR
40776443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                if(*numConfigs > 0) {
40876443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                    configs[0] = 0;
40976443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                    *numConfigs = 1;
41076443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                }
41176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            }
4122e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
413660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    }
414befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return ret;
415befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
416befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
4172e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahint hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
4182e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        uint32_t config, const uint32_t* attributes, int32_t* values) {
4192e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
4202e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
42176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah    //If hotpluggable displays are inactive return error
42276443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah    if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
42376443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        return -1;
42476443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah    }
42576443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
4262e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    //From HWComposer
4272e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    static const uint32_t DISPLAY_ATTRIBUTES[] = {
4282e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        HWC_DISPLAY_VSYNC_PERIOD,
4292e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        HWC_DISPLAY_WIDTH,
4302e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        HWC_DISPLAY_HEIGHT,
4312e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        HWC_DISPLAY_DPI_X,
4322e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        HWC_DISPLAY_DPI_Y,
4332e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        HWC_DISPLAY_NO_ATTRIBUTE,
4342e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    };
4352e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
4362e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
4372e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            sizeof(DISPLAY_ATTRIBUTES)[0]);
4382e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
4392e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
4402e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        switch (attributes[i]) {
4412e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_VSYNC_PERIOD:
4422e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            values[i] = ctx->dpyAttr[disp].vsync_period;
4432e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
4442e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_WIDTH:
4452e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            values[i] = ctx->dpyAttr[disp].xres;
44676443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
44776443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                    ctx->dpyAttr[disp].xres);
4482e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
4492e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_HEIGHT:
4502e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            values[i] = ctx->dpyAttr[disp].yres;
45176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
45276443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                    ctx->dpyAttr[disp].yres);
4532e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
4542e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_DPI_X:
45579e14117f5e66a080b9f2a783ce3b215c72c8653Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
4562e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
4572e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_DPI_Y:
45879e14117f5e66a080b9f2a783ce3b215c72c8653Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
4592e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
4602e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        default:
4612e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            ALOGE("Unknown display attribute %d",
4622e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah                    attributes[i]);
4632e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            return -EINVAL;
4642e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        }
4652e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
4662e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    return 0;
4672e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah}
4682e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
46993138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmedvoid hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
47093138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed{
47193138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
47293138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed    android::String8 buf("");
47393138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed    dumpsys_log(buf, "Qualcomm HWC state:\n");
47493138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed    dumpsys_log(buf, "  MDPVersion=%d\n", ctx->mMDP.version);
47593138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed    dumpsys_log(buf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
476c18b3a0ef41fe474fe37e2e1833ef1bb11c85b11Saurabh Shah    ctx->mMDPComp->dump(buf);
47793138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed    //XXX: Call Other dump functions
47893138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed    strlcpy(buff, buf.string(), buff_len);
47993138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed}
48093138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed
481befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int hwc_device_close(struct hw_device_t *dev)
482befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
483befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!dev) {
4841589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ALOGE("%s: NULL device pointer", __FUNCTION__);
485befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -1;
486befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
487befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    closeContext((hwc_context_t*)dev);
488befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    free(dev);
489befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
490befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return 0;
491befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
492befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
493befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module, const char* name,
494befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                           struct hw_device_t** device)
495befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
496befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = -EINVAL;
497befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
498befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
499befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        struct hwc_context_t *dev;
500befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev = (hwc_context_t*)malloc(sizeof(*dev));
501befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memset(dev, 0, sizeof(*dev));
5021589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
5031589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        //Initialize hwc context
504befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        initContext(dev);
5051589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
5061589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        //Setup HWC methods
5072e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
5082e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_1;
5092e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.common.module       = const_cast<hw_module_t*>(module);
5102e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.common.close        = hwc_device_close;
5112e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.prepare             = hwc_prepare;
5122e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.set                 = hwc_set;
5132e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.eventControl        = hwc_eventControl;
5142e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.blank               = hwc_blank;
5152e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.query               = hwc_query;
5162e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.registerProcs       = hwc_registerProcs;
51793138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed        dev->device.dump                = hwc_dump;
5182e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
5192e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
5202e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        *device = &dev->device.common;
521befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = 0;
522befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
523befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
524befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
525