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

Commit 411df880 authored by Mathias Agopian's avatar Mathias Agopian Committed by Android Git Automerger
Browse files

am 1f432b19: am b7d1be01: Merge "Fix a couple issues with the new hwcomposer HAL" into gingerbread

Merge commit '1f432b19203b86a2b4da825943024c5b01eaeb60'

* commit '1f432b19203b86a2b4da825943024c5b01eaeb60':
  Fix a couple issues with the new hwcomposer HAL
parents 69033cd9 5e9615ea
Loading
Loading
Loading
Loading
+12 −9
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ namespace android {
// ---------------------------------------------------------------------------

HWComposer::HWComposer()
    : mModule(0), mHwc(0), mList(0),
    : mModule(0), mHwc(0), mList(0), mCapacity(0),
      mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
{
    int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
@@ -63,10 +63,13 @@ void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) {
}

status_t HWComposer::createWorkList(size_t numLayers) {
    if (mHwc && (!mList || mList->numHwLayers < numLayers)) {
    if (mHwc) {
        if (!mList || mCapacity < numLayers) {
            free(mList);
            size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t);
            mList = (hwc_layer_list_t*)malloc(size);
            mCapacity = numLayers;
        }
        mList->flags = HWC_GEOMETRY_CHANGED;
        mList->numHwLayers = numLayers;
    }
@@ -84,12 +87,12 @@ status_t HWComposer::commit() const {
    return (status_t)err;
}

HWComposer::iterator HWComposer::begin() {
    return mList ? &(mList->hwLayers[0]) : NULL;
size_t HWComposer::getNumLayers() const {
    return mList ? mList->numHwLayers : 0;
}

HWComposer::iterator HWComposer::end() {
    return mList ? &(mList->hwLayers[mList->numHwLayers]) : NULL;
hwc_layer_t* HWComposer::getLayers() const {
    return mList ? mList->hwLayers : 0;
}

// ---------------------------------------------------------------------------
+3 −5
Original line number Diff line number Diff line
@@ -49,16 +49,14 @@ public:
    status_t commit() const;


    typedef hwc_layer_t const * const_iterator;
    typedef hwc_layer_t* iterator;

    iterator begin();
    iterator end();
    size_t getNumLayers() const;
    hwc_layer_t* getLayers() const;

private:
    hw_module_t const*      mModule;
    hwc_composer_device_t*  mHwc;
    hwc_layer_list_t*       mList;
    size_t                  mCapacity;
    hwc_display_t           mDpy;
    hwc_surface_t           mSur;
};
+47 −35
Original line number Diff line number Diff line
@@ -755,10 +755,9 @@ void SurfaceFlinger::handleWorkList()
        const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
        const size_t count = currentLayers.size();
        hwc.createWorkList(count);
        HWComposer::iterator cur(hwc.begin());
        HWComposer::iterator last(hwc.end());
        for (size_t i=0 ; (i<count) && (cur!=last) ; ++i, ++cur) {
            currentLayers[i]->setGeometry(cur);
        hwc_layer_t* const cur(hwc.getLayers());
        for (size_t i=0 ; cur && i<count ; i++) {
            currentLayers[i]->setGeometry(&cur[i]);
        }
    }
}
@@ -829,47 +828,41 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)

    status_t err = NO_ERROR;
    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
    const size_t count = layers.size();
    size_t count = layers.size();

    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    HWComposer& hwc(hw.getHwComposer());
    HWComposer::iterator cur(hwc.begin());
    HWComposer::iterator last(hwc.end());
    hwc_layer_t* const cur(hwc.getLayers());

    // update the per-frame h/w composer data for each layer
    if (cur != last) {
        for (size_t i=0 ; i<count && cur!=last ; ++i, ++cur) {
            layers[i]->setPerFrameData(cur);
        }
        err = hwc.prepare();
        LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
    }
    LOGE_IF(cur && hwc.getNumLayers() != count,
            "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
            hwc.getNumLayers(), count);

    // and then, render the layers targeted at the framebuffer
    Region transparent(hw.bounds());
    for (size_t i=0 ; i<count ; ++i) {
    // just to be extra-safe, use the smallest count
    count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();

        // see if we need to skip this layer
        if (!err && cur != last) {
            if (!((cur->compositionType == HWC_FRAMEBUFFER) ||
                    (cur->flags & HWC_SKIP_LAYER))) {
                ++cur;
                continue;
    /*
     *  update the per-frame h/w composer data for each layer
     *  and build the transparent region of the FB
     */
    Region transparent;
    if (cur) {
        for (size_t i=0 ; i<count ; i++) {
            const sp<LayerBase>& layer(layers[i]);
            layer->setPerFrameData(&cur[i]);
            if (cur[i].hints & HWC_HINT_CLEAR_FB) {
                if (!(layer->needsBlending())) {
                    transparent.orSelf(layer->visibleRegionScreen);
                }
            ++cur;
            }

        // draw the layer into the framebuffer
        const sp<LayerBase>& layer(layers[i]);
        transparent.subtractSelf(layer->visibleRegionScreen);
        const Region clip(dirty.intersect(layer->visibleRegionScreen));
        if (!clip.isEmpty()) {
            layer->draw(clip);
        }
        err = hwc.prepare();
        LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
    }

    // finally clear everything we didn't draw as a result of calling
    // prepare (this leaves the FB transparent).
    /*
     *  clear the area of the FB that need to be transparent
     */
    transparent.andSelf(dirty);
    if (!transparent.isEmpty()) {
        glClearColor(0,0,0,0);
@@ -883,6 +876,25 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
            glClear(GL_COLOR_BUFFER_BIT);
        }
    }


    /*
     * and then, render the layers targeted at the framebuffer
     */
    for (size_t i=0 ; i<count ; i++) {
        if (cur) {
            if (!(cur[i].compositionType == HWC_FRAMEBUFFER) ||
                    cur[i].flags & HWC_SKIP_LAYER) {
                // skip layers handled by the HAL
                continue;
            }
        }
        const sp<LayerBase>& layer(layers[i]);
        const Region clip(dirty.intersect(layer->visibleRegionScreen));
        if (!clip.isEmpty()) {
            layer->draw(clip);
        }
    }
}

void SurfaceFlinger::unlockClients()