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