Home | History | Annotate | Download | only in DisplayHardware
      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 
     43 namespace android {
     44 // ---------------------------------------------------------------------------
     45 
     46 HWComposer::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 
     96 HWComposer::~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 
    107 status_t HWComposer::initCheck() const {
    108     return mHwc ? NO_ERROR : NO_INIT;
    109 }
    110 
    111 void HWComposer::hook_invalidate(struct hwc_procs* procs) {
    112     reinterpret_cast<cb_context *>(procs)->hwc->invalidate();
    113 }
    114 
    115 void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp) {
    116     reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy, timestamp);
    117 }
    118 
    119 void HWComposer::invalidate() {
    120     mFlinger->repaintEverything();
    121 }
    122 
    123 void HWComposer::vsync(int dpy, int64_t timestamp) {
    124     ATRACE_INT("VSYNC", ++mVSyncCount&1);
    125     mEventHandler.onVSyncReceived(dpy, timestamp);
    126 }
    127 
    128 void 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             // error here should not happen -- not sure what we should
    134             // do if it does.
    135             ALOGE_IF(err, "eventControl(%d, %d) failed %s",
    136                     event, enabled, strerror(-err));
    137         }
    138     }
    139 
    140     if (err == NO_ERROR && mVSyncThread != NULL) {
    141         mVSyncThread->setEnabled(enabled);
    142     }
    143 }
    144 
    145 void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) {
    146     mDpy = (hwc_display_t)dpy;
    147     mSur = (hwc_surface_t)sur;
    148 }
    149 
    150 status_t HWComposer::createWorkList(size_t numLayers) {
    151     if (mHwc) {
    152         if (!mList || mCapacity < numLayers) {
    153             free(mList);
    154             size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t);
    155             mList = (hwc_layer_list_t*)malloc(size);
    156             mCapacity = numLayers;
    157         }
    158         mList->flags = HWC_GEOMETRY_CHANGED;
    159         mList->numHwLayers = numLayers;
    160     }
    161     return NO_ERROR;
    162 }
    163 
    164 status_t HWComposer::prepare() const {
    165     int err = mHwc->prepare(mHwc, mList);
    166     if (err == NO_ERROR) {
    167         size_t numOVLayers = 0;
    168         size_t numFBLayers = 0;
    169         size_t count = mList->numHwLayers;
    170         for (size_t i=0 ; i<count ; i++) {
    171             hwc_layer& l(mList->hwLayers[i]);
    172             if (l.flags & HWC_SKIP_LAYER) {
    173                 l.compositionType = HWC_FRAMEBUFFER;
    174             }
    175             switch (l.compositionType) {
    176                 case HWC_OVERLAY:
    177                     numOVLayers++;
    178                     break;
    179                 case HWC_FRAMEBUFFER:
    180                     numFBLayers++;
    181                     break;
    182             }
    183         }
    184         mNumOVLayers = numOVLayers;
    185         mNumFBLayers = numFBLayers;
    186     }
    187     return (status_t)err;
    188 }
    189 
    190 size_t HWComposer::getLayerCount(int type) const {
    191     switch (type) {
    192         case HWC_OVERLAY:
    193             return mNumOVLayers;
    194         case HWC_FRAMEBUFFER:
    195             return mNumFBLayers;
    196     }
    197     return 0;
    198 }
    199 
    200 status_t HWComposer::commit() const {
    201     int err = mHwc->set(mHwc, mDpy, mSur, mList);
    202     if (mList) {
    203         mList->flags &= ~HWC_GEOMETRY_CHANGED;
    204     }
    205     return (status_t)err;
    206 }
    207 
    208 status_t HWComposer::release() const {
    209     if (mHwc) {
    210         if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
    211             mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0);
    212         }
    213         int err = mHwc->set(mHwc, NULL, NULL, NULL);
    214         return (status_t)err;
    215     }
    216     return NO_ERROR;
    217 }
    218 
    219 status_t HWComposer::disable() {
    220     if (mHwc) {
    221         free(mList);
    222         mList = NULL;
    223         int err = mHwc->prepare(mHwc, NULL);
    224         return (status_t)err;
    225     }
    226     return NO_ERROR;
    227 }
    228 
    229 size_t HWComposer::getNumLayers() const {
    230     return mList ? mList->numHwLayers : 0;
    231 }
    232 
    233 hwc_layer_t* HWComposer::getLayers() const {
    234     return mList ? mList->hwLayers : 0;
    235 }
    236 
    237 void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
    238         const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
    239     if (mHwc && mList) {
    240         result.append("Hardware Composer state:\n");
    241         result.appendFormat("  mDebugForceFakeVSync=%d\n",
    242                 mDebugForceFakeVSync);
    243         result.appendFormat("  numHwLayers=%u, flags=%08x\n",
    244                 mList->numHwLayers, mList->flags);
    245         result.append(
    246                 "   type   |  handle  |   hints  |   flags  | tr | blend |  format  |       source crop         |           frame           name \n"
    247                 "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
    248         //      " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
    249         for (size_t i=0 ; i<mList->numHwLayers ; i++) {
    250             const hwc_layer_t& l(mList->hwLayers[i]);
    251             const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
    252             int32_t format = -1;
    253             if (layer->getLayer() != NULL) {
    254                 const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
    255                 if (buffer != NULL) {
    256                     format = buffer->getPixelFormat();
    257                 }
    258             }
    259             result.appendFormat(
    260                     " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
    261                     l.compositionType ? "OVERLAY" : "FB",
    262                     intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
    263                     l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
    264                     l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
    265                     layer->getName().string());
    266         }
    267     }
    268     if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_1 && mHwc->dump) {
    269         mHwc->dump(mHwc, buffer, SIZE);
    270         result.append(buffer);
    271     }
    272 }
    273 
    274 // ---------------------------------------------------------------------------
    275 
    276 HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
    277     : mHwc(hwc), mEnabled(false),
    278       mNextFakeVSync(0),
    279       mRefreshPeriod(hwc.mRefreshPeriod)
    280 {
    281 }
    282 
    283 void HWComposer::VSyncThread::setEnabled(bool enabled) {
    284     Mutex::Autolock _l(mLock);
    285     mEnabled = enabled;
    286     mCondition.signal();
    287 }
    288 
    289 void HWComposer::VSyncThread::onFirstRef() {
    290     run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
    291 }
    292 
    293 bool HWComposer::VSyncThread::threadLoop() {
    294     { // scope for lock
    295         Mutex::Autolock _l(mLock);
    296         while (!mEnabled) {
    297             mCondition.wait(mLock);
    298         }
    299     }
    300 
    301     const nsecs_t period = mRefreshPeriod;
    302     const nsecs_t now = systemTime(CLOCK_MONOTONIC);
    303     nsecs_t next_vsync = mNextFakeVSync;
    304     nsecs_t sleep = next_vsync - now;
    305     if (sleep < 0) {
    306         // we missed, find where the next vsync should be
    307         sleep = (period - ((now - next_vsync) % period));
    308         next_vsync = now + sleep;
    309     }
    310     mNextFakeVSync = next_vsync + period;
    311 
    312     struct timespec spec;
    313     spec.tv_sec  = next_vsync / 1000000000;
    314     spec.tv_nsec = next_vsync % 1000000000;
    315 
    316     int err;
    317     do {
    318         err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
    319     } while (err<0 && errno == EINTR);
    320 
    321     if (err == 0) {
    322         mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
    323     }
    324 
    325     return true;
    326 }
    327 
    328 // ---------------------------------------------------------------------------
    329 }; // namespace android
    330