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

Commit a02e9484 authored by Eric Penner's avatar Eric Penner Committed by Android (Google) Code Review
Browse files

Merge "SurfaceFlinger: Prevent deadlock by updating an atomic layer set." into lmp-dev

parents 68fd9e71 51c59cd1
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -281,6 +281,11 @@ public:
     */
    Rect getContentCrop() const;

    /*
     * Returns if a frame is queued.
     */
    bool hasQueuedFrame() const { return mQueuedFrames > 0; }

    // -----------------------------------------------------------------------

    void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
+17 −2
Original line number Diff line number Diff line
@@ -1636,9 +1636,24 @@ void SurfaceFlinger::handlePageFlip()

    bool visibleRegions = false;
    const LayerVector& layers(mDrawingState.layersSortedByZ);
    const size_t count = layers.size();
    for (size_t i=0 ; i<count ; i++) {

    // Store the set of layers that need updates. This set must not change as
    // buffers are being latched, as this could result in a deadlock.
    // Example: Two producers share the same command stream and:
    // 1.) Layer 0 is latched
    // 2.) Layer 0 gets a new frame
    // 2.) Layer 1 gets a new frame
    // 3.) Layer 1 is latched.
    // Display is now waiting on Layer 1's frame, which is behind layer 0's
    // second frame. But layer 0's second frame could be waiting on display.
    Vector<Layer*> layersWithQueuedFrames;
    for (size_t i = 0, count = layers.size(); i<count ; i++) {
        const sp<Layer>& layer(layers[i]);
        if (layer->hasQueuedFrame())
            layersWithQueuedFrames.push_back(layer.get());
    }
    for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {
        Layer* layer = layersWithQueuedFrames[i];
        const Region dirty(layer->latchBuffer(visibleRegions));
        const Layer::State& s(layer->getDrawingState());
        invalidateLayerStack(s.layerStack, dirty);