HWComposer.cpp revision 30bcc61431d8e3bef779472dd52a7b156dcaba09
1/* 2 * Copyright (C) 2010 The Android Open Source Project 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 17#define ATRACE_TAG ATRACE_TAG_GRAPHICS 18 19// Uncomment this to remove support for HWC_DEVICE_API_VERSION_0_3 and older 20#define HWC_REMOVE_DEPRECATED_VERSIONS 1 21 22#include <stdint.h> 23#include <stdio.h> 24#include <stdlib.h> 25#include <string.h> 26#include <sys/types.h> 27 28#include <utils/Errors.h> 29#include <utils/String8.h> 30#include <utils/Thread.h> 31#include <utils/Trace.h> 32#include <utils/Vector.h> 33 34#include <ui/GraphicBuffer.h> 35 36#include <hardware/hardware.h> 37#include <hardware/hwcomposer.h> 38 39#include <cutils/log.h> 40#include <cutils/properties.h> 41 42#include "Layer.h" // needed only for debugging 43#include "LayerBase.h" 44#include "HWComposer.h" 45#include "SurfaceFlinger.h" 46 47namespace android { 48 49static bool hwcHasVersion(const hwc_composer_device_1_t* hwc, uint32_t version) { 50 return hwc->common.version >= version; 51} 52 53// --------------------------------------------------------------------------- 54 55struct HWComposer::cb_context { 56 struct callbacks : public hwc_procs_t { 57 // these are here to facilitate the transition when adding 58 // new callbacks (an implementation can check for NULL before 59 // calling a new callback). 60 void (*zero[4])(void); 61 }; 62 callbacks procs; 63 HWComposer* hwc; 64}; 65 66// --------------------------------------------------------------------------- 67 68HWComposer::HWComposer( 69 const sp<SurfaceFlinger>& flinger, 70 EventHandler& handler, 71 framebuffer_device_t const* fbDev) 72 : mFlinger(flinger), 73 mModule(0), mHwc(0), mNumDisplays(1), mCapacity(0), 74 mCBContext(new cb_context), 75 mEventHandler(handler), 76 mVSyncCount(0), mDebugForceFakeVSync(false) 77{ 78 for (size_t i =0 ; i<MAX_DISPLAYS ; i++) { 79 mLists[i] = 0; 80 } 81 82 char value[PROPERTY_VALUE_MAX]; 83 property_get("debug.sf.no_hw_vsync", value, "0"); 84 mDebugForceFakeVSync = atoi(value); 85 86 bool needVSyncThread = true; 87 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); 88 ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID); 89 if (err == 0) { 90 err = hwc_open_1(mModule, &mHwc); 91 ALOGE_IF(err, "%s device failed to initialize (%s)", 92 HWC_HARDWARE_COMPOSER, strerror(-err)); 93 if (err == 0) { 94 if (mHwc->common.version < HWC_DEVICE_API_VERSION_1_0) { 95 ALOGE("%s device version %#x too old, will not be used", 96 HWC_HARDWARE_COMPOSER, mHwc->common.version); 97 hwc_close_1(mHwc); 98 mHwc = NULL; 99 } 100 } 101 102 if (mHwc) { 103 if (mHwc->registerProcs) { 104 mCBContext->hwc = this; 105 mCBContext->procs.invalidate = &hook_invalidate; 106 mCBContext->procs.vsync = &hook_vsync; 107 memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero)); 108 mHwc->registerProcs(mHwc, &mCBContext->procs); 109 } 110 111 // these IDs are always reserved 112 mTokens.markBit(HWC_DISPLAY_PRIMARY); 113 mTokens.markBit(HWC_DISPLAY_EXTERNAL); 114 115 // always turn vsync off when we start 116 needVSyncThread = false; 117 118 mHwc->eventControl(mHwc, 0, HWC_EVENT_VSYNC, 0); 119 120 int period; 121 if (mHwc->query(mHwc, HWC_VSYNC_PERIOD, &period) == NO_ERROR) { 122 mDisplayData[0].refresh = nsecs_t(period); 123 } 124 125 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) 126 mNumDisplays = HWC_NUM_DISPLAY_TYPES; 127 128 // create initial empty display contents for display 0 129 createWorkList(HWC_DISPLAY_PRIMARY, 0); 130 } 131 } 132 133 134 if (fbDev) { 135 if (mDisplayData[HWC_DISPLAY_PRIMARY].refresh == 0) { 136 mDisplayData[HWC_DISPLAY_PRIMARY].refresh = nsecs_t(1e9 / fbDev->fps); 137 ALOGW("getting VSYNC period from fb HAL: %lld", mDisplayData[0].refresh); 138 } 139 mDisplayData[HWC_DISPLAY_PRIMARY].xdpi = fbDev->xdpi; 140 mDisplayData[HWC_DISPLAY_PRIMARY].ydpi = fbDev->ydpi; 141 } 142 143 if (mDisplayData[HWC_DISPLAY_PRIMARY].refresh == 0) { 144 mDisplayData[HWC_DISPLAY_PRIMARY].refresh = nsecs_t(1e9 / 60.0); 145 ALOGW("getting VSYNC period thin air: %lld", mDisplayData[0].refresh); 146 } 147 148 if (needVSyncThread) { 149 // we don't have VSYNC support, we need to fake it 150 mVSyncThread = new VSyncThread(*this); 151 } 152} 153 154HWComposer::~HWComposer() { 155 mHwc->eventControl(mHwc, 0, EVENT_VSYNC, 0); 156 for (size_t i = 0; i < MAX_DISPLAYS; i++) { 157 free(mLists[i]); 158 } 159 if (mVSyncThread != NULL) { 160 mVSyncThread->requestExitAndWait(); 161 } 162 if (mHwc) { 163 hwc_close_1(mHwc); 164 } 165 delete mCBContext; 166} 167 168status_t HWComposer::initCheck() const { 169 return mHwc ? NO_ERROR : NO_INIT; 170} 171 172void HWComposer::hook_invalidate(const struct hwc_procs* procs) { 173 cb_context* ctx = reinterpret_cast<cb_context*>( 174 const_cast<hwc_procs_t*>(procs)); 175 ctx->hwc->invalidate(); 176} 177 178void HWComposer::hook_vsync(const struct hwc_procs* procs, int dpy, 179 int64_t timestamp) { 180 cb_context* ctx = reinterpret_cast<cb_context*>( 181 const_cast<hwc_procs_t*>(procs)); 182 ctx->hwc->vsync(dpy, timestamp); 183} 184 185void HWComposer::invalidate() { 186 mFlinger->repaintEverything(); 187} 188 189void HWComposer::vsync(int dpy, int64_t timestamp) { 190 ATRACE_INT("VSYNC", ++mVSyncCount&1); 191 mEventHandler.onVSyncReceived(dpy, timestamp); 192 Mutex::Autolock _l(mLock); 193 mLastHwVSync = timestamp; 194} 195 196int32_t HWComposer::allocateDisplayId() { 197 if (mTokens.isFull()) { 198 return NO_MEMORY; 199 } 200 201 // FIXME: for now we don't support h/w composition wifi displays 202 return -1; 203 204 int32_t id = mTokens.firstUnmarkedBit(); 205 mTokens.markBit(id); 206 return id; 207} 208 209status_t HWComposer::freeDisplayId(int32_t id) { 210 if (id < MAX_DISPLAYS) { 211 return BAD_VALUE; 212 } 213 if (!mTokens.hasBit(id)) { 214 return BAD_INDEX; 215 } 216 mTokens.clearBit(id); 217 return NO_ERROR; 218} 219 220nsecs_t HWComposer::getRefreshPeriod() const { 221 return mDisplayData[0].refresh; 222} 223 224nsecs_t HWComposer::getRefreshTimestamp() const { 225 // this returns the last refresh timestamp. 226 // if the last one is not available, we estimate it based on 227 // the refresh period and whatever closest timestamp we have. 228 Mutex::Autolock _l(mLock); 229 nsecs_t now = systemTime(CLOCK_MONOTONIC); 230 return now - ((now - mLastHwVSync) % mDisplayData[0].refresh); 231} 232 233float HWComposer::getDpiX() const { 234 return mDisplayData[HWC_DISPLAY_PRIMARY].xdpi; 235} 236 237float HWComposer::getDpiY() const { 238 return mDisplayData[HWC_DISPLAY_PRIMARY].ydpi; 239} 240 241void HWComposer::eventControl(int event, int enabled) { 242 status_t err = NO_ERROR; 243 if (mHwc) { 244 if (!mDebugForceFakeVSync) { 245 err = mHwc->eventControl(mHwc, 0, event, enabled); 246 // error here should not happen -- not sure what we should 247 // do if it does. 248 ALOGE_IF(err, "eventControl(%d, %d) failed %s", 249 event, enabled, strerror(-err)); 250 } 251 } 252 253 if (err == NO_ERROR && mVSyncThread != NULL) { 254 mVSyncThread->setEnabled(enabled); 255 } 256} 257 258status_t HWComposer::createWorkList(int32_t id, size_t numLayers) { 259 if (!mTokens.hasBit(id)) { 260 return BAD_INDEX; 261 } 262 263 // FIXME: handle multiple displays 264 if (mHwc) { 265 // TODO: must handle multiple displays here 266 // mLists[0] is NULL only when this is called from the constructor 267 if (!mLists[0] || mCapacity < numLayers) { 268 free(mLists[0]); 269 size_t size = sizeof(hwc_display_contents_1_t) + numLayers * sizeof(hwc_layer_1_t); 270 mLists[0] = (hwc_display_contents_1_t*)malloc(size); 271 mCapacity = numLayers; 272 } 273 mLists[0]->flags = HWC_GEOMETRY_CHANGED; 274 mLists[0]->numHwLayers = numLayers; 275 mLists[0]->flipFenceFd = -1; 276 } 277 return NO_ERROR; 278} 279 280status_t HWComposer::prepare() { 281 int err = mHwc->prepare(mHwc, mNumDisplays, 282 const_cast<hwc_display_contents_1_t**>(mLists)); 283 284 if (err == NO_ERROR) { 285 286 // here we're just making sure that "skip" layers are set 287 // to HWC_FRAMEBUFFER and we're also counting how many layers 288 // we have of each type. 289 // It would be nice if we could get rid of this entirely, which I 290 // think is almost possible. 291 292 // TODO: must handle multiple displays here 293 294 size_t count = getNumLayers(0); 295 struct hwc_display_contents_1* disp = mLists[0]; 296 mDisplayData[0].hasFbComp = false; 297 mDisplayData[0].hasOvComp = false; 298 for (size_t i=0 ; i<count ; i++) { 299 hwc_layer_1_t* l = &disp->hwLayers[i]; 300 if (l->flags & HWC_SKIP_LAYER) { 301 l->compositionType = HWC_FRAMEBUFFER; 302 } 303 if (l->compositionType == HWC_FRAMEBUFFER) 304 mDisplayData[HWC_DISPLAY_PRIMARY].hasFbComp = true; 305 if (l->compositionType == HWC_OVERLAY) 306 mDisplayData[HWC_DISPLAY_PRIMARY].hasOvComp = true; 307 } 308 } 309 return (status_t)err; 310} 311 312bool HWComposer::hasHwcComposition(int32_t id) const { 313 if (!mTokens.hasBit(id)) 314 return false; 315 return mDisplayData[id].hasOvComp; 316} 317 318bool HWComposer::hasGlesComposition(int32_t id) const { 319 if (!mTokens.hasBit(id)) 320 return false; 321 return mDisplayData[id].hasFbComp; 322} 323 324status_t HWComposer::commit() { 325 int err = NO_ERROR; 326 if (mHwc) { 327 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { 328 mLists[0]->dpy = EGL_NO_DISPLAY; 329 mLists[0]->sur = EGL_NO_SURFACE; 330 } else { 331 // On version 1.0, the OpenGL ES target surface is communicated 332 // by the (dpy, sur) fields 333 mLists[0]->dpy = eglGetCurrentDisplay(); 334 mLists[0]->sur = eglGetCurrentSurface(EGL_DRAW); 335 } 336 err = mHwc->set(mHwc, mNumDisplays, mLists); 337 if (mLists[0]->flipFenceFd != -1) { 338 close(mLists[0]->flipFenceFd); 339 mLists[0]->flipFenceFd = -1; 340 } 341 mLists[0]->flags &= ~HWC_GEOMETRY_CHANGED; 342 } 343 return (status_t)err; 344} 345 346status_t HWComposer::release() const { 347 if (mHwc) { 348 mHwc->eventControl(mHwc, 0, HWC_EVENT_VSYNC, 0); 349 return (status_t)mHwc->blank(mHwc, 0, 1); 350 } 351 return NO_ERROR; 352} 353 354status_t HWComposer::acquire() const { 355 if (mHwc) { 356 return (status_t)mHwc->blank(mHwc, 0, 0); 357 } 358 return NO_ERROR; 359} 360 361status_t HWComposer::disable() { 362 if (mHwc) { 363 mLists[0]->numHwLayers = 0; 364 int err = mHwc->prepare(mHwc, mNumDisplays, mLists); 365 return (status_t)err; 366 } 367 return NO_ERROR; 368} 369 370size_t HWComposer::getNumLayers(int32_t id) const { // FIXME: handle multiple displays 371 return mHwc ? mLists[0]->numHwLayers : 0; 372} 373 374/* 375 * Helper template to implement a concrete HWCLayer 376 * This holds the pointer to the concrete hwc layer type 377 * and implements the "iterable" side of HWCLayer. 378 */ 379template<typename CONCRETE, typename HWCTYPE> 380class Iterable : public HWComposer::HWCLayer { 381protected: 382 HWCTYPE* const mLayerList; 383 HWCTYPE* mCurrentLayer; 384 Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { } 385 inline HWCTYPE const * getLayer() const { return mCurrentLayer; } 386 inline HWCTYPE* getLayer() { return mCurrentLayer; } 387 virtual ~Iterable() { } 388private: 389 // returns a copy of ourselves 390 virtual HWComposer::HWCLayer* dup() { 391 return new CONCRETE( static_cast<const CONCRETE&>(*this) ); 392 } 393 virtual status_t setLayer(size_t index) { 394 mCurrentLayer = &mLayerList[index]; 395 return NO_ERROR; 396 } 397}; 398 399/* 400 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0. 401 * This implements the HWCLayer side of HWCIterableLayer. 402 */ 403class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> { 404public: 405 HWCLayerVersion1(hwc_layer_1_t* layer) 406 : Iterable<HWCLayerVersion1, hwc_layer_1_t>(layer) { } 407 408 virtual int32_t getCompositionType() const { 409 return getLayer()->compositionType; 410 } 411 virtual uint32_t getHints() const { 412 return getLayer()->hints; 413 } 414 virtual int getAndResetReleaseFenceFd() { 415 int fd = getLayer()->releaseFenceFd; 416 getLayer()->releaseFenceFd = -1; 417 return fd; 418 } 419 virtual void setAcquireFenceFd(int fenceFd) { 420 getLayer()->acquireFenceFd = fenceFd; 421 } 422 423 virtual void setDefaultState() { 424 getLayer()->compositionType = HWC_FRAMEBUFFER; 425 getLayer()->hints = 0; 426 getLayer()->flags = HWC_SKIP_LAYER; 427 getLayer()->transform = 0; 428 getLayer()->blending = HWC_BLENDING_NONE; 429 getLayer()->visibleRegionScreen.numRects = 0; 430 getLayer()->visibleRegionScreen.rects = NULL; 431 getLayer()->acquireFenceFd = -1; 432 getLayer()->releaseFenceFd = -1; 433 } 434 virtual void setSkip(bool skip) { 435 if (skip) { 436 getLayer()->flags |= HWC_SKIP_LAYER; 437 } else { 438 getLayer()->flags &= ~HWC_SKIP_LAYER; 439 } 440 } 441 virtual void setBlending(uint32_t blending) { 442 getLayer()->blending = blending; 443 } 444 virtual void setTransform(uint32_t transform) { 445 getLayer()->transform = transform; 446 } 447 virtual void setFrame(const Rect& frame) { 448 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame; 449 } 450 virtual void setCrop(const Rect& crop) { 451 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop; 452 } 453 virtual void setVisibleRegionScreen(const Region& reg) { 454 getLayer()->visibleRegionScreen.rects = 455 reinterpret_cast<hwc_rect_t const *>( 456 reg.getArray(&getLayer()->visibleRegionScreen.numRects)); 457 } 458 virtual void setBuffer(const sp<GraphicBuffer>& buffer) { 459 if (buffer == 0 || buffer->handle == 0) { 460 getLayer()->compositionType = HWC_FRAMEBUFFER; 461 getLayer()->flags |= HWC_SKIP_LAYER; 462 getLayer()->handle = 0; 463 } else { 464 getLayer()->handle = buffer->handle; 465 } 466 } 467}; 468 469/* 470 * returns an iterator initialized at a given index in the layer list 471 */ 472HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) { 473 if (!mTokens.hasBit(id)) 474 return LayerListIterator(); 475 476 // FIXME: handle multiple displays 477 if (!mHwc || index > mLists[0]->numHwLayers) 478 return LayerListIterator(); 479 480 return LayerListIterator(new HWCLayerVersion1(mLists[0]->hwLayers), index); 481} 482 483/* 484 * returns an iterator on the beginning of the layer list 485 */ 486HWComposer::LayerListIterator HWComposer::begin(int32_t id) { 487 return getLayerIterator(id, 0); 488} 489 490/* 491 * returns an iterator on the end of the layer list 492 */ 493HWComposer::LayerListIterator HWComposer::end(int32_t id) { 494 return getLayerIterator(id, getNumLayers(id)); 495} 496 497void HWComposer::dump(String8& result, char* buffer, size_t SIZE, 498 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const { 499 if (mHwc) { 500 result.append("Hardware Composer state:\n"); 501 result.appendFormat(" mDebugForceFakeVSync=%d\n", 502 mDebugForceFakeVSync); 503 result.appendFormat(" numHwLayers=%u, flags=%08x\n", 504 mLists[0]->numHwLayers, mLists[0]->flags); 505 result.append( 506 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n" 507 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n"); 508 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____] 509 for (size_t i=0 ; i<mLists[0]->numHwLayers ; i++) { 510 hwc_layer_1_t const* lp= &mLists[0]->hwLayers[i]; 511 const sp<LayerBase> layer(visibleLayersSortedByZ[i]); 512 int32_t format = -1; 513 if (layer->getLayer() != NULL) { 514 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer()); 515 if (buffer != NULL) { 516 format = buffer->getPixelFormat(); 517 } 518 } 519 const hwc_layer_1_t& l(*lp); 520 result.appendFormat( 521 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n", 522 l.compositionType ? "OVERLAY" : "FB", 523 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format, 524 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom, 525 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom, 526 layer->getName().string()); 527 } 528 } 529 530 if (mHwc && mHwc->dump) { 531 mHwc->dump(mHwc, buffer, SIZE); 532 result.append(buffer); 533 } 534} 535 536// --------------------------------------------------------------------------- 537 538HWComposer::VSyncThread::VSyncThread(HWComposer& hwc) 539 : mHwc(hwc), mEnabled(false), 540 mNextFakeVSync(0), 541 mRefreshPeriod(hwc.getRefreshPeriod()) 542{ 543} 544 545void HWComposer::VSyncThread::setEnabled(bool enabled) { 546 Mutex::Autolock _l(mLock); 547 mEnabled = enabled; 548 mCondition.signal(); 549} 550 551void HWComposer::VSyncThread::onFirstRef() { 552 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); 553} 554 555bool HWComposer::VSyncThread::threadLoop() { 556 { // scope for lock 557 Mutex::Autolock _l(mLock); 558 while (!mEnabled) { 559 mCondition.wait(mLock); 560 } 561 } 562 563 const nsecs_t period = mRefreshPeriod; 564 const nsecs_t now = systemTime(CLOCK_MONOTONIC); 565 nsecs_t next_vsync = mNextFakeVSync; 566 nsecs_t sleep = next_vsync - now; 567 if (sleep < 0) { 568 // we missed, find where the next vsync should be 569 sleep = (period - ((now - next_vsync) % period)); 570 next_vsync = now + sleep; 571 } 572 mNextFakeVSync = next_vsync + period; 573 574 struct timespec spec; 575 spec.tv_sec = next_vsync / 1000000000; 576 spec.tv_nsec = next_vsync % 1000000000; 577 578 int err; 579 do { 580 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL); 581 } while (err<0 && errno == EINTR); 582 583 if (err == 0) { 584 mHwc.mEventHandler.onVSyncReceived(0, next_vsync); 585 } 586 587 return true; 588} 589 590// --------------------------------------------------------------------------- 591}; // namespace android 592