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