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