hwc.cpp revision ced6b79c3e1b60b05e2e054e709b1f9a2b6b304c
1ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson/*
2ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Copyright (C) 2010 The Android Open Source Project
3a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
4ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *
5ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Not a Contribution, Apache license notifications and license are retained
6ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * for attribution purposes only.
7ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *
8ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Licensed under the Apache License, Version 2.0 (the "License");
9ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * you may not use this file except in compliance with the License.
10ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * You may obtain a copy of the License at
11ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *
12ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *      http://www.apache.org/licenses/LICENSE-2.0
13ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson *
14ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Unless required by applicable law or agreed to in writing, software
15ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * distributed under the License is distributed on an "AS IS" BASIS,
16ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * See the License for the specific language governing permissions and
18ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * limitations under the License.
19ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson */
20ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
21ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <fcntl.h>
22ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <errno.h>
23ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
24ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <cutils/log.h>
25ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <cutils/atomic.h>
26ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <EGL/egl.h>
27ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <utils/Trace.h>
28ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <sys/ioctl.h>
29ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <overlay.h>
30ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <overlayRotator.h>
31ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <overlayWriteback.h>
32ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include <mdp_version.h>
33ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "hwc_utils.h"
34ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "hwc_fbupdate.h"
35ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "hwc_mdpcomp.h"
36a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include "hwc_dump_layers.h"
37ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "external.h"
38ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "hwc_copybit.h"
39ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "hwc_ad.h"
40ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#include "profiler.h"
41a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#include "hwc_virtual.h"
42ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
43ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonusing namespace qhwc;
44ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonusing namespace overlay;
45ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
46ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#define VSYNC_DEBUG 0
47ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson#define BLANK_DEBUG 1
48ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
49ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_device_open(const struct hw_module_t* module,
50ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                           const char* name,
51ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                           struct hw_device_t** device);
52ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
53ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic struct hw_module_methods_t hwc_module_methods = {
54ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    open: hwc_device_open
55ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson};
56ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
57a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonstatic void reset_panel(struct hwc_composer_device_1* dev);
58a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
59ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonhwc_module_t HAL_MODULE_INFO_SYM = {
60ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    common: {
61ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        tag: HARDWARE_MODULE_TAG,
62ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        version_major: 2,
63ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        version_minor: 0,
64ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        id: HWC_HARDWARE_MODULE_ID,
65ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        name: "Qualcomm Hardware Composer Module",
66ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        author: "CodeAurora Forum",
67ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        methods: &hwc_module_methods,
68ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dso: 0,
69ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        reserved: {0},
70ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
71ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson};
72ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
73a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson/* In case of non-hybrid WFD session, we are fooling SF by piggybacking on
74a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * HDMI display ID for virtual. This helper is needed to differentiate their
75a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * paths in HAL.
76a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson * TODO: Not needed once we have WFD client working on top of Google API's */
77a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
78a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonstatic int getDpyforExternalDisplay(hwc_context_t *ctx, int dpy) {
79a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if(dpy == HWC_DISPLAY_EXTERNAL && ctx->mVirtualonExtActive)
80a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        return HWC_DISPLAY_VIRTUAL;
81a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    return dpy;
82a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson}
83a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
84ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson/*
85ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson * Save callback functions registered to HWC
86ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson */
87ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic void hwc_registerProcs(struct hwc_composer_device_1* dev,
88ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                              hwc_procs_t const* procs)
89ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
90ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ALOGI("%s", __FUNCTION__);
91ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
92ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if(!ctx) {
93ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ALOGE("%s: Invalid context", __FUNCTION__);
94ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return;
95ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
96ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->proc = procs;
97ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
98ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    // Now that we have the functions needed, kick off
99ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    // the uevent & vsync threads
100ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    init_uevent_thread(ctx);
101ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    init_vsync_thread(ctx);
102ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
103ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
104ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson//Helper
105ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic void reset(hwc_context_t *ctx, int numDisplays,
106ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                  hwc_display_contents_1_t** displays) {
107a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
108a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    ctx->numActiveDisplays = 0;
109a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    ctx->isPaddingRound = false;
110a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
111a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    for(int i = 0; i < numDisplays; i++) {
112ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hwc_display_contents_1_t *list = displays[i];
113ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // XXX:SurfaceFlinger no longer guarantees that this
114ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // value is reset on every prepare. However, for the layer
115ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // cache we need to reset it.
116ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // We can probably rethink that later on
117a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if (LIKELY(list && list->numHwLayers > 0)) {
118ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            for(uint32_t j = 0; j < list->numHwLayers; j++) {
119ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
120ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                    list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
121ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
122a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
123a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            /* For display devices like SSD and screenrecord, we cannot
124a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * rely on isActive and connected attributes of dpyAttr to
125a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * determine if the displaydevice is active. Hence in case if
126a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * the layer-list is non-null and numHwLayers > 0, we assume
127a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * the display device to be active.
128a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             */
129a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ctx->numActiveDisplays += 1;
130a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
131a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            if((ctx->mPrevHwLayerCount[i] == 1) and (list->numHwLayers > 1)) {
132a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                /* If the previous cycle for dpy 'i' has 0 AppLayers and the
133a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                 * current cycle has atleast 1 AppLayer, padding round needs
134a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                 * to be invoked on current cycle to free up the resources.
135a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                 */
136a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                ctx->isPaddingRound = true;
137a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            }
138a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ctx->mPrevHwLayerCount[i] = list->numHwLayers;
139a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        } else {
140a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ctx->mPrevHwLayerCount[i] = 0;
141ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
142ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
143ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(ctx->mFBUpdate[i])
144ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ctx->mFBUpdate[i]->reset();
145ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(ctx->mCopyBit[i])
146ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ctx->mCopyBit[i]->reset();
147ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(ctx->mLayerRotMap[i])
148ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ctx->mLayerRotMap[i]->reset();
149ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
150ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
151ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mAD->reset();
152a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    MDPComp::reset();
153a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if(ctx->mHWCVirtual)
154a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ctx->mHWCVirtual->destroy(ctx, numDisplays, displays);
155ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
156ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
157a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonbool isEqual(float f1, float f2) {
158a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        return ((int)(f1*100) == (int)(f2*100)) ? true : false;
159ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
160ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
161a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonstatic void scaleDisplayFrame(hwc_context_t *ctx, int dpy,
162a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                            hwc_display_contents_1_t *list) {
163a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    float origXres = ctx->dpyAttr[dpy].xres_orig;
164a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    float origYres = ctx->dpyAttr[dpy].yres_orig;
165a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    float fakeXres = ctx->dpyAttr[dpy].xres;
166a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    float fakeYres = ctx->dpyAttr[dpy].yres;
167a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    float xresRatio = origXres / fakeXres;
168a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    float yresRatio = origYres / fakeYres;
169a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    for (size_t i = 0; i < list->numHwLayers; i++) {
170a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        hwc_layer_1_t *layer = &list->hwLayers[i];
171a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        hwc_rect_t& displayFrame = layer->displayFrame;
172a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
173a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        float layerWidth = displayFrame.right - displayFrame.left;
174a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        float layerHeight = displayFrame.bottom - displayFrame.top;
175a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        float sourceWidth = sourceCrop.right - sourceCrop.left;
176a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        float sourceHeight = sourceCrop.bottom - sourceCrop.top;
177a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
178a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if (isEqual(layerWidth / sourceWidth, xresRatio) &&
179a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                isEqual(layerHeight / sourceHeight, yresRatio))
180a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            break;
181ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
182a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        displayFrame.left = xresRatio * displayFrame.left;
183a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        displayFrame.top = yresRatio * displayFrame.top;
184a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        displayFrame.right = displayFrame.left + layerWidth * xresRatio;
185a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        displayFrame.bottom = displayFrame.top + layerHeight * yresRatio;
186ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
187ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
188ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
189ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_prepare_primary(hwc_composer_device_1 *dev,
190ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hwc_display_contents_1_t *list) {
191ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ATRACE_CALL();
192ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
193ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    const int dpy = HWC_DISPLAY_PRIMARY;
194a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    bool fbComp = false;
195ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (LIKELY(list && list->numHwLayers > 1) &&
196ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ctx->dpyAttr[dpy].isActive) {
197a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
198a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if (ctx->dpyAttr[dpy].customFBSize)
199a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            scaleDisplayFrame(ctx, dpy, list);
200a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
201ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
202ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        setListStats(ctx, list, dpy);
203a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
204201e4c9a80c1adb32ac8271a95721aa838c4d9feNaseer Ahmed        fbComp = (ctx->mMDPComp[dpy]->prepare(ctx, list) < 0);
205a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
206a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if (fbComp) {
207ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            const int fbZ = 0;
208a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ);
209ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
210a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
211ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if (ctx->mMDP.version < qdutils::MDP_V4_0) {
212ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if(ctx->mCopyBit[dpy])
213ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
214ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
2151b0c2f1b1c7201502f75c12131e3bc54f92d60eaRamkumar Radhakrishnan        setGPUHint(ctx, list);
216ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
217ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
218ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
219ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
220ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_prepare_external(hwc_composer_device_1 *dev,
221ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hwc_display_contents_1_t *list) {
222ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ATRACE_CALL();
223ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
224ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    const int dpy = HWC_DISPLAY_EXTERNAL;
225ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
226ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (LIKELY(list && list->numHwLayers > 1) &&
227ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ctx->dpyAttr[dpy].isActive &&
228ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ctx->dpyAttr[dpy].connected) {
229ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
230ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(!ctx->dpyAttr[dpy].isPause) {
231ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ctx->dpyAttr[dpy].isConfiguring = false;
232ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            setListStats(ctx, list, dpy);
233ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
234ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                const int fbZ = 0;
235a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ);
236ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
237ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        } else {
238a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            /* External Display is in Pause state.
239a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * Mark all application layers as OVERLAY so that
240a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * GPU will not compose.
241a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             */
242a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) {
243a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                hwc_layer_1_t *layer = &list->hwLayers[i];
244a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                layer->compositionType = HWC_OVERLAY;
245a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            }
246ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
247ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
248ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
249ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
250ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
251ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
252ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                       hwc_display_contents_1_t** displays)
253ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
254ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int ret = 0;
255ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
256a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
257a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if (ctx->mPanelResetStatus) {
258a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ALOGW("%s: panel is in bad state. reset the panel", __FUNCTION__);
259a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        reset_panel(dev);
260a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    }
261a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
262ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    //Will be unlocked at the end of set
263ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mDrawLock.lock();
264ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    reset(ctx, numDisplays, displays);
265ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
266ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mOverlay->configBegin();
267ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mRotMgr->configBegin();
268ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    overlay::Writeback::configBegin();
269ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
270a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    for (int32_t i = (numDisplays-1); i >= 0; i--) {
271ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hwc_display_contents_1_t *list = displays[i];
272a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        int dpy = getDpyforExternalDisplay(ctx, i);
273a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        switch(dpy) {
274ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            case HWC_DISPLAY_PRIMARY:
275ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = hwc_prepare_primary(dev, list);
276ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
277ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            case HWC_DISPLAY_EXTERNAL:
278ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = hwc_prepare_external(dev, list);
279ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
280ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            case HWC_DISPLAY_VIRTUAL:
281a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                if(ctx->mHWCVirtual)
282a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                    ret = ctx->mHWCVirtual->prepare(dev, list);
283ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
284ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            default:
285ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = -EINVAL;
286ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
287ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
288ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
289ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mOverlay->configDone();
290ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mRotMgr->configDone();
291ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    overlay::Writeback::configDone();
292ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
293ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return ret;
294ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
295ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
296ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
297ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                             int event, int enable)
298ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
299ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ATRACE_CALL();
300ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int ret = 0;
301ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
302ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    switch(event) {
303ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_EVENT_VSYNC:
304ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if (ctx->vstate.enable == enable)
305ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
306ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = hwc_vsync_control(ctx, dpy, enable);
307ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if(ret == 0)
308ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ctx->vstate.enable = !!enable;
309ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
310ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                      (enable)?"ENABLED":"DISABLED");
311ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
312a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#ifdef QCOM_BSP
313a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        case  HWC_EVENT_ORIENTATION:
314a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            if(dpy == HWC_DISPLAY_PRIMARY) {
315a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                Locker::Autolock _l(ctx->mDrawLock);
316a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                // store the primary display orientation
317a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                ctx->deviceOrientation = enable;
318a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            }
319a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            break;
320a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#endif
321ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        default:
322ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = -EINVAL;
323ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
324ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return ret;
325ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
326ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
327ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
328ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
329ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ATRACE_CALL();
330ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
331ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
332ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    Locker::Autolock _l(ctx->mDrawLock);
333a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    int ret = 0, value = 0;
334a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
335a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    /* In case of non-hybrid WFD session, we are fooling SF by
336a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson     * piggybacking on HDMI display ID for virtual.
337a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson     * TODO: Not needed once we have WFD client working on top
338a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson     * of Google API's.
339a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson     */
340a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    dpy = getDpyforExternalDisplay(ctx,dpy);
341a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
342ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__,
343ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson          blank==1 ? "Blanking":"Unblanking", dpy);
344ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if(blank) {
345ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // free up all the overlay pipes in use
346ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // when we get a blank for either display
347ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // makes sure that all pipes are freed
348ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ctx->mOverlay->configBegin();
349ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ctx->mOverlay->configDone();
350ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ctx->mRotMgr->clear();
351a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // If VDS is connected, do not clear WB object as it
352a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // will end up detaching IOMMU. This is required
353a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // to send black frame to WFD sink on power suspend.
354a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // Note: With this change, we keep the WriteBack object
355a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // alive on power suspend for AD use case.
356ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
357ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    switch(dpy) {
358a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    case HWC_DISPLAY_PRIMARY:
359a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        value = blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK;
360a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) {
361a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ALOGE("%s: Failed to handle blank event(%d) for Primary!!",
362a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                  __FUNCTION__, blank );
363a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            return -1;
364a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        }
365a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
366a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(!blank) {
367a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            // Enable HPD here, as during bootup unblank is called
368a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            // when SF is completely initialized
369a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ctx->mExtDisplay->setHPD(1);
370a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        }
371a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
372a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ctx->dpyAttr[dpy].isActive = !blank;
373a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
374a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(ctx->mVirtualonExtActive) {
375a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            /* if mVirtualonExtActive is true, display hal will
376a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * receive unblank calls for non-hybrid WFD solution
377a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * since we piggyback on HDMI.
378a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * TODO: Not needed once we have WFD client working on top
379a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             of Google API's */
380ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
381a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        }
382a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    case HWC_DISPLAY_VIRTUAL:
383a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        /* There are two ways to reach this block of code.
384a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
385a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         * Display hal has received unblank call on HWC_DISPLAY_EXTERNAL
386a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         and ctx->mVirtualonExtActive is true. In this case, non-hybrid
387a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         WFD is active. If so, getDpyforExternalDisplay will return dpy
388a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         as HWC_DISPLAY_VIRTUAL.
389a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
390a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         * Display hal has received unblank call on HWC_DISPLAY_PRIMARY
391a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         and since SF is not aware of VIRTUAL DISPLAY being handle by HWC,
392a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         it wont send blank / unblank events for it. We piggyback on
393a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         PRIMARY DISPLAY events to release mdp pipes and
394a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         activate/deactivate VIRTUAL DISPLAY.
395a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
396a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         * TODO: This separate case statement is not needed once we have
397a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         WFD client working on top of Google API's.
398a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
399a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         */
400a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
401a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) {
402a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            if(blank and (!ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause)) {
403a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                int dpy = HWC_DISPLAY_VIRTUAL;
404a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
405a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                    ALOGE("%s: display commit fail for virtual!", __FUNCTION__);
406ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                    ret = -1;
407ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                }
408ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
409a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = !blank;
410a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        }
411a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        break;
412a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    case HWC_DISPLAY_EXTERNAL:
413a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(blank) {
414a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
415a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                ALOGE("%s: display commit fail for external!", __FUNCTION__);
416a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                ret = -1;
417a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            }
418a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        }
419ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ctx->dpyAttr[dpy].isActive = !blank;
420a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        break;
421a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    default:
422a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        return -EINVAL;
423ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
424ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
425ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__,
426a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson          blank ? "blanking":"unblanking", dpy);
427a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    return ret;
428a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson}
429a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
430a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonstatic void reset_panel(struct hwc_composer_device_1* dev)
431a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson{
432a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    int ret = 0;
433a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
434a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
435a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if (!ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
436a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ALOGD ("%s : Display OFF - Skip BLANK & UNBLANK", __FUNCTION__);
437a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ctx->mPanelResetStatus = false;
438a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        return;
439a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    }
440a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
441a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    ALOGD("%s: calling BLANK DISPLAY", __FUNCTION__);
442a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    ret = hwc_blank(dev, HWC_DISPLAY_PRIMARY, 1);
443a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if (ret < 0) {
444a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ALOGE("%s: FBIOBLANK failed to BLANK:  %s", __FUNCTION__,
445a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                                                            strerror(errno));
446a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    }
447a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
448a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    ALOGD("%s: calling UNBLANK DISPLAY and enabling vsync", __FUNCTION__);
449a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    ret = hwc_blank(dev, HWC_DISPLAY_PRIMARY, 0);
450a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if (ret < 0) {
451a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ALOGE("%s: FBIOBLANK failed to UNBLANK : %s", __FUNCTION__,
452a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                                                            strerror(errno));
453a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    }
454a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1);
455a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
456a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    ctx->mPanelResetStatus = false;
457ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
458ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
459a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
460ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_query(struct hwc_composer_device_1* dev,
461ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                     int param, int* value)
462ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
463ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
464ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int supported = HWC_DISPLAY_PRIMARY_BIT;
465ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
466ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    switch (param) {
467ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    case HWC_BACKGROUND_LAYER_SUPPORTED:
468ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // Not supported for now
469ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        value[0] = 0;
470ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        break;
471a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    case HWC_DISPLAY_TYPES_SUPPORTED:
472ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(ctx->mMDP.hasOverlay) {
473ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            supported |= HWC_DISPLAY_VIRTUAL_BIT;
4740fdae193307fb17bb537598ab62682edd5138b72radhakrishna            if(!(qdutils::MDPVersion::getInstance().is8x26() ||
4750fdae193307fb17bb537598ab62682edd5138b72radhakrishna                        qdutils::MDPVersion::getInstance().is8x16()))
476ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                supported |= HWC_DISPLAY_EXTERNAL_BIT;
477ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
478ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        value[0] = supported;
479ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        break;
480a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    case HWC_FORMAT_RB_SWAP:
481a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        value[0] = 1;
482a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        break;
483a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    case HWC_COLOR_FILL:
484a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        value[0] = 1;
485a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        break;
486ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    default:
487ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -EINVAL;
488ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
489ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
490ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
491ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
492ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
493ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
494ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
495ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ATRACE_CALL();
496ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int ret = 0;
497ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    const int dpy = HWC_DISPLAY_PRIMARY;
498ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
499ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        uint32_t last = list->numHwLayers - 1;
500ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
501ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        int fd = -1; //FenceFD from the Copybit(valid in async mode)
502ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        bool copybitDone = false;
503ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(ctx->mCopyBit[dpy])
504ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
505ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(list->numHwLayers > 1)
506ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            hwc_sync(ctx, list, dpy, fd);
507ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
508a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // Dump the layers for primary
509a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(ctx->mHwcDebug[dpy])
510a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ctx->mHwcDebug[dpy]->dumpLayers(list);
511a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
512201e4c9a80c1adb32ac8271a95721aa838c4d9feNaseer Ahmed        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
513ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
514ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = -1;
515ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
516ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
517ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        //TODO We dont check for SKIP flag on this layer because we need PAN
518ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        //always. Last layer is always FB
519ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
520a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(copybitDone && ctx->mMDP.version >= qdutils::MDP_V4_0) {
521ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
522ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
523ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
524ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(hnd) {
525ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
526ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
527ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = -1;
528ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
529ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
530ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
531a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd,
532a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                                            ctx->listStats[dpy].roi)) {
533a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
534ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = -1;
535ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
536a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
537ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
538ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
539a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    closeAcquireFds(list);
540ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return ret;
541ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
542ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
543ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_set_external(hwc_context_t *ctx,
544a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                            hwc_display_contents_1_t* list)
545ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
546ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ATRACE_CALL();
547ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int ret = 0;
548a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
549ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    const int dpy = HWC_DISPLAY_EXTERNAL;
550ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
551a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
552ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
553a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ctx->dpyAttr[dpy].connected &&
554a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        !ctx->dpyAttr[dpy].isPause) {
555ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        uint32_t last = list->numHwLayers - 1;
556ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
557ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        int fd = -1; //FenceFD from the Copybit(valid in async mode)
558ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        bool copybitDone = false;
559ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(ctx->mCopyBit[dpy])
560ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
561ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
562ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(list->numHwLayers > 1)
563ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            hwc_sync(ctx, list, dpy, fd);
564ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
565a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // Dump the layers for external
566a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(ctx->mHwcDebug[dpy])
567a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ctx->mHwcDebug[dpy]->dumpLayers(list);
568a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
569ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
570ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
571ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = -1;
572ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
573ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
574a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        int extOnlyLayerIndex =
575a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                ctx->listStats[dpy].extOnlyLayerIndex;
576a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
577ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
578a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(extOnlyLayerIndex!= -1) {
579a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex];
580a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            hnd = (private_handle_t *)extLayer->handle;
581a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        } else if(copybitDone) {
582ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
583ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
584ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
585a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(hnd && !isYuvBuffer(hnd)) {
586ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
587ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
588ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = -1;
589ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
590ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
591ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
592a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
593a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
594ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = -1;
595ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
596ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
597ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
598a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    closeAcquireFds(list);
599ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return ret;
600ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
601ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
602ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_set(hwc_composer_device_1 *dev,
603ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                   size_t numDisplays,
604ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                   hwc_display_contents_1_t** displays)
605ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
606ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int ret = 0;
607ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
608ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    for (uint32_t i = 0; i < numDisplays; i++) {
609ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hwc_display_contents_1_t* list = displays[i];
610a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        int dpy = getDpyforExternalDisplay(ctx, i);
611a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        switch(dpy) {
612ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            case HWC_DISPLAY_PRIMARY:
613ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = hwc_set_primary(ctx, list);
614ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
615ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            case HWC_DISPLAY_EXTERNAL:
616ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = hwc_set_external(ctx, list);
617ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
618ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            case HWC_DISPLAY_VIRTUAL:
619a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                if(ctx->mHWCVirtual)
620a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                    ret = ctx->mHWCVirtual->set(ctx, list);
621ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
622ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            default:
623ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = -EINVAL;
624ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
625ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
626ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    // This is only indicative of how many times SurfaceFlinger posts
627ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    // frames to the display.
628ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    CALC_FPS();
629ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    MDPComp::resetIdleFallBack();
630ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mVideoTransFlag = false;
631a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if(ctx->mRotMgr->getNumActiveSessions() == 0)
632a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        Overlay::setDMAMode(Overlay::DMA_LINE_MODE);
633ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    //Was locked at the beginning of prepare
634ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mDrawLock.unlock();
635ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return ret;
636ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
637ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
638ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
639ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        uint32_t* configs, size_t* numConfigs) {
640ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int ret = 0;
641ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
642a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    disp = getDpyforExternalDisplay(ctx, disp);
643ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    //in 1.1 there is no way to choose a config, report as config id # 0
644ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    //This config is passed to getDisplayAttributes. Ignore for now.
645ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    switch(disp) {
646ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_PRIMARY:
647ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if(*numConfigs > 0) {
648ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                configs[0] = 0;
649ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                *numConfigs = 1;
650ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
651ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = 0; //NO_ERROR
652ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
653ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_EXTERNAL:
654a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        case HWC_DISPLAY_VIRTUAL:
655ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = -1; //Not connected
656a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            if(ctx->dpyAttr[disp].connected) {
657ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = 0; //NO_ERROR
658ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                if(*numConfigs > 0) {
659ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                    configs[0] = 0;
660ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                    *numConfigs = 1;
661ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                }
662ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
663ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
664ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
665ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return ret;
666ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
667ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
668ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
669a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        uint32_t /*config*/, const uint32_t* attributes, int32_t* values) {
670ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
671ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
672a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    disp = getDpyforExternalDisplay(ctx, disp);
673a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error
674a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) {
675ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -1;
676ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
677ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
678ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    //From HWComposer
679ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    static const uint32_t DISPLAY_ATTRIBUTES[] = {
680ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        HWC_DISPLAY_VSYNC_PERIOD,
681ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        HWC_DISPLAY_WIDTH,
682ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        HWC_DISPLAY_HEIGHT,
683ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        HWC_DISPLAY_DPI_X,
684ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        HWC_DISPLAY_DPI_Y,
685ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        HWC_DISPLAY_NO_ATTRIBUTE,
686ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    };
687ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
688ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
689ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            sizeof(DISPLAY_ATTRIBUTES)[0]);
690ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
691ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
692ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        switch (attributes[i]) {
693ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_VSYNC_PERIOD:
694ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            values[i] = ctx->dpyAttr[disp].vsync_period;
695ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
696ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_WIDTH:
697ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            values[i] = ctx->dpyAttr[disp].xres;
698ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
699ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                    ctx->dpyAttr[disp].xres);
700ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
701ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_HEIGHT:
702ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            values[i] = ctx->dpyAttr[disp].yres;
703ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
704ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                    ctx->dpyAttr[disp].yres);
705ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
706ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_DPI_X:
707ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
708ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
709ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_DPI_Y:
710ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
711ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
712ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        default:
713ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ALOGE("Unknown display attribute %d",
714ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                    attributes[i]);
715ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            return -EINVAL;
716ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
717ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
718ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
719ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
720ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
721ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonvoid hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
722ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
723ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
724ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    Locker::Autolock _l(ctx->mDrawLock);
725ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    android::String8 aBuf("");
726ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    dumpsys_log(aBuf, "Qualcomm HWC state:\n");
727ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
728ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
729ced6b79c3e1b60b05e2e054e709b1f9a2b6b304cNaseer Ahmed    if(ctx->vstate.fakevsync)
730ced6b79c3e1b60b05e2e054e709b1f9a2b6b304cNaseer Ahmed        dumpsys_log(aBuf, "  Vsync is being faked!!\n");
731a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) {
732ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(ctx->mMDPComp[dpy])
733ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ctx->mMDPComp[dpy]->dump(aBuf);
734ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
735ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    char ovDump[2048] = {'\0'};
736ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mOverlay->getDump(ovDump, 2048);
737ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    dumpsys_log(aBuf, ovDump);
738ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ovDump[0] = '\0';
739ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mRotMgr->getDump(ovDump, 1024);
740ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    dumpsys_log(aBuf, ovDump);
741ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ovDump[0] = '\0';
742ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if(Writeback::getDump(ovDump, 1024)) {
743ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dumpsys_log(aBuf, ovDump);
744ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ovDump[0] = '\0';
745ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
746ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    strlcpy(buff, aBuf.string(), buff_len);
747ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
748ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
749ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_device_close(struct hw_device_t *dev)
750ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
751ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if(!dev) {
752ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ALOGE("%s: NULL device pointer", __FUNCTION__);
753ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -1;
754ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
755ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    closeContext((hwc_context_t*)dev);
756ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    free(dev);
757ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
758ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
759ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
760ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
761ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_device_open(const struct hw_module_t* module, const char* name,
762ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                           struct hw_device_t** device)
763ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
764ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int status = -EINVAL;
765ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
766ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
767ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        struct hwc_context_t *dev;
768ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev = (hwc_context_t*)malloc(sizeof(*dev));
769a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(dev == NULL)
770a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            return status;
771ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        memset(dev, 0, sizeof(*dev));
772ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
773ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        //Initialize hwc context
774ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        initContext(dev);
775ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
776ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        //Setup HWC methods
777ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
778ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_3;
779ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.common.module       = const_cast<hw_module_t*>(module);
780ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.common.close        = hwc_device_close;
781ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.prepare             = hwc_prepare;
782ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.set                 = hwc_set;
783ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.eventControl        = hwc_eventControl;
784ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.blank               = hwc_blank;
785ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.query               = hwc_query;
786ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.registerProcs       = hwc_registerProcs;
787ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.dump                = hwc_dump;
788ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
789ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
790ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        *device = &dev->device.common;
791ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        status = 0;
792ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
793ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return status;
794ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
795