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