HwcLayerList.cpp revision c0529447ae16f023dfab2978ea2b245f368e893b
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
40HwcLayerList::HwcLayerList(hwc_display_contents_1_t *list, int disp)
41    : mList(list),
42      mLayerCount(0),
43      mLayers(),
44      mFBLayers(),
45      mSpriteCandidates(),
46      mOverlayCandidates(),
47      mZOrderConfig(),
48      mFrameBufferTarget(NULL),
49      mDisplayIndex(disp)
50{
51    initialize();
52}
53
54HwcLayerList::~HwcLayerList()
55{
56    deinitialize();
57}
58
59bool HwcLayerList::checkSupported(int planeType, HwcLayer *hwcLayer)
60{
61    bool valid = false;
62    hwc_layer_1_t& layer = *(hwcLayer->getLayer());
63
64    // if layer was forced to use FB
65    if (hwcLayer->getType() == HwcLayer::LAYER_FORCE_FB) {
66        VTRACE("layer was forced to use HWC_FRAMEBUFFER");
67        return false;
68    }
69
70    // check layer flags
71    if (layer.flags & HWC_SKIP_LAYER) {
72        VTRACE("plane type %d: (skip layer flag was set)", planeType);
73        return false;
74    }
75
76    if (layer.handle == 0) {
77        WTRACE("invalid buffer handle");
78        return false;
79    }
80
81    // check usage
82    if (!hwcLayer->getUsage() & GRALLOC_USAGE_HW_COMPOSER) {
83        WTRACE("not a composer layer");
84        return false;
85    }
86
87    // check layer transform
88    valid = PlaneCapabilities::isTransformSupported(planeType, hwcLayer);
89    if (!valid) {
90        VTRACE("plane type %d: (bad transform)", planeType);
91        return false;
92    }
93
94    // check buffer format
95    valid = PlaneCapabilities::isFormatSupported(planeType, hwcLayer);
96    if (!valid) {
97        VTRACE("plane type %d: (bad buffer format)", planeType);
98        return false;
99    }
100
101    // check buffer size
102    valid = PlaneCapabilities::isSizeSupported(planeType, hwcLayer);
103    if (!valid) {
104        VTRACE("plane type %d: (bad buffer size)", planeType);
105        return false;
106    }
107
108    // check layer blending
109    valid = PlaneCapabilities::isBlendingSupported(planeType, hwcLayer);
110    if (!valid) {
111        VTRACE("plane type %d: (bad blending)", planeType);
112        return false;
113    }
114
115    // check layer scaling
116    valid = PlaneCapabilities::isScalingSupported(planeType, hwcLayer);
117    if (!valid) {
118        VTRACE("plane type %d: (bad scaling)", planeType);
119        return false;
120    }
121
122    // TODO: check visible region?
123    return true;
124}
125
126bool HwcLayerList::initialize()
127{
128    if (!mList || mList->numHwLayers == 0) {
129        ETRACE("invalid hwc list");
130        return false;
131    }
132
133    mLayerCount = (int)mList->numHwLayers;
134    mLayers.setCapacity(mLayerCount);
135    mFBLayers.setCapacity(mLayerCount);
136    mSpriteCandidates.setCapacity(mLayerCount);
137    mOverlayCandidates.setCapacity(mLayerCount);
138    mZOrderConfig.setCapacity(mLayerCount);
139    Hwcomposer& hwc = Hwcomposer::getInstance();
140
141    for (int i = 0; i < mLayerCount; i++) {
142        hwc_layer_1_t *layer = &mList->hwLayers[i];
143        if (!layer) {
144            DEINIT_AND_RETURN_FALSE("layer %d is null", i);
145        }
146
147        HwcLayer *hwcLayer = new HwcLayer(i, layer);
148        if (!hwcLayer) {
149            DEINIT_AND_RETURN_FALSE("failed to allocate hwc layer %d", i);
150        }
151
152        if (layer->compositionType == HWC_FRAMEBUFFER_TARGET) {
153            hwcLayer->setType(HwcLayer::LAYER_FRAMEBUFFER_TARGET);
154            mFrameBufferTarget = hwcLayer;
155        } else if (layer->compositionType == HWC_OVERLAY){
156            // skipped layer, filtered by Display Analyzer
157            hwcLayer->setType(HwcLayer::LAYER_SKIPPED);
158        } else if (layer->compositionType == HWC_FORCE_FRAMEBUFFER) {
159            layer->compositionType = HWC_FRAMEBUFFER;
160            hwcLayer->setType(HwcLayer::LAYER_FORCE_FB);
161            // add layer to FB layer list for zorder check during plane assignment
162            mFBLayers.add(hwcLayer);
163        } else  if (layer->compositionType == HWC_FRAMEBUFFER) {
164            // by default use GPU composition
165            hwcLayer->setType(HwcLayer::LAYER_FB);
166            mFBLayers.add(hwcLayer);
167            if (checkSupported(DisplayPlane::PLANE_SPRITE, hwcLayer)) {
168                mSpriteCandidates.add(hwcLayer);
169            } else if (hwc.getDisplayAnalyzer()->isOverlayAllowed() &&
170                checkSupported(DisplayPlane::PLANE_OVERLAY, hwcLayer)) {
171                mOverlayCandidates.add(hwcLayer);
172            } else {
173                // noncandidate layer
174            }
175        } else {
176            DEINIT_AND_RETURN_FALSE("invalid composition type %d", layer->compositionType);
177        }
178        // add layer to layer list
179        mLayers.add(hwcLayer);
180    }
181
182    if (mFrameBufferTarget == NULL) {
183        ETRACE("no frame buffer target?");
184        return false;
185    }
186
187    allocatePlanes();
188
189    //dump();
190    return true;
191}
192
193void HwcLayerList::deinitialize()
194{
195    if (mLayerCount == 0) {
196        return;
197    }
198
199    DisplayPlaneManager *planeManager = Hwcomposer::getInstance().getPlaneManager();
200    for (int i = 0; i < mLayerCount; i++) {
201        HwcLayer *hwcLayer = mLayers.itemAt(i);
202        if (hwcLayer) {
203            DisplayPlane *plane = hwcLayer->detachPlane();
204            if (plane) {
205                planeManager->reclaimPlane(mDisplayIndex, *plane);
206            }
207        }
208        delete hwcLayer;
209    }
210
211    mLayers.clear();
212    mFBLayers.clear();
213    mOverlayCandidates.clear();
214    mSpriteCandidates.clear();
215    mZOrderConfig.clear();
216    mFrameBufferTarget = NULL;
217    mLayerCount = 0;
218}
219
220
221bool HwcLayerList::allocatePlanes()
222{
223    return assignOverlayPlanes();
224}
225
226bool HwcLayerList::assignOverlayPlanes()
227{
228    int overlayCandidates = (int)mOverlayCandidates.size();
229    if (overlayCandidates == 0) {
230        return assignSpritePlanes();
231    }
232
233    DisplayPlaneManager *planeManager = Hwcomposer::getInstance().getPlaneManager();
234    int planeNumber = planeManager->getFreePlanes(mDisplayIndex, DisplayPlane::PLANE_OVERLAY);
235    if (planeNumber == 0) {
236        DTRACE("no overlay plane available. candidates %d", overlayCandidates);
237        return assignSpritePlanes();
238    }
239
240    if (planeNumber > overlayCandidates) {
241        // assuming all overlay planes have the same capabilities, just
242        // need up to number of candidates for plane assignment
243        planeNumber = overlayCandidates;
244    }
245
246    for (int i = planeNumber; i >= 0; i--) {
247        // assign as many overlay planes as possible
248        if (assignOverlayPlanes(0, i)) {
249            return true;
250        }
251        if (mZOrderConfig.size() != 0) {
252            ETRACE("ZOrder config is not cleaned up!");
253        }
254    }
255    return false;
256}
257
258
259bool HwcLayerList::assignOverlayPlanes(int index, int planeNumber)
260{
261    // index indicates position in mOverlayCandidates to start plane assignment
262    if (planeNumber == 0) {
263        return assignSpritePlanes();
264    }
265
266    int overlayCandidates = (int)mOverlayCandidates.size();
267    for (int i = index; i <= overlayCandidates - planeNumber; i++) {
268        ZOrderLayer *zlayer = addZOrderLayer(DisplayPlane::PLANE_OVERLAY, mOverlayCandidates[i]);
269        if (assignOverlayPlanes(i + 1, planeNumber - 1)) {
270            return true;
271        }
272        removeZOrderLayer(zlayer);
273    }
274    return false;
275}
276
277bool HwcLayerList::assignSpritePlanes()
278{
279    int spriteCandidates = (int)mSpriteCandidates.size();
280    if (spriteCandidates == 0) {
281        return assignPrimaryPlane();
282    }
283
284    //  number does not include primary plane
285    DisplayPlaneManager *planeManager = Hwcomposer::getInstance().getPlaneManager();
286    int planeNumber = planeManager->getFreePlanes(mDisplayIndex, DisplayPlane::PLANE_SPRITE);
287    if (planeNumber == 0) {
288        VTRACE("no sprite plane available, candidates %d", spriteCandidates);
289        return assignPrimaryPlane();
290    }
291
292    if (planeNumber > spriteCandidates) {
293        // assuming all sprite planes have the same capabilities, just
294        // need up to number of candidates for plane assignment
295        planeNumber = spriteCandidates;
296    }
297
298    for (int i = planeNumber; i >= 0; i--) {
299        // assign as many sprite planes as possible
300        if (assignSpritePlanes(0, i)) {
301            return true;
302        }
303
304        if (mOverlayCandidates.size() == 0 && mZOrderConfig.size() != 0) {
305            ETRACE("ZOrder config is not cleaned up!");
306        }
307    }
308    return false;
309}
310
311
312bool HwcLayerList::assignSpritePlanes(int index, int planeNumber)
313{
314    if (planeNumber == 0) {
315        return assignPrimaryPlane();
316    }
317
318    int spriteCandidates = (int)mSpriteCandidates.size();
319    for (int i = index; i <= spriteCandidates - planeNumber; i++) {
320        ZOrderLayer *zlayer = addZOrderLayer(DisplayPlane::PLANE_SPRITE, mSpriteCandidates[i]);
321        if (assignSpritePlanes(i + 1, planeNumber - 1)) {
322            return true;
323        }
324        removeZOrderLayer(zlayer);
325    }
326    return false;
327}
328
329bool HwcLayerList::assignPrimaryPlane()
330{
331    // find a sprit layer that is not candidate but has lower priority than candidates.
332    HwcLayer *spriteLayer = NULL;
333    for (int i = (int)mSpriteCandidates.size() - 1; i >= 0; i--) {
334        if (mSpriteCandidates[i]->mPlaneCandidate)
335            break;
336
337        spriteLayer = mSpriteCandidates[i];
338    }
339
340    int candidates = (int)mZOrderConfig.size();
341    int layers = (int)mFBLayers.size();
342    bool ok = false;
343
344    if (candidates == layers - 1 && spriteLayer != NULL) {
345        // primary plane is configured as sprite, all sprite candidates are offloaded to display planes
346        ok = assignPrimaryPlaneHelper(spriteLayer);
347        if (!ok) {
348            VTRACE("failed to use primary as sprite plane");
349        }
350    } else if (candidates == 0) {
351        // none assigned, use primary plane for frame buffer target and set zorder to 0
352        ok = assignPrimaryPlaneHelper(mFrameBufferTarget, 0);
353        if (!ok) {
354            ETRACE("failed to compose all layers to primary plane, should never happen");
355        }
356    } else if (candidates == layers) {
357        // all assigned, primary plane may be used during ZOrder config.
358        ok = attachPlanes();
359        if (!ok) {
360            VTRACE("failed to assign layers without primary");
361        }
362    } else {
363        // check if the remaining planes can be composed to frame buffer target (FBT)
364        // look up a legitimate Z order position to place FBT.
365        for (int i = 0; i < layers && !ok; i++) {
366            if (mFBLayers[i]->mPlaneCandidate) {
367                continue;
368            }
369            if (useAsFrameBufferTarget(mFBLayers[i])) {
370                ok = assignPrimaryPlaneHelper(mFrameBufferTarget, mFBLayers[i]->getZOrder());
371                if (!ok) {
372                    VTRACE("failed to use zorder %d for frame buffer target",
373                        mFBLayers[i]->getZOrder());
374                }
375            }
376        }
377        if (!ok) {
378            VTRACE("no possible zorder for frame buffer target");
379        }
380
381    }
382    return ok;
383}
384
385bool HwcLayerList::assignPrimaryPlaneHelper(HwcLayer *hwcLayer, int zorder)
386{
387    ZOrderLayer *zlayer = addZOrderLayer(DisplayPlane::PLANE_PRIMARY, hwcLayer, zorder);
388    bool ok = attachPlanes();
389    if (!ok) {
390        removeZOrderLayer(zlayer);
391    }
392    return ok;
393}
394
395bool HwcLayerList::attachPlanes()
396{
397    DisplayPlaneManager *planeManager = Hwcomposer::getInstance().getPlaneManager();
398    if (!planeManager->isValidZOrder(mDisplayIndex, mZOrderConfig)) {
399        VTRACE("invalid z order, size of config %d", mZOrderConfig.size());
400        return false;
401    }
402
403    if (!planeManager->assignPlanes(mDisplayIndex, mZOrderConfig)) {
404        WTRACE("failed to assign planes");
405        return false;
406    }
407
408    VTRACE("============= plane assignment===================");
409    for (int i = 0; i < (int)mZOrderConfig.size(); i++) {
410        ZOrderLayer *zlayer = mZOrderConfig.itemAt(i);
411        if (zlayer->plane == NULL || zlayer->hwcLayer == NULL) {
412            ETRACE("invalid ZOrderLayer, should never happen!!");
413            return false;
414        }
415
416        zlayer->plane->setZOrder(i);
417
418        if (zlayer->hwcLayer != mFrameBufferTarget) {
419            zlayer->hwcLayer->setType(HwcLayer::LAYER_OVERLAY);
420            // update FB layers for smart composition
421            mFBLayers.remove(zlayer->hwcLayer);
422        }
423
424        zlayer->hwcLayer->attachPlane(zlayer->plane, mDisplayIndex);
425
426        VTRACE("total %d, layer %d, type %d, index %d, zorder %d",
427            mLayerCount - 1,
428            zlayer->hwcLayer->getIndex(),
429            zlayer->plane->getType(),
430            zlayer->plane->getIndex(),
431            zlayer->zorder);
432
433        delete zlayer;
434    }
435
436    mZOrderConfig.clear();
437    return true;
438}
439
440bool HwcLayerList::useAsFrameBufferTarget(HwcLayer *target)
441{
442    // check if zorder of target can be used as zorder of frame buffer target
443    // eligible only when all noncandidate layers can be merged to the target layer:
444    // 1) noncandidate layer and candidate layer below the target layer can't overlap
445    // if candidate layer is on top of non candidate layer, as "noncandidate layer" needs
446    // to be moved up to target layer in z order;
447    // 2) noncandidate layer and candidate layers above the target layer can't overlap
448    // if candidate layer is below noncandidate layer, as "noncandidate layer" needs
449    // to be moved down to target layer in z order.
450
451    int targetLayerIndex = target->getIndex();
452
453    // check candidate and noncandidate layers below this candidate does not overlap
454    for (int below = 0; below < targetLayerIndex; below++) {
455        if (mFBLayers[below]->mPlaneCandidate) {
456            continue;
457        } else {
458            // check candidate layer above this noncandidate layer does not overlap
459            for (int above = below + 1; above < targetLayerIndex; above++) {
460                if (mFBLayers[above]->mPlaneCandidate == false) {
461                    continue;
462                }
463                if (hasIntersection(mFBLayers[above], mFBLayers[below])) {
464                    return false;
465                }
466            }
467        }
468    }
469
470    // check candidate and noncandidate layers above this candidate does not overlap
471    for (int above = targetLayerIndex + 1; above < mLayerCount - 1; above++) {
472        if (mFBLayers[above]->mPlaneCandidate) {
473            continue;
474        } else {
475            // check candidate layer below this noncandidate layer does not overlap
476            for (int below = targetLayerIndex + 1; below < above; below++) {
477                if (mFBLayers[below]->mPlaneCandidate == false) {
478                    continue;
479                }
480                if (hasIntersection(mFBLayers[above], mFBLayers[below])) {
481                    return false;
482                }
483            }
484        }
485    }
486
487    return true;
488}
489
490bool HwcLayerList::hasIntersection(HwcLayer *la, HwcLayer *lb)
491{
492    hwc_layer_1_t *a = la->getLayer();
493    hwc_layer_1_t *b = lb->getLayer();
494    hwc_rect_t *aRect = &a->displayFrame;
495    hwc_rect_t *bRect = &b->displayFrame;
496
497    if (bRect->right <= aRect->left ||
498        bRect->left >= aRect->right ||
499        bRect->top >= aRect->bottom ||
500        bRect->bottom <= aRect->top)
501        return false;
502
503    return true;
504}
505
506ZOrderLayer* HwcLayerList::addZOrderLayer(int type, HwcLayer *hwcLayer, int zorder)
507{
508    ZOrderLayer *layer = new ZOrderLayer;
509    layer->planeType = type;
510    layer->hwcLayer = hwcLayer;
511    layer->zorder = (zorder != -1) ? zorder : hwcLayer->getZOrder();
512    layer->plane = NULL;
513
514    if (hwcLayer->mPlaneCandidate) {
515        ETRACE("plane is candidate!, order = %d", zorder);
516    }
517
518    hwcLayer->mPlaneCandidate = true;
519
520    if ((int)mZOrderConfig.indexOf(layer) >= 0) {
521        ETRACE("layer exists!");
522    }
523
524    mZOrderConfig.add(layer);
525    return layer;
526}
527
528void HwcLayerList::removeZOrderLayer(ZOrderLayer *layer)
529{
530    if ((int)mZOrderConfig.indexOf(layer) < 0) {
531        ETRACE("layer does not exist!");
532    }
533
534    mZOrderConfig.remove(layer);
535
536    if (layer->hwcLayer->mPlaneCandidate == false) {
537        ETRACE("plane is not candidate!, order %d", layer->zorder);
538    }
539    layer->hwcLayer->mPlaneCandidate = false;
540    delete layer;
541}
542
543void HwcLayerList::setupSmartComposition()
544{
545    uint32_t compositionType = HWC_OVERLAY;
546    HwcLayer *hwcLayer = NULL;
547
548    // setup smart composition only there's no update on all FB layers
549    for (size_t i = 0; i < mFBLayers.size(); i++) {
550        hwcLayer = mFBLayers.itemAt(i);
551        if (hwcLayer->isUpdated()) {
552            compositionType = HWC_FRAMEBUFFER;
553        }
554    }
555
556    VTRACE("smart composition enabled %s",
557           (compositionType == HWC_OVERLAY) ? "TRUE" : "FALSE");
558    for (size_t i = 0; i < mFBLayers.size(); i++) {
559        hwcLayer = mFBLayers.itemAt(i);
560        switch (hwcLayer->getType()) {
561        case HwcLayer::LAYER_FB:
562        case HwcLayer::LAYER_FORCE_FB:
563            hwcLayer->setCompositionType(compositionType);
564            break;
565        default:
566            ETRACE("Invalid layer type %d", hwcLayer->getType());
567            break;
568        }
569    }
570}
571
572#if 1  // support overlay fallback to GLES
573
574bool HwcLayerList::update(hwc_display_contents_1_t *list)
575{
576    bool ret;
577
578    // basic check to make sure the consistance
579    if (!list) {
580        ETRACE("null layer list");
581        return false;
582    }
583
584    if ((int)list->numHwLayers != mLayerCount) {
585        ETRACE("layer count doesn't match (%d, %d)", list->numHwLayers, mLayerCount);
586        return false;
587    }
588
589    // update list
590    mList = list;
591
592    bool ok = true;
593    // update all layers, call each layer's update()
594    for (int i = 0; i < mLayerCount; i++) {
595        HwcLayer *hwcLayer = mLayers.itemAt(i);
596        if (!hwcLayer) {
597            ETRACE("no HWC layer for layer %d", i);
598            continue;
599        }
600
601        if (!hwcLayer->update(&list->hwLayers[i])) {
602            ok = false;
603            hwcLayer->setCompositionType(HWC_FORCE_FRAMEBUFFER);
604        }
605    }
606
607    if (!ok) {
608        ITRACE("overlay fallback to GLES. flags: %#x", list->flags);
609        for (int i = 0; i < mLayerCount - 1; i++) {
610            HwcLayer *hwcLayer = mLayers.itemAt(i);
611            if (hwcLayer->getPlane() &&
612                hwcLayer->getCompositionType() == HWC_OVERLAY) {
613                hwcLayer->setCompositionType(HWC_FRAMEBUFFER);
614            }
615        }
616        mLayers.itemAt(mLayerCount - 1)->setCompositionType(HWC_FRAMEBUFFER_TARGET);
617        deinitialize();
618        mList = list;
619        initialize();
620    }
621
622    setupSmartComposition();
623    return true;
624}
625
626#else
627
628bool HwcLayerList::update(hwc_display_contents_1_t *list)
629{
630    bool ret;
631
632    // basic check to make sure the consistance
633    if (!list) {
634        ETRACE("null layer list");
635        return false;
636    }
637
638    if ((int)list->numHwLayers != mLayerCount) {
639        ETRACE("layer count doesn't match (%d, %d)", list->numHwLayers, mLayerCount);
640        return false;
641    }
642
643    // update list
644    mList = list;
645
646    // update all layers, call each layer's update()
647    for (int i = 0; i < mLayerCount; i++) {
648        HwcLayer *hwcLayer = mLayers.itemAt(i);
649        if (!hwcLayer) {
650            ETRACE("no HWC layer for layer %d", i);
651            continue;
652        }
653
654        hwcLayer->update(&list->hwLayers[i]);
655    }
656
657    setupSmartComposition();
658    return true;
659}
660
661#endif
662
663DisplayPlane* HwcLayerList::getPlane(uint32_t index) const
664{
665    HwcLayer *hwcLayer;
666
667    if (index >= mLayers.size()) {
668        ETRACE("invalid layer index %d", index);
669        return 0;
670    }
671
672    hwcLayer = mLayers.itemAt(index);
673    if ((hwcLayer->getType() == HwcLayer::LAYER_FB) ||
674        (hwcLayer->getType() == HwcLayer::LAYER_FORCE_FB) ||
675        (hwcLayer->getType() == HwcLayer::LAYER_SKIPPED)) {
676        return 0;
677    }
678
679    if (hwcLayer->getHandle() == 0) {
680        DTRACE("plane is attached with invalid handle");
681        return 0;
682    }
683
684    return hwcLayer->getPlane();
685}
686
687void HwcLayerList::postFlip()
688{
689    for (size_t i = 0; i < mLayers.size(); i++) {
690        HwcLayer *hwcLayer = mLayers.itemAt(i);
691        hwcLayer->postFlip();
692    }
693}
694
695void HwcLayerList::dump(Dump& d)
696{
697    d.append("Layer list: (number of layers %d):\n", mLayers.size());
698    d.append(" LAYER |          TYPE          |   PLANE  | INDEX | Z Order \n");
699    d.append("-------+------------------------+----------------------------\n");
700    for (size_t i = 0; i < mLayers.size(); i++) {
701        HwcLayer *hwcLayer = mLayers.itemAt(i);
702        DisplayPlane *plane;
703        int planeIndex = -1;
704        int zorder = -1;
705        const char *type = "HWC_FB";
706        const char *planeType = "N/A";
707
708        if (hwcLayer) {
709            switch (hwcLayer->getType()) {
710            case HwcLayer::LAYER_FB:
711            case HwcLayer::LAYER_FORCE_FB:
712                type = "HWC_FB";
713                break;
714            case HwcLayer::LAYER_OVERLAY:
715            case HwcLayer::LAYER_SKIPPED:
716                type = "HWC_OVERLAY";
717                break;
718            case HwcLayer::LAYER_FRAMEBUFFER_TARGET:
719                type = "HWC_FRAMEBUFFER_TARGET";
720                break;
721            default:
722                type = "Unknown";
723            }
724
725            plane = hwcLayer->getPlane();
726            if (plane) {
727                planeIndex = plane->getIndex();
728                zorder = plane->getZOrder();
729                switch (plane->getType()) {
730                case DisplayPlane::PLANE_OVERLAY:
731                    planeType = "OVERLAY";
732                    break;
733                case DisplayPlane::PLANE_SPRITE:
734                    planeType = "SPRITE";
735                    break;
736                case DisplayPlane::PLANE_PRIMARY:
737                    planeType = "PRIMARY";
738                    break;
739                default:
740                    planeType = "Unknown";
741                }
742            }
743
744            d.append("  %2d   | %22s | %8s | %3D   | %3D \n",
745                     i, type, planeType, planeIndex, zorder);
746        }
747    }
748}
749
750
751void HwcLayerList::dump()
752{
753    static char const* compositionTypeName[] = {
754        "GLES",
755        "HWC",
756        "BG",
757        "FBT",
758        "N/A"};
759
760    static char const* planeTypeName[] = {
761        "SPRITE",
762        "OVERLAY",
763        "PRIMARY",
764        "UNKNOWN"};
765
766    DTRACE(" numHwLayers = %u, flags = %08x", mList->numHwLayers, mList->flags);
767
768    DTRACE(" type |  handle  | hints | flags | tr | blend | alpha |  format  |           source crop             |            frame          | index | zorder |  plane  ");
769    DTRACE("------+----------+-------+-------+----+-------+-------+----------+-----------------------------------+---------------------------+-------+--------+---------");
770
771
772    for (int i = 0 ; i < mLayerCount ; i++) {
773        const hwc_layer_1_t&l = mList->hwLayers[i];
774        DisplayPlane *plane = mLayers[i]->getPlane();
775        int planeIndex = -1;
776        int zorder = -1;
777        const char *planeType = "N/A";
778        if (plane) {
779            planeIndex = plane->getIndex();
780            zorder = plane->getZOrder();
781            planeType = planeTypeName[plane->getType()];
782        }
783
784        DTRACE(
785            " %4s | %8x | %5x | %5x | %2x | %5x | %5x | %8x | [%7.1f,%7.1f,%7.1f,%7.1f] | [%5d,%5d,%5d,%5d] | %5d | %6d | %7s ",
786            compositionTypeName[l.compositionType],
787            mLayers[i]->getHandle(), l.hints, l.flags, l.transform, l.blending, l.planeAlpha, mLayers[i]->getFormat(),
788            l.sourceCropf.left, l.sourceCropf.top, l.sourceCropf.right, l.sourceCropf.bottom,
789            l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
790            planeIndex, zorder, planeType);
791    }
792
793}
794
795
796} // namespace intel
797} // namespace android
798