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

Commit ac3c64a0 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 5760827 from f076c019 to qt-qpr1-release

Change-Id: I97b86a6695b4118715706f896da6754a91ce20f1
parents ca045778 f076c019
Loading
Loading
Loading
Loading
+5 −4
Original line number Original line Diff line number Diff line
@@ -575,10 +575,11 @@ String8 ProgramCache::generateFragmentShader(const Key& needs) {
            float applyCornerRadius(vec2 cropCoords)
            float applyCornerRadius(vec2 cropCoords)
            {
            {
                vec2 position = cropCoords - cropCenter;
                vec2 position = cropCoords - cropCenter;
                // Increase precision here so that a large corner radius doesn't
                // Scale down the dist vector here, as otherwise large corner
                // cause floating point error
                // radii can cause floating point issues when computing the norm
                highp vec2 dist = abs(position) + vec2(cornerRadius) - cropCenter;
                vec2 dist = (abs(position) - cropCenter + vec2(cornerRadius)) / 16.0;
                float plane = length(max(dist, vec2(0.0)));
                // Once we've found the norm, then scale back up.
                float plane = length(max(dist, vec2(0.0))) * 16.0;
                return 1.0 - clamp(plane - cornerRadius, 0.0, 1.0);
                return 1.0 - clamp(plane - cornerRadius, 0.0, 1.0);
            }
            }
            )__SHADER__";
            )__SHADER__";
+9 −0
Original line number Original line Diff line number Diff line
@@ -369,6 +369,15 @@ const Region& BufferLayerConsumer::getSurfaceDamage() const {
    return mCurrentSurfaceDamage;
    return mCurrentSurfaceDamage;
}
}


void BufferLayerConsumer::mergeSurfaceDamage(const Region& damage) {
    if (damage.bounds() == Rect::INVALID_RECT ||
        mCurrentSurfaceDamage.bounds() == Rect::INVALID_RECT) {
        mCurrentSurfaceDamage = Region::INVALID_REGION;
    } else {
        mCurrentSurfaceDamage |= damage;
    }
}

int BufferLayerConsumer::getCurrentApi() const {
int BufferLayerConsumer::getCurrentApi() const {
    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);
    return mCurrentApi;
    return mCurrentApi;
+3 −0
Original line number Original line Diff line number Diff line
@@ -140,6 +140,9 @@ public:
    // must be called from SF main thread
    // must be called from SF main thread
    const Region& getSurfaceDamage() const;
    const Region& getSurfaceDamage() const;


    // Merge the given damage region into the current damage region value.
    void mergeSurfaceDamage(const Region& damage);

    // getCurrentApi retrieves the API which queues the current buffer.
    // getCurrentApi retrieves the API which queues the current buffer.
    int getCurrentApi() const;
    int getCurrentApi() const;


+2 −0
Original line number Original line Diff line number Diff line
@@ -316,6 +316,7 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t
        // and return early
        // and return early
        if (queuedBuffer) {
        if (queuedBuffer) {
            Mutex::Autolock lock(mQueueItemLock);
            Mutex::Autolock lock(mQueueItemLock);
            mConsumer->mergeSurfaceDamage(mQueueItems[0].mSurfaceDamage);
            mFlinger->mTimeStats->removeTimeRecord(layerID, mQueueItems[0].mFrameNumber);
            mFlinger->mTimeStats->removeTimeRecord(layerID, mQueueItems[0].mFrameNumber);
            mQueueItems.removeAt(0);
            mQueueItems.removeAt(0);
            mQueuedFrames--;
            mQueuedFrames--;
@@ -351,6 +352,7 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t
        // Remove any stale buffers that have been dropped during
        // Remove any stale buffers that have been dropped during
        // updateTexImage
        // updateTexImage
        while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
        while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
            mConsumer->mergeSurfaceDamage(mQueueItems[0].mSurfaceDamage);
            mFlinger->mTimeStats->removeTimeRecord(layerID, mQueueItems[0].mFrameNumber);
            mFlinger->mTimeStats->removeTimeRecord(layerID, mQueueItems[0].mFrameNumber);
            mQueueItems.removeAt(0);
            mQueueItems.removeAt(0);
            mQueuedFrames--;
            mQueuedFrames--;
+94 −0
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@


#include <binder/ProcessState.h>
#include <binder/ProcessState.h>
#include <gui/BufferItemConsumer.h>
#include <gui/BufferItemConsumer.h>
#include <gui/IProducerListener.h>
#include <gui/ISurfaceComposer.h>
#include <gui/ISurfaceComposer.h>
#include <gui/LayerState.h>
#include <gui/LayerState.h>
#include <gui/Surface.h>
#include <gui/Surface.h>
@@ -6059,4 +6060,97 @@ TEST_F(RelativeZTest, LayerRemovedOffscreenRelativeParent) {
    }
    }
}
}


// This test ensures that when we drop an app buffer in SurfaceFlinger, we merge
// the dropped buffer's damage region into the next buffer's damage region. If
// we don't do this, we'll report an incorrect damage region to hardware
// composer, resulting in broken rendering. This test checks the BufferQueue
// case.
//
// Unfortunately, we don't currently have a way to inspect the damage region
// SurfaceFlinger sends to hardware composer from a test, so this test requires
// the dev to manually watch the device's screen during the test to spot broken
// rendering. Because the results can't be automatically verified, this test is
// marked disabled.
TEST_F(LayerTransactionTest, DISABLED_BufferQueueLayerMergeDamageRegionWhenDroppingBuffers) {
    const int width = mDisplayWidth;
    const int height = mDisplayHeight;
    sp<SurfaceControl> layer;
    ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", width, height));
    const auto producer = layer->getIGraphicBufferProducer();
    const sp<IProducerListener> dummyListener(new DummyProducerListener);
    IGraphicBufferProducer::QueueBufferOutput queueBufferOutput;
    ASSERT_EQ(OK,
              producer->connect(dummyListener, NATIVE_WINDOW_API_CPU, true, &queueBufferOutput));

    std::map<int, sp<GraphicBuffer>> slotMap;
    auto slotToBuffer = [&](int slot, sp<GraphicBuffer>* buf) {
        ASSERT_NE(nullptr, buf);
        const auto iter = slotMap.find(slot);
        ASSERT_NE(slotMap.end(), iter);
        *buf = iter->second;
    };

    auto dequeue = [&](int* outSlot) {
        ASSERT_NE(nullptr, outSlot);
        *outSlot = -1;
        int slot;
        sp<Fence> fence;
        uint64_t age;
        FrameEventHistoryDelta timestamps;
        const status_t dequeueResult =
                producer->dequeueBuffer(&slot, &fence, width, height, PIXEL_FORMAT_RGBA_8888,
                                        GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
                                        &age, &timestamps);
        if (dequeueResult == IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
            sp<GraphicBuffer> newBuf;
            ASSERT_EQ(OK, producer->requestBuffer(slot, &newBuf));
            ASSERT_NE(nullptr, newBuf.get());
            slotMap[slot] = newBuf;
        } else {
            ASSERT_EQ(OK, dequeueResult);
        }
        *outSlot = slot;
    };

    auto queue = [&](int slot, const Region& damage, nsecs_t displayTime) {
        IGraphicBufferProducer::QueueBufferInput input(
                /*timestamp=*/displayTime, /*isAutoTimestamp=*/false, HAL_DATASPACE_UNKNOWN,
                /*crop=*/Rect::EMPTY_RECT, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW,
                /*transform=*/0, Fence::NO_FENCE);
        input.setSurfaceDamage(damage);
        IGraphicBufferProducer::QueueBufferOutput output;
        ASSERT_EQ(OK, producer->queueBuffer(slot, input, &output));
    };

    auto fillAndPostBuffers = [&](const Color& color) {
        int slot1;
        ASSERT_NO_FATAL_FAILURE(dequeue(&slot1));
        int slot2;
        ASSERT_NO_FATAL_FAILURE(dequeue(&slot2));

        sp<GraphicBuffer> buf1;
        ASSERT_NO_FATAL_FAILURE(slotToBuffer(slot1, &buf1));
        sp<GraphicBuffer> buf2;
        ASSERT_NO_FATAL_FAILURE(slotToBuffer(slot2, &buf2));
        fillGraphicBufferColor(buf1, Rect(width, height), color);
        fillGraphicBufferColor(buf2, Rect(width, height), color);

        const auto displayTime = systemTime() + milliseconds_to_nanoseconds(100);
        ASSERT_NO_FATAL_FAILURE(queue(slot1, Region::INVALID_REGION, displayTime));
        ASSERT_NO_FATAL_FAILURE(
                queue(slot2, Region(Rect(width / 3, height / 3, 2 * width / 3, 2 * height / 3)),
                      displayTime));
    };

    const auto startTime = systemTime();
    const std::array<Color, 3> colors = {Color::RED, Color::GREEN, Color::BLUE};
    int colorIndex = 0;
    while (nanoseconds_to_seconds(systemTime() - startTime) < 10) {
        ASSERT_NO_FATAL_FAILURE(fillAndPostBuffers(colors[colorIndex++ % colors.size()]));
        std::this_thread::sleep_for(1s);
    }

    ASSERT_EQ(OK, producer->disconnect(NATIVE_WINDOW_API_CPU));
}

} // namespace android
} // namespace android