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

Commit b643c59b authored by Brian Lindahl's avatar Brian Lindahl Committed by Automerger Merge Worker
Browse files

Merge "Increase frame history size when SF buffer queue size changes" into udc-dev am: ca910afe

parents e990e42f ca910afe
Loading
Loading
Loading
Loading
+42 −3
Original line number Original line Diff line number Diff line
@@ -139,6 +139,11 @@ void BLASTBufferItemConsumer::onSidebandStreamChanged() {
    }
    }
}
}


void BLASTBufferItemConsumer::resizeFrameEventHistory(size_t newSize) {
    Mutex::Autolock lock(mMutex);
    mFrameEventHistory.resize(newSize);
}

BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinationFrame)
BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinationFrame)
      : mSurfaceControl(nullptr),
      : mSurfaceControl(nullptr),
        mSize(1, 1),
        mSize(1, 1),
@@ -1069,8 +1074,9 @@ public:
// can be non-blocking when the producer is in the client process.
// can be non-blocking when the producer is in the client process.
class BBQBufferQueueProducer : public BufferQueueProducer {
class BBQBufferQueueProducer : public BufferQueueProducer {
public:
public:
    BBQBufferQueueProducer(const sp<BufferQueueCore>& core)
    BBQBufferQueueProducer(const sp<BufferQueueCore>& core, wp<BLASTBufferQueue> bbq)
          : BufferQueueProducer(core, false /* consumerIsSurfaceFlinger*/) {}
          : BufferQueueProducer(core, false /* consumerIsSurfaceFlinger*/),
            mBLASTBufferQueue(std::move(bbq)) {}


    status_t connect(const sp<IProducerListener>& listener, int api, bool producerControlledByApp,
    status_t connect(const sp<IProducerListener>& listener, int api, bool producerControlledByApp,
                     QueueBufferOutput* output) override {
                     QueueBufferOutput* output) override {
@@ -1082,6 +1088,26 @@ public:
                                            producerControlledByApp, output);
                                            producerControlledByApp, output);
    }
    }


    // We want to resize the frame history when changing the size of the buffer queue
    status_t setMaxDequeuedBufferCount(int maxDequeuedBufferCount) override {
        int maxBufferCount;
        status_t status = BufferQueueProducer::setMaxDequeuedBufferCount(maxDequeuedBufferCount,
                                                                         &maxBufferCount);
        // if we can't determine the max buffer count, then just skip growing the history size
        if (status == OK) {
            size_t newFrameHistorySize = maxBufferCount + 2; // +2 because triple buffer rendering
            // optimize away resizing the frame history unless it will grow
            if (newFrameHistorySize > FrameEventHistory::INITIAL_MAX_FRAME_HISTORY) {
                sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
                if (bbq != nullptr) {
                    ALOGV("increasing frame history size to %zu", newFrameHistorySize);
                    bbq->resizeFrameEventHistory(newFrameHistorySize);
                }
            }
        }
        return status;
    }

    int query(int what, int* value) override {
    int query(int what, int* value) override {
        if (what == NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER) {
        if (what == NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER) {
            *value = 1;
            *value = 1;
@@ -1089,6 +1115,9 @@ public:
        }
        }
        return BufferQueueProducer::query(what, value);
        return BufferQueueProducer::query(what, value);
    }
    }

private:
    const wp<BLASTBufferQueue> mBLASTBufferQueue;
};
};


// Similar to BufferQueue::createBufferQueue but creates an adapter specific bufferqueue producer.
// Similar to BufferQueue::createBufferQueue but creates an adapter specific bufferqueue producer.
@@ -1103,7 +1132,7 @@ void BLASTBufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer
    sp<BufferQueueCore> core(new BufferQueueCore());
    sp<BufferQueueCore> core(new BufferQueueCore());
    LOG_ALWAYS_FATAL_IF(core == nullptr, "BLASTBufferQueue: failed to create BufferQueueCore");
    LOG_ALWAYS_FATAL_IF(core == nullptr, "BLASTBufferQueue: failed to create BufferQueueCore");


    sp<IGraphicBufferProducer> producer(new BBQBufferQueueProducer(core));
    sp<IGraphicBufferProducer> producer(new BBQBufferQueueProducer(core, this));
    LOG_ALWAYS_FATAL_IF(producer == nullptr,
    LOG_ALWAYS_FATAL_IF(producer == nullptr,
                        "BLASTBufferQueue: failed to create BBQBufferQueueProducer");
                        "BLASTBufferQueue: failed to create BBQBufferQueueProducer");


@@ -1116,6 +1145,16 @@ void BLASTBufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer
    *outConsumer = consumer;
    *outConsumer = consumer;
}
}


void BLASTBufferQueue::resizeFrameEventHistory(size_t newSize) {
    // This can be null during creation of the buffer queue, but resizing won't do anything at that
    // point in time, so just ignore. This can go away once the class relationships and lifetimes of
    // objects are cleaned up with a major refactor of BufferQueue as a whole.
    if (mBufferItemConsumer != nullptr) {
        std::unique_lock _lock{mMutex};
        mBufferItemConsumer->resizeFrameEventHistory(newSize);
    }
}

PixelFormat BLASTBufferQueue::convertBufferFormat(PixelFormat& format) {
PixelFormat BLASTBufferQueue::convertBufferFormat(PixelFormat& format) {
    PixelFormat convertedFormat = format;
    PixelFormat convertedFormat = format;
    switch (format) {
    switch (format) {
+9 −0
Original line number Original line Diff line number Diff line
@@ -119,6 +119,12 @@ status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {


status_t BufferQueueProducer::setMaxDequeuedBufferCount(
status_t BufferQueueProducer::setMaxDequeuedBufferCount(
        int maxDequeuedBuffers) {
        int maxDequeuedBuffers) {
    int maxBufferCount;
    return setMaxDequeuedBufferCount(maxDequeuedBuffers, &maxBufferCount);
}

status_t BufferQueueProducer::setMaxDequeuedBufferCount(int maxDequeuedBuffers,
                                                        int* maxBufferCount) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("setMaxDequeuedBufferCount: maxDequeuedBuffers = %d",
    BQ_LOGV("setMaxDequeuedBufferCount: maxDequeuedBuffers = %d",
            maxDequeuedBuffers);
            maxDequeuedBuffers);
@@ -134,6 +140,8 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount(
            return NO_INIT;
            return NO_INIT;
        }
        }


        *maxBufferCount = mCore->getMaxBufferCountLocked();

        if (maxDequeuedBuffers == mCore->mMaxDequeuedBufferCount) {
        if (maxDequeuedBuffers == mCore->mMaxDequeuedBufferCount) {
            return NO_ERROR;
            return NO_ERROR;
        }
        }
@@ -183,6 +191,7 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount(
            return BAD_VALUE;
            return BAD_VALUE;
        }
        }
        mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers;
        mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers;
        *maxBufferCount = mCore->getMaxBufferCountLocked();
        VALIDATE_CONSISTENCY();
        VALIDATE_CONSISTENCY();
        if (delta < 0) {
        if (delta < 0) {
            listener = mCore->mConsumerListener;
            listener = mCore->mConsumerListener;
+106 −9
Original line number Original line Diff line number Diff line
@@ -168,10 +168,11 @@ struct FrameNumberEqual {


}  // namespace
}  // namespace


const size_t FrameEventHistory::MAX_FRAME_HISTORY =
const size_t FrameEventHistory::INITIAL_MAX_FRAME_HISTORY =
        sysprop::LibGuiProperties::frame_event_history_size().value_or(8);
        sysprop::LibGuiProperties::frame_event_history_size().value_or(8);


FrameEventHistory::FrameEventHistory() : mFrames(std::vector<FrameEvents>(MAX_FRAME_HISTORY)) {}
FrameEventHistory::FrameEventHistory()
      : mFrames(std::vector<FrameEvents>(INITIAL_MAX_FRAME_HISTORY)) {}


FrameEventHistory::~FrameEventHistory() = default;
FrameEventHistory::~FrameEventHistory() = default;


@@ -227,7 +228,6 @@ void FrameEventHistory::dump(std::string& outString) const {
    }
    }
}
}



// ============================================================================
// ============================================================================
// ProducerFrameEventHistory
// ProducerFrameEventHistory
// ============================================================================
// ============================================================================
@@ -273,6 +273,13 @@ void ProducerFrameEventHistory::applyDelta(
        const FrameEventHistoryDelta& delta) {
        const FrameEventHistoryDelta& delta) {
    mCompositorTiming = delta.mCompositorTiming;
    mCompositorTiming = delta.mCompositorTiming;


    // Deltas should have enough reserved capacity for the consumer-side, therefore if there's a
    // different capacity, we re-sized on the consumer side and now need to resize on the producer
    // side.
    if (delta.mDeltas.capacity() > mFrames.capacity()) {
        resize(delta.mDeltas.capacity());
    }

    for (auto& d : delta.mDeltas) {
    for (auto& d : delta.mDeltas) {
        // Avoid out-of-bounds access.
        // Avoid out-of-bounds access.
        if (CC_UNLIKELY(d.mIndex >= mFrames.size())) {
        if (CC_UNLIKELY(d.mIndex >= mFrames.size())) {
@@ -349,13 +356,48 @@ std::shared_ptr<FenceTime> ProducerFrameEventHistory::createFenceTime(
    return std::make_shared<FenceTime>(fence);
    return std::make_shared<FenceTime>(fence);
}
}


void ProducerFrameEventHistory::resize(size_t newSize) {
    // we don't want to drop events by resizing too small, so don't resize in the negative direction
    if (newSize <= mFrames.size()) {
        return;
    }

    // This algorithm for resizing needs to be the same as ConsumerFrameEventHistory::resize,
    // because the indexes need to match when communicating the FrameEventDeltas.

    // We need to find the oldest frame, because that frame needs to move to index 0 in the new
    // frame history.
    size_t oldestFrameIndex = 0;
    size_t oldestFrameNumber = INT32_MAX;
    for (size_t i = 0; i < mFrames.size(); ++i) {
        if (mFrames[i].frameNumber < oldestFrameNumber && mFrames[i].valid) {
            oldestFrameNumber = mFrames[i].frameNumber;
            oldestFrameIndex = i;
        }
    }

    // move the existing frame information into a new vector, so that the oldest frames are at
    // index 0, and the latest frames are at the end of the vector
    std::vector<FrameEvents> newFrames(newSize);
    size_t oldI = oldestFrameIndex;
    size_t newI = 0;
    do {
        if (mFrames[oldI].valid) {
            newFrames[newI++] = std::move(mFrames[oldI]);
        }
        oldI = (oldI + 1) % mFrames.size();
    } while (oldI != oldestFrameIndex);

    mFrames = std::move(newFrames);
    mAcquireOffset = 0; // this is just a hint, so setting this to anything is fine
}


// ============================================================================
// ============================================================================
// ConsumerFrameEventHistory
// ConsumerFrameEventHistory
// ============================================================================
// ============================================================================


ConsumerFrameEventHistory::ConsumerFrameEventHistory()
ConsumerFrameEventHistory::ConsumerFrameEventHistory()
      : mFramesDirty(std::vector<FrameEventDirtyFields>(MAX_FRAME_HISTORY)) {}
      : mFramesDirty(std::vector<FrameEventDirtyFields>(INITIAL_MAX_FRAME_HISTORY)) {}


ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;
ConsumerFrameEventHistory::~ConsumerFrameEventHistory() = default;


@@ -489,6 +531,36 @@ void ConsumerFrameEventHistory::getAndResetDelta(
    }
    }
}
}


void ConsumerFrameEventHistory::resize(size_t newSize) {
    // we don't want to drop events by resizing too small, so don't resize in the negative direction
    if (newSize <= mFrames.size()) {
        return;
    }

    // This algorithm for resizing needs to be the same as ProducerFrameEventHistory::resize,
    // because the indexes need to match when communicating the FrameEventDeltas.

    // move the existing frame information into a new vector, so that the oldest frames are at
    // index 0, and the latest frames are towards the end of the vector
    std::vector<FrameEvents> newFrames(newSize);
    std::vector<FrameEventDirtyFields> newFramesDirty(newSize);
    size_t oldestFrameIndex = mQueueOffset;
    size_t oldI = oldestFrameIndex;
    size_t newI = 0;
    do {
        if (mFrames[oldI].valid) {
            newFrames[newI] = std::move(mFrames[oldI]);
            newFramesDirty[newI] = mFramesDirty[oldI];
            newI += 1;
        }
        oldI = (oldI + 1) % mFrames.size();
    } while (oldI != oldestFrameIndex);

    mFrames = std::move(newFrames);
    mFramesDirty = std::move(newFramesDirty);
    mQueueOffset = newI;
    mCompositionOffset = 0; // this is just a hint, so setting this to anything is fine
}


// ============================================================================
// ============================================================================
// FrameEventsDelta
// FrameEventsDelta
@@ -558,8 +630,7 @@ status_t FrameEventsDelta::flatten(void*& buffer, size_t& size, int*& fds,
        return NO_MEMORY;
        return NO_MEMORY;
    }
    }


    if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY ||
    if (mIndex >= UINT8_MAX || mIndex < 0) {
            mIndex > std::numeric_limits<uint16_t>::max()) {
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }


@@ -601,7 +672,7 @@ status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
    uint16_t temp16 = 0;
    uint16_t temp16 = 0;
    FlattenableUtils::read(buffer, size, temp16);
    FlattenableUtils::read(buffer, size, temp16);
    mIndex = temp16;
    mIndex = temp16;
    if (mIndex >= FrameEventHistory::MAX_FRAME_HISTORY) {
    if (mIndex >= UINT8_MAX) {
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }
    uint8_t temp8 = 0;
    uint8_t temp8 = 0;
@@ -627,6 +698,25 @@ status_t FrameEventsDelta::unflatten(void const*& buffer, size_t& size,
    return NO_ERROR;
    return NO_ERROR;
}
}


uint64_t FrameEventsDelta::getFrameNumber() const {
    return mFrameNumber;
}

bool FrameEventsDelta::getLatchTime(nsecs_t* latchTime) const {
    if (mLatchTime == FrameEvents::TIMESTAMP_PENDING) {
        return false;
    }
    *latchTime = mLatchTime;
    return true;
}

bool FrameEventsDelta::getDisplayPresentFence(sp<Fence>* fence) const {
    if (mDisplayPresentFence.fence == Fence::NO_FENCE) {
        return false;
    }
    *fence = mDisplayPresentFence.fence;
    return true;
}


// ============================================================================
// ============================================================================
// FrameEventHistoryDelta
// FrameEventHistoryDelta
@@ -665,7 +755,7 @@ size_t FrameEventHistoryDelta::getFdCount() const {


status_t FrameEventHistoryDelta::flatten(
status_t FrameEventHistoryDelta::flatten(
            void*& buffer, size_t& size, int*& fds, size_t& count) const {
            void*& buffer, size_t& size, int*& fds, size_t& count) const {
    if (mDeltas.size() > FrameEventHistory::MAX_FRAME_HISTORY) {
    if (mDeltas.size() > UINT8_MAX) {
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }
    if (size < getFlattenedSize()) {
    if (size < getFlattenedSize()) {
@@ -695,7 +785,7 @@ status_t FrameEventHistoryDelta::unflatten(


    uint32_t deltaCount = 0;
    uint32_t deltaCount = 0;
    FlattenableUtils::read(buffer, size, deltaCount);
    FlattenableUtils::read(buffer, size, deltaCount);
    if (deltaCount > FrameEventHistory::MAX_FRAME_HISTORY) {
    if (deltaCount > UINT8_MAX) {
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }
    mDeltas.resize(deltaCount);
    mDeltas.resize(deltaCount);
@@ -708,5 +798,12 @@ status_t FrameEventHistoryDelta::unflatten(
    return NO_ERROR;
    return NO_ERROR;
}
}


std::vector<FrameEventsDelta>::const_iterator FrameEventHistoryDelta::begin() const {
    return mDeltas.begin();
}

std::vector<FrameEventsDelta>::const_iterator FrameEventHistoryDelta::end() const {
    return mDeltas.end();
}


} // namespace android
} // namespace android
+4 −11
Original line number Original line Diff line number Diff line
@@ -725,12 +725,7 @@ status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
    // These were written as uint8_t for alignment.
    // These were written as uint8_t for alignment.
    uint8_t temp = 0;
    uint8_t temp = 0;
    FlattenableUtils::read(buffer, size, temp);
    FlattenableUtils::read(buffer, size, temp);
    size_t index = static_cast<size_t>(temp);
    t->index = static_cast<uint32_t>(temp);
    if (index >= ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
        return BAD_VALUE;
    }
    t->index = static_cast<uint32_t>(index);

    FlattenableUtils::read(buffer, size, temp);
    FlattenableUtils::read(buffer, size, temp);
    t->addPostCompositeCalled = static_cast<bool>(temp);
    t->addPostCompositeCalled = static_cast<bool>(temp);
    FlattenableUtils::read(buffer, size, temp);
    FlattenableUtils::read(buffer, size, temp);
@@ -786,8 +781,7 @@ status_t unflatten(HGraphicBufferProducer::FrameEventsDelta* t,
status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
        void*& buffer, size_t& size, int*& fds, size_t numFds) {
        void*& buffer, size_t& size, int*& fds, size_t numFds) {
    // Check that t.index is within a valid range.
    // Check that t.index is within a valid range.
    if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY)
    if (t.index > UINT8_MAX || t.index < 0) {
            || t.index > std::numeric_limits<uint8_t>::max()) {
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }


@@ -887,8 +881,7 @@ status_t unflatten(


    uint32_t deltaCount = 0;
    uint32_t deltaCount = 0;
    FlattenableUtils::read(buffer, size, deltaCount);
    FlattenableUtils::read(buffer, size, deltaCount);
    if (static_cast<size_t>(deltaCount) >
    if (deltaCount > UINT8_MAX) {
            ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }
    t->deltas.resize(deltaCount);
    t->deltas.resize(deltaCount);
@@ -919,7 +912,7 @@ status_t unflatten(
status_t flatten(
status_t flatten(
        HGraphicBufferProducer::FrameEventHistoryDelta const& t,
        HGraphicBufferProducer::FrameEventHistoryDelta const& t,
        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
    if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
    if (t.deltas.size() > UINT8_MAX) {
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }
    if (size < getFlattenedSize(t)) {
    if (size < getFlattenedSize(t)) {
+2 −3
Original line number Original line Diff line number Diff line
@@ -725,8 +725,7 @@ inline status_t flatten(HGraphicBufferProducer::FrameEventsDelta const& t,
        std::vector<native_handle_t*>* nh,
        std::vector<native_handle_t*>* nh,
        void*& buffer, size_t& size, int*& fds, size_t numFds) {
        void*& buffer, size_t& size, int*& fds, size_t numFds) {
    // Check that t.index is within a valid range.
    // Check that t.index is within a valid range.
    if (t.index >= static_cast<uint32_t>(FrameEventHistory::MAX_FRAME_HISTORY)
    if (t.index > UINT8_MAX || t.index < 0) {
            || t.index > std::numeric_limits<uint8_t>::max()) {
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }


@@ -829,7 +828,7 @@ inline status_t flatten(
        HGraphicBufferProducer::FrameEventHistoryDelta const& t,
        HGraphicBufferProducer::FrameEventHistoryDelta const& t,
        std::vector<std::vector<native_handle_t*> >* nh,
        std::vector<std::vector<native_handle_t*> >* nh,
        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
        void*& buffer, size_t& size, int*& fds, size_t& numFds) {
    if (t.deltas.size() > ::android::FrameEventHistory::MAX_FRAME_HISTORY) {
    if (t.deltas.size() > UINT8_MAX) {
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }
    if (size < getFlattenedSize(t)) {
    if (size < getFlattenedSize(t)) {
Loading