Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e260874 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

Add a display parameter to HWComposer where needed

- also replace C casts with C++ casts
- only the interface is changed, HWComposer still doesn't
  fully handle multiple displays

Change-Id: I48eb89bff2edb76bf1d4d41f46802b9b2a7166a8
parent 28947d7f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@ public:
    int                     getOrientation() const { return mOrientation; }
    const Transform&        getTransform() const { return mGlobalTransform; }
    uint32_t                getLayerStack() const { return mLayerStack; }
    int32_t                 getDisplayId() const { return mId; }

    status_t compositionComplete() const;
    
+44 −36
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ static int hwcEventControl(hwc_composer_device_1_t* hwc, int dpy,
    if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
        return hwc->methods->eventControl(hwc, dpy, event, enabled);
    } else {
        hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc;
        hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
        return hwc0->methods->eventControl(hwc0, event, enabled);
    }
}
@@ -101,7 +101,7 @@ static int hwcBlank(hwc_composer_device_1_t* hwc, int dpy, int blank) {
        return hwc->methods->blank(hwc, dpy, blank);
    } else {
        if (blank) {
            hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc;
            hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
            return hwc0->set(hwc0, NULL, NULL, NULL);
        } else {
            // HWC 0.x turns the screen on at the next set()
@@ -115,8 +115,8 @@ static int hwcPrepare(hwc_composer_device_1_t* hwc,
    if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
        return hwc->prepare(hwc, numDisplays, displays);
    } else {
        hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc;
        hwc_layer_list_t* list0 = (hwc_layer_list_t*)displays[0];
        hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(displays[0]);
        // In the past, SurfaceFlinger would pass a NULL list when doing full
        // OpenGL ES composition. I don't know what, if any, dependencies there
        // are on this behavior, so I'm playing it safe and preserving it.
@@ -135,8 +135,8 @@ static int hwcSet(hwc_composer_device_1_t* hwc, EGLDisplay dpy, EGLSurface sur,
        displays[0]->sur = sur;
        err = hwc->set(hwc, numDisplays, displays);
    } else {
        hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc;
        hwc_layer_list_t* list0 = (hwc_layer_list_t*)displays[0];
        hwc_composer_device_t* hwc0 = reinterpret_cast<hwc_composer_device_t*>(hwc);
        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(displays[0]);
        err = hwc0->set(hwc0, dpy, sur, list0);
    }
    return err;
@@ -147,8 +147,7 @@ static uint32_t& hwcFlags(hwc_composer_device_1_t* hwc,
    if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
        return display->flags;
    } else {
        hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc;
        hwc_layer_list_t* list0 = (hwc_layer_list_t*)display;
        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(display);
        return list0->flags;
    }
}
@@ -158,8 +157,7 @@ static size_t& hwcNumHwLayers(hwc_composer_device_1_t* hwc,
    if (hwcHasVersion(hwc, HWC_DEVICE_API_VERSION_1_0)) {
        return display->numHwLayers;
    } else {
        hwc_composer_device_t* hwc0 = (hwc_composer_device_t*)hwc;
        hwc_layer_list_t* list0 = (hwc_layer_list_t*)display;
        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(display);
        return list0->numHwLayers;
    }
}
@@ -236,7 +234,7 @@ HWComposer::HWComposer(
            }

            // create initial empty display contents for display 0
            createWorkList(0);
            createWorkList(MAIN, 0);
        }
    }

@@ -332,8 +330,12 @@ void HWComposer::eventControl(int event, int enabled) {
    }
}

status_t HWComposer::createWorkList(size_t numLayers) {
status_t HWComposer::createWorkList(int32_t id, size_t numLayers) { // FIXME: handle multiple displays
    if (uint32_t(id) >= MAX_DISPLAYS)
        return BAD_INDEX;

    if (mHwc) {
        // TODO: must handle multiple displays here
        // mLists[0] is NULL only when this is called from the constructor
        if (!mLists[0] || mCapacity < numLayers) {
            free(mLists[0]);
@@ -356,21 +358,27 @@ status_t HWComposer::prepare() const {
    if (err == NO_ERROR) {
        size_t numOVLayers = 0;
        size_t numFBLayers = 0;
        size_t count = getNumLayers();
        size_t count = getNumLayers(0);

        for (size_t i=0 ; i<count ; i++) {
            hwc_layer_1_t* l = NULL;
            int compositionType;
            if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
                l = &mLists[0]->hwLayers[i];
                hwc_layer_1_t* l = &mLists[0]->hwLayers[i];
                if (l->flags & HWC_SKIP_LAYER) {
                    l->compositionType = HWC_FRAMEBUFFER;
                }
                compositionType = l->compositionType;
            } else {
                // mList really has hwc_layer_list_t memory layout
                hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0];
                hwc_layer_t* layer = &list0->hwLayers[i];
                l = (hwc_layer_1_t*)layer;
            }
                hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);
                hwc_layer_t* l = &list0->hwLayers[i];
                if (l->flags & HWC_SKIP_LAYER) {
                    l->compositionType = HWC_FRAMEBUFFER;
                }
            switch (l->compositionType) {
                compositionType = l->compositionType;
            }

            switch (compositionType) {
                case HWC_OVERLAY:
                    numOVLayers++;
                    break;
@@ -385,7 +393,7 @@ status_t HWComposer::prepare() const {
    return (status_t)err;
}

size_t HWComposer::getLayerCount(int type) const {
size_t HWComposer::getLayerCount(int32_t id, int type) const { // FIXME: handle multiple displays
    switch (type) {
        case HWC_OVERLAY:
            return mNumOVLayers;
@@ -437,7 +445,7 @@ status_t HWComposer::disable() {
    return NO_ERROR;
}

size_t HWComposer::getNumLayers() const {
size_t HWComposer::getNumLayers(int32_t id) const { // FIXME: handle multiple displays
    return mHwc ? hwcNumHwLayers(mHwc, mLists[0]) : 0;
}

@@ -611,14 +619,14 @@ public:
/*
 * returns an iterator initialized at a given index in the layer list
 */
HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) {
HWComposer::LayerListIterator HWComposer::getLayerIterator(int32_t id, size_t index) { // FIXME: handle multiple displays
    if (index > hwcNumHwLayers(mHwc, mLists[0]))
        return LayerListIterator();
    if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
        return LayerListIterator(new HWCLayerVersion1(mLists[0]->hwLayers),
                index);
    } else {
        hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0];
        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);
        return LayerListIterator(new HWCLayerVersion0(list0->hwLayers), index);
    }
}
@@ -626,21 +634,21 @@ HWComposer::LayerListIterator HWComposer::getLayerIterator(size_t index) {
/*
 * returns an iterator on the beginning of the layer list
 */
HWComposer::LayerListIterator HWComposer::begin() {
    return getLayerIterator(0);
HWComposer::LayerListIterator HWComposer::begin(int32_t id) { // FIXME: handle multiple displays
    return getLayerIterator(id, 0);
}

/*
 * returns an iterator on the end of the layer list
 */
HWComposer::LayerListIterator HWComposer::end() {
    return getLayerIterator(getNumLayers());
HWComposer::LayerListIterator HWComposer::end(int32_t id) { // FIXME: handle multiple displays
    return getLayerIterator(id, getNumLayers(id));
}

void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
        const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const {
    if (mHwc) {
        hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0];
        hwc_layer_list_t* list0 = reinterpret_cast<hwc_layer_list_t*>(mLists[0]);

        result.append("Hardware Composer state:\n");
        result.appendFormat("  mDebugForceFakeVSync=%d\n",
@@ -652,13 +660,12 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
                "----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
        //      " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
        for (size_t i=0 ; i<hwcNumHwLayers(mHwc, mLists[0]) ; i++) {
            hwc_layer_1_t l;
            hwc_layer_1_t const* lp;
            if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
                l = mLists[0]->hwLayers[i];
                lp = &mLists[0]->hwLayers[i];
            } else {
                hwc_layer_list_t* list0 = (hwc_layer_list_t*)mLists[0];
                *(hwc_layer_t*)&l = list0->hwLayers[i];
                l.acquireFenceFd = l.releaseFenceFd = -1;
                // FIXME: here we rely on hwc_layer_1_t and hwc_layer_t having the same layout
                lp = reinterpret_cast<hwc_layer_1_t const*>(&list0->hwLayers[i]);
            }
            const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
            int32_t format = -1;
@@ -668,6 +675,7 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
                    format = buffer->getPixelFormat();
                }
            }
            const hwc_layer_1_t& l(*lp);
            result.appendFormat(
                    " %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
                    l.compositionType ? "OVERLAY" : "FB",
+14 −9
Original line number Diff line number Diff line
@@ -56,6 +56,12 @@ public:
        virtual ~EventHandler() {}
    };

    enum {
        MAIN = 0,
        HDMI = 1,
        MAX_DISPLAYS
    };

    HWComposer(const sp<SurfaceFlinger>& flinger, EventHandler& handler);
    ~HWComposer();

@@ -77,14 +83,11 @@ public:
    status_t acquire() const;

    // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED.
    status_t createWorkList(size_t numLayers);

    // get the layer array created by createWorkList()
    size_t getNumLayers() const;
    status_t createWorkList(int32_t id, size_t numLayers);

    // get number of layers of the given type as updated in prepare().
    // type is HWC_OVERLAY or HWC_FRAMEBUFFER
    size_t getLayerCount(int type) const;
    size_t getLayerCount(int32_t id, int type) const;

    // needed forward declarations
    class LayerListIterator;
@@ -175,10 +178,10 @@ public:
    };

    // Returns an iterator to the beginning of the layer list
    LayerListIterator begin();
    LayerListIterator begin(int32_t id);

    // Returns an iterator to the end of the layer list
    LayerListIterator end();
    LayerListIterator end(int32_t id);


    // Events handling ---------------------------------------------------------
@@ -215,9 +218,9 @@ public:
            const Vector< sp<LayerBase> >& visibleLayersSortedByZ) const;

private:
    enum { MAX_DISPLAYS = 1 };

    LayerListIterator getLayerIterator(size_t index);
    LayerListIterator getLayerIterator(int32_t id, size_t index);
    size_t getNumLayers(int32_t id) const;

    struct cb_context;

@@ -227,6 +230,7 @@ private:
    inline void invalidate();
    inline void vsync(int dpy, int64_t timestamp);


    sp<SurfaceFlinger>              mFlinger;
    hw_module_t const*              mModule;
    struct hwc_composer_device_1*   mHwc;
@@ -234,6 +238,7 @@ private:
    // TODO: decide whether mLists[i>0] should be non-NULL when display i is
    //       not attached/enabled.
    struct hwc_display_contents_1*  mLists[MAX_DISPLAYS];

    size_t                          mCapacity;
    mutable size_t                  mNumOVLayers;
    mutable size_t                  mNumFBLayers;
+31 −27
Original line number Diff line number Diff line
@@ -454,8 +454,8 @@ bool SurfaceFlinger::authenticateSurfaceTexture(
}

status_t SurfaceFlinger::getDisplayInfo(DisplayID dpy, DisplayInfo* info) {
    // TODO: this is here only for compatibility -- show go away eventually.
    if (uint32_t(dpy) >= 2) {
    // TODO: this is here only for compatibility -- should go away eventually.
    if (uint32_t(dpy) >= 1) {
        return BAD_INDEX;
    }
    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
@@ -628,10 +628,10 @@ void SurfaceFlinger::handleMessageRefresh() {
            const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
            const size_t count = currentLayers.size();

            hwc.createWorkList(count); // FIXME: the worklist should include enough space for all layer of all displays

            HWComposer::LayerListIterator cur = hwc.begin();
            const HWComposer::LayerListIterator end = hwc.end();
            const int32_t id = hw->getDisplayId();
            if (hwc.createWorkList(id, count) >= 0) {
                HWComposer::LayerListIterator cur = hwc.begin(id);
                const HWComposer::LayerListIterator end = hwc.end(id);
                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
                    const sp<LayerBase>& layer(currentLayers[i]);

@@ -649,6 +649,7 @@ void SurfaceFlinger::handleMessageRefresh() {
                    layer->setPerFrameData(hw, *cur);
                }
            }
        }
        status_t err = hwc.prepare();
        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
    }
@@ -738,8 +739,9 @@ void SurfaceFlinger::postFramebuffer()
        if (hwc.initCheck() == NO_ERROR) {
            const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
            const size_t count = currentLayers.size();
            HWComposer::LayerListIterator cur = hwc.begin();
            const HWComposer::LayerListIterator end = hwc.end();
            const int32_t id = hw->getDisplayId();
            HWComposer::LayerListIterator cur = hwc.begin(id);
            const HWComposer::LayerListIterator end = hwc.end(id);
            for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
                const sp<LayerBase>& layer(currentLayers[i]);
                layer->setAcquireFence(hw, *cur);
@@ -759,8 +761,9 @@ void SurfaceFlinger::postFramebuffer()
        const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
        const size_t count = currentLayers.size();
        if (hwc.initCheck() == NO_ERROR) {
            HWComposer::LayerListIterator cur = hwc.begin();
            const HWComposer::LayerListIterator end = hwc.end();
            int32_t id = hw->getDisplayId();
            HWComposer::LayerListIterator cur = hwc.begin(id);
            const HWComposer::LayerListIterator end = hwc.end(id);
            for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
                currentLayers[i]->onLayerDisplayed(hw, &*cur);
            }
@@ -1152,10 +1155,11 @@ void SurfaceFlinger::handleRepaint(const sp<const DisplayDevice>& hw,
void SurfaceFlinger::composeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
{
    HWComposer& hwc(getHwComposer());
    HWComposer::LayerListIterator cur = hwc.begin();
    const HWComposer::LayerListIterator end = hwc.end();
    int32_t id = hw->getDisplayId();
    HWComposer::LayerListIterator cur = hwc.begin(id);
    const HWComposer::LayerListIterator end = hwc.end(id);

    const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);  // FIXME: this should be per display
    const size_t fbLayerCount = hwc.getLayerCount(id, HWC_FRAMEBUFFER);
    if (cur==end || fbLayerCount) {

        DisplayDevice::makeCurrent(hw, mEGLContext);
@@ -1165,7 +1169,7 @@ void SurfaceFlinger::composeSurfaces(const sp<const DisplayDevice>& hw, const Re
        glLoadIdentity();

        // Never touch the framebuffer if we don't have any framebuffer layers
        if (hwc.getLayerCount(HWC_OVERLAY)) { // FIXME: this should be per display
        if (hwc.getLayerCount(id, HWC_OVERLAY)) {
            // when using overlays, we assume a fully transparent framebuffer
            // NOTE: we could reduce how much we need to clear, for instance
            // remove where there are opaque FB layers. however, on some