hwc_mdpcomp.cpp revision db0ce0b85469e6de8b460860aad55c5833692be6
1/*
2 * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
3 * Not a Contribution, Apache license notifications and license are retained
4 * for attribution purposes only.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#include <math.h>
20#include "hwc_mdpcomp.h"
21#include <sys/ioctl.h>
22#include "external.h"
23#include "qdMetaData.h"
24#include "mdp_version.h"
25#include <overlayRotator.h>
26
27using namespace overlay;
28using namespace qdutils;
29using namespace overlay::utils;
30namespace ovutils = overlay::utils;
31
32namespace qhwc {
33
34//==============MDPComp========================================================
35
36IdleInvalidator *MDPComp::idleInvalidator = NULL;
37bool MDPComp::sIdleFallBack = false;
38bool MDPComp::sDebugLogs = false;
39bool MDPComp::sEnabled = false;
40int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
41
42MDPComp* MDPComp::getObject(const int& width, int dpy) {
43    if(width <= MAX_DISPLAY_DIM) {
44        return new MDPCompLowRes(dpy);
45    } else {
46        return new MDPCompHighRes(dpy);
47    }
48}
49
50MDPComp::MDPComp(int dpy):mDpy(dpy){};
51
52void MDPComp::dump(android::String8& buf)
53{
54    dumpsys_log(buf,"HWC Map for Dpy: %s \n",
55                mDpy ? "\"EXTERNAL\"" : "\"PRIMARY\"");
56    dumpsys_log(buf,"PREV_FRAME: layerCount:%2d    mdpCount:%2d \
57                cacheCount:%2d \n", mCachedFrame.layerCount,
58                mCachedFrame.mdpCount, mCachedFrame.cacheCount);
59    dumpsys_log(buf,"CURR_FRAME: layerCount:%2d    mdpCount:%2d \
60                fbCount:%2d \n", mCurrentFrame.layerCount,
61                mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
62    dumpsys_log(buf,"needsFBRedraw:%3s  pipesUsed:%2d  MaxPipesPerMixer: %d \n",
63                (mCurrentFrame.needsRedraw? "YES" : "NO"),
64                mCurrentFrame.mdpCount, sMaxPipesPerMixer);
65    dumpsys_log(buf," ---------------------------------------------  \n");
66    dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype  |  Z  \n");
67    dumpsys_log(buf," ---------------------------------------------  \n");
68    for(int index = 0; index < mCurrentFrame.layerCount; index++ )
69        dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
70                    index,
71                    (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
72                    mCurrentFrame.layerToMDP[index],
73                    (mCurrentFrame.isFBComposed[index] ?
74                     (mCurrentFrame.needsRedraw ? "GLES" : "CACHE") : "MDP"),
75                    (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
76    mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
77    dumpsys_log(buf,"\n");
78}
79
80bool MDPComp::init(hwc_context_t *ctx) {
81
82    if(!ctx) {
83        ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
84        return false;
85    }
86
87    char property[PROPERTY_VALUE_MAX];
88
89    sEnabled = false;
90    if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
91       (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
92        (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
93        sEnabled = true;
94        if(!setupBasePipe(ctx)) {
95            ALOGE("%s: Failed to setup primary base pipe", __FUNCTION__);
96            return false;
97        }
98    }
99
100    sDebugLogs = false;
101    if(property_get("debug.mdpcomp.logs", property, NULL) > 0) {
102        if(atoi(property) != 0)
103            sDebugLogs = true;
104    }
105
106    sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
107    if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) {
108        int val = atoi(property);
109        if(val >= 0)
110            sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER);
111    }
112
113    unsigned long idle_timeout = DEFAULT_IDLE_TIME;
114    if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
115        if(atoi(property) != 0)
116            idle_timeout = atoi(property);
117    }
118
119    //create Idle Invalidator
120    idleInvalidator = IdleInvalidator::getInstance();
121
122    if(idleInvalidator == NULL) {
123        ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__);
124    } else {
125        idleInvalidator->init(timeout_handler, ctx, idle_timeout);
126    }
127    return true;
128}
129
130void MDPComp::timeout_handler(void *udata) {
131    struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
132
133    if(!ctx) {
134        ALOGE("%s: received empty data in timer callback", __FUNCTION__);
135        return;
136    }
137
138    if(!ctx->proc) {
139        ALOGE("%s: HWC proc not registered", __FUNCTION__);
140        return;
141    }
142    sIdleFallBack = true;
143    /* Trigger SF to redraw the current frame */
144    ctx->proc->invalidate(ctx->proc);
145}
146
147void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
148                                   hwc_display_contents_1_t* list) {
149    LayerProp *layerProp = ctx->layerProp[mDpy];
150
151    for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
152        hwc_layer_1_t* layer = &(list->hwLayers[index]);
153        if(!mCurrentFrame.isFBComposed[index]) {
154            layerProp[index].mFlags |= HWC_MDPCOMP;
155            layer->compositionType = HWC_OVERLAY;
156            layer->hints |= HWC_HINT_CLEAR_FB;
157            mCachedFrame.hnd[index] = NULL;
158        } else {
159            if(!mCurrentFrame.needsRedraw)
160                layer->compositionType = HWC_OVERLAY;
161        }
162    }
163}
164
165/*
166 * Sets up BORDERFILL as default base pipe and detaches RGB0.
167 * Framebuffer is always updated using PLAY ioctl.
168 */
169bool MDPComp::setupBasePipe(hwc_context_t *ctx) {
170    const int dpy = HWC_DISPLAY_PRIMARY;
171    int fb_stride = ctx->dpyAttr[dpy].stride;
172    int fb_width = ctx->dpyAttr[dpy].xres;
173    int fb_height = ctx->dpyAttr[dpy].yres;
174    int fb_fd = ctx->dpyAttr[dpy].fd;
175
176    mdp_overlay ovInfo;
177    msmfb_overlay_data ovData;
178    memset(&ovInfo, 0, sizeof(mdp_overlay));
179    memset(&ovData, 0, sizeof(msmfb_overlay_data));
180
181    ovInfo.src.format = MDP_RGB_BORDERFILL;
182    ovInfo.src.width  = fb_width;
183    ovInfo.src.height = fb_height;
184    ovInfo.src_rect.w = fb_width;
185    ovInfo.src_rect.h = fb_height;
186    ovInfo.dst_rect.w = fb_width;
187    ovInfo.dst_rect.h = fb_height;
188    ovInfo.id = MSMFB_NEW_REQUEST;
189
190    if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) {
191        ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
192              strerror(errno));
193        return false;
194    }
195
196    ovData.id = ovInfo.id;
197    if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) {
198        ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
199              strerror(errno));
200        return false;
201    }
202    return true;
203}
204
205MDPComp::FrameInfo::FrameInfo() {
206    reset(0);
207}
208
209void MDPComp::FrameInfo::reset(const int& numLayers) {
210    for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
211        if(mdpToLayer[i].pipeInfo) {
212            delete mdpToLayer[i].pipeInfo;
213            mdpToLayer[i].pipeInfo = NULL;
214            //We dont own the rotator
215            mdpToLayer[i].rot = NULL;
216        }
217    }
218
219    memset(&mdpToLayer, 0, sizeof(mdpToLayer));
220    memset(&layerToMDP, -1, sizeof(layerToMDP));
221    memset(&isFBComposed, 1, sizeof(isFBComposed));
222
223    layerCount = numLayers;
224    fbCount = numLayers;
225    mdpCount = 0;
226    needsRedraw = true;
227    fbZ = 0;
228}
229
230void MDPComp::FrameInfo::map() {
231    // populate layer and MDP maps
232    int mdpIdx = 0;
233    for(int idx = 0; idx < layerCount; idx++) {
234        if(!isFBComposed[idx]) {
235            mdpToLayer[mdpIdx].listIndex = idx;
236            layerToMDP[idx] = mdpIdx++;
237        }
238    }
239}
240
241MDPComp::LayerCache::LayerCache() {
242    reset();
243}
244
245void MDPComp::LayerCache::reset() {
246    memset(&hnd, 0, sizeof(hnd));
247    mdpCount = 0;
248    cacheCount = 0;
249    layerCount = 0;
250    fbZ = -1;
251}
252
253void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
254    const int numAppLayers = list->numHwLayers - 1;
255    for(int i = 0; i < numAppLayers; i++) {
256        hnd[i] = list->hwLayers[i].handle;
257    }
258}
259
260void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
261    mdpCount = curFrame.mdpCount;
262    cacheCount = curFrame.fbCount;
263    layerCount = curFrame.layerCount;
264    fbZ = curFrame.fbZ;
265}
266
267bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
268    const int dpy = HWC_DISPLAY_PRIMARY;
269    private_handle_t *hnd = (private_handle_t *)layer->handle;
270
271    if(!hnd) {
272        ALOGE("%s: layer handle is NULL", __FUNCTION__);
273        return false;
274    }
275
276    int hw_w = ctx->dpyAttr[mDpy].xres;
277    int hw_h = ctx->dpyAttr[mDpy].yres;
278
279    hwc_rect_t crop = layer->sourceCrop;
280    hwc_rect_t dst = layer->displayFrame;
281
282    if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) {
283       hwc_rect_t scissor = {0, 0, hw_w, hw_h };
284       qhwc::calculate_crop_rects(crop, dst, scissor, layer->transform);
285    }
286
287    int crop_w = crop.right - crop.left;
288    int crop_h = crop.bottom - crop.top;
289    int dst_w = dst.right - dst.left;
290    int dst_h = dst.bottom - dst.top;
291    float w_dscale = ceilf((float)crop_w / (float)dst_w);
292    float h_dscale = ceilf((float)crop_h / (float)dst_h);
293
294    //Workaround for MDP HW limitation in DSI command mode panels where
295    //FPS will not go beyond 30 if buffers on RGB pipes are of width < 5
296
297    if((crop_w < 5)||(crop_h < 5))
298        return false;
299
300    const uint32_t downscale =
301            qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
302    if(ctx->mMDP.version >= qdutils::MDSS_V5) {
303        if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
304            if(crop_w > MAX_DISPLAY_DIM || w_dscale > downscale ||
305                    h_dscale > downscale)
306                return false;
307        } else if(w_dscale > 64 || h_dscale > 64) {
308            return false;
309        }
310    } else { //A-family
311        if(w_dscale > downscale || h_dscale > downscale)
312            return false;
313    }
314
315    return true;
316}
317
318ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type) {
319    overlay::Overlay& ov = *ctx->mOverlay;
320    ovutils::eDest mdp_pipe = ovutils::OV_INVALID;
321
322    switch(type) {
323    case MDPCOMP_OV_DMA:
324        mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, mDpy);
325        if(mdp_pipe != ovutils::OV_INVALID) {
326            return mdp_pipe;
327        }
328    case MDPCOMP_OV_ANY:
329    case MDPCOMP_OV_RGB:
330        mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
331        if(mdp_pipe != ovutils::OV_INVALID) {
332            return mdp_pipe;
333        }
334
335        if(type == MDPCOMP_OV_RGB) {
336            //Requested only for RGB pipe
337            break;
338        }
339    case  MDPCOMP_OV_VG:
340        return ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
341    default:
342        ALOGE("%s: Invalid pipe type",__FUNCTION__);
343        return ovutils::OV_INVALID;
344    };
345    return ovutils::OV_INVALID;
346}
347
348bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
349    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
350    bool ret = true;
351
352    if(!isEnabled()) {
353        ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
354        ret = false;
355    } else if(ctx->mExtDispConfiguring) {
356        ALOGD_IF( isDebug(),"%s: External Display connection is pending",
357                  __FUNCTION__);
358        ret = false;
359    } else if(ctx->isPaddingRound) {
360        ctx->isPaddingRound = false;
361        ALOGD_IF(isDebug(), "%s: padding round",__FUNCTION__);
362        ret = false;
363    }
364    return ret;
365}
366
367/* Checks for conditions where all the layers marked for MDP comp cannot be
368 * bypassed. On such conditions we try to bypass atleast YUV layers */
369bool MDPComp::isFullFrameDoable(hwc_context_t *ctx,
370                                hwc_display_contents_1_t* list){
371
372    const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
373
374    if(sIdleFallBack) {
375        ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
376        return false;
377    }
378
379    if(mDpy > HWC_DISPLAY_PRIMARY){
380        ALOGD_IF(isDebug(), "%s: Cannot support External display(s)",
381                 __FUNCTION__);
382        return false;
383    }
384
385    if(isSkipPresent(ctx, mDpy)) {
386        ALOGD_IF(isDebug(),"%s: SKIP present: %d",
387                __FUNCTION__,
388                isSkipPresent(ctx, mDpy));
389        return false;
390    }
391
392    if(ctx->listStats[mDpy].planeAlpha
393                     && ctx->mMDP.version >= qdutils::MDSS_V5) {
394        ALOGD_IF(isDebug(), "%s: plane alpha not implemented on MDSS",
395                 __FUNCTION__);
396        return false;
397    }
398
399    if(ctx->listStats[mDpy].needsAlphaScale
400       && ctx->mMDP.version < qdutils::MDSS_V5) {
401        ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
402        return false;
403    }
404
405    //MDP composition is not efficient if layer needs rotator.
406    for(int i = 0; i < numAppLayers; ++i) {
407        // As MDP h/w supports flip operation, use MDP comp only for
408        // 180 transforms. Fail for any transform involving 90 (90, 270).
409        hwc_layer_1_t* layer = &list->hwLayers[i];
410        private_handle_t *hnd = (private_handle_t *)layer->handle;
411        if(isYuvBuffer(hnd) ) {
412            if(isSecuring(ctx, layer)) {
413                ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
414                return false;
415            }
416        } else if(layer->transform & HWC_TRANSFORM_ROT_90) {
417            ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
418            return false;
419        }
420
421        if(!isValidDimension(ctx,layer)) {
422            ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
423                __FUNCTION__);
424            return false;
425        }
426    }
427
428    //If all above hard conditions are met we can do full or partial MDP comp.
429    bool ret = false;
430    if(fullMDPComp(ctx, list)) {
431        ret = true;
432    } else if (partialMDPComp(ctx, list)) {
433        ret = true;
434    }
435    return ret;
436}
437
438bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
439    //Setup mCurrentFrame
440    mCurrentFrame.mdpCount = mCurrentFrame.layerCount;
441    mCurrentFrame.fbCount = 0;
442    mCurrentFrame.fbZ = -1;
443    memset(&mCurrentFrame.isFBComposed, 0, sizeof(mCurrentFrame.isFBComposed));
444
445    int mdpCount = mCurrentFrame.mdpCount;
446    if(mdpCount > sMaxPipesPerMixer) {
447        ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
448        return false;
449    }
450
451    int numPipesNeeded = pipesNeeded(ctx, list);
452    int availPipes = getAvailablePipes(ctx);
453
454    if(numPipesNeeded > availPipes) {
455        ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes, needed %d, avail %d",
456                __FUNCTION__, numPipesNeeded, availPipes);
457        return false;
458    }
459
460    return true;
461}
462
463bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
464{
465    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
466    //Setup mCurrentFrame
467    mCurrentFrame.reset(numAppLayers);
468    updateLayerCache(ctx, list);
469    updateYUV(ctx, list);
470    batchLayers(); //sets up fbZ also
471
472    int mdpCount = mCurrentFrame.mdpCount;
473    if(mdpCount > (sMaxPipesPerMixer - 1)) { // -1 since FB is used
474        ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
475        return false;
476    }
477
478    int numPipesNeeded = pipesNeeded(ctx, list);
479    int availPipes = getAvailablePipes(ctx);
480
481    if(numPipesNeeded > availPipes) {
482        ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes, needed %d, avail %d",
483                __FUNCTION__, numPipesNeeded, availPipes);
484        return false;
485    }
486
487    return true;
488}
489
490bool MDPComp::isOnlyVideoDoable(hwc_context_t *ctx,
491        hwc_display_contents_1_t* list){
492    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
493    mCurrentFrame.reset(numAppLayers);
494    updateYUV(ctx, list);
495    int mdpCount = mCurrentFrame.mdpCount;
496    int fbNeeded = int(mCurrentFrame.fbCount != 0);
497
498    if(!isYuvPresent(ctx, mDpy)) {
499        return false;
500    }
501
502    if(!mdpCount)
503        return false;
504
505    if(mdpCount > (sMaxPipesPerMixer - fbNeeded)) {
506        ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
507        return false;
508    }
509
510    int numPipesNeeded = pipesNeeded(ctx, list);
511    int availPipes = getAvailablePipes(ctx);
512    if(numPipesNeeded > availPipes) {
513        ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes, needed %d, avail %d",
514                __FUNCTION__, numPipesNeeded, availPipes);
515        return false;
516    }
517
518    return true;
519}
520
521/* Checks for conditions where YUV layers cannot be bypassed */
522bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
523    if(isSkipLayer(layer)) {
524        ALOGE("%s: Unable to bypass skipped YUV", __FUNCTION__);
525        return false;
526    }
527
528    if(isSecuring(ctx, layer)) {
529        ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
530        return false;
531    }
532
533    if(!isValidDimension(ctx, layer)) {
534        ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
535            __FUNCTION__);
536        return false;
537    }
538
539    return true;
540}
541
542void  MDPComp::batchLayers() {
543    /* Idea is to keep as many contiguous non-updating(cached) layers in FB and
544     * send rest of them through MDP. NEVER mark an updating layer for caching.
545     * But cached ones can be marked for MDP*/
546
547    int maxBatchStart = -1;
548    int maxBatchCount = 0;
549
550    /* All or Nothing is cached. No batching needed */
551    if(!mCurrentFrame.fbCount) {
552        mCurrentFrame.fbZ = -1;
553        return;
554    }
555    if(!mCurrentFrame.mdpCount) {
556        mCurrentFrame.fbZ = 0;
557        return;
558    }
559
560    /* Search for max number of contiguous (cached) layers */
561    int i = 0;
562    while (i < mCurrentFrame.layerCount) {
563        int count = 0;
564        while(mCurrentFrame.isFBComposed[i] && i < mCurrentFrame.layerCount) {
565            count++; i++;
566        }
567        if(count > maxBatchCount) {
568            maxBatchCount = count;
569            maxBatchStart = i - count;
570            mCurrentFrame.fbZ = maxBatchStart;
571        }
572        if(i < mCurrentFrame.layerCount) i++;
573    }
574
575    /* reset rest of the layers for MDP comp */
576    for(int i = 0; i < mCurrentFrame.layerCount; i++) {
577        if(i != maxBatchStart){
578            mCurrentFrame.isFBComposed[i] = false;
579        } else {
580            i += maxBatchCount;
581        }
582    }
583
584    mCurrentFrame.fbCount = maxBatchCount;
585    mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
586            mCurrentFrame.fbCount;
587
588    ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
589             mCurrentFrame.fbCount);
590}
591
592void MDPComp::updateLayerCache(hwc_context_t* ctx,
593                               hwc_display_contents_1_t* list) {
594
595    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
596    int numCacheableLayers = 0;
597
598    for(int i = 0; i < numAppLayers; i++) {
599        if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
600            numCacheableLayers++;
601            mCurrentFrame.isFBComposed[i] = true;
602        } else {
603            mCurrentFrame.isFBComposed[i] = false;
604            mCachedFrame.hnd[i] = list->hwLayers[i].handle;
605        }
606    }
607
608    mCurrentFrame.fbCount = numCacheableLayers;
609    mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
610            mCurrentFrame.fbCount;
611    ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, numCacheableLayers);
612}
613
614int MDPComp::getAvailablePipes(hwc_context_t* ctx) {
615    int numDMAPipes = qdutils::MDPVersion::getInstance().getDMAPipes();
616    overlay::Overlay& ov = *ctx->mOverlay;
617
618    int numAvailable = ov.availablePipes(mDpy);
619
620    //Reserve DMA for rotator
621    if(Overlay::getDMAMode() == Overlay::DMA_BLOCK_MODE)
622        numAvailable -= numDMAPipes;
623
624    //Reserve pipe(s)for FB
625    if(mCurrentFrame.fbCount)
626        numAvailable -= pipesForFB();
627
628    return numAvailable;
629}
630
631void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
632
633    int nYuvCount = ctx->listStats[mDpy].yuvCount;
634    for(int index = 0;index < nYuvCount; index++){
635        int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
636        hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
637
638        if(!isYUVDoable(ctx, layer)) {
639            if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
640                mCurrentFrame.isFBComposed[nYuvIndex] = true;
641                mCurrentFrame.fbCount++;
642            }
643        } else {
644            if(mCurrentFrame.isFBComposed[nYuvIndex]) {
645                mCurrentFrame.isFBComposed[nYuvIndex] = false;
646                mCurrentFrame.fbCount--;
647            }
648        }
649    }
650
651    mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
652            mCurrentFrame.fbCount;
653    ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
654             mCurrentFrame.fbCount);
655}
656
657bool MDPComp::programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
658    if(!allocLayerPipes(ctx, list)) {
659        ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
660        return false;
661    }
662
663    bool fbBatch = false;
664    for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
665            index++) {
666        if(!mCurrentFrame.isFBComposed[index]) {
667            int mdpIndex = mCurrentFrame.layerToMDP[index];
668            hwc_layer_1_t* layer = &list->hwLayers[index];
669
670            MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
671            cur_pipe->zOrder = mdpNextZOrder++;
672
673            if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
674                ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
675                         layer %d",__FUNCTION__, index);
676                return false;
677            }
678        } else if(fbBatch == false) {
679                mdpNextZOrder++;
680                fbBatch = true;
681        }
682    }
683
684    return true;
685}
686
687bool MDPComp::programYUV(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
688    if(!allocLayerPipes(ctx, list)) {
689        ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
690        return false;
691    }
692    //If we are in this block, it means we have yuv + rgb layers both
693    int mdpIdx = 0;
694    for (int index = 0; index < mCurrentFrame.layerCount; index++) {
695        if(!mCurrentFrame.isFBComposed[index]) {
696            hwc_layer_1_t* layer = &list->hwLayers[index];
697            int mdpIndex = mCurrentFrame.layerToMDP[index];
698            MdpPipeInfo* cur_pipe =
699                    mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
700            cur_pipe->zOrder = mdpIdx++;
701
702            if(configure(ctx, layer,
703                        mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
704                ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
705                        layer %d",__FUNCTION__, index);
706                return false;
707            }
708        }
709    }
710    return true;
711}
712
713int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
714
715    const int numLayers = ctx->listStats[mDpy].numAppLayers;
716
717    //number of app layers exceeds MAX_NUM_APP_LAYERS fall back to GPU
718    //do not cache the information for next draw cycle.
719    if(numLayers > MAX_NUM_APP_LAYERS) {
720        ALOGD_IF(isDebug(), "%s: Number of App layers exceeded the limit ",
721                 __FUNCTION__);
722        return 0;
723    }
724    //reset old data
725    mCurrentFrame.reset(numLayers);
726
727    //Hard conditions, if not met, cannot do MDP comp
728    if(!isFrameDoable(ctx)) {
729        ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
730                  __FUNCTION__);
731        mCurrentFrame.reset(numLayers);
732        mCachedFrame.cacheAll(list);
733        mCachedFrame.updateCounts(mCurrentFrame);
734        return 0;
735    }
736
737    //Check whether layers marked for MDP Composition is actually doable.
738    if(isFullFrameDoable(ctx, list)){
739        mCurrentFrame.map();
740        //Acquire and Program MDP pipes
741        if(!programMDP(ctx, list)) {
742            mCurrentFrame.reset(numLayers);
743            mCachedFrame.cacheAll(list);
744        } else { //Success
745            //Any change in composition types needs an FB refresh
746            mCurrentFrame.needsRedraw = false;
747            if(mCurrentFrame.fbCount &&
748                    ((mCurrentFrame.mdpCount != mCachedFrame.mdpCount) ||
749                     (mCurrentFrame.fbCount != mCachedFrame.cacheCount) ||
750                     (mCurrentFrame.fbZ != mCachedFrame.fbZ) ||
751                     (!mCurrentFrame.mdpCount) ||
752                     (list->flags & HWC_GEOMETRY_CHANGED) ||
753                     isSkipPresent(ctx, mDpy) ||
754                     (mDpy > HWC_DISPLAY_PRIMARY))) {
755                mCurrentFrame.needsRedraw = true;
756            }
757        }
758    } else if(isOnlyVideoDoable(ctx, list)) {
759        //All layers marked for MDP comp cannot be bypassed.
760        //Try to compose atleast YUV layers through MDP comp and let
761        //all the RGB layers compose in FB
762        //Destination over
763        mCurrentFrame.fbZ = -1;
764        if(mCurrentFrame.fbCount)
765            mCurrentFrame.fbZ = ctx->listStats[mDpy].yuvCount;
766
767        mCurrentFrame.map();
768        if(!programYUV(ctx, list)) {
769            mCurrentFrame.reset(numLayers);
770            mCachedFrame.cacheAll(list);
771        }
772    } else {
773        mCurrentFrame.reset(numLayers);
774        mCachedFrame.cacheAll(list);
775    }
776
777    //UpdateLayerFlags
778    setMDPCompLayerFlags(ctx, list);
779    mCachedFrame.updateCounts(mCurrentFrame);
780
781    if(isDebug()) {
782        ALOGD("GEOMETRY change: %d", (list->flags & HWC_GEOMETRY_CHANGED));
783        android::String8 sDump("");
784        dump(sDump);
785        ALOGE("%s",sDump.string());
786    }
787
788    return mCurrentFrame.fbZ;
789}
790
791//=============MDPCompLowRes===================================================
792
793/*
794 * Configures pipe(s) for MDP composition
795 */
796int MDPCompLowRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
797                             PipeLayerPair& PipeLayerPair) {
798    MdpPipeInfoLowRes& mdp_info =
799        *(static_cast<MdpPipeInfoLowRes*>(PipeLayerPair.pipeInfo));
800    eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
801    eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
802    eIsFg isFg = IS_FG_OFF;
803    eDest dest = mdp_info.index;
804
805    ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
806             __FUNCTION__, layer, zOrder, dest);
807
808    return configureLowRes(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
809                           &PipeLayerPair.rot);
810}
811
812int MDPCompLowRes::pipesNeeded(hwc_context_t *ctx,
813                               hwc_display_contents_1_t* list) {
814    return mCurrentFrame.mdpCount;
815}
816
817bool MDPCompLowRes::allocLayerPipes(hwc_context_t *ctx,
818        hwc_display_contents_1_t* list) {
819    for(int index = 0; index < mCurrentFrame.layerCount; index++) {
820
821        if(mCurrentFrame.isFBComposed[index]) continue;
822
823        hwc_layer_1_t* layer = &list->hwLayers[index];
824        private_handle_t *hnd = (private_handle_t *)layer->handle;
825        int mdpIndex = mCurrentFrame.layerToMDP[index];
826        PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
827        info.pipeInfo = new MdpPipeInfoLowRes;
828        info.rot = NULL;
829        MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo;
830        ePipeType type = MDPCOMP_OV_ANY;
831
832        if(isYuvBuffer(hnd)) {
833            type = MDPCOMP_OV_VG;
834        } else if(!qhwc::needsScaling(ctx, layer, mDpy)
835            && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
836            && ctx->mMDP.version >= qdutils::MDSS_V5) {
837            type = MDPCOMP_OV_DMA;
838        }
839
840        pipe_info.index = getMdpPipe(ctx, type);
841        if(pipe_info.index == ovutils::OV_INVALID) {
842            ALOGD_IF(isDebug(), "%s: Unable to get pipe type = %d",
843                __FUNCTION__, (int) type);
844            return false;
845        }
846    }
847    return true;
848}
849
850bool MDPCompLowRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
851
852    if(!isEnabled()) {
853        ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
854        return true;
855    }
856
857    if(!ctx || !list) {
858        ALOGE("%s: invalid contxt or list",__FUNCTION__);
859        return false;
860    }
861
862    /* reset Invalidator */
863    if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount)
864        idleInvalidator->markForSleep();
865
866    overlay::Overlay& ov = *ctx->mOverlay;
867    LayerProp *layerProp = ctx->layerProp[mDpy];
868
869    int numHwLayers = ctx->listStats[mDpy].numAppLayers;
870    for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
871    {
872        if(mCurrentFrame.isFBComposed[i]) continue;
873
874        hwc_layer_1_t *layer = &list->hwLayers[i];
875        private_handle_t *hnd = (private_handle_t *)layer->handle;
876        if(!hnd) {
877            ALOGE("%s handle null", __FUNCTION__);
878            return false;
879        }
880
881        int mdpIndex = mCurrentFrame.layerToMDP[i];
882
883        MdpPipeInfoLowRes& pipe_info =
884            *(MdpPipeInfoLowRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
885        ovutils::eDest dest = pipe_info.index;
886        if(dest == ovutils::OV_INVALID) {
887            ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
888            return false;
889        }
890
891        if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
892            continue;
893        }
894
895        ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
896                 using  pipe: %d", __FUNCTION__, layer,
897                 hnd, dest );
898
899        int fd = hnd->fd;
900        uint32_t offset = hnd->offset;
901        Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
902        if(rot) {
903            if(!rot->queueBuffer(fd, offset))
904                return false;
905            fd = rot->getDstMemId();
906            offset = rot->getDstOffset();
907        }
908
909        if (!ov.queueBuffer(fd, offset, dest)) {
910            ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
911            return false;
912        }
913
914        layerProp[i].mFlags &= ~HWC_MDPCOMP;
915    }
916    return true;
917}
918
919//=============MDPCompHighRes===================================================
920
921int MDPCompHighRes::pipesNeeded(hwc_context_t *ctx,
922                                hwc_display_contents_1_t* list) {
923    int pipesNeeded = 0;
924    int hw_w = ctx->dpyAttr[mDpy].xres;
925
926    for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
927        if(!mCurrentFrame.isFBComposed[i]) {
928            hwc_layer_1_t* layer = &list->hwLayers[i];
929            hwc_rect_t dst = layer->displayFrame;
930            if(dst.left > hw_w/2) {
931                pipesNeeded++;
932            } else if(dst.right <= hw_w/2) {
933                pipesNeeded++;
934            } else {
935                pipesNeeded += 2;
936            }
937        }
938    }
939    return pipesNeeded;
940}
941
942bool MDPCompHighRes::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
943                                     MdpPipeInfoHighRes& pipe_info,
944                                     ePipeType type) {
945    int hw_w = ctx->dpyAttr[mDpy].xres;
946
947    hwc_rect_t dst = layer->displayFrame;
948    if(dst.left > hw_w/2) {
949        pipe_info.lIndex = ovutils::OV_INVALID;
950        pipe_info.rIndex = getMdpPipe(ctx, type);
951        if(pipe_info.rIndex == ovutils::OV_INVALID)
952            return false;
953    } else if (dst.right <= hw_w/2) {
954        pipe_info.rIndex = ovutils::OV_INVALID;
955        pipe_info.lIndex = getMdpPipe(ctx, type);
956        if(pipe_info.lIndex == ovutils::OV_INVALID)
957            return false;
958    } else {
959        pipe_info.rIndex = getMdpPipe(ctx, type);
960        pipe_info.lIndex = getMdpPipe(ctx, type);
961        if(pipe_info.rIndex == ovutils::OV_INVALID ||
962           pipe_info.lIndex == ovutils::OV_INVALID)
963            return false;
964    }
965    return true;
966}
967
968bool MDPCompHighRes::allocLayerPipes(hwc_context_t *ctx,
969        hwc_display_contents_1_t* list) {
970    for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
971
972        if(mCurrentFrame.isFBComposed[index]) continue;
973
974        hwc_layer_1_t* layer = &list->hwLayers[index];
975        private_handle_t *hnd = (private_handle_t *)layer->handle;
976        int mdpIndex = mCurrentFrame.layerToMDP[index];
977        PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
978        info.pipeInfo = new MdpPipeInfoHighRes;
979        info.rot = NULL;
980        MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo;
981        ePipeType type = MDPCOMP_OV_ANY;
982
983        if(isYuvBuffer(hnd)) {
984            type = MDPCOMP_OV_VG;
985        } else if(!qhwc::needsScaling(ctx, layer, mDpy)
986            && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
987            && ctx->mMDP.version >= qdutils::MDSS_V5) {
988            type = MDPCOMP_OV_DMA;
989        }
990
991        if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
992            ALOGD_IF(isDebug(), "%s: Unable to get pipe for type = %d",
993                    __FUNCTION__, (int) type);
994            return false;
995        }
996    }
997    return true;
998}
999/*
1000 * Configures pipe(s) for MDP composition
1001 */
1002int MDPCompHighRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
1003                              PipeLayerPair& PipeLayerPair) {
1004    MdpPipeInfoHighRes& mdp_info =
1005        *(static_cast<MdpPipeInfoHighRes*>(PipeLayerPair.pipeInfo));
1006    eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1007    eIsFg isFg = IS_FG_OFF;
1008    eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1009    eDest lDest = mdp_info.lIndex;
1010    eDest rDest = mdp_info.rIndex;
1011
1012    ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
1013             "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
1014
1015    return configureHighRes(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
1016                            rDest, &PipeLayerPair.rot);
1017}
1018
1019bool MDPCompHighRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1020
1021    if(!isEnabled()) {
1022        ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
1023        return true;
1024    }
1025
1026    if(!ctx || !list) {
1027        ALOGE("%s: invalid contxt or list",__FUNCTION__);
1028        return false;
1029    }
1030
1031    /* reset Invalidator */
1032    if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount)
1033        idleInvalidator->markForSleep();
1034
1035    overlay::Overlay& ov = *ctx->mOverlay;
1036    LayerProp *layerProp = ctx->layerProp[mDpy];
1037
1038    int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1039    for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
1040    {
1041        if(mCurrentFrame.isFBComposed[i]) continue;
1042
1043        hwc_layer_1_t *layer = &list->hwLayers[i];
1044        private_handle_t *hnd = (private_handle_t *)layer->handle;
1045        if(!hnd) {
1046            ALOGE("%s handle null", __FUNCTION__);
1047            return false;
1048        }
1049
1050        if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1051            continue;
1052        }
1053
1054        int mdpIndex = mCurrentFrame.layerToMDP[i];
1055
1056        MdpPipeInfoHighRes& pipe_info =
1057            *(MdpPipeInfoHighRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1058        Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1059
1060        ovutils::eDest indexL = pipe_info.lIndex;
1061        ovutils::eDest indexR = pipe_info.rIndex;
1062
1063        int fd = hnd->fd;
1064        int offset = hnd->offset;
1065
1066        if(rot) {
1067            rot->queueBuffer(fd, offset);
1068            fd = rot->getDstMemId();
1069            offset = rot->getDstOffset();
1070        }
1071
1072        //************* play left mixer **********
1073        if(indexL != ovutils::OV_INVALID) {
1074            ovutils::eDest destL = (ovutils::eDest)indexL;
1075            ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1076                     using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
1077            if (!ov.queueBuffer(fd, offset, destL)) {
1078                ALOGE("%s: queueBuffer failed for left mixer", __FUNCTION__);
1079                return false;
1080            }
1081        }
1082
1083        //************* play right mixer **********
1084        if(indexR != ovutils::OV_INVALID) {
1085            ovutils::eDest destR = (ovutils::eDest)indexR;
1086            ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1087                     using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
1088            if (!ov.queueBuffer(fd, offset, destR)) {
1089                ALOGE("%s: queueBuffer failed for right mixer", __FUNCTION__);
1090                return false;
1091            }
1092        }
1093
1094        layerProp[i].mFlags &= ~HWC_MDPCOMP;
1095    }
1096
1097    return true;
1098}
1099}; //namespace
1100
1101