hwc.cpp revision 90571fc7c38e38858ad22a79e95efcb99c3a8b1d
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 *
54019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R * Not a Contribution, Apache license notifications and license are retained
64019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R * for attribution purposes only.
74019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R *
8befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License");
9befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * you may not use this file except in compliance with the License.
10befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * You may obtain a copy of the License at
11befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
12befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *      http://www.apache.org/licenses/LICENSE-2.0
13befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
14befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Unless required by applicable law or agreed to in writing, software
15befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS,
16befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * See the License for the specific language governing permissions and
18befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * limitations under the License.
19befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
20befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
21befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <fcntl.h>
22befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <errno.h>
23befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
24befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <cutils/log.h>
25befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <cutils/atomic.h>
261589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed#include <EGL/egl.h>
27befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
281589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed#include <overlay.h>
291589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed#include <fb_priv.h>
30b3c6e058ce1dbc689f27e7d7acbf1529d37307d8Naseer Ahmed#include <mdp_version.h>
31befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include "hwc_utils.h"
32ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed#include "hwc_video.h"
3347377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed#include "hwc_fbupdate.h"
3416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed#include "hwc_mdpcomp.h"
35bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah#include "external.h"
364019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R#include "hwc_copybit.h"
37befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
38befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedusing namespace qhwc;
3947377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed#define VSYNC_DEBUG 0
40befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
41befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module,
42befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                           const char* name,
43befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                           struct hw_device_t** device);
44befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
45befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic struct hw_module_methods_t hwc_module_methods = {
46befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    open: hwc_device_open
47befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
48befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
49befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedhwc_module_t HAL_MODULE_INFO_SYM = {
50befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    common: {
51befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        tag: HARDWARE_MODULE_TAG,
52befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        version_major: 2,
53befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        version_minor: 0,
54befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        id: HWC_HARDWARE_MODULE_ID,
55befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        name: "Qualcomm Hardware Composer Module",
56befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        author: "CodeAurora Forum",
57befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        methods: &hwc_module_methods,
58befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dso: 0,
59befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        reserved: {0},
60befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
61befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
62befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
63befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*
64befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Save callback functions registered to HWC
65befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
66660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic void hwc_registerProcs(struct hwc_composer_device_1* dev,
67befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              hwc_procs_t const* procs)
68befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
698eb66cfb97ccc186e9f4ae5f38e8d8f6087ae5b7Iliyan Malchev    ALOGI("%s", __FUNCTION__);
70befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
71befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!ctx) {
72befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: Invalid context", __FUNCTION__);
73befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return;
74befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
75359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall    ctx->proc = procs;
76359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall
77aff82051a79fbaf752d3769667d34828cee2841dNaseer Ahmed    // Now that we have the functions needed, kick off
78aff82051a79fbaf752d3769667d34828cee2841dNaseer Ahmed    // the uevent & vsync threads
79359c544e1ca5ad76be326d9ee809e7bee51f94b4Jesse Hall    init_uevent_thread(ctx);
80aff82051a79fbaf752d3769667d34828cee2841dNaseer Ahmed    init_vsync_thread(ctx);
81befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
82befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
8325322c7f78dfeb2c9c441dc0720dba6c639b198cSaurabh Shah//Helper
849f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmedstatic void reset(hwc_context_t *ctx, int numDisplays,
859f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed                  hwc_display_contents_1_t** displays) {
862e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    memset(ctx->listStats, 0, sizeof(ctx->listStats));
8790571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar    for(int i = 0; i < MAX_DISPLAYS; i++) {
889f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        hwc_display_contents_1_t *list = displays[i];
899f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        // XXX:SurfaceFlinger no longer guarantees that this
909f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        // value is reset on every prepare. However, for the layer
919f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        // cache we need to reset it.
929f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        // We can probably rethink that later on
939f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        if (LIKELY(list && list->numHwLayers > 1)) {
949f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed            for(uint32_t j = 0; j < list->numHwLayers; j++) {
959f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed                if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
969f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed                    list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
979f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed            }
989f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed        }
99640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah
100640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        if(ctx->mFBUpdate[i])
101640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            ctx->mFBUpdate[i]->reset();
1024019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R
1034019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R        if(ctx->mCopyBit[i])
1044019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R            ctx->mCopyBit[i]->reset();
1052e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
10647377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed    VideoOverlay::reset();
1072e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah}
1082e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
10916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed//clear prev layer prop flags and realloc for current frame
11016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmedstatic void reset_layer_prop(hwc_context_t* ctx, int dpy) {
11116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    int layer_count = ctx->listStats[dpy].numAppLayers;
11216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed
11316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    if(ctx->layerProp[dpy]) {
11416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed       delete[] ctx->layerProp[dpy];
11516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed       ctx->layerProp[dpy] = NULL;
11616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    }
11716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed
11816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    if(layer_count) {
11916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed       ctx->layerProp[dpy] = new LayerProp[layer_count];
12016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed    }
12116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed}
12216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed
1232e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahstatic int hwc_prepare_primary(hwc_composer_device_1 *dev,
1242e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        hwc_display_contents_1_t *list) {
1252e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
126640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah    const int dpy = HWC_DISPLAY_PRIMARY;
1276e458c9164c7891d0f869a58c0ea12280c23e9caSaurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
128640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        ctx->dpyAttr[dpy].isActive) {
1296e458c9164c7891d0f869a58c0ea12280c23e9caSaurabh Shah
130074dab343c4cfc5c77511a77247d759b10089a94Saurabh Shah        uint32_t last = list->numHwLayers - 1;
1316e458c9164c7891d0f869a58c0ea12280c23e9caSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
1326e458c9164c7891d0f869a58c0ea12280c23e9caSaurabh Shah        if(fbLayer->handle) {
133640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            setListStats(ctx, list, dpy);
134640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            reset_layer_prop(ctx, dpy);
1354019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R            int ret = ctx->mMDPComp->prepare(ctx, list);
1364019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R            if(!ret) {
1374019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R                // IF MDPcomp fails use this route
138640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah                VideoOverlay::prepare(ctx, list, dpy);
139640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah                ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
14016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            }
141640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            ctx->mLayerCache[dpy]->updateLayerCache(list);
1424019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R            // Use Copybit, when MDP comp fails
1434019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R            if(!ret && ctx->mCopyBit[dpy])
1444019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
1452e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        }
1462e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
1472e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    return 0;
1482e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah}
1492e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
1502e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahstatic int hwc_prepare_external(hwc_composer_device_1 *dev,
15190571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar        hwc_display_contents_1_t *list, int dpy) {
1522e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
15376443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
1548cc5d853c3125df5867ce35a10d7a01dd51d48c6Saurabh Shah    if (LIKELY(list && list->numHwLayers > 1) &&
155640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        ctx->dpyAttr[dpy].isActive &&
156640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        ctx->dpyAttr[dpy].connected) {
15776443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        uint32_t last = list->numHwLayers - 1;
15890571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar        if(!ctx->dpyAttr[dpy].isPause) {
15990571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar            hwc_layer_1_t *fbLayer = &list->hwLayers[last];
16090571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar            if(fbLayer->handle) {
16190571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar                setListStats(ctx, list, dpy);
16290571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar                reset_layer_prop(ctx, dpy);
16390571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar                VideoOverlay::prepare(ctx, list, dpy);
16490571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar                ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
16590571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar                ctx->mLayerCache[dpy]->updateLayerCache(list);
16690571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar                if(ctx->mCopyBit[dpy])
16790571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar                    ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
16890571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar                ctx->mExtDispConfiguring = false;
16990571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar            }
17090571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar        } else {
17190571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar            // External Display is in Pause state.
17290571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar            // ToDo:
17390571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar            // Mark all application layers as OVERLAY so that
17490571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar            // GPU will not compose. This is done for power
17590571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar            // optimization
17676443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        }
1772e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
1782e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    return 0;
17925322c7f78dfeb2c9c441dc0720dba6c639b198cSaurabh Shah}
18025322c7f78dfeb2c9c441dc0720dba6c639b198cSaurabh Shah
181660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
182660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                       hwc_display_contents_1_t** displays)
183befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1842e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    int ret = 0;
185befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
18647377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
1879f0b36a26d1c37ad0d31e59136b1e5d6f4d7efdeNaseer Ahmed    reset(ctx, numDisplays, displays);
188bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah
18947377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed    ctx->mOverlay->configBegin();
190bbee5b1c3475b630caa5061fbf535f87f21743f7Saurabh Shah
19190571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar    for (int32_t i = numDisplays; i >= 0; i--) {
19216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed        hwc_display_contents_1_t *list = displays[i];
19316791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed        switch(i) {
19416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            case HWC_DISPLAY_PRIMARY:
19516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                ret = hwc_prepare_primary(dev, list);
19616791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                break;
19716791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            case HWC_DISPLAY_EXTERNAL:
19890571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar            case HWC_DISPLAY_VIRTUAL:
19990571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar                ret = hwc_prepare_external(dev, list, i);
20016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                break;
20116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            default:
20216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                ret = -EINVAL;
203befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
204befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
20547377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed
206640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah    ctx->mOverlay->configDone();
2072e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    return ret;
208befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
209befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
210660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
2111589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                             int event, int enabled)
2121589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed{
2131589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    int ret = 0;
214aff82051a79fbaf752d3769667d34828cee2841dNaseer Ahmed
2151589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
2161589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
2171589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                ctx->mFbDev->common.module);
218dc8c69a5f00ed27acab3821541e2d41d13b777bcIliyan Malchev    pthread_mutex_lock(&ctx->vstate.lock);
2191589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    switch(event) {
2201589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        case HWC_EVENT_VSYNC:
2214267d405186dccc076536208c9f428761146bae4Omprakash Dhyade            if (ctx->vstate.enable == enabled)
2224267d405186dccc076536208c9f428761146bae4Omprakash Dhyade                break;
223dc8c69a5f00ed27acab3821541e2d41d13b777bcIliyan Malchev            ctx->vstate.enable = !!enabled;
2240f5d0c11aff663c047803afcc2cb30e33bad8051Naseer Ahmed            pthread_cond_signal(&ctx->vstate.cond);
225dc8c69a5f00ed27acab3821541e2d41d13b777bcIliyan Malchev            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
226dc8c69a5f00ed27acab3821541e2d41d13b777bcIliyan Malchev                      (enabled)?"ENABLED":"DISABLED");
227dc8c69a5f00ed27acab3821541e2d41d13b777bcIliyan Malchev            break;
2281589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        default:
2291589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed            ret = -EINVAL;
2301589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    }
231dc8c69a5f00ed27acab3821541e2d41d13b777bcIliyan Malchev    pthread_mutex_unlock(&ctx->vstate.lock);
2321589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    return ret;
2331589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed}
2341589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
235660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
236660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed{
2371ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
2381ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
2391ddbd4ef2e8a4e14b19e9ce4c9ad00b63b76bbe9Naseer Ahmed        ctx->mFbDev->common.module);
24047377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
2412e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    int ret = 0;
2422e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2432e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    switch(dpy) {
2442e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_PRIMARY:
2452e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            if(blank) {
24647377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed                ctx->mOverlay->configBegin();
24747377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed                ctx->mOverlay->configDone();
2482e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN);
2492e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            } else {
2502e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK);
2512e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            }
2522e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
2532e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_EXTERNAL:
25490571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar        case HWC_DISPLAY_VIRTUAL:
2552e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            if(blank) {
25690571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar                // External/Virtual Display post commits the changes to display
2573ffc467822ce99b148d842c13dc22e1889ba0241Arun Kumar K.R                // Call this on blank, so that any pipe unsets gets committed
2583ffc467822ce99b148d842c13dc22e1889ba0241Arun Kumar K.R                if (!ctx->mExtDisplay->post()) {
2593ffc467822ce99b148d842c13dc22e1889ba0241Arun Kumar K.R                    ret = -1;
2603ffc467822ce99b148d842c13dc22e1889ba0241Arun Kumar K.R                    ALOGE("%s:ctx->mExtDisplay->post fail!! ", __FUNCTION__);
2613ffc467822ce99b148d842c13dc22e1889ba0241Arun Kumar K.R                }
2622e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            } else {
2632e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            }
2642e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
2652e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        default:
2662e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            return -EINVAL;
2672e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
26871005afe9fda149b1bdd2720d0aed1414dc5a455Arun Kumar K.R    // Enable HPD here, as during bootup unblank is called
26971005afe9fda149b1bdd2720d0aed1414dc5a455Arun Kumar K.R    // when SF is completely initialized
27071005afe9fda149b1bdd2720d0aed1414dc5a455Arun Kumar K.R    ctx->mExtDisplay->setHPD(1);
2712e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
2722e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    if(ret < 0) {
2732e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        ALOGE("%s: failed. Dpy=%d, blank=%d : %s",
2742e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah                __FUNCTION__, dpy, blank, strerror(errno));
2752e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        return ret;
276660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    }
2772e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    ALOGD("%s: Done Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
2782e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    ctx->dpyAttr[dpy].isActive = !blank;
279660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    return 0;
280660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed}
281660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed
282660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_query(struct hwc_composer_device_1* dev,
2831589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed                     int param, int* value)
2841589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed{
2851589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
2861589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    private_module_t* m = reinterpret_cast<private_module_t*>(
2871589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ctx->mFbDev->common.module);
2882e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    int supported = HWC_DISPLAY_PRIMARY_BIT;
2891589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
2901589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    switch (param) {
2911589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    case HWC_BACKGROUND_LAYER_SUPPORTED:
2921589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        // Not supported for now
2931589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        value[0] = 0;
2941589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        break;
2952e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    case HWC_VSYNC_PERIOD: //Not used for hwc > 1.1
29621fe85b5b8212ac43d81f5db4b2b30f71ac048e2Saurabh Shah        value[0] = m->fps;
2971589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ALOGI("fps: %d", value[0]);
2981589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        break;
2992e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    case HWC_DISPLAY_TYPES_SUPPORTED:
30076443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        if(ctx->mMDP.hasOverlay)
30176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            supported |= HWC_DISPLAY_EXTERNAL_BIT;
3022e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        value[0] = supported;
3032e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        break;
3041589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    default:
3051589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        return -EINVAL;
3061589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    }
3071589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed    return 0;
3081589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
3091589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed}
3101589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
3112e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahstatic int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
3123475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah    int ret = 0;
313640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah    const int dpy = HWC_DISPLAY_PRIMARY;
3143475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah
315e5287a408d2eae29afa055d6bfd646c250d129fbAmara Venkata Mastan Manoj Kumar    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
31676443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        uint32_t last = list->numHwLayers - 1;
31776443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
3184019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R        int fd = -1; //FenceFD from the Copybit(valid in async mode)
3194019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R        if(ctx->mCopyBit[dpy])
3204019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R            ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
321e5287a408d2eae29afa055d6bfd646c250d129fbAmara Venkata Mastan Manoj Kumar        if(list->numHwLayers > 1)
322e5287a408d2eae29afa055d6bfd646c250d129fbAmara Venkata Mastan Manoj Kumar            hwc_sync(ctx, list, dpy, fd);
323640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        if (!VideoOverlay::draw(ctx, list, dpy)) {
3243475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
3253475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            ret = -1;
3263475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah        }
327c18b3a0ef41fe474fe37e2e1833ef1bb11c85b11Saurabh Shah        if (!ctx->mMDPComp->draw(ctx, list)) {
32816791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            ALOGE("%s: MDPComp::draw fail!", __FUNCTION__);
32916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            ret = -1;
33016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed        }
33116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed
3322e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        //TODO We dont check for SKIP flag on this layer because we need PAN
3332e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        //always. Last layer is always FB
33416791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
33516791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
336e5287a408d2eae29afa055d6bfd646c250d129fbAmara Venkata Mastan Manoj Kumar            if(!(fbLayer->flags & HWC_SKIP_LAYER) &&
337e5287a408d2eae29afa055d6bfd646c250d129fbAmara Venkata Mastan Manoj Kumar                (list->numHwLayers > 1)) {
338640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah                if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
33916791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                    ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
34016791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                    ret = -1;
34116791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed                }
34216791f95b2570b9d48fa360875676e9c8559c0a1Naseer Ahmed            }
3432a67868e6e048684c4a505f74808c3a2aba63c79Saurabh Shah        }
3442a67868e6e048684c4a505f74808c3a2aba63c79Saurabh Shah        if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) {
3452a67868e6e048684c4a505f74808c3a2aba63c79Saurabh Shah            ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__);
3462a67868e6e048684c4a505f74808c3a2aba63c79Saurabh Shah            return -1;
3472e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        }
3482e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
3493475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah    return ret;
3502e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah}
3512e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
3522e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahstatic int hwc_set_external(hwc_context_t *ctx,
35390571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar        hwc_display_contents_1_t* list, int dpy) {
3543475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah    int ret = 0;
355f6205c18f4bbd23e7f39672f781498c34e6b7494Kinjal Bhavsar    Locker::Autolock _l(ctx->mExtSetLock);
35676443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
357e5287a408d2eae29afa055d6bfd646c250d129fbAmara Venkata Mastan Manoj Kumar    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
35890571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar        !ctx->dpyAttr[dpy].isPause &&
359640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        ctx->dpyAttr[dpy].connected) {
3602e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        uint32_t last = list->numHwLayers - 1;
36176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
3624019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R        int fd = -1; //FenceFD from the Copybit(valid in async mode)
3634019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R        if(ctx->mCopyBit[dpy])
3644019c64ad8721cd9f3dc5c4e7be260a5f0706e34Arun Kumar K.R            ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
36576443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
366e5287a408d2eae29afa055d6bfd646c250d129fbAmara Venkata Mastan Manoj Kumar        if(list->numHwLayers > 1)
367e5287a408d2eae29afa055d6bfd646c250d129fbAmara Venkata Mastan Manoj Kumar            hwc_sync(ctx, list, dpy, fd);
36876443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
369640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah        if (!VideoOverlay::draw(ctx, list, dpy)) {
3703475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
3713475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            ret = -1;
3723475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah        }
37376443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
37476443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
375a2bfc3940f0cbf6e3a8f25d397c0335efeb4721bSaurabh Shah        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
376e5287a408d2eae29afa055d6bfd646c250d129fbAmara Venkata Mastan Manoj Kumar                !(fbLayer->flags & HWC_SKIP_LAYER) && hnd &&
377e5287a408d2eae29afa055d6bfd646c250d129fbAmara Venkata Mastan Manoj Kumar                (list->numHwLayers > 1)) {
378640cb9421639c13248aeb30c3496cdfaec6d894cSaurabh Shah            if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
37947377987cc4eef72ee3b0cdced8c3a15038b39ebNaseer Ahmed                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
3803475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah                ret = -1;
3813475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            }
3823475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah        }
3833475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah        if (!ctx->mExtDisplay->post()) {
3843475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            ALOGE("%s: ctx->mExtDisplay->post fail!", __FUNCTION__);
3853475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah            return -1;
3862e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        }
3872e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
3883475d840ef8603c8e21fe903cb5b17fa4cc948b3Saurabh Shah    return ret;
3892e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah}
3902e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
391660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmedstatic int hwc_set(hwc_composer_device_1 *dev,
392660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                   size_t numDisplays,
393660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed                   hwc_display_contents_1_t** displays)
394befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
395befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int ret = 0;
396befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
39777d8f24cb4fece120f062f2f997f018372338b66Naseer Ahmed    Locker::Autolock _l(ctx->mBlankLock);
39890571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar    for (uint32_t i = 0; i <= numDisplays; i++) {
399660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        hwc_display_contents_1_t* list = displays[i];
4002e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        switch(i) {
4012e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            case HWC_DISPLAY_PRIMARY:
4022e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah                ret = hwc_set_primary(ctx, list);
40376443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                break;
4042e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            case HWC_DISPLAY_EXTERNAL:
40590571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar            case HWC_DISPLAY_VIRTUAL:
40690571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar            /* ToDo: We are using hwc_set_external path for both External and
40790571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar                     Virtual displays on HWC1.1. Eventually, we will have
40890571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar                     separate functions when we move to HWC1.2
40990571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar            */
41090571fc7c38e38858ad22a79e95efcb99c3a8b1dAmara Venkata Mastan Manoj Kumar                ret = hwc_set_external(ctx, list, i);
41176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                break;
4122e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            default:
4132e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah                ret = -EINVAL;
414660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed        }
4152e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
4162e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    return ret;
4172e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah}
418ee7fc0347e52276d43413e91f31d72d6db99dcfbNaseer Ahmed
4192e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahint hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
4202e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        uint32_t* configs, size_t* numConfigs) {
4212e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    int ret = 0;
42276443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
4232e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    //in 1.1 there is no way to choose a config, report as config id # 0
4242e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    //This config is passed to getDisplayAttributes. Ignore for now.
4252e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    switch(disp) {
4262e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_PRIMARY:
42776443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            if(*numConfigs > 0) {
42876443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                configs[0] = 0;
42976443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                *numConfigs = 1;
43076443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            }
43176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            ret = 0; //NO_ERROR
4322e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
4332e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_EXTERNAL:
43476443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            ret = -1; //Not connected
43576443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
43676443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                ret = 0; //NO_ERROR
43776443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                if(*numConfigs > 0) {
43876443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                    configs[0] = 0;
43976443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                    *numConfigs = 1;
44076443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                }
44176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            }
4422e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
443660267c43bb3370ab49f4e95562c027171d8fb83Naseer Ahmed    }
444befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return ret;
445befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
446befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
4472e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shahint hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
4482e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        uint32_t config, const uint32_t* attributes, int32_t* values) {
4492e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
4502e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    hwc_context_t* ctx = (hwc_context_t*)(dev);
45176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah    //If hotpluggable displays are inactive return error
45276443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah    if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
45376443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah        return -1;
45476443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah    }
45576443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah
4562e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    //From HWComposer
4572e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    static const uint32_t DISPLAY_ATTRIBUTES[] = {
4582e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        HWC_DISPLAY_VSYNC_PERIOD,
4592e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        HWC_DISPLAY_WIDTH,
4602e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        HWC_DISPLAY_HEIGHT,
4612e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        HWC_DISPLAY_DPI_X,
4622e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        HWC_DISPLAY_DPI_Y,
4632e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        HWC_DISPLAY_NO_ATTRIBUTE,
4642e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    };
4652e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
4662e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
4672e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            sizeof(DISPLAY_ATTRIBUTES)[0]);
4682e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
4692e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
4702e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        switch (attributes[i]) {
4712e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_VSYNC_PERIOD:
4722e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            values[i] = ctx->dpyAttr[disp].vsync_period;
4732e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
4742e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_WIDTH:
4752e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            values[i] = ctx->dpyAttr[disp].xres;
47676443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
47776443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                    ctx->dpyAttr[disp].xres);
4782e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
4792e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_HEIGHT:
4802e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            values[i] = ctx->dpyAttr[disp].yres;
48176443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
48276443245d153635b512539fbc68fdf7a904fdf6fSaurabh Shah                    ctx->dpyAttr[disp].yres);
4832e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
4842e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_DPI_X:
48579e14117f5e66a080b9f2a783ce3b215c72c8653Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
4862e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
4872e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        case HWC_DISPLAY_DPI_Y:
48879e14117f5e66a080b9f2a783ce3b215c72c8653Naseer Ahmed            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
4892e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            break;
4902e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        default:
4912e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            ALOGE("Unknown display attribute %d",
4922e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah                    attributes[i]);
4932e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah            return -EINVAL;
4942e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        }
4952e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    }
4962e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah    return 0;
4972e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah}
4982e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah
49993138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmedvoid hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
50093138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed{
50193138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed    hwc_context_t* ctx = (hwc_context_t*)(dev);
502a22f5873a9974b00f352370e077db9788ad67699Saurabh Shah    android::String8 aBuf("");
503a22f5873a9974b00f352370e077db9788ad67699Saurabh Shah    dumpsys_log(aBuf, "Qualcomm HWC state:\n");
504a22f5873a9974b00f352370e077db9788ad67699Saurabh Shah    dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
505a22f5873a9974b00f352370e077db9788ad67699Saurabh Shah    dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
506a22f5873a9974b00f352370e077db9788ad67699Saurabh Shah    ctx->mMDPComp->dump(aBuf);
507a22f5873a9974b00f352370e077db9788ad67699Saurabh Shah    char ovDump[2048] = {'\0'};
508a22f5873a9974b00f352370e077db9788ad67699Saurabh Shah    ctx->mOverlay->getDump(ovDump, 2048);
509a22f5873a9974b00f352370e077db9788ad67699Saurabh Shah    dumpsys_log(aBuf, ovDump);
510a22f5873a9974b00f352370e077db9788ad67699Saurabh Shah    strlcpy(buff, aBuf.string(), buff_len);
51193138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed}
51293138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed
513befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int hwc_device_close(struct hw_device_t *dev)
514befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
515befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!dev) {
5161589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        ALOGE("%s: NULL device pointer", __FUNCTION__);
517befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -1;
518befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
519befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    closeContext((hwc_context_t*)dev);
520befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    free(dev);
521befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
522befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return 0;
523befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
524befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
525befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int hwc_device_open(const struct hw_module_t* module, const char* name,
526befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                           struct hw_device_t** device)
527befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
528befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = -EINVAL;
529befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
530befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
531befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        struct hwc_context_t *dev;
532befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dev = (hwc_context_t*)malloc(sizeof(*dev));
533befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memset(dev, 0, sizeof(*dev));
5341589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
5351589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        //Initialize hwc context
536befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        initContext(dev);
5371589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed
5381589dee5c27293d278d3e549af8a4bda27e080f8Naseer Ahmed        //Setup HWC methods
5392e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
5402e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_1;
5412e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.common.module       = const_cast<hw_module_t*>(module);
5422e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.common.close        = hwc_device_close;
5432e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.prepare             = hwc_prepare;
5442e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.set                 = hwc_set;
5452e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.eventControl        = hwc_eventControl;
5462e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.blank               = hwc_blank;
5472e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.query               = hwc_query;
5482e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.registerProcs       = hwc_registerProcs;
54993138887ec8fb0f232340c4fb852e3dbcb3542e4Naseer Ahmed        dev->device.dump                = hwc_dump;
5502e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
5512e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
5522e449280f98f003bb5831c274fc07ab722ac1a94Saurabh Shah        *device = &dev->device.common;
553befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = 0;
554befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
555befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
556befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
557