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

Commit 6ae55032 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Convert Mutex to std::mutex in BufferQueueCore/Producer/Consumer

Bug: 111517695
Change-Id: I1226ed7396d0d768a26f4145af5fe48e2c70e8d2
parent 8ef26834
Loading
Loading
Loading
Loading
+25 −25
Original line number Original line Diff line number Diff line
@@ -58,7 +58,7 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
    int numDroppedBuffers = 0;
    int numDroppedBuffers = 0;
    sp<IProducerListener> listener;
    sp<IProducerListener> listener;
    {
    {
        Mutex::Autolock lock(mCore->mMutex);
        std::unique_lock<std::mutex> lock(mCore->mMutex);


        // Check that the consumer doesn't currently have the maximum number of
        // Check that the consumer doesn't currently have the maximum number of
        // buffers acquired. We allow the max buffer count to be exceeded by one
        // buffers acquired. We allow the max buffer count to be exceeded by one
@@ -203,7 +203,7 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,


        if (sharedBufferAvailable && mCore->mQueue.empty()) {
        if (sharedBufferAvailable && mCore->mQueue.empty()) {
            // make sure the buffer has finished allocating before acquiring it
            // make sure the buffer has finished allocating before acquiring it
            mCore->waitWhileAllocatingLocked();
            mCore->waitWhileAllocatingLocked(lock);


            slot = mCore->mSharedBufferSlot;
            slot = mCore->mSharedBufferSlot;


@@ -264,7 +264,7 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
        // We might have freed a slot while dropping old buffers, or the producer
        // We might have freed a slot while dropping old buffers, or the producer
        // may be blocked waiting for the number of buffers in the queue to
        // may be blocked waiting for the number of buffers in the queue to
        // decrease.
        // decrease.
        mCore->mDequeueCondition.broadcast();
        mCore->mDequeueCondition.notify_all();


        ATRACE_INT(mCore->mConsumerName.string(),
        ATRACE_INT(mCore->mConsumerName.string(),
                static_cast<int32_t>(mCore->mQueue.size()));
                static_cast<int32_t>(mCore->mQueue.size()));
@@ -286,7 +286,7 @@ status_t BufferQueueConsumer::detachBuffer(int slot) {
    ATRACE_CALL();
    ATRACE_CALL();
    ATRACE_BUFFER_INDEX(slot);
    ATRACE_BUFFER_INDEX(slot);
    BQ_LOGV("detachBuffer: slot %d", slot);
    BQ_LOGV("detachBuffer: slot %d", slot);
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);


    if (mCore->mIsAbandoned) {
    if (mCore->mIsAbandoned) {
        BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
        BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
@@ -312,7 +312,7 @@ status_t BufferQueueConsumer::detachBuffer(int slot) {
    mCore->mActiveBuffers.erase(slot);
    mCore->mActiveBuffers.erase(slot);
    mCore->mFreeSlots.insert(slot);
    mCore->mFreeSlots.insert(slot);
    mCore->clearBufferSlotLocked(slot);
    mCore->clearBufferSlotLocked(slot);
    mCore->mDequeueCondition.broadcast();
    mCore->mDequeueCondition.notify_all();
    VALIDATE_CONSISTENCY();
    VALIDATE_CONSISTENCY();


    return NO_ERROR;
    return NO_ERROR;
@@ -330,7 +330,7 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot,
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }


    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);


    if (mCore->mSharedBufferMode) {
    if (mCore->mSharedBufferMode) {
        BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
        BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
@@ -422,7 +422,7 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,


    sp<IProducerListener> listener;
    sp<IProducerListener> listener;
    { // Autolock scope
    { // Autolock scope
        Mutex::Autolock lock(mCore->mMutex);
        std::lock_guard<std::mutex> lock(mCore->mMutex);


        // If the frame number has changed because the buffer has been reallocated,
        // If the frame number has changed because the buffer has been reallocated,
        // we can ignore this releaseBuffer for the old buffer.
        // we can ignore this releaseBuffer for the old buffer.
@@ -461,7 +461,7 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
        listener = mCore->mConnectedProducerListener;
        listener = mCore->mConnectedProducerListener;
        BQ_LOGV("releaseBuffer: releasing slot %d", slot);
        BQ_LOGV("releaseBuffer: releasing slot %d", slot);


        mCore->mDequeueCondition.broadcast();
        mCore->mDequeueCondition.notify_all();
        VALIDATE_CONSISTENCY();
        VALIDATE_CONSISTENCY();
    } // Autolock scope
    } // Autolock scope


@@ -485,7 +485,7 @@ status_t BufferQueueConsumer::connect(
    BQ_LOGV("connect: controlledByApp=%s",
    BQ_LOGV("connect: controlledByApp=%s",
            controlledByApp ? "true" : "false");
            controlledByApp ? "true" : "false");


    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);


    if (mCore->mIsAbandoned) {
    if (mCore->mIsAbandoned) {
        BQ_LOGE("connect: BufferQueue has been abandoned");
        BQ_LOGE("connect: BufferQueue has been abandoned");
@@ -503,7 +503,7 @@ status_t BufferQueueConsumer::disconnect() {


    BQ_LOGV("disconnect");
    BQ_LOGV("disconnect");


    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);


    if (mCore->mConsumerListener == nullptr) {
    if (mCore->mConsumerListener == nullptr) {
        BQ_LOGE("disconnect: no consumer is connected");
        BQ_LOGE("disconnect: no consumer is connected");
@@ -515,7 +515,7 @@ status_t BufferQueueConsumer::disconnect() {
    mCore->mQueue.clear();
    mCore->mQueue.clear();
    mCore->freeAllBuffersLocked();
    mCore->freeAllBuffersLocked();
    mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
    mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
    mCore->mDequeueCondition.broadcast();
    mCore->mDequeueCondition.notify_all();
    return NO_ERROR;
    return NO_ERROR;
}
}


@@ -527,7 +527,7 @@ status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) {
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }


    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);


    if (mCore->mIsAbandoned) {
    if (mCore->mIsAbandoned) {
        BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned");
        BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned");
@@ -569,7 +569,7 @@ status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width,


    BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height);
    BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height);


    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    mCore->mDefaultWidth = width;
    mCore->mDefaultWidth = width;
    mCore->mDefaultHeight = height;
    mCore->mDefaultHeight = height;
    return NO_ERROR;
    return NO_ERROR;
@@ -583,7 +583,7 @@ status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) {
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }


    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);


    if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
    if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
        BQ_LOGE("setMaxBufferCount: producer is already connected");
        BQ_LOGE("setMaxBufferCount: producer is already connected");
@@ -623,8 +623,8 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount(


    sp<IConsumerListener> listener;
    sp<IConsumerListener> listener;
    { // Autolock scope
    { // Autolock scope
        Mutex::Autolock lock(mCore->mMutex);
        std::unique_lock<std::mutex> lock(mCore->mMutex);
        mCore->waitWhileAllocatingLocked();
        mCore->waitWhileAllocatingLocked(lock);


        if (mCore->mIsAbandoned) {
        if (mCore->mIsAbandoned) {
            BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned");
            BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned");
@@ -684,7 +684,7 @@ status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
status_t BufferQueueConsumer::setConsumerName(const String8& name) {
status_t BufferQueueConsumer::setConsumerName(const String8& name) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("setConsumerName: '%s'", name.string());
    BQ_LOGV("setConsumerName: '%s'", name.string());
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    mCore->mConsumerName = name;
    mCore->mConsumerName = name;
    mConsumerName = name;
    mConsumerName = name;
    return NO_ERROR;
    return NO_ERROR;
@@ -693,7 +693,7 @@ status_t BufferQueueConsumer::setConsumerName(const String8& name) {
status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
    BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    mCore->mDefaultBufferFormat = defaultFormat;
    mCore->mDefaultBufferFormat = defaultFormat;
    return NO_ERROR;
    return NO_ERROR;
}
}
@@ -702,7 +702,7 @@ status_t BufferQueueConsumer::setDefaultBufferDataSpace(
        android_dataspace defaultDataSpace) {
        android_dataspace defaultDataSpace) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
    BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    mCore->mDefaultBufferDataSpace = defaultDataSpace;
    mCore->mDefaultBufferDataSpace = defaultDataSpace;
    return NO_ERROR;
    return NO_ERROR;
}
}
@@ -710,7 +710,7 @@ status_t BufferQueueConsumer::setDefaultBufferDataSpace(
status_t BufferQueueConsumer::setConsumerUsageBits(uint64_t usage) {
status_t BufferQueueConsumer::setConsumerUsageBits(uint64_t usage) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("setConsumerUsageBits: %#" PRIx64, usage);
    BQ_LOGV("setConsumerUsageBits: %#" PRIx64, usage);
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    mCore->mConsumerUsageBits = usage;
    mCore->mConsumerUsageBits = usage;
    return NO_ERROR;
    return NO_ERROR;
}
}
@@ -718,7 +718,7 @@ status_t BufferQueueConsumer::setConsumerUsageBits(uint64_t usage) {
status_t BufferQueueConsumer::setConsumerIsProtected(bool isProtected) {
status_t BufferQueueConsumer::setConsumerIsProtected(bool isProtected) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("setConsumerIsProtected: %s", isProtected ? "true" : "false");
    BQ_LOGV("setConsumerIsProtected: %s", isProtected ? "true" : "false");
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    mCore->mConsumerIsProtected = isProtected;
    mCore->mConsumerIsProtected = isProtected;
    return NO_ERROR;
    return NO_ERROR;
}
}
@@ -726,26 +726,26 @@ status_t BufferQueueConsumer::setConsumerIsProtected(bool isProtected) {
status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("setTransformHint: %#x", hint);
    BQ_LOGV("setTransformHint: %#x", hint);
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    mCore->mTransformHint = hint;
    mCore->mTransformHint = hint;
    return NO_ERROR;
    return NO_ERROR;
}
}


status_t BufferQueueConsumer::getSidebandStream(sp<NativeHandle>* outStream) const {
status_t BufferQueueConsumer::getSidebandStream(sp<NativeHandle>* outStream) const {
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    *outStream = mCore->mSidebandStream;
    *outStream = mCore->mSidebandStream;
    return NO_ERROR;
    return NO_ERROR;
}
}


status_t BufferQueueConsumer::getOccupancyHistory(bool forceFlush,
status_t BufferQueueConsumer::getOccupancyHistory(bool forceFlush,
        std::vector<OccupancyTracker::Segment>* outHistory) {
        std::vector<OccupancyTracker::Segment>* outHistory) {
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    *outHistory = mCore->mOccupancyTracker.getSegmentHistory(forceFlush);
    *outHistory = mCore->mOccupancyTracker.getSegmentHistory(forceFlush);
    return NO_ERROR;
    return NO_ERROR;
}
}


status_t BufferQueueConsumer::discardFreeBuffers() {
status_t BufferQueueConsumer::discardFreeBuffers() {
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    mCore->discardFreeBuffersLocked();
    mCore->discardFreeBuffersLocked();
    return NO_ERROR;
    return NO_ERROR;
}
}
+3 −3
Original line number Original line Diff line number Diff line
@@ -110,7 +110,7 @@ BufferQueueCore::BufferQueueCore() :
BufferQueueCore::~BufferQueueCore() {}
BufferQueueCore::~BufferQueueCore() {}


void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const {
void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const {
    Mutex::Autolock lock(mMutex);
    std::lock_guard<std::mutex> lock(mMutex);


    outResult->appendFormat("%s- BufferQueue ", prefix.string());
    outResult->appendFormat("%s- BufferQueue ", prefix.string());
    outResult->appendFormat("mMaxAcquiredBufferCount=%d mMaxDequeuedBufferCount=%d\n",
    outResult->appendFormat("mMaxAcquiredBufferCount=%d mMaxDequeuedBufferCount=%d\n",
@@ -306,10 +306,10 @@ bool BufferQueueCore::adjustAvailableSlotsLocked(int delta) {
    return true;
    return true;
}
}


void BufferQueueCore::waitWhileAllocatingLocked() const {
void BufferQueueCore::waitWhileAllocatingLocked(std::unique_lock<std::mutex>& lock) const {
    ATRACE_CALL();
    ATRACE_CALL();
    while (mIsAllocating) {
    while (mIsAllocating) {
        mIsAllocatingCondition.wait(mMutex);
        mIsAllocatingCondition.wait(lock);
    }
    }
}
}


+54 −55
Original line number Original line Diff line number Diff line
@@ -66,7 +66,7 @@ BufferQueueProducer::~BufferQueueProducer() {}
status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("requestBuffer: slot %d", slot);
    BQ_LOGV("requestBuffer: slot %d", slot);
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);


    if (mCore->mIsAbandoned) {
    if (mCore->mIsAbandoned) {
        BQ_LOGE("requestBuffer: BufferQueue has been abandoned");
        BQ_LOGE("requestBuffer: BufferQueue has been abandoned");
@@ -101,8 +101,8 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount(


    sp<IConsumerListener> listener;
    sp<IConsumerListener> listener;
    { // Autolock scope
    { // Autolock scope
        Mutex::Autolock lock(mCore->mMutex);
        std::unique_lock<std::mutex> lock(mCore->mMutex);
        mCore->waitWhileAllocatingLocked();
        mCore->waitWhileAllocatingLocked(lock);


        if (mCore->mIsAbandoned) {
        if (mCore->mIsAbandoned) {
            BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue has been "
            BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue has been "
@@ -163,7 +163,7 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount(
        if (delta < 0) {
        if (delta < 0) {
            listener = mCore->mConsumerListener;
            listener = mCore->mConsumerListener;
        }
        }
        mCore->mDequeueCondition.broadcast();
        mCore->mDequeueCondition.notify_all();
    } // Autolock scope
    } // Autolock scope


    // Call back without lock held
    // Call back without lock held
@@ -180,8 +180,8 @@ status_t BufferQueueProducer::setAsyncMode(bool async) {


    sp<IConsumerListener> listener;
    sp<IConsumerListener> listener;
    { // Autolock scope
    { // Autolock scope
        Mutex::Autolock lock(mCore->mMutex);
        std::unique_lock<std::mutex> lock(mCore->mMutex);
        mCore->waitWhileAllocatingLocked();
        mCore->waitWhileAllocatingLocked(lock);


        if (mCore->mIsAbandoned) {
        if (mCore->mIsAbandoned) {
            BQ_LOGE("setAsyncMode: BufferQueue has been abandoned");
            BQ_LOGE("setAsyncMode: BufferQueue has been abandoned");
@@ -215,7 +215,7 @@ status_t BufferQueueProducer::setAsyncMode(bool async) {
        }
        }
        mCore->mAsyncMode = async;
        mCore->mAsyncMode = async;
        VALIDATE_CONSISTENCY();
        VALIDATE_CONSISTENCY();
        mCore->mDequeueCondition.broadcast();
        mCore->mDequeueCondition.notify_all();
        if (delta < 0) {
        if (delta < 0) {
            listener = mCore->mConsumerListener;
            listener = mCore->mConsumerListener;
        }
        }
@@ -247,7 +247,7 @@ int BufferQueueProducer::getFreeSlotLocked() const {
}
}


status_t BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller,
status_t BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller,
        int* found) const {
        std::unique_lock<std::mutex>& lock, int* found) const {
    auto callerString = (caller == FreeSlotCaller::Dequeue) ?
    auto callerString = (caller == FreeSlotCaller::Dequeue) ?
            "dequeueBuffer" : "attachBuffer";
            "dequeueBuffer" : "attachBuffer";
    bool tryAgain = true;
    bool tryAgain = true;
@@ -334,13 +334,13 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller,
                return WOULD_BLOCK;
                return WOULD_BLOCK;
            }
            }
            if (mDequeueTimeout >= 0) {
            if (mDequeueTimeout >= 0) {
                status_t result = mCore->mDequeueCondition.waitRelative(
                std::cv_status result = mCore->mDequeueCondition.wait_for(lock,
                        mCore->mMutex, mDequeueTimeout);
                        std::chrono::nanoseconds(mDequeueTimeout));
                if (result == TIMED_OUT) {
                if (result == std::cv_status::timeout) {
                    return result;
                    return TIMED_OUT;
                }
                }
            } else {
            } else {
                mCore->mDequeueCondition.wait(mCore->mMutex);
                mCore->mDequeueCondition.wait(lock);
            }
            }
        }
        }
    } // while (tryAgain)
    } // while (tryAgain)
@@ -354,7 +354,7 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou
                                            FrameEventHistoryDelta* outTimestamps) {
                                            FrameEventHistoryDelta* outTimestamps) {
    ATRACE_CALL();
    ATRACE_CALL();
    { // Autolock scope
    { // Autolock scope
        Mutex::Autolock lock(mCore->mMutex);
        std::lock_guard<std::mutex> lock(mCore->mMutex);
        mConsumerName = mCore->mConsumerName;
        mConsumerName = mCore->mConsumerName;


        if (mCore->mIsAbandoned) {
        if (mCore->mIsAbandoned) {
@@ -381,7 +381,7 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou
    bool attachedByConsumer = false;
    bool attachedByConsumer = false;


    { // Autolock scope
    { // Autolock scope
        Mutex::Autolock lock(mCore->mMutex);
        std::unique_lock<std::mutex> lock(mCore->mMutex);


        if (format == 0) {
        if (format == 0) {
            format = mCore->mDefaultBufferFormat;
            format = mCore->mDefaultBufferFormat;
@@ -398,8 +398,7 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou


        int found = BufferItem::INVALID_BUFFER_SLOT;
        int found = BufferItem::INVALID_BUFFER_SLOT;
        while (found == BufferItem::INVALID_BUFFER_SLOT) {
        while (found == BufferItem::INVALID_BUFFER_SLOT) {
            status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue,
            status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue, lock, &found);
                    &found);
            if (status != NO_ERROR) {
            if (status != NO_ERROR) {
                return status;
                return status;
            }
            }
@@ -506,7 +505,7 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou
        status_t error = graphicBuffer->initCheck();
        status_t error = graphicBuffer->initCheck();


        { // Autolock scope
        { // Autolock scope
            Mutex::Autolock lock(mCore->mMutex);
            std::lock_guard<std::mutex> lock(mCore->mMutex);


            if (error == NO_ERROR && !mCore->mIsAbandoned) {
            if (error == NO_ERROR && !mCore->mIsAbandoned) {
                graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
                graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
@@ -514,7 +513,7 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou
            }
            }


            mCore->mIsAllocating = false;
            mCore->mIsAllocating = false;
            mCore->mIsAllocatingCondition.broadcast();
            mCore->mIsAllocatingCondition.notify_all();


            if (error != NO_ERROR) {
            if (error != NO_ERROR) {
                mCore->mFreeSlots.insert(*outSlot);
                mCore->mFreeSlots.insert(*outSlot);
@@ -573,7 +572,7 @@ status_t BufferQueueProducer::detachBuffer(int slot) {


    sp<IConsumerListener> listener;
    sp<IConsumerListener> listener;
    {
    {
        Mutex::Autolock lock(mCore->mMutex);
        std::lock_guard<std::mutex> lock(mCore->mMutex);


        if (mCore->mIsAbandoned) {
        if (mCore->mIsAbandoned) {
            BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
            BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
@@ -608,7 +607,7 @@ status_t BufferQueueProducer::detachBuffer(int slot) {
        mCore->mActiveBuffers.erase(slot);
        mCore->mActiveBuffers.erase(slot);
        mCore->mFreeSlots.insert(slot);
        mCore->mFreeSlots.insert(slot);
        mCore->clearBufferSlotLocked(slot);
        mCore->clearBufferSlotLocked(slot);
        mCore->mDequeueCondition.broadcast();
        mCore->mDequeueCondition.notify_all();
        VALIDATE_CONSISTENCY();
        VALIDATE_CONSISTENCY();
        listener = mCore->mConsumerListener;
        listener = mCore->mConsumerListener;
    }
    }
@@ -634,7 +633,7 @@ status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,


    sp<IConsumerListener> listener;
    sp<IConsumerListener> listener;
    {
    {
        Mutex::Autolock lock(mCore->mMutex);
        std::unique_lock<std::mutex> lock(mCore->mMutex);


        if (mCore->mIsAbandoned) {
        if (mCore->mIsAbandoned) {
            BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
            BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
@@ -652,7 +651,7 @@ status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
            return BAD_VALUE;
            return BAD_VALUE;
        }
        }


        mCore->waitWhileAllocatingLocked();
        mCore->waitWhileAllocatingLocked(lock);


        if (mCore->mFreeBuffers.empty()) {
        if (mCore->mFreeBuffers.empty()) {
            return NO_MEMORY;
            return NO_MEMORY;
@@ -690,7 +689,7 @@ status_t BufferQueueProducer::attachBuffer(int* outSlot,
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }


    Mutex::Autolock lock(mCore->mMutex);
    std::unique_lock<std::mutex> lock(mCore->mMutex);


    if (mCore->mIsAbandoned) {
    if (mCore->mIsAbandoned) {
        BQ_LOGE("attachBuffer: BufferQueue has been abandoned");
        BQ_LOGE("attachBuffer: BufferQueue has been abandoned");
@@ -714,11 +713,11 @@ status_t BufferQueueProducer::attachBuffer(int* outSlot,
        return BAD_VALUE;
        return BAD_VALUE;
    }
    }


    mCore->waitWhileAllocatingLocked();
    mCore->waitWhileAllocatingLocked(lock);


    status_t returnFlags = NO_ERROR;
    status_t returnFlags = NO_ERROR;
    int found;
    int found;
    status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Attach, &found);
    status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Attach, lock, &found);
    if (status != NO_ERROR) {
    if (status != NO_ERROR) {
        return status;
        return status;
    }
    }
@@ -791,7 +790,7 @@ status_t BufferQueueProducer::queueBuffer(int slot,
    uint64_t currentFrameNumber = 0;
    uint64_t currentFrameNumber = 0;
    BufferItem item;
    BufferItem item;
    { // Autolock scope
    { // Autolock scope
        Mutex::Autolock lock(mCore->mMutex);
        std::lock_guard<std::mutex> lock(mCore->mMutex);


        if (mCore->mIsAbandoned) {
        if (mCore->mIsAbandoned) {
            BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
            BQ_LOGE("queueBuffer: BufferQueue has been abandoned");
@@ -932,7 +931,7 @@ status_t BufferQueueProducer::queueBuffer(int slot,
        }
        }


        mCore->mBufferHasBeenQueued = true;
        mCore->mBufferHasBeenQueued = true;
        mCore->mDequeueCondition.broadcast();
        mCore->mDequeueCondition.notify_all();
        mCore->mLastQueuedSlot = slot;
        mCore->mLastQueuedSlot = slot;


        output->width = mCore->mDefaultWidth;
        output->width = mCore->mDefaultWidth;
@@ -968,9 +967,9 @@ status_t BufferQueueProducer::queueBuffer(int slot,
    sp<Fence> lastQueuedFence;
    sp<Fence> lastQueuedFence;


    { // scope for the lock
    { // scope for the lock
        Mutex::Autolock lock(mCallbackMutex);
        std::unique_lock<std::mutex> lock(mCallbackMutex);
        while (callbackTicket != mCurrentCallbackTicket) {
        while (callbackTicket != mCurrentCallbackTicket) {
            mCallbackCondition.wait(mCallbackMutex);
            mCallbackCondition.wait(lock);
        }
        }


        if (frameAvailableListener != nullptr) {
        if (frameAvailableListener != nullptr) {
@@ -987,7 +986,7 @@ status_t BufferQueueProducer::queueBuffer(int slot,
        mLastQueuedTransform = item.mTransform;
        mLastQueuedTransform = item.mTransform;


        ++mCurrentCallbackTicket;
        ++mCurrentCallbackTicket;
        mCallbackCondition.broadcast();
        mCallbackCondition.notify_all();
    }
    }


    // Wait without lock held
    // Wait without lock held
@@ -1015,7 +1014,7 @@ status_t BufferQueueProducer::queueBuffer(int slot,
status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("cancelBuffer: slot %d", slot);
    BQ_LOGV("cancelBuffer: slot %d", slot);
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);


    if (mCore->mIsAbandoned) {
    if (mCore->mIsAbandoned) {
        BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
        BQ_LOGE("cancelBuffer: BufferQueue has been abandoned");
@@ -1060,7 +1059,7 @@ status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
    }
    }


    mSlots[slot].mFence = fence;
    mSlots[slot].mFence = fence;
    mCore->mDequeueCondition.broadcast();
    mCore->mDequeueCondition.notify_all();
    VALIDATE_CONSISTENCY();
    VALIDATE_CONSISTENCY();


    return NO_ERROR;
    return NO_ERROR;
@@ -1068,7 +1067,7 @@ status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {


int BufferQueueProducer::query(int what, int *outValue) {
int BufferQueueProducer::query(int what, int *outValue) {
    ATRACE_CALL();
    ATRACE_CALL();
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);


    if (outValue == nullptr) {
    if (outValue == nullptr) {
        BQ_LOGE("query: outValue was NULL");
        BQ_LOGE("query: outValue was NULL");
@@ -1136,7 +1135,7 @@ int BufferQueueProducer::query(int what, int *outValue) {
status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
        int api, bool producerControlledByApp, QueueBufferOutput *output) {
        int api, bool producerControlledByApp, QueueBufferOutput *output) {
    ATRACE_CALL();
    ATRACE_CALL();
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    mConsumerName = mCore->mConsumerName;
    mConsumerName = mCore->mConsumerName;
    BQ_LOGV("connect: api=%d producerControlledByApp=%s", api,
    BQ_LOGV("connect: api=%d producerControlledByApp=%s", api,
            producerControlledByApp ? "true" : "false");
            producerControlledByApp ? "true" : "false");
@@ -1231,7 +1230,7 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) {
    int status = NO_ERROR;
    int status = NO_ERROR;
    sp<IConsumerListener> listener;
    sp<IConsumerListener> listener;
    { // Autolock scope
    { // Autolock scope
        Mutex::Autolock lock(mCore->mMutex);
        std::unique_lock<std::mutex> lock(mCore->mMutex);


        if (mode == DisconnectMode::AllLocal) {
        if (mode == DisconnectMode::AllLocal) {
            if (BufferQueueThreadState::getCallingPid() != mCore->mConnectedPid) {
            if (BufferQueueThreadState::getCallingPid() != mCore->mConnectedPid) {
@@ -1240,7 +1239,7 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) {
            api = BufferQueueCore::CURRENTLY_CONNECTED_API;
            api = BufferQueueCore::CURRENTLY_CONNECTED_API;
        }
        }


        mCore->waitWhileAllocatingLocked();
        mCore->waitWhileAllocatingLocked(lock);


        if (mCore->mIsAbandoned) {
        if (mCore->mIsAbandoned) {
            // It's not really an error to disconnect after the surface has
            // It's not really an error to disconnect after the surface has
@@ -1284,7 +1283,7 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) {
                    mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
                    mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API;
                    mCore->mConnectedPid = -1;
                    mCore->mConnectedPid = -1;
                    mCore->mSidebandStream.clear();
                    mCore->mSidebandStream.clear();
                    mCore->mDequeueCondition.broadcast();
                    mCore->mDequeueCondition.notify_all();
                    listener = mCore->mConsumerListener;
                    listener = mCore->mConsumerListener;
                } else if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
                } else if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) {
                    BQ_LOGE("disconnect: not connected (req=%d)", api);
                    BQ_LOGE("disconnect: not connected (req=%d)", api);
@@ -1314,7 +1313,7 @@ status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) {
status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) {
    sp<IConsumerListener> listener;
    sp<IConsumerListener> listener;
    { // Autolock scope
    { // Autolock scope
        Mutex::Autolock _l(mCore->mMutex);
        std::lock_guard<std::mutex> _l(mCore->mMutex);
        mCore->mSidebandStream = stream;
        mCore->mSidebandStream = stream;
        listener = mCore->mConsumerListener;
        listener = mCore->mConsumerListener;
    } // Autolock scope
    } // Autolock scope
@@ -1336,8 +1335,8 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
        uint64_t allocUsage = 0;
        uint64_t allocUsage = 0;
        std::string allocName;
        std::string allocName;
        { // Autolock scope
        { // Autolock scope
            Mutex::Autolock lock(mCore->mMutex);
            std::unique_lock<std::mutex> lock(mCore->mMutex);
            mCore->waitWhileAllocatingLocked();
            mCore->waitWhileAllocatingLocked(lock);


            if (!mCore->mAllowAllocation) {
            if (!mCore->mAllowAllocation) {
                BQ_LOGE("allocateBuffers: allocation is not allowed for this "
                BQ_LOGE("allocateBuffers: allocation is not allowed for this "
@@ -1372,16 +1371,16 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
            if (result != NO_ERROR) {
            if (result != NO_ERROR) {
                BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
                BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
                        " %u, usage %#" PRIx64 ")", width, height, format, usage);
                        " %u, usage %#" PRIx64 ")", width, height, format, usage);
                Mutex::Autolock lock(mCore->mMutex);
                std::lock_guard<std::mutex> lock(mCore->mMutex);
                mCore->mIsAllocating = false;
                mCore->mIsAllocating = false;
                mCore->mIsAllocatingCondition.broadcast();
                mCore->mIsAllocatingCondition.notify_all();
                return;
                return;
            }
            }
            buffers.push_back(graphicBuffer);
            buffers.push_back(graphicBuffer);
        }
        }


        { // Autolock scope
        { // Autolock scope
            Mutex::Autolock lock(mCore->mMutex);
            std::unique_lock<std::mutex> lock(mCore->mMutex);
            uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
            uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
            uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
            uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
            PixelFormat checkFormat = format != 0 ?
            PixelFormat checkFormat = format != 0 ?
@@ -1392,7 +1391,7 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
                // Something changed while we released the lock. Retry.
                // Something changed while we released the lock. Retry.
                BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying.");
                BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying.");
                mCore->mIsAllocating = false;
                mCore->mIsAllocating = false;
                mCore->mIsAllocatingCondition.broadcast();
                mCore->mIsAllocatingCondition.notify_all();
                continue;
                continue;
            }
            }


@@ -1420,7 +1419,7 @@ void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,
            }
            }


            mCore->mIsAllocating = false;
            mCore->mIsAllocating = false;
            mCore->mIsAllocatingCondition.broadcast();
            mCore->mIsAllocatingCondition.notify_all();
            VALIDATE_CONSISTENCY();
            VALIDATE_CONSISTENCY();
        } // Autolock scope
        } // Autolock scope
    }
    }
@@ -1430,7 +1429,7 @@ status_t BufferQueueProducer::allowAllocation(bool allow) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("allowAllocation: %s", allow ? "true" : "false");
    BQ_LOGV("allowAllocation: %s", allow ? "true" : "false");


    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    mCore->mAllowAllocation = allow;
    mCore->mAllowAllocation = allow;
    return NO_ERROR;
    return NO_ERROR;
}
}
@@ -1439,14 +1438,14 @@ status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("setGenerationNumber: %u", generationNumber);
    BQ_LOGV("setGenerationNumber: %u", generationNumber);


    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    mCore->mGenerationNumber = generationNumber;
    mCore->mGenerationNumber = generationNumber;
    return NO_ERROR;
    return NO_ERROR;
}
}


String8 BufferQueueProducer::getConsumerName() const {
String8 BufferQueueProducer::getConsumerName() const {
    ATRACE_CALL();
    ATRACE_CALL();
    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    BQ_LOGV("getConsumerName: %s", mConsumerName.string());
    BQ_LOGV("getConsumerName: %s", mConsumerName.string());
    return mConsumerName;
    return mConsumerName;
}
}
@@ -1455,7 +1454,7 @@ status_t BufferQueueProducer::setSharedBufferMode(bool sharedBufferMode) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode);
    BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode);


    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    if (!sharedBufferMode) {
    if (!sharedBufferMode) {
        mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
        mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
    }
    }
@@ -1467,7 +1466,7 @@ status_t BufferQueueProducer::setAutoRefresh(bool autoRefresh) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("setAutoRefresh: %d", autoRefresh);
    BQ_LOGV("setAutoRefresh: %d", autoRefresh);


    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);


    mCore->mAutoRefresh = autoRefresh;
    mCore->mAutoRefresh = autoRefresh;
    return NO_ERROR;
    return NO_ERROR;
@@ -1477,7 +1476,7 @@ status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) {
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("setDequeueTimeout: %" PRId64, timeout);
    BQ_LOGV("setDequeueTimeout: %" PRId64, timeout);


    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false,
    int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false,
            mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked();
            mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked();
    if (!mCore->adjustAvailableSlotsLocked(delta)) {
    if (!mCore->adjustAvailableSlotsLocked(delta)) {
@@ -1498,7 +1497,7 @@ status_t BufferQueueProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
    ATRACE_CALL();
    ATRACE_CALL();
    BQ_LOGV("getLastQueuedBuffer");
    BQ_LOGV("getLastQueuedBuffer");


    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) {
    if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) {
        *outBuffer = nullptr;
        *outBuffer = nullptr;
        *outFence = Fence::NO_FENCE;
        *outFence = Fence::NO_FENCE;
@@ -1534,7 +1533,7 @@ void BufferQueueProducer::addAndGetFrameTimestamps(
    BQ_LOGV("addAndGetFrameTimestamps");
    BQ_LOGV("addAndGetFrameTimestamps");
    sp<IConsumerListener> listener;
    sp<IConsumerListener> listener;
    {
    {
        Mutex::Autolock lock(mCore->mMutex);
        std::lock_guard<std::mutex> lock(mCore->mMutex);
        listener = mCore->mConsumerListener;
        listener = mCore->mConsumerListener;
    }
    }
    if (listener != nullptr) {
    if (listener != nullptr) {
@@ -1561,7 +1560,7 @@ status_t BufferQueueProducer::getUniqueId(uint64_t* outId) const {
status_t BufferQueueProducer::getConsumerUsage(uint64_t* outUsage) const {
status_t BufferQueueProducer::getConsumerUsage(uint64_t* outUsage) const {
    BQ_LOGV("getConsumerUsage");
    BQ_LOGV("getConsumerUsage");


    Mutex::Autolock lock(mCore->mMutex);
    std::lock_guard<std::mutex> lock(mCore->mMutex);
    *outUsage = mCore->mConsumerUsageBits;
    *outUsage = mCore->mConsumerUsageBits;
    return NO_ERROR;
    return NO_ERROR;
}
}
+6 −6
Original line number Original line Diff line number Diff line
@@ -22,8 +22,6 @@
#include <gui/BufferSlot.h>
#include <gui/BufferSlot.h>
#include <gui/OccupancyTracker.h>
#include <gui/OccupancyTracker.h>


#include <utils/Condition.h>
#include <utils/Mutex.h>
#include <utils/NativeHandle.h>
#include <utils/NativeHandle.h>
#include <utils/RefBase.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
#include <utils/String8.h>
@@ -33,6 +31,8 @@


#include <list>
#include <list>
#include <set>
#include <set>
#include <mutex>
#include <condition_variable>


#define BQ_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
#define BQ_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
#define BQ_LOGD(x, ...) ALOGD("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
#define BQ_LOGD(x, ...) ALOGD("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
@@ -134,7 +134,7 @@ private:
    bool adjustAvailableSlotsLocked(int delta);
    bool adjustAvailableSlotsLocked(int delta);


    // waitWhileAllocatingLocked blocks until mIsAllocating is false.
    // waitWhileAllocatingLocked blocks until mIsAllocating is false.
    void waitWhileAllocatingLocked() const;
    void waitWhileAllocatingLocked(std::unique_lock<std::mutex>& lock) const;


#if DEBUG_ONLY_CODE
#if DEBUG_ONLY_CODE
    // validateConsistencyLocked ensures that the free lists are in sync with
    // validateConsistencyLocked ensures that the free lists are in sync with
@@ -145,7 +145,7 @@ private:
    // mMutex is the mutex used to prevent concurrent access to the member
    // mMutex is the mutex used to prevent concurrent access to the member
    // variables of BufferQueueCore objects. It must be locked whenever any
    // variables of BufferQueueCore objects. It must be locked whenever any
    // member variable is accessed.
    // member variable is accessed.
    mutable Mutex mMutex;
    mutable std::mutex mMutex;


    // mIsAbandoned indicates that the BufferQueue will no longer be used to
    // mIsAbandoned indicates that the BufferQueue will no longer be used to
    // consume image buffers pushed to it using the IGraphicBufferProducer
    // consume image buffers pushed to it using the IGraphicBufferProducer
@@ -219,7 +219,7 @@ private:


    // mDequeueCondition is a condition variable used for dequeueBuffer in
    // mDequeueCondition is a condition variable used for dequeueBuffer in
    // synchronous mode.
    // synchronous mode.
    mutable Condition mDequeueCondition;
    mutable std::condition_variable mDequeueCondition;


    // mDequeueBufferCannotBlock indicates whether dequeueBuffer is allowed to
    // mDequeueBufferCannotBlock indicates whether dequeueBuffer is allowed to
    // block. This flag is set during connect when both the producer and
    // block. This flag is set during connect when both the producer and
@@ -282,7 +282,7 @@ private:


    // mIsAllocatingCondition is a condition variable used by producers to wait until mIsAllocating
    // mIsAllocatingCondition is a condition variable used by producers to wait until mIsAllocating
    // becomes false.
    // becomes false.
    mutable Condition mIsAllocatingCondition;
    mutable std::condition_variable mIsAllocatingCondition;


    // mAllowAllocation determines whether dequeueBuffer is allowed to allocate
    // mAllowAllocation determines whether dequeueBuffer is allowed to allocate
    // new buffers
    // new buffers
+4 −3
Original line number Original line Diff line number Diff line
@@ -211,7 +211,8 @@ private:
        Dequeue,
        Dequeue,
        Attach,
        Attach,
    };
    };
    status_t waitForFreeSlotThenRelock(FreeSlotCaller caller, int* found) const;
    status_t waitForFreeSlotThenRelock(FreeSlotCaller caller, std::unique_lock<std::mutex>& lock,
            int* found) const;


    sp<BufferQueueCore> mCore;
    sp<BufferQueueCore> mCore;


@@ -243,10 +244,10 @@ private:
    // (mCore->mMutex) is held, a ticket is retained by the producer. After
    // (mCore->mMutex) is held, a ticket is retained by the producer. After
    // dropping the BufferQueue lock, the producer must wait on the condition
    // dropping the BufferQueue lock, the producer must wait on the condition
    // variable until the current callback ticket matches its retained ticket.
    // variable until the current callback ticket matches its retained ticket.
    Mutex mCallbackMutex;
    std::mutex mCallbackMutex;
    int mNextCallbackTicket; // Protected by mCore->mMutex
    int mNextCallbackTicket; // Protected by mCore->mMutex
    int mCurrentCallbackTicket; // Protected by mCallbackMutex
    int mCurrentCallbackTicket; // Protected by mCallbackMutex
    Condition mCallbackCondition;
    std::condition_variable mCallbackCondition;


    // Sets how long dequeueBuffer or attachBuffer will block if a buffer or
    // Sets how long dequeueBuffer or attachBuffer will block if a buffer or
    // slot is not yet available.
    // slot is not yet available.