HWComposer.cpp revision e2c4f4ec23b735dd2a03f4ea8b08b288a1bb04e8
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 int err = mHwc->set(mHwc, NULL, NULL, NULL); 209 return (status_t)err; 210 } 211 return NO_ERROR; 212} 213 214status_t HWComposer::disable() { 215 if (mHwc) { 216 free(mList); 217 mList = NULL; 218 int err = mHwc->prepare(mHwc, NULL); 219 return (status_t)err; 220 } 221 return NO_ERROR; 222} 223 224size_t HWComposer::getNumLayers() const { 225 return mList ? mList->numHwLayers : 0; 226} 227 228hwc_layer_t* HWComposer::getLayers() const { 229 return mList ? mList->hwLayers : 0; 230} 231 232void HWComposer::dump(String8& result, char* buffer, size_t SIZE, 233 const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const { 234 if (mHwc && mList) { 235 result.append("Hardware Composer state:\n"); 236 result.appendFormat(" mDebugForceFakeVSync=%d\n", 237 mDebugForceFakeVSync); 238 result.appendFormat(" numHwLayers=%u, flags=%08x\n", 239 mList->numHwLayers, mList->flags); 240 result.append( 241 " type | handle | hints | flags | tr | blend | format | source crop | frame name \n" 242 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n"); 243 // " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____] 244 for (size_t i=0 ; i<mList->numHwLayers ; i++) { 245 const hwc_layer_t& l(mList->hwLayers[i]); 246 const sp<LayerBase> layer(visibleLayersSortedByZ[i]); 247 int32_t format = -1; 248 if (layer->getLayer() != NULL) { 249 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer()); 250 if (buffer != NULL) { 251 format = buffer->getPixelFormat(); 252 } 253 } 254 result.appendFormat( 255 " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n", 256 l.compositionType ? "OVERLAY" : "FB", 257 intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format, 258 l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom, 259 l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom, 260 layer->getName().string()); 261 } 262 } 263 if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_1 && mHwc->dump) { 264 mHwc->dump(mHwc, buffer, SIZE); 265 result.append(buffer); 266 } 267} 268 269// --------------------------------------------------------------------------- 270 271HWComposer::VSyncThread::VSyncThread(HWComposer& hwc) 272 : mHwc(hwc), mEnabled(false), 273 mNextFakeVSync(0), 274 mRefreshPeriod(hwc.mRefreshPeriod) 275{ 276} 277 278void HWComposer::VSyncThread::setEnabled(bool enabled) { 279 Mutex::Autolock _l(mLock); 280 mEnabled = enabled; 281 mCondition.signal(); 282} 283 284void HWComposer::VSyncThread::onFirstRef() { 285 run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE); 286} 287 288bool HWComposer::VSyncThread::threadLoop() { 289 { // scope for lock 290 Mutex::Autolock _l(mLock); 291 while (!mEnabled) { 292 mCondition.wait(mLock); 293 } 294 } 295 296 const nsecs_t period = mRefreshPeriod; 297 const nsecs_t now = systemTime(CLOCK_MONOTONIC); 298 nsecs_t next_vsync = mNextFakeVSync; 299 nsecs_t sleep = next_vsync - now; 300 if (sleep < 0) { 301 // we missed, find where the next vsync should be 302 sleep = (period - ((now - next_vsync) % period)); 303 next_vsync = now + sleep; 304 } 305 mNextFakeVSync = next_vsync + period; 306 307 struct timespec spec; 308 spec.tv_sec = next_vsync / 1000000000; 309 spec.tv_nsec = next_vsync % 1000000000; 310 311 int err; 312 do { 313 err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL); 314 } while (err<0 && errno == EINTR); 315 316 if (err == 0) { 317 mHwc.mEventHandler.onVSyncReceived(0, next_vsync); 318 } 319 320 return true; 321} 322 323// --------------------------------------------------------------------------- 324}; // namespace android 325