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