HWComposer.cpp revision 3e8b853d67c737abdb363f9c978e7d83eac4d888
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#include <stdint.h> 20#include <stdio.h> 21#include <stdlib.h> 22#include <string.h> 23#include <sys/types.h> 24 25#include <utils/Errors.h> 26#include <utils/String8.h> 27#include <utils/Thread.h> 28#include <utils/Trace.h> 29#include <utils/Vector.h> 30 31#include <hardware/hardware.h> 32#include <hardware/hwcomposer.h> 33 34#include <cutils/log.h> 35#include <cutils/properties.h> 36 37#include <EGL/egl.h> 38 39#include "LayerBase.h" 40#include "HWComposer.h" 41#include "SurfaceFlinger.h" 42 43namespace android { 44// --------------------------------------------------------------------------- 45 46struct HWComposer::cb_context { 47 struct callbacks : public hwc_procs_t { 48 // these are here to facilitate the transition when adding 49 // new callbacks (an implementation can check for NULL before 50 // calling a new callback). 51 void (*zero[4])(void); 52 }; 53 callbacks procs; 54 HWComposer* hwc; 55}; 56 57// --------------------------------------------------------------------------- 58 59HWComposer::HWComposer( 60 const sp<SurfaceFlinger>& flinger, 61 EventHandler& handler, 62 nsecs_t refreshPeriod) 63 : mFlinger(flinger), 64 mModule(0), mHwc(0), mList(0), mCapacity(0), 65 mNumOVLayers(0), mNumFBLayers(0), 66 mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE), 67 mCBContext(new cb_context), 68 mEventHandler(handler), 69 mRefreshPeriod(refreshPeriod), 70 mVSyncCount(0), mDebugForceFakeVSync(false) 71{ 72 char value[PROPERTY_VALUE_MAX]; 73 property_get("debug.sf.no_hw_vsync", value, "0"); 74 mDebugForceFakeVSync = atoi(value); 75 76 bool needVSyncThread = false; 77 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); 78 ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID); 79 if (err == 0) { 80 err = hwc_open(mModule, &mHwc); 81 ALOGE_IF(err, "%s device failed to initialize (%s)", 82 HWC_HARDWARE_COMPOSER, strerror(-err)); 83 if (err == 0) { 84 if (mHwc->registerProcs) { 85 mCBContext->hwc = this; 86 mCBContext->procs.invalidate = &hook_invalidate; 87 mCBContext->procs.vsync = &hook_vsync; 88 mHwc->registerProcs(mHwc, &mCBContext->procs); 89 memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero)); 90 } 91 if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { 92 if (mDebugForceFakeVSync) { 93 // make sure to turn h/w vsync off in "fake vsync" mode 94 mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0); 95 } 96 } else { 97 needVSyncThread = true; 98 } 99 } 100 } else { 101 needVSyncThread = true; 102 } 103 104 if (needVSyncThread) { 105 // we don't have VSYNC support, we need to fake it 106 mVSyncThread = new VSyncThread(*this); 107 } 108} 109 110HWComposer::~HWComposer() { 111 eventControl(EVENT_VSYNC, 0); 112 free(mList); 113 if (mVSyncThread != NULL) { 114 mVSyncThread->requestExitAndWait(); 115 } 116 if (mHwc) { 117 hwc_close(mHwc); 118 } 119 delete mCBContext; 120} 121 122status_t HWComposer::initCheck() const { 123 return mHwc ? NO_ERROR : NO_INIT; 124} 125 126void HWComposer::hook_invalidate(struct hwc_procs* procs) { 127 reinterpret_cast<cb_context *>(procs)->hwc->invalidate(); 128} 129 130void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp) { 131 reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy, timestamp); 132} 133 134void HWComposer::invalidate() { 135 mFlinger->repaintEverything(); 136} 137 138void HWComposer::vsync(int dpy, int64_t timestamp) { 139 ATRACE_INT("VSYNC", ++mVSyncCount&1); 140 mEventHandler.onVSyncReceived(dpy, timestamp); 141} 142 143void HWComposer::eventControl(int event, int enabled) { 144 status_t err = NO_ERROR; 145 if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { 146 if (!mDebugForceFakeVSync) { 147 err = mHwc->methods->eventControl(mHwc, event, enabled); 148 // error here should not happen -- not sure what we should 149 // do if it does. 150 ALOGE_IF(err, "eventControl(%d, %d) failed %s", 151 event, enabled, strerror(-err)); 152 } 153 } 154 155 if (err == NO_ERROR && mVSyncThread != NULL) { 156 mVSyncThread->setEnabled(enabled); 157 } 158} 159 160void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) { 161 mDpy = (hwc_display_t)dpy; 162 mSur = (hwc_surface_t)sur; 163} 164 165status_t HWComposer::createWorkList(size_t numLayers) { 166 if (mHwc) { 167 if (!mList || mCapacity < numLayers) { 168 free(mList); 169 size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t); 170 mList = (hwc_layer_list_t*)malloc(size); 171 mCapacity = numLayers; 172 } 173 mList->flags = HWC_GEOMETRY_CHANGED; 174 mList->numHwLayers = numLayers; 175 } 176 return NO_ERROR; 177} 178 179status_t HWComposer::prepare() const { 180 int err = mHwc->prepare(mHwc, mList); 181 if (err == NO_ERROR) { 182 size_t numOVLayers = 0; 183 size_t numFBLayers = 0; 184 size_t count = mList->numHwLayers; 185 for (size_t i=0 ; i<count ; i++) { 186 hwc_layer& l(mList->hwLayers[i]); 187 if (l.flags & HWC_SKIP_LAYER) { 188 l.compositionType = HWC_FRAMEBUFFER; 189 } 190 switch (l.compositionType) { 191 case HWC_OVERLAY: 192 numOVLayers++; 193 break; 194 case HWC_FRAMEBUFFER: 195 numFBLayers++; 196 break; 197 } 198 } 199 mNumOVLayers = numOVLayers; 200 mNumFBLayers = numFBLayers; 201 } 202 return (status_t)err; 203} 204 205size_t HWComposer::getLayerCount(int type) const { 206 switch (type) { 207 case HWC_OVERLAY: 208 return mNumOVLayers; 209 case HWC_FRAMEBUFFER: 210 return mNumFBLayers; 211 } 212 return 0; 213} 214 215status_t HWComposer::commit() const { 216 int err = mHwc->set(mHwc, mDpy, mSur, mList); 217 if (mList) { 218 mList->flags &= ~HWC_GEOMETRY_CHANGED; 219 } 220 return (status_t)err; 221} 222 223status_t HWComposer::release() const { 224 if (mHwc) { 225 if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { 226 mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0); 227 } 228 int err = mHwc->set(mHwc, NULL, NULL, NULL); 229 return (status_t)err; 230 } 231 return NO_ERROR; 232} 233 234status_t HWComposer::disable() { 235 if (mHwc) { 236 free(mList); 237 mList = NULL; 238 int err = mHwc->prepare(mHwc, NULL); 239 return (status_t)err; 240 } 241 return NO_ERROR; 242} 243 244size_t HWComposer::getNumLayers() const { 245 return mList ? mList->numHwLayers : 0; 246} 247 248/* 249 * Helper template to implement a concrete HWCLayer 250 * This holds the pointer to the concrete hwc layer type 251 * and implements the "iterable" side of HWCLayer. 252 */ 253template<typename CONCRETE, typename HWCTYPE> 254class Iterable : public HWComposer::HWCLayer { 255protected: 256 HWCTYPE* const mLayerList; 257 HWCTYPE* mCurrentLayer; 258 Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { } 259 inline HWCTYPE const * getLayer() const { return mCurrentLayer; } 260 inline HWCTYPE* getLayer() { return mCurrentLayer; } 261 virtual ~Iterable() { } 262private: 263 // returns a copy of ourselves 264 virtual HWComposer::HWCLayer* dup() { 265 return new CONCRETE( static_cast<const CONCRETE&>(*this) ); 266 } 267 virtual status_t setLayer(size_t index) { 268 mCurrentLayer = &mLayerList[index]; 269 return NO_ERROR; 270 } 271}; 272 273/* 274 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3 275 * This implements the HWCLayer side of HWCIterableLayer. 276 */ 277class HWCLayerVersion03 : public Iterable<HWCLayerVersion03, hwc_layer_t> { 278public: 279 HWCLayerVersion03(hwc_layer_t* layer) 280 : Iterable<HWCLayerVersion03, hwc_layer_t>(layer) { } 281 282 virtual int32_t getCompositionType() const { 283 return getLayer()->compositionType; 284 } 285 virtual uint32_t getHints() const { 286 return getLayer()->hints; 287 } 288 289 virtual void setDefaultState() { 290 getLayer()->compositionType = HWC_FRAMEBUFFER; 291 getLayer()->hints = 0; 292 getLayer()->flags = HWC_SKIP_LAYER; 293 getLayer()->transform = 0; 294 getLayer()->blending = HWC_BLENDING_NONE; 295 getLayer()->visibleRegionScreen.numRects = 0; 296 getLayer()->visibleRegionScreen.rects = NULL; 297 } 298 virtual void setSkip(bool skip) { 299 if (skip) { 300 getLayer()->flags |= HWC_SKIP_LAYER; 301 } else { 302 getLayer()->flags &= ~HWC_SKIP_LAYER; 303 } 304 } 305 virtual void setBlending(uint32_t blending) { 306 getLayer()->blending = blending; 307 } 308 virtual void setTransform(uint32_t transform) { 309 getLayer()->transform = transform; 310 } 311 virtual void setFrame(const Rect& frame) { 312 reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame; 313 } 314 virtual void setCrop(const Rect& crop) { 315 reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop; 316 } 317 virtual void setVisibleRegionScreen(const Region& reg) { 318 getLayer()->visibleRegionScreen.rects = 319 reinterpret_cast<hwc_rect_t const *>( 320 reg.getArray(&getLayer()->visibleRegionScreen.numRects)); 321 } 322 virtual void setBuffer(const sp<GraphicBuffer>& buffer) { 323 if (buffer == 0 || buffer->handle == 0) { 324 getLayer()->compositionType = HWC_FRAMEBUFFER; 325 getLayer()->flags |= HWC_SKIP_LAYER; 326 getLayer()->handle = 0; 327 } else { 328 getLayer()->handle = buffer->handle; 329 } 330 } 331}; 332 333/* 334 * returns an iterator initialized at a given index in the layer list 335 */ 336HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) { 337 if (!mList || index > mList->numHwLayers) { 338 return LayerListIterator(); 339 } 340 return LayerListIterator(new HWCLayerVersion03(mList->hwLayers), index); 341} 342 343/* 344 * returns an iterator on the beginning of the layer list 345 */ 346HWComposer::LayerListIterator HWComposer::begin() { 347 return getLayerIterator(0); 348} 349 350/* 351 * returns an iterator on the end of the layer list 352 */ 353HWComposer::LayerListIterator HWComposer::end() { 354 return getLayerIterator(getNumLayers()); 355} 356 357 358 359void HWComposer::dump(String8& result, char* buffer, size_t SIZE, 360 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const { 361 if (mHwc && mList) { 362 result.append("Hardware Composer state:\n"); 363 result.appendFormat(" mDebugForceFakeVSync=%d\n", 364 mDebugForceFakeVSync); 365 result.appendFormat(" numHwLayers=%u, flags=%08x\n", 366 mList->numHwLayers, mList->flags); 367 result.append( 368 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n" 369 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n"); 370 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____] 371 for (size_t i=0 ; i<mList->numHwLayers ; i++) { 372 const hwc_layer_t& l(mList->hwLayers[i]); 373 const sp<LayerBase> layer(visibleLayersSortedByZ[i]); 374 int32_t format = -1; 375 if (layer->getLayer() != NULL) { 376 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer()); 377 if (buffer != NULL) { 378 format = buffer->getPixelFormat(); 379 } 380 } 381 result.appendFormat( 382 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n", 383 l.compositionType ? "OVERLAY" : "FB", 384 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format, 385 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom, 386 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom, 387 layer->getName().string()); 388 } 389 } 390 if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_1 && mHwc->dump) { 391 mHwc->dump(mHwc, buffer, SIZE); 392 result.append(buffer); 393 } 394} 395 396// --------------------------------------------------------------------------- 397 398HWComposer::VSyncThread::VSyncThread(HWComposer& hwc) 399 : mHwc(hwc), mEnabled(false), 400 mNextFakeVSync(0), 401 mRefreshPeriod(hwc.mRefreshPeriod) 402{ 403} 404 405void HWComposer::VSyncThread::setEnabled(bool enabled) { 406 Mutex::Autolock _l(mLock); 407 mEnabled = enabled; 408 mCondition.signal(); 409} 410 411void HWComposer::VSyncThread::onFirstRef() { 412 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); 413} 414 415bool HWComposer::VSyncThread::threadLoop() { 416 { // scope for lock 417 Mutex::Autolock _l(mLock); 418 while (!mEnabled) { 419 mCondition.wait(mLock); 420 } 421 } 422 423 const nsecs_t period = mRefreshPeriod; 424 const nsecs_t now = systemTime(CLOCK_MONOTONIC); 425 nsecs_t next_vsync = mNextFakeVSync; 426 nsecs_t sleep = next_vsync - now; 427 if (sleep < 0) { 428 // we missed, find where the next vsync should be 429 sleep = (period - ((now - next_vsync) % period)); 430 next_vsync = now + sleep; 431 } 432 mNextFakeVSync = next_vsync + period; 433 434 struct timespec spec; 435 spec.tv_sec = next_vsync / 1000000000; 436 spec.tv_nsec = next_vsync % 1000000000; 437 438 int err; 439 do { 440 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL); 441 } while (err<0 && errno == EINTR); 442 443 if (err == 0) { 444 mHwc.mEventHandler.onVSyncReceived(0, next_vsync); 445 } 446 447 return true; 448} 449 450// --------------------------------------------------------------------------- 451}; // namespace android 452