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