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

Commit 1fafee4f authored by Vishnu Nair's avatar Vishnu Nair Committed by Android (Google) Code Review
Browse files

Merge "SurfaceView: Avoid destination frame updates on multiple threads 2/2" into tm-dev

parents 49630f6a d2aaab14
Loading
Loading
Loading
Loading
+18 −17
Original line number Diff line number Diff line
@@ -132,12 +132,13 @@ void BLASTBufferItemConsumer::onSidebandStreamChanged() {
    }
}

BLASTBufferQueue::BLASTBufferQueue(const std::string& name)
BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinationFrame)
      : mSurfaceControl(nullptr),
        mSize(1, 1),
        mRequestedSize(mSize),
        mFormat(PIXEL_FORMAT_RGBA_8888),
        mSyncTransaction(nullptr) {
        mSyncTransaction(nullptr),
        mUpdateDestinationFrame(updateDestinationFrame) {
    createBufferQueue(&mProducer, &mConsumer);
    // since the adapter is in the client process, set dequeue timeout
    // explicitly so that dequeueBuffer will block
@@ -184,7 +185,7 @@ BLASTBufferQueue::~BLASTBufferQueue() {
}

void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height,
                              int32_t format, SurfaceComposerClient::Transaction* outTransaction) {
                              int32_t format) {
    LOG_ALWAYS_FATAL_IF(surface == nullptr, "BLASTBufferQueue: mSurfaceControl must not be NULL");

    std::unique_lock _lock{mMutex};
@@ -193,7 +194,6 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width,
        mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format));
    }

    SurfaceComposerClient::Transaction t;
    const bool surfaceControlChanged = !SurfaceControl::isSameSurface(mSurfaceControl, surface);
    if (surfaceControlChanged && mSurfaceControl != nullptr) {
        BQA_LOGD("Updating SurfaceControl without recreating BBQ");
@@ -203,6 +203,7 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width,
    // Always update the native object even though they might have the same layer handle, so we can
    // get the updated transform hint from WM.
    mSurfaceControl = surface;
    SurfaceComposerClient::Transaction t;
    if (surfaceControlChanged) {
        t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure,
                   layer_state_t::eEnableBackpressure);
@@ -221,14 +222,12 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width,
            // If the buffer supports scaling, update the frame immediately since the client may
            // want to scale the existing buffer to the new size.
            mSize = mRequestedSize;
            SurfaceComposerClient::Transaction* destFrameTransaction =
                    (outTransaction) ? outTransaction : &t;
            destFrameTransaction->setDestinationFrame(mSurfaceControl,
                                                      Rect(0, 0, newSize.getWidth(),
                                                           newSize.getHeight()));
            if (mUpdateDestinationFrame) {
                t.setDestinationFrame(mSurfaceControl, Rect(newSize));
                applyTransaction = true;
            }
        }
    }
    if (applyTransaction) {
        t.setApplyToken(mApplyToken).apply();
    }
@@ -498,7 +497,6 @@ void BLASTBufferQueue::acquireNextBufferLocked(
    // Ensure BLASTBufferQueue stays alive until we receive the transaction complete callback.
    incStrong((void*)transactionCallbackThunk);

    const bool updateDestinationFrame = mRequestedSize != mSize;
    mSize = mRequestedSize;
    Rect crop = computeCrop(bufferItem);
    mLastBufferInfo.update(true /* hasBuffer */, bufferItem.mGraphicBuffer->getWidth(),
@@ -517,12 +515,19 @@ void BLASTBufferQueue::acquireNextBufferLocked(

    mSurfaceControlsWithPendingCallback.push(mSurfaceControl);

    if (updateDestinationFrame) {
        t->setDestinationFrame(mSurfaceControl, Rect(0, 0, mSize.getWidth(), mSize.getHeight()));
    if (mUpdateDestinationFrame) {
        t->setDestinationFrame(mSurfaceControl, Rect(mSize));
    } else {
        const bool ignoreDestinationFrame =
                bufferItem.mScalingMode == NATIVE_WINDOW_SCALING_MODE_FREEZE;
        t->setFlags(mSurfaceControl,
                    ignoreDestinationFrame ? layer_state_t::eIgnoreDestinationFrame : 0,
                    layer_state_t::eIgnoreDestinationFrame);
    }
    t->setBufferCrop(mSurfaceControl, crop);
    t->setTransform(mSurfaceControl, bufferItem.mTransform);
    t->setTransformToDisplayInverse(mSurfaceControl, bufferItem.mTransformToDisplayInverse);
    t->setAutoRefresh(mSurfaceControl, bufferItem.mAutoRefresh);
    if (!bufferItem.mIsAutoTimestamp) {
        t->setDesiredPresentTime(bufferItem.mTimestamp);
    }
@@ -532,10 +537,6 @@ void BLASTBufferQueue::acquireNextBufferLocked(
        mNextFrameTimelineInfoQueue.pop();
    }

    if (mAutoRefresh != bufferItem.mAutoRefresh) {
        t->setAutoRefresh(mSurfaceControl, bufferItem.mAutoRefresh);
        mAutoRefresh = bufferItem.mAutoRefresh;
    }
    {
        std::unique_lock _lock{mTimestampMutex};
        auto dequeueTime = mDequeueTimestamps.find(buffer->getId());
+8 −8
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ class BLASTBufferQueue
    : public ConsumerBase::FrameAvailableListener, public BufferItemConsumer::BufferFreedListener
{
public:
    BLASTBufferQueue(const std::string& name);
    BLASTBufferQueue(const std::string& name, bool updateDestinationFrame = true);
    BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
                     int height, int32_t format);

@@ -100,8 +100,7 @@ public:
    void applyPendingTransactions(uint64_t frameNumber);
    SurfaceComposerClient::Transaction* gatherPendingTransactions(uint64_t frameNumber);

    void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format,
                SurfaceComposerClient::Transaction* outTransaction = nullptr);
    void update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height, int32_t format);

    status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless);
    status_t setFrameTimelineInfo(const FrameTimelineInfo& info);
@@ -218,11 +217,6 @@ private:
    std::vector<std::tuple<uint64_t /* framenumber */, SurfaceComposerClient::Transaction>>
            mPendingTransactions GUARDED_BY(mMutex);

    // Last requested auto refresh state set by the producer. The state indicates that the consumer
    // should acquire the next frame as soon as it can and not wait for a frame to become available.
    // This is only relevant for shared buffer mode.
    bool mAutoRefresh GUARDED_BY(mMutex) = false;

    std::queue<FrameTimelineInfo> mNextFrameTimelineInfoQueue GUARDED_BY(mMutex);

    // Tracks the last acquired frame number
@@ -250,6 +244,12 @@ private:
    // Flag to determine if syncTransaction should only acquire a single buffer and then clear or
    // continue to acquire buffers until explicitly cleared
    bool mAcquireSingleBuffer GUARDED_BY(mMutex) = true;

    // True if BBQ will update the destination frame used to scale the buffer to the requested size.
    // If false, the caller is responsible for updating the destination frame on the BBQ
    // surfacecontol. This is useful if the caller wants to synchronize the buffer scale with
    // additional scales in the hierarchy.
    bool mUpdateDestinationFrame GUARDED_BY(mMutex) = true;
};

} // namespace android
+7 −2
Original line number Diff line number Diff line
@@ -130,6 +130,11 @@ struct layer_state_t {
        // have presentation timestamps, then we may drop buffers.
        eEnableBackpressure = 0x100,       // ENABLE_BACKPRESSURE
        eLayerIsDisplayDecoration = 0x200, // DISPLAY_DECORATION
        // Ignore any destination frame set on the layer. This is used when the buffer scaling mode
        // is freeze and the destination frame is applied asynchronously with the buffer submission.
        // This is needed to maintain compatibility for SurfaceView scaling behavior.
        // See SurfaceView scaling behavior for more details.
        eIgnoreDestinationFrame = 0x400,
    };

    enum {
+2 −1
Original line number Diff line number Diff line
@@ -271,7 +271,8 @@ static bool assignTransform(ui::Transform* dst, ui::Transform& from) {
// Translate destination frame into scale and position. If a destination frame is not set, use the
// provided scale and position
bool BufferStateLayer::updateGeometry() {
    if (mDrawingState.destinationFrame.isEmpty()) {
    if ((mDrawingState.flags & layer_state_t::eIgnoreDestinationFrame) ||
        mDrawingState.destinationFrame.isEmpty()) {
        // If destination frame is not set, use the requested transform set via
        // BufferStateLayer::setPosition and BufferStateLayer::setMatrix.
        return assignTransform(&mDrawingState.transform, mRequestedTransform);
+3 −0
Original line number Diff line number Diff line
@@ -2142,6 +2142,9 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet
            (*protoMap)[entry.first] = std::string(entry.second.cbegin(), entry.second.cend());
        }
    }

    LayerProtoHelper::writeToProto(state.destinationFrame,
                                   [&]() { return layerInfo->mutable_destination_frame(); });
}

bool Layer::isRemovedFromCurrentState() const  {
Loading