題外話
剛剛開始著筆寫作這篇文章時,正好看電視在採訪一位92歲的考古學家,在他的日記中有這樣一句話,寫在這裡與君共勉“不要等待幸運的降臨,要去努力的掌握知識”。如此樸實的一句話,此時此刻,正適合我們。
1 前言
// create the native surface
sp<SurfaceControl> surfaceControl = surfaceComposerClient->createSurface(mName,
resolution.getWidth(),
resolution.getHeight(), PIXEL_FORMAT_RGBA_8888,
ISurfaceComposerClient::eFXSurfaceBufferState,
/*parent*/ nullptr);
注:本片涉及的程式碼
/frameworks/native/libs/gui/SurfaceComposerClient.cpp
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
/frameworks/native/services/surfaceflinger/Client.cpp
/frameworks/native/libs/gui/ISurfaceComposer.cpp
2 createSurface的流程
SurfaceComposerClient::createSurface
程式碼如下,比較簡單,使用時需要傳遞一個名字(name),指定寬高資訊,指定格式(format)等,返回一個SurfaceControl的指標,這個方法中呼叫了createSurfaceChecked
* /frameworks/native/libs/gui/SurfaceComposerClient.cpp
sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h,
PixelFormat format, uint32_t flags,
const sp<IBinder>& parentHandle,
LayerMetadata metadata,
uint32_t* outTransformHint) {
sp<SurfaceControl> s;
createSurfaceChecked(name, w, h, format, &s, flags, parentHandle, std::move(metadata),
outTransformHint);
return s;
}
SurfaceComposerClient::createSurfaceChecked
這個方法的核心是 mClient->createSurface ,前面講過(sp<ISurfaceComposerClient> mClient)是Client的代理客戶端,最終呼叫到服務端 Client::createSurface
這個方法中還有兩個變數:
sp<IBinder> handle == 這個代表什麼? ==> SurfaceFlinger中建立的Layer的控制程式碼或標識
sp<IGraphicBufferProducer> gbp == 他又是誰?==>這個gbp貌似已經沒有實際用途了,BLASTBufferQueue分擔了任務
* /frameworks/native/libs/gui/SurfaceComposerClient.cpp
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
PixelFormat format,
sp<SurfaceControl>* outSurface, uint32_t flags,
const sp<IBinder>& parentHandle,
LayerMetadata metadata,
uint32_t* outTransformHint) {
sp<SurfaceControl> sur;
status_t err = mStatus;
if (mStatus == NO_ERROR) {
sp<IBinder> handle;
sp<IGraphicBufferProducer> gbp;
uint32_t transformHint = 0;
int32_t id = -1;
err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
&handle, &gbp, &id, &transformHint);
if (outTransformHint) {
*outTransformHint = transformHint;
}
ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
if (err == NO_ERROR) {
*outSurface =
new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
}
}
return err;
}
Client::createSurface
* /frameworks/native/services/surfaceflinger/Client.cpp
status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
uint32_t flags, const sp<IBinder>& parentHandle,
LayerMetadata metadata, sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
uint32_t* outTransformHint) {
// We rely on createLayer to check permissions.
return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
parentHandle, outLayerId, nullptr, outTransformHint);
}
SurfaceFlinger::createLayer
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,
uint32_t h, PixelFormat format, uint32_t flags,
LayerMetadata metadata, sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp,
const sp<IBinder>& parentHandle, int32_t* outLayerId,
const sp<Layer>& parentLayer, uint32_t* outTransformHint) {
if (int32_t(w|h) < 0) {
ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
int(w), int(h));
return BAD_VALUE;
}
ALOG_ASSERT(parentLayer == nullptr || parentHandle == nullptr,
"Expected only one of parentLayer or parentHandle to be non-null. "
"Programmer error?");
status_t result = NO_ERROR;
sp<Layer> layer;
std::string uniqueName = getUniqueLayerName(name.string());
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceBufferQueue:
case ISurfaceComposerClient::eFXSurfaceBufferState: {
result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags,
std::move(metadata), handle, &layer);
std::atomic<int32_t>* pendingBufferCounter = layer->getPendingBufferCounter();
if (pendingBufferCounter) {
std::string counterName = layer->getPendingBufferCounterName();
mBufferCountTracker.add((*handle)->localBinder(), counterName,
pendingBufferCounter);
}
} break;
case ISurfaceComposerClient::eFXSurfaceEffect:
// check if buffer size is set for color layer.
if (w > 0 || h > 0) {
ALOGE("createLayer() failed, w or h cannot be set for color layer (w=%d, h=%d)",
int(w), int(h));
return BAD_VALUE;
}
result = createEffectLayer(client, std::move(uniqueName), w, h, flags,
std::move(metadata), handle, &layer);
break;
case ISurfaceComposerClient::eFXSurfaceContainer:
// check if buffer size is set for container layer.
if (w > 0 || h > 0) {
ALOGE("createLayer() failed, w or h cannot be set for container layer (w=%d, h=%d)",
int(w), int(h));
return BAD_VALUE;
}
result = createContainerLayer(client, std::move(uniqueName), w, h, flags,
std::move(metadata), handle, &layer);
break;
default:
result = BAD_VALUE;
break;
}
if (result != NO_ERROR) {
return result;
}
bool addToRoot = callingThreadHasUnscopedSurfaceFlingerAccess();
result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer, addToRoot,
outTransformHint);
if (result != NO_ERROR) {
return result;
}
mInterceptor->saveSurfaceCreation(layer);
setTransactionFlags(eTransactionNeeded);
*outLayerId = layer->sequence;
return result;
}
1. 檢查寬高數值是否合法,寬/高不應為負值;
2. 檢查parentLayer/parentHandle,對於我們的應用來說,沒有parent,兩者都為 null;
3. 獲取一個獨一無二的Layer name,即不能有重名的Layer;
4. 根據flags去建立對應型別的Layer ⇒ createBufferStateLayer or createEffectLayer or createContainerLayer
Surface建立標誌 | SurfaceFlinger方法 | Layer例項 | 簡單說明 |
eFXSurfaceBufferQueue | createBufferStateLayer | BufferStateLayer |
Creates a normal surface. 標準的Surface |
eFXSurfaceBufferState | |||
eFXSurfaceEffect | createEffectLayer | EffectLayer |
Creates a effect surface which represents a solid color and or shadows. 純色或陰影的顯示效果的Surface |
eFXSurfaceContainer | createContainerLayer | ContainerLayer |
Creates a container surface. This surface will have no buffers and will only be used as a container for other surfaces, or for its InputInfo. 建立surface容器。此surface沒有緩衝區,僅用作其他surfaces或InputInfo的容器。 |
Tips:
有意思的一點是 BufferQueueLayer 貌似不再有實際用途了
比如addClientLayer時設定一些Transaction State
感覺這裡講解的還是迷迷糊糊,雲裡霧裡,其實我自己也很多疑惑
Surface or Layer建立完成,應用得到了什麼?
回過頭再瞅一眼 SurfaceComposerClient::createSurfaceChecked 這個函式的程式碼,客戶端主要獲取到以下幾個資訊:
sp<IBinder> handle;
sp<IGraphicBufferProducer> gbp;
uint32_t transformHint = 0;
int32_t id = -1;
Layer handle
這個handle是在建立Layer時賦值的
status_t SurfaceFlinger::createBufferStateLayer(const sp<Client>& client, std::string name,
uint32_t w, uint32_t h, uint32_t flags,
LayerMetadata metadata, sp<IBinder>* handle,
sp<Layer>* outLayer) {
LayerCreationArgs args(this, client, std::move(name), w, h, flags, std::move(metadata));
args.textureName = getNewTexture();
sp<BufferStateLayer> layer = getFactory().createBufferStateLayer(args);
*handle = layer->getHandle();
*outLayer = layer;
return NO_ERROR;
}
sp<IBinder> Layer::getHandle() {
Mutex::Autolock _l(mLock);
if (mGetHandleCalled) {
ALOGE("Get handle called twice" );
return nullptr;
}
mGetHandleCalled = true;
return new Handle(mFlinger, this);
}
/*
* The layer handle is just a BBinder object passed to the client
* (remote process) -- we don't keep any reference on our side such that
* the dtor is called when the remote side let go of its reference.
*
* LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for
* this layer when the handle is destroyed.
*/
class Handle : public BBinder, public LayerCleaner {
public:
Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
: LayerCleaner(flinger, layer), owner(layer) {}
wp<Layer> owner;
};
if (err == NO_ERROR) {
*outSurface =
new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
}
3 事務處理
SurfaceComposerClient::Transaction{}
.setLayer(surfaceControl, std::numeric_limits<int32_t>::max())
.show(surfaceControl)
.apply();
* /frameworks/native/libs/gui/include/gui/LayerState.h
struct ComposerState {
layer_state_t state;
status_t write(Parcel& output) const;
status_t read(const Parcel& input);
};
enum {
ePositionChanged = 0x00000001,
eLayerChanged = 0x00000002,
eSizeChanged = 0x00000004,
eAlphaChanged = 0x00000008,
eMatrixChanged = 0x00000010,
eTransparentRegionChanged = 0x00000020,
eFlagsChanged = 0x00000040,
eLayerStackChanged = 0x00000080,
eReleaseBufferListenerChanged = 0x00000400,
eShadowRadiusChanged = 0x00000800,
eLayerCreated = 0x00001000,
eBufferCropChanged = 0x00002000,
eRelativeLayerChanged = 0x00004000,
eReparent = 0x00008000,
eColorChanged = 0x00010000,
eDestroySurface = 0x00020000,
eTransformChanged = 0x00040000,
eTransformToDisplayInverseChanged = 0x00080000,
eCropChanged = 0x00100000,
eBufferChanged = 0x00200000,
eAcquireFenceChanged = 0x00400000,
eDataspaceChanged = 0x00800000,
eHdrMetadataChanged = 0x01000000,
eSurfaceDamageRegionChanged = 0x02000000,
eApiChanged = 0x04000000,
eSidebandStreamChanged = 0x08000000,
eColorTransformChanged = 0x10000000,
eHasListenerCallbacksChanged = 0x20000000,
eInputInfoChanged = 0x40000000,
eCornerRadiusChanged = 0x80000000,
eDestinationFrameChanged = 0x1'00000000,
eCachedBufferChanged = 0x2'00000000,
eBackgroundColorChanged = 0x4'00000000,
eMetadataChanged = 0x8'00000000,
eColorSpaceAgnosticChanged = 0x10'00000000,
eFrameRateSelectionPriority = 0x20'00000000,
eFrameRateChanged = 0x40'00000000,
eBackgroundBlurRadiusChanged = 0x80'00000000,
eProducerDisconnect = 0x100'00000000,
eFixedTransformHintChanged = 0x200'00000000,
eFrameNumberChanged = 0x400'00000000,
eBlurRegionsChanged = 0x800'00000000,
eAutoRefreshChanged = 0x1000'00000000,
eStretchChanged = 0x2000'00000000,
eTrustedOverlayChanged = 0x4000'00000000,
};
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffer(...) {
layer_state_t* s = getLayerState(sc);
...
s->what |= layer_state_t::eBufferChanged;
...
}
struct DisplayState {
enum {
eSurfaceChanged = 0x01,
eLayerStackChanged = 0x02,
eDisplayProjectionChanged = 0x04,
eDisplaySizeChanged = 0x08
};
DisplayState();
void merge(const DisplayState& other);
uint32_t what;
sp<IBinder> token;
sp<IGraphicBufferProducer> surface;
uint32_t layerStack;
// These states define how layers are projected onto the physical display.
//
// Layers are first clipped to `layerStackSpaceRect'. They are then translated and
// scaled from `layerStackSpaceRect' to `orientedDisplaySpaceRect'. Finally, they are rotated
// according to `orientation', `width', and `height'.
//
// For example, assume layerStackSpaceRect is Rect(0, 0, 200, 100), orientedDisplaySpaceRect is
// Rect(20, 10, 420, 210), and the size of the display is WxH. When orientation is 0, layers
// will be scaled by a factor of 2 and translated by (20, 10). When orientation is 1, layers
// will be additionally rotated by 90 degrees around the origin clockwise and translated by (W,
// 0).
ui::Rotation orientation = ui::ROTATION_0;
Rect layerStackSpaceRect;
Rect orientedDisplaySpaceRect;
uint32_t width, height;
status_t write(Parcel& output) const;
status_t read(const Parcel& input);
};
enum {
eSurfaceChanged = 0x01, // surface改變了
eLayerStackChanged = 0x02, // layer stack改變了
eDisplayProjectionChanged = 0x04, // display projecttion改變了
eDisplaySizeChanged = 0x08 // display size改變了
};
void SurfaceComposerClient::Transaction::setDisplaySize(const sp<IBinder>& token, uint32_t width, uint32_t height) {
DisplayState& s(getDisplayState(token));
s.width = width;
s.height = height;
s.what |= DisplayState::eDisplaySizeChanged;
}
在我們的應用中,呼叫了setLayer/show/apply,我們看看Transaction是如何把狀態/屬性資訊傳遞給SurfaceFlinger的.
setLayer,設定Layer的z-order
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer(
const sp<SurfaceControl>& sc, int32_t z) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
s->what |= layer_state_t::eLayerChanged;
s->what &= ~layer_state_t::eRelativeLayerChanged;
s->z = z;
registerSurfaceControlForCallback(sc);
return *this;
}
getLayerState,就是根據SurfaceCotrol物件去找對應的layer_state_t。
layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<SurfaceControl>& sc) {
auto handle = sc->getLayerStateHandle();
if (mComposerStates.count(handle) == 0) {
// we don't have it, add an initialized layer_state to our list
ComposerState s;
s.state.surface = handle;
s.state.layerId = sc->getLayerId();
mComposerStates[handle] = s;
}
return &(mComposerStates[handle].state);
}
文章前面講解SurfaceComposerClient::createSurface時,我們知曉SurfaceFlinger建立好Layer後返回給客戶端Layer handle和id,這些Layer資訊都被封裝到一個SurfaceControl物件,SurfaceControl::getLayerStateHandle返回的就是這個Layer handle
sp<IBinder> SurfaceControl::getLayerStateHandle() const
{
return mHandle;
}
然後判斷這個layer hanlde是否在mComposerStates中,如果沒有則建立對應的ComposerState並加入
我們看,setLayer時,增加標識what是layer_state_t::eLayerChanged,而對應的值儲存到layer_state_t 中。你應該注意到了設定看起來沒有立即生效,
同樣,show時,也是將對應的標識加到what中,而是否顯示的標識存放在layer_state_t的flag中。
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::show(
const sp<SurfaceControl>& sc) {
return setFlags(sc, 0, layer_state_t::eLayerHidden);
}
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags(
const sp<SurfaceControl>& sc, uint32_t flags,
uint32_t mask) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
if ((mask & layer_state_t::eLayerOpaque) || (mask & layer_state_t::eLayerHidden) ||
(mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot) ||
(mask & layer_state_t::eEnableBackpressure)) {
s->what |= layer_state_t::eFlagsChanged;
}
s->flags &= ~mask;
s->flags |= (flags & mask);
s->mask |= mask;
registerSurfaceControlForCallback(sc);
return *this;
}
最後呼叫apply,使得設定生效
status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
...
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
...
cacheBuffers();
Vector<ComposerState> composerStates;
Vector<DisplayState> displayStates;
for (auto const& kv : mComposerStates){
composerStates.add(kv.second);
}
displayStates = std::move(mDisplayStates);
...
sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
{} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,
hasListenerCallbacks, listenerCallbacks, mId);
mId = generateId();
// Clear the current states and flags
clear();
...
}
apply時,最重要的就是呼叫sf->setTransactionState,Binder IPC一路飛奔到了SurfaceFlinger::setTransactionState
status_t SurfaceFlinger::setTransactionState(...) {
ATRACE_CALL();
......
IPCThreadState* ipc = IPCThreadState::self();
const int originPid = ipc->getCallingPid();
const int originUid = ipc->getCallingUid();
TransactionState state{frameTimelineInfo, states,
displays, flags,
applyToken, inputWindowCommands,
desiredPresentTime, isAutoTimestamp,
uncacheBuffer, postTime,
permissions, hasListenerCallbacks,
listenerCallbacks, originPid,
originUid, transactionId};
// Check for incoming buffer updates and increment the pending buffer count.
state.traverseStatesWithBuffers([&](const layer_state_t& state) {
mBufferCountTracker.increment(state.surface->localBinder());
});
queueTransaction(state);
// Check the pending state to make sure the transaction is synchronous.
if (state.transactionCommittedSignal) {
waitForSynchronousTransaction(*state.transactionCommittedSignal);
}
return NO_ERROR;
}
SurfaceFlinger把資訊封裝到一個TransactionState變數中:
TransactionState state{frameTimelineInfo, states,
displays, flags,
applyToken, inputWindowCommands,
desiredPresentTime, isAutoTimestamp,
uncacheBuffer, postTime,
permissions, hasListenerCallbacks,
listenerCallbacks, originPid,
originUid, transactionId};
然後放置到待處理的Transaction佇列中: SurfaceFlinger::queueTransaction
void SurfaceFlinger::queueTransaction(TransactionState& state) {
Mutex::Autolock _l(mQueueLock);
...
mTransactionQueue.emplace(state);
ATRACE_INT("TransactionQueue", mTransactionQueue.size());
setTransactionFlags(eTransactionFlushNeeded, schedule, state.applyToken);
}
SurfaceFlinger::setTransactionFlags中在 滿足一定條件時 呼叫signalTransaction觸發執行 invalidate 操作
uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, TransactionSchedule schedule,
const sp<IBinder>& token) {
uint32_t old = mTransactionFlags.fetch_or(flags);
modulateVsync(&VsyncModulator::setTransactionSchedule, schedule, token);
if ((old & flags) == 0) signalTransaction();
return old;
}
void SurfaceFlinger::signalTransaction() {
mScheduler->resetIdleTimer();
mPowerAdvisor.notifyDisplayUpdateImminent();
mEventQueue->invalidate();
}
上一篇文章 Android 12(S) 圖形顯示系統 - SurfaceFlinger的啟動和訊息佇列處理機制(四)
我們分析訊息處理機制時對 invalidate 的執行介紹過
// 第一步
void SurfaceFlinger::onMessageReceived(int32_t what, int64_t vsyncId, nsecs_t expectedVSyncTime) {
switch (what) {
case MessageQueue::INVALIDATE: {
onMessageInvalidate(vsyncId, expectedVSyncTime);
break;
}
}
}
// 第二步
void SurfaceFlinger::onMessageInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTime) {
...
refreshNeeded = handleMessageTransaction();
...
}
// 第三步
bool SurfaceFlinger::handleMessageTransaction() {
ATRACE_CALL();
if (getTransactionFlags(eTransactionFlushNeeded)) {
flushTransactionQueues();
}
...
}
// 第四步
void SurfaceFlinger::flushTransactionQueues() {
...
// Now apply all transactions.
for (const auto& transaction : transactions) {
applyTransactionState(transaction.frameTimelineInfo, transaction.states,
transaction.displays, transaction.flags,
transaction.inputWindowCommands, transaction.desiredPresentTime,
transaction.isAutoTimestamp, transaction.buffer,
transaction.postTime, transaction.permissions,
transaction.hasListenerCallbacks, transaction.listenerCallbacks,
transaction.originPid, transaction.originUid, transaction.id);
if (transaction.transactionCommittedSignal) {
mTransactionCommittedSignals.emplace_back(
std::move(transaction.transactionCommittedSignal));
}
}
...
}
// 第五步
void SurfaceFlinger::applyTransactionState(...) {
...
for (const DisplayState& display : displays) {
transactionFlags |= setDisplayStateLocked(display);
}
for (const ComposerState& state : states) {
clientStateFlags |=
setClientStateLocked(frameTimelineInfo, state, desiredPresentTime, isAutoTimestamp,
postTime, permissions, listenerCallbacksWithSurfaces);
}
...
}
// 第六步
uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) {}
uint32_t SurfaceFlinger::setClientStateLocked(){}
跋山涉水,走到了setClientStateLocked/setDisplayStateLocked
setDisplayStateLocked
uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) {
const ssize_t index = mCurrentState.displays.indexOfKey(s.token);
if (index < 0) return 0;
uint32_t flags = 0;
DisplayDeviceState& state = mCurrentState.displays.editValueAt(index);
const uint32_t what = s.what;
if (what & DisplayState::eSurfaceChanged) {
if (IInterface::asBinder(state.surface) != IInterface::asBinder(s.surface)) {
state.surface = s.surface;
flags |= eDisplayTransactionNeeded;
}
}
....
}
setDisplayStateLocked中會把我們在客戶端設定的標誌為資訊解析出來儲存到mCurrentState中
setClientStateLocked
uint32_t SurfaceFlinger::setClientStateLocked(){
....
if (what & layer_state_t::eLayerChanged) {
// NOTE: index needs to be calculated before we update the state
const auto& p = layer->getParent();
if (p == nullptr) {
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
if (layer->setLayer(s.z) && idx >= 0) { // setLayer
mCurrentState.layersSortedByZ.removeAt(idx);
mCurrentState.layersSortedByZ.add(layer);
// we need traversal (state changed)
// AND transaction (list changed)
flags |= eTransactionNeeded|eTraversalNeeded;
}
} else {
if (p->setChildLayer(layer, s.z)) {
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
}
....
}
setClientStateLocked中同樣會把我們在客戶端設定的標誌為資訊解析出來,然後設定到對應的Layer中去,這裡就是呼叫了layer->setLayer,z-order資訊儲存到了layer的mDrawingState中
bool Layer::setLayer(int32_t z) {
if (mDrawingState.z == z && !usingRelativeZ(LayerVector::StateSet::Current)) return false;
mDrawingState.sequence++;
mDrawingState.z = z;
mDrawingState.modified = true;
mFlinger->mSomeChildrenChanged = true;
// Discard all relative layering.
if (mDrawingState.zOrderRelativeOf != nullptr) {
sp<Layer> strongRelative = mDrawingState.zOrderRelativeOf.promote();
if (strongRelative != nullptr) {
strongRelative->removeZOrderRelative(this);
}
setZOrderRelativeOf(nullptr);
}
setTransactionFlags(eTransactionNeeded);
return true;
}
至此createSurface的流程基本就講完了。
隱隱約約,迷迷糊糊感覺還是很多事情沒講透徹,比如設定下來的資訊 儲存到 mDrawingState or mCurrentState 後,這些資訊又是什麼時候確實被利用的呢?走了怎麼樣的流程?
哈哈,我現在只能說下次繪製圖形時就會用了(嘻嘻)