1/* 2// Copyright (c) 2014 Intel Corporation 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15*/ 16#include <common/utils/HwcTrace.h> 17#include <Hwcomposer.h> 18#include <common/utils/Dump.h> 19#include <UeventObserver.h> 20 21namespace android { 22namespace intel { 23 24Hwcomposer* Hwcomposer::sInstance(0); 25 26Hwcomposer::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 42Hwcomposer::~Hwcomposer() 43{ 44 CTRACE(); 45 deinitialize(); 46} 47 48bool Hwcomposer::initCheck() const 49{ 50 return mInitialized; 51} 52 53bool 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 103bool 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 145bool 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 166bool 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 187bool 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 209bool 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 232bool 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 255bool 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 273int 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 291bool 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 309bool 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 321void 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 333void 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 346void 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 356bool Hwcomposer::release() 357{ 358 RETURN_FALSE_IF_NOT_INIT(); 359 360 return true; 361} 362 363bool 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 389void 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 399bool 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 454void 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 473Drm* Hwcomposer::getDrm() 474{ 475 return mDrm; 476} 477 478DisplayPlaneManager* Hwcomposer::getPlaneManager() 479{ 480 return mPlaneManager; 481} 482 483BufferManager* Hwcomposer::getBufferManager() 484{ 485 return mBufferManager; 486} 487 488IDisplayContext* Hwcomposer::getDisplayContext() 489{ 490 return mDisplayContext; 491} 492 493DisplayAnalyzer* Hwcomposer::getDisplayAnalyzer() 494{ 495 return mDisplayAnalyzer; 496} 497 498IDisplayDevice* 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 510UeventObserver* Hwcomposer::getUeventObserver() 511{ 512 return mUeventObserver; 513} 514 515 516} // namespace intel 517} // namespace android 518