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