hwc.cpp revision 0fdae193307fb17bb537598ab62682edd5138b72
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        }
215ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
216ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
217ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
218ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
219ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_prepare_external(hwc_composer_device_1 *dev,
220ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hwc_display_contents_1_t *list) {
221ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ATRACE_CALL();
222ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
223ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    const int dpy = HWC_DISPLAY_EXTERNAL;
224ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
225ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (LIKELY(list && list->numHwLayers > 1) &&
226ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ctx->dpyAttr[dpy].isActive &&
227ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ctx->dpyAttr[dpy].connected) {
228ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
229ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(!ctx->dpyAttr[dpy].isPause) {
230ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ctx->dpyAttr[dpy].isConfiguring = false;
231ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            setListStats(ctx, list, dpy);
232ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
233ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                const int fbZ = 0;
234a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ);
235ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
236ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        } else {
237a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            /* External Display is in Pause state.
238a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * Mark all application layers as OVERLAY so that
239a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * GPU will not compose.
240a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             */
241a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) {
242a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                hwc_layer_1_t *layer = &list->hwLayers[i];
243a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                layer->compositionType = HWC_OVERLAY;
244a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            }
245ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
246ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
247ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
248ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
249ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
250ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
251ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                       hwc_display_contents_1_t** displays)
252ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
253ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int ret = 0;
254ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
255a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
256a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if (ctx->mPanelResetStatus) {
257a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ALOGW("%s: panel is in bad state. reset the panel", __FUNCTION__);
258a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        reset_panel(dev);
259a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    }
260a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
261ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    //Will be unlocked at the end of set
262ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mDrawLock.lock();
263ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    reset(ctx, numDisplays, displays);
264ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
265ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mOverlay->configBegin();
266ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mRotMgr->configBegin();
267ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    overlay::Writeback::configBegin();
268ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
269a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    for (int32_t i = (numDisplays-1); i >= 0; i--) {
270ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hwc_display_contents_1_t *list = displays[i];
271a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        int dpy = getDpyforExternalDisplay(ctx, i);
272a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        switch(dpy) {
273ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            case HWC_DISPLAY_PRIMARY:
274ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = hwc_prepare_primary(dev, list);
275ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
276ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            case HWC_DISPLAY_EXTERNAL:
277ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = hwc_prepare_external(dev, list);
278ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
279ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            case HWC_DISPLAY_VIRTUAL:
280a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                if(ctx->mHWCVirtual)
281a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                    ret = ctx->mHWCVirtual->prepare(dev, list);
282ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
283ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            default:
284ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = -EINVAL;
285ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
286ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
287ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
288ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mOverlay->configDone();
289ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mRotMgr->configDone();
290ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    overlay::Writeback::configDone();
291ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
292ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return ret;
293ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
294ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
295ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
296ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                             int event, int enable)
297ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
298ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ATRACE_CALL();
299ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int ret = 0;
300ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
301ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    switch(event) {
302ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_EVENT_VSYNC:
303ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if (ctx->vstate.enable == enable)
304ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
305ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = hwc_vsync_control(ctx, dpy, enable);
306ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if(ret == 0)
307ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ctx->vstate.enable = !!enable;
308ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
309ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                      (enable)?"ENABLED":"DISABLED");
310ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
311a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#ifdef QCOM_BSP
312a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        case  HWC_EVENT_ORIENTATION:
313a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            if(dpy == HWC_DISPLAY_PRIMARY) {
314a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                Locker::Autolock _l(ctx->mDrawLock);
315a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                // store the primary display orientation
316a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                ctx->deviceOrientation = enable;
317a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            }
318a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            break;
319a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson#endif
320ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        default:
321ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = -EINVAL;
322ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
323ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return ret;
324ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
325ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
326ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
327ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
328ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ATRACE_CALL();
329ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
330ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
331ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    Locker::Autolock _l(ctx->mDrawLock);
332a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    int ret = 0, value = 0;
333a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
334a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    /* In case of non-hybrid WFD session, we are fooling SF by
335a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson     * piggybacking on HDMI display ID for virtual.
336a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson     * TODO: Not needed once we have WFD client working on top
337a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson     * of Google API's.
338a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson     */
339a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    dpy = getDpyforExternalDisplay(ctx,dpy);
340a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
341ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__,
342ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson          blank==1 ? "Blanking":"Unblanking", dpy);
343ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if(blank) {
344ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // free up all the overlay pipes in use
345ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // when we get a blank for either display
346ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // makes sure that all pipes are freed
347ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ctx->mOverlay->configBegin();
348ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ctx->mOverlay->configDone();
349ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ctx->mRotMgr->clear();
350a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // If VDS is connected, do not clear WB object as it
351a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // will end up detaching IOMMU. This is required
352a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // to send black frame to WFD sink on power suspend.
353a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // Note: With this change, we keep the WriteBack object
354a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // alive on power suspend for AD use case.
355ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
356ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    switch(dpy) {
357a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    case HWC_DISPLAY_PRIMARY:
358a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        value = blank ? FB_BLANK_POWERDOWN : FB_BLANK_UNBLANK;
359a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) {
360a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ALOGE("%s: Failed to handle blank event(%d) for Primary!!",
361a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                  __FUNCTION__, blank );
362a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            return -1;
363a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        }
364a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
365a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(!blank) {
366a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            // Enable HPD here, as during bootup unblank is called
367a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            // when SF is completely initialized
368a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ctx->mExtDisplay->setHPD(1);
369a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        }
370a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
371a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ctx->dpyAttr[dpy].isActive = !blank;
372a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
373a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(ctx->mVirtualonExtActive) {
374a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            /* if mVirtualonExtActive is true, display hal will
375a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * receive unblank calls for non-hybrid WFD solution
376a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * since we piggyback on HDMI.
377a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             * TODO: Not needed once we have WFD client working on top
378a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson             of Google API's */
379ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
380a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        }
381a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    case HWC_DISPLAY_VIRTUAL:
382a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        /* There are two ways to reach this block of code.
383a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
384a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         * Display hal has received unblank call on HWC_DISPLAY_EXTERNAL
385a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         and ctx->mVirtualonExtActive is true. In this case, non-hybrid
386a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         WFD is active. If so, getDpyforExternalDisplay will return dpy
387a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         as HWC_DISPLAY_VIRTUAL.
388a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
389a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         * Display hal has received unblank call on HWC_DISPLAY_PRIMARY
390a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         and since SF is not aware of VIRTUAL DISPLAY being handle by HWC,
391a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         it wont send blank / unblank events for it. We piggyback on
392a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         PRIMARY DISPLAY events to release mdp pipes and
393a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         activate/deactivate VIRTUAL DISPLAY.
394a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
395a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         * TODO: This separate case statement is not needed once we have
396a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         WFD client working on top of Google API's.
397a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
398a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson         */
399a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
400a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) {
401a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            if(blank and (!ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause)) {
402a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                int dpy = HWC_DISPLAY_VIRTUAL;
403a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
404a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                    ALOGE("%s: display commit fail for virtual!", __FUNCTION__);
405ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                    ret = -1;
406ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                }
407ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
408a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = !blank;
409a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        }
410a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        break;
411a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    case HWC_DISPLAY_EXTERNAL:
412a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(blank) {
413a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
414a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                ALOGE("%s: display commit fail for external!", __FUNCTION__);
415a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                ret = -1;
416a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            }
417a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        }
418ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ctx->dpyAttr[dpy].isActive = !blank;
419a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        break;
420a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    default:
421a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        return -EINVAL;
422ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
423ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
424ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__,
425a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson          blank ? "blanking":"unblanking", dpy);
426a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    return ret;
427a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson}
428a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
429a653efede03423aa840da24634f1ec6f20796f1eSimon Wilsonstatic void reset_panel(struct hwc_composer_device_1* dev)
430a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson{
431a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    int ret = 0;
432a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
433a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
434a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if (!ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
435a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ALOGD ("%s : Display OFF - Skip BLANK & UNBLANK", __FUNCTION__);
436a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ctx->mPanelResetStatus = false;
437a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        return;
438a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    }
439a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
440a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    ALOGD("%s: calling BLANK DISPLAY", __FUNCTION__);
441a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    ret = hwc_blank(dev, HWC_DISPLAY_PRIMARY, 1);
442a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if (ret < 0) {
443a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ALOGE("%s: FBIOBLANK failed to BLANK:  %s", __FUNCTION__,
444a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                                                            strerror(errno));
445a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    }
446a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
447a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    ALOGD("%s: calling UNBLANK DISPLAY and enabling vsync", __FUNCTION__);
448a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    ret = hwc_blank(dev, HWC_DISPLAY_PRIMARY, 0);
449a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if (ret < 0) {
450a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ALOGE("%s: FBIOBLANK failed to UNBLANK : %s", __FUNCTION__,
451a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                                                            strerror(errno));
452a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    }
453a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1);
454a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
455a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    ctx->mPanelResetStatus = false;
456ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
457ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
458a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
459ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_query(struct hwc_composer_device_1* dev,
460ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                     int param, int* value)
461ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
462ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
463ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int supported = HWC_DISPLAY_PRIMARY_BIT;
464ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
465ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    switch (param) {
466ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    case HWC_BACKGROUND_LAYER_SUPPORTED:
467ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        // Not supported for now
468ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        value[0] = 0;
469ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        break;
470a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    case HWC_DISPLAY_TYPES_SUPPORTED:
471ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(ctx->mMDP.hasOverlay) {
472ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            supported |= HWC_DISPLAY_VIRTUAL_BIT;
4730fdae193307fb17bb537598ab62682edd5138b72radhakrishna            if(!(qdutils::MDPVersion::getInstance().is8x26() ||
4740fdae193307fb17bb537598ab62682edd5138b72radhakrishna                        qdutils::MDPVersion::getInstance().is8x16()))
475ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                supported |= HWC_DISPLAY_EXTERNAL_BIT;
476ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
477ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        value[0] = supported;
478ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        break;
479a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    case HWC_FORMAT_RB_SWAP:
480a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        value[0] = 1;
481a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        break;
482a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    case HWC_COLOR_FILL:
483a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        value[0] = 1;
484a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        break;
485ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    default:
486ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -EINVAL;
487ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
488ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
489ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
490ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
491ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
492ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
493ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
494ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ATRACE_CALL();
495ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int ret = 0;
496ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    const int dpy = HWC_DISPLAY_PRIMARY;
497ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
498ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        uint32_t last = list->numHwLayers - 1;
499ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
500ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        int fd = -1; //FenceFD from the Copybit(valid in async mode)
501ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        bool copybitDone = false;
502ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(ctx->mCopyBit[dpy])
503ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
504ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(list->numHwLayers > 1)
505ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            hwc_sync(ctx, list, dpy, fd);
506ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
507a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // Dump the layers for primary
508a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(ctx->mHwcDebug[dpy])
509a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ctx->mHwcDebug[dpy]->dumpLayers(list);
510a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
511201e4c9a80c1adb32ac8271a95721aa838c4d9feNaseer Ahmed        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
512ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
513ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = -1;
514ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
515ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
516ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        //TODO We dont check for SKIP flag on this layer because we need PAN
517ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        //always. Last layer is always FB
518ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
519a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(copybitDone && ctx->mMDP.version >= qdutils::MDP_V4_0) {
520ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
521ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
522ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
523ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(hnd) {
524ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
525ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
526ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = -1;
527ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
528ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
529ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
530a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd,
531a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                                            ctx->listStats[dpy].roi)) {
532a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
533ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = -1;
534ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
535a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
536ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
537ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
538a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    closeAcquireFds(list);
539ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return ret;
540ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
541ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
542ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_set_external(hwc_context_t *ctx,
543a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                            hwc_display_contents_1_t* list)
544ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
545ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ATRACE_CALL();
546ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int ret = 0;
547a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
548ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    const int dpy = HWC_DISPLAY_EXTERNAL;
549ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
550a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
551ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
552a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        ctx->dpyAttr[dpy].connected &&
553a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        !ctx->dpyAttr[dpy].isPause) {
554ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        uint32_t last = list->numHwLayers - 1;
555ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
556ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        int fd = -1; //FenceFD from the Copybit(valid in async mode)
557ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        bool copybitDone = false;
558ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(ctx->mCopyBit[dpy])
559ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
560ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
561ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(list->numHwLayers > 1)
562ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            hwc_sync(ctx, list, dpy, fd);
563ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
564a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        // Dump the layers for external
565a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(ctx->mHwcDebug[dpy])
566a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ctx->mHwcDebug[dpy]->dumpLayers(list);
567a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
568ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
569ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
570ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = -1;
571ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
572ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
573a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        int extOnlyLayerIndex =
574a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                ctx->listStats[dpy].extOnlyLayerIndex;
575a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson
576ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
577a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(extOnlyLayerIndex!= -1) {
578a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex];
579a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            hnd = (private_handle_t *)extLayer->handle;
580a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        } else if(copybitDone) {
581ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
582ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
583ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
584a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(hnd && !isYuvBuffer(hnd)) {
585ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
586ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
587ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = -1;
588ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
589ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
590ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
591a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
592a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
593ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = -1;
594ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
595ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
596ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
597a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    closeAcquireFds(list);
598ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return ret;
599ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
600ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
601ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_set(hwc_composer_device_1 *dev,
602ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                   size_t numDisplays,
603ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                   hwc_display_contents_1_t** displays)
604ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
605ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int ret = 0;
606ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
607ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    for (uint32_t i = 0; i < numDisplays; i++) {
608ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        hwc_display_contents_1_t* list = displays[i];
609a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        int dpy = getDpyforExternalDisplay(ctx, i);
610a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        switch(dpy) {
611ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            case HWC_DISPLAY_PRIMARY:
612ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = hwc_set_primary(ctx, list);
613ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
614ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            case HWC_DISPLAY_EXTERNAL:
615ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = hwc_set_external(ctx, list);
616ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
617ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            case HWC_DISPLAY_VIRTUAL:
618a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                if(ctx->mHWCVirtual)
619a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson                    ret = ctx->mHWCVirtual->set(ctx, list);
620ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                break;
621ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            default:
622ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = -EINVAL;
623ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
624ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
625ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    // This is only indicative of how many times SurfaceFlinger posts
626ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    // frames to the display.
627ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    CALC_FPS();
628ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    MDPComp::resetIdleFallBack();
629ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mVideoTransFlag = false;
630a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if(ctx->mRotMgr->getNumActiveSessions() == 0)
631a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        Overlay::setDMAMode(Overlay::DMA_LINE_MODE);
632ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    //Was locked at the beginning of prepare
633ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mDrawLock.unlock();
634ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return ret;
635ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
636ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
637ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
638ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        uint32_t* configs, size_t* numConfigs) {
639ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int ret = 0;
640ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
641a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    disp = getDpyforExternalDisplay(ctx, disp);
642ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    //in 1.1 there is no way to choose a config, report as config id # 0
643ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    //This config is passed to getDisplayAttributes. Ignore for now.
644ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    switch(disp) {
645ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_PRIMARY:
646ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            if(*numConfigs > 0) {
647ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                configs[0] = 0;
648ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                *numConfigs = 1;
649ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
650ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = 0; //NO_ERROR
651ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
652ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_EXTERNAL:
653a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        case HWC_DISPLAY_VIRTUAL:
654ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ret = -1; //Not connected
655a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            if(ctx->dpyAttr[disp].connected) {
656ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                ret = 0; //NO_ERROR
657ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                if(*numConfigs > 0) {
658ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                    configs[0] = 0;
659ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                    *numConfigs = 1;
660ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                }
661ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            }
662ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
663ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
664ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return ret;
665ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
666ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
667ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonint hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
668a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        uint32_t /*config*/, const uint32_t* attributes, int32_t* values) {
669ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
670ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
671a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    disp = getDpyforExternalDisplay(ctx, disp);
672a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error
673a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) {
674ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -1;
675ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
676ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
677ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    //From HWComposer
678ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    static const uint32_t DISPLAY_ATTRIBUTES[] = {
679ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        HWC_DISPLAY_VSYNC_PERIOD,
680ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        HWC_DISPLAY_WIDTH,
681ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        HWC_DISPLAY_HEIGHT,
682ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        HWC_DISPLAY_DPI_X,
683ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        HWC_DISPLAY_DPI_Y,
684ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        HWC_DISPLAY_NO_ATTRIBUTE,
685ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    };
686ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
687ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
688ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            sizeof(DISPLAY_ATTRIBUTES)[0]);
689ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
690ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
691ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        switch (attributes[i]) {
692ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_VSYNC_PERIOD:
693ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            values[i] = ctx->dpyAttr[disp].vsync_period;
694ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
695ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_WIDTH:
696ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            values[i] = ctx->dpyAttr[disp].xres;
697ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
698ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                    ctx->dpyAttr[disp].xres);
699ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
700ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_HEIGHT:
701ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            values[i] = ctx->dpyAttr[disp].yres;
702ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
703ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                    ctx->dpyAttr[disp].yres);
704ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
705ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_DPI_X:
706ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
707ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
708ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        case HWC_DISPLAY_DPI_Y:
709ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
710ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            break;
711ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        default:
712ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ALOGE("Unknown display attribute %d",
713ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                    attributes[i]);
714ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            return -EINVAL;
715ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        }
716ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
717ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
718ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
719ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
720ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonvoid hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
721ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
722ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    hwc_context_t* ctx = (hwc_context_t*)(dev);
723ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    Locker::Autolock _l(ctx->mDrawLock);
724ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    android::String8 aBuf("");
725ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    dumpsys_log(aBuf, "Qualcomm HWC state:\n");
726ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
727ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
728a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson    for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) {
729ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        if(ctx->mMDPComp[dpy])
730ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson            ctx->mMDPComp[dpy]->dump(aBuf);
731ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
732ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    char ovDump[2048] = {'\0'};
733ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mOverlay->getDump(ovDump, 2048);
734ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    dumpsys_log(aBuf, ovDump);
735ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ovDump[0] = '\0';
736ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ctx->mRotMgr->getDump(ovDump, 1024);
737ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    dumpsys_log(aBuf, ovDump);
738ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    ovDump[0] = '\0';
739ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if(Writeback::getDump(ovDump, 1024)) {
740ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dumpsys_log(aBuf, ovDump);
741ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ovDump[0] = '\0';
742ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
743ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    strlcpy(buff, aBuf.string(), buff_len);
744ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
745ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
746ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_device_close(struct hw_device_t *dev)
747ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
748ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if(!dev) {
749ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        ALOGE("%s: NULL device pointer", __FUNCTION__);
750ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        return -1;
751ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
752ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    closeContext((hwc_context_t*)dev);
753ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    free(dev);
754ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
755ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return 0;
756ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
757ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
758ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilsonstatic int hwc_device_open(const struct hw_module_t* module, const char* name,
759ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson                           struct hw_device_t** device)
760ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson{
761ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    int status = -EINVAL;
762ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
763ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
764ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        struct hwc_context_t *dev;
765ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev = (hwc_context_t*)malloc(sizeof(*dev));
766a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson        if(dev == NULL)
767a653efede03423aa840da24634f1ec6f20796f1eSimon Wilson            return status;
768ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        memset(dev, 0, sizeof(*dev));
769ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
770ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        //Initialize hwc context
771ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        initContext(dev);
772ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson
773ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        //Setup HWC methods
774ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
775ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_3;
776ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.common.module       = const_cast<hw_module_t*>(module);
777ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.common.close        = hwc_device_close;
778ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.prepare             = hwc_prepare;
779ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.set                 = hwc_set;
780ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.eventControl        = hwc_eventControl;
781ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.blank               = hwc_blank;
782ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.query               = hwc_query;
783ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.registerProcs       = hwc_registerProcs;
784ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.dump                = hwc_dump;
785ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
786ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
787ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        *device = &dev->device.common;
788ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson        status = 0;
789ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    }
790ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson    return status;
791ef53c1c84ec55ed50f607d52b7abfbb86239408eSimon Wilson}
792