本內(nèi)容基于自己對于代碼的理解以及網(wǎng)上大牛的博客參考寫的留拾,作為回顧時的參考之用。
一泞辐、SurfaceFlinger事務(wù)處理handleTransaction()
這里為什么要用Transaction(事務(wù))這個詞呢腕铸? 我們從數(shù)據(jù)庫事務(wù)概念大致可以看出一點(diǎn)端倪, 它的其中一個很重要的信息就是說"將一組相關(guān)操作組合成一個單元去處理", 這個有點(diǎn)意思惜犀,這個思路也運(yùn)用在了SurfaceFlinger里,為什么呢狠裹?handleTransaction就是處理一次事務(wù)虽界,因?yàn)槊恳粋€Vsync去刷新一次,但是在一個Vsync周期里涛菠,Layer中的屬性可能改變了莉御,由于Layer的屬性有很多,如果改變一個就去觸發(fā)相關(guān)操作俗冻,這樣顯然是浪費(fèi)資源的事情礁叔,所以正確的做法就是當(dāng)Layer屬性的值改變了,然后記錄下來迄薄,最后在 handleTransaction 一次就處理完了琅关。
事務(wù)標(biāo)志位有三種基本類形(可以是多種組合)
enum {
eTransactionNeeded = 0x01, //Layer的屬性發(fā)生變化了,表示需要處理事務(wù)
eTraversalNeeded = 0x02, //遍歷的是SurfaceFlinger中所有的Layer
eDisplayTransactionNeeded = 0x04, //這個是顯示器相關(guān)的事務(wù),如顯示器hotplug
eTransactionMask = 0x07 //掩碼
};
1.1 SurfaceFlinger中幾個重要變量
State mCurrentState
SurfaceFlinger下一幀的狀態(tài)State mDrawingState
當(dāng)前正在繪制的狀態(tài)讥蔽,這個是SurfaceFlinger處理完事務(wù)后更新出來的狀態(tài)涣易,是最終的狀態(tài)mVisibleRegionsDirty
表示當(dāng)前可見區(qū)域是否臟了,如果臟了的話冶伞,比如(layer added/removed, Display added/remove相關(guān))在最后合成的時候會對每個屏幕重建layer stack, 但是一般都為false
struct State {
LayerVector layersSortedByZ; //SurfaceFlinger中所有的按照Z order排序的 Layer
DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays; //外接的顯示屏
};
1.2 handleTransaction
void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
{
ATRACE_CALL();
// here we keep a copy of the drawing state (that is the state that's
// going to be overwritten by handleTransactionLocked()) outside of
// mStateLock so that the side-effects of the State assignment
// don't happen with mStateLock held (which can cause deadlocks).
//保存 mDrawingState, 但是這里根本沒有使用到
State drawingState(mDrawingState);
Mutex::Autolock _l(mStateLock);
const nsecs_t now = systemTime();
mDebugInTransaction = now;
// Here we're guaranteed that some transaction flags are set
// so we can call handleTransactionLocked() unconditionally.
// We call getTransactionFlags(), which will also clear the flags,
// with mStateLock held to guarantee that mCurrentState won't change
// until the transaction is committed.
//獲得SurfaceFlinger中的Transaction標(biāo)志位
transactionFlags = getTransactionFlags(eTransactionMask);
handleTransactionLocked(transactionFlags); //真正處理事務(wù)的函數(shù)
mLastTransactionTime = systemTime() - now;
mDebugInTransaction = 0;
invalidateHwcGeometry();
// here the transaction has been committed
}
1.3 handleTransactionLocked
void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
//獲得當(dāng)前所有Layer
const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
const size_t count = currentLayers.size();
// Notify all layers of available frames
for (size_t i = 0; i < count; ++i) {
//檢查當(dāng)前Frame是否是SyncPoint需要的(也就說之前想延遲的Buffer已經(jīng)到來了), 如果是新症,則設(shè)置SyncPoint中mFrameIsAvailable為true
currentLayers[i]->notifyAvailableFrames();
}
/*
* Traversal of the children
* (perform the transaction for each of them if needed)
*/
//遍歷所有的Layer, 讓Layer去執(zhí)行自己的事務(wù)
if (transactionFlags & eTraversalNeeded) {
for (size_t i=0 ; i<count ; i++) {
const sp<Layer>& layer(currentLayers[i]);
// 獲得Layer的Transaction flags
uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
if (!trFlags) continue;
// Layer處理自己的事務(wù)
const uint32_t flags = layer->doTransaction(0);
if (flags & Layer::eVisibleRegion)
//如果Layer的可見區(qū)域改變了,則SurfaceFlinger就標(biāo)注出當(dāng)前可視區(qū)域改變了
mVisibleRegionsDirty = true;
}
}
/*
* Perform display own transactions if needed
*/
//跟顯示器相關(guān)的事務(wù)响禽,比如hotplug顯示屏, 初始化/銷除顯示屏徒爹,顯示屏的配置變化,
if (transactionFlags & eDisplayTransactionNeeded) {
}
if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
// The transform hint might have changed for some layers
// (either because a display has changed, or because a layer
// as changed).
//
// Walk through all the layers in currentLayers,
// and update their transform hint.
//
// If a layer is visible only on a single display, then that
// display is used to calculate the hint, otherwise we use the
// default display.
//
// NOTE: we do this here, rather than in rebuildLayerStacks() so that
// the hint is set before we acquire a buffer from the surface texture.
//
// NOTE: layer transactions have taken place already, so we use their
// drawing state. However, SurfaceFlinger's own transaction has not
// happened yet, so we must use the current state layer list
// (soon to become the drawing state list).
//
sp<const DisplayDevice> disp;
uint32_t currentlayerStack = 0;
for (size_t i=0; i<count; i++) {
// NOTE: we rely on the fact that layers are sorted by
// layerStack first (so we don't have to traverse the list
// of displays for every layer).
const sp<Layer>& layer(currentLayers[i]);
//獲得Layer的 layer stack
uint32_t layerStack = layer->getDrawingState().layerStack;
//通過遍歷所有的Display來找到Layer所在的顯示屏
if (i==0 || currentlayerStack != layerStack) {
currentlayerStack = layerStack;
// figure out if this layerstack is mirrored
// (more than one display) if so, pick the default display,
// if not, pick the only display it's on.
disp.clear();
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
sp<const DisplayDevice> hw(mDisplays[dpy]);
if (hw->getLayerStack() == currentlayerStack) {
if (disp == NULL) {
disp = hw;
} else {
disp = NULL;
break;
}
}
}
}
if (disp == NULL) {
// NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
// redraw after transform hint changes. See bug 8508397.
// could be null when this layer is using a layerStack
// that is not visible on any display. Also can occur at
// screen off/on times.
disp = getDefaultDisplayDevice();
}
//更新Layer的旋轉(zhuǎn)方向芋类,最終會體現(xiàn)在 BufferQueueCore中的mTransformHint變量
layer->updateTransformHint(disp);
}
}
/*
* Perform our own transaction if needed
*/
//前面都是執(zhí)行的Layer相關(guān)的事務(wù)
//下面就是執(zhí)行SurfaceFlinger自己的事務(wù)
const LayerVector& layers(mDrawingState.layersSortedByZ);
if (currentLayers.size() > layers.size()) {
// layers have been added , 有新的Layer加入
mVisibleRegionsDirty = true;
}
// some layers might have been removed, so
// we need to update the regions they're exposing.
//下面有Layer移出了的情況
if (mLayersRemoved) {
mLayersRemoved = false;
mVisibleRegionsDirty = true;
const size_t count = layers.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Layer>& layer(layers[i]);
if (currentLayers.indexOf(layer) < 0) {
// this layer is not visible anymore
// TODO: we could traverse the tree from front to back and
// compute the actual visible region
// TODO: we could cache the transformed region
const Layer::State& s(layer->getDrawingState());
//獲得移除的Layer的可見區(qū)域, 這塊可見區(qū)域就是dirty的
Region visibleReg = s.active.transform.transform(
Region(Rect(s.active.w, s.active.h)));
//找到被移除掉的Layer所在的Display, 然后更新Diplay的dirty 區(qū)域隆嗅,也就是對region做或運(yùn)算
invalidateLayerStack(s.layerStack, visibleReg);
}
}
}
//提交事務(wù)
commitTransaction();
//更新Display中光標(biāo)的位置
updateCursorAsync();
}
1.4 commitTransaction
void SurfaceFlinger::commitTransaction()
{
//mLayersPendingRemoval是保存的是pending 著需要移除的Layer. 比如APP調(diào)用destroySurface
if (!mLayersPendingRemoval.isEmpty()) {
// Notify removed layers now that they can't be drawn from
for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
mLayersPendingRemoval[i]->onRemoved(); //回調(diào) onRemoved, 調(diào)用Consumer的consumerDisconnect侯繁,清理BufferQueueBuffer
}
mLayersPendingRemoval.clear();
}
// If this transaction is part of a window animation then the next frame
// we composite should be considered an animation as well.
mAnimCompositionPending = mAnimTransactionPending;
//更新 mDrawingState
mDrawingState = mCurrentState;
mTransactionPending = false;
mAnimTransactionPending = false;
//釋放mTransactionCV, 如果SurfaceFlinger正在處理事務(wù)榛瓮,而這時如果調(diào)用setTransactionState就可能會一直等著mTransactionCV,
//因?yàn)閟etTransactionState可能會改變SurfaceFlinger的Transaction標(biāo)志位,導(dǎo)致前后不一致
mTransactionCV.broadcast();
}
二巫击、Layer處理自己的事務(wù)
2.1 Layer中重要變量
sp<NativeHandle> mSidebandStream; //sideband buffer stream
std::list<std::shared_ptr<SyncPoint>> mLocalSyncPoints;
//一系列的SyncPoint, 這些SyncPoint是在特定的Frame來了才更新State mCurrentState;
表示Layer下一幀的屬性狀態(tài)禀晓,當(dāng)某個屬性變化時,直接操作該變量State mDrawingState;
表示當(dāng)前正在繪制的幀的屬性狀態(tài)坝锰。Layer處理完事務(wù)后粹懒,最終的用于繪制的狀態(tài)
struct State {
Geometry active; //當(dāng)前Layer的可見區(qū)域
Geometry requested; //請求的Layer的可見區(qū)域, 在Layer做doTransaction時會將 requested賦值給active. setSize/setMatrix/setPosition
uint32_t z;
uint32_t layerStack; //layerStack指明當(dāng)前Layer屬于哪個Display,Display的layer stack可以用 hw->getLayerStack獲得
uint8_t alpha;
uint8_t flags;
uint8_t mask;
uint8_t reserved[2];
int32_t sequence; //當(dāng)Layer的屬性變化時顷级, sequence就會加1
bool modified; //當(dāng)Layer的屬性變化了凫乖,該變量就會被置為true
Rect crop;
Rect finalCrop;
// If set, defers this state update until the Layer identified by handle
// receives a frame with the given frameNumber
sp<IBinder> handle; //延遲更新特定的Frame
uint64_t frameNumber; //這個就是Handle要延遲的Frame號
// the transparentRegion hint is a bit special, it's latched only
// when we receive a buffer -- this is because it's "content"
// dependent.
Region activeTransparentRegion;
Region requestedTransparentRegion;
};
struct Geometry {
uint32_t w;
uint32_t h;
Transform transform; //Geometry的傳輸矩陣
};
2.2 doTransaction
// Layer處理的事務(wù)
uint32_t Layer::doTransaction(uint32_t flags) {
ATRACE_CALL();
pushPendingState(); //將mCurrentState保存到mPendingStates中
//獲得Layer的mCurrentState, 這里為什么不直接用mCurrentState呢?是因?yàn)榉乐筸CurrentState在處理的時候被其它線程給改變了
Layer::State c = getCurrentState();
if (!applyPendingStates(&c)) { //針對 SyncPoints相關(guān)
return 0;
}
//獲得上一次的Drawing state
const Layer::State& s(getDrawingState());
//如果requested的可見區(qū)域與舊的可見區(qū)域不同了,則size changed
const bool sizeChanged = (c.requested.w != s.requested.w) ||
(c.requested.h != s.requested.h);
if (sizeChanged) {
// 如果size changed, 把新的 w|h 設(shè)置到 BufferQueueCore中的 mDefaultWidth|mDefaultHeight中去
mSurfaceFlingerConsumer->setDefaultBufferSize(
c.requested.w, c.requested.h);
}
//如果新的請求的 w|h 與新的原本要顯示的區(qū)域不同帽芽,表明是 resize了
const bool resizePending = (c.requested.w != c.active.w) ||
(c.requested.h != c.active.h);
if (!isFixedSize()) {
if (resizePending && mSidebandStream == NULL) {
//resize只發(fā)生在非固定尺寸模式删掀,并且sideband layer(sideband buffer stream)為空的情況
// don't let Layer::doTransaction update the drawing state
// if we have a pending resize, unless we are in fixed-size mode.
// the drawing state will be updated only once we receive a buffer
// with the correct size.
//
// in particular, we want to make sure the clip (which is part
// of the geometry state) is latched together with the size but is
// latched immediately when no resizing is involved.
//
// If a sideband stream is attached, however, we want to skip this
// optimization so that transactions aren't missed when a buffer
// never arrives
flags |= eDontUpdateGeometryState;
}
}
// always set active to requested, unless we're asked not to
// this is used by Layer, which special cases resizes.
if (flags & eDontUpdateGeometryState) { //這個是在resize里面做的,
} else {
//這里是允許更新 可見區(qū)域
Layer::State& editCurrentState(getCurrentState());
if (mFreezePositionUpdates) {
float tx = c.active.transform.tx();
float ty = c.active.transform.ty();
c.active = c.requested;
c.active.transform.set(tx, ty);
editCurrentState.active = c.active;
} else {
editCurrentState.active = editCurrentState.requested;
c.active = c.requested;
}
}
if (s.active != c.active) {
// invalidate and recompute the visible regions if needed
flags |= Layer::eVisibleRegion;
}
// 只要Layer有屬性發(fā)生變化了导街,sequence就會加1,這樣可以很直觀判斷是否當(dāng)前的state和舊的state是否發(fā)生變化了
// 但是這樣并不能保證sequence相同披泪,但是屬性變化的這種情況
if (c.sequence != s.sequence) {
// invalidate and recompute the visible regions if needed
flags |= eVisibleRegion;
this->contentDirty = true;
// we may use linear filtering, if the matrix scales us
const uint8_t type = c.active.transform.getType();
mNeedsFiltering = (!c.active.transform.preserveRects() ||
(type >= Transform::SCALE));
}
// If the layer is hidden, signal and clear out all local sync points so
// that transactions for layers depending on this layer's frames becoming
// visible are not blocked
//是否Layer是hide的
if (c.flags & layer_state_t::eLayerHidden) {
Mutex::Autolock lock(mLocalSyncPointMutex);
for (auto& point : mLocalSyncPoints) {
point->setFrameAvailable();
}
mLocalSyncPoints.clear();
}
// Commit the transaction
//提交事務(wù)
commitTransaction(c);
return flags;
}
2.3 pushPendingState
void Layer::pushPendingState() {
//只要Layer的屬性改變了,都會將modified置為true
if (!mCurrentState.modified) {
return;
}
// If this transaction is waiting on the receipt of a frame, generate a sync
// point and send it to the remote layer.
if (mCurrentState.handle != nullptr) { //表示當(dāng)前需要等著特定的frame(frame number號標(biāo)識)
sp<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
sp<Layer> handleLayer = handle->owner.promote();
if (handleLayer == nullptr) {
ALOGE("[%s] Unable to promote Layer handle", mName.string());
// If we can't promote the layer we are intended to wait on,
// then it is expired or otherwise invalid. Allow this transaction
// to be applied as per normal (no synchronization).
mCurrentState.handle = nullptr;
} else {
//創(chuàng)建一個 SyncPoint搬瑰, 表示只在 frameNumber的這個Frame才更新
auto syncPoint = std::make_shared<SyncPoint>(
mCurrentState.frameNumber);
if (handleLayer->addSyncPoint(syncPoint)) { //加入到 mLocalSyncPoints
mRemoteSyncPoints.push_back(std::move(syncPoint));
} else {
// We already missed the frame we're supposed to synchronize
// on, so go ahead and apply the state update
mCurrentState.handle = nullptr;
}
}
// Wake us up to check if the frame has been received
setTransactionFlags(eTransactionNeeded);
}
//將當(dāng)前的狀態(tài)保存在mPendingStates, 接下來會處理到
mPendingStates.push_back(mCurrentState);
}
//提交事務(wù)款票, 也就是更新 Layer的 mDrawingState
void Layer::commitTransaction(const State& stateToCommit) {
mDrawingState = stateToCommit;
}