SurfaceFlinger代码笔记

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。

相关推荐
Damon_X24 天前
帧缓存的分配
display
锦天6 个月前
弹性布局 flex layout HTML CSS
css·html·display·flex·弹性布局·justify-content·flex layout
唐诺1 年前
Android 获取屏幕方向,根据屏幕旋转角度判断屏幕实际方向
android·display·windowmanager·rotation
Laurence1 年前
在 spark-sql / spark-shell / hive / beeline 中粘贴 sql、程序脚本时的常见错误
hive·sql·spark·display·possibilities