HwcLayerList.cpp revision 93d8b1eff292888eeb8bf47299a766185a4fc8b0
1/*
2 * Copyright © 2012 Intel Corporation
3 * All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 *
24 * Authors:
25 *    Jackie Li <yaodong.li@intel.com>
26 *
27 */
28#include <HwcTrace.h>
29#include <Drm.h>
30#include <HwcLayerList.h>
31#include <Hwcomposer.h>
32#include <GraphicBuffer.h>
33#include <IDisplayDevice.h>
34#include <PlaneCapabilities.h>
35#include <DisplayQuery.h>
36
37namespace android {
38namespace intel {
39
40inline bool operator==(const hwc_rect_t& x, const hwc_rect_t& y)
41{
42    return (x.top == y.top &&
43            x.bottom == y.bottom &&
44            x.left == y.left &&
45            x.right == y.right);
46}
47
48inline bool operator !=(const hwc_rect_t& x, const hwc_rect_t& y)
49{
50    return !operator==(x, y);
51}
52
53HwcLayer::HwcLayer(int index, hwc_layer_1_t *layer)
54    : mIndex(index),
55      mLayer(layer),
56      mPlane(0),
57      mFormat(DataBuffer::FORMAT_INVALID),
58      mUsage(0),
59      mHandle(0),
60      mIsProtected(false),
61      mType(LAYER_FB),
62      mPriority(0),
63      mTransform(0),
64      mUpdated(false)
65{
66    memset(&mSourceCrop, 0, sizeof(mSourceCrop));
67    memset(&mDisplayFrame, 0, sizeof(mDisplayFrame));
68
69    setupAttributes();
70}
71
72HwcLayer::~HwcLayer()
73{
74    if (mPlane) {
75        WTRACE("HwcLayer is not cleaned up");
76    }
77
78    mLayer = NULL;
79    mPlane = NULL;
80}
81
82bool HwcLayer::attachPlane(DisplayPlane* plane, int device)
83{
84    if (mPlane) {
85        ETRACE("failed to attach plane, plane exists");
86        return false;
87    }
88
89    if (!plane) {
90        ETRACE("Invalid plane");
91        return false;
92    }
93
94    // update plane's z order
95    // z order = layer's index + 1
96    // reserve z order 0 for frame buffer target layer
97    plane->setZOrder(mIndex + 1);
98    plane->assignToDevice(device);
99    mPlane = plane;
100    return true;
101}
102
103DisplayPlane* HwcLayer::detachPlane()
104{
105    // reset plane's z order
106    if (mPlane)
107        mPlane->setZOrder(-1);
108    DisplayPlane *plane = mPlane;
109    mPlane = 0;
110    return plane;
111}
112
113void HwcLayer::setType(uint32_t type)
114{
115    if (!mLayer)
116        return;
117
118    switch (type) {
119    case LAYER_OVERLAY:
120    case LAYER_SKIPPED:
121        mLayer->compositionType = HWC_OVERLAY;
122        mLayer->hints |= HWC_HINT_CLEAR_FB;
123        break;
124    // NOTE: set compositionType to HWC_FRAMEBUFFER here so that we have
125    // a chance to submit the primary changes to HW.
126    // Upper layer HWComposer will reset the compositionType automatically.
127    case LAYER_FRAMEBUFFER_TARGET:
128    case LAYER_FB:
129    case LAYER_FORCE_FB:
130    default:
131        mLayer->compositionType = HWC_FRAMEBUFFER;
132        break;
133    }
134
135    mType = type;
136}
137
138uint32_t HwcLayer::getType() const
139{
140    return mType;
141}
142
143void HwcLayer::setCompositionType(int32_t type)
144{
145    mLayer->compositionType = type;
146}
147
148int32_t HwcLayer::getCompositionType() const
149{
150    return mLayer->compositionType;
151}
152
153int HwcLayer::getIndex() const
154{
155    return mIndex;
156}
157
158uint32_t HwcLayer::getFormat() const
159{
160    return mFormat;
161}
162
163uint32_t HwcLayer::getUsage() const
164{
165    return mUsage;
166}
167
168uint32_t HwcLayer::getHandle() const
169{
170    return mHandle;
171}
172
173bool HwcLayer::isProtected() const
174{
175    return mIsProtected;
176}
177
178hwc_layer_1_t* HwcLayer::getLayer() const
179{
180    return mLayer;
181}
182
183DisplayPlane* HwcLayer::getPlane() const
184{
185    return mPlane;
186}
187
188void HwcLayer::setPriority(uint32_t priority)
189{
190    mPriority = priority;
191}
192
193uint32_t HwcLayer::getPriority() const
194{
195    return mPriority;
196}
197
198bool HwcLayer::update(hwc_layer_1_t *layer)
199{
200    // update layer
201    mLayer = layer;
202    setupAttributes();
203
204    // if not a FB layer & a plane was attached update plane's data buffer
205    if (mPlane) {
206        mPlane->setPosition(layer->displayFrame.left,
207                            layer->displayFrame.top,
208                            layer->displayFrame.right - layer->displayFrame.left,
209                            layer->displayFrame.bottom - layer->displayFrame.top);
210        mPlane->setSourceCrop(layer->sourceCrop.left,
211                              layer->sourceCrop.top,
212                              layer->sourceCrop.right - layer->sourceCrop.left,
213                              layer->sourceCrop.bottom - layer->sourceCrop.top);
214        mPlane->setTransform(layer->transform);
215        bool ret = mPlane->setDataBuffer((uint32_t)layer->handle);
216        if (ret == true) {
217            return true;
218        }
219        WTRACE("failed to set data buffer, handle = %#x", (uint32_t)layer->handle);
220        if (!mIsProtected) {
221            // typical case: rotated buffer is not ready or handle is null
222            return false;
223        } else {
224            // protected video has to be rendered using overlay.
225            // if buffer is not ready overlay will still be attached to this layer
226            // but rendering needs to be skipped.
227            WTRACE("ignoring result of data buffer setting for protected video");
228            return true;
229        }
230    }
231
232    if (mType == LAYER_FRAMEBUFFER_TARGET ||
233        mType == LAYER_FB ||
234        mType == LAYER_FORCE_FB) {
235        // reset composition type after possible smart composition
236        mLayer->compositionType = HWC_FRAMEBUFFER;
237    }
238
239    return true;
240}
241
242bool HwcLayer::isUpdated()
243{
244    return mUpdated;
245}
246
247void HwcLayer::postFlip()
248{
249    mUpdated = false;
250    if (mPlane) {
251        mPlane->postFlip();
252    }
253}
254
255void HwcLayer::setupAttributes()
256{
257    if ((mLayer->flags & HWC_SKIP_LAYER) ||
258        mTransform != mLayer->transform ||
259        mSourceCrop != mLayer->sourceCrop ||
260        mDisplayFrame != mLayer->displayFrame ||
261        mHandle != (uint32_t)mLayer->handle) {
262        // TODO: same handle does not mean there is always no update
263        mUpdated = true;
264    }
265
266    // update handle always as it can become "NULL"
267    // if the given layer is not ready
268    mTransform = mLayer->transform;
269    mSourceCrop = mLayer->sourceCrop;
270    mDisplayFrame = mLayer->displayFrame;
271    mHandle = (uint32_t)mLayer->handle;
272
273    if (mFormat != DataBuffer::FORMAT_INVALID) {
274        // other attributes have been set.
275        return;
276    }
277
278    if (mLayer->handle == NULL) {
279        VTRACE("invalid handle");
280        return;
281    }
282
283    BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
284    if (bm == NULL) {
285        // TODO: this check is redundant
286        return;
287    }
288
289    DataBuffer *buffer = bm->lockDataBuffer((uint32_t)mLayer->handle);
290     if (!buffer) {
291         ETRACE("failed to get buffer");
292     } else {
293        mFormat = buffer->getFormat();
294        mPriority = buffer->getWidth() * buffer->getHeight();
295        mPriority <<= LAYER_PRIORITY_SIZE_OFFSET;
296        mPriority |= mIndex;
297        GraphicBuffer *gBuffer = (GraphicBuffer*)buffer;
298        mUsage = gBuffer->getUsage();
299        mIsProtected = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer);
300        if (mIsProtected) {
301            mPriority |= LAYER_PRIORITY_PROTECTED;
302        }
303        bm->unlockDataBuffer(buffer);
304    }
305}
306
307//------------------------------------------------------------------------------
308HwcLayerList::HwcLayerList(hwc_display_contents_1_t *list,
309                            DisplayPlaneManager& dpm,
310                            int disp)
311    : mList(list),
312      mLayerCount(0),
313      mLayers(),
314      mOverlayLayers(),
315      mFBLayers(),
316      mZOrderConfig(),
317      mDisplayPlaneManager(dpm),
318      mDisplayIndex(disp)
319{
320    if (mList) {
321        VTRACE("layer count = %d", list->numHwLayers);
322        mLayers.setCapacity(list->numHwLayers);
323        mOverlayLayers.setCapacity(list->numHwLayers);
324        mSkippedLayers.setCapacity(list->numHwLayers);
325        mFBLayers.setCapacity(list->numHwLayers);
326        mCandidates.setCapacity(list->numHwLayers);
327        mSpriteCandidates.setCapacity(list->numHwLayers);
328        mOverlayCandidates.setCapacity(list->numHwLayers);
329        mPossiblePrimaryLayers.setCapacity(list->numHwLayers);
330        mLayerCount = list->numHwLayers;
331        // analyze list from the top layer
332        analyze();
333    }
334}
335
336HwcLayerList::~HwcLayerList()
337{
338    CTRACE();
339}
340
341//------------------------------------------------------------------------------
342
343HwcLayerList::HwcLayerVector::HwcLayerVector()
344{
345
346}
347
348int HwcLayerList::HwcLayerVector::do_compare(const void* lhs,
349                                              const void* rhs) const
350{
351    const HwcLayer* l = *(HwcLayer**)lhs;
352    const HwcLayer* r = *(HwcLayer**)rhs;
353
354    // sorted from index 0 to n
355    return l->getIndex() - r->getIndex();
356}
357
358HwcLayerList::PriorityVector::PriorityVector()
359{
360
361}
362
363int HwcLayerList::PriorityVector::do_compare(const void* lhs,
364                                              const void* rhs) const
365{
366    const HwcLayer* l = *(HwcLayer**)lhs;
367    const HwcLayer* r = *(HwcLayer**)rhs;
368
369    return r->getPriority() - l->getPriority();
370}
371
372//------------------------------------------------------------------------------
373bool HwcLayerList::checkSupported(int planeType, HwcLayer *hwcLayer)
374{
375    bool valid = false;
376    hwc_layer_1_t& layer = *(hwcLayer->getLayer());
377
378    // if layer was forced to use FB
379    if (hwcLayer->getType() == HwcLayer::LAYER_FORCE_FB) {
380        VTRACE("layer was forced to use HWC_FRAMEBUFFER");
381        return false;
382    }
383
384    // check layer flags
385    if (layer.flags & HWC_SKIP_LAYER) {
386        VTRACE("plane type %d: (skip layer flag was set)", planeType);
387        return false;
388    }
389
390    if (layer.handle == 0) {
391        WTRACE("invalid buffer handle");
392        return false;
393    }
394
395    // check usage
396    if (!hwcLayer->getUsage() & GRALLOC_USAGE_HW_COMPOSER) {
397        WTRACE("not a composer layer");
398        return false;
399    }
400
401    // check buffer format
402    valid = PlaneCapabilities::isFormatSupported(planeType,
403                                                 hwcLayer->getFormat(),
404                                                 layer.transform);
405    if (!valid) {
406        VTRACE("plane type %d: (bad buffer format)", planeType);
407        return false;
408    }
409
410    // check layer blending
411    valid = PlaneCapabilities::isBlendingSupported(planeType,
412                                                  (uint32_t)layer.blending);
413    if (!valid) {
414        VTRACE("plane type %d: (bad blending)", planeType);
415        return false;
416    }
417
418    // check layer scaling
419    valid = PlaneCapabilities::isScalingSupported(planeType,
420                                                  layer.sourceCrop,
421                                                  layer.displayFrame);
422    if (!valid) {
423        VTRACE("plane type %d: (bad scaling)", planeType);
424        return false;
425    }
426
427    // TODO: check visible region?
428    return true;
429}
430
431void HwcLayerList::analyze()
432{
433    Hwcomposer& hwc = Hwcomposer::getInstance();
434    Drm *drm = hwc.getDrm();
435    DisplayPlane *plane;
436
437    if (!mList || mLayerCount == 0 || !drm)
438        return;
439
440    if (!initialize()) {
441        ETRACE("failed to initialize layer list");
442        return;
443    }
444
445    // go through layer list from top to bottom
446    preProccess();
447
448    // assign planes
449    assignPlanes();
450
451    // revisit the plane assignments
452    revisit();
453}
454
455bool HwcLayerList::initialize()
456{
457    for (size_t i = 0; i < mLayerCount; i++) {
458        hwc_layer_1_t *layer = &mList->hwLayers[i];
459        if (!layer) {
460            // unlikely happen
461            ETRACE("layer %d is null", i);
462            DEINIT_AND_RETURN_FALSE();
463        }
464
465        HwcLayer *hwcLayer = new HwcLayer(i, layer);
466        if (!hwcLayer) {
467            ETRACE("failed to allocate hwc layer %d", i);
468            DEINIT_AND_RETURN_FALSE();
469        }
470
471        // by default use GPU for rendering
472        if (layer->compositionType == HWC_FRAMEBUFFER_TARGET) {
473            hwcLayer->setType(HwcLayer::LAYER_FRAMEBUFFER_TARGET);
474        } else if (layer->compositionType == HWC_OVERLAY){
475            hwcLayer->setType(HwcLayer::LAYER_OVERLAY);
476        } else {
477            hwcLayer->setType(HwcLayer::LAYER_FB);
478        }
479
480        // add layer to layer list
481        mLayers.add(hwcLayer);
482    }
483
484    return true;
485}
486
487void HwcLayerList::deinitialize()
488{
489    // reclaim planes
490    for (size_t i = 0; i < mLayers.size(); i++) {
491        HwcLayer *hwcLayer = mLayers.itemAt(i);
492        if (hwcLayer) {
493            DisplayPlane *plane = hwcLayer->detachPlane();
494            if (plane)
495                mDisplayPlaneManager.reclaimPlane(*plane);
496        }
497        // delete HWC layer
498        delete hwcLayer;
499    }
500
501    mLayers.clear();
502    mOverlayLayers.clear();
503    mSkippedLayers.clear();
504    mFBLayers.clear();
505    mCandidates.clear();
506    mOverlayCandidates.clear();
507    mSpriteCandidates.clear();
508    mPossiblePrimaryLayers.clear();
509}
510
511void HwcLayerList::preProccess()
512{
513    Hwcomposer& hwc = Hwcomposer::getInstance();
514
515    // go through layer list, settle down the candidate layers
516    int topLayerIndex = mLayers.size() - 2;
517    for (int i = topLayerIndex; i >= 0; i--) {
518        HwcLayer *hwcLayer = mLayers.itemAt(i);
519        hwc_layer_1_t *layer = hwcLayer->getLayer();
520
521        if (layer->compositionType == HWC_OVERLAY) {
522            hwcLayer->setType(HwcLayer::LAYER_SKIPPED);
523            mSkippedLayers.add(hwcLayer);
524            continue;
525        }
526
527        // add layer to FB layer list anyways
528        mFBLayers.add(hwcLayer);
529
530        if (checkSupported(DisplayPlane::PLANE_SPRITE, hwcLayer)) {
531            // found a sprite candidate, add it to candidate & sprite
532            // candidate list
533            mCandidates.add(hwcLayer);
534            mSpriteCandidates.add(hwcLayer);
535            continue;
536        }
537
538        if (checkSupported(DisplayPlane::PLANE_OVERLAY, hwcLayer)) {
539            // video play back has 'special' cases, do more checks!!!
540
541            // use case #1: bypass overlay layers of primary device
542            // if in extend video mode
543            if (mDisplayIndex == IDisplayDevice::DEVICE_PRIMARY) {
544                // check if HWC is in video extended mode
545                if (DisplayQuery::isVideoFormat(hwcLayer->getFormat()) &&
546                    hwc.getDisplayAnalyzer()->checkVideoExtendedMode()) {
547                    ITRACE("video is skipped in extended mode");
548                    // remove it from fb layer list first
549                    mFBLayers.remove(hwcLayer);
550                    // layer has been skipped
551                    hwcLayer->setType(HwcLayer::LAYER_SKIPPED);
552                    mSkippedLayers.add(hwcLayer);
553                    continue;
554                }
555            }
556
557            // use case #2: overlay is not allowed at the moment, use 3D for it
558            if (!(hwc.getDisplayAnalyzer()->isOverlayAllowed())) {
559                ITRACE("overlay is not allowed");
560                continue;
561            }
562
563            // use case #3: don't use overlay for video layer during rotation
564            // TODO: review this change for it's NOT AOSP compatible!!!
565            if (mList->flags & HWC_ROTATION_IN_PROGRESS) {
566                continue;
567            }
568
569            // found a overlay candidate, add it to candidate & overlay
570            // candidate list
571            mCandidates.add(hwcLayer);
572            mOverlayCandidates.add(hwcLayer);
573            continue;
574        }
575    }
576}
577
578void HwcLayerList::assignPlanes()
579{
580    // assign overlay planes
581    for (size_t idx = 0; idx < mOverlayCandidates.size(); idx++) {
582        // break if no free overlay
583        if (!mDisplayPlaneManager.hasFreeOverlay()) {
584            VTRACE("no free overlay available");
585            break;
586        }
587
588        // attach plane
589        HwcLayer *hwcLayer = mOverlayCandidates.itemAt(idx);
590        DisplayPlane *plane = mDisplayPlaneManager.getOverlayPlane(mDisplayIndex);
591        if (!hwcLayer->attachPlane(plane, mDisplayIndex)) {
592            WTRACE("failed to attach plane");
593            mDisplayPlaneManager.reclaimPlane(*plane);
594            continue;
595        }
596
597        mFBLayers.remove(hwcLayer);
598        hwcLayer->setType(HwcLayer::LAYER_OVERLAY);
599        mOverlayLayers.add(hwcLayer);
600    }
601
602    for (size_t idx = 0; idx < mSpriteCandidates.size(); idx++) {
603        // break if no free sprite
604        if (!mDisplayPlaneManager.hasFreeSprite()) {
605            VTRACE("no free sprite available");
606            break;
607        }
608
609        HwcLayer *hwcLayer = mSpriteCandidates.itemAt(idx);
610        DisplayPlane *plane = mDisplayPlaneManager.getSpritePlane();
611        if (!plane) {
612            ETRACE("sprite plane is null");
613            break;
614        }
615        if (!plane->enable()) {
616            ETRACE("sprite plane is not ready");
617            mDisplayPlaneManager.putPlane(*plane);
618            continue;
619        }
620
621        // attach plane to hwc layer
622        if (!hwcLayer->attachPlane(plane, mDisplayIndex)) {
623            WTRACE("failed to attach plane");
624            mDisplayPlaneManager.reclaimPlane(*plane);
625            continue;
626        }
627        mFBLayers.remove(hwcLayer);
628        hwcLayer->setType(HwcLayer::LAYER_OVERLAY);
629        mOverlayLayers.add(hwcLayer);
630    }
631}
632
633void HwcLayerList::adjustAssignment()
634{
635    // find the least priority layer that has been attached a plane
636    HwcLayer *target = 0;
637    for (int i = mCandidates.size() - 1; i >= 0; i--) {
638        HwcLayer *hwcLayer = mCandidates.itemAt(i);
639        if (hwcLayer->getPlane() &&
640            hwcLayer->getType() == HwcLayer::LAYER_OVERLAY) {
641            target = hwcLayer;
642            break;
643        }
644    }
645
646    // it's impossible, print a warning message
647    if (!target) {
648        WTRACE("failed to find a HWC_OVERLAY layer");
649        return;
650    }
651
652    // if found a least priority layer detach plane from it and try to attach
653    // the reclaimed plane to the same type layer which has lower priority than
654    // the old layer
655
656    // set the layer type to LAYER_FORCE_FB
657    target->setType(HwcLayer::LAYER_FORCE_FB);
658    // remove layer from overlay layer list
659    mOverlayLayers.remove(target);
660    // add layer to FB layer list
661    mFBLayers.add(target);
662
663    // detach plane from the targeted layer
664    DisplayPlane *plane = target->detachPlane();
665    // try to find next candidate which we can attach the plane to it
666    HwcLayer *next = target;
667    ssize_t idx;
668    do {
669        // remove layer from candidates list
670        mCandidates.remove(next);
671
672        // remove layer from specific candidates list
673        switch (plane->getType()) {
674        case DisplayPlane::PLANE_OVERLAY:
675            idx = mOverlayCandidates.remove(next);
676            if (idx >= 0 && (size_t)idx < mOverlayCandidates.size()) {
677                next = mOverlayCandidates.itemAt(idx);
678            } else {
679                next = NULL;
680            }
681            break;
682        case DisplayPlane::PLANE_SPRITE:
683        case DisplayPlane::PLANE_PRIMARY:
684            idx = mSpriteCandidates.remove(next);
685            if (idx >= 0 && (size_t)idx < mSpriteCandidates.size()) {
686                next = mSpriteCandidates.itemAt(idx);
687            } else {
688                next = NULL;
689            }
690            break;
691        }
692    } while(next && !next->attachPlane(plane, mDisplayIndex));
693
694    // if failed to get next candidate, reclaim this plane
695    if (!next) {
696        VTRACE("reclaimed plane type %d, index %d",
697               plane->getType(), plane->getIndex());
698        mDisplayPlaneManager.reclaimPlane(*plane);
699        return;
700    }
701
702    mFBLayers.remove(next);
703    next->setType(HwcLayer::LAYER_OVERLAY);
704    mOverlayLayers.add(next);
705}
706
707void HwcLayerList::revisit()
708{
709    bool ret = false;
710
711    do {
712        // detach primaryPlane
713        detachPrimary();
714
715        // calculate possible primary layers
716        updatePossiblePrimaryLayers();
717
718        // if failed to find target primary layers, adjust current assignment
719        if (mFBLayers.size() && !mPossiblePrimaryLayers.size() ) {
720            VTRACE("failed to find primary target layers");
721            adjustAssignment();
722            continue;
723        }
724
725        ret = updateZOrderConfig();
726        //if failed to apply a z order configuration, fall back an overlay layer
727        if (!ret && mOverlayLayers.size()) {
728           VTRACE("failed to set zorder config, adjusting plane assigment...");
729           adjustAssignment();
730           continue;
731        }
732    } while (!ret);
733
734    // skip protected layers if we cannot find an appropriate solution to
735    // assign overlays.
736    // This could barely happen. however, if it happened we want make sure
737    // screen content is NOT messed up.
738    for (size_t i = 0; i < mLayers.size(); i++) {
739        HwcLayer *layer = mLayers.itemAt(i);
740        // set a layer to layer overlay and add it back to overlay layer list
741        if (layer->getType() != HwcLayer::LAYER_OVERLAY &&
742            layer->isProtected()) {
743            ITRACE("skip protected layer %d", layer->getIndex());
744            layer->setType(HwcLayer::LAYER_SKIPPED);
745            // move it from FB layer list to overlay layer list
746            mFBLayers.remove(layer);
747            mSkippedLayers.add(layer);
748        }
749    }
750}
751
752bool HwcLayerList::updateZOrderConfig()
753{
754    // acquire primary plane of this display device
755    DisplayPlane *primaryPlane =
756        mDisplayPlaneManager.getPrimaryPlane(mDisplayIndex);
757    if (!primaryPlane) {
758        // if primary allocation is failed, it should be a fatal error
759        ETRACE("failed to get primary plane for display %d", mDisplayIndex);
760        return false;
761    }
762
763    // primary can be used as sprite, setup Z order directly
764    if (usePrimaryAsSprite(primaryPlane)) {
765        VTRACE("primary was used as sprite");
766        return setupZOrderConfig();
767    }
768
769    // attach primary to frame buffer target
770    usePrimaryAsFramebufferTarget(primaryPlane);
771
772    int primaryZOrder = 0;
773    // if no possible primary layers, place it at bottom
774    if (!mPossiblePrimaryLayers.size()) {
775        primaryPlane->setZOrder(primaryZOrder);
776        return setupZOrderConfig();
777    }
778    // try to find out a suitable layer to place primary plane
779    bool success = false;
780    while (mPossiblePrimaryLayers.size()) {
781        HwcLayer *primaryLayer = mPossiblePrimaryLayers.itemAt(0);
782        // need update primary plane zorder
783        primaryZOrder = primaryLayer->getIndex() + 1;
784        primaryPlane->setZOrder(primaryZOrder);
785
786        // try to set z order config, return if setup z order successfully
787        success = setupZOrderConfig();
788        if (success) {
789            VTRACE("primary was attached to framebuffer target");
790            break;
791        }
792        // remove this layer from possible primary layer list
793        mPossiblePrimaryLayers.remove(primaryLayer);
794    }
795
796    return success;
797}
798
799bool HwcLayerList::usePrimaryAsSprite(DisplayPlane *primaryPlane)
800{
801    // only one FB layer left, it's possible to use primary as sprite
802    // if the assignment successes, we are done! update primary z order
803    // and attach primary plane to this layer.
804    if ((mFBLayers.size() == 1)) {
805        HwcLayer *layer = mFBLayers.itemAt(0);
806        if (checkSupported(DisplayPlane::PLANE_PRIMARY, layer)) {
807            VTRACE("primary check passed for primary layer");
808            // attach primary to layer
809            if (!layer->attachPlane(primaryPlane, mDisplayIndex)) {
810                WTRACE("failed to attach plane");
811                mDisplayPlaneManager.reclaimPlane(*primaryPlane);
812                return false;
813            }
814            // set the layer type to overlay
815            layer->setType(HwcLayer::LAYER_OVERLAY);
816            // remove layer from FB layer list
817            mFBLayers.remove(layer);
818            // add layer to overlay layers
819            mOverlayLayers.add(layer);
820            return true;
821        }
822    }
823
824    return false;
825}
826
827void HwcLayerList::detachPrimary()
828{
829    HwcLayer *framebufferTarget = mLayers.itemAt(mLayers.size() - 1);
830    DisplayPlane *primaryPlane = framebufferTarget->getPlane();
831
832    // if primary plane was attached to framebuffer target
833    // detach plane
834    if (primaryPlane) {
835        framebufferTarget->detachPlane();
836        // reclaim primary plane
837        mDisplayPlaneManager.reclaimPlane(*primaryPlane);
838        return;
839    }
840
841    // if primary plane was attached to a normal layer
842    for (size_t i = 0; i < mLayers.size() - 1; i++) {
843        HwcLayer *hwcLayer = mLayers.itemAt(i);
844        DisplayPlane *plane = hwcLayer->getPlane();
845        if (!plane)
846            continue;
847        if (plane->getType() == DisplayPlane::PLANE_PRIMARY) {
848            // detach plane
849            hwcLayer->detachPlane();
850            // set layer type to FRAMEBUFFER
851            hwcLayer->setType(HwcLayer::LAYER_FB);
852            // remove it from overlay list
853            mOverlayLayers.remove(hwcLayer);
854            // add it to fb layer list
855            mFBLayers.add(hwcLayer);
856            // reclaim primary plane
857            mDisplayPlaneManager.reclaimPlane(*plane);
858            break;
859        }
860    }
861}
862
863void HwcLayerList::updatePossiblePrimaryLayers()
864{
865    mPossiblePrimaryLayers.clear();
866
867    // if no FB layers, clear vector
868    if (!mFBLayers.size()) {
869        return;
870    }
871
872    for (size_t i = 0; i < mFBLayers.size(); i++) {
873        HwcLayer *target = mFBLayers.itemAt(i);
874        if (mergeFBLayersToLayer(target, i)) {
875            mPossiblePrimaryLayers.add(target);
876        }
877    }
878}
879
880void HwcLayerList::usePrimaryAsFramebufferTarget(DisplayPlane *primaryPlane)
881{
882    // attach primary to frame buffer target
883    HwcLayer *layer = mLayers.itemAt(mLayers.size() - 1);
884
885    // invalidate primary plane's data buffer cache
886    primaryPlane->invalidateBufferCache();
887    // NOTE: calling setType again to trigger glClear() for
888    // other overlay layers
889    layer->setType(HwcLayer::LAYER_FRAMEBUFFER_TARGET);
890    // attach primary plane, it has to be successful
891    layer->attachPlane(primaryPlane, mDisplayIndex);
892}
893
894bool HwcLayerList::calculatePrimaryZOrder(int& zorder)
895{
896    int primaryZOrder = -1;
897
898    // if no FB layers, move primary to the bottom
899    if (!mFBLayers.size()) {
900        primaryZOrder = 0;
901        return true;
902    }
903
904    for (size_t i = 0; i < mFBLayers.size(); i++) {
905        HwcLayer *target = mFBLayers.itemAt(i);
906        // if all other FB layers can be merged to target layer
907        // then it's fine to put primary plane here
908        if (mergeFBLayersToLayer(target, i)) {
909            primaryZOrder = (target->getIndex() + 1);
910            break;
911        }
912    }
913
914    zorder = primaryZOrder;
915
916    return (primaryZOrder != -1) ? true : false;
917}
918
919bool HwcLayerList::mergeFBLayersToLayer(HwcLayer *target, int idx)
920{
921    // merge all below FB layers to the target layer
922    for (int i = 0; i < idx; i++) {
923        HwcLayer *below = mFBLayers.itemAt(i);
924        if (!mergeToLayer(target, below)) {
925            return false;
926        }
927    }
928
929    // merge all above FB layer to the target layer
930    for (size_t i = idx + 1; i < mFBLayers.size(); i++) {
931        HwcLayer *above = mFBLayers.itemAt(i);
932        if (!mergeToLayer(target, above)) {
933            return false;
934        }
935    }
936
937    return true;
938}
939
940bool HwcLayerList::mergeToLayer(HwcLayer* target, HwcLayer* layer)
941{
942    int targetZOrder = target->getIndex();
943    int layerZOrder = layer->getIndex();
944
945    if (targetZOrder == layerZOrder) {
946        return true;
947    }
948
949    if (targetZOrder < layerZOrder) {
950        // layer is above target layer need check intersection with all
951        // overlay layers below this layer
952        for (int i = layerZOrder - 1; i > targetZOrder; i--) {
953            HwcLayer *l = mLayers.itemAt(i);
954            if (l->getPlane() && l->getType() == HwcLayer::LAYER_OVERLAY) {
955                // check intersection
956                if (hasIntersection(l, layer)) {
957                    return false;
958                }
959            }
960        }
961    } else {
962       // layer is under target layer need check intersection with all
963       // overlay layers above this layer
964       for (int i = layerZOrder + 1; i < targetZOrder; i++) {
965           HwcLayer *l = mLayers.itemAt(i);
966           if (l->getPlane() && l->getType() == HwcLayer::LAYER_OVERLAY) {
967               // check intersection
968               if (hasIntersection(l, layer)) {
969                   return false;
970               }
971           }
972       }
973    }
974
975    return true;
976}
977
978bool HwcLayerList::hasIntersection(HwcLayer *la, HwcLayer *lb)
979{
980    hwc_layer_1_t *a = la->getLayer();
981    hwc_layer_1_t *b = lb->getLayer();
982    hwc_rect_t *aRect = &a->displayFrame;
983    hwc_rect_t *bRect = &b->displayFrame;
984
985    if (bRect->right <= aRect->left ||
986        bRect->left >= aRect->right ||
987        bRect->top >= aRect->bottom ||
988        bRect->bottom <= aRect->top)
989        return false;
990
991    return true;
992}
993
994bool HwcLayerList::setupZOrderConfig()
995{
996    ZOrderConfig zorderConfig;
997    DisplayPlane *plane;
998    HwcLayer *layer;
999
1000    zorderConfig.setCapacity(mOverlayLayers.size() + 1);
1001
1002    // add all planes in overlay layer list
1003    for (size_t i = 0; i < mOverlayLayers.size(); i++) {
1004        layer = mOverlayLayers.itemAt(i);
1005        plane = layer->getPlane();
1006        if (!plane)
1007            continue;
1008        zorderConfig.add(plane);
1009    }
1010
1011    // add primary plane if it had been assigned to frame buffer target
1012    layer = mLayers.itemAt(mLayers.size() - 1);
1013    plane = layer->getPlane();
1014    if (plane) {
1015        zorderConfig.add(plane);
1016    }
1017
1018    return mDisplayPlaneManager.setZOrderConfig(zorderConfig);
1019}
1020
1021void HwcLayerList::setupSmartComposition()
1022{
1023    bool smartComposition = true;
1024    int frameBufferLayers = 0;
1025    HwcLayer *hwcLayer = NULL;
1026
1027    for (size_t i = 0; i < mLayerCount - 1; i++) {
1028        hwcLayer = mLayers.itemAt(i);
1029        if (hwcLayer->getCompositionType() == HWC_FRAMEBUFFER) {
1030            frameBufferLayers++;
1031            if (hwcLayer->isUpdated()) {
1032                smartComposition = false;
1033                break;
1034            }
1035        }
1036    }
1037
1038    if (!smartComposition || !frameBufferLayers) {
1039        return;
1040    }
1041
1042    ITRACE("entering smart composition");
1043    for (size_t i = 0; i < mLayerCount - 1; i++) {
1044        hwcLayer = mLayers.itemAt(i);
1045        hwcLayer->setCompositionType(HWC_OVERLAY);
1046    }
1047}
1048
1049bool HwcLayerList::update(hwc_display_contents_1_t *list)
1050{
1051    bool ret;
1052    bool again = false;
1053
1054    CTRACE();
1055
1056    // basic check to make sure the consistance
1057    if (!list) {
1058        ETRACE("null layer list");
1059        return false;
1060    }
1061
1062    if (list->numHwLayers != mLayerCount) {
1063        ETRACE("layer count doesn't match (%d, %d)", list->numHwLayers, mLayerCount);
1064        return false;
1065    }
1066
1067    // update list
1068    mList = list;
1069
1070    do {
1071        again = false;
1072        // update all layers, call each layer's update()
1073        for (size_t i = 0; i < mLayerCount; i++) {
1074            HwcLayer *hwcLayer = mLayers.itemAt(i);
1075            if (!hwcLayer) {
1076                ETRACE("no HWC layer for layer %d", i);
1077                continue;
1078            }
1079
1080            ret = hwcLayer->update(&list->hwLayers[i]);
1081            if (ret == false) {
1082                // layer update failed, fall back to ST and revisit all plane
1083                // assignment
1084                WTRACE("failed to update layer %d, count %d, type %d",
1085                         i, mLayerCount, hwcLayer->getType());
1086                // if type of layer is LAYER_FB, that layer must have been added to mFBLayers.
1087                if (hwcLayer->getType() != HwcLayer::LAYER_FB) {
1088                    // set layer to FB layer
1089                    hwcLayer->setType(HwcLayer::LAYER_FB);
1090                    // remove layer from overlay layer list
1091                    mOverlayLayers.remove(hwcLayer);
1092                    // add layer to FB layer list
1093                    mFBLayers.add(hwcLayer);
1094                    // revisit the overlay assignment.
1095                    revisit();
1096                }
1097            } else if (hwcLayer->getPlane() &&
1098                        hwcLayer->getType() == HwcLayer::LAYER_FB) {
1099                // layer update success, if the layer was assigned a plane
1100                // switch back to overlay and revisit all plane assignment
1101                ITRACE("updated layer %d, switch back to overlay", i);
1102                // set layer to overlay layer
1103                hwcLayer->setType(HwcLayer::LAYER_OVERLAY);
1104                // remove layer from Fb layer list
1105                mFBLayers.remove(hwcLayer);
1106                // add layer to overlay layer list
1107                mOverlayLayers.add(hwcLayer);
1108                // revisit plane assignment
1109                revisit();
1110                // need update again since we changed the plane assignment
1111                again = true;
1112            }
1113        }
1114    } while (again && mOverlayLayers.size());
1115
1116    setupSmartComposition();
1117    return true;
1118}
1119
1120DisplayPlane* HwcLayerList::getPlane(uint32_t index) const
1121{
1122    HwcLayer *hwcLayer;
1123
1124    if (index >= mLayers.size()) {
1125        ETRACE("invalid layer index %d", index);
1126        return 0;
1127    }
1128
1129    hwcLayer = mLayers.itemAt(index);
1130    if (!hwcLayer || (hwcLayer->getType() == HwcLayer::LAYER_FB) ||
1131        (hwcLayer->getType() ==  HwcLayer::LAYER_FORCE_FB))
1132        return 0;
1133
1134    if (hwcLayer->getHandle() == 0) {
1135        WTRACE("plane is attached with invalid handle");
1136        return 0;
1137    }
1138
1139    return hwcLayer->getPlane();
1140}
1141
1142bool HwcLayerList::hasProtectedLayer()
1143{
1144    for (size_t i = 0; i < mLayers.size(); i++) {
1145        HwcLayer *hwcLayer = mLayers.itemAt(i);
1146        if (hwcLayer && hwcLayer->isProtected()) {
1147            ITRACE("protected layer found, layer index is %d", i);
1148            return true;
1149        }
1150    }
1151    return false;
1152}
1153
1154bool HwcLayerList::hasVisibleLayer()
1155{
1156    // excluding framebuffer target layer
1157    int count = (int)mLayers.size() - 1;
1158    if (count <= 0) {
1159        ITRACE("number of layer is %d, visible layer is 0", mLayers.size());
1160        return false;
1161    }
1162
1163    // the last layer is always frambuffer target layer?
1164    for (size_t i = 0; i < mLayers.size() - 1; i++) {
1165        HwcLayer *hwcLayer = mLayers.itemAt(i);
1166        if (hwcLayer == NULL) {
1167            // TODO: remove this redundant check
1168            continue;
1169        }
1170        if (hwcLayer->getType() == HwcLayer::LAYER_OVERLAY &&
1171            hwcLayer->getPlane() == NULL) {
1172            // layer is invisible
1173            count--;
1174        }
1175    }
1176    ITRACE("number of visible layers %d", count);
1177    return count != 0;
1178}
1179
1180void HwcLayerList::postFlip()
1181{
1182    for (size_t i = 0; i < mLayers.size(); i++) {
1183        HwcLayer *hwcLayer = mLayers.itemAt(i);
1184        hwcLayer->postFlip();
1185    }
1186}
1187
1188void HwcLayerList::dump(Dump& d)
1189{
1190    d.append("Layer list: (number of layers %d):\n", mLayers.size());
1191    d.append(" LAYER |          TYPE          |   PLANE  | INDEX | Z Order \n");
1192    d.append("-------+------------------------+----------------------------\n");
1193    for (size_t i = 0; i < mLayers.size(); i++) {
1194        HwcLayer *hwcLayer = mLayers.itemAt(i);
1195        DisplayPlane *plane;
1196        int planeIndex = -1;
1197        int zorder = -1;
1198        const char *type = "HWC_FB";
1199        const char *planeType = "N/A";
1200
1201        if (hwcLayer) {
1202            switch (hwcLayer->getType()) {
1203            case HwcLayer::LAYER_FB:
1204            case HwcLayer::LAYER_FORCE_FB:
1205                type = "HWC_FB";
1206                break;
1207            case HwcLayer::LAYER_OVERLAY:
1208            case HwcLayer::LAYER_SKIPPED:
1209                type = "HWC_OVERLAY";
1210                break;
1211            case HwcLayer::LAYER_FRAMEBUFFER_TARGET:
1212                type = "HWC_FRAMEBUFFER_TARGET";
1213                break;
1214            default:
1215                type = "Unknown";
1216            }
1217
1218            plane = hwcLayer->getPlane();
1219            if (plane) {
1220                planeIndex = plane->getIndex();
1221                zorder = plane->getZOrder();
1222                switch (plane->getType()) {
1223                case DisplayPlane::PLANE_OVERLAY:
1224                    planeType = "OVERLAY";
1225                    break;
1226                case DisplayPlane::PLANE_SPRITE:
1227                    planeType = "SPRITE";
1228                    break;
1229                case DisplayPlane::PLANE_PRIMARY:
1230                    planeType = "PRIMARY";
1231                    break;
1232                default:
1233                    planeType = "Unknown";
1234                }
1235            }
1236
1237            d.append("  %2d   | %22s | %8s | %3D   | %3D \n",
1238                     i, type, planeType, planeIndex, zorder);
1239        }
1240    }
1241}
1242
1243} // namespace intel
1244} // namespace android
1245