HWComposer.cpp revision 8b736f138cfd9b239a2c7073347a13c489534ae1
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// Uncomment this to remove support for HWC_DEVICE_API_VERSION_0_3 and older
20// #define HWC_REMOVE_DEPRECATED_VERSIONS 1
21
22#include <stdint.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <sys/types.h>
27
28#include <utils/Errors.h>
29#include <utils/String8.h>
30#include <utils/Thread.h>
31#include <utils/Trace.h>
32#include <utils/Vector.h>
33
34#include <ui/GraphicBuffer.h>
35
36#include <hardware/hardware.h>
37#include <hardware/hwcomposer.h>
38
39#include <cutils/log.h>
40#include <cutils/properties.h>
41
42#include "Layer.h"           // needed only for debugging
43#include "LayerBase.h"
44#include "HWComposer.h"
45#include "SurfaceFlinger.h"
46
47namespace android {
48
49// ---------------------------------------------------------------------------
50// Support for HWC_DEVICE_API_VERSION_0_3 and older:
51// Since v0.3 is deprecated and support will be dropped soon, as much as
52// possible the code is written to target v1.0. When using a v0.3 HWC, we
53// allocate v0.3 structures, but assign them to v1.0 pointers.
54
55#if HWC_REMOVE_DEPRECATED_VERSIONS
56// We need complete types to satisfy semantic checks, even though the code
57// paths that use these won't get executed at runtime (and will likely be dead-
58// code-eliminated). When we remove the code to support v0.3 we can remove
59// these as well.
60typedef hwc_layer_1_t hwc_layer_t;
61typedef hwc_display_contents_1_t hwc_layer_list_t;
62typedef hwc_composer_device_1_t hwc_composer_device_t;
63#endif
64
65// This function assumes we've already rejected HWC's with lower-than-required
66// versions. Don't use it for the initial "does HWC meet requirements" check!
67static bool hwcHasVersion(const hwc_composer_device_1_t* hwc, uint32_t version) {
68    if (HWC_REMOVE_DEPRECATED_VERSIONS &&
69            version <= HWC_DEVICE_API_VERSION_1_0) {
70        return true;
71    } else {
72        return hwc->common.version >= version;
73    }
74}
75
76static bool hwcHasVsyncEvent(const hwc_composer_device_1_t* hwc) {
77    return hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_0_3);
78}
79
80static size_t sizeofHwcLayerList(const hwc_composer_device_1_t* hwc,
81        size_t numLayers) {
82    if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
83        return sizeof(hwc_display_contents_1_t) + numLayers*sizeof(hwc_layer_1_t);
84    } else {
85        return sizeof(hwc_layer_list_t) + numLayers*sizeof(hwc_layer_t);
86    }
87}
88
89static int hwcEventControl(hwc_composer_device_1_t* hwc, int dpy,
90        int event, int enabled) {
91    if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
92        return hwc->methods->eventControl(hwc, dpy, event, enabled);
93    } else {
94        hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
95        return hwc0->methods->eventControl(hwc0, event, enabled);
96    }
97}
98
99static int hwcBlank(hwc_composer_device_1_t* hwc, int dpy, int blank) {
100    if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
101        return hwc->methods->blank(hwc, dpy, blank);
102    } else {
103        if (blank) {
104            hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
105            return hwc0->set(hwc0, NULL, NULL, NULL);
106        } else {
107            // HWC 0.x turns the screen on at the next set()
108            return NO_ERROR;
109        }
110    }
111}
112
113static int hwcPrepare(hwc_composer_device_1_t* hwc,
114        size_t numDisplays, hwc_display_contents_1_t** displays) {
115    if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
116        return hwc->prepare(hwc, numDisplays, displays);
117    } else {
118        hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
119        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(displays[0]);
120        // In the past, SurfaceFlinger would pass a NULL list when doing full
121        // OpenGL ES composition. I don't know what, if any, dependencies there
122        // are on this behavior, so I'm playing it safe and preserving it.
123        if (list0->numHwLayers == 0)
124            return hwc0->prepare(hwc0, NULL);
125        else
126            return hwc0->prepare(hwc0, list0);
127    }
128}
129
130static int hwcSet(hwc_composer_device_1_t* hwc, EGLDisplay dpy, EGLSurface sur,
131        size_t numDisplays, hwc_display_contents_1_t** displays) {
132    int err;
133    if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
134        displays[0]->dpy = dpy;
135        displays[0]->sur = sur;
136        err = hwc->set(hwc, numDisplays, displays);
137    } else {
138        hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
139        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(displays[0]);
140        err = hwc0->set(hwc0, dpy, sur, list0);
141    }
142    return err;
143}
144
145static uint32_t& hwcFlags(hwc_composer_device_1_t* hwc,
146        hwc_display_contents_1_t* display) {
147    if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
148        return display->flags;
149    } else {
150        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(display);
151        return list0->flags;
152    }
153}
154
155static size_t& hwcNumHwLayers(hwc_composer_device_1_t* hwc,
156        hwc_display_contents_1_t* display) {
157    if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
158        return display->numHwLayers;
159    } else {
160        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(display);
161        return list0->numHwLayers;
162    }
163}
164
165// ---------------------------------------------------------------------------
166
167struct HWComposer::cb_context {
168    struct callbacks : public hwc_procs_t {
169        // these are here to facilitate the transition when adding
170        // new callbacks (an implementation can check for NULL before
171        // calling a new callback).
172        void (*zero[4])(void);
173    };
174    callbacks procs;
175    HWComposer* hwc;
176};
177
178// ---------------------------------------------------------------------------
179
180HWComposer::HWComposer(
181        const sp<SurfaceFlinger>& flinger,
182        EventHandler& handler,
183        framebuffer_device_t const* fbDev)
184    : mFlinger(flinger),
185      mModule(0), mHwc(0), mCapacity(0),
186      mNumOVLayers(0), mNumFBLayers(0),
187      mCBContext(new cb_context),
188      mEventHandler(handler), mRefreshPeriod(0),
189      mVSyncCount(0), mDebugForceFakeVSync(false)
190{
191    for (size_t i = 0; i < MAX_DISPLAYS; i++)
192        mLists[i] = NULL;
193
194    char value[PROPERTY_VALUE_MAX];
195    property_get("debug.sf.no_hw_vsync", value, "0");
196    mDebugForceFakeVSync = atoi(value);
197
198    bool needVSyncThread = true;
199    int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
200    ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
201    if (err == 0) {
202        err = hwc_open_1(mModule, &mHwc);
203        ALOGE_IF(err, "%s device failed to initialize (%s)",
204                HWC_HARDWARE_COMPOSER, strerror(-err));
205        if (err == 0) {
206            if (HWC_REMOVE_DEPRECATED_VERSIONS &&
207                    mHwc->common.version < HWC_DEVICE_API_VERSION_1_0) {
208                ALOGE("%s device version %#x too old, will not be used",
209                        HWC_HARDWARE_COMPOSER, mHwc->common.version);
210                hwc_close_1(mHwc);
211                mHwc = NULL;
212            }
213        }
214
215        if (mHwc) {
216            // always turn vsync off when we start
217            needVSyncThread = false;
218            if (hwcHasVsyncEvent(mHwc)) {
219                hwcEventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
220
221                int period;
222                if (mHwc->query(mHwc, HWC_VSYNC_PERIOD, &period) == NO_ERROR) {
223                    mRefreshPeriod = nsecs_t(period);
224                }
225            } else {
226                needVSyncThread = true;
227            }
228
229            if (mHwc->registerProcs) {
230                mCBContext->hwc = this;
231                mCBContext->procs.invalidate = &hook_invalidate;
232                mCBContext->procs.vsync = &hook_vsync;
233                mHwc->registerProcs(mHwc, &mCBContext->procs);
234                memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
235            }
236
237            // create initial empty display contents for display 0
238            createWorkList(MAIN, 0);
239        }
240    }
241
242
243    if (fbDev) {
244        if (mRefreshPeriod == 0) {
245            mRefreshPeriod = nsecs_t(1e9 / fbDev->fps);
246            ALOGW("getting VSYNC period from fb HAL: %lld", mRefreshPeriod);
247        }
248        mDpiX = fbDev->xdpi;
249        mDpiY = fbDev->ydpi;
250    }
251
252    if (mRefreshPeriod == 0) {
253        mRefreshPeriod = nsecs_t(1e9 / 60.0);
254        ALOGW("getting VSYNC period thin air: %lld", mRefreshPeriod);
255    }
256
257    if (needVSyncThread) {
258        // we don't have VSYNC support, we need to fake it
259        mVSyncThread = new VSyncThread(*this);
260    }
261}
262
263HWComposer::~HWComposer() {
264    hwcEventControl(mHwc, 0, EVENT_VSYNC, 0);
265    for (size_t i = 0; i < MAX_DISPLAYS; i++)
266        free(mLists[i]);
267    if (mVSyncThread != NULL) {
268        mVSyncThread->requestExitAndWait();
269    }
270    if (mHwc) {
271        hwc_close_1(mHwc);
272    }
273    delete mCBContext;
274}
275
276status_t HWComposer::initCheck() const {
277    return mHwc ? NO_ERROR : NO_INIT;
278}
279
280void HWComposer::hook_invalidate(struct hwc_procs* procs) {
281    reinterpret_cast<cb_context *>(procs)->hwc->invalidate();
282}
283
284void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp) {
285    reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy, timestamp);
286}
287
288void HWComposer::invalidate() {
289    mFlinger->repaintEverything();
290}
291
292void HWComposer::vsync(int dpy, int64_t timestamp) {
293    ATRACE_INT("VSYNC", ++mVSyncCount&1);
294    mEventHandler.onVSyncReceived(dpy, timestamp);
295    Mutex::Autolock _l(mLock);
296    mLastHwVSync = timestamp;
297}
298
299nsecs_t HWComposer::getRefreshPeriod() const {
300    return mRefreshPeriod;
301}
302
303nsecs_t HWComposer::getRefreshTimestamp() const {
304    // this returns the last refresh timestamp.
305    // if the last one is not available, we estimate it based on
306    // the refresh period and whatever closest timestamp we have.
307    Mutex::Autolock _l(mLock);
308    nsecs_t now = systemTime(CLOCK_MONOTONIC);
309    return now - ((now - mLastHwVSync) %  mRefreshPeriod);
310}
311
312float HWComposer::getDpiX() const {
313    return mDpiX;
314}
315
316float HWComposer::getDpiY() const {
317    return mDpiY;
318}
319
320void HWComposer::eventControl(int event, int enabled) {
321    status_t err = NO_ERROR;
322    if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
323        if (!mDebugForceFakeVSync) {
324            err = hwcEventControl(mHwc, 0, event, enabled);
325            // error here should not happen -- not sure what we should
326            // do if it does.
327            ALOGE_IF(err, "eventControl(%d, %d) failed %s",
328                    event, enabled, strerror(-err));
329        }
330    }
331
332    if (err == NO_ERROR && mVSyncThread != NULL) {
333        mVSyncThread->setEnabled(enabled);
334    }
335}
336
337status_t HWComposer::createWorkList(int32_t id, size_t numLayers) { // FIXME: handle multiple displays
338    if (uint32_t(id) >= MAX_DISPLAYS)
339        return BAD_INDEX;
340
341    if (mHwc) {
342        // TODO: must handle multiple displays here
343        // mLists[0] is NULL only when this is called from the constructor
344        if (!mLists[0] || mCapacity < numLayers) {
345            free(mLists[0]);
346            size_t size = sizeofHwcLayerList(mHwc, numLayers);
347            mLists[0] = (hwc_display_contents_1_t*)malloc(size);
348            mCapacity = numLayers;
349        }
350        hwcFlags(mHwc, mLists[0]) = HWC_GEOMETRY_CHANGED;
351        hwcNumHwLayers(mHwc, mLists[0]) = numLayers;
352        if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
353            mLists[0]->flipFenceFd = -1;
354        }
355    }
356    return NO_ERROR;
357}
358
359status_t HWComposer::prepare() const {
360    int err = hwcPrepare(mHwc, 1,
361            const_cast<hwc_display_contents_1_t**>(mLists));
362    if (err == NO_ERROR) {
363        size_t numOVLayers = 0;
364        size_t numFBLayers = 0;
365        size_t count = getNumLayers(0);
366
367        for (size_t i=0 ; i<count ; i++) {
368            int compositionType;
369            if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
370                hwc_layer_1_t* l = &mLists[0]->hwLayers[i];
371                if (l->flags & HWC_SKIP_LAYER) {
372                    l->compositionType = HWC_FRAMEBUFFER;
373                }
374                compositionType = l->compositionType;
375            } else {
376                // mList really has hwc_layer_list_t memory layout
377                hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);
378                hwc_layer_t* l = &list0->hwLayers[i];
379                if (l->flags & HWC_SKIP_LAYER) {
380                    l->compositionType = HWC_FRAMEBUFFER;
381                }
382                compositionType = l->compositionType;
383            }
384
385            switch (compositionType) {
386                case HWC_OVERLAY:
387                    numOVLayers++;
388                    break;
389                case HWC_FRAMEBUFFER:
390                    numFBLayers++;
391                    break;
392            }
393        }
394        mNumOVLayers = numOVLayers;
395        mNumFBLayers = numFBLayers;
396    }
397    return (status_t)err;
398}
399
400size_t HWComposer::getLayerCount(int32_t id, int type) const { // FIXME: handle multiple displays
401    switch (type) {
402        case HWC_OVERLAY:
403            return mNumOVLayers;
404        case HWC_FRAMEBUFFER:
405            return mNumFBLayers;
406    }
407    return 0;
408}
409
410status_t HWComposer::commit(void* fbDisplay, void* fbSurface) const {
411    int err = NO_ERROR;
412    if (mHwc) {
413        err = hwcSet(mHwc, fbDisplay, fbSurface, 1,
414                const_cast<hwc_display_contents_1_t**>(mLists));
415        if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
416            if (mLists[0]->flipFenceFd != -1) {
417                close(mLists[0]->flipFenceFd);
418                mLists[0]->flipFenceFd = -1;
419            }
420        }
421        hwcFlags(mHwc, mLists[0]) &= ~HWC_GEOMETRY_CHANGED;
422    }
423    return (status_t)err;
424}
425
426status_t HWComposer::release() const {
427    if (mHwc) {
428        if (hwcHasVsyncEvent(mHwc)) {
429            hwcEventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
430        }
431        return (status_t)hwcBlank(mHwc, 0, 1);
432    }
433    return NO_ERROR;
434}
435
436status_t HWComposer::acquire() const {
437    if (mHwc) {
438        return (status_t)hwcBlank(mHwc, 0, 0);
439    }
440    return NO_ERROR;
441}
442
443status_t HWComposer::disable() {
444    if (mHwc) {
445        hwcNumHwLayers(mHwc, mLists[0]) = 0;
446        int err = hwcPrepare(mHwc, 1, mLists);
447        return (status_t)err;
448    }
449    return NO_ERROR;
450}
451
452size_t HWComposer::getNumLayers(int32_t id) const { // FIXME: handle multiple displays
453    return mHwc ? hwcNumHwLayers(mHwc, mLists[0]) : 0;
454}
455
456/*
457 * Helper template to implement a concrete HWCLayer
458 * This holds the pointer to the concrete hwc layer type
459 * and implements the "iterable" side of HWCLayer.
460 */
461template<typename CONCRETE, typename HWCTYPE>
462class Iterable : public HWComposer::HWCLayer {
463protected:
464    HWCTYPE* const mLayerList;
465    HWCTYPE* mCurrentLayer;
466    Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { }
467    inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
468    inline HWCTYPE* getLayer() { return mCurrentLayer; }
469    virtual ~Iterable() { }
470private:
471    // returns a copy of ourselves
472    virtual HWComposer::HWCLayer* dup() {
473        return new CONCRETE( static_cast<const CONCRETE&>(*this) );
474    }
475    virtual status_t setLayer(size_t index) {
476        mCurrentLayer = &mLayerList[index];
477        return NO_ERROR;
478    }
479};
480
481// #if !HWC_REMOVE_DEPRECATED_VERSIONS
482/*
483 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3
484 * This implements the HWCLayer side of HWCIterableLayer.
485 */
486class HWCLayerVersion0 : public Iterable<HWCLayerVersion0, hwc_layer_t> {
487public:
488    HWCLayerVersion0(hwc_layer_t* layer)
489        : Iterable<HWCLayerVersion0, hwc_layer_t>(layer) { }
490
491    virtual int32_t getCompositionType() const {
492        return getLayer()->compositionType;
493    }
494    virtual uint32_t getHints() const {
495        return getLayer()->hints;
496    }
497    virtual int getAndResetReleaseFenceFd() {
498        // not supported on VERSION_03
499        return -1;
500    }
501    virtual void setAcquireFenceFd(int fenceFd) {
502        if (fenceFd != -1) {
503            ALOGE("HWC 0.x can't handle acquire fences");
504            close(fenceFd);
505        }
506    }
507
508    virtual void setDefaultState() {
509        getLayer()->compositionType = HWC_FRAMEBUFFER;
510        getLayer()->hints = 0;
511        getLayer()->flags = HWC_SKIP_LAYER;
512        getLayer()->transform = 0;
513        getLayer()->blending = HWC_BLENDING_NONE;
514        getLayer()->visibleRegionScreen.numRects = 0;
515        getLayer()->visibleRegionScreen.rects = NULL;
516    }
517    virtual void setSkip(bool skip) {
518        if (skip) {
519            getLayer()->flags |= HWC_SKIP_LAYER;
520        } else {
521            getLayer()->flags &= ~HWC_SKIP_LAYER;
522        }
523    }
524    virtual void setBlending(uint32_t blending) {
525        getLayer()->blending = blending;
526    }
527    virtual void setTransform(uint32_t transform) {
528        getLayer()->transform = transform;
529    }
530    virtual void setFrame(const Rect& frame) {
531        reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
532    }
533    virtual void setCrop(const Rect& crop) {
534        reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
535    }
536    virtual void setVisibleRegionScreen(const Region& reg) {
537        getLayer()->visibleRegionScreen.rects =
538                reinterpret_cast<hwc_rect_t const *>(
539                        reg.getArray(&getLayer()->visibleRegionScreen.numRects));
540    }
541    virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
542        if (buffer == 0 || buffer->handle == 0) {
543            getLayer()->compositionType = HWC_FRAMEBUFFER;
544            getLayer()->flags |= HWC_SKIP_LAYER;
545            getLayer()->handle = 0;
546        } else {
547            getLayer()->handle = buffer->handle;
548        }
549    }
550};
551// #endif // !HWC_REMOVE_DEPRECATED_VERSIONS
552
553/*
554 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0.
555 * This implements the HWCLayer side of HWCIterableLayer.
556 */
557class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> {
558public:
559    HWCLayerVersion1(hwc_layer_1_t* layer)
560        : Iterable<HWCLayerVersion1, hwc_layer_1_t>(layer) { }
561
562    virtual int32_t getCompositionType() const {
563        return getLayer()->compositionType;
564    }
565    virtual uint32_t getHints() const {
566        return getLayer()->hints;
567    }
568    virtual int getAndResetReleaseFenceFd() {
569        int fd = getLayer()->releaseFenceFd;
570        getLayer()->releaseFenceFd = -1;
571        return fd;
572    }
573    virtual void setAcquireFenceFd(int fenceFd) {
574        getLayer()->acquireFenceFd = fenceFd;
575    }
576
577    virtual void setDefaultState() {
578        getLayer()->compositionType = HWC_FRAMEBUFFER;
579        getLayer()->hints = 0;
580        getLayer()->flags = HWC_SKIP_LAYER;
581        getLayer()->transform = 0;
582        getLayer()->blending = HWC_BLENDING_NONE;
583        getLayer()->visibleRegionScreen.numRects = 0;
584        getLayer()->visibleRegionScreen.rects = NULL;
585        getLayer()->acquireFenceFd = -1;
586        getLayer()->releaseFenceFd = -1;
587    }
588    virtual void setSkip(bool skip) {
589        if (skip) {
590            getLayer()->flags |= HWC_SKIP_LAYER;
591        } else {
592            getLayer()->flags &= ~HWC_SKIP_LAYER;
593        }
594    }
595    virtual void setBlending(uint32_t blending) {
596        getLayer()->blending = blending;
597    }
598    virtual void setTransform(uint32_t transform) {
599        getLayer()->transform = transform;
600    }
601    virtual void setFrame(const Rect& frame) {
602        reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
603    }
604    virtual void setCrop(const Rect& crop) {
605        reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
606    }
607    virtual void setVisibleRegionScreen(const Region& reg) {
608        getLayer()->visibleRegionScreen.rects =
609                reinterpret_cast<hwc_rect_t const *>(
610                        reg.getArray(&getLayer()->visibleRegionScreen.numRects));
611    }
612    virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
613        if (buffer == 0 || buffer->handle == 0) {
614            getLayer()->compositionType = HWC_FRAMEBUFFER;
615            getLayer()->flags |= HWC_SKIP_LAYER;
616            getLayer()->handle = 0;
617        } else {
618            getLayer()->handle = buffer->handle;
619        }
620    }
621};
622
623/*
624 * returns an iterator initialized at a given index in the layer list
625 */
626HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) { // FIXME: handle multiple displays
627    if (!mHwc || index > hwcNumHwLayers(mHwc, mLists[0]))
628        return LayerListIterator();
629    if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
630        return LayerListIterator(new HWCLayerVersion1(mLists[0]->hwLayers),
631                index);
632    } else {
633        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);
634        return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index);
635    }
636}
637
638/*
639 * returns an iterator on the beginning of the layer list
640 */
641HWComposer::LayerListIterator HWComposer::begin(int32_t id) { // FIXME: handle multiple displays
642    return getLayerIterator(id, 0);
643}
644
645/*
646 * returns an iterator on the end of the layer list
647 */
648HWComposer::LayerListIterator HWComposer::end(int32_t id) { // FIXME: handle multiple displays
649    return getLayerIterator(id, getNumLayers(id));
650}
651
652void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
653        const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
654    if (mHwc) {
655        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);
656
657        result.append("Hardware Composer state:\n");
658        result.appendFormat("  mDebugForceFakeVSync=%d\n",
659                mDebugForceFakeVSync);
660        result.appendFormat("  numHwLayers=%u, flags=%08x\n",
661                hwcNumHwLayers(mHwc, mLists[0]), hwcFlags(mHwc, mLists[0]));
662        result.append(
663                "   type   |  handle  |   hints  |   flags  | tr | blend |  format  |       source crop         |           frame           name \n"
664                "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
665        //      " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
666        for (size_t i=0 ; i<hwcNumHwLayers(mHwc, mLists[0]) ; i++) {
667            hwc_layer_1_t const* lp;
668            if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
669                lp = &mLists[0]->hwLayers[i];
670            } else {
671                // FIXME: here we rely on hwc_layer_1_t and hwc_layer_t having the same layout
672                lp = reinterpret_cast<hwc_layer_1_t const*>(&list0->hwLayers[i]);
673            }
674            const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
675            int32_t format = -1;
676            if (layer->getLayer() != NULL) {
677                const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
678                if (buffer != NULL) {
679                    format = buffer->getPixelFormat();
680                }
681            }
682            const hwc_layer_1_t& l(*lp);
683            result.appendFormat(
684                    " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
685                    l.compositionType ? "OVERLAY" : "FB",
686                    intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
687                    l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
688                    l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
689                    layer->getName().string());
690        }
691    }
692    if (mHwc && hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_1) && mHwc->dump) {
693        mHwc->dump(mHwc, buffer, SIZE);
694        result.append(buffer);
695    }
696}
697
698// ---------------------------------------------------------------------------
699
700HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
701    : mHwc(hwc), mEnabled(false),
702      mNextFakeVSync(0),
703      mRefreshPeriod(hwc.mRefreshPeriod)
704{
705}
706
707void HWComposer::VSyncThread::setEnabled(bool enabled) {
708    Mutex::Autolock _l(mLock);
709    mEnabled = enabled;
710    mCondition.signal();
711}
712
713void HWComposer::VSyncThread::onFirstRef() {
714    run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
715}
716
717bool HWComposer::VSyncThread::threadLoop() {
718    { // scope for lock
719        Mutex::Autolock _l(mLock);
720        while (!mEnabled) {
721            mCondition.wait(mLock);
722        }
723    }
724
725    const nsecs_t period = mRefreshPeriod;
726    const nsecs_t now = systemTime(CLOCK_MONOTONIC);
727    nsecs_t next_vsync = mNextFakeVSync;
728    nsecs_t sleep = next_vsync - now;
729    if (sleep < 0) {
730        // we missed, find where the next vsync should be
731        sleep = (period - ((now - next_vsync) % period));
732        next_vsync = now + sleep;
733    }
734    mNextFakeVSync = next_vsync + period;
735
736    struct timespec spec;
737    spec.tv_sec  = next_vsync / 1000000000;
738    spec.tv_nsec = next_vsync % 1000000000;
739
740    int err;
741    do {
742        err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
743    } while (err<0 && errno == EINTR);
744
745    if (err == 0) {
746        mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
747    }
748
749    return true;
750}
751
752// ---------------------------------------------------------------------------
753}; // namespace android
754