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