Hwcomposer.cpp revision c0529447ae16f023dfab2978ea2b245f368e893b
1/* 2 * Copyright © 2012 Intel Corporation 3 * All rights reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 * 24 * Authors: 25 * Jackie Li <yaodong.li@intel.com> 26 * 27 */ 28#include <HwcTrace.h> 29#include <Hwcomposer.h> 30#include <Dump.h> 31#include <UeventObserver.h> 32 33namespace android { 34namespace intel { 35 36Hwcomposer* Hwcomposer::sInstance(0); 37 38Hwcomposer::Hwcomposer() 39 : mProcs(0), 40 mDrm(0), 41 mPlaneManager(0), 42 mBufferManager(0), 43 mDisplayAnalyzer(0), 44 mDisplayContext(0), 45 mVsyncManager(0), 46 mMultiDisplayObserver(0), 47 mUeventObserver(0), 48 mPowerManager(0), 49 mInitialized(false) 50{ 51 CTRACE(); 52 53 mDisplayDevices.setCapacity(IDisplayDevice::DEVICE_COUNT); 54 mDisplayDevices.clear(); 55} 56 57Hwcomposer::~Hwcomposer() 58{ 59 CTRACE(); 60 deinitialize(); 61} 62 63bool Hwcomposer::initCheck() const 64{ 65 return mInitialized; 66} 67 68bool Hwcomposer::prepare(size_t numDisplays, 69 hwc_display_contents_1_t** displays) 70{ 71 bool ret = true; 72 73 RETURN_FALSE_IF_NOT_INIT(); 74 ATRACE("display count = %d", numDisplays); 75 76 if (!numDisplays || !displays) { 77 ETRACE("invalid parameters"); 78 return false; 79 } 80 81 mDisplayAnalyzer->analyzeContents(numDisplays, displays); 82 83 // disable reclaimed planes 84 mPlaneManager->disableReclaimedPlanes(); 85 86 // reclaim all allocated planes if possible 87 for (size_t i = 0; i < numDisplays; i++) { 88 IDisplayDevice *device = mDisplayDevices.itemAt(i); 89 if (!device) { 90 VTRACE("device %d doesn't exist", i); 91 continue; 92 } 93 94 device->prePrepare(displays[i]); 95 } 96 97 for (size_t i = 0; i < numDisplays; i++) { 98 IDisplayDevice *device = mDisplayDevices.itemAt(i); 99 if (!device) { 100 VTRACE("device %d doesn't exist", i); 101 continue; 102 } 103 104 ret = device->prepare(displays[i]); 105 if (ret == false) { 106 ETRACE("failed to do prepare for device %d", i); 107 continue; 108 } 109 } 110 111 return ret; 112} 113 114bool Hwcomposer::commit(size_t numDisplays, 115 hwc_display_contents_1_t **displays) 116{ 117 bool ret = true; 118 119 RETURN_FALSE_IF_NOT_INIT(); 120 ATRACE("display count = %d", numDisplays); 121 122 if (!numDisplays || !displays) { 123 ETRACE("invalid parameters"); 124 return false; 125 } 126 127 mDisplayContext->commitBegin(numDisplays, displays); 128 129 for (size_t i = 0; i < numDisplays; i++) { 130 IDisplayDevice *device = mDisplayDevices.itemAt(i); 131 if (!device) { 132 VTRACE("device %d doesn't exist", i); 133 continue; 134 } 135 136 if (!device->isConnected()) { 137 VTRACE("device %d is disconnected", i); 138 continue; 139 } 140 141 ret = device->commit(displays[i], mDisplayContext); 142 if (ret == false) { 143 ETRACE("failed to do commit for device %d", i); 144 continue; 145 } 146 } 147 148 mDisplayContext->commitEnd(numDisplays, displays); 149 // return true always 150 return true; 151} 152 153bool Hwcomposer::vsyncControl(int disp, int enabled) 154{ 155 RETURN_FALSE_IF_NOT_INIT(); 156 ATRACE("disp = %d, enabled = %d", disp, enabled); 157 return mVsyncManager->handleVsyncControl(disp, enabled ? true : false); 158} 159 160bool Hwcomposer::blank(int disp, int blank) 161{ 162 RETURN_FALSE_IF_NOT_INIT(); 163 ATRACE("disp = %d, blank = %d", disp, blank); 164 165 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { 166 ETRACE("invalid disp %d", disp); 167 return false; 168 } 169 170 IDisplayDevice *device = mDisplayDevices.itemAt(disp); 171 if (!device) { 172 ETRACE("no device found"); 173 return false; 174 } 175 176 return device->blank(blank ? true : false); 177} 178 179bool Hwcomposer::getDisplayConfigs(int disp, 180 uint32_t *configs, 181 size_t *numConfigs) 182{ 183 RETURN_FALSE_IF_NOT_INIT(); 184 185 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { 186 ETRACE("invalid disp %d", disp); 187 return false; 188 } 189 190 IDisplayDevice *device = mDisplayDevices.itemAt(disp); 191 if (!device) { 192 ETRACE("no device %d found", disp); 193 return false; 194 } 195 196 return device->getDisplayConfigs(configs, numConfigs); 197} 198 199bool Hwcomposer::getDisplayAttributes(int disp, 200 uint32_t config, 201 const uint32_t *attributes, 202 int32_t *values) 203{ 204 RETURN_FALSE_IF_NOT_INIT(); 205 206 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { 207 ETRACE("invalid disp %d", disp); 208 return false; 209 } 210 211 IDisplayDevice *device = mDisplayDevices.itemAt(disp); 212 if (!device) { 213 ETRACE("no device found"); 214 return false; 215 } 216 217 return device->getDisplayAttributes(config, attributes, values); 218} 219 220bool Hwcomposer::compositionComplete(int disp) 221{ 222 RETURN_FALSE_IF_NOT_INIT(); 223 224 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { 225 ETRACE("invalid disp %d", disp); 226 return false; 227 } 228 229 mDisplayContext->compositionComplete(); 230 231 IDisplayDevice *device = mDisplayDevices.itemAt(disp); 232 if (!device) { 233 ETRACE("no device found"); 234 return false; 235 } 236 237 return device->compositionComplete(); 238} 239 240void Hwcomposer::vsync(int disp, int64_t timestamp) 241{ 242 RETURN_VOID_IF_NOT_INIT(); 243 244 if (mProcs && mProcs->vsync) { 245 VTRACE("report vsync on disp %d, timestamp %llu", disp, timestamp); 246 // workaround to pretend vsync is from primary display 247 // Display will freeze if vsync is from external display. 248 mProcs->vsync(const_cast<hwc_procs_t*>(mProcs), IDisplayDevice::DEVICE_PRIMARY, timestamp); 249 } 250} 251 252void Hwcomposer::hotplug(int disp, bool connected) 253{ 254 RETURN_VOID_IF_NOT_INIT(); 255 256 // TODO: Two fake hotplug events are sent during mode setting. To avoid 257 // unnecessary audio switch, real connection status should be sent to MDS 258 mMultiDisplayObserver->notifyHotPlug(mDrm->isConnected(disp)); 259 260 if (mProcs && mProcs->hotplug) { 261 DTRACE("report hotplug on disp %d, connected %d", disp, connected); 262 mProcs->hotplug(const_cast<hwc_procs_t*>(mProcs), disp, connected); 263 DTRACE("hotplug callback processed and returned!"); 264 } 265 266 mDisplayAnalyzer->postHotplugEvent(connected); 267} 268 269void Hwcomposer::invalidate() 270{ 271 RETURN_VOID_IF_NOT_INIT(); 272 273 if (mProcs && mProcs->invalidate) { 274 DTRACE("invalidating screen..."); 275 mProcs->invalidate(const_cast<hwc_procs_t*>(mProcs)); 276 } 277} 278 279bool Hwcomposer::release() 280{ 281 RETURN_FALSE_IF_NOT_INIT(); 282 283 return true; 284} 285 286bool Hwcomposer::dump(char *buff, int buff_len, int *cur_len) 287{ 288 RETURN_FALSE_IF_NOT_INIT(); 289 290 Dump d(buff, buff_len); 291 292 // dump composer status 293 d.append("Hardware Composer state:"); 294 // dump device status 295 for (size_t i= 0; i < mDisplayDevices.size(); i++) { 296 IDisplayDevice *device = mDisplayDevices.itemAt(i); 297 if (device) 298 device->dump(d); 299 } 300 301 // dump plane manager status 302 if (mPlaneManager) 303 mPlaneManager->dump(d); 304 305 // dump buffer manager status 306 if (mBufferManager) 307 mBufferManager->dump(d); 308 309 return true; 310} 311 312void Hwcomposer::registerProcs(hwc_procs_t const *procs) 313{ 314 CTRACE(); 315 316 if (!procs) { 317 WTRACE("procs is NULL"); 318 } 319 mProcs = procs; 320} 321 322bool Hwcomposer::initialize() 323{ 324 CTRACE(); 325 326 // create drm 327 mDrm = new Drm(); 328 if (!mDrm || !mDrm->initialize()) { 329 DEINIT_AND_RETURN_FALSE("failed to create DRM"); 330 } 331 332 // create buffer manager 333 mBufferManager = createBufferManager(); 334 if (!mBufferManager || !mBufferManager->initialize()) { 335 DEINIT_AND_RETURN_FALSE("failed to create buffer manager"); 336 } 337 338 // create display plane manager 339 mPlaneManager = createDisplayPlaneManager(); 340 if (!mPlaneManager || !mPlaneManager->initialize()) { 341 DEINIT_AND_RETURN_FALSE("failed to create display plane manager"); 342 } 343 344 mDisplayContext = createDisplayContext(); 345 if (!mDisplayContext || !mDisplayContext->initialize()) { 346 DEINIT_AND_RETURN_FALSE("failed to create display context"); 347 } 348 349 mPowerManager = createPowerManager(); 350 if (!mPowerManager || !mPowerManager->initialize()) { 351 DEINIT_AND_RETURN_FALSE("failed to initialize power manager"); 352 } 353 354 mUeventObserver = new UeventObserver(); 355 if (!mUeventObserver || !mUeventObserver->initialize()) { 356 DEINIT_AND_RETURN_FALSE("failed to initialize uevent observer"); 357 } 358 359 // create display device 360 for (int i = 0; i < IDisplayDevice::DEVICE_COUNT; i++) { 361 IDisplayDevice *device = createDisplayDevice(i, *mPlaneManager); 362 if (!device || !device->initialize()) { 363 DEINIT_AND_DELETE_OBJ(device); 364 DEINIT_AND_RETURN_FALSE("failed to create device %d", i); 365 } 366 // add this device 367 mDisplayDevices.insertAt(device, i, 1); 368 } 369 370 mVsyncManager = new VsyncManager(mDisplayDevices); 371 if (!mVsyncManager || !mVsyncManager->initialize()) { 372 DEINIT_AND_RETURN_FALSE("failed to create Vsync Manager"); 373 } 374 375 mDisplayAnalyzer = new DisplayAnalyzer(); 376 if (!mDisplayAnalyzer || !mDisplayAnalyzer->initialize()) { 377 DEINIT_AND_RETURN_FALSE("failed to initialize display analyzer"); 378 } 379 380 mMultiDisplayObserver = new MultiDisplayObserver(); 381 if (!mMultiDisplayObserver || !mMultiDisplayObserver->initialize()) { 382 DEINIT_AND_RETURN_FALSE("failed to initialize display observer"); 383 } 384 385 // all initialized, starting uevent observer 386 mUeventObserver->start(); 387 388 mInitialized = true; 389 return true; 390} 391 392void Hwcomposer::deinitialize() 393{ 394 DEINIT_AND_DELETE_OBJ(mMultiDisplayObserver); 395 DEINIT_AND_DELETE_OBJ(mDisplayAnalyzer); 396 // delete mVsyncManager first as it holds reference to display devices. 397 DEINIT_AND_DELETE_OBJ(mVsyncManager); 398 399 DEINIT_AND_DELETE_OBJ(mUeventObserver); 400 // destroy display devices 401 for (size_t i = 0; i < mDisplayDevices.size(); i++) { 402 IDisplayDevice *device = mDisplayDevices.itemAt(i); 403 DEINIT_AND_DELETE_OBJ(device); 404 } 405 mDisplayDevices.clear(); 406 407 DEINIT_AND_DELETE_OBJ(mPowerManager); 408 DEINIT_AND_DELETE_OBJ(mDisplayContext); 409 DEINIT_AND_DELETE_OBJ(mPlaneManager); 410 DEINIT_AND_DELETE_OBJ(mBufferManager); 411 DEINIT_AND_DELETE_OBJ(mDrm); 412 mInitialized = false; 413} 414 415Drm* Hwcomposer::getDrm() 416{ 417 return mDrm; 418} 419 420DisplayPlaneManager* Hwcomposer::getPlaneManager() 421{ 422 return mPlaneManager; 423} 424 425BufferManager* Hwcomposer::getBufferManager() 426{ 427 return mBufferManager; 428} 429 430IDisplayContext* Hwcomposer::getDisplayContext() 431{ 432 return mDisplayContext; 433} 434 435DisplayAnalyzer* Hwcomposer::getDisplayAnalyzer() 436{ 437 return mDisplayAnalyzer; 438} 439 440MultiDisplayObserver* Hwcomposer::getMultiDisplayObserver() 441{ 442 return mMultiDisplayObserver; 443} 444 445IDisplayDevice* Hwcomposer::getDisplayDevice(int disp) 446{ 447 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { 448 ETRACE("invalid disp %d", disp); 449 return NULL; 450 } 451 return mDisplayDevices.itemAt(disp); 452} 453 454VsyncManager* Hwcomposer::getVsyncManager() 455{ 456 return mVsyncManager; 457} 458 459UeventObserver* Hwcomposer::getUeventObserver() 460{ 461 return mUeventObserver; 462} 463 464IPowerManager* Hwcomposer::getPowerManager() 465{ 466 return mPowerManager; 467} 468 469} // namespace intel 470} // namespace android 471