HWComposer.cpp revision 3eb38cb33e41ce40dd1094bdec850f0fca9f8a53
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#include <stdint.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <sys/types.h>
22
23#include <utils/Errors.h>
24#include <utils/String8.h>
25#include <utils/Thread.h>
26#include <utils/Vector.h>
27
28#include <hardware/hardware.h>
29#include <hardware/hwcomposer.h>
30
31#include <cutils/log.h>
32
33#include <EGL/egl.h>
34
35#include "LayerBase.h"
36#include "HWComposer.h"
37#include "SurfaceFlinger.h"
38
39namespace android {
40// ---------------------------------------------------------------------------
41
42HWComposer::HWComposer(
43        const sp<SurfaceFlinger>& flinger,
44        EventHandler& handler,
45        nsecs_t refreshPeriod)
46    : mFlinger(flinger),
47      mModule(0), mHwc(0), mList(0), mCapacity(0),
48      mNumOVLayers(0), mNumFBLayers(0),
49      mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE),
50      mEventHandler(handler),
51      mRefreshPeriod(refreshPeriod)
52{
53    int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
54    ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
55    if (err == 0) {
56        err = hwc_open(mModule, &mHwc);
57        ALOGE_IF(err, "%s device failed to initialize (%s)",
58                HWC_HARDWARE_COMPOSER, strerror(-err));
59        if (err == 0) {
60            if (mHwc->registerProcs) {
61                mCBContext.hwc = this;
62                mCBContext.procs.invalidate = &hook_invalidate;
63                mCBContext.procs.vsync = &hook_vsync;
64                mHwc->registerProcs(mHwc, &mCBContext.procs);
65                memset(mCBContext.procs.zero, 0, sizeof(mCBContext.procs.zero));
66            }
67
68            if (mHwc->common.version < HWC_DEVICE_API_VERSION_0_3) {
69                // we don't have VSYNC support, we need to fake it
70                mVSyncThread = new VSyncThread(*this);
71            }
72        }
73    }
74}
75
76HWComposer::~HWComposer() {
77    free(mList);
78    if (mVSyncThread != NULL) {
79        mVSyncThread->requestExitAndWait();
80    }
81    if (mHwc) {
82        hwc_close(mHwc);
83    }
84}
85
86status_t HWComposer::initCheck() const {
87    return mHwc ? NO_ERROR : NO_INIT;
88}
89
90void HWComposer::hook_invalidate(struct hwc_procs* procs) {
91    reinterpret_cast<cb_context *>(procs)->hwc->invalidate();
92}
93
94void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp) {
95    reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy, timestamp);
96}
97
98void HWComposer::invalidate() {
99    mFlinger->repaintEverything();
100}
101
102void HWComposer::vsync(int dpy, int64_t timestamp) {
103    mEventHandler.onVSyncReceived(dpy, timestamp);
104}
105
106status_t HWComposer::eventControl(int event, int enabled) {
107    status_t err = NO_ERROR;
108    if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
109        err = mHwc->methods->eventControl(mHwc, event, enabled);
110    } else {
111        if (mVSyncThread != NULL) {
112            mVSyncThread->setEnabled(enabled);
113        } else {
114            err = BAD_VALUE;
115        }
116    }
117    return err;
118}
119
120void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) {
121    mDpy = (hwc_display_t)dpy;
122    mSur = (hwc_surface_t)sur;
123}
124
125status_t HWComposer::createWorkList(size_t numLayers) {
126    if (mHwc) {
127        if (!mList || mCapacity < numLayers) {
128            free(mList);
129            size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t);
130            mList = (hwc_layer_list_t*)malloc(size);
131            mCapacity = numLayers;
132        }
133        mList->flags = HWC_GEOMETRY_CHANGED;
134        mList->numHwLayers = numLayers;
135    }
136    return NO_ERROR;
137}
138
139status_t HWComposer::prepare() const {
140    int err = mHwc->prepare(mHwc, mList);
141    if (err == NO_ERROR) {
142        size_t numOVLayers = 0;
143        size_t numFBLayers = 0;
144        size_t count = mList->numHwLayers;
145        for (size_t i=0 ; i<count ; i++) {
146            hwc_layer& l(mList->hwLayers[i]);
147            if (l.flags & HWC_SKIP_LAYER) {
148                l.compositionType = HWC_FRAMEBUFFER;
149            }
150            switch (l.compositionType) {
151                case HWC_OVERLAY:
152                    numOVLayers++;
153                    break;
154                case HWC_FRAMEBUFFER:
155                    numFBLayers++;
156                    break;
157            }
158        }
159        mNumOVLayers = numOVLayers;
160        mNumFBLayers = numFBLayers;
161    }
162    return (status_t)err;
163}
164
165size_t HWComposer::getLayerCount(int type) const {
166    switch (type) {
167        case HWC_OVERLAY:
168            return mNumOVLayers;
169        case HWC_FRAMEBUFFER:
170            return mNumFBLayers;
171    }
172    return 0;
173}
174
175status_t HWComposer::commit() const {
176    int err = mHwc->set(mHwc, mDpy, mSur, mList);
177    if (mList) {
178        mList->flags &= ~HWC_GEOMETRY_CHANGED;
179    }
180    return (status_t)err;
181}
182
183status_t HWComposer::release() const {
184    if (mHwc) {
185        int err = mHwc->set(mHwc, NULL, NULL, NULL);
186        return (status_t)err;
187    }
188    return NO_ERROR;
189}
190
191status_t HWComposer::disable() {
192    if (mHwc) {
193        free(mList);
194        mList = NULL;
195        int err = mHwc->prepare(mHwc, NULL);
196        return (status_t)err;
197    }
198    return NO_ERROR;
199}
200
201size_t HWComposer::getNumLayers() const {
202    return mList ? mList->numHwLayers : 0;
203}
204
205hwc_layer_t* HWComposer::getLayers() const {
206    return mList ? mList->hwLayers : 0;
207}
208
209void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
210        const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
211    if (mHwc && mList) {
212        result.append("Hardware Composer state:\n");
213
214        snprintf(buffer, SIZE, "  numHwLayers=%u, flags=%08x\n",
215                mList->numHwLayers, mList->flags);
216        result.append(buffer);
217        result.append(
218                "   type   |  handle  |   hints  |   flags  | tr | blend |  format  |       source crop         |           frame           name \n"
219                "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
220        //      " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
221        for (size_t i=0 ; i<mList->numHwLayers ; i++) {
222            const hwc_layer_t& l(mList->hwLayers[i]);
223            const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
224            int32_t format = -1;
225            if (layer->getLayer() != NULL) {
226                const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
227                if (buffer != NULL) {
228                    format = buffer->getPixelFormat();
229                }
230            }
231            snprintf(buffer, SIZE,
232                    " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
233                    l.compositionType ? "OVERLAY" : "FB",
234                    intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
235                    l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
236                    l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
237                    layer->getName().string());
238            result.append(buffer);
239        }
240    }
241    if (mHwc && mHwc->common.version >= 1 && mHwc->dump) {
242        mHwc->dump(mHwc, buffer, SIZE);
243        result.append(buffer);
244    }
245}
246
247// ---------------------------------------------------------------------------
248}; // namespace android
249