Home | History | Annotate | Download | only in anniedale
      1 /*
      2 // Copyright(c)2014 IntelCorporation
      3 //
      4 // LicensedundertheApacheLicense,Version2.0(the"License");
      5 // youmaynotusethisfileexceptincompliancewiththeLicense.
      6 // YoumayobtainacopyoftheLicenseat
      7 //
      8 // http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unlessrequiredbyapplicablelaworagreedtoinwriting,software
     11 // distributedundertheLicenseisdistributedonan"ASIS"BASIS,
     12 // WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.
     13 // SeetheLicenseforthespecificlanguagegoverningpermissionsand
     14 // limitationsundertheLicense.
     15 */
     16 #include <HwcTrace.h>
     17 #include <utils/String8.h>
     18 #include <anniedale/AnnPlaneManager.h>
     19 #include <anniedale/AnnRGBPlane.h>
     20 #include <anniedale/AnnOverlayPlane.h>
     21 #include <anniedale/AnnCursorPlane.h>
     22 #include <PlaneCapabilities.h>
     23 
     24 namespace android {
     25 namespace intel {
     26 
     27 
     28 struct PlaneDescription {
     29     char nickname;
     30     int type;
     31     int index;
     32 };
     33 
     34 
     35 static PlaneDescription PLANE_DESC[] =
     36 {
     37     // nickname must be continous and start with 'A',
     38     // it is used to fast locate plane index and type
     39     {'A', DisplayPlane::PLANE_PRIMARY, 0},
     40     {'B', DisplayPlane::PLANE_PRIMARY, 1},
     41     {'C', DisplayPlane::PLANE_PRIMARY, 2},
     42     {'D', DisplayPlane::PLANE_SPRITE,  0},
     43     {'E', DisplayPlane::PLANE_SPRITE,  1},
     44     {'F', DisplayPlane::PLANE_SPRITE,  2},
     45     {'G', DisplayPlane::PLANE_OVERLAY, 0},  // nickname for Overlay A
     46     {'H', DisplayPlane::PLANE_OVERLAY, 1},   // nickname for Overlay C
     47     {'I', DisplayPlane::PLANE_CURSOR,  0},  // nickname for cursor A
     48     {'J', DisplayPlane::PLANE_CURSOR,  1},  // nickname for cursor B
     49     {'K', DisplayPlane::PLANE_CURSOR,  2}   // nickname for cursor C
     50 };
     51 
     52 
     53 struct ZOrderDescription {
     54     int index;  // based on overlay position
     55     const char *zorder;
     56 };
     57 
     58 // If overlay is in the bottom of Z order, two legitimate combinations are Oa, D, E, F
     59 // and Oc, D, E, F. However, plane A has to be part of the blending chain as it can't
     60 //  be disabled [HW bug]. The only legitimate combinations including overlay and plane A is:
     61 // A, Oa, E, F
     62 // A, Oc, E, F
     63 // Cursor plane can be placed on top of any plane below and is intentionally ignored
     64 // in the zorder table.
     65 
     66 // video mode panel doesn't need the primay plane A always on hack
     67 static ZOrderDescription PIPE_A_ZORDER_DESC_VID[] =
     68 {
     69     {0, "ADEF"},  // no overlay
     70     {1, "GDEF"},  // overlay A at bottom (1 << 0)
     71     {1, "HDEF"},  // overlay C at bottom (1 << 0)
     72     {2, "AGEF"},  // overlay A at next to bottom (1 << 1)
     73     {2, "AHEF"},  // overlay C at next to bottom (1 << 1)
     74     {3, "GHEF"},  // overlay A, C at bottom
     75     {4, "ADGF"},  // overlay A at next to top (1 << 2)
     76     {4, "ADHF"},  // overlay C at next to top (1 << 2)
     77     {6, "AGHF"},  // overlay A, C in between
     78     {8, "ADEG"},  // overlay A at top (1 << 3)
     79     {8, "ADEH"},  // overlay C at top (1 <<3)
     80     {12, "ADGH"}  // overlay A, C at top
     81 };
     82 
     83 static ZOrderDescription PIPE_A_ZORDER_DESC_CMD[] =
     84 {
     85     {0, "ADEF"},  // no overlay
     86     {1, "GEF"},  // overlay A at bottom (1 << 0)
     87     {1, "HEF"},  // overlay C at bottom (1 << 0)
     88     {2, "AGEF"},  // overlay A at next to bottom (1 << 1)
     89     {2, "AHEF"},  // overlay C at next to bottom (1 << 1)
     90     {3, "GHF"},   // overlay A, C at bottom
     91     {4, "ADGF"},  // overlay A at next to top (1 << 2)
     92     {4, "ADHF"},  // overlay C at next to top (1 << 2)
     93     {6, "AGHF"},  // overlay A, C in between
     94     {8, "ADEG"},  // overlay A at top (1 << 3)
     95     {8, "ADEH"},  // overlay C at top (1 <<3)
     96     {12, "ADGH"}  // overlay A, C at top
     97 };
     98 
     99 // use overlay C over overlay A if possible on pipe B
    100 static ZOrderDescription PIPE_B_ZORDER_DESC[] =
    101 {
    102     {0, "BD"},    // no overlay
    103     {1, "HBD"},   // overlay C at bottom (1 << 0)
    104 //    {1, "GBD"},   // overlay A at bottom (1 << 0), overlay A don`t switch to pipeB and only overlay C on pipeB
    105     {2, "BHD"},   // overlay C at middle (1 << 1)
    106 //   {2, "BGD"},   // overlay A at middle (1 << 1), overlay A don`t switch to pipeB and only overaly C on pipeB
    107     {3, "GHBD"},  // overlay A and C at bottom ( 1 << 0 + 1 << 1)
    108     {4, "BDH"},   // overlay C at top (1 << 2)
    109     {4, "BDG"},   // overlay A at top (1 << 2)
    110     {6, "BGHD"},  // overlay A/C at middle  1 << 1 + 1 << 2)
    111     {12, "BDGH"}  // overlay A/C at top (1 << 2 + 1 << 3)
    112 };
    113 
    114 static ZOrderDescription *PIPE_A_ZORDER_TBL;
    115 static int PIPE_A_ZORDER_COMBINATIONS;
    116 static ZOrderDescription *PIPE_B_ZORDER_TBL;
    117 static int PIPE_B_ZORDER_COMBINATIONS;
    118 static bool OVERLAY_HW_WORKAROUND;
    119 
    120 AnnPlaneManager::AnnPlaneManager()
    121     : DisplayPlaneManager()
    122 {
    123 }
    124 
    125 AnnPlaneManager::~AnnPlaneManager()
    126 {
    127 }
    128 
    129 bool AnnPlaneManager::initialize()
    130 {
    131     mSpritePlaneCount = 3;  // Sprite D, E, F
    132     mOverlayPlaneCount = 2; // Overlay A, C
    133     mPrimaryPlaneCount = 3; // Primary A, B, C
    134     mCursorPlaneCount = 3;
    135 
    136     uint32_t videoMode = 0;
    137     Drm *drm = Hwcomposer::getInstance().getDrm();
    138     drm->readIoctl(DRM_PSB_PANEL_QUERY, &videoMode, sizeof(uint32_t));
    139     if (videoMode == 1) {
    140         DTRACE("video mode panel, no primay A always on hack");
    141         PIPE_A_ZORDER_TBL = PIPE_A_ZORDER_DESC_VID;
    142         PIPE_A_ZORDER_COMBINATIONS =
    143             sizeof(PIPE_A_ZORDER_DESC_VID)/sizeof(ZOrderDescription);
    144     } else {
    145         DTRACE("command mode panel, need primay A always on hack");
    146         PIPE_A_ZORDER_TBL = PIPE_A_ZORDER_DESC_CMD;
    147         PIPE_A_ZORDER_COMBINATIONS =
    148             sizeof(PIPE_A_ZORDER_DESC_CMD)/sizeof(ZOrderDescription);
    149 	OVERLAY_HW_WORKAROUND = true;
    150     }
    151 
    152     PIPE_B_ZORDER_TBL = PIPE_B_ZORDER_DESC;
    153     PIPE_B_ZORDER_COMBINATIONS =
    154         sizeof(PIPE_B_ZORDER_DESC)/sizeof(ZOrderDescription);
    155 
    156     return DisplayPlaneManager::initialize();
    157 }
    158 
    159 void AnnPlaneManager::deinitialize()
    160 {
    161     DisplayPlaneManager::deinitialize();
    162 }
    163 
    164 DisplayPlane* AnnPlaneManager::allocPlane(int index, int type)
    165 {
    166     DisplayPlane *plane = NULL;
    167 
    168     switch (type) {
    169     case DisplayPlane::PLANE_PRIMARY:
    170         plane = new AnnRGBPlane(index, DisplayPlane::PLANE_PRIMARY, index/*disp*/);
    171         break;
    172     case DisplayPlane::PLANE_SPRITE:
    173         plane = new AnnRGBPlane(index, DisplayPlane::PLANE_SPRITE, 0/*disp*/);
    174         break;
    175     case DisplayPlane::PLANE_OVERLAY:
    176         plane = new AnnOverlayPlane(index, 0/*disp*/);
    177         break;
    178     case DisplayPlane::PLANE_CURSOR:
    179         plane = new AnnCursorPlane(index, index /*disp */);
    180         break;
    181     default:
    182         ETRACE("unsupported type %d", type);
    183         break;
    184     }
    185 
    186     if (plane && !plane->initialize(DisplayPlane::MIN_DATA_BUFFER_COUNT)) {
    187         ETRACE("failed to initialize plane.");
    188         DEINIT_AND_DELETE_OBJ(plane);
    189     }
    190 
    191     return plane;
    192 }
    193 
    194 bool AnnPlaneManager::isValidZOrder(int dsp, ZOrderConfig& config)
    195 {
    196     int size = (int)config.size();
    197     bool hasCursor = false;
    198 
    199     for (int i = 0; i < size; i++) {
    200         if (config[i]->planeType == DisplayPlane::PLANE_CURSOR) {
    201             hasCursor = true;
    202             break;
    203         }
    204     }
    205 
    206     if (size <= 0 ||
    207         (hasCursor && size > 5) ||
    208         (!hasCursor && size > 4)) {
    209         VTRACE("invalid z order config size %d", size);
    210         return false;
    211     }
    212 
    213     if (dsp == IDisplayDevice::DEVICE_PRIMARY) {
    214         int firstOverlay = -1;
    215         for (int i = 0; i < size; i++) {
    216             if (config[i]->planeType == DisplayPlane::PLANE_OVERLAY) {
    217                 firstOverlay = i;
    218                 break;
    219             }
    220         }
    221 
    222         int sprites = 0;
    223         for (int i = 0; i < size; i++) {
    224             if (config[i]->planeType != DisplayPlane::PLANE_OVERLAY &&
    225                 config[i]->planeType != DisplayPlane::PLANE_CURSOR) {
    226                 sprites++;
    227             }
    228         }
    229 
    230         if (firstOverlay < 0 && sprites > 4) {
    231             VTRACE("not capable to support more than 4 sprite layers");
    232             return false;
    233         }
    234 
    235         if (OVERLAY_HW_WORKAROUND) {
    236             if (firstOverlay == 0 && size > 2) {
    237                 VTRACE("can not support 3 sprite layers on top of overlay");
    238                 return false;
    239             }
    240         }
    241     } else if (dsp == IDisplayDevice::DEVICE_EXTERNAL) {
    242         int sprites = 0;
    243         for (int i = 0; i < size; i++) {
    244             if (config[i]->planeType != DisplayPlane::PLANE_OVERLAY &&
    245                 config[i]->planeType != DisplayPlane::PLANE_CURSOR) {
    246                 sprites++;
    247             }
    248         }
    249         if (sprites > 2) {
    250             ETRACE("number of sprite: %d, maximum 1 sprite and 1 primary supported on pipe 1", sprites);
    251             return false;
    252         }
    253     } else {
    254         ETRACE("invalid display device %d", dsp);
    255         return false;
    256     }
    257     return true;
    258 }
    259 
    260 bool AnnPlaneManager::assignPlanes(int dsp, ZOrderConfig& config)
    261 {
    262     if (dsp < 0 || dsp > IDisplayDevice::DEVICE_EXTERNAL) {
    263         ETRACE("invalid display device %d", dsp);
    264         return false;
    265     }
    266 
    267     int size = (int)config.size();
    268 
    269     // calculate index based on overlay Z order position
    270     int index = 0;
    271     for (int i = 0; i < size; i++) {
    272         if (config[i]->planeType == DisplayPlane::PLANE_OVERLAY) {
    273             index += (1 << i);
    274         }
    275     }
    276 
    277     int combinations;
    278     ZOrderDescription *table;
    279     if (dsp == IDisplayDevice::DEVICE_PRIMARY) {
    280         combinations = PIPE_A_ZORDER_COMBINATIONS;
    281         table = PIPE_A_ZORDER_TBL;
    282     } else {
    283         combinations = PIPE_B_ZORDER_COMBINATIONS;
    284         table = PIPE_B_ZORDER_TBL;
    285     }
    286 
    287     for (int i = 0; i < combinations; i++) {
    288         ZOrderDescription *zorderDesc = table + i;
    289 
    290         if (zorderDesc->index != index)
    291             continue;
    292 
    293         if (assignPlanes(dsp, config, zorderDesc->zorder)) {
    294             VTRACE("zorder assigned %s", zorderDesc->zorder);
    295             return true;
    296         }
    297     }
    298     return false;
    299 }
    300 
    301 bool AnnPlaneManager::assignPlanes(int dsp, ZOrderConfig& config, const char *zorder)
    302 {
    303     // zorder string does not include cursor plane, therefore cursor layer needs to be handled
    304     // in a special way. Cursor layer must be on top of zorder and no more than one cursor layer.
    305 
    306     int size = (int)config.size();
    307     if (zorder == NULL || size == 0) {
    308         //DTRACE("invalid zorder or ZOrder config.");
    309         return false;
    310     }
    311 
    312     int zorderLen = (int)strlen(zorder);
    313 
    314     // test if plane is avalable
    315     for (int i = 0; i < size; i++) {
    316         if (config[i]->planeType == DisplayPlane::PLANE_CURSOR) {
    317             if (i != size - 1) {
    318                 ETRACE("invalid zorder of cursor layer");
    319                 return false;
    320             }
    321             PlaneDescription& desc = PLANE_DESC['I' - 'A' + dsp];
    322             if (!isFreePlane(desc.type, desc.index)) {
    323                 ETRACE("cursor plane is not available");
    324                 return false;
    325             }
    326             continue;
    327         }
    328         if (i >= zorderLen) {
    329             DTRACE("index of ZOrderConfig is out of bound");
    330             return false;
    331         }
    332 
    333         char id = *(zorder + i);
    334         PlaneDescription& desc = PLANE_DESC[id - 'A'];
    335         if (!isFreePlane(desc.type, desc.index)) {
    336             DTRACE("plane type %d index %d is not available", desc.type, desc.index);
    337             return false;
    338         }
    339 
    340 #if 0
    341         // plane type check
    342         if (config[i]->planeType == DisplayPlane::PLANE_OVERLAY &&
    343             desc.type != DisplayPlane::PLANE_OVERLAY) {
    344             ETRACE("invalid plane type %d, expected %d", desc.type, config[i]->planeType);
    345             return false;
    346         }
    347 
    348         if (config[i]->planeType != DisplayPlane::PLANE_OVERLAY) {
    349             if (config[i]->planeType != DisplayPlane::PLANE_PRIMARY &&
    350                 config[i]->planeType != DisplayPlane::PLANE_SPRITE) {
    351                 ETRACE("invalid plane type %d,", config[i]->planeType);
    352                 return false;
    353             }
    354             if (desc.type != DisplayPlane::PLANE_PRIMARY &&
    355                 desc.type != DisplayPlane::PLANE_SPRITE) {
    356                 ETRACE("invalid plane type %d, expected %d", desc.type, config[i]->planeType);
    357                 return false;
    358             }
    359         }
    360 #endif
    361 
    362         if  (desc.type == DisplayPlane::PLANE_OVERLAY && desc.index == 1 &&
    363              config[i]->hwcLayer->getTransform() != 0) {
    364             DTRACE("overlay C does not support transform");
    365             return false;
    366         }
    367     }
    368 
    369     bool primaryPlaneActive = false;
    370     // allocate planes
    371     for (int i = 0; i < size; i++) {
    372         if (config[i]->planeType == DisplayPlane::PLANE_CURSOR) {
    373             PlaneDescription& desc = PLANE_DESC['I' - 'A' + dsp];
    374             ZOrderLayer *zLayer = config.itemAt(i);
    375             zLayer->plane = getPlane(desc.type, desc.index);
    376             if (zLayer->plane == NULL) {
    377                 ETRACE("failed to get cursor plane, should never happen!");
    378             }
    379             continue;
    380         }
    381 
    382         char id = *(zorder + i);
    383         PlaneDescription& desc = PLANE_DESC[id - 'A'];
    384         ZOrderLayer *zLayer = config.itemAt(i);
    385         zLayer->plane = getPlane(desc.type, desc.index);
    386         if (zLayer->plane == NULL) {
    387             ETRACE("failed to get plane, should never happen!");
    388         }
    389         // override type
    390         zLayer->planeType = desc.type;
    391         if (desc.type == DisplayPlane::PLANE_PRIMARY) {
    392             primaryPlaneActive = true;
    393         }
    394     }
    395 
    396     // setup Z order
    397     int slot = 0;
    398     for (int i = 0; i < size; i++) {
    399         slot = i;
    400 
    401         if (OVERLAY_HW_WORKAROUND) {
    402             if (!primaryPlaneActive &&
    403                 config[i]->planeType == DisplayPlane::PLANE_OVERLAY) {
    404                 slot += 1;
    405             }
    406         }
    407 
    408         config[i]->plane->setZOrderConfig(config, (void *)(unsigned long)slot);
    409         config[i]->plane->enable();
    410     }
    411 
    412 #if 0
    413     DTRACE("config size %d, zorder %s", size, zorder);
    414     for (int i = 0; i < size; i++) {
    415         const ZOrderLayer *l = config.itemAt(i);
    416         ITRACE("%d: plane type %d, index %d, zorder %d",
    417             i, l->planeType, l->plane->getIndex(), l->zorder);
    418     }
    419 #endif
    420 
    421     return true;
    422 }
    423 
    424 void* AnnPlaneManager::getZOrderConfig() const
    425 {
    426     return NULL;
    427 }
    428 
    429 int AnnPlaneManager::getFreePlanes(int dsp, int type)
    430 {
    431     RETURN_NULL_IF_NOT_INIT();
    432 
    433     if (type != DisplayPlane::PLANE_SPRITE) {
    434         return DisplayPlaneManager::getFreePlanes(dsp, type);
    435     }
    436 
    437     if (dsp < 0 || dsp > IDisplayDevice::DEVICE_EXTERNAL) {
    438         ETRACE("invalid display device %d", dsp);
    439         return 0;
    440     }
    441 
    442     uint32_t freePlanes = mFreePlanes[type] | mReclaimedPlanes[type];
    443     int start = 0;
    444     int stop = mSpritePlaneCount;
    445     if (dsp == IDisplayDevice::DEVICE_EXTERNAL) {
    446         // only Sprite D (index 0) can be assigned to pipe 1
    447         // Sprites E/F (index 1, 2) are fixed on pipe 0
    448         stop = 1;
    449     }
    450     int count = 0;
    451     for (int i = start; i < stop; i++) {
    452         if ((1 << i) & freePlanes) {
    453             count++;
    454         }
    455     }
    456     return count;
    457 }
    458 
    459 } // namespace intel
    460 } // namespace android
    461 
    462