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 #ifndef INTEL_SUPPORT_HDMI_PRIMARY
    338     if (mProcs && mProcs->hotplug) {
    339         DLOGTRACE("report hotplug on disp %d, connected %d", disp, connected);
    340         mProcs->hotplug(const_cast<hwc_procs_t*>(mProcs), disp, connected);
    341         DLOGTRACE("hotplug callback processed and returned!");
    342     }
    343 #endif
    344 
    345     mDisplayAnalyzer->postHotplugEvent(connected);
    346 }
    347 
    348 void Hwcomposer::invalidate()
    349 {
    350     RETURN_VOID_IF_NOT_INIT();
    351 
    352     if (mProcs && mProcs->invalidate) {
    353         DLOGTRACE("invalidating screen...");
    354         mProcs->invalidate(const_cast<hwc_procs_t*>(mProcs));
    355     }
    356 }
    357 
    358 bool Hwcomposer::release()
    359 {
    360     RETURN_FALSE_IF_NOT_INIT();
    361 
    362     return true;
    363 }
    364 
    365 bool Hwcomposer::dump(char *buff, int buff_len, int * /* cur_len */)
    366 {
    367     RETURN_FALSE_IF_NOT_INIT();
    368 
    369     Dump d(buff, buff_len);
    370 
    371     // dump composer status
    372     d.append("Hardware Composer state:");
    373     // dump device status
    374     for (size_t i= 0; i < mDisplayDevices.size(); i++) {
    375         IDisplayDevice *device = mDisplayDevices.itemAt(i);
    376         if (device)
    377             device->dump(d);
    378     }
    379 
    380     // dump plane manager status
    381     if (mPlaneManager)
    382         mPlaneManager->dump(d);
    383 
    384     // dump buffer manager status
    385     if (mBufferManager)
    386         mBufferManager->dump(d);
    387 
    388     return true;
    389 }
    390 
    391 void Hwcomposer::registerProcs(hwc_procs_t const *procs)
    392 {
    393     CTRACE();
    394 
    395     if (!procs) {
    396         WLOGTRACE("procs is NULL");
    397     }
    398     mProcs = procs;
    399 }
    400 
    401 bool Hwcomposer::initialize()
    402 {
    403     CTRACE();
    404 
    405     // create drm
    406     mDrm = new Drm();
    407     if (!mDrm || !mDrm->initialize()) {
    408         DEINIT_AND_RETURN_FALSE("failed to create DRM");
    409     }
    410 
    411     // create buffer manager
    412     mBufferManager = createBufferManager();
    413     if (!mBufferManager || !mBufferManager->initialize()) {
    414         DEINIT_AND_RETURN_FALSE("failed to create buffer manager");
    415     }
    416 
    417     // create display plane manager
    418     mPlaneManager = createDisplayPlaneManager();
    419     if (!mPlaneManager || !mPlaneManager->initialize()) {
    420         DEINIT_AND_RETURN_FALSE("failed to create display plane manager");
    421     }
    422 
    423     mDisplayContext = createDisplayContext();
    424     if (!mDisplayContext || !mDisplayContext->initialize()) {
    425         DEINIT_AND_RETURN_FALSE("failed to create display context");
    426     }
    427 
    428     mUeventObserver = new UeventObserver();
    429     if (!mUeventObserver || !mUeventObserver->initialize()) {
    430         DEINIT_AND_RETURN_FALSE("failed to initialize uevent observer");
    431     }
    432 
    433     // create display device
    434     for (int i = 0; i < IDisplayDevice::DEVICE_COUNT; i++) {
    435         IDisplayDevice *device = createDisplayDevice(i, *mPlaneManager);
    436         if (!device || !device->initialize()) {
    437             DEINIT_AND_DELETE_OBJ(device);
    438             DEINIT_AND_RETURN_FALSE("failed to create device %d", i);
    439         }
    440         // add this device
    441         mDisplayDevices.insertAt(device, i, 1);
    442     }
    443 
    444     mDisplayAnalyzer = new DisplayAnalyzer();
    445     if (!mDisplayAnalyzer || !mDisplayAnalyzer->initialize()) {
    446         DEINIT_AND_RETURN_FALSE("failed to initialize display analyzer");
    447     }
    448 
    449     // all initialized, starting uevent observer
    450     mUeventObserver->start();
    451 
    452     mInitialized = true;
    453     return true;
    454 }
    455 
    456 void Hwcomposer::deinitialize()
    457 {
    458     DEINIT_AND_DELETE_OBJ(mDisplayAnalyzer);
    459 
    460     DEINIT_AND_DELETE_OBJ(mUeventObserver);
    461     // destroy display devices
    462     for (size_t i = 0; i < mDisplayDevices.size(); i++) {
    463         IDisplayDevice *device = mDisplayDevices.itemAt(i);
    464         DEINIT_AND_DELETE_OBJ(device);
    465     }
    466     mDisplayDevices.clear();
    467 
    468     DEINIT_AND_DELETE_OBJ(mDisplayContext);
    469     DEINIT_AND_DELETE_OBJ(mPlaneManager);
    470     DEINIT_AND_DELETE_OBJ(mBufferManager);
    471     DEINIT_AND_DELETE_OBJ(mDrm);
    472     mInitialized = false;
    473 }
    474 
    475 Drm* Hwcomposer::getDrm()
    476 {
    477     return mDrm;
    478 }
    479 
    480 DisplayPlaneManager* Hwcomposer::getPlaneManager()
    481 {
    482     return mPlaneManager;
    483 }
    484 
    485 BufferManager* Hwcomposer::getBufferManager()
    486 {
    487     return mBufferManager;
    488 }
    489 
    490 IDisplayContext* Hwcomposer::getDisplayContext()
    491 {
    492     return mDisplayContext;
    493 }
    494 
    495 DisplayAnalyzer* Hwcomposer::getDisplayAnalyzer()
    496 {
    497     return mDisplayAnalyzer;
    498 }
    499 
    500 IDisplayDevice* Hwcomposer::getDisplayDevice(int disp)
    501 {
    502     if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
    503         ELOGTRACE("invalid disp %d", disp);
    504         return NULL;
    505     }
    506     if (disp >= (int) mDisplayDevices.size()) {
    507         return NULL;
    508     }
    509     return mDisplayDevices.itemAt(disp);
    510 }
    511 
    512 UeventObserver* Hwcomposer::getUeventObserver()
    513 {
    514     return mUeventObserver;
    515 }
    516 
    517 
    518 } // namespace intel
    519 } // namespace android
    520