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