Home | History | Annotate | Download | only in base
      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 <common/utils/HwcTrace.h>
     17 #include <Hwcomposer.h>
     18 #include <common/utils/Dump.h>
     19 #include <UeventObserver.h>
     20 
     21 namespace android {
     22 namespace intel {
     23 
     24 Hwcomposer* Hwcomposer::sInstance(0);
     25 
     26 Hwcomposer::Hwcomposer()
     27     : mProcs(0),
     28       mDrm(0),
     29       mPlaneManager(0),
     30       mBufferManager(0),
     31       mDisplayAnalyzer(0),
     32       mDisplayContext(0),
     33       mUeventObserver(0),
     34       mInitialized(false)
     35 {
     36     CTRACE();
     37 
     38     mDisplayDevices.setCapacity(IDisplayDevice::DEVICE_COUNT);
     39     mDisplayDevices.clear();
     40 }
     41 
     42 Hwcomposer::~Hwcomposer()
     43 {
     44     CTRACE();
     45     deinitialize();
     46 }
     47 
     48 bool Hwcomposer::initCheck() const
     49 {
     50     return mInitialized;
     51 }
     52 
     53 bool Hwcomposer::prepare(size_t numDisplays,
     54                           hwc_display_contents_1_t** displays)
     55 {
     56     bool ret = true;
     57 
     58     RETURN_FALSE_IF_NOT_INIT();
     59     ALOGTRACE("display count = %d", numDisplays);
     60 
     61     if (!numDisplays || !displays) {
     62         ELOGTRACE("invalid parameters");
     63         return false;
     64     }
     65 
     66     mDisplayAnalyzer->analyzeContents(numDisplays, displays);
     67 
     68     // disable reclaimed planes
     69     mPlaneManager->disableReclaimedPlanes();
     70 
     71     // reclaim all allocated planes if possible
     72     for (size_t i = 0; i < numDisplays; i++) {
     73         if (i >= mDisplayDevices.size()) {
     74             continue;
     75         }
     76         IDisplayDevice *device = mDisplayDevices.itemAt(i);
     77         if (!device) {
     78             VLOGTRACE("device %d doesn't exist", i);
     79             continue;
     80         }
     81         device->prePrepare(displays[i]);
     82     }
     83 
     84     for (size_t i = 0; i < numDisplays; i++) {
     85         if (i >= mDisplayDevices.size()) {
     86             continue;
     87         }
     88         IDisplayDevice *device = mDisplayDevices.itemAt(i);
     89         if (!device) {
     90             VLOGTRACE("device %d doesn't exist", i);
     91             continue;
     92         }
     93         ret = device->prepare(displays[i]);
     94         if (ret == false) {
     95             ELOGTRACE("failed to do prepare for device %d", i);
     96             continue;
     97         }
     98     }
     99 
    100     return ret;
    101 }
    102 
    103 bool Hwcomposer::commit(size_t numDisplays,
    104                          hwc_display_contents_1_t **displays)
    105 {
    106     bool ret = true;
    107 
    108     RETURN_FALSE_IF_NOT_INIT();
    109     ALOGTRACE("display count = %d", numDisplays);
    110 
    111     if (!numDisplays || !displays) {
    112         ELOGTRACE("invalid parameters");
    113         return false;
    114     }
    115 
    116     mDisplayContext->commitBegin(numDisplays, displays);
    117 
    118     for (size_t i = 0; i < numDisplays; i++) {
    119         if (i >= mDisplayDevices.size()) {
    120             continue;
    121         }
    122         IDisplayDevice *device = mDisplayDevices.itemAt(i);
    123         if (!device) {
    124             VLOGTRACE("device %d doesn't exist", i);
    125             continue;
    126         }
    127 
    128         if (!device->isConnected()) {
    129             VLOGTRACE("device %d is disconnected", i);
    130             continue;
    131         }
    132 
    133         ret = device->commit(displays[i], mDisplayContext);
    134         if (ret == false) {
    135             ELOGTRACE("failed to do commit for device %d", i);
    136             continue;
    137         }
    138     }
    139 
    140     mDisplayContext->commitEnd(numDisplays, displays);
    141     // return true always
    142     return true;
    143 }
    144 
    145 bool Hwcomposer::vsyncControl(int disp, int enabled)
    146 {
    147     RETURN_FALSE_IF_NOT_INIT();
    148     ALOGTRACE("disp = %d, enabled = %d", disp, enabled);
    149 
    150     if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
    151         ELOGTRACE("invalid disp %d", disp);
    152         return false;
    153     }
    154     if (disp >= (int) mDisplayDevices.size()) {
    155         return false;
    156     }
    157     IDisplayDevice *device = mDisplayDevices.itemAt(disp);
    158     if (!device) {
    159         ELOGTRACE("no device found");
    160         return false;
    161     }
    162 
    163     return device->vsyncControl(enabled ? true : false);
    164 }
    165 
    166 bool Hwcomposer::blank(int disp, int blank)
    167 {
    168     RETURN_FALSE_IF_NOT_INIT();
    169     ALOGTRACE("disp = %d, blank = %d", disp, blank);
    170 
    171     if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
    172         ELOGTRACE("invalid disp %d", disp);
    173         return false;
    174     }
    175     if (disp >= (int) mDisplayDevices.size()) {
    176         return false;
    177     }
    178     IDisplayDevice *device = mDisplayDevices.itemAt(disp);
    179     if (!device) {
    180         ELOGTRACE("no device found");
    181         return false;
    182     }
    183 
    184     return device->blank(blank ? true : false);
    185 }
    186 
    187 bool Hwcomposer::getDisplayConfigs(int disp,
    188                                       uint32_t *configs,
    189                                       size_t *numConfigs)
    190 {
    191     RETURN_FALSE_IF_NOT_INIT();
    192 
    193     if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
    194         ELOGTRACE("invalid disp %d", disp);
    195         return false;
    196     }
    197     if (disp >= (int) mDisplayDevices.size()) {
    198         return false;
    199     }
    200     IDisplayDevice *device = mDisplayDevices.itemAt(disp);
    201     if (!device) {
    202         ELOGTRACE("no device %d found", disp);
    203         return false;
    204     }
    205 
    206     return device->getDisplayConfigs(configs, numConfigs);
    207 }
    208 
    209 bool Hwcomposer::getDisplayAttributes(int disp,
    210                                          uint32_t config,
    211                                          const uint32_t *attributes,
    212                                          int32_t *values)
    213 {
    214     RETURN_FALSE_IF_NOT_INIT();
    215 
    216     if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
    217         ELOGTRACE("invalid disp %d", disp);
    218         return false;
    219     }
    220     if (disp >= (int) mDisplayDevices.size()) {
    221         return false;
    222     }
    223     IDisplayDevice *device = mDisplayDevices.itemAt(disp);
    224     if (!device) {
    225         ELOGTRACE("no device found");
    226         return false;
    227     }
    228 
    229     return device->getDisplayAttributes(config, attributes, values);
    230 }
    231 
    232 bool Hwcomposer::compositionComplete(int disp)
    233 {
    234     RETURN_FALSE_IF_NOT_INIT();
    235 
    236     if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
    237         ELOGTRACE("invalid disp %d", disp);
    238         return false;
    239     }
    240 
    241     mDisplayContext->compositionComplete();
    242     if (disp >= (int) mDisplayDevices.size()) {
    243         return false;
    244     }
    245 
    246     IDisplayDevice *device = mDisplayDevices.itemAt(disp);
    247     if (!device) {
    248         ELOGTRACE("no device found");
    249         return false;
    250     }
    251 
    252     return device->compositionComplete();
    253 }
    254 
    255 bool Hwcomposer::setPowerMode(int disp, int mode)
    256 {
    257     RETURN_FALSE_IF_NOT_INIT();
    258 
    259     if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
    260         ELOGTRACE("invalid disp %d", disp);
    261         return false;
    262     }
    263 
    264     IDisplayDevice *device = mDisplayDevices.itemAt(disp);
    265     if (!device) {
    266         ELOGTRACE("no device found");
    267         return false;
    268     }
    269 
    270     return device->setPowerMode(mode);
    271 }
    272 
    273 int Hwcomposer::getActiveConfig(int disp)
    274 {
    275     RETURN_NULL_IF_NOT_INIT();
    276 
    277     if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
    278         ELOGTRACE("invalid disp %d", disp);
    279         return -1;
    280     }
    281 
    282     IDisplayDevice *device = mDisplayDevices.itemAt(disp);
    283     if (!device) {
    284         ELOGTRACE("no device found");
    285         return -1;
    286     }
    287 
    288     return device->getActiveConfig();
    289 }
    290 
    291 bool Hwcomposer::setActiveConfig(int disp, int index)
    292 {
    293     RETURN_FALSE_IF_NOT_INIT();
    294 
    295     if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
    296         ELOGTRACE("invalid disp %d", disp);
    297         return false;
    298     }
    299 
    300     IDisplayDevice *device = mDisplayDevices.itemAt(disp);
    301     if (!device) {
    302         ELOGTRACE("no device found");
    303         return false;
    304     }
    305 
    306     return device->setActiveConfig(index);
    307 }
    308 
    309 bool Hwcomposer::setCursorPositionAsync(int disp, int x, int y)
    310 {
    311     RETURN_FALSE_IF_NOT_INIT();
    312 
    313     if (disp != HWC_DISPLAY_PRIMARY && disp != HWC_DISPLAY_EXTERNAL) {
    314         ELOGTRACE("invalid disp %d", disp);
    315         return false;
    316     }
    317 
    318     return mDisplayContext->setCursorPosition(disp, x, y);
    319 }
    320 
    321 void Hwcomposer::vsync(int disp, int64_t timestamp)
    322 {
    323     RETURN_VOID_IF_NOT_INIT();
    324 
    325     if (mProcs && mProcs->vsync) {
    326         VLOGTRACE("report vsync on disp %d, timestamp %llu", disp, timestamp);
    327         // workaround to pretend vsync is from primary display
    328         // Display will freeze if vsync is from external display.
    329         mProcs->vsync(const_cast<hwc_procs_t*>(mProcs), IDisplayDevice::DEVICE_PRIMARY, timestamp);
    330     }
    331 }
    332 
    333 void Hwcomposer::hotplug(__attribute__((unused))int disp, bool connected)
    334 {
    335     RETURN_VOID_IF_NOT_INIT();
    336 
    337     if (mProcs && mProcs->hotplug) {
    338         DLOGTRACE("report hotplug on disp %d, connected %d", disp, connected);
    339         mProcs->hotplug(const_cast<hwc_procs_t*>(mProcs), disp, connected);
    340         DLOGTRACE("hotplug callback processed and returned!");
    341     }
    342 
    343     mDisplayAnalyzer->postHotplugEvent(connected);
    344 }
    345 
    346 void Hwcomposer::invalidate()
    347 {
    348     RETURN_VOID_IF_NOT_INIT();
    349 
    350     if (mProcs && mProcs->invalidate) {
    351         DLOGTRACE("invalidating screen...");
    352         mProcs->invalidate(const_cast<hwc_procs_t*>(mProcs));
    353     }
    354 }
    355 
    356 bool Hwcomposer::release()
    357 {
    358     RETURN_FALSE_IF_NOT_INIT();
    359 
    360     return true;
    361 }
    362 
    363 bool Hwcomposer::dump(char *buff, int buff_len, int * /* cur_len */)
    364 {
    365     RETURN_FALSE_IF_NOT_INIT();
    366 
    367     Dump d(buff, buff_len);
    368 
    369     // dump composer status
    370     d.append("Hardware Composer state:");
    371     // dump device status
    372     for (size_t i= 0; i < mDisplayDevices.size(); i++) {
    373         IDisplayDevice *device = mDisplayDevices.itemAt(i);
    374         if (device)
    375             device->dump(d);
    376     }
    377 
    378     // dump plane manager status
    379     if (mPlaneManager)
    380         mPlaneManager->dump(d);
    381 
    382     // dump buffer manager status
    383     if (mBufferManager)
    384         mBufferManager->dump(d);
    385 
    386     return true;
    387 }
    388 
    389 void Hwcomposer::registerProcs(hwc_procs_t const *procs)
    390 {
    391     CTRACE();
    392 
    393     if (!procs) {
    394         WLOGTRACE("procs is NULL");
    395     }
    396     mProcs = procs;
    397 }
    398 
    399 bool Hwcomposer::initialize()
    400 {
    401     CTRACE();
    402 
    403     // create drm
    404     mDrm = new Drm();
    405     if (!mDrm || !mDrm->initialize()) {
    406         DEINIT_AND_RETURN_FALSE("failed to create DRM");
    407     }
    408 
    409     // create buffer manager
    410     mBufferManager = createBufferManager();
    411     if (!mBufferManager || !mBufferManager->initialize()) {
    412         DEINIT_AND_RETURN_FALSE("failed to create buffer manager");
    413     }
    414 
    415     // create display plane manager
    416     mPlaneManager = createDisplayPlaneManager();
    417     if (!mPlaneManager || !mPlaneManager->initialize()) {
    418         DEINIT_AND_RETURN_FALSE("failed to create display plane manager");
    419     }
    420 
    421     mDisplayContext = createDisplayContext();
    422     if (!mDisplayContext || !mDisplayContext->initialize()) {
    423         DEINIT_AND_RETURN_FALSE("failed to create display context");
    424     }
    425 
    426     mUeventObserver = new UeventObserver();
    427     if (!mUeventObserver || !mUeventObserver->initialize()) {
    428         DEINIT_AND_RETURN_FALSE("failed to initialize uevent observer");
    429     }
    430 
    431     // create display device
    432     for (int i = 0; i < IDisplayDevice::DEVICE_COUNT; i++) {
    433         IDisplayDevice *device = createDisplayDevice(i, *mPlaneManager);
    434         if (!device || !device->initialize()) {
    435             DEINIT_AND_DELETE_OBJ(device);
    436             DEINIT_AND_RETURN_FALSE("failed to create device %d", i);
    437         }
    438         // add this device
    439         mDisplayDevices.insertAt(device, i, 1);
    440     }
    441 
    442     mDisplayAnalyzer = new DisplayAnalyzer();
    443     if (!mDisplayAnalyzer || !mDisplayAnalyzer->initialize()) {
    444         DEINIT_AND_RETURN_FALSE("failed to initialize display analyzer");
    445     }
    446 
    447     // all initialized, starting uevent observer
    448     mUeventObserver->start();
    449 
    450     mInitialized = true;
    451     return true;
    452 }
    453 
    454 void Hwcomposer::deinitialize()
    455 {
    456     DEINIT_AND_DELETE_OBJ(mDisplayAnalyzer);
    457 
    458     DEINIT_AND_DELETE_OBJ(mUeventObserver);
    459     // destroy display devices
    460     for (size_t i = 0; i < mDisplayDevices.size(); i++) {
    461         IDisplayDevice *device = mDisplayDevices.itemAt(i);
    462         DEINIT_AND_DELETE_OBJ(device);
    463     }
    464     mDisplayDevices.clear();
    465 
    466     DEINIT_AND_DELETE_OBJ(mDisplayContext);
    467     DEINIT_AND_DELETE_OBJ(mPlaneManager);
    468     DEINIT_AND_DELETE_OBJ(mBufferManager);
    469     DEINIT_AND_DELETE_OBJ(mDrm);
    470     mInitialized = false;
    471 }
    472 
    473 Drm* Hwcomposer::getDrm()
    474 {
    475     return mDrm;
    476 }
    477 
    478 DisplayPlaneManager* Hwcomposer::getPlaneManager()
    479 {
    480     return mPlaneManager;
    481 }
    482 
    483 BufferManager* Hwcomposer::getBufferManager()
    484 {
    485     return mBufferManager;
    486 }
    487 
    488 IDisplayContext* Hwcomposer::getDisplayContext()
    489 {
    490     return mDisplayContext;
    491 }
    492 
    493 DisplayAnalyzer* Hwcomposer::getDisplayAnalyzer()
    494 {
    495     return mDisplayAnalyzer;
    496 }
    497 
    498 IDisplayDevice* Hwcomposer::getDisplayDevice(int disp)
    499 {
    500     if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
    501         ELOGTRACE("invalid disp %d", disp);
    502         return NULL;
    503     }
    504     if (disp >= (int) mDisplayDevices.size()) {
    505         return NULL;
    506     }
    507     return mDisplayDevices.itemAt(disp);
    508 }
    509 
    510 UeventObserver* Hwcomposer::getUeventObserver()
    511 {
    512     return mUeventObserver;
    513 }
    514 
    515 
    516 } // namespace intel
    517 } // namespace android
    518