HWComposer.cpp revision b685c542836b93c99cd85053e07696406ea37adb
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 49// --------------------------------------------------------------------------- 50// Support for HWC_DEVICE_API_VERSION_0_3 and older: 51// Since v0.3 is deprecated and support will be dropped soon, as much as 52// possible the code is written to target v1.0. When using a v0.3 HWC, we 53// allocate v0.3 structures, but assign them to v1.0 pointers. 54 55#if HWC_REMOVE_DEPRECATED_VERSIONS 56// We need complete types to satisfy semantic checks, even though the code 57// paths that use these won't get executed at runtime (and will likely be dead- 58// code-eliminated). When we remove the code to support v0.3 we can remove 59// these as well. 60typedef hwc_layer_1_t hwc_layer_t; 61typedef hwc_display_contents_1_t hwc_layer_list_t; 62typedef hwc_composer_device_1_t hwc_composer_device_t; 63#endif 64 65// This function assumes we've already rejected HWC's with lower-than-required 66// versions. Don't use it for the initial "does HWC meet requirements" check! 67static bool hwcHasVersion(const hwc_composer_device_1_t* hwc, uint32_t version) { 68 if (HWC_REMOVE_DEPRECATED_VERSIONS && 69 version <= HWC_DEVICE_API_VERSION_1_0) { 70 return true; 71 } else { 72 return hwc->common.version >= version; 73 } 74} 75 76static bool hwcHasVsyncEvent(const hwc_composer_device_1_t* hwc) { 77 return hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_0_3); 78} 79 80static size_t sizeofHwcLayerList(const hwc_composer_device_1_t* hwc, 81 size_t numLayers) { 82 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { 83 return sizeof(hwc_display_contents_1_t) + numLayers*sizeof(hwc_layer_1_t); 84 } else { 85 return sizeof(hwc_layer_list_t) + numLayers*sizeof(hwc_layer_t); 86 } 87} 88 89static int hwcEventControl(hwc_composer_device_1_t* hwc, int dpy, 90 int event, int enabled) { 91 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { 92 return hwc->methods->eventControl(hwc, dpy, event, enabled); 93 } else { 94 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; 95 return hwc0->methods->eventControl(hwc0, event, enabled); 96 } 97} 98 99static int hwcBlank(hwc_composer_device_1_t* hwc, int dpy, int blank) { 100 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { 101 return hwc->methods->blank(hwc, dpy, blank); 102 } else { 103 if (blank) { 104 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; 105 return hwc0->set(hwc0, NULL, NULL, NULL); 106 } else { 107 // HWC 0.x turns the screen on at the next set() 108 return NO_ERROR; 109 } 110 } 111} 112 113static int hwcPrepare(hwc_composer_device_1_t* hwc, 114 size_t numDisplays, hwc_display_contents_1_t** displays) { 115 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { 116 return hwc->prepare(hwc, numDisplays, displays); 117 } else { 118 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; 119 hwc_layer_list_t* list0 = (hwc_layer_list_t*)displays[0]; 120 // In the past, SurfaceFlinger would pass a NULL list when doing full 121 // OpenGL ES composition. I don't know what, if any, dependencies there 122 // are on this behavior, so I'm playing it safe and preserving it. 123 if (list0->numHwLayers == 0) 124 return hwc0->prepare(hwc0, NULL); 125 else 126 return hwc0->prepare(hwc0, list0); 127 } 128} 129 130static int hwcSet(hwc_composer_device_1_t* hwc, EGLDisplay dpy, EGLSurface sur, 131 size_t numDisplays, hwc_display_contents_1_t** displays) { 132 int err; 133 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { 134 displays[0]->dpy = dpy; 135 displays[0]->sur = sur; 136 err = hwc->set(hwc, numDisplays, displays); 137 } else { 138 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; 139 hwc_layer_list_t* list0 = (hwc_layer_list_t*)displays[0]; 140 err = hwc0->set(hwc0, dpy, sur, list0); 141 } 142 return err; 143} 144 145static uint32_t& hwcFlags(hwc_composer_device_1_t* hwc, 146 hwc_display_contents_1_t* display) { 147 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { 148 return display->flags; 149 } else { 150 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; 151 hwc_layer_list_t* list0 = (hwc_layer_list_t*)display; 152 return list0->flags; 153 } 154} 155 156static size_t& hwcNumHwLayers(hwc_composer_device_1_t* hwc, 157 hwc_display_contents_1_t* display) { 158 if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) { 159 return display->numHwLayers; 160 } else { 161 hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc; 162 hwc_layer_list_t* list0 = (hwc_layer_list_t*)display; 163 return list0->numHwLayers; 164 } 165} 166 167// --------------------------------------------------------------------------- 168 169struct HWComposer::cb_context { 170 struct callbacks : public hwc_procs_t { 171 // these are here to facilitate the transition when adding 172 // new callbacks (an implementation can check for NULL before 173 // calling a new callback). 174 void (*zero[4])(void); 175 }; 176 callbacks procs; 177 HWComposer* hwc; 178}; 179 180// --------------------------------------------------------------------------- 181 182HWComposer::HWComposer( 183 const sp<SurfaceFlinger>& flinger, 184 EventHandler& handler) 185 : mFlinger(flinger), 186 mModule(0), mHwc(0), mCapacity(0), 187 mNumOVLayers(0), mNumFBLayers(0), 188 mCBContext(new cb_context), 189 mEventHandler(handler), mRefreshPeriod(0), 190 mVSyncCount(0), mDebugForceFakeVSync(false) 191{ 192 for (size_t i = 0; i < MAX_DISPLAYS; i++) 193 mLists[i] = NULL; 194 195 char value[PROPERTY_VALUE_MAX]; 196 property_get("debug.sf.no_hw_vsync", value, "0"); 197 mDebugForceFakeVSync = atoi(value); 198 199 bool needVSyncThread = true; 200 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); 201 ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID); 202 if (err == 0) { 203 err = hwc_open_1(mModule, &mHwc); 204 ALOGE_IF(err, "%s device failed to initialize (%s)", 205 HWC_HARDWARE_COMPOSER, strerror(-err)); 206 if (err == 0) { 207 if (HWC_REMOVE_DEPRECATED_VERSIONS && 208 mHwc->common.version < HWC_DEVICE_API_VERSION_1_0) { 209 ALOGE("%s device version %#x too old, will not be used", 210 HWC_HARDWARE_COMPOSER, mHwc->common.version); 211 hwc_close_1(mHwc); 212 mHwc = NULL; 213 } 214 } 215 216 if (mHwc) { 217 // always turn vsync off when we start 218 needVSyncThread = false; 219 if (hwcHasVsyncEvent(mHwc)) { 220 hwcEventControl(mHwc, 0, HWC_EVENT_VSYNC, 0); 221 222 int period; 223 if (mHwc->query(mHwc, HWC_VSYNC_PERIOD, &period) == NO_ERROR) { 224 mRefreshPeriod = nsecs_t(period); 225 } 226 } else { 227 needVSyncThread = true; 228 } 229 230 if (mHwc->registerProcs) { 231 mCBContext->hwc = this; 232 mCBContext->procs.invalidate = &hook_invalidate; 233 mCBContext->procs.vsync = &hook_vsync; 234 mHwc->registerProcs(mHwc, &mCBContext->procs); 235 memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero)); 236 } 237 238 // create initial empty display contents for display 0 239 createWorkList(0); 240 } 241 } 242 243 if (mRefreshPeriod == 0) { 244 // for compatibility, we attempt to get the refresh rate from 245 // the FB HAL if we couldn't get it from the HWC HAL. 246 hw_module_t const* module; 247 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { 248 framebuffer_device_t* fbDev; 249 int err = framebuffer_open(module, &fbDev); 250 if (!err && fbDev) { 251 mRefreshPeriod = nsecs_t(1e9 / fbDev->fps); 252 framebuffer_close(fbDev); 253 } 254 } 255 ALOGW("getting VSYNC period from fb HAL: %lld", mRefreshPeriod); 256 } 257 258 if (mRefreshPeriod == 0) { 259 mRefreshPeriod = nsecs_t(1e9 / 60.0); 260 ALOGW("getting VSYNC period thin air: %lld", mRefreshPeriod); 261 } 262 263 if (needVSyncThread) { 264 // we don't have VSYNC support, we need to fake it 265 mVSyncThread = new VSyncThread(*this); 266 } 267} 268 269HWComposer::~HWComposer() { 270 hwcEventControl(mHwc, 0, EVENT_VSYNC, 0); 271 for (size_t i = 0; i < MAX_DISPLAYS; i++) 272 free(mLists[i]); 273 if (mVSyncThread != NULL) { 274 mVSyncThread->requestExitAndWait(); 275 } 276 if (mHwc) { 277 hwc_close_1(mHwc); 278 } 279 delete mCBContext; 280} 281 282status_t HWComposer::initCheck() const { 283 return mHwc ? NO_ERROR : NO_INIT; 284} 285 286void HWComposer::hook_invalidate(struct hwc_procs* procs) { 287 reinterpret_cast<cb_context *>(procs)->hwc->invalidate(); 288} 289 290void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp) { 291 reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy, timestamp); 292} 293 294void HWComposer::invalidate() { 295 mFlinger->repaintEverything(); 296} 297 298void HWComposer::vsync(int dpy, int64_t timestamp) { 299 ATRACE_INT("VSYNC", ++mVSyncCount&1); 300 mEventHandler.onVSyncReceived(dpy, timestamp); 301 Mutex::Autolock _l(mLock); 302 mLastHwVSync = timestamp; 303} 304 305nsecs_t HWComposer::getRefreshPeriod() const { 306 return mRefreshPeriod; 307} 308 309nsecs_t HWComposer::getRefreshTimestamp() const { 310 // this returns the last refresh timestamp. 311 // if the last one is not available, we estimate it based on 312 // the refresh period and whatever closest timestamp we have. 313 Mutex::Autolock _l(mLock); 314 nsecs_t now = systemTime(CLOCK_MONOTONIC); 315 return now - ((now - mLastHwVSync) % mRefreshPeriod); 316} 317 318void HWComposer::eventControl(int event, int enabled) { 319 status_t err = NO_ERROR; 320 if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { 321 if (!mDebugForceFakeVSync) { 322 err = hwcEventControl(mHwc, 0, event, enabled); 323 // error here should not happen -- not sure what we should 324 // do if it does. 325 ALOGE_IF(err, "eventControl(%d, %d) failed %s", 326 event, enabled, strerror(-err)); 327 } 328 } 329 330 if (err == NO_ERROR && mVSyncThread != NULL) { 331 mVSyncThread->setEnabled(enabled); 332 } 333} 334 335status_t HWComposer::createWorkList(size_t numLayers) { 336 if (mHwc) { 337 // mLists[0] is NULL only when this is called from the constructor 338 if (!mLists[0] || mCapacity < numLayers) { 339 free(mLists[0]); 340 size_t size = sizeofHwcLayerList(mHwc, numLayers); 341 mLists[0] = (hwc_display_contents_1_t*)malloc(size); 342 mCapacity = numLayers; 343 } 344 hwcFlags(mHwc, mLists[0]) = HWC_GEOMETRY_CHANGED; 345 hwcNumHwLayers(mHwc, mLists[0]) = numLayers; 346 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { 347 mLists[0]->flipFenceFd = -1; 348 } 349 } 350 return NO_ERROR; 351} 352 353status_t HWComposer::prepare() const { 354 int err = hwcPrepare(mHwc, 1, 355 const_cast<hwc_display_contents_1_t**>(mLists)); 356 if (err == NO_ERROR) { 357 size_t numOVLayers = 0; 358 size_t numFBLayers = 0; 359 size_t count = getNumLayers(); 360 for (size_t i=0 ; i<count ; i++) { 361 hwc_layer_1_t* l = NULL; 362 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { 363 l = &mLists[0]->hwLayers[i]; 364 } else { 365 // mList really has hwc_layer_list_t memory layout 366 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0]; 367 hwc_layer_t* layer = &list0->hwLayers[i]; 368 l = (hwc_layer_1_t*)layer; 369 } 370 if (l->flags & HWC_SKIP_LAYER) { 371 l->compositionType = HWC_FRAMEBUFFER; 372 } 373 switch (l->compositionType) { 374 case HWC_OVERLAY: 375 numOVLayers++; 376 break; 377 case HWC_FRAMEBUFFER: 378 numFBLayers++; 379 break; 380 } 381 } 382 mNumOVLayers = numOVLayers; 383 mNumFBLayers = numFBLayers; 384 } 385 return (status_t)err; 386} 387 388size_t HWComposer::getLayerCount(int type) const { 389 switch (type) { 390 case HWC_OVERLAY: 391 return mNumOVLayers; 392 case HWC_FRAMEBUFFER: 393 return mNumFBLayers; 394 } 395 return 0; 396} 397 398status_t HWComposer::commit(void* fbDisplay, void* fbSurface) const { 399 int err = NO_ERROR; 400 if (mHwc) { 401 err = hwcSet(mHwc, fbDisplay, fbSurface, 1, 402 const_cast<hwc_display_contents_1_t**>(mLists)); 403 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { 404 if (mLists[0]->flipFenceFd != -1) { 405 close(mLists[0]->flipFenceFd); 406 mLists[0]->flipFenceFd = -1; 407 } 408 } 409 hwcFlags(mHwc, mLists[0]) &= ~HWC_GEOMETRY_CHANGED; 410 } 411 return (status_t)err; 412} 413 414status_t HWComposer::release() const { 415 if (mHwc) { 416 if (hwcHasVsyncEvent(mHwc)) { 417 hwcEventControl(mHwc, 0, HWC_EVENT_VSYNC, 0); 418 } 419 return (status_t)hwcBlank(mHwc, 0, 1); 420 } 421 return NO_ERROR; 422} 423 424status_t HWComposer::acquire() const { 425 if (mHwc) { 426 return (status_t)hwcBlank(mHwc, 0, 0); 427 } 428 return NO_ERROR; 429} 430 431status_t HWComposer::disable() { 432 if (mHwc) { 433 hwcNumHwLayers(mHwc, mLists[0]) = 0; 434 int err = hwcPrepare(mHwc, 1, mLists); 435 return (status_t)err; 436 } 437 return NO_ERROR; 438} 439 440size_t HWComposer::getNumLayers() const { 441 return mHwc ? hwcNumHwLayers(mHwc, mLists[0]) : 0; 442} 443 444/* 445 * Helper template to implement a concrete HWCLayer 446 * This holds the pointer to the concrete hwc layer type 447 * and implements the "iterable" side of HWCLayer. 448 */ 449template<typename CONCRETE, typename HWCTYPE> 450class Iterable : public HWComposer::HWCLayer { 451protected: 452 HWCTYPE* const mLayerList; 453 HWCTYPE* mCurrentLayer; 454 Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { } 455 inline HWCTYPE const * getLayer() const { return mCurrentLayer; } 456 inline HWCTYPE* getLayer() { return mCurrentLayer; } 457 virtual ~Iterable() { } 458private: 459 // returns a copy of ourselves 460 virtual HWComposer::HWCLayer* dup() { 461 return new CONCRETE( static_cast<const CONCRETE&>(*this) ); 462 } 463 virtual status_t setLayer(size_t index) { 464 mCurrentLayer = &mLayerList[index]; 465 return NO_ERROR; 466 } 467}; 468 469// #if !HWC_REMOVE_DEPRECATED_VERSIONS 470/* 471 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3 472 * This implements the HWCLayer side of HWCIterableLayer. 473 */ 474class HWCLayerVersion0 : public Iterable<HWCLayerVersion0, hwc_layer_t> { 475public: 476 HWCLayerVersion0(hwc_layer_t* layer) 477 : Iterable<HWCLayerVersion0, hwc_layer_t>(layer) { } 478 479 virtual int32_t getCompositionType() const { 480 return getLayer()->compositionType; 481 } 482 virtual uint32_t getHints() const { 483 return getLayer()->hints; 484 } 485 virtual int getAndResetReleaseFenceFd() { 486 // not supported on VERSION_03 487 return -1; 488 } 489 virtual void setAcquireFenceFd(int fenceFd) { 490 if (fenceFd != -1) { 491 ALOGE("HWC 0.x can't handle acquire fences"); 492 close(fenceFd); 493 } 494 } 495 496 virtual void setDefaultState() { 497 getLayer()->compositionType = HWC_FRAMEBUFFER; 498 getLayer()->hints = 0; 499 getLayer()->flags = HWC_SKIP_LAYER; 500 getLayer()->transform = 0; 501 getLayer()->blending = HWC_BLENDING_NONE; 502 getLayer()->visibleRegionScreen.numRects = 0; 503 getLayer()->visibleRegionScreen.rects = NULL; 504 } 505 virtual void setSkip(bool skip) { 506 if (skip) { 507 getLayer()->flags |= HWC_SKIP_LAYER; 508 } else { 509 getLayer()->flags &= ~HWC_SKIP_LAYER; 510 } 511 } 512 virtual void setBlending(uint32_t blending) { 513 getLayer()->blending = blending; 514 } 515 virtual void setTransform(uint32_t transform) { 516 getLayer()->transform = transform; 517 } 518 virtual void setFrame(const Rect& frame) { 519 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame; 520 } 521 virtual void setCrop(const Rect& crop) { 522 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop; 523 } 524 virtual void setVisibleRegionScreen(const Region& reg) { 525 getLayer()->visibleRegionScreen.rects = 526 reinterpret_cast<hwc_rect_t const *>( 527 reg.getArray(&getLayer()->visibleRegionScreen.numRects)); 528 } 529 virtual void setBuffer(const sp<GraphicBuffer>& buffer) { 530 if (buffer == 0 || buffer->handle == 0) { 531 getLayer()->compositionType = HWC_FRAMEBUFFER; 532 getLayer()->flags |= HWC_SKIP_LAYER; 533 getLayer()->handle = 0; 534 } else { 535 getLayer()->handle = buffer->handle; 536 } 537 } 538}; 539// #endif // !HWC_REMOVE_DEPRECATED_VERSIONS 540 541/* 542 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0. 543 * This implements the HWCLayer side of HWCIterableLayer. 544 */ 545class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> { 546public: 547 HWCLayerVersion1(hwc_layer_1_t* layer) 548 : Iterable<HWCLayerVersion1, hwc_layer_1_t>(layer) { } 549 550 virtual int32_t getCompositionType() const { 551 return getLayer()->compositionType; 552 } 553 virtual uint32_t getHints() const { 554 return getLayer()->hints; 555 } 556 virtual int getAndResetReleaseFenceFd() { 557 int fd = getLayer()->releaseFenceFd; 558 getLayer()->releaseFenceFd = -1; 559 return fd; 560 } 561 virtual void setAcquireFenceFd(int fenceFd) { 562 getLayer()->acquireFenceFd = fenceFd; 563 } 564 565 virtual void setDefaultState() { 566 getLayer()->compositionType = HWC_FRAMEBUFFER; 567 getLayer()->hints = 0; 568 getLayer()->flags = HWC_SKIP_LAYER; 569 getLayer()->transform = 0; 570 getLayer()->blending = HWC_BLENDING_NONE; 571 getLayer()->visibleRegionScreen.numRects = 0; 572 getLayer()->visibleRegionScreen.rects = NULL; 573 getLayer()->acquireFenceFd = -1; 574 getLayer()->releaseFenceFd = -1; 575 } 576 virtual void setSkip(bool skip) { 577 if (skip) { 578 getLayer()->flags |= HWC_SKIP_LAYER; 579 } else { 580 getLayer()->flags &= ~HWC_SKIP_LAYER; 581 } 582 } 583 virtual void setBlending(uint32_t blending) { 584 getLayer()->blending = blending; 585 } 586 virtual void setTransform(uint32_t transform) { 587 getLayer()->transform = transform; 588 } 589 virtual void setFrame(const Rect& frame) { 590 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame; 591 } 592 virtual void setCrop(const Rect& crop) { 593 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop; 594 } 595 virtual void setVisibleRegionScreen(const Region& reg) { 596 getLayer()->visibleRegionScreen.rects = 597 reinterpret_cast<hwc_rect_t const *>( 598 reg.getArray(&getLayer()->visibleRegionScreen.numRects)); 599 } 600 virtual void setBuffer(const sp<GraphicBuffer>& buffer) { 601 if (buffer == 0 || buffer->handle == 0) { 602 getLayer()->compositionType = HWC_FRAMEBUFFER; 603 getLayer()->flags |= HWC_SKIP_LAYER; 604 getLayer()->handle = 0; 605 } else { 606 getLayer()->handle = buffer->handle; 607 } 608 } 609}; 610 611/* 612 * returns an iterator initialized at a given index in the layer list 613 */ 614HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) { 615 if (index > hwcNumHwLayers(mHwc, mLists[0])) 616 return LayerListIterator(); 617 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { 618 return LayerListIterator(new HWCLayerVersion1(mLists[0]->hwLayers), 619 index); 620 } else { 621 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0]; 622 return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index); 623 } 624} 625 626/* 627 * returns an iterator on the beginning of the layer list 628 */ 629HWComposer::LayerListIterator HWComposer::begin() { 630 return getLayerIterator(0); 631} 632 633/* 634 * returns an iterator on the end of the layer list 635 */ 636HWComposer::LayerListIterator HWComposer::end() { 637 return getLayerIterator(getNumLayers()); 638} 639 640void HWComposer::dump(String8& result, char* buffer, size_t SIZE, 641 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const { 642 if (mHwc) { 643 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0]; 644 645 result.append("Hardware Composer state:\n"); 646 result.appendFormat(" mDebugForceFakeVSync=%d\n", 647 mDebugForceFakeVSync); 648 result.appendFormat(" numHwLayers=%u, flags=%08x\n", 649 hwcNumHwLayers(mHwc, mLists[0]), hwcFlags(mHwc, mLists[0])); 650 result.append( 651 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n" 652 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n"); 653 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____] 654 for (size_t i=0 ; i<hwcNumHwLayers(mHwc, mLists[0]) ; i++) { 655 hwc_layer_1_t l; 656 if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { 657 l = mLists[0]->hwLayers[i]; 658 } else { 659 hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0]; 660 *(hwc_layer_t*)&l = list0->hwLayers[i]; 661 l.acquireFenceFd = l.releaseFenceFd = -1; 662 } 663 const sp<LayerBase> layer(visibleLayersSortedByZ[i]); 664 int32_t format = -1; 665 if (layer->getLayer() != NULL) { 666 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer()); 667 if (buffer != NULL) { 668 format = buffer->getPixelFormat(); 669 } 670 } 671 result.appendFormat( 672 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n", 673 l.compositionType ? "OVERLAY" : "FB", 674 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format, 675 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom, 676 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom, 677 layer->getName().string()); 678 } 679 } 680 if (mHwc && hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_1) && mHwc->dump) { 681 mHwc->dump(mHwc, buffer, SIZE); 682 result.append(buffer); 683 } 684} 685 686// --------------------------------------------------------------------------- 687 688HWComposer::VSyncThread::VSyncThread(HWComposer& hwc) 689 : mHwc(hwc), mEnabled(false), 690 mNextFakeVSync(0), 691 mRefreshPeriod(hwc.mRefreshPeriod) 692{ 693} 694 695void HWComposer::VSyncThread::setEnabled(bool enabled) { 696 Mutex::Autolock _l(mLock); 697 mEnabled = enabled; 698 mCondition.signal(); 699} 700 701void HWComposer::VSyncThread::onFirstRef() { 702 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); 703} 704 705bool HWComposer::VSyncThread::threadLoop() { 706 { // scope for lock 707 Mutex::Autolock _l(mLock); 708 while (!mEnabled) { 709 mCondition.wait(mLock); 710 } 711 } 712 713 const nsecs_t period = mRefreshPeriod; 714 const nsecs_t now = systemTime(CLOCK_MONOTONIC); 715 nsecs_t next_vsync = mNextFakeVSync; 716 nsecs_t sleep = next_vsync - now; 717 if (sleep < 0) { 718 // we missed, find where the next vsync should be 719 sleep = (period - ((now - next_vsync) % period)); 720 next_vsync = now + sleep; 721 } 722 mNextFakeVSync = next_vsync + period; 723 724 struct timespec spec; 725 spec.tv_sec = next_vsync / 1000000000; 726 spec.tv_nsec = next_vsync % 1000000000; 727 728 int err; 729 do { 730 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL); 731 } while (err<0 && errno == EINTR); 732 733 if (err == 0) { 734 mHwc.mEventHandler.onVSyncReceived(0, next_vsync); 735 } 736 737 return true; 738} 739 740// --------------------------------------------------------------------------- 741}; // namespace android 742