HWComposer.cpp revision 22ffb117b0c2a906bd04aef9738a52223cdd1dce
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 46HWComposer::HWComposer( 47 const sp<SurfaceFlinger>& flinger, 48 EventHandler& handler, 49 nsecs_t refreshPeriod) 50 : mFlinger(flinger), 51 mModule(0), mHwc(0), mList(0), mCapacity(0), 52 mNumOVLayers(0), mNumFBLayers(0), 53 mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE), 54 mEventHandler(handler), 55 mRefreshPeriod(refreshPeriod), 56 mVSyncCount(0), mDebugForceFakeVSync(false) 57{ 58 char value[PROPERTY_VALUE_MAX]; 59 property_get("debug.sf.no_hw_vsync", value, "0"); 60 mDebugForceFakeVSync = atoi(value); 61 62 bool needVSyncThread = false; 63 int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); 64 ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID); 65 if (err == 0) { 66 err = hwc_open(mModule, &mHwc); 67 ALOGE_IF(err, "%s device failed to initialize (%s)", 68 HWC_HARDWARE_COMPOSER, strerror(-err)); 69 if (err == 0) { 70 if (mHwc->registerProcs) { 71 mCBContext.hwc = this; 72 mCBContext.procs.invalidate = &hook_invalidate; 73 mCBContext.procs.vsync = &hook_vsync; 74 mHwc->registerProcs(mHwc, &mCBContext.procs); 75 memset(mCBContext.procs.zero, 0, sizeof(mCBContext.procs.zero)); 76 } 77 if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { 78 if (mDebugForceFakeVSync) { 79 // make sure to turn h/w vsync off in "fake vsync" mode 80 mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0); 81 } 82 } else { 83 needVSyncThread = true; 84 } 85 } 86 } else { 87 needVSyncThread = true; 88 } 89 90 if (needVSyncThread) { 91 // we don't have VSYNC support, we need to fake it 92 mVSyncThread = new VSyncThread(*this); 93 } 94} 95 96HWComposer::~HWComposer() { 97 eventControl(EVENT_VSYNC, 0); 98 free(mList); 99 if (mVSyncThread != NULL) { 100 mVSyncThread->requestExitAndWait(); 101 } 102 if (mHwc) { 103 hwc_close(mHwc); 104 } 105} 106 107status_t HWComposer::initCheck() const { 108 return mHwc ? NO_ERROR : NO_INIT; 109} 110 111void HWComposer::hook_invalidate(struct hwc_procs* procs) { 112 reinterpret_cast<cb_context *>(procs)->hwc->invalidate(); 113} 114 115void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp) { 116 reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy, timestamp); 117} 118 119void HWComposer::invalidate() { 120 mFlinger->repaintEverything(); 121} 122 123void HWComposer::vsync(int dpy, int64_t timestamp) { 124 ATRACE_INT("VSYNC", ++mVSyncCount&1); 125 mEventHandler.onVSyncReceived(dpy, timestamp); 126} 127 128status_t HWComposer::eventControl(int event, int enabled) { 129 status_t err = NO_ERROR; 130 if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { 131 if (!mDebugForceFakeVSync) { 132 err = mHwc->methods->eventControl(mHwc, event, enabled); 133 } 134 } 135 136 if (err == NO_ERROR && mVSyncThread != NULL) { 137 mVSyncThread->setEnabled(enabled); 138 } 139 140 return err; 141} 142 143void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) { 144 mDpy = (hwc_display_t)dpy; 145 mSur = (hwc_surface_t)sur; 146} 147 148status_t HWComposer::createWorkList(size_t numLayers) { 149 if (mHwc) { 150 if (!mList || mCapacity < numLayers) { 151 free(mList); 152 size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t); 153 mList = (hwc_layer_list_t*)malloc(size); 154 mCapacity = numLayers; 155 } 156 mList->flags = HWC_GEOMETRY_CHANGED; 157 mList->numHwLayers = numLayers; 158 } 159 return NO_ERROR; 160} 161 162status_t HWComposer::prepare() const { 163 int err = mHwc->prepare(mHwc, mList); 164 if (err == NO_ERROR) { 165 size_t numOVLayers = 0; 166 size_t numFBLayers = 0; 167 size_t count = mList->numHwLayers; 168 for (size_t i=0 ; i<count ; i++) { 169 hwc_layer& l(mList->hwLayers[i]); 170 if (l.flags & HWC_SKIP_LAYER) { 171 l.compositionType = HWC_FRAMEBUFFER; 172 } 173 switch (l.compositionType) { 174 case HWC_OVERLAY: 175 numOVLayers++; 176 break; 177 case HWC_FRAMEBUFFER: 178 numFBLayers++; 179 break; 180 } 181 } 182 mNumOVLayers = numOVLayers; 183 mNumFBLayers = numFBLayers; 184 } 185 return (status_t)err; 186} 187 188size_t HWComposer::getLayerCount(int type) const { 189 switch (type) { 190 case HWC_OVERLAY: 191 return mNumOVLayers; 192 case HWC_FRAMEBUFFER: 193 return mNumFBLayers; 194 } 195 return 0; 196} 197 198status_t HWComposer::commit() const { 199 int err = mHwc->set(mHwc, mDpy, mSur, mList); 200 if (mList) { 201 mList->flags &= ~HWC_GEOMETRY_CHANGED; 202 } 203 return (status_t)err; 204} 205 206status_t HWComposer::release() const { 207 if (mHwc) { 208 if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) { 209 mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0); 210 } 211 int err = mHwc->set(mHwc, NULL, NULL, NULL); 212 return (status_t)err; 213 } 214 return NO_ERROR; 215} 216 217status_t HWComposer::disable() { 218 if (mHwc) { 219 free(mList); 220 mList = NULL; 221 int err = mHwc->prepare(mHwc, NULL); 222 return (status_t)err; 223 } 224 return NO_ERROR; 225} 226 227size_t HWComposer::getNumLayers() const { 228 return mList ? mList->numHwLayers : 0; 229} 230 231hwc_layer_t* HWComposer::getLayers() const { 232 return mList ? mList->hwLayers : 0; 233} 234 235void HWComposer::dump(String8& result, char* buffer, size_t SIZE, 236 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const { 237 if (mHwc && mList) { 238 result.append("Hardware Composer state:\n"); 239 result.appendFormat(" mDebugForceFakeVSync=%d\n", 240 mDebugForceFakeVSync); 241 result.appendFormat(" numHwLayers=%u, flags=%08x\n", 242 mList->numHwLayers, mList->flags); 243 result.append( 244 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n" 245 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n"); 246 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____] 247 for (size_t i=0 ; i<mList->numHwLayers ; i++) { 248 const hwc_layer_t& l(mList->hwLayers[i]); 249 const sp<LayerBase> layer(visibleLayersSortedByZ[i]); 250 int32_t format = -1; 251 if (layer->getLayer() != NULL) { 252 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer()); 253 if (buffer != NULL) { 254 format = buffer->getPixelFormat(); 255 } 256 } 257 result.appendFormat( 258 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n", 259 l.compositionType ? "OVERLAY" : "FB", 260 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format, 261 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom, 262 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom, 263 layer->getName().string()); 264 } 265 } 266 if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_1 && mHwc->dump) { 267 mHwc->dump(mHwc, buffer, SIZE); 268 result.append(buffer); 269 } 270} 271 272// --------------------------------------------------------------------------- 273 274HWComposer::VSyncThread::VSyncThread(HWComposer& hwc) 275 : mHwc(hwc), mEnabled(false), 276 mNextFakeVSync(0), 277 mRefreshPeriod(hwc.mRefreshPeriod) 278{ 279} 280 281void HWComposer::VSyncThread::setEnabled(bool enabled) { 282 Mutex::Autolock _l(mLock); 283 mEnabled = enabled; 284 mCondition.signal(); 285} 286 287void HWComposer::VSyncThread::onFirstRef() { 288 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); 289} 290 291bool HWComposer::VSyncThread::threadLoop() { 292 { // scope for lock 293 Mutex::Autolock _l(mLock); 294 while (!mEnabled) { 295 mCondition.wait(mLock); 296 } 297 } 298 299 const nsecs_t period = mRefreshPeriod; 300 const nsecs_t now = systemTime(CLOCK_MONOTONIC); 301 nsecs_t next_vsync = mNextFakeVSync; 302 nsecs_t sleep = next_vsync - now; 303 if (sleep < 0) { 304 // we missed, find where the next vsync should be 305 sleep = (period - ((now - next_vsync) % period)); 306 next_vsync = now + sleep; 307 } 308 mNextFakeVSync = next_vsync + period; 309 310 struct timespec spec; 311 spec.tv_sec = next_vsync / 1000000000; 312 spec.tv_nsec = next_vsync % 1000000000; 313 314 int err; 315 do { 316 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL); 317 } while (err<0 && errno == EINTR); 318 319 if (err == 0) { 320 mHwc.mEventHandler.onVSyncReceived(0, next_vsync); 321 } 322 323 return true; 324} 325 326// --------------------------------------------------------------------------- 327}; // namespace android 328