hwc_mdpcomp.cpp revision 788b7bb579ed9375c3428d9ecf8bbe517a13ffef
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    unsigned long idle_timeout = DEFAULT_IDLE_TIME;
108    if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
109        if(atoi(property) != 0)
110            idle_timeout = atoi(property);
111    }
112
113    //create Idle Invalidator
114    idleInvalidator = IdleInvalidator::getInstance();
115
116    if(idleInvalidator == NULL) {
117        ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__);
118    } else {
119        idleInvalidator->init(timeout_handler, ctx, idle_timeout);
120    }
121    return true;
122}
123
124void MDPComp::timeout_handler(void *udata) {
125    struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
126
127    if(!ctx) {
128        ALOGE("%s: received empty data in timer callback", __FUNCTION__);
129        return;
130    }
131
132    if(!ctx->proc) {
133        ALOGE("%s: HWC proc not registered", __FUNCTION__);
134        return;
135    }
136    sIdleFallBack = true;
137    /* Trigger SF to redraw the current frame */
138    ctx->proc->invalidate(ctx->proc);
139}
140
141void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
142                                   hwc_display_contents_1_t* list) {
143    LayerProp *layerProp = ctx->layerProp[mDpy];
144
145    for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) {
146        hwc_layer_1_t* layer = &(list->hwLayers[index]);
147        if(!mCurrentFrame.isFBComposed[index]) {
148            layerProp[index].mFlags |= HWC_MDPCOMP;
149            layer->compositionType = HWC_OVERLAY;
150            layer->hints |= HWC_HINT_CLEAR_FB;
151            mCachedFrame.hnd[index] = NULL;
152        } else {
153            if(!mCurrentFrame.needsRedraw)
154                layer->compositionType = HWC_OVERLAY;
155        }
156    }
157}
158
159/*
160 * Sets up BORDERFILL as default base pipe and detaches RGB0.
161 * Framebuffer is always updated using PLAY ioctl.
162 */
163bool MDPComp::setupBasePipe(hwc_context_t *ctx) {
164    const int dpy = HWC_DISPLAY_PRIMARY;
165    int fb_stride = ctx->dpyAttr[dpy].stride;
166    int fb_width = ctx->dpyAttr[dpy].xres;
167    int fb_height = ctx->dpyAttr[dpy].yres;
168    int fb_fd = ctx->dpyAttr[dpy].fd;
169
170    mdp_overlay ovInfo;
171    msmfb_overlay_data ovData;
172    memset(&ovInfo, 0, sizeof(mdp_overlay));
173    memset(&ovData, 0, sizeof(msmfb_overlay_data));
174
175    ovInfo.src.format = MDP_RGB_BORDERFILL;
176    ovInfo.src.width  = fb_width;
177    ovInfo.src.height = fb_height;
178    ovInfo.src_rect.w = fb_width;
179    ovInfo.src_rect.h = fb_height;
180    ovInfo.dst_rect.w = fb_width;
181    ovInfo.dst_rect.h = fb_height;
182    ovInfo.id = MSMFB_NEW_REQUEST;
183
184    if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) {
185        ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
186              strerror(errno));
187        return false;
188    }
189
190    ovData.id = ovInfo.id;
191    if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) {
192        ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
193              strerror(errno));
194        return false;
195    }
196    return true;
197}
198
199MDPComp::FrameInfo::FrameInfo() {
200    reset(0);
201}
202
203void MDPComp::FrameInfo::reset(const int& numLayers) {
204    for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) {
205        if(mdpToLayer[i].pipeInfo) {
206            delete mdpToLayer[i].pipeInfo;
207            mdpToLayer[i].pipeInfo = NULL;
208            //We dont own the rotator
209            mdpToLayer[i].rot = NULL;
210        }
211    }
212
213    memset(&mdpToLayer, 0, sizeof(mdpToLayer));
214    memset(&layerToMDP, -1, sizeof(layerToMDP));
215    memset(&isFBComposed, 1, sizeof(isFBComposed));
216
217    layerCount = numLayers;
218    fbCount = numLayers;
219    mdpCount = 0;
220    needsRedraw = true;
221    fbZ = 0;
222}
223
224void MDPComp::FrameInfo::map() {
225    // populate layer and MDP maps
226    int mdpIdx = 0;
227    for(int idx = 0; idx < layerCount; idx++) {
228        if(!isFBComposed[idx]) {
229            mdpToLayer[mdpIdx].listIndex = idx;
230            layerToMDP[idx] = mdpIdx++;
231        }
232    }
233}
234
235MDPComp::LayerCache::LayerCache() {
236    reset();
237}
238
239void MDPComp::LayerCache::reset() {
240    memset(&hnd, 0, sizeof(hnd));
241    mdpCount = 0;
242    cacheCount = 0;
243    layerCount = 0;
244    fbZ = -1;
245}
246
247void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) {
248    const int numAppLayers = list->numHwLayers - 1;
249    for(int i = 0; i < numAppLayers; i++) {
250        hnd[i] = list->hwLayers[i].handle;
251    }
252}
253
254void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) {
255    mdpCount = curFrame.mdpCount;
256    cacheCount = curFrame.fbCount;
257    layerCount = curFrame.layerCount;
258    fbZ = curFrame.fbZ;
259}
260
261bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
262    const int dpy = HWC_DISPLAY_PRIMARY;
263    private_handle_t *hnd = (private_handle_t *)layer->handle;
264
265    if(!hnd) {
266        ALOGE("%s: layer handle is NULL", __FUNCTION__);
267        return false;
268    }
269
270    int hw_w = ctx->dpyAttr[mDpy].xres;
271    int hw_h = ctx->dpyAttr[mDpy].yres;
272
273    hwc_rect_t crop = layer->sourceCrop;
274    hwc_rect_t dst = layer->displayFrame;
275
276    if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) {
277       hwc_rect_t scissor = {0, 0, hw_w, hw_h };
278       qhwc::calculate_crop_rects(crop, dst, scissor, layer->transform);
279    }
280
281    int crop_w = crop.right - crop.left;
282    int crop_h = crop.bottom - crop.top;
283    int dst_w = dst.right - dst.left;
284    int dst_h = dst.bottom - dst.top;
285    float w_dscale = ceilf((float)crop_w / (float)dst_w);
286    float h_dscale = ceilf((float)crop_h / (float)dst_h);
287
288    //Workaround for MDP HW limitation in DSI command mode panels where
289    //FPS will not go beyond 30 if buffers on RGB pipes are of width < 5
290
291    if((crop_w < 5)||(crop_h < 5))
292        return false;
293
294    if(ctx->mMDP.version >= qdutils::MDSS_V5) {
295        /* Workaround for downscales larger than 4x.
296         * Will be removed once decimator block is enabled for MDSS
297         */
298        if(w_dscale > 4.0f || h_dscale > 4.0f)
299            return false;
300    } else {
301        if(w_dscale > 8.0f || h_dscale > 8.0f)
302            // MDP 4 supports 1/8 downscale
303            return false;
304    }
305
306    return true;
307}
308
309ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type) {
310    overlay::Overlay& ov = *ctx->mOverlay;
311    ovutils::eDest mdp_pipe = ovutils::OV_INVALID;
312
313    switch(type) {
314    case MDPCOMP_OV_DMA:
315        mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, mDpy);
316        if(mdp_pipe != ovutils::OV_INVALID) {
317            ctx->mDMAInUse = true;
318            return mdp_pipe;
319        }
320    case MDPCOMP_OV_ANY:
321    case MDPCOMP_OV_RGB:
322        mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
323        if(mdp_pipe != ovutils::OV_INVALID) {
324            return mdp_pipe;
325        }
326
327        if(type == MDPCOMP_OV_RGB) {
328            //Requested only for RGB pipe
329            break;
330        }
331    case  MDPCOMP_OV_VG:
332        return ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
333    default:
334        ALOGE("%s: Invalid pipe type",__FUNCTION__);
335        return ovutils::OV_INVALID;
336    };
337    return ovutils::OV_INVALID;
338}
339
340bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
341    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
342    bool ret = true;
343
344    if(!isEnabled()) {
345        ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
346        ret = false;
347    } else if(ctx->mExtDispConfiguring) {
348        ALOGD_IF( isDebug(),"%s: External Display connection is pending",
349                  __FUNCTION__);
350        ret = false;
351    }
352    return ret;
353}
354
355/* Checks for conditions where all the layers marked for MDP comp cannot be
356 * bypassed. On such conditions we try to bypass atleast YUV layers */
357bool MDPComp::isFullFrameDoable(hwc_context_t *ctx,
358                                hwc_display_contents_1_t* list){
359
360    const int numAppLayers = ctx->listStats[mDpy].numAppLayers;
361
362    if(sIdleFallBack) {
363        ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy);
364        return false;
365    }
366
367    if(mDpy > HWC_DISPLAY_PRIMARY){
368        ALOGD_IF(isDebug(), "%s: Cannot support External display(s)",
369                 __FUNCTION__);
370        return false;
371    }
372
373    if(isSkipPresent(ctx, mDpy)) {
374        ALOGD_IF(isDebug(),"%s: SKIP present: %d",
375                __FUNCTION__,
376                isSkipPresent(ctx, mDpy));
377        return false;
378    }
379
380    if(ctx->listStats[mDpy].planeAlpha
381                     && ctx->mMDP.version >= qdutils::MDSS_V5) {
382        ALOGD_IF(isDebug(), "%s: plane alpha not implemented on MDSS",
383                 __FUNCTION__);
384        return false;
385    }
386
387    if(ctx->listStats[mDpy].needsAlphaScale
388       && ctx->mMDP.version < qdutils::MDSS_V5) {
389        ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
390        return false;
391    }
392
393    //MDP composition is not efficient if layer needs rotator.
394    for(int i = 0; i < numAppLayers; ++i) {
395        // As MDP h/w supports flip operation, use MDP comp only for
396        // 180 transforms. Fail for any transform involving 90 (90, 270).
397        hwc_layer_1_t* layer = &list->hwLayers[i];
398        private_handle_t *hnd = (private_handle_t *)layer->handle;
399        if(isYuvBuffer(hnd) ) {
400            if(isSecuring(ctx, layer)) {
401                ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
402                return false;
403            }
404        } else if(layer->transform & HWC_TRANSFORM_ROT_90) {
405            ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
406            return false;
407        }
408
409        if(!isValidDimension(ctx,layer)) {
410            ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
411                __FUNCTION__);
412            return false;
413        }
414    }
415
416    //If all above hard conditions are met we can do full or partial MDP comp.
417    bool ret = false;
418    if(fullMDPComp(ctx, list)) {
419        ret = true;
420    } else if (partialMDPComp(ctx, list)) {
421        ret = true;
422    }
423    return ret;
424}
425
426bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
427    //Setup mCurrentFrame
428    mCurrentFrame.mdpCount = mCurrentFrame.layerCount;
429    mCurrentFrame.fbCount = 0;
430    mCurrentFrame.fbZ = -1;
431    memset(&mCurrentFrame.isFBComposed, 0, sizeof(mCurrentFrame.isFBComposed));
432
433    int mdpCount = mCurrentFrame.mdpCount;
434    if(mdpCount > sMaxPipesPerMixer) {
435        ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
436        return false;
437    }
438
439    int numPipesNeeded = pipesNeeded(ctx, list);
440    int availPipes = getAvailablePipes(ctx);
441
442    if(numPipesNeeded > availPipes) {
443        ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes, needed %d, avail %d",
444                __FUNCTION__, numPipesNeeded, availPipes);
445        return false;
446    }
447
448    return true;
449}
450
451bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list)
452{
453    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
454    //Setup mCurrentFrame
455    mCurrentFrame.reset(numAppLayers);
456    updateLayerCache(ctx, list);
457    updateYUV(ctx, list);
458    batchLayers(); //sets up fbZ also
459
460    int mdpCount = mCurrentFrame.mdpCount;
461    if(mdpCount > (sMaxPipesPerMixer - 1)) { // -1 since FB is used
462        ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
463        return false;
464    }
465
466    int numPipesNeeded = pipesNeeded(ctx, list);
467    int availPipes = getAvailablePipes(ctx);
468
469    if(numPipesNeeded > availPipes) {
470        ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes, needed %d, avail %d",
471                __FUNCTION__, numPipesNeeded, availPipes);
472        return false;
473    }
474
475    return true;
476}
477
478bool MDPComp::isOnlyVideoDoable(hwc_context_t *ctx,
479        hwc_display_contents_1_t* list){
480    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
481    mCurrentFrame.reset(numAppLayers);
482    updateYUV(ctx, list);
483    int mdpCount = mCurrentFrame.mdpCount;
484    int fbNeeded = int(mCurrentFrame.fbCount != 0);
485
486    if(!isYuvPresent(ctx, mDpy)) {
487        return false;
488    }
489
490    if(!mdpCount)
491        return false;
492
493    if(mdpCount > (sMaxPipesPerMixer - fbNeeded)) {
494        ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
495        return false;
496    }
497
498    int numPipesNeeded = pipesNeeded(ctx, list);
499    int availPipes = getAvailablePipes(ctx);
500    if(numPipesNeeded > availPipes) {
501        ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes, needed %d, avail %d",
502                __FUNCTION__, numPipesNeeded, availPipes);
503        return false;
504    }
505
506    return true;
507}
508
509/* Checks for conditions where YUV layers cannot be bypassed */
510bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
511
512    if(isSkipLayer(layer)) {
513        ALOGE("%s: Unable to bypass skipped YUV", __FUNCTION__);
514        return false;
515    }
516
517    if(layer->planeAlpha < 0xFF) {
518        ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha",
519                 __FUNCTION__);
520        return false;
521    }
522
523    if(ctx->mNeedsRotator && ctx->mDMAInUse) {
524        ALOGE("%s: No DMA for Rotator",__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(ctx->mNeedsRotator)
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    ctx->mDMAInUse = false;
659    if(!allocLayerPipes(ctx, list)) {
660        ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
661        return false;
662    }
663
664    bool fbBatch = false;
665    for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
666            index++) {
667        if(!mCurrentFrame.isFBComposed[index]) {
668            int mdpIndex = mCurrentFrame.layerToMDP[index];
669            hwc_layer_1_t* layer = &list->hwLayers[index];
670
671            MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
672            cur_pipe->zOrder = mdpNextZOrder++;
673
674            if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
675                ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
676                         layer %d",__FUNCTION__, index);
677                return false;
678            }
679        } else if(fbBatch == false) {
680                mdpNextZOrder++;
681                fbBatch = true;
682        }
683    }
684
685    return true;
686}
687
688bool MDPComp::programYUV(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
689    if(!allocLayerPipes(ctx, list)) {
690        ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
691        return false;
692    }
693    //If we are in this block, it means we have yuv + rgb layers both
694    int mdpIdx = 0;
695    for (int index = 0; index < mCurrentFrame.layerCount; index++) {
696        if(!mCurrentFrame.isFBComposed[index]) {
697            hwc_layer_1_t* layer = &list->hwLayers[index];
698            int mdpIndex = mCurrentFrame.layerToMDP[index];
699            MdpPipeInfo* cur_pipe =
700                    mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
701            cur_pipe->zOrder = mdpIdx++;
702
703            if(configure(ctx, layer,
704                        mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
705                ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
706                        layer %d",__FUNCTION__, index);
707                return false;
708            }
709        }
710    }
711    return true;
712}
713
714int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
715
716    //reset old data
717    const int numLayers = ctx->listStats[mDpy].numAppLayers;
718    mCurrentFrame.reset(numLayers);
719
720    //Hard conditions, if not met, cannot do MDP comp
721    if(!isFrameDoable(ctx)) {
722        ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
723                  __FUNCTION__);
724        mCurrentFrame.reset(numLayers);
725        mCachedFrame.cacheAll(list);
726        mCachedFrame.updateCounts(mCurrentFrame);
727        return 0;
728    }
729
730    //Check whether layers marked for MDP Composition is actually doable.
731    if(isFullFrameDoable(ctx, list)){
732        mCurrentFrame.map();
733        //Acquire and Program MDP pipes
734        if(!programMDP(ctx, list)) {
735            mCurrentFrame.reset(numLayers);
736            mCachedFrame.cacheAll(list);
737        } else { //Success
738            //Any change in composition types needs an FB refresh
739            mCurrentFrame.needsRedraw = false;
740            if(mCurrentFrame.fbCount &&
741                    ((mCurrentFrame.mdpCount != mCachedFrame.mdpCount) ||
742                     (mCurrentFrame.fbCount != mCachedFrame.cacheCount) ||
743                     (mCurrentFrame.fbZ != mCachedFrame.fbZ) ||
744                     (!mCurrentFrame.mdpCount) ||
745                     (list->flags & HWC_GEOMETRY_CHANGED) ||
746                     isSkipPresent(ctx, mDpy) ||
747                     (mDpy > HWC_DISPLAY_PRIMARY))) {
748                mCurrentFrame.needsRedraw = true;
749            }
750        }
751    } else if(isOnlyVideoDoable(ctx, list)) {
752        //All layers marked for MDP comp cannot be bypassed.
753        //Try to compose atleast YUV layers through MDP comp and let
754        //all the RGB layers compose in FB
755        //Destination over
756        mCurrentFrame.fbZ = -1;
757        if(mCurrentFrame.fbCount)
758            mCurrentFrame.fbZ = ctx->listStats[mDpy].yuvCount;
759
760        mCurrentFrame.map();
761        if(!programYUV(ctx, list)) {
762            mCurrentFrame.reset(numLayers);
763            mCachedFrame.cacheAll(list);
764        }
765    } else {
766        mCurrentFrame.reset(numLayers);
767        mCachedFrame.cacheAll(list);
768    }
769
770    //UpdateLayerFlags
771    setMDPCompLayerFlags(ctx, list);
772    mCachedFrame.updateCounts(mCurrentFrame);
773
774    if(isDebug()) {
775        ALOGD("GEOMETRY change: %d", (list->flags & HWC_GEOMETRY_CHANGED));
776        android::String8 sDump("");
777        dump(sDump);
778        ALOGE("%s",sDump.string());
779    }
780
781    return mCurrentFrame.fbZ;
782}
783
784//=============MDPCompLowRes===================================================
785
786/*
787 * Configures pipe(s) for MDP composition
788 */
789int MDPCompLowRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
790                             PipeLayerPair& PipeLayerPair) {
791    MdpPipeInfoLowRes& mdp_info =
792        *(static_cast<MdpPipeInfoLowRes*>(PipeLayerPair.pipeInfo));
793    eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
794    eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
795    eIsFg isFg = IS_FG_OFF;
796    eDest dest = mdp_info.index;
797
798    ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
799             __FUNCTION__, layer, zOrder, dest);
800
801    return configureLowRes(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
802                           &PipeLayerPair.rot);
803}
804
805int MDPCompLowRes::pipesNeeded(hwc_context_t *ctx,
806                               hwc_display_contents_1_t* list) {
807    return mCurrentFrame.mdpCount;
808}
809
810bool MDPCompLowRes::allocLayerPipes(hwc_context_t *ctx,
811                                    hwc_display_contents_1_t* list) {
812    if(isYuvPresent(ctx, mDpy)) {
813        int nYuvCount = ctx->listStats[mDpy].yuvCount;
814
815        for(int index = 0; index < nYuvCount ; index ++) {
816            int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
817
818            if(mCurrentFrame.isFBComposed[nYuvIndex])
819                continue;
820
821            hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
822
823            int mdpIndex = mCurrentFrame.layerToMDP[nYuvIndex];
824
825            PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
826            info.pipeInfo = new MdpPipeInfoLowRes;
827            info.rot = NULL;
828            MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo;
829
830            pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
831            if(pipe_info.index == ovutils::OV_INVALID) {
832                ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
833                         __FUNCTION__);
834                return false;
835            }
836        }
837    }
838
839    for(int index = 0 ; index < mCurrentFrame.layerCount; index++ ) {
840        if(mCurrentFrame.isFBComposed[index]) continue;
841        hwc_layer_1_t* layer = &list->hwLayers[index];
842        private_handle_t *hnd = (private_handle_t *)layer->handle;
843
844        if(isYuvBuffer(hnd))
845            continue;
846
847        int mdpIndex = mCurrentFrame.layerToMDP[index];
848
849        PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
850        info.pipeInfo = new MdpPipeInfoLowRes;
851        info.rot = NULL;
852        MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo;
853
854        ePipeType type = MDPCOMP_OV_ANY;
855
856        if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator
857           && ctx->mMDP.version >= qdutils::MDSS_V5) {
858            type = MDPCOMP_OV_DMA;
859        }
860
861        pipe_info.index = getMdpPipe(ctx, type);
862        if(pipe_info.index == ovutils::OV_INVALID) {
863            ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
864            return false;
865        }
866    }
867    return true;
868}
869
870bool MDPCompLowRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
871
872    if(!isEnabled()) {
873        ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
874        return true;
875    }
876
877    if(!ctx || !list) {
878        ALOGE("%s: invalid contxt or list",__FUNCTION__);
879        return false;
880    }
881
882    /* reset Invalidator */
883    if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount)
884        idleInvalidator->markForSleep();
885
886    overlay::Overlay& ov = *ctx->mOverlay;
887    LayerProp *layerProp = ctx->layerProp[mDpy];
888
889    int numHwLayers = ctx->listStats[mDpy].numAppLayers;
890    for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
891    {
892        if(mCurrentFrame.isFBComposed[i]) continue;
893
894        hwc_layer_1_t *layer = &list->hwLayers[i];
895        private_handle_t *hnd = (private_handle_t *)layer->handle;
896        if(!hnd) {
897            ALOGE("%s handle null", __FUNCTION__);
898            return false;
899        }
900
901        int mdpIndex = mCurrentFrame.layerToMDP[i];
902
903        MdpPipeInfoLowRes& pipe_info =
904            *(MdpPipeInfoLowRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
905        ovutils::eDest dest = pipe_info.index;
906        if(dest == ovutils::OV_INVALID) {
907            ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
908            return false;
909        }
910
911        if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
912            continue;
913        }
914
915        ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
916                 using  pipe: %d", __FUNCTION__, layer,
917                 hnd, dest );
918
919        int fd = hnd->fd;
920        uint32_t offset = hnd->offset;
921        Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
922        if(rot) {
923            if(!rot->queueBuffer(fd, offset))
924                return false;
925            fd = rot->getDstMemId();
926            offset = rot->getDstOffset();
927        }
928
929        if (!ov.queueBuffer(fd, offset, dest)) {
930            ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
931            return false;
932        }
933
934        layerProp[i].mFlags &= ~HWC_MDPCOMP;
935    }
936    return true;
937}
938
939//=============MDPCompHighRes===================================================
940
941int MDPCompHighRes::pipesNeeded(hwc_context_t *ctx,
942                                hwc_display_contents_1_t* list) {
943    int pipesNeeded = 0;
944    int hw_w = ctx->dpyAttr[mDpy].xres;
945
946    for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
947        if(!mCurrentFrame.isFBComposed[i]) {
948            hwc_layer_1_t* layer = &list->hwLayers[i];
949            hwc_rect_t dst = layer->displayFrame;
950            if(dst.left > hw_w/2) {
951                pipesNeeded++;
952            } else if(dst.right <= hw_w/2) {
953                pipesNeeded++;
954            } else {
955                pipesNeeded += 2;
956            }
957        }
958    }
959    return pipesNeeded;
960}
961
962bool MDPCompHighRes::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
963                                     MdpPipeInfoHighRes& pipe_info,
964                                     ePipeType type) {
965    int hw_w = ctx->dpyAttr[mDpy].xres;
966
967    hwc_rect_t dst = layer->displayFrame;
968    if(dst.left > hw_w/2) {
969        pipe_info.lIndex = ovutils::OV_INVALID;
970        pipe_info.rIndex = getMdpPipe(ctx, type);
971        if(pipe_info.rIndex == ovutils::OV_INVALID)
972            return false;
973    } else if (dst.right <= hw_w/2) {
974        pipe_info.rIndex = ovutils::OV_INVALID;
975        pipe_info.lIndex = getMdpPipe(ctx, type);
976        if(pipe_info.lIndex == ovutils::OV_INVALID)
977            return false;
978    } else {
979        pipe_info.rIndex = getMdpPipe(ctx, type);
980        pipe_info.lIndex = getMdpPipe(ctx, type);
981        if(pipe_info.rIndex == ovutils::OV_INVALID ||
982           pipe_info.lIndex == ovutils::OV_INVALID)
983            return false;
984    }
985    return true;
986}
987
988bool MDPCompHighRes::allocLayerPipes(hwc_context_t *ctx,
989                                     hwc_display_contents_1_t* list) {
990    overlay::Overlay& ov = *ctx->mOverlay;
991    int layer_count = ctx->listStats[mDpy].numAppLayers;
992
993    if(isYuvPresent(ctx, mDpy)) {
994        int nYuvCount = ctx->listStats[mDpy].yuvCount;
995
996        for(int index = 0; index < nYuvCount; index ++) {
997            int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
998            hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
999            PipeLayerPair& info = mCurrentFrame.mdpToLayer[nYuvIndex];
1000            info.pipeInfo = new MdpPipeInfoHighRes;
1001            info.rot = NULL;
1002            MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo;
1003            if(!acquireMDPPipes(ctx, layer, pipe_info,MDPCOMP_OV_VG)) {
1004                ALOGD_IF(isDebug(),"%s: Unable to get pipe for videos",
1005                         __FUNCTION__);
1006                //TODO: windback pipebook data on fail
1007                return false;
1008            }
1009            pipe_info.zOrder = nYuvIndex;
1010        }
1011    }
1012
1013    for(int index = 0 ; index < layer_count ; index++ ) {
1014        hwc_layer_1_t* layer = &list->hwLayers[index];
1015        private_handle_t *hnd = (private_handle_t *)layer->handle;
1016
1017        if(isYuvBuffer(hnd))
1018            continue;
1019
1020        PipeLayerPair& info = mCurrentFrame.mdpToLayer[index];
1021        info.pipeInfo = new MdpPipeInfoHighRes;
1022        info.rot = NULL;
1023        MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo;
1024
1025        ePipeType type = MDPCOMP_OV_ANY;
1026
1027        if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator
1028           && ctx->mMDP.version >= qdutils::MDSS_V5)
1029            type = MDPCOMP_OV_DMA;
1030
1031        if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
1032            ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
1033            //TODO: windback pipebook data on fail
1034            return false;
1035        }
1036        pipe_info.zOrder = index;
1037    }
1038    return true;
1039}
1040/*
1041 * Configures pipe(s) for MDP composition
1042 */
1043int MDPCompHighRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
1044                              PipeLayerPair& PipeLayerPair) {
1045    MdpPipeInfoHighRes& mdp_info =
1046        *(static_cast<MdpPipeInfoHighRes*>(PipeLayerPair.pipeInfo));
1047    eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
1048    eIsFg isFg = IS_FG_OFF;
1049    eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
1050    eDest lDest = mdp_info.lIndex;
1051    eDest rDest = mdp_info.rIndex;
1052
1053    ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
1054             "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
1055
1056    return configureHighRes(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
1057                            rDest, &PipeLayerPair.rot);
1058}
1059
1060bool MDPCompHighRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
1061
1062    if(!isEnabled()) {
1063        ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
1064        return true;
1065    }
1066
1067    if(!ctx || !list) {
1068        ALOGE("%s: invalid contxt or list",__FUNCTION__);
1069        return false;
1070    }
1071
1072    /* reset Invalidator */
1073    if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount)
1074        idleInvalidator->markForSleep();
1075
1076    overlay::Overlay& ov = *ctx->mOverlay;
1077    LayerProp *layerProp = ctx->layerProp[mDpy];
1078
1079    int numHwLayers = ctx->listStats[mDpy].numAppLayers;
1080    for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
1081    {
1082        if(mCurrentFrame.isFBComposed[i]) continue;
1083
1084        hwc_layer_1_t *layer = &list->hwLayers[i];
1085        private_handle_t *hnd = (private_handle_t *)layer->handle;
1086        if(!hnd) {
1087            ALOGE("%s handle null", __FUNCTION__);
1088            return false;
1089        }
1090
1091        if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
1092            continue;
1093        }
1094
1095        int mdpIndex = mCurrentFrame.layerToMDP[i];
1096
1097        MdpPipeInfoHighRes& pipe_info =
1098            *(MdpPipeInfoHighRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
1099        Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
1100
1101        ovutils::eDest indexL = pipe_info.lIndex;
1102        ovutils::eDest indexR = pipe_info.rIndex;
1103
1104        int fd = hnd->fd;
1105        int offset = hnd->offset;
1106
1107        if(rot) {
1108            rot->queueBuffer(fd, offset);
1109            fd = rot->getDstMemId();
1110            offset = rot->getDstOffset();
1111        }
1112
1113        //************* play left mixer **********
1114        if(indexL != ovutils::OV_INVALID) {
1115            ovutils::eDest destL = (ovutils::eDest)indexL;
1116            ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1117                     using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
1118            if (!ov.queueBuffer(fd, offset, destL)) {
1119                ALOGE("%s: queueBuffer failed for left mixer", __FUNCTION__);
1120                return false;
1121            }
1122        }
1123
1124        //************* play right mixer **********
1125        if(indexR != ovutils::OV_INVALID) {
1126            ovutils::eDest destR = (ovutils::eDest)indexR;
1127            ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
1128                     using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
1129            if (!ov.queueBuffer(fd, offset, destR)) {
1130                ALOGE("%s: queueBuffer failed for right mixer", __FUNCTION__);
1131                return false;
1132            }
1133        }
1134
1135        layerProp[i].mFlags &= ~HWC_MDPCOMP;
1136    }
1137
1138    return true;
1139}
1140}; //namespace
1141
1142