HWComposer.cpp revision 748f3df66f6695681cde44461e2548e6e1dbc1bb
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    : mFlinger(flinger),
184      mModule(0), mHwc(0), mCapacity(0),
185      mNumOVLayers(0), mNumFBLayers(0),
186      mCBContext(new cb_context),
187      mEventHandler(handler), mRefreshPeriod(0),
188      mVSyncCount(0), mDebugForceFakeVSync(false)
189{
190    for (size_t i = 0; i < MAX_DISPLAYS; i++)
191        mLists[i] = NULL;
192
193    char value[PROPERTY_VALUE_MAX];
194    property_get("debug.sf.no_hw_vsync", value, "0");
195    mDebugForceFakeVSync = atoi(value);
196
197    bool needVSyncThread = true;
198    int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
199    ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
200    if (err == 0) {
201        err = hwc_open_1(mModule, &mHwc);
202        ALOGE_IF(err, "%s device failed to initialize (%s)",
203                HWC_HARDWARE_COMPOSER, strerror(-err));
204        if (err == 0) {
205            if (HWC_REMOVE_DEPRECATED_VERSIONS &&
206                    mHwc->common.version < HWC_DEVICE_API_VERSION_1_0) {
207                ALOGE("%s device version %#x too old, will not be used",
208                        HWC_HARDWARE_COMPOSER, mHwc->common.version);
209                hwc_close_1(mHwc);
210                mHwc = NULL;
211            }
212        }
213
214        if (mHwc) {
215            // always turn vsync off when we start
216            needVSyncThread = false;
217            if (hwcHasVsyncEvent(mHwc)) {
218                hwcEventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
219
220                int period;
221                if (mHwc->query(mHwc, HWC_VSYNC_PERIOD, &period) == NO_ERROR) {
222                    mRefreshPeriod = nsecs_t(period);
223                }
224            } else {
225                needVSyncThread = true;
226            }
227
228            if (mHwc->registerProcs) {
229                mCBContext->hwc = this;
230                mCBContext->procs.invalidate = &hook_invalidate;
231                mCBContext->procs.vsync = &hook_vsync;
232                mHwc->registerProcs(mHwc, &mCBContext->procs);
233                memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));
234            }
235
236            // create initial empty display contents for display 0
237            createWorkList(MAIN, 0);
238        }
239    }
240
241    if (mRefreshPeriod == 0) {
242        // for compatibility, we attempt to get the refresh rate from
243        // the FB HAL if we couldn't get it from the HWC HAL.
244        hw_module_t const* module;
245        if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
246            framebuffer_device_t* fbDev;
247            int err = framebuffer_open(module, &fbDev);
248            if (!err && fbDev) {
249                mRefreshPeriod = nsecs_t(1e9 / fbDev->fps);
250                framebuffer_close(fbDev);
251            }
252        }
253        ALOGW("getting VSYNC period from fb HAL: %lld", mRefreshPeriod);
254    }
255
256    if (mRefreshPeriod == 0) {
257        mRefreshPeriod = nsecs_t(1e9 / 60.0);
258        ALOGW("getting VSYNC period thin air: %lld", mRefreshPeriod);
259    }
260
261    if (needVSyncThread) {
262        // we don't have VSYNC support, we need to fake it
263        mVSyncThread = new VSyncThread(*this);
264    }
265}
266
267HWComposer::~HWComposer() {
268    hwcEventControl(mHwc, 0, EVENT_VSYNC, 0);
269    for (size_t i = 0; i < MAX_DISPLAYS; i++)
270        free(mLists[i]);
271    if (mVSyncThread != NULL) {
272        mVSyncThread->requestExitAndWait();
273    }
274    if (mHwc) {
275        hwc_close_1(mHwc);
276    }
277    delete mCBContext;
278}
279
280status_t HWComposer::initCheck() const {
281    return mHwc ? NO_ERROR : NO_INIT;
282}
283
284void HWComposer::hook_invalidate(struct hwc_procs* procs) {
285    reinterpret_cast<cb_context *>(procs)->hwc->invalidate();
286}
287
288void HWComposer::hook_vsync(struct hwc_procs* procs, int dpy, int64_t timestamp) {
289    reinterpret_cast<cb_context *>(procs)->hwc->vsync(dpy, timestamp);
290}
291
292void HWComposer::invalidate() {
293    mFlinger->repaintEverything();
294}
295
296void HWComposer::vsync(int dpy, int64_t timestamp) {
297    ATRACE_INT("VSYNC", ++mVSyncCount&1);
298    mEventHandler.onVSyncReceived(dpy, timestamp);
299    Mutex::Autolock _l(mLock);
300    mLastHwVSync = timestamp;
301}
302
303nsecs_t HWComposer::getRefreshPeriod() const {
304    return mRefreshPeriod;
305}
306
307nsecs_t HWComposer::getRefreshTimestamp() const {
308    // this returns the last refresh timestamp.
309    // if the last one is not available, we estimate it based on
310    // the refresh period and whatever closest timestamp we have.
311    Mutex::Autolock _l(mLock);
312    nsecs_t now = systemTime(CLOCK_MONOTONIC);
313    return now - ((now - mLastHwVSync) %  mRefreshPeriod);
314}
315
316void HWComposer::eventControl(int event, int enabled) {
317    status_t err = NO_ERROR;
318    if (mHwc && mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
319        if (!mDebugForceFakeVSync) {
320            err = hwcEventControl(mHwc, 0, event, enabled);
321            // error here should not happen -- not sure what we should
322            // do if it does.
323            ALOGE_IF(err, "eventControl(%d, %d) failed %s",
324                    event, enabled, strerror(-err));
325        }
326    }
327
328    if (err == NO_ERROR && mVSyncThread != NULL) {
329        mVSyncThread->setEnabled(enabled);
330    }
331}
332
333status_t HWComposer::createWorkList(int32_t id, size_t numLayers) { // FIXME: handle multiple displays
334    if (uint32_t(id) >= MAX_DISPLAYS)
335        return BAD_INDEX;
336
337    if (mHwc) {
338        // TODO: must handle multiple displays here
339        // mLists[0] is NULL only when this is called from the constructor
340        if (!mLists[0] || mCapacity < numLayers) {
341            free(mLists[0]);
342            size_t size = sizeofHwcLayerList(mHwc, numLayers);
343            mLists[0] = (hwc_display_contents_1_t*)malloc(size);
344            mCapacity = numLayers;
345        }
346        hwcFlags(mHwc, mLists[0]) = HWC_GEOMETRY_CHANGED;
347        hwcNumHwLayers(mHwc, mLists[0]) = numLayers;
348        if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
349            mLists[0]->flipFenceFd = -1;
350        }
351    }
352    return NO_ERROR;
353}
354
355status_t HWComposer::prepare() const {
356    int err = hwcPrepare(mHwc, 1,
357            const_cast<hwc_display_contents_1_t**>(mLists));
358    if (err == NO_ERROR) {
359        size_t numOVLayers = 0;
360        size_t numFBLayers = 0;
361        size_t count = getNumLayers(0);
362
363        for (size_t i=0 ; i<count ; i++) {
364            int compositionType;
365            if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
366                hwc_layer_1_t* l = &mLists[0]->hwLayers[i];
367                if (l->flags & HWC_SKIP_LAYER) {
368                    l->compositionType = HWC_FRAMEBUFFER;
369                }
370                compositionType = l->compositionType;
371            } else {
372                // mList really has hwc_layer_list_t memory layout
373                hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);
374                hwc_layer_t* l = &list0->hwLayers[i];
375                if (l->flags & HWC_SKIP_LAYER) {
376                    l->compositionType = HWC_FRAMEBUFFER;
377                }
378                compositionType = l->compositionType;
379            }
380
381            switch (compositionType) {
382                case HWC_OVERLAY:
383                    numOVLayers++;
384                    break;
385                case HWC_FRAMEBUFFER:
386                    numFBLayers++;
387                    break;
388            }
389        }
390        mNumOVLayers = numOVLayers;
391        mNumFBLayers = numFBLayers;
392    }
393    return (status_t)err;
394}
395
396size_t HWComposer::getLayerCount(int32_t id, int type) const { // FIXME: handle multiple displays
397    switch (type) {
398        case HWC_OVERLAY:
399            return mNumOVLayers;
400        case HWC_FRAMEBUFFER:
401            return mNumFBLayers;
402    }
403    return 0;
404}
405
406status_t HWComposer::commit(void* fbDisplay, void* fbSurface) const {
407    int err = NO_ERROR;
408    if (mHwc) {
409        err = hwcSet(mHwc, fbDisplay, fbSurface, 1,
410                const_cast<hwc_display_contents_1_t**>(mLists));
411        if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
412            if (mLists[0]->flipFenceFd != -1) {
413                close(mLists[0]->flipFenceFd);
414                mLists[0]->flipFenceFd = -1;
415            }
416        }
417        hwcFlags(mHwc, mLists[0]) &= ~HWC_GEOMETRY_CHANGED;
418    }
419    return (status_t)err;
420}
421
422status_t HWComposer::release() const {
423    if (mHwc) {
424        if (hwcHasVsyncEvent(mHwc)) {
425            hwcEventControl(mHwc, 0, HWC_EVENT_VSYNC, 0);
426        }
427        return (status_t)hwcBlank(mHwc, 0, 1);
428    }
429    return NO_ERROR;
430}
431
432status_t HWComposer::acquire() const {
433    if (mHwc) {
434        return (status_t)hwcBlank(mHwc, 0, 0);
435    }
436    return NO_ERROR;
437}
438
439status_t HWComposer::disable() {
440    if (mHwc) {
441        hwcNumHwLayers(mHwc, mLists[0]) = 0;
442        int err = hwcPrepare(mHwc, 1, mLists);
443        return (status_t)err;
444    }
445    return NO_ERROR;
446}
447
448size_t HWComposer::getNumLayers(int32_t id) const { // FIXME: handle multiple displays
449    return mHwc ? hwcNumHwLayers(mHwc, mLists[0]) : 0;
450}
451
452/*
453 * Helper template to implement a concrete HWCLayer
454 * This holds the pointer to the concrete hwc layer type
455 * and implements the "iterable" side of HWCLayer.
456 */
457template<typename CONCRETE, typename HWCTYPE>
458class Iterable : public HWComposer::HWCLayer {
459protected:
460    HWCTYPE* const mLayerList;
461    HWCTYPE* mCurrentLayer;
462    Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer) { }
463    inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
464    inline HWCTYPE* getLayer() { return mCurrentLayer; }
465    virtual ~Iterable() { }
466private:
467    // returns a copy of ourselves
468    virtual HWComposer::HWCLayer* dup() {
469        return new CONCRETE( static_cast<const CONCRETE&>(*this) );
470    }
471    virtual status_t setLayer(size_t index) {
472        mCurrentLayer = &mLayerList[index];
473        return NO_ERROR;
474    }
475};
476
477// #if !HWC_REMOVE_DEPRECATED_VERSIONS
478/*
479 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_0_3
480 * This implements the HWCLayer side of HWCIterableLayer.
481 */
482class HWCLayerVersion0 : public Iterable<HWCLayerVersion0, hwc_layer_t> {
483public:
484    HWCLayerVersion0(hwc_layer_t* layer)
485        : Iterable<HWCLayerVersion0, hwc_layer_t>(layer) { }
486
487    virtual int32_t getCompositionType() const {
488        return getLayer()->compositionType;
489    }
490    virtual uint32_t getHints() const {
491        return getLayer()->hints;
492    }
493    virtual int getAndResetReleaseFenceFd() {
494        // not supported on VERSION_03
495        return -1;
496    }
497    virtual void setAcquireFenceFd(int fenceFd) {
498        if (fenceFd != -1) {
499            ALOGE("HWC 0.x can't handle acquire fences");
500            close(fenceFd);
501        }
502    }
503
504    virtual void setDefaultState() {
505        getLayer()->compositionType = HWC_FRAMEBUFFER;
506        getLayer()->hints = 0;
507        getLayer()->flags = HWC_SKIP_LAYER;
508        getLayer()->transform = 0;
509        getLayer()->blending = HWC_BLENDING_NONE;
510        getLayer()->visibleRegionScreen.numRects = 0;
511        getLayer()->visibleRegionScreen.rects = NULL;
512    }
513    virtual void setSkip(bool skip) {
514        if (skip) {
515            getLayer()->flags |= HWC_SKIP_LAYER;
516        } else {
517            getLayer()->flags &= ~HWC_SKIP_LAYER;
518        }
519    }
520    virtual void setBlending(uint32_t blending) {
521        getLayer()->blending = blending;
522    }
523    virtual void setTransform(uint32_t transform) {
524        getLayer()->transform = transform;
525    }
526    virtual void setFrame(const Rect& frame) {
527        reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
528    }
529    virtual void setCrop(const Rect& crop) {
530        reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
531    }
532    virtual void setVisibleRegionScreen(const Region& reg) {
533        getLayer()->visibleRegionScreen.rects =
534                reinterpret_cast<hwc_rect_t const *>(
535                        reg.getArray(&getLayer()->visibleRegionScreen.numRects));
536    }
537    virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
538        if (buffer == 0 || buffer->handle == 0) {
539            getLayer()->compositionType = HWC_FRAMEBUFFER;
540            getLayer()->flags |= HWC_SKIP_LAYER;
541            getLayer()->handle = 0;
542        } else {
543            getLayer()->handle = buffer->handle;
544        }
545    }
546};
547// #endif // !HWC_REMOVE_DEPRECATED_VERSIONS
548
549/*
550 * Concrete implementation of HWCLayer for HWC_DEVICE_API_VERSION_1_0.
551 * This implements the HWCLayer side of HWCIterableLayer.
552 */
553class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> {
554public:
555    HWCLayerVersion1(hwc_layer_1_t* layer)
556        : Iterable<HWCLayerVersion1, hwc_layer_1_t>(layer) { }
557
558    virtual int32_t getCompositionType() const {
559        return getLayer()->compositionType;
560    }
561    virtual uint32_t getHints() const {
562        return getLayer()->hints;
563    }
564    virtual int getAndResetReleaseFenceFd() {
565        int fd = getLayer()->releaseFenceFd;
566        getLayer()->releaseFenceFd = -1;
567        return fd;
568    }
569    virtual void setAcquireFenceFd(int fenceFd) {
570        getLayer()->acquireFenceFd = fenceFd;
571    }
572
573    virtual void setDefaultState() {
574        getLayer()->compositionType = HWC_FRAMEBUFFER;
575        getLayer()->hints = 0;
576        getLayer()->flags = HWC_SKIP_LAYER;
577        getLayer()->transform = 0;
578        getLayer()->blending = HWC_BLENDING_NONE;
579        getLayer()->visibleRegionScreen.numRects = 0;
580        getLayer()->visibleRegionScreen.rects = NULL;
581        getLayer()->acquireFenceFd = -1;
582        getLayer()->releaseFenceFd = -1;
583    }
584    virtual void setSkip(bool skip) {
585        if (skip) {
586            getLayer()->flags |= HWC_SKIP_LAYER;
587        } else {
588            getLayer()->flags &= ~HWC_SKIP_LAYER;
589        }
590    }
591    virtual void setBlending(uint32_t blending) {
592        getLayer()->blending = blending;
593    }
594    virtual void setTransform(uint32_t transform) {
595        getLayer()->transform = transform;
596    }
597    virtual void setFrame(const Rect& frame) {
598        reinterpret_cast<Rect&>(getLayer()->displayFrame) = frame;
599    }
600    virtual void setCrop(const Rect& crop) {
601        reinterpret_cast<Rect&>(getLayer()->sourceCrop) = crop;
602    }
603    virtual void setVisibleRegionScreen(const Region& reg) {
604        getLayer()->visibleRegionScreen.rects =
605                reinterpret_cast<hwc_rect_t const *>(
606                        reg.getArray(&getLayer()->visibleRegionScreen.numRects));
607    }
608    virtual void setBuffer(const sp<GraphicBuffer>& buffer) {
609        if (buffer == 0 || buffer->handle == 0) {
610            getLayer()->compositionType = HWC_FRAMEBUFFER;
611            getLayer()->flags |= HWC_SKIP_LAYER;
612            getLayer()->handle = 0;
613        } else {
614            getLayer()->handle = buffer->handle;
615        }
616    }
617};
618
619/*
620 * returns an iterator initialized at a given index in the layer list
621 */
622HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) { // FIXME: handle multiple displays
623    if (!mHwc || index > hwcNumHwLayers(mHwc, mLists[0]))
624        return LayerListIterator();
625    if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
626        return LayerListIterator(new HWCLayerVersion1(mLists[0]->hwLayers),
627                index);
628    } else {
629        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);
630        return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index);
631    }
632}
633
634/*
635 * returns an iterator on the beginning of the layer list
636 */
637HWComposer::LayerListIterator HWComposer::begin(int32_t id) { // FIXME: handle multiple displays
638    return getLayerIterator(id, 0);
639}
640
641/*
642 * returns an iterator on the end of the layer list
643 */
644HWComposer::LayerListIterator HWComposer::end(int32_t id) { // FIXME: handle multiple displays
645    return getLayerIterator(id, getNumLayers(id));
646}
647
648void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
649        const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
650    if (mHwc) {
651        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);
652
653        result.append("Hardware Composer state:\n");
654        result.appendFormat("  mDebugForceFakeVSync=%d\n",
655                mDebugForceFakeVSync);
656        result.appendFormat("  numHwLayers=%u, flags=%08x\n",
657                hwcNumHwLayers(mHwc, mLists[0]), hwcFlags(mHwc, mLists[0]));
658        result.append(
659                "   type   |  handle  |   hints  |   flags  | tr | blend |  format  |       source crop         |           frame           name \n"
660                "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
661        //      " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
662        for (size_t i=0 ; i<hwcNumHwLayers(mHwc, mLists[0]) ; i++) {
663            hwc_layer_1_t const* lp;
664            if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
665                lp = &mLists[0]->hwLayers[i];
666            } else {
667                // FIXME: here we rely on hwc_layer_1_t and hwc_layer_t having the same layout
668                lp = reinterpret_cast<hwc_layer_1_t const*>(&list0->hwLayers[i]);
669            }
670            const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
671            int32_t format = -1;
672            if (layer->getLayer() != NULL) {
673                const sp<GraphicBuffer>& buffer(layer->getLayer()->getActiveBuffer());
674                if (buffer != NULL) {
675                    format = buffer->getPixelFormat();
676                }
677            }
678            const hwc_layer_1_t& l(*lp);
679            result.appendFormat(
680                    " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
681                    l.compositionType ? "OVERLAY" : "FB",
682                    intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
683                    l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
684                    l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
685                    layer->getName().string());
686        }
687    }
688    if (mHwc && hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_0_1) && mHwc->dump) {
689        mHwc->dump(mHwc, buffer, SIZE);
690        result.append(buffer);
691    }
692}
693
694// ---------------------------------------------------------------------------
695
696HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
697    : mHwc(hwc), mEnabled(false),
698      mNextFakeVSync(0),
699      mRefreshPeriod(hwc.mRefreshPeriod)
700{
701}
702
703void HWComposer::VSyncThread::setEnabled(bool enabled) {
704    Mutex::Autolock _l(mLock);
705    mEnabled = enabled;
706    mCondition.signal();
707}
708
709void HWComposer::VSyncThread::onFirstRef() {
710    run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
711}
712
713bool HWComposer::VSyncThread::threadLoop() {
714    { // scope for lock
715        Mutex::Autolock _l(mLock);
716        while (!mEnabled) {
717            mCondition.wait(mLock);
718        }
719    }
720
721    const nsecs_t period = mRefreshPeriod;
722    const nsecs_t now = systemTime(CLOCK_MONOTONIC);
723    nsecs_t next_vsync = mNextFakeVSync;
724    nsecs_t sleep = next_vsync - now;
725    if (sleep < 0) {
726        // we missed, find where the next vsync should be
727        sleep = (period - ((now - next_vsync) % period));
728        next_vsync = now + sleep;
729    }
730    mNextFakeVSync = next_vsync + period;
731
732    struct timespec spec;
733    spec.tv_sec  = next_vsync / 1000000000;
734    spec.tv_nsec = next_vsync % 1000000000;
735
736    int err;
737    do {
738        err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
739    } while (err<0 && errno == EINTR);
740
741    if (err == 0) {
742        mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
743    }
744
745    return true;
746}
747
748// ---------------------------------------------------------------------------
749}; // namespace android
750