You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
3.8 KiB
99 lines
3.8 KiB
/*
|
|
* Copyright 2022 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <semaphore.h>
|
|
#include <cstdint>
|
|
#include <optional>
|
|
#include <vector>
|
|
|
|
#include <LocklessQueue.h>
|
|
#include <TransactionState.h>
|
|
#include <android-base/thread_annotations.h>
|
|
#include <ftl/small_map.h>
|
|
#include <ftl/small_vector.h>
|
|
|
|
namespace android {
|
|
|
|
class TestableSurfaceFlinger;
|
|
namespace surfaceflinger::frontend {
|
|
|
|
class TransactionHandler {
|
|
public:
|
|
struct TransactionFlushState {
|
|
TransactionState* transaction;
|
|
bool firstTransaction = true;
|
|
nsecs_t queueProcessTime = 0;
|
|
// Layer handles that have transactions with buffers that are ready to be applied.
|
|
ftl::SmallMap<IBinder* /* binder address */, uint64_t /* framenumber */, 15>
|
|
bufferLayersReadyToPresent = {};
|
|
// Tracks the queue with an unsignaled buffer. This is used to handle
|
|
// LatchUnsignaledConfig::AutoSingleLayer to ensure we only apply an unsignaled buffer
|
|
// if it's the only transaction that is ready to be applied.
|
|
sp<IBinder> queueWithUnsignaledBuffer = nullptr;
|
|
};
|
|
enum class TransactionReadiness {
|
|
// Transaction is ready to be applied
|
|
Ready,
|
|
// Transaction has unmet conditions (fence, present time, etc) and cannot be applied.
|
|
NotReady,
|
|
// Transaction is waiting on a barrier (another buffer to be latched first)
|
|
NotReadyBarrier,
|
|
// Transaction has an unsignaled fence but can be applied if it's the only transaction
|
|
NotReadyUnsignaled,
|
|
};
|
|
using TransactionFilter = std::function<TransactionReadiness(const TransactionFlushState&)>;
|
|
|
|
bool hasPendingTransactions();
|
|
std::vector<TransactionState> flushTransactions();
|
|
void addTransactionReadyFilter(TransactionFilter&&);
|
|
void queueTransaction(TransactionState&&);
|
|
|
|
struct StalledTransactionInfo {
|
|
pid_t pid;
|
|
uint32_t layerId;
|
|
std::string layerName;
|
|
uint64_t bufferId;
|
|
uint64_t frameNumber;
|
|
};
|
|
void onTransactionQueueStalled(uint64_t transactionId, StalledTransactionInfo);
|
|
void removeFromStalledTransactions(uint64_t transactionId);
|
|
std::optional<StalledTransactionInfo> getStalledTransactionInfo(pid_t pid);
|
|
void onLayerDestroyed(uint32_t layerId);
|
|
|
|
private:
|
|
// For unit tests
|
|
friend class ::android::TestableSurfaceFlinger;
|
|
|
|
int flushPendingTransactionQueues(std::vector<TransactionState>&, TransactionFlushState&);
|
|
void applyUnsignaledBufferTransaction(std::vector<TransactionState>&, TransactionFlushState&);
|
|
void popTransactionFromPending(std::vector<TransactionState>&, TransactionFlushState&,
|
|
std::queue<TransactionState>&);
|
|
TransactionReadiness applyFilters(TransactionFlushState&);
|
|
std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IListenerHash>
|
|
mPendingTransactionQueues;
|
|
LocklessQueue<TransactionState> mLocklessTransactionQueue;
|
|
std::atomic<size_t> mPendingTransactionCount = 0;
|
|
ftl::SmallVector<TransactionFilter, 2> mTransactionReadyFilters;
|
|
|
|
std::mutex mStalledMutex;
|
|
std::unordered_map<uint64_t /* transactionId */, StalledTransactionInfo> mStalledTransactions
|
|
GUARDED_BY(mStalledMutex);
|
|
};
|
|
} // namespace surfaceflinger::frontend
|
|
} // namespace android
|