hwc_fbupdate.cpp revision a85d9f9f2d5cd0555b409b1fc974a9ecec3fee56
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
4 *
5 * Not a Contribution, Apache license notifications and license are
6 * retained for attribution purposes only.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21#define DEBUG_FBUPDATE 0
22#include <cutils/properties.h>
23#include <gralloc_priv.h>
24#include <overlay.h>
25#include <overlayRotator.h>
26#include "hwc_fbupdate.h"
27#include "mdp_version.h"
28#include "external.h"
29#include "virtual.h"
30
31using namespace qdutils;
32using namespace overlay;
33using overlay::Rotator;
34using namespace overlay::utils;
35
36namespace qhwc {
37
38namespace ovutils = overlay::utils;
39
40IFBUpdate* IFBUpdate::getObject(hwc_context_t *ctx, const int& dpy) {
41    if(isDisplaySplit(ctx, dpy)) {
42        if(qdutils::MDPVersion::getInstance().isSrcSplit()) {
43            return new FBSrcSplit(ctx, dpy);
44        }
45        return new FBUpdateSplit(ctx, dpy);
46    }
47    return new FBUpdateNonSplit(ctx, dpy);
48}
49
50IFBUpdate::IFBUpdate(hwc_context_t *ctx, const int& dpy) : mDpy(dpy) {
51    size_t size = 0;
52    getBufferAttributes(ctx->dpyAttr[mDpy].xres,
53            ctx->dpyAttr[mDpy].yres,
54            HAL_PIXEL_FORMAT_RGBA_8888,
55            0,
56            mAlignedFBWidth,
57            mAlignedFBHeight,
58            mTileEnabled, size);
59}
60
61void IFBUpdate::reset() {
62    mModeOn = false;
63    mRot = NULL;
64}
65
66bool IFBUpdate::prepareAndValidate(hwc_context_t *ctx,
67            hwc_display_contents_1 *list, int fbZorder) {
68    hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
69    mModeOn = prepare(ctx, list, layer->displayFrame, fbZorder) &&
70            ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd);
71    return mModeOn;
72}
73
74//================= Low res====================================
75FBUpdateNonSplit::FBUpdateNonSplit(hwc_context_t *ctx, const int& dpy):
76        IFBUpdate(ctx, dpy) {}
77
78void FBUpdateNonSplit::reset() {
79    IFBUpdate::reset();
80    mDest = ovutils::OV_INVALID;
81}
82
83bool FBUpdateNonSplit::preRotateExtDisplay(hwc_context_t *ctx,
84                                            hwc_layer_1_t *layer,
85                                            ovutils::Whf &info,
86                                            hwc_rect_t& sourceCrop,
87                                            ovutils::eMdpFlags& mdpFlags,
88                                            int& rotFlags)
89{
90    int extOrient = getExtOrientation(ctx);
91    ovutils::eTransform orient = static_cast<ovutils::eTransform >(extOrient);
92    if(mDpy && (extOrient & HWC_TRANSFORM_ROT_90)) {
93        mRot = ctx->mRotMgr->getNext();
94        if(mRot == NULL) return false;
95        ctx->mLayerRotMap[mDpy]->add(layer, mRot);
96        // Composed FB content will have black bars, if the viewFrame of the
97        // external is different from {0, 0, fbWidth, fbHeight}, so intersect
98        // viewFrame with sourceCrop to avoid those black bars
99        sourceCrop = getIntersection(sourceCrop, ctx->mViewFrame[mDpy]);
100        //Configure rotator for pre-rotation
101        if(configRotator(mRot, info, sourceCrop, mdpFlags, orient, 0) < 0) {
102            ALOGE("%s: configRotator Failed!", __FUNCTION__);
103            mRot = NULL;
104            return false;
105        }
106        info.format = (mRot)->getDstFormat();
107        updateSource(orient, info, sourceCrop);
108        rotFlags |= ovutils::ROT_PREROTATED;
109    }
110    return true;
111}
112
113bool FBUpdateNonSplit::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
114                             hwc_rect_t fbUpdatingRect, int fbZorder) {
115    if(!ctx->mMDP.hasOverlay) {
116        ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
117                 __FUNCTION__);
118        return false;
119    }
120    mModeOn = configure(ctx, list, fbUpdatingRect, fbZorder);
121    return mModeOn;
122}
123
124// Configure
125bool FBUpdateNonSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
126                               hwc_rect_t fbUpdatingRect, int fbZorder) {
127    bool ret = false;
128    hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
129    if (LIKELY(ctx->mOverlay)) {
130        int extOnlyLayerIndex = ctx->listStats[mDpy].extOnlyLayerIndex;
131        // ext only layer present..
132        if(extOnlyLayerIndex != -1) {
133            layer = &list->hwLayers[extOnlyLayerIndex];
134            layer->compositionType = HWC_OVERLAY;
135        }
136        overlay::Overlay& ov = *(ctx->mOverlay);
137
138        ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
139                ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
140                    mTileEnabled));
141
142        //Request a pipe
143        ovutils::eMdpPipeType type = ovutils::OV_MDP_PIPE_ANY;
144        if((qdutils::MDPVersion::getInstance().is8x26() ||
145                   qdutils::MDPVersion::getInstance().is8x16()) && mDpy) {
146            //For 8x26 external always use DMA pipe
147            type = ovutils::OV_MDP_PIPE_DMA;
148        }
149        ovutils::eDest dest = ov.nextPipe(type, mDpy, Overlay::MIXER_DEFAULT);
150        if(dest == ovutils::OV_INVALID) { //None available
151            ALOGE("%s: No pipes available to configure fb for dpy %d",
152                __FUNCTION__, mDpy);
153            return false;
154        }
155        mDest = dest;
156
157        if((mDpy && ctx->deviceOrientation) &&
158            ctx->listStats[mDpy].isDisplayAnimating) {
159            fbZorder = 0;
160        }
161
162        ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
163        ovutils::eIsFg isFg = ovutils::IS_FG_OFF;
164        ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
165
166        hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
167        hwc_rect_t displayFrame = layer->displayFrame;
168
169        // No FB update optimization on (1) Custom FB resolution,
170        // (2) External Mirror mode, (3) External orientation
171        if(!ctx->dpyAttr[mDpy].customFBSize && !ctx->mBufferMirrorMode
172           && !ctx->mExtOrientation) {
173            sourceCrop = fbUpdatingRect;
174            displayFrame = fbUpdatingRect;
175        }
176
177        int transform = layer->transform;
178        int rotFlags = ovutils::ROT_FLAGS_NONE;
179
180        ovutils::eTransform orient =
181                    static_cast<ovutils::eTransform>(transform);
182        // use ext orientation if any
183        int extOrient = getExtOrientation(ctx);
184
185        // Do not use getNonWormholeRegion() function to calculate the
186        // sourceCrop during animation on external display and
187        // Dont do wormhole calculation when extorientation is set on External
188        // Dont do wormhole calculation when extDownscale is enabled on External
189        if(ctx->listStats[mDpy].isDisplayAnimating && mDpy) {
190            sourceCrop = layer->displayFrame;
191        } else if((!mDpy ||
192                  (mDpy && !extOrient
193                  && !ctx->dpyAttr[mDpy].mDownScaleMode))
194                  && (extOnlyLayerIndex == -1)) {
195            if(!qdutils::MDPVersion::getInstance().is8x26() &&
196                !ctx->dpyAttr[mDpy].customFBSize) {
197                getNonWormholeRegion(list, sourceCrop);
198                displayFrame = sourceCrop;
199            }
200        }
201        calcExtDisplayPosition(ctx, NULL, mDpy, sourceCrop, displayFrame,
202                                   transform, orient);
203        //Store the displayFrame, will be used in getDisplayViewFrame
204        ctx->dpyAttr[mDpy].mDstRect = displayFrame;
205        setMdpFlags(layer, mdpFlags, 0, transform);
206        // For External use rotator if there is a rotation value set
207        ret = preRotateExtDisplay(ctx, layer, info,
208                sourceCrop, mdpFlags, rotFlags);
209        if(!ret) {
210            ALOGE("%s: preRotate for external Failed!", __FUNCTION__);
211            ctx->mOverlay->clear(mDpy);
212            ctx->mLayerRotMap[mDpy]->clear();
213            return false;
214        }
215        //For the mdp, since either we are pre-rotating or MDP does flips
216        orient = ovutils::OVERLAY_TRANSFORM_0;
217        transform = 0;
218        ovutils::PipeArgs parg(mdpFlags, info, zOrder, isFg,
219                               static_cast<ovutils::eRotFlags>(rotFlags),
220                               ovutils::DEFAULT_PLANE_ALPHA,
221                               (ovutils::eBlending)
222                               getBlending(layer->blending));
223        ret = true;
224        if(configMdp(ctx->mOverlay, parg, orient, sourceCrop, displayFrame,
225                    NULL, mDest) < 0) {
226            ALOGE("%s: configMdp failed for dpy %d", __FUNCTION__, mDpy);
227            ctx->mLayerRotMap[mDpy]->clear();
228            ret = false;
229        }
230    }
231    return ret;
232}
233
234bool FBUpdateNonSplit::draw(hwc_context_t *ctx, private_handle_t *hnd)
235{
236    if(!mModeOn) {
237        return true;
238    }
239    bool ret = true;
240    overlay::Overlay& ov = *(ctx->mOverlay);
241    ovutils::eDest dest = mDest;
242    int fd = hnd->fd;
243    uint32_t offset = hnd->offset;
244    if(mRot) {
245        if(!mRot->queueBuffer(fd, offset))
246            return false;
247        fd = mRot->getDstMemId();
248        offset = mRot->getDstOffset();
249    }
250    if (!ov.queueBuffer(fd, offset, dest)) {
251        ALOGE("%s: queueBuffer failed for FBUpdate", __FUNCTION__);
252        ret = false;
253    }
254    return ret;
255}
256
257//================= High res====================================
258FBUpdateSplit::FBUpdateSplit(hwc_context_t *ctx, const int& dpy):
259        IFBUpdate(ctx, dpy) {}
260
261void FBUpdateSplit::reset() {
262    IFBUpdate::reset();
263    mDestLeft = ovutils::OV_INVALID;
264    mDestRight = ovutils::OV_INVALID;
265    mRot = NULL;
266}
267
268bool FBUpdateSplit::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
269                              hwc_rect_t fbUpdatingRect, int fbZorder) {
270    if(!ctx->mMDP.hasOverlay) {
271        ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
272                 __FUNCTION__);
273        return false;
274    }
275    ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
276    mModeOn = configure(ctx, list, fbUpdatingRect, fbZorder);
277    return mModeOn;
278}
279
280// Configure
281bool FBUpdateSplit::configure(hwc_context_t *ctx,
282        hwc_display_contents_1 *list, hwc_rect_t fbUpdatingRect, int fbZorder) {
283    bool ret = false;
284    hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
285    if (LIKELY(ctx->mOverlay)) {
286        /*  External only layer present */
287        int extOnlyLayerIndex = ctx->listStats[mDpy].extOnlyLayerIndex;
288        if(extOnlyLayerIndex != -1) {
289            layer = &list->hwLayers[extOnlyLayerIndex];
290            layer->compositionType = HWC_OVERLAY;
291        }
292        ovutils::Whf info(mAlignedFBWidth, mAlignedFBHeight,
293                          ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
294                                                mTileEnabled));
295
296        overlay::Overlay& ov = *(ctx->mOverlay);
297        ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
298        ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
299        ovutils::eTransform orient =
300            static_cast<ovutils::eTransform>(layer->transform);
301        const int hw_w = ctx->dpyAttr[mDpy].xres;
302        const int hw_h = ctx->dpyAttr[mDpy].yres;
303        const int lSplit = getLeftSplit(ctx, mDpy);
304        mDestLeft = ovutils::OV_INVALID;
305        mDestRight = ovutils::OV_INVALID;
306
307        hwc_rect_t sourceCrop = fbUpdatingRect;
308        hwc_rect_t displayFrame = fbUpdatingRect;
309
310        ret = true;
311        /* Configure left pipe */
312        if(displayFrame.left < lSplit) {
313            ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
314                                               Overlay::MIXER_LEFT);
315            if(destL == ovutils::OV_INVALID) { //None available
316                ALOGE("%s: No pipes available to configure fb for dpy %d's left"
317                      " mixer", __FUNCTION__, mDpy);
318                return false;
319            }
320
321            mDestLeft = destL;
322
323            //XXX: FB layer plane alpha is currently sent as zero from
324            //surfaceflinger
325            ovutils::PipeArgs pargL(mdpFlags,
326                                    info,
327                                    zOrder,
328                                    ovutils::IS_FG_OFF,
329                                    ovutils::ROT_FLAGS_NONE,
330                                    ovutils::DEFAULT_PLANE_ALPHA,
331                                    (ovutils::eBlending)
332                                    getBlending(layer->blending));
333            hwc_rect_t cropL = sourceCrop;
334            hwc_rect_t dstL = displayFrame;
335            hwc_rect_t scissorL = {0, 0, lSplit, hw_h };
336            qhwc::calculate_crop_rects(cropL, dstL, scissorL, 0);
337
338            if (configMdp(ctx->mOverlay, pargL, orient, cropL,
339                           dstL, NULL, destL)< 0) {
340                ALOGE("%s: configMdp fails for left FB", __FUNCTION__);
341                ret = false;
342            }
343        }
344
345        /* Configure right pipe */
346        if(displayFrame.right > lSplit) {
347            ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
348                                               Overlay::MIXER_RIGHT);
349            if(destR == ovutils::OV_INVALID) { //None available
350                ALOGE("%s: No pipes available to configure fb for dpy %d's"
351                      " right mixer", __FUNCTION__, mDpy);
352                return false;
353            }
354
355            mDestRight = destR;
356            ovutils::eMdpFlags mdpFlagsR = mdpFlags;
357            ovutils::setMdpFlags(mdpFlagsR, ovutils::OV_MDSS_MDP_RIGHT_MIXER);
358
359            //XXX: FB layer plane alpha is currently sent as zero from
360            //surfaceflinger
361            ovutils::PipeArgs pargR(mdpFlagsR,
362                                    info,
363                                    zOrder,
364                                    ovutils::IS_FG_OFF,
365                                    ovutils::ROT_FLAGS_NONE,
366                                    ovutils::DEFAULT_PLANE_ALPHA,
367                                    (ovutils::eBlending)
368                                    getBlending(layer->blending));
369
370            hwc_rect_t cropR = sourceCrop;
371            hwc_rect_t dstR = displayFrame;
372            hwc_rect_t scissorR = {lSplit, 0, hw_w, hw_h };
373            qhwc::calculate_crop_rects(cropR, dstR, scissorR, 0);
374
375            dstR.left -= lSplit;
376            dstR.right -= lSplit;
377
378            if (configMdp(ctx->mOverlay, pargR, orient, cropR,
379                           dstR, NULL, destR) < 0) {
380                ALOGE("%s: configMdp fails for right FB", __FUNCTION__);
381                ret = false;
382            }
383        }
384
385        if(ret == false) {
386            ctx->mLayerRotMap[mDpy]->clear();
387        }
388    }
389    return ret;
390}
391
392bool FBUpdateSplit::draw(hwc_context_t *ctx, private_handle_t *hnd)
393{
394    if(!mModeOn) {
395        return true;
396    }
397    bool ret = true;
398    overlay::Overlay& ov = *(ctx->mOverlay);
399    if(mDestLeft != ovutils::OV_INVALID) {
400        if (!ov.queueBuffer(hnd->fd, hnd->offset, mDestLeft)) {
401            ALOGE("%s: queue failed for left of dpy = %d",
402                  __FUNCTION__, mDpy);
403            ret = false;
404        }
405    }
406    if(mDestRight != ovutils::OV_INVALID) {
407        if (!ov.queueBuffer(hnd->fd, hnd->offset, mDestRight)) {
408            ALOGE("%s: queue failed for right of dpy = %d",
409                  __FUNCTION__, mDpy);
410            ret = false;
411        }
412    }
413    return ret;
414}
415
416//=================FBSrcSplit====================================
417FBSrcSplit::FBSrcSplit(hwc_context_t *ctx, const int& dpy):
418        FBUpdateSplit(ctx, dpy) {}
419
420bool FBSrcSplit::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
421        hwc_rect_t fbUpdatingRect, int fbZorder) {
422    bool ret = false;
423    hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
424    int extOnlyLayerIndex = ctx->listStats[mDpy].extOnlyLayerIndex;
425    // ext only layer present..
426    if(extOnlyLayerIndex != -1) {
427        layer = &list->hwLayers[extOnlyLayerIndex];
428        layer->compositionType = HWC_OVERLAY;
429    }
430
431    overlay::Overlay& ov = *(ctx->mOverlay);
432
433    ovutils::Whf info(mAlignedFBWidth,
434            mAlignedFBHeight,
435            ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
436                mTileEnabled));
437
438    ovutils::eMdpFlags mdpFlags = OV_MDP_BLEND_FG_PREMULT;
439    ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
440
441    ovutils::PipeArgs parg(mdpFlags,
442            info,
443            zOrder,
444            ovutils::IS_FG_OFF,
445            ovutils::ROT_FLAGS_NONE,
446            ovutils::DEFAULT_PLANE_ALPHA,
447            (ovutils::eBlending)
448            getBlending(layer->blending));
449
450    int transform = layer->transform;
451    ovutils::eTransform orient =
452            static_cast<ovutils::eTransform>(transform);
453
454    hwc_rect_t cropL = fbUpdatingRect;
455    hwc_rect_t cropR = fbUpdatingRect;
456
457    //Request left pipe (or 1 by default)
458    ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
459            Overlay::MIXER_DEFAULT);
460    if(destL == ovutils::OV_INVALID) {
461        ALOGE("%s: No pipes available to configure fb for dpy %d's left"
462                " mixer", __FUNCTION__, mDpy);
463        return false;
464    }
465
466    ovutils::eDest destR = ovutils::OV_INVALID;
467
468    //Request right pipe (2 pipes needed only if dim > 2048)
469    if((fbUpdatingRect.right - fbUpdatingRect.left) >
470            qdutils::MAX_DISPLAY_DIM) {
471        destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
472                Overlay::MIXER_DEFAULT);
473        if(destR == ovutils::OV_INVALID) {
474            ALOGE("%s: No pipes available to configure fb for dpy %d's right"
475                    " mixer", __FUNCTION__, mDpy);
476            return false;
477        }
478
479        if(ctx->mOverlay->comparePipePriority(destL, destR) == -1) {
480            qhwc::swap(destL, destR);
481        }
482
483        //Split crop equally when using 2 pipes
484        cropL.right = (fbUpdatingRect.right + fbUpdatingRect.left) / 2;
485        cropR.left = cropL.right;
486    }
487
488    mDestLeft = destL;
489    mDestRight = destR;
490
491    if(destL != OV_INVALID) {
492        if(configMdp(ctx->mOverlay, parg, orient,
493                    cropL, cropL, NULL /*metadata*/, destL) < 0) {
494            ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
495            ctx->mLayerRotMap[mDpy]->clear();
496            return false;
497        }
498    }
499
500    //configure right pipe
501    if(destR != OV_INVALID) {
502        if(configMdp(ctx->mOverlay, parg, orient,
503                    cropR, cropR, NULL /*metadata*/, destR) < 0) {
504            ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
505            ctx->mLayerRotMap[mDpy]->clear();
506            return false;
507        }
508    }
509
510    return true;
511}
512
513//---------------------------------------------------------------------
514}; //namespace qhwc
515