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