native\native\libs\gui\SurfaceComposerClient.cpp文件里的
class BufferCache类可能是ClientCache的proxy端,关注cache函数的调用,看看CS两侧是怎么建立连接的。
ClientCache类的注释:
// This class manages a cache of buffer handles between SurfaceFlinger clients
// and the SurfaceFlinger process which optimizes away some of the cost of
// sending buffer handles across processes.
//
// Buffers are explicitly cached and uncached by the SurfaceFlinger client. When
// a buffer is uncached, it is not only purged from this cache, but the buffer
// ID is also passed down to CompositionEngine to purge it from a similar cache
// used between SurfaceFlinger and Composer HAL. The buffer ID used to purge
// both the SurfaceFlinger side of this other cache, as well as Composer HAL's
// side of the cache.
//
class ClientCache
看上去这是个从上到下的机制,还涉及到HAL
BufferCache的注释:
/**
* We use the BufferCache to reduce the overhead of exchanging GraphicBuffers with
* the server. If we were to simply parcel the GraphicBuffer we would pay two overheads
* 1. Cost of sending the FD
* 2. Cost of importing the GraphicBuffer with the mapper in the receiving process.
* To ease this cost we implement the following scheme of caching buffers to integers,
* or said-otherwise, naming them with integers. This is the scheme known as slots in
* the legacy BufferQueue system.
* 1. When sending Buffers to SurfaceFlinger we look up the Buffer in the cache.
* 2. If there is a cache-hit we remove the Buffer from the Transaction and instead
* send the cached integer.
* 3. If there is a cache miss, we cache the new buffer and send the integer
* along with the Buffer, SurfaceFlinger on it's side creates a new cache
* entry, and we use the integer for further communication.
* A few details about lifetime:
* 1. The cache evicts by LRU. The server side cache is keyed by BufferCache::getToken
* which is per process Unique. The server side cache is larger than the client side
* cache so that the server will never evict entries before the client.
* 2. When the client evicts an entry it notifies the server via an uncacheBuffer
* transaction.
* 3. The client only references the Buffers by ID, and uses buffer->addDeathCallback
* to auto-evict destroyed buffers.
*/
class BufferCache
VsyncSchedule
的mRequestHardwareVsync是一个lambda表达式:
void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr) {
auto schedulePtr = std::make_shared<VsyncSchedule>(displayId, mFeatures,
[this](PhysicalDisplayId id, bool enable) {
onHardwareVsyncRequest(id, enable);
});
然后又调回到
VsyncSchedule::setPendingHardwareVsyncState
和
SurfaceFlinger::requestHardwareVsync
下面看另一个复杂的调用关系:
void SurfaceFlinger::onComposerHalVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp,
std::optional<hal::VsyncPeriodNanos> vsyncPeriod) {
ATRACE_NAME(vsyncPeriod
? ftl::Concat(func, ' ', hwcDisplayId, ' ', *vsyncPeriod, "ns").c_str()
: ftl::Concat(func, ' ', hwcDisplayId).c_str());
Mutex::Autolock lock(mStateLock);
if (const auto displayIdOpt = getHwComposer().onVsync(hwcDisplayId, timestamp)) {
if (mScheduler->addResyncSample(*displayIdOpt, timestamp, vsyncPeriod)) {
// period flushed
mScheduler->modulateVsync(displayIdOpt, &VsyncModulator::onRefreshRateChangeCompleted);
}
}
}
addResyncSample是一个模板成员函数:
template <typename... Args,
typename Handler = std::optional<VsyncConfig> (VsyncModulator::*)(Args...)>
void modulateVsync(std::optional<PhysicalDisplayId> id, Handler handler, Args... args) {
if (id) {
std::scoped_lock lock(mDisplayLock);
ftl::FakeGuard guard(kMainThreadContext);
if (id != mPacesetterDisplayId) {
return;
}
}
if (const auto config = (*mVsyncModulator.*handler)(args...)) {
setVsyncConfig(*config, getPacesetterVsyncPeriod());
}
}
它的参数Handler是VsyncModulator的一个成员函数:onRefreshRateChangeCompleted。