void SurfaceComposerClient::Transaction::cacheBuffers() {
if (!mContainsBuffer) {
return;
}
size_t count = 0;
for (auto& [handle, cs] : mComposerStates) {
layer_state_t* s = &(mComposerStates[handle].state);
if (!(s->what & layer_state_t::eBufferChanged)) {
continue;
} else if (s->what & layer_state_t::eCachedBufferChanged) {
// If eBufferChanged and eCachedBufferChanged are both trued then that means
// we already cached the buffer in a previous call to cacheBuffers, perhaps
// from writeToParcel on a Transaction that was merged in to this one.
continue;
}
// Don't try to cache a null buffer. Sending null buffers is cheap so we shouldn't waste
// time trying to cache them.
if (!s->buffer) {
continue;
}
mContainsBuffer
表示是否调用 setBuffer()
。
- 遍历
mComposerStates
,当满足如下 3 个条件中一个则跳过该 layer_state_t:
- Buffer 没有变化。
- 已经缓存过。
buffer
是 null
。因为 null
没有传递成本,所以没必要缓存,缓存反而有成本。
uint64_t cacheId = 0;
status_t ret = BufferCache::getInstance().getCacheId(s->buffer, &cacheId);
if (ret == NO_ERROR) {
// Cache-hit. Strip the buffer and send only the id.
s->what &= ~static_cast<uint64_t>(layer_state_t::eBufferChanged);
s->buffer = nullptr;
} else {
// Cache-miss. Include the buffer and send the new cacheId.
cacheId = BufferCache::getInstance().cache(s->buffer);
}
s->what |= layer_state_t::eCachedBufferChanged;
s->cachedBuffer.token = BufferCache::getInstance().getToken();
s->cachedBuffer.id = cacheId;
// If we have more buffers than the size of the cache, we should stop caching so we don't
// evict other buffers in this transaction
count++;
if (count >= BUFFER_CACHE_MAX_SIZE) {
break;
}
}