1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2012-2016, The Linux Foundation. All rights reserved.
4 *
5 * Not a Contribution, Apache license notifications and license are retained
6 * for attribution purposes only.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
21#include <fcntl.h>
22#include <errno.h>
23
24#include <cutils/log.h>
25#include <cutils/atomic.h>
26#include <EGL/egl.h>
27#include <utils/Trace.h>
28#include <sys/ioctl.h>
29#include <overlay.h>
30#include <overlayRotator.h>
31#include <overlayWriteback.h>
32#include <mdp_version.h>
33#include "hwc_utils.h"
34#include "hwc_fbupdate.h"
35#include "hwc_mdpcomp.h"
36#include "hwc_dump_layers.h"
37#include "hdmi.h"
38#include "hwc_copybit.h"
39#include "hwc_ad.h"
40#include "profiler.h"
41#include "hwc_virtual.h"
42#include "hwc_qdcm.h"
43
44using namespace qhwc;
45using namespace overlay;
46using namespace qQdcm;
47
48#define VSYNC_DEBUG 0
49#define POWER_MODE_DEBUG 1
50
51static int hwc_device_open(const struct hw_module_t* module,
52                           const char* name,
53                           struct hw_device_t** device);
54
55static struct hw_module_methods_t hwc_module_methods = {
56    .open = hwc_device_open
57};
58
59static void reset_panel(struct hwc_composer_device_1* dev);
60
61hwc_module_t HAL_MODULE_INFO_SYM = {
62    .common = {
63        .tag = HARDWARE_MODULE_TAG,
64        .version_major = 2,
65        .version_minor = 0,
66        .id = HWC_HARDWARE_MODULE_ID,
67        .name = "Qualcomm Hardware Composer Module",
68        .author = "CodeAurora Forum",
69        .methods = &hwc_module_methods,
70        .dso = 0,
71        .reserved = {0},
72    }
73};
74
75/*
76 * Save callback functions registered to HWC
77 */
78static void hwc_registerProcs(struct hwc_composer_device_1* dev,
79                              hwc_procs_t const* procs)
80{
81    ALOGI("%s", __FUNCTION__);
82    hwc_context_t* ctx = (hwc_context_t*)(dev);
83    if(!ctx) {
84        ALOGE("%s: Invalid context", __FUNCTION__);
85        return;
86    }
87    ctx->proc = procs;
88
89    // Now that we have the functions needed, kick off
90    // the uevent & vsync threads
91    init_uevent_thread(ctx);
92    init_vsync_thread(ctx);
93}
94
95static void setPaddingRound(hwc_context_t *ctx, int numDisplays,
96                            hwc_display_contents_1_t** displays) {
97    ctx->isPaddingRound = false;
98    for(int i = 0; i < numDisplays; i++) {
99        hwc_display_contents_1_t *list = displays[i];
100        if (LIKELY(list && list->numHwLayers > 0)) {
101            if((ctx->mPrevHwLayerCount[i] == 1 or
102                ctx->mPrevHwLayerCount[i] == 0) and
103               (list->numHwLayers > 1)) {
104                /* If the previous cycle for dpy 'i' has 0 AppLayers and the
105                 * current cycle has atleast 1 AppLayer, padding round needs
106                 * to be invoked in current cycle on all the active displays
107                 * to free up the resources.
108                 */
109                ctx->isPaddingRound = true;
110            }
111            ctx->mPrevHwLayerCount[i] = (int)list->numHwLayers;
112        } else {
113            ctx->mPrevHwLayerCount[i] = 0;
114        }
115    }
116}
117
118/* Based on certain conditions, isPaddingRound will be set
119 * to make this function self-contained */
120static void setDMAState(hwc_context_t *ctx, int numDisplays,
121                        hwc_display_contents_1_t** displays) {
122
123    if(ctx->mRotMgr->getNumActiveSessions() == 0)
124        Overlay::setDMAMode(Overlay::DMA_LINE_MODE);
125
126    for(int dpy = 0; dpy < numDisplays; dpy++) {
127        hwc_display_contents_1_t *list = displays[dpy];
128        if (LIKELY(list && list->numHwLayers > 0)) {
129            for(size_t layerIndex = 0; layerIndex < list->numHwLayers;
130                                                  layerIndex++) {
131                if(list->hwLayers[layerIndex].compositionType !=
132                                            HWC_FRAMEBUFFER_TARGET)
133                {
134                    hwc_layer_1_t const* layer = &list->hwLayers[layerIndex];
135                    private_handle_t *hnd = (private_handle_t *)layer->handle;
136
137                    /* If a layer requires rotation, set the DMA state
138                     * to BLOCK_MODE */
139
140                    if (canUseRotator(ctx, dpy) &&
141                        (has90Transform(layer) || getRotDownscale(ctx, layer))
142                        && isRotationDoable(ctx, hnd)) {
143                        if(not (ctx->mOverlay->isDMAMultiplexingSupported() &&
144                                          dpy)) {
145                            if(ctx->mOverlay->isPipeTypeAttached(
146                                             overlay::utils::OV_MDP_PIPE_DMA))
147                                ctx->isPaddingRound = true;
148                        }
149                        Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
150                    }
151                }
152            }
153            if(dpy) {
154                /* Uncomment the below code for testing purpose.
155                   Assuming the orientation value is in terms of HAL_TRANSFORM,
156                   this needs mapping to HAL, if its in different convention */
157
158                /* char value[PROPERTY_VALUE_MAX];
159                   property_get("sys.ext_orientation", value, "0");
160                   ctx->mExtOrientation = atoi(value);*/
161
162                if(ctx->mExtOrientation || ctx->mBufferMirrorMode) {
163                    if(ctx->mOverlay->isPipeTypeAttached(
164                                         overlay::utils::OV_MDP_PIPE_DMA)) {
165                        ctx->isPaddingRound = true;
166                    }
167                    Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
168                }
169            }
170        }
171    }
172}
173
174static void setNumActiveDisplays(hwc_context_t *ctx, int numDisplays,
175                            hwc_display_contents_1_t** displays) {
176
177    ctx->numActiveDisplays = 0;
178    for(int i = 0; i < numDisplays; i++) {
179        hwc_display_contents_1_t *list = displays[i];
180        if (LIKELY(list && list->numHwLayers > 0)) {
181            /* For display devices like SSD and screenrecord, we cannot
182             * rely on isActive and connected attributes of dpyAttr to
183             * determine if the displaydevice is active. Hence in case if
184             * the layer-list is non-null and numHwLayers > 0, we assume
185             * the display device to be active.
186             */
187            ctx->numActiveDisplays += 1;
188        }
189    }
190}
191
192static bool validDisplay(int disp) {
193    switch(disp) {
194        case HWC_DISPLAY_PRIMARY:
195        case HWC_DISPLAY_EXTERNAL:
196        case HWC_DISPLAY_VIRTUAL:
197            return true;
198            break;
199        default:
200            return false;
201    }
202}
203
204static void reset(hwc_context_t *ctx, int numDisplays,
205                  hwc_display_contents_1_t** displays) {
206
207
208    for(int i = 0; i < numDisplays; i++) {
209        hwc_display_contents_1_t *list = displays[i];
210        // XXX:SurfaceFlinger no longer guarantees that this
211        // value is reset on every prepare. However, for the layer
212        // cache we need to reset it.
213        // We can probably rethink that later on
214        if (LIKELY(list && list->numHwLayers > 0)) {
215            for(size_t j = 0; j < list->numHwLayers; j++) {
216                if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
217                    list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
218            }
219
220        }
221
222        if(ctx->mMDPComp[i])
223            ctx->mMDPComp[i]->reset();
224        if(ctx->mFBUpdate[i])
225            ctx->mFBUpdate[i]->reset();
226        if(ctx->mCopyBit[i])
227            ctx->mCopyBit[i]->reset();
228        if(ctx->mLayerRotMap[i])
229            ctx->mLayerRotMap[i]->reset();
230    }
231
232    ctx->mAD->reset();
233
234}
235
236static void scaleDisplayFrame(hwc_context_t *ctx, int dpy,
237                            hwc_display_contents_1_t *list) {
238    uint32_t origXres = ctx->dpyAttr[dpy].xres;
239    uint32_t origYres = ctx->dpyAttr[dpy].yres;
240    uint32_t newXres = ctx->dpyAttr[dpy].xres_new;
241    uint32_t newYres = ctx->dpyAttr[dpy].yres_new;
242    float xresRatio = (float)origXres / (float)newXres;
243    float yresRatio = (float)origYres / (float)newYres;
244    for (size_t i = 0; i < list->numHwLayers; i++) {
245        hwc_layer_1_t *layer = &list->hwLayers[i];
246        hwc_rect_t& displayFrame = layer->displayFrame;
247        uint32_t layerWidth = displayFrame.right - displayFrame.left;
248        uint32_t layerHeight = displayFrame.bottom - displayFrame.top;
249        displayFrame.left = (int)(xresRatio * (float)displayFrame.left);
250        displayFrame.top = (int)(yresRatio * (float)displayFrame.top);
251        displayFrame.right = (int)((float)displayFrame.left +
252                                   (float)layerWidth * xresRatio);
253        displayFrame.bottom = (int)((float)displayFrame.top +
254                                    (float)layerHeight * yresRatio);
255    }
256}
257
258static int hwc_prepare_primary(hwc_composer_device_1 *dev,
259        hwc_display_contents_1_t *list) {
260    ATRACE_CALL();
261    hwc_context_t* ctx = (hwc_context_t*)(dev);
262    const int dpy = HWC_DISPLAY_PRIMARY;
263    bool fbComp = false;
264    static int compStart = false;
265    if (!ctx->mBootAnimCompleted)
266        processBootAnimCompleted(ctx);
267
268    if (LIKELY(list && (list->numHwLayers > 1 ||
269                    (ctx->mMDP.version < qdutils::MDP_V4_0 && compStart))) &&
270            (ctx->dpyAttr[dpy].isActive ||
271             ctx->mHDMIDisplay->isHDMIPrimaryDisplay())
272            && !ctx->dpyAttr[dpy].isPause) {
273        compStart = true;
274
275        // When HDMI is primary we should rely on the first valid
276        // draw call in order to activate the display
277        if (!ctx->dpyAttr[dpy].isActive) {
278            // If the cable is connected after HWC initialization and before
279            // the UEvent thread is initialized then we will miss the ONLINE
280            // event. We need to update the display appropriately when we get
281            // the first valid frame.
282            int cableConnected = ctx->mHDMIDisplay->getConnectedState();
283            if ((cableConnected == 1) && !ctx->dpyAttr[dpy].connected) {
284                qhwc::handle_online(ctx, dpy);
285            }
286            ctx->mHDMIDisplay->activateDisplay();
287            ctx->dpyAttr[dpy].isActive = true;
288        }
289
290        if (ctx->dpyAttr[dpy].customFBSize &&
291                list->flags & HWC_GEOMETRY_CHANGED)
292            scaleDisplayFrame(ctx, dpy, list);
293
294        reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
295        setListStats(ctx, list, dpy);
296
297        fbComp = (ctx->mMDPComp[dpy]->prepare(ctx, list) < 0);
298
299        if (fbComp) {
300            const int fbZ = 0;
301            if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ)) {
302                ctx->mOverlay->clear(dpy);
303                ctx->mLayerRotMap[dpy]->clear();
304            }
305        }
306
307        if (ctx->mMDP.version < qdutils::MDP_V4_0) {
308            if(ctx->mCopyBit[dpy])
309                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
310        }
311        setGPUHint(ctx, list);
312    }
313    return 0;
314}
315
316static int hwc_prepare_external(hwc_composer_device_1 *dev,
317        hwc_display_contents_1_t *list) {
318    ATRACE_CALL();
319    hwc_context_t* ctx = (hwc_context_t*)(dev);
320    const int dpy = HWC_DISPLAY_EXTERNAL;
321
322    if (LIKELY(list && list->numHwLayers > 1) &&
323            ctx->dpyAttr[dpy].isActive &&
324            ctx->dpyAttr[dpy].connected) {
325        reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
326        if(!ctx->dpyAttr[dpy].isPause) {
327            ctx->dpyAttr[dpy].isConfiguring = false;
328            setListStats(ctx, list, dpy);
329            if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
330                const int fbZ = 0;
331                if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ))
332                {
333                    ctx->mOverlay->clear(dpy);
334                    ctx->mLayerRotMap[dpy]->clear();
335                }
336            }
337        } else {
338            /* External Display is in Pause state.
339             * Mark all application layers as OVERLAY so that
340             * GPU will not compose.
341             */
342            for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) {
343                hwc_layer_1_t *layer = &list->hwLayers[i];
344                layer->compositionType = HWC_OVERLAY;
345            }
346        }
347    }
348    return 0;
349}
350
351static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
352                       hwc_display_contents_1_t** displays)
353{
354    int ret = 0;
355    hwc_context_t* ctx = (hwc_context_t*)(dev);
356
357    if (ctx->mPanelResetStatus) {
358        ALOGW("%s: panel is in bad state. reset the panel", __FUNCTION__);
359        reset_panel(dev);
360    }
361
362    //Will be unlocked at the end of set
363    ctx->mDrawLock.lock();
364    setPaddingRound(ctx, (int)numDisplays, displays);
365    setDMAState(ctx, (int)numDisplays, displays);
366    setNumActiveDisplays(ctx, (int)numDisplays, displays);
367    reset(ctx, (int)numDisplays, displays);
368
369    ctx->mOverlay->configBegin();
370    ctx->mRotMgr->configBegin();
371    overlay::Writeback::configBegin();
372
373    for (int32_t dpy = ((int32_t)numDisplays-1); dpy >=0 ; dpy--) {
374        hwc_display_contents_1_t *list = displays[dpy];
375        resetROI(ctx, dpy);
376        switch(dpy) {
377            case HWC_DISPLAY_PRIMARY:
378                ret = hwc_prepare_primary(dev, list);
379                break;
380            case HWC_DISPLAY_EXTERNAL:
381                ret = hwc_prepare_external(dev, list);
382                break;
383            case HWC_DISPLAY_VIRTUAL:
384                if(ctx->mHWCVirtual)
385                    ret = ctx->mHWCVirtual->prepare(dev, list);
386                break;
387            default:
388                ret = -EINVAL;
389        }
390    }
391
392    ctx->mOverlay->configDone();
393    ctx->mRotMgr->configDone();
394    overlay::Writeback::configDone();
395    // If VD list is deleted, mdp overlay pipe objects and writeback object
396    // are deleted as part of configDone functions.
397    // Proceed with HWCVirtualVDS object deletion.
398    if(ctx->mHWCVirtual)
399        ctx->mHWCVirtual->destroy(ctx, numDisplays, displays);
400
401    return ret;
402}
403
404static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
405                             int event, int enable)
406{
407    ATRACE_CALL();
408    int ret = 0;
409    hwc_context_t* ctx = (hwc_context_t*)(dev);
410    if(!validDisplay(dpy)) {
411        return -EINVAL;
412    }
413
414    switch(event) {
415        case HWC_EVENT_VSYNC:
416            if (ctx->vstate.enable == enable)
417                break;
418            ret = hwc_vsync_control(ctx, dpy, enable);
419            if(ret == 0)
420                ctx->vstate.enable = !!enable;
421            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
422                      (enable)?"ENABLED":"DISABLED");
423            break;
424#ifdef QTI_BSP
425        case  HWC_EVENT_ORIENTATION:
426            if(dpy == HWC_DISPLAY_PRIMARY) {
427                Locker::Autolock _l(ctx->mDrawLock);
428                // store the primary display orientation
429                ctx->deviceOrientation = enable;
430            }
431            break;
432#endif
433        default:
434            ret = -EINVAL;
435    }
436    return ret;
437}
438
439static int hwc_setPowerMode(struct hwc_composer_device_1* dev, int dpy,
440        int mode)
441{
442    ATRACE_CALL();
443    hwc_context_t* ctx = (hwc_context_t*)(dev);
444    int ret = 0, value = 0;
445
446    Locker::Autolock _l(ctx->mDrawLock);
447
448    if(!validDisplay(dpy)) {
449        return -EINVAL;
450    }
451
452    ALOGD_IF(POWER_MODE_DEBUG, "%s: Setting mode %d on display: %d",
453            __FUNCTION__, mode, dpy);
454
455    switch(mode) {
456        case HWC_POWER_MODE_OFF:
457            // free up all the overlay pipes in use
458            // when we get a blank for either display
459            // makes sure that all pipes are freed
460            ctx->mOverlay->configBegin();
461            ctx->mOverlay->configDone();
462            ctx->mRotMgr->clear();
463            // If VDS is connected, do not clear WB object as it
464            // will end up detaching IOMMU. This is required
465            // to send black frame to WFD sink on power suspend.
466            // Note: With this change, we keep the WriteBack object
467            // alive on power suspend for AD use case.
468            value = FB_BLANK_POWERDOWN;
469            break;
470        case HWC_POWER_MODE_DOZE:
471        case HWC_POWER_MODE_DOZE_SUSPEND:
472            value = FB_BLANK_VSYNC_SUSPEND;
473            break;
474        case HWC_POWER_MODE_NORMAL:
475            value = FB_BLANK_UNBLANK;
476            break;
477    }
478
479    switch(dpy) {
480    case HWC_DISPLAY_PRIMARY:
481        if(ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
482            if(ctx->dpyAttr[dpy].connected) {
483                // When HDMI is connected as primary we clean up resources
484                // and call commit to generate a black frame on the interface.
485                // However, we do not call blank since we need the timing
486                // generator and HDMI core to remain turned on.
487                if((mode == HWC_POWER_MODE_OFF) &&
488                        (!Overlay::displayCommit(ctx->dpyAttr[dpy].fd))) {
489                    ALOGE("%s: display commit fail for %d", __FUNCTION__, dpy);
490                    ret = -1;
491                }
492            }
493        } else {
494            if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) {
495                ALOGE("%s: ioctl FBIOBLANK failed for Primary with error %s"
496                        " value %d", __FUNCTION__, strerror(errno), value);
497                return -errno;
498            }
499
500            if(mode == HWC_POWER_MODE_NORMAL) {
501                // Enable HPD here, as during bootup POWER_MODE_NORMAL is set
502                // when SF is completely initialized
503                ctx->mHDMIDisplay->setHPD(1);
504            }
505
506            ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
507        }
508        //Deliberate fall through since there is no explicit power mode for
509        //virtual displays.
510    case HWC_DISPLAY_VIRTUAL:
511        if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) {
512            const int dpy = HWC_DISPLAY_VIRTUAL;
513            if(mode == HWC_POWER_MODE_OFF and
514                    (not ctx->dpyAttr[dpy].isPause)) {
515                if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
516                    ALOGE("%s: displayCommit failed for virtual", __FUNCTION__);
517                    ret = -1;
518                }
519            }
520            ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
521        }
522        break;
523    case HWC_DISPLAY_EXTERNAL:
524        if(mode == HWC_POWER_MODE_OFF) {
525            if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
526                ALOGE("%s: displayCommit failed for external", __FUNCTION__);
527                ret = -1;
528            }
529        }
530        ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
531        break;
532    default:
533        return -EINVAL;
534    }
535
536    ALOGD_IF(POWER_MODE_DEBUG, "%s: Done setting mode %d on display %d",
537            __FUNCTION__, mode, dpy);
538    return ret;
539}
540
541static void reset_panel(struct hwc_composer_device_1* dev)
542{
543    int ret = 0;
544    hwc_context_t* ctx = (hwc_context_t*)(dev);
545
546    if (!ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
547        ALOGD ("%s : Display OFF - Skip BLANK & UNBLANK", __FUNCTION__);
548        ctx->mPanelResetStatus = false;
549        return;
550    }
551
552    ALOGD("%s: setting power mode off", __FUNCTION__);
553    ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_OFF);
554    if (ret < 0) {
555        ALOGE("%s: FBIOBLANK failed to BLANK:  %s", __FUNCTION__,
556                strerror(errno));
557    }
558
559    ALOGD("%s: setting power mode normal and enabling vsync", __FUNCTION__);
560    ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_NORMAL);
561    if (ret < 0) {
562        ALOGE("%s: FBIOBLANK failed to UNBLANK : %s", __FUNCTION__,
563                strerror(errno));
564    }
565    hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1);
566
567    ctx->mPanelResetStatus = false;
568}
569
570
571static int hwc_query(struct hwc_composer_device_1* dev,
572                     int param, int* value)
573{
574    hwc_context_t* ctx = (hwc_context_t*)(dev);
575    int supported = HWC_DISPLAY_PRIMARY_BIT;
576
577    switch (param) {
578    case HWC_BACKGROUND_LAYER_SUPPORTED:
579        // Not supported for now
580        value[0] = 0;
581        break;
582    case HWC_DISPLAY_TYPES_SUPPORTED:
583        if(ctx->mMDP.hasOverlay) {
584            supported |= HWC_DISPLAY_VIRTUAL_BIT;
585            if(!(qdutils::MDPVersion::getInstance().is8x26() ||
586                        qdutils::MDPVersion::getInstance().is8x16() ||
587                        qdutils::MDPVersion::getInstance().is8x39()))
588                supported |= HWC_DISPLAY_EXTERNAL_BIT;
589        }
590        value[0] = supported;
591        break;
592    case HWC_FORMAT_RB_SWAP:
593        value[0] = 1;
594        break;
595    case HWC_COLOR_FILL:
596        value[0] = 1;
597        break;
598    default:
599        return -EINVAL;
600    }
601    return 0;
602
603}
604
605
606static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
607    ATRACE_CALL();
608    int ret = 0;
609    const int dpy = HWC_DISPLAY_PRIMARY;
610    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive
611            && !ctx->dpyAttr[dpy].isPause) {
612        size_t last = list->numHwLayers - 1;
613        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
614        int fd = -1; //FenceFD from the Copybit(valid in async mode)
615        bool copybitDone = false;
616
617        if (ctx->mCopyBit[dpy]) {
618            if (ctx->mMDP.version < qdutils::MDP_V4_0)
619                copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
620            else
621                fd = ctx->mMDPComp[dpy]->drawOverlap(ctx, list);
622        }
623
624        if(list->numHwLayers > 1)
625            hwc_sync(ctx, list, dpy, fd);
626
627        // Dump the layers for primary
628        if(ctx->mHwcDebug[dpy])
629            ctx->mHwcDebug[dpy]->dumpLayers(list);
630
631        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
632            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
633            ret = -1;
634        }
635
636        //TODO We dont check for SKIP flag on this layer because we need PAN
637        //always. Last layer is always FB
638        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
639        if(copybitDone && ((ctx->mMDP.version >= qdutils::MDP_V4_0)
640#ifdef SUPPORT_BLIT_TO_FB
641                            || (ctx->mMDP.version == qdutils::MDP_V3_0_5)
642#endif
643        )) {
644            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
645        }
646
647        if(isAbcInUse(ctx) == true) {
648            int index = ctx->listStats[dpy].renderBufIndexforABC;
649            hwc_layer_1_t *tempLayer = &list->hwLayers[index];
650            hnd = (private_handle_t *)tempLayer->handle;
651        }
652
653        if(hnd) {
654            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
655                ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
656                ret = -1;
657            }
658        }
659
660        int lSplit = getLeftSplit(ctx, dpy);
661        qhwc::ovutils::Dim lRoi = qhwc::ovutils::Dim(
662            ctx->listStats[dpy].lRoi.left,
663            ctx->listStats[dpy].lRoi.top,
664            ctx->listStats[dpy].lRoi.right - ctx->listStats[dpy].lRoi.left,
665            ctx->listStats[dpy].lRoi.bottom - ctx->listStats[dpy].lRoi.top);
666
667        qhwc::ovutils::Dim rRoi = qhwc::ovutils::Dim(
668            ctx->listStats[dpy].rRoi.left - lSplit,
669            ctx->listStats[dpy].rRoi.top,
670            ctx->listStats[dpy].rRoi.right - ctx->listStats[dpy].rRoi.left,
671            ctx->listStats[dpy].rRoi.bottom - ctx->listStats[dpy].rRoi.top);
672
673        if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd, lRoi, rRoi)) {
674            ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
675            ret = -1;
676        }
677
678    }
679
680    closeAcquireFds(list);
681    return ret;
682}
683
684static int hwc_set_external(hwc_context_t *ctx,
685                            hwc_display_contents_1_t* list)
686{
687    ATRACE_CALL();
688    int ret = 0;
689
690    const int dpy = HWC_DISPLAY_EXTERNAL;
691
692    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
693        ctx->dpyAttr[dpy].connected &&
694        !ctx->dpyAttr[dpy].isPause) {
695        size_t last = list->numHwLayers - 1;
696        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
697        int fd = -1; //FenceFD from the Copybit(valid in async mode)
698        bool copybitDone = false;
699        if(ctx->mCopyBit[dpy])
700            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
701
702        if(list->numHwLayers > 1)
703            hwc_sync(ctx, list, dpy, fd);
704
705        // Dump the layers for external
706        if(ctx->mHwcDebug[dpy])
707            ctx->mHwcDebug[dpy]->dumpLayers(list);
708
709        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
710            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
711            ret = -1;
712        }
713
714        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
715        if(copybitDone) {
716            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
717        }
718
719        if(hnd) {
720            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
721                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
722                ret = -1;
723            }
724        }
725
726        if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
727            ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
728            ret = -1;
729        }
730    }
731
732    closeAcquireFds(list);
733    return ret;
734}
735
736static int hwc_set(hwc_composer_device_1 *dev,
737                   size_t numDisplays,
738                   hwc_display_contents_1_t** displays)
739{
740    int ret = 0;
741    hwc_context_t* ctx = (hwc_context_t*)(dev);
742    for (int dpy = 0; dpy < (int)numDisplays; dpy++) {
743        hwc_display_contents_1_t* list = displays[dpy];
744        switch(dpy) {
745            case HWC_DISPLAY_PRIMARY:
746                ret = hwc_set_primary(ctx, list);
747                break;
748            case HWC_DISPLAY_EXTERNAL:
749                ret = hwc_set_external(ctx, list);
750                break;
751            case HWC_DISPLAY_VIRTUAL:
752                if(ctx->mHWCVirtual)
753                    ret = ctx->mHWCVirtual->set(ctx, list);
754                break;
755            default:
756                ret = -EINVAL;
757        }
758    }
759    // This is only indicative of how many times SurfaceFlinger posts
760    // frames to the display.
761    CALC_FPS();
762    MDPComp::resetIdleFallBack();
763    ctx->mVideoTransFlag = false;
764    //Was locked at the beginning of prepare
765    ctx->mDrawLock.unlock();
766    return ret;
767}
768
769int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
770        uint32_t* configs, size_t* numConfigs) {
771    int ret = 0;
772    hwc_context_t* ctx = (hwc_context_t*)(dev);
773
774    Locker::Autolock _l(ctx->mDrawLock);
775
776    if(!validDisplay(disp)) {
777        return -EINVAL;
778    }
779    //Currently we allow only 1 config, reported as config id # 0
780    //This config is passed in to getDisplayAttributes. Ignored for now.
781
782    switch(disp) {
783        case HWC_DISPLAY_PRIMARY:
784            if(*numConfigs > 0) {
785                configs[0] = 0;
786                *numConfigs = 1;
787            }
788            ret = 0; //NO_ERROR
789            break;
790        case HWC_DISPLAY_EXTERNAL:
791        case HWC_DISPLAY_VIRTUAL:
792            ret = -1; //Not connected
793            if(ctx->dpyAttr[disp].connected) {
794                ret = 0; //NO_ERROR
795                if(*numConfigs > 0) {
796                    configs[0] = 0;
797                    *numConfigs = 1;
798                }
799            }
800            break;
801    }
802    return ret;
803}
804
805int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
806        uint32_t /*config*/, const uint32_t* attributes, int32_t* values) {
807
808    hwc_context_t* ctx = (hwc_context_t*)(dev);
809
810    Locker::Autolock _l(ctx->mDrawLock);
811
812    if(!validDisplay(disp)) {
813        return -EINVAL;
814    }
815    //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error
816    if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) {
817        return -1;
818    }
819
820    //From HWComposer
821    static const uint32_t DISPLAY_ATTRIBUTES[] = {
822        HWC_DISPLAY_VSYNC_PERIOD,
823        HWC_DISPLAY_WIDTH,
824        HWC_DISPLAY_HEIGHT,
825        HWC_DISPLAY_DPI_X,
826        HWC_DISPLAY_DPI_Y,
827#ifdef GET_FRAMEBUFFER_FORMAT_FROM_HWC
828        HWC_DISPLAY_FBFORMAT,
829#endif
830        HWC_DISPLAY_NO_ATTRIBUTE,
831    };
832
833    const size_t NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
834            sizeof(DISPLAY_ATTRIBUTES)[0]);
835
836    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
837        switch (attributes[i]) {
838        case HWC_DISPLAY_VSYNC_PERIOD:
839            values[i] = ctx->dpyAttr[disp].vsync_period;
840            break;
841        case HWC_DISPLAY_WIDTH:
842            if (ctx->dpyAttr[disp].customFBSize)
843                values[i] = ctx->dpyAttr[disp].xres_new;
844            else
845                values[i] = ctx->dpyAttr[disp].xres;
846
847            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
848                    values[i]);
849            break;
850        case HWC_DISPLAY_HEIGHT:
851            if (ctx->dpyAttr[disp].customFBSize)
852                values[i] = ctx->dpyAttr[disp].yres_new;
853            else
854                values[i] = ctx->dpyAttr[disp].yres;
855            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
856                    values[i]);
857            break;
858        case HWC_DISPLAY_DPI_X:
859            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
860            break;
861        case HWC_DISPLAY_DPI_Y:
862            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
863            break;
864#ifdef GET_FRAMEBUFFER_FORMAT_FROM_HWC
865        case HWC_DISPLAY_FBFORMAT:
866            values[i] = ctx->dpyAttr[disp].fbformat;
867            break;
868#endif
869        default:
870            ALOGE("Unknown display attribute %d",
871                    attributes[i]);
872            return -EINVAL;
873        }
874    }
875    return 0;
876}
877
878void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
879{
880    hwc_context_t* ctx = (hwc_context_t*)(dev);
881    Locker::Autolock _l(ctx->mDrawLock);
882    android::String8 aBuf("");
883    dumpsys_log(aBuf, "Qualcomm HWC state:\n");
884    dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
885    dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
886    dumpsys_log(aBuf, "  DynRefreshRate=%d\n",
887                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].dynRefreshRate);
888    for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) {
889        if(ctx->mMDPComp[dpy])
890            ctx->mMDPComp[dpy]->dump(aBuf, ctx);
891    }
892    char ovDump[2048] = {'\0'};
893    ctx->mOverlay->getDump(ovDump, 2048);
894    dumpsys_log(aBuf, ovDump);
895    ovDump[0] = '\0';
896    ctx->mRotMgr->getDump(ovDump, 1024);
897    dumpsys_log(aBuf, ovDump);
898    ovDump[0] = '\0';
899    if(Writeback::getDump(ovDump, 1024)) {
900        dumpsys_log(aBuf, ovDump);
901        ovDump[0] = '\0';
902    }
903    dumpsys_log(aBuf, "Copybit::isAbcInUse=%d\n\n",isAbcInUse(ctx) ? 1 : 0);
904    strlcpy(buff, aBuf.string(), buff_len);
905}
906
907int hwc_getActiveConfig(struct hwc_composer_device_1* dev, int disp) {
908    hwc_context_t* ctx = (hwc_context_t*)(dev);
909    Locker::Autolock _l(ctx->mDrawLock);
910    if(!validDisplay(disp)) {
911        return -EINVAL;
912    }
913
914    //Supports only the default config (0th index) for now
915    return 0;
916}
917
918int hwc_setActiveConfig(struct hwc_composer_device_1* dev, int disp,
919        int index) {
920    hwc_context_t* ctx = (hwc_context_t*)(dev);
921    Locker::Autolock _l(ctx->mDrawLock);
922    if(!validDisplay(disp)) {
923        return -EINVAL;
924    }
925
926    //Supports only the default config (0th index) for now
927    return (index == 0) ? index : -EINVAL;
928}
929
930static int hwc_device_close(struct hw_device_t *dev)
931{
932    if(!dev) {
933        ALOGE("%s: NULL device pointer", __FUNCTION__);
934        return -1;
935    }
936    closeContext((hwc_context_t*)dev);
937    free(dev);
938
939    return 0;
940}
941
942static int hwc_device_open(const struct hw_module_t* module, const char* name,
943                           struct hw_device_t** device)
944{
945    int status = -EINVAL;
946
947    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
948        struct hwc_context_t *dev;
949        dev = (hwc_context_t*)malloc(sizeof(*dev));
950        if(dev == NULL)
951            return status;
952        memset(dev, 0, sizeof(*dev));
953
954        //Initialize hwc context
955        initContext(dev);
956
957        //Setup HWC methods
958        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
959        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_5;
960        dev->device.common.module       = const_cast<hw_module_t*>(module);
961        dev->device.common.close        = hwc_device_close;
962        dev->device.prepare             = hwc_prepare;
963        dev->device.set                 = hwc_set;
964        dev->device.eventControl        = hwc_eventControl;
965        dev->device.setPowerMode        = hwc_setPowerMode;
966        dev->device.query               = hwc_query;
967        dev->device.registerProcs       = hwc_registerProcs;
968        dev->device.dump                = hwc_dump;
969        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
970        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
971        dev->device.getActiveConfig     = hwc_getActiveConfig;
972        dev->device.setActiveConfig     = hwc_setActiveConfig;
973        *device = &dev->device.common;
974        status = 0;
975    }
976    return status;
977}
978