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

Commit 4b9507d5 authored by Patrick Williams's avatar Patrick Williams
Browse files

Revert "Optimize BLAST buffer releases via Unix sockets"

Reverting due to b/355260320

Change-Id: I8a32f73b6805d3f2bceb2948925be6a9baaa3015
parent 8f71501b
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -255,7 +255,6 @@ filegroup {
        "BitTube.cpp",
        "BitTube.cpp",
        "BLASTBufferQueue.cpp",
        "BLASTBufferQueue.cpp",
        "BufferItemConsumer.cpp",
        "BufferItemConsumer.cpp",
        "BufferReleaseChannel.cpp",
        "Choreographer.cpp",
        "Choreographer.cpp",
        "CompositorTiming.cpp",
        "CompositorTiming.cpp",
        "ConsumerBase.cpp",
        "ConsumerBase.cpp",
+19 −324
Original line number Original line Diff line number Diff line
@@ -38,17 +38,13 @@
#include <private/gui/ComposerService.h>
#include <private/gui/ComposerService.h>
#include <private/gui/ComposerServiceAIDL.h>
#include <private/gui/ComposerServiceAIDL.h>


#include <android-base/stringprintf.h>
#include <android-base/thread_annotations.h>
#include <android-base/thread_annotations.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <chrono>
#include <chrono>


#include <com_android_graphics_libgui_flags.h>
#include <com_android_graphics_libgui_flags.h>


using namespace com::android::graphics::libgui;
using namespace com::android::graphics::libgui;
using namespace std::chrono_literals;
using namespace std::chrono_literals;
using android::base::unique_fd;


namespace {
namespace {
inline const char* boolToString(bool b) {
inline const char* boolToString(bool b) {
@@ -183,6 +179,8 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati
    // explicitly so that dequeueBuffer will block
    // explicitly so that dequeueBuffer will block
    mProducer->setDequeueTimeout(std::numeric_limits<int64_t>::max());
    mProducer->setDequeueTimeout(std::numeric_limits<int64_t>::max());


    // safe default, most producers are expected to override this
    mProducer->setMaxDequeuedBufferCount(2);
    mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
    mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
                                                      GraphicBuffer::USAGE_HW_COMPOSER |
                                                      GraphicBuffer::USAGE_HW_COMPOSER |
                                                              GraphicBuffer::USAGE_HW_TEXTURE,
                                                              GraphicBuffer::USAGE_HW_TEXTURE,
@@ -212,12 +210,6 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati
            },
            },
            this);
            this);


#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
    std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> bufferReleaseConsumer;
    gui::BufferReleaseChannel::open(mName, bufferReleaseConsumer, mBufferReleaseProducer);
    mBufferReleaseReader.emplace(std::move(bufferReleaseConsumer));
#endif

    BQA_LOGV("BLASTBufferQueue created");
    BQA_LOGV("BLASTBufferQueue created");
}
}


@@ -267,9 +259,6 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width,
    if (surfaceControlChanged) {
    if (surfaceControlChanged) {
        t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure,
        t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure,
                   layer_state_t::eEnableBackpressure);
                   layer_state_t::eEnableBackpressure);
        if (mBufferReleaseProducer) {
            t.setBufferReleaseChannel(mSurfaceControl, mBufferReleaseProducer);
        }
        applyTransaction = true;
        applyTransaction = true;
    }
    }
    mTransformHint = mSurfaceControl->getTransformHint();
    mTransformHint = mSurfaceControl->getTransformHint();
@@ -450,21 +439,6 @@ void BLASTBufferQueue::releaseBufferCallback(
    BBQ_TRACE();
    BBQ_TRACE();
    releaseBufferCallbackLocked(id, releaseFence, currentMaxAcquiredBufferCount,
    releaseBufferCallbackLocked(id, releaseFence, currentMaxAcquiredBufferCount,
                                false /* fakeRelease */);
                                false /* fakeRelease */);
    if (!mBufferReleaseReader) {
        return;
    }
    // Drain the buffer release channel socket
    while (true) {
        ReleaseCallbackId releaseCallbackId;
        sp<Fence> releaseFence;
        if (status_t status =
                    mBufferReleaseReader->readNonBlocking(releaseCallbackId, releaseFence);
            status != OK) {
            break;
        }
        releaseBufferCallbackLocked(releaseCallbackId, releaseFence, std::nullopt,
                                    false /* fakeRelease */);
    }
}
}


void BLASTBufferQueue::releaseBufferCallbackLocked(
void BLASTBufferQueue::releaseBufferCallbackLocked(
@@ -521,13 +495,11 @@ void BLASTBufferQueue::releaseBuffer(const ReleaseCallbackId& callbackId,
                                     const sp<Fence>& releaseFence) {
                                     const sp<Fence>& releaseFence) {
    auto it = mSubmitted.find(callbackId);
    auto it = mSubmitted.find(callbackId);
    if (it == mSubmitted.end()) {
    if (it == mSubmitted.end()) {
        BQA_LOGE("ERROR: releaseBufferCallback without corresponding submitted buffer %s",
                 callbackId.to_string().c_str());
        return;
        return;
    }
    }
    mNumAcquired--;
    mNumAcquired--;
    updateDequeueShouldBlockLocked();
    if (mBufferReleaseReader) {
        mBufferReleaseReader->interruptBlockingRead();
    }
    BBQ_TRACE("frame=%" PRIu64, callbackId.framenumber);
    BBQ_TRACE("frame=%" PRIu64, callbackId.framenumber);
    BQA_LOGV("released %s", callbackId.to_string().c_str());
    BQA_LOGV("released %s", callbackId.to_string().c_str());
    mBufferItemConsumer->releaseBuffer(it->second, releaseFence);
    mBufferItemConsumer->releaseBuffer(it->second, releaseFence);
@@ -592,7 +564,6 @@ status_t BLASTBufferQueue::acquireNextBufferLocked(


    auto buffer = bufferItem.mGraphicBuffer;
    auto buffer = bufferItem.mGraphicBuffer;
    mNumFrameAvailable--;
    mNumFrameAvailable--;
    updateDequeueShouldBlockLocked();
    BBQ_TRACE("frame=%" PRIu64, bufferItem.mFrameNumber);
    BBQ_TRACE("frame=%" PRIu64, bufferItem.mFrameNumber);


    if (buffer == nullptr) {
    if (buffer == nullptr) {
@@ -611,7 +582,6 @@ status_t BLASTBufferQueue::acquireNextBufferLocked(
    }
    }


    mNumAcquired++;
    mNumAcquired++;
    updateDequeueShouldBlockLocked();
    mLastAcquiredFrameNumber = bufferItem.mFrameNumber;
    mLastAcquiredFrameNumber = bufferItem.mFrameNumber;
    ReleaseCallbackId releaseCallbackId(buffer->getId(), mLastAcquiredFrameNumber);
    ReleaseCallbackId releaseCallbackId(buffer->getId(), mLastAcquiredFrameNumber);
    mSubmitted[releaseCallbackId] = bufferItem;
    mSubmitted[releaseCallbackId] = bufferItem;
@@ -738,7 +708,6 @@ void BLASTBufferQueue::acquireAndReleaseBuffer() {
        return;
        return;
    }
    }
    mNumFrameAvailable--;
    mNumFrameAvailable--;
    updateDequeueShouldBlockLocked();
    mBufferItemConsumer->releaseBuffer(bufferItem, bufferItem.mFence);
    mBufferItemConsumer->releaseBuffer(bufferItem, bufferItem.mFence);
}
}


@@ -792,9 +761,7 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) {
        }
        }


        // add to shadow queue
        // add to shadow queue
        mNumDequeued--;
        mNumFrameAvailable++;
        mNumFrameAvailable++;
        updateDequeueShouldBlockLocked();
        if (waitForTransactionCallback && mNumFrameAvailable >= 2) {
        if (waitForTransactionCallback && mNumFrameAvailable >= 2) {
            acquireAndReleaseBuffer();
            acquireAndReleaseBuffer();
        }
        }
@@ -845,24 +812,11 @@ void BLASTBufferQueue::onFrameReplaced(const BufferItem& item) {
void BLASTBufferQueue::onFrameDequeued(const uint64_t bufferId) {
void BLASTBufferQueue::onFrameDequeued(const uint64_t bufferId) {
    std::lock_guard _lock{mTimestampMutex};
    std::lock_guard _lock{mTimestampMutex};
    mDequeueTimestamps[bufferId] = systemTime();
    mDequeueTimestamps[bufferId] = systemTime();
    mNumDequeued++;
};
}


void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) {
void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) {
    {
    std::lock_guard _lock{mTimestampMutex};
    std::lock_guard _lock{mTimestampMutex};
    mDequeueTimestamps.erase(bufferId);
    mDequeueTimestamps.erase(bufferId);
    }

    {
        std::lock_guard lock{mMutex};
        mNumDequeued--;
        updateDequeueShouldBlockLocked();
    }

    if (mBufferReleaseReader) {
        mBufferReleaseReader->interruptBlockingRead();
    }
};
};


bool BLASTBufferQueue::syncNextTransaction(
bool BLASTBufferQueue::syncNextTransaction(
@@ -934,22 +888,6 @@ bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) {
    return mSize != bufferSize;
    return mSize != bufferSize;
}
}


void BLASTBufferQueue::updateDequeueShouldBlockLocked() {
    int32_t buffersInUse = mNumDequeued + mNumFrameAvailable + mNumAcquired;
    int32_t maxBufferCount = std::min(mMaxAcquiredBuffers + mMaxDequeuedBuffers, kMaxBufferCount);
    bool bufferAvailable = buffersInUse < maxBufferCount;
    // BLASTBufferQueueProducer should block until a buffer is released if
    // (1) There are no free buffers available.
    // (2) We're not in async mode. In async mode, BufferQueueProducer::dequeueBuffer returns
    //     WOULD_BLOCK instead of blocking when there are no free buffers.
    // (3) We're not in shared buffer mode. In shared buffer mode, both the producer and consumer
    //     can access the same buffer simultaneously. BufferQueueProducer::dequeueBuffer returns
    //     the shared buffer immediately instead of blocking.
    mDequeueShouldBlock = !(bufferAvailable || mAsyncMode || mSharedBufferMode);
    ATRACE_INT("Dequeued", mNumDequeued);
    ATRACE_INT("DequeueShouldBlock", mDequeueShouldBlock);
}

class BBQSurface : public Surface {
class BBQSurface : public Surface {
private:
private:
    std::mutex mMutex;
    std::mutex mMutex;
@@ -1178,64 +1116,24 @@ public:
                                            producerControlledByApp, output);
                                            producerControlledByApp, output);
    }
    }


    status_t disconnect(int api, DisconnectMode mode) override {
        if (status_t status = BufferQueueProducer::disconnect(api, mode); status != OK) {
            return status;
        }

        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
        if (!bbq) {
            return OK;
        }

        {
            std::lock_guard lock{bbq->mMutex};
            bbq->mNumDequeued = 0;
            bbq->mNumFrameAvailable = 0;
            bbq->mNumAcquired = 0;
            bbq->mSubmitted.clear();
            bbq->updateDequeueShouldBlockLocked();
        }

        if (bbq->mBufferReleaseReader) {
            bbq->mBufferReleaseReader->interruptBlockingRead();
        }

        return OK;
    }

    // We want to resize the frame history when changing the size of the buffer queue
    // We want to resize the frame history when changing the size of the buffer queue
    status_t setMaxDequeuedBufferCount(int maxDequeuedBufferCount) override {
    status_t setMaxDequeuedBufferCount(int maxDequeuedBufferCount) override {
        int maxBufferCount;
        int maxBufferCount;
        status_t status = BufferQueueProducer::setMaxDequeuedBufferCount(maxDequeuedBufferCount,
        status_t status = BufferQueueProducer::setMaxDequeuedBufferCount(maxDequeuedBufferCount,
                                                                         &maxBufferCount);
                                                                         &maxBufferCount);
        if (status != OK) {
        // if we can't determine the max buffer count, then just skip growing the history size
            return status;
        if (status == OK) {
        }

        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
        if (!bbq) {
            return OK;
        }

        {
            std::lock_guard lock{bbq->mMutex};
            bbq->mMaxDequeuedBuffers = maxDequeuedBufferCount;
            bbq->updateDequeueShouldBlockLocked();
        }

        if (bbq->mBufferReleaseReader) {
            bbq->mBufferReleaseReader->interruptBlockingRead();
        }

            size_t newFrameHistorySize = maxBufferCount + 2; // +2 because triple buffer rendering
            size_t newFrameHistorySize = maxBufferCount + 2; // +2 because triple buffer rendering
            // optimize away resizing the frame history unless it will grow
            // optimize away resizing the frame history unless it will grow
            if (newFrameHistorySize > FrameEventHistory::INITIAL_MAX_FRAME_HISTORY) {
            if (newFrameHistorySize > FrameEventHistory::INITIAL_MAX_FRAME_HISTORY) {
                sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
                if (bbq != nullptr) {
                    ALOGV("increasing frame history size to %zu", newFrameHistorySize);
                    ALOGV("increasing frame history size to %zu", newFrameHistorySize);
                    bbq->resizeFrameEventHistory(newFrameHistorySize);
                    bbq->resizeFrameEventHistory(newFrameHistorySize);
                }
                }

            }
        return OK;
        }
        return status;
    }
    }


    int query(int what, int* value) override {
    int query(int what, int* value) override {
@@ -1246,131 +1144,6 @@ public:
        return BufferQueueProducer::query(what, value);
        return BufferQueueProducer::query(what, value);
    }
    }


    status_t setAsyncMode(bool asyncMode) override {
        if (status_t status = BufferQueueProducer::setAsyncMode(asyncMode); status != NO_ERROR) {
            return status;
        }

        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
        if (!bbq) {
            return NO_ERROR;
        }

        {
            std::lock_guard lock{bbq->mMutex};
            bbq->mAsyncMode = asyncMode;
            bbq->updateDequeueShouldBlockLocked();
        }

        if (bbq->mBufferReleaseReader) {
            bbq->mBufferReleaseReader->interruptBlockingRead();
        }
        return NO_ERROR;
    }

    status_t setSharedBufferMode(bool sharedBufferMode) override {
        if (status_t status = BufferQueueProducer::setSharedBufferMode(sharedBufferMode);
            status != NO_ERROR) {
            return status;
        }

        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
        if (!bbq) {
            return NO_ERROR;
        }

        {
            std::lock_guard lock{bbq->mMutex};
            bbq->mSharedBufferMode = sharedBufferMode;
            bbq->updateDequeueShouldBlockLocked();
        }

        if (bbq->mBufferReleaseReader) {
            bbq->mBufferReleaseReader->interruptBlockingRead();
        }
        return NO_ERROR;
    }

    status_t detachBuffer(int slot) override {
        if (status_t status = BufferQueueProducer::detachBuffer(slot); status != NO_ERROR) {
            return status;
        }

        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
        if (!bbq) {
            return NO_ERROR;
        }

        {
            std::lock_guard lock{bbq->mMutex};
            bbq->mNumDequeued--;
            bbq->updateDequeueShouldBlockLocked();
        }

        if (bbq->mBufferReleaseReader) {
            bbq->mBufferReleaseReader->interruptBlockingRead();
        }
        return NO_ERROR;
    }

    // Override dequeueBuffer to block if there are no free buffers.
    //
    // Buffer releases are communicated via the BufferReleaseChannel. When dequeueBuffer determines
    // a free buffer is not available, it blocks on an epoll file descriptor. Epoll is configured to
    // detect messages on the BufferReleaseChannel's socket and an eventfd. The eventfd is signaled
    // whenever an event other than a buffer release occurs that may change the number of free
    // buffers. dequeueBuffer uses epoll in a similar manner as a condition variable by testing for
    // the availability of a free buffer in a loop, breaking the loop once a free buffer is
    // available.
    //
    // This is an optimization implemented to reduce thread scheduling delays in the previously
    // existing binder release callback. The binder buffer release callback is still used and there
    // are no guarantees around order between buffer releases via binder and the
    // BufferReleaseChannel. If we attempt to a release a buffer here that has already been released
    // via binder, the release is ignored.
    status_t dequeueBuffer(int* outSlot, sp<Fence>* outFence, uint32_t width, uint32_t height,
                           PixelFormat format, uint64_t usage, uint64_t* outBufferAge,
                           FrameEventHistoryDelta* outTimestamps) {
        sp<BLASTBufferQueue> bbq = mBLASTBufferQueue.promote();
        if (!bbq || !bbq->mBufferReleaseReader) {
            return BufferQueueProducer::dequeueBuffer(outSlot, outFence, width, height, format,
                                                      usage, outBufferAge, outTimestamps);
        }

        if (bbq->mDequeueShouldBlock) {
            ATRACE_FORMAT("waiting for free buffer");
            auto maxWaitTime = std::chrono::steady_clock::now() + 1s;
            do {
                auto timeout = std::chrono::duration_cast<std::chrono::milliseconds>(
                        maxWaitTime - std::chrono::steady_clock::now());
                if (timeout <= 0ms) {
                    break;
                }

                ReleaseCallbackId releaseCallbackId;
                sp<Fence> releaseFence;
                status_t status = bbq->mBufferReleaseReader->readBlocking(releaseCallbackId,
                                                                          releaseFence, timeout);
                if (status == WOULD_BLOCK) {
                    // readBlocking was interrupted. The loop will test if we have a free buffer.
                    continue;
                }

                if (status != OK) {
                    // An error occurred or readBlocking timed out.
                    break;
                }

                std::lock_guard lock{bbq->mMutex};
                bbq->releaseBufferCallbackLocked(releaseCallbackId, releaseFence, std::nullopt,
                                                 false);
            } while (bbq->mDequeueShouldBlock);
        }

        return BufferQueueProducer::dequeueBuffer(outSlot, outFence, width, height, format, usage,
                                                  outBufferAge, outTimestamps);
    }

private:
private:
    const wp<BLASTBufferQueue> mBLASTBufferQueue;
    const wp<BLASTBufferQueue> mBLASTBufferQueue;
};
};
@@ -1400,16 +1173,6 @@ void BLASTBufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer
    *outConsumer = consumer;
    *outConsumer = consumer;
}
}


void BLASTBufferQueue::onFirstRef() {
    // safe default, most producers are expected to override this
    //
    // This is done in onFirstRef instead of BLASTBufferQueue's constructor because
    // BBQBufferQueueProducer::setMaxDequeuedBufferCount promotes a weak pointer to BLASTBufferQueue
    // to a strong pointer. If this is done in the constructor, then when the strong pointer goes
    // out of scope, it's the last reference so BLASTBufferQueue is deleted.
    mProducer->setMaxDequeuedBufferCount(2);
}

void BLASTBufferQueue::resizeFrameEventHistory(size_t newSize) {
void BLASTBufferQueue::resizeFrameEventHistory(size_t newSize) {
    // This can be null during creation of the buffer queue, but resizing won't do anything at that
    // 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
    // point in time, so just ignore. This can go away once the class relationships and lifetimes of
@@ -1459,72 +1222,4 @@ void BLASTBufferQueue::setTransactionHangCallback(
    mTransactionHangCallback = callback;
    mTransactionHangCallback = callback;
}
}


BLASTBufferQueue::BufferReleaseReader::BufferReleaseReader(
        std::unique_ptr<gui::BufferReleaseChannel::ConsumerEndpoint> endpoint)
      : mEndpoint(std::move(endpoint)) {
    mEpollFd = android::base::unique_fd(epoll_create1(0));
    if (!mEpollFd.ok()) {
        ALOGE("Failed to create buffer release epoll file descriptor. errno=%d message='%s'", errno,
              strerror(errno));
    }

    epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = mEndpoint->getFd();
    if (epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mEndpoint->getFd(), &event) == -1) {
        ALOGE("Failed to register buffer release consumer file descriptor with epoll. errno=%d "
              "message='%s'",
              errno, strerror(errno));
    }

    mEventFd = android::base::unique_fd(eventfd(0, EFD_NONBLOCK));
    event.data.fd = mEventFd.get();
    if (epoll_ctl(mEpollFd.get(), EPOLL_CTL_ADD, mEventFd.get(), &event) == -1) {
        ALOGE("Failed to register buffer release eventfd with epoll. errno=%d message='%s'", errno,
              strerror(errno));
    }
}

status_t BLASTBufferQueue::BufferReleaseReader::readNonBlocking(ReleaseCallbackId& outId,
                                                                sp<Fence>& outFence) {
    std::lock_guard lock{mMutex};
    return mEndpoint->readReleaseFence(outId, outFence);
}

status_t BLASTBufferQueue::BufferReleaseReader::readBlocking(ReleaseCallbackId& outId,
                                                             sp<Fence>& outFence,
                                                             std::chrono::milliseconds timeout) {
    epoll_event event;
    int eventCount = epoll_wait(mEpollFd.get(), &event, 1 /* maxevents */, timeout.count());

    if (eventCount == -1) {
        ALOGE("epoll_wait error while waiting for buffer release. errno=%d message='%s'", errno,
              strerror(errno));
        return UNKNOWN_ERROR;
    }

    if (eventCount == 0) {
        return TIMED_OUT;
    }

    if (event.data.fd == mEventFd.get()) {
        uint64_t value;
        if (read(mEventFd.get(), &value, sizeof(uint64_t)) == -1 && errno != EWOULDBLOCK) {
            ALOGE("error while reading from eventfd. errno=%d message='%s'", errno,
                  strerror(errno));
        }
        return WOULD_BLOCK;
    }

    std::lock_guard lock{mMutex};
    return mEndpoint->readReleaseFence(outId, outFence);
}

void BLASTBufferQueue::BufferReleaseReader::interruptBlockingRead() {
    uint64_t value = 1;
    if (write(mEventFd.get(), &value, sizeof(uint64_t)) == -1) {
        ALOGE("failed to notify dequeue event. errno=%d message='%s'", errno, strerror(errno));
    }
}

} // namespace android
} // namespace android

libs/gui/BufferReleaseChannel.cpp

deleted100644 → 0
+0 −364

File deleted.

Preview size limit exceeded, changes collapsed.

+0 −17
Original line number Original line Diff line number Diff line
@@ -194,12 +194,6 @@ status_t layer_state_t::write(Parcel& output) const
    SAFE_PARCEL(output.writeFloat, currentHdrSdrRatio);
    SAFE_PARCEL(output.writeFloat, currentHdrSdrRatio);
    SAFE_PARCEL(output.writeFloat, desiredHdrSdrRatio);
    SAFE_PARCEL(output.writeFloat, desiredHdrSdrRatio);
    SAFE_PARCEL(output.writeInt32, static_cast<int32_t>(cachingHint));
    SAFE_PARCEL(output.writeInt32, static_cast<int32_t>(cachingHint));

    const bool hasBufferReleaseChannel = (bufferReleaseChannel != nullptr);
    SAFE_PARCEL(output.writeBool, hasBufferReleaseChannel);
    if (hasBufferReleaseChannel) {
        SAFE_PARCEL(output.writeParcelable, *bufferReleaseChannel);
    }
    return NO_ERROR;
    return NO_ERROR;
}
}


@@ -345,12 +339,6 @@ status_t layer_state_t::read(const Parcel& input)
    SAFE_PARCEL(input.readInt32, &tmpInt32);
    SAFE_PARCEL(input.readInt32, &tmpInt32);
    cachingHint = static_cast<gui::CachingHint>(tmpInt32);
    cachingHint = static_cast<gui::CachingHint>(tmpInt32);


    bool hasBufferReleaseChannel;
    SAFE_PARCEL(input.readBool, &hasBufferReleaseChannel);
    if (hasBufferReleaseChannel) {
        bufferReleaseChannel = std::make_shared<gui::BufferReleaseChannel::ProducerEndpoint>();
        SAFE_PARCEL(input.readParcelable, bufferReleaseChannel.get());
    }
    return NO_ERROR;
    return NO_ERROR;
}
}


@@ -730,10 +718,6 @@ void layer_state_t::merge(const layer_state_t& other) {
    if (other.what & eFlushJankData) {
    if (other.what & eFlushJankData) {
        what |= eFlushJankData;
        what |= eFlushJankData;
    }
    }
    if (other.what & eBufferReleaseChannelChanged) {
        what |= eBufferReleaseChannelChanged;
        bufferReleaseChannel = other.bufferReleaseChannel;
    }
    if ((other.what & what) != other.what) {
    if ((other.what & what) != other.what) {
        ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
        ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
              "other.what=0x%" PRIX64 " what=0x%" PRIX64 " unmerged flags=0x%" PRIX64,
              "other.what=0x%" PRIX64 " what=0x%" PRIX64 " unmerged flags=0x%" PRIX64,
@@ -813,7 +797,6 @@ uint64_t layer_state_t::diff(const layer_state_t& other) const {
    CHECK_DIFF(diff, eColorChanged, other, color.rgb);
    CHECK_DIFF(diff, eColorChanged, other, color.rgb);
    CHECK_DIFF(diff, eColorSpaceAgnosticChanged, other, colorSpaceAgnostic);
    CHECK_DIFF(diff, eColorSpaceAgnosticChanged, other, colorSpaceAgnostic);
    CHECK_DIFF(diff, eDimmingEnabledChanged, other, dimmingEnabled);
    CHECK_DIFF(diff, eDimmingEnabledChanged, other, dimmingEnabled);
    if (other.what & eBufferReleaseChannelChanged) diff |= eBufferReleaseChannelChanged;
    return diff;
    return diff;
}
}


+0 −16
Original line number Original line Diff line number Diff line
@@ -2395,22 +2395,6 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDropI
    return *this;
    return *this;
}
}


SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBufferReleaseChannel(
        const sp<SurfaceControl>& sc,
        const std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint>& channel) {
    layer_state_t* s = getLayerState(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }

    s->what |= layer_state_t::eBufferReleaseChannelChanged;
    s->bufferReleaseChannel = channel;

    registerSurfaceControlForCallback(sc);
    return *this;
}

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


DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) {
DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) {
Loading