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

Commit fb47d839 authored by Romain Guy's avatar Romain Guy Committed by The Android Automerger
Browse files

Prevent crash when a single layer is enqueued several times for updates

Bug #8504687

Change-Id: I9b01bbc4e3f37af23dfe5e68d3d03ad3d238b94a
parent cd93fb98
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -158,6 +158,9 @@ void Layer::defer() {
            dirtyRect.right, dirtyRect.bottom, !isBlend());

    displayList->defer(deferredState, 0);

    deferredUpdateScheduled = false;
    displayList = NULL;
}

void Layer::flush() {
@@ -176,5 +179,21 @@ void Layer::flush() {
    }
}

void Layer::render() {
    renderer->setViewport(layer.getWidth(), layer.getHeight());
    renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
            !isBlend());

    renderer->drawDisplayList(displayList, dirtyRect, DisplayList::kReplayFlag_ClipChildren);

    renderer->finish();
    renderer = NULL;

    dirtyRect.setEmpty();

    deferredUpdateScheduled = false;
    displayList = NULL;
}

}; // namespace uirenderer
}; // namespace android
+1 −0
Original line number Diff line number Diff line
@@ -275,6 +275,7 @@ struct Layer {

    void defer();
    void flush();
    void render();

    /**
     * Bounds of the layer.
+16 −19
Original line number Diff line number Diff line
@@ -540,13 +540,7 @@ bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) {
        }

        if (CC_UNLIKELY(inFrame || mCaches.drawDeferDisabled)) {
            OpenGLRenderer* renderer = layer->renderer;
            renderer->setViewport(layer->layer.getWidth(), layer->layer.getHeight());
            renderer->prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom,
                    !layer->isBlend());
            renderer->drawDisplayList(layer->displayList, dirty,
                    DisplayList::kReplayFlag_ClipChildren);
            renderer->finish();
            layer->render();
        } else {
            layer->defer();
        }
@@ -556,13 +550,6 @@ bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) {
            startTiling(mSnapshot);
        }

        if (CC_UNLIKELY(inFrame || mCaches.drawDeferDisabled)) {
            dirty.setEmpty();
            layer->renderer = NULL;
        }

        layer->deferredUpdateScheduled = false;
        layer->displayList = NULL;
        layer->debugDrawUpdate = mCaches.debugLayersUpdates;

        return true;
@@ -609,11 +596,12 @@ void OpenGLRenderer::flushLayers() {
        // Note: it is very important to update the layers in reverse order
        for (int i = count - 1; i >= 0; i--) {
            sprintf(layerName, "Layer #%d", i);
            startMark(layerName); {
            startMark(layerName);

            Layer* layer = mLayerUpdates.itemAt(i);
            layer->flush();
            mCaches.resourceCache.decrementRefcount(layer);
            }

            endMark();
        }

@@ -626,6 +614,15 @@ void OpenGLRenderer::flushLayers() {

void OpenGLRenderer::pushLayerUpdate(Layer* layer) {
    if (layer) {
        // Make sure we don't introduce duplicates.
        // SortedVector would do this automatically but we need to respect
        // the insertion order. The linear search is not an issue since
        // this list is usually very short (typically one item, at most a few)
        for (int i = mLayerUpdates.size() - 1; i >= 0; i--) {
            if (mLayerUpdates.itemAt(i) == layer) {
                return;
            }
        }
        mLayerUpdates.push_back(layer);
        mCaches.resourceCache.incrementRefcount(layer);
    }