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