一.概述
???????我們知道催首,Android設(shè)備都有錄屏功能,其實(shí)主要是通過(guò)VirtualDisplay來(lái)實(shí)現(xiàn)的洒疚,VirtualDisplay對(duì)應(yīng)虛擬Display鸠姨,主要用來(lái)進(jìn)行屏幕錄制等相關(guān)功能;
???????在DMS的registerDefaultDisplayAdapters()內(nèi)部,除了創(chuàng)建LocalDisplayAdapter抓韩,還創(chuàng)建了VirtualDisplayAdapter纠永,可以參考文章Android Display管理服務(wù)DMS,接下來(lái)一起看一下VirtualDisplayAdapter類(lèi)實(shí)現(xiàn):
二.VirtualDisplayAdapter
public VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener) {
this(syncRoot, context, handler, listener,
(String name, boolean secure) -> SurfaceControl.createDisplay(name, secure));
}
@VisibleForTesting
VirtualDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,Context context, Handler handler, Listener listener,
SurfaceControlDisplayFactory surfaceControlDisplayFactory) {
super(syncRoot, context, handler, listener, TAG);
mHandler = handler;
mSurfaceControlDisplayFactory = surfaceControlDisplayFactory;
}
???????在構(gòu)造方法內(nèi)部會(huì)通過(guò)SurfaceControl的createDisplay()獲取的對(duì)象賦值給mSurfaceControlDisplayFactory變量谒拴,后續(xù)在創(chuàng)建VirtualDisplayDevice時(shí)需要尝江;
三.VirtualDisplayDevice
???????通過(guò)VirtualDisplayAdapter內(nèi)部的createVirtualDisplayLocked()來(lái)創(chuàng)建VirtualDisplayDevice;
public DisplayDevice createVirtualDisplayLocked(IVirtualDisplayCallback callback,
IMediaProjection projection, int ownerUid, String ownerPackageName, String name,
int width, int height, int densityDpi, Surface surface, int flags, String uniqueId) {
boolean secure = (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0;
IBinder appToken = callback.asBinder();
IBinder displayToken = mSurfaceControlDisplayFactory.createDisplay(name, secure);
final String baseUniqueId =
UNIQUE_ID_PREFIX + ownerPackageName + "," + ownerUid + "," + name + ",";
final int uniqueIndex = getNextUniqueIndex(baseUniqueId);
if (uniqueId == null) {
uniqueId = baseUniqueId + uniqueIndex;
} else {
uniqueId = UNIQUE_ID_PREFIX + ownerPackageName + ":" + uniqueId;
}
VirtualDisplayDevice device = new VirtualDisplayDevice(displayToken, appToken,
ownerUid, ownerPackageName, name, width, height, densityDpi, surface, flags,
new Callback(callback, mHandler), uniqueId, uniqueIndex);
mVirtualDisplayDevices.put(appToken, device);
try {
if (projection != null) {
projection.registerCallback(new MediaProjectionCallback(appToken));
}
appToken.linkToDeath(device, 0);
}
return device;
}
???????1.通過(guò)mSurfaceControlDisplayFactory的createDisplay()來(lái)獲取對(duì)應(yīng)的displayToken英上,由于是虛擬設(shè)備炭序,跟BUILT_IN設(shè)備獲取方式是不同的;
???????2.VirtualDisplay的mUniqueId格式為:virtual:com.hly.test,1000(ownerUid),-display(name),0苍日;
???????3.將創(chuàng)建的VirtualDisplayDevice加入mVirtualDisplayDevices進(jìn)行管理惭聂;
???????4.projection.registerCallback()執(zhí)行錄屏相關(guān)注冊(cè);
四.VirtualDisplay創(chuàng)建
???????當(dāng)要執(zhí)行屏幕錄制前相恃,會(huì)先通過(guò)MediaProjection執(zhí)行createVirtualDisplay()來(lái)創(chuàng)建VirtualDisplay彼妻;
1.createVirtualDisplay()
public VirtualDisplay createVirtualDisplay(@NonNull String name,int width, int height, int dpi, int flags, @Nullable Surface surface,@Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
return dm.createVirtualDisplay(this, name, width, height, dpi, surface, flags, callback,handler, null /* uniqueId */);
}
???????需要傳入VirtualDisplay的name、width豆茫、height侨歉、Surface等,Surface用來(lái)獲取或顯示屏幕數(shù)據(jù)揩魂,最后會(huì)調(diào)用到DisplayMangerGlobal內(nèi)部的createVirtualDisplay()方法:
2.createVirtualDisplay()
public VirtualDisplay createVirtualDisplay(Context context, MediaProjection projection,
String name, int width, int height, int densityDpi, Surface surface, int flags,
VirtualDisplay.Callback callback, Handler handler, String uniqueId) {
..........................
VirtualDisplayCallback callbackWrapper = new VirtualDisplayCallback(callback, handler);
IMediaProjection projectionToken = projection != null ? projection.getProjection() : null;
int displayId;
try {
displayId = mDm.createVirtualDisplay(callbackWrapper, projectionToken,
context.getPackageName(), name, width, height, densityDpi, surface, flags,
uniqueId);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
Display display = getRealDisplay(displayId);
...............................
return new VirtualDisplay(this, display, callbackWrapper, surface);
}
???????接下來(lái)會(huì)調(diào)用執(zhí)行到DMS的createVirtualDisplay()來(lái)先創(chuàng)建VirtualDisplayDevice和LogicalDisplay幽邓,根據(jù)LogicalDisplay的displayId創(chuàng)建Display,然后將Display作為參數(shù)創(chuàng)建VirtualDisplay返回火脉;
3.總結(jié)
???????用一張流程圖總結(jié)一下創(chuàng)建流程:
五.鏡像實(shí)現(xiàn)
???????在錄屏?xí)r牵舵,其實(shí)就是一個(gè)鏡像,VirtualDisplayDevice是沒(méi)有內(nèi)容顯示的倦挂,所以需要將其鏡像到要錄制屏對(duì)應(yīng)的DisplayDevice就可以了畸颅,具體實(shí)現(xiàn)邏輯是在DMS的configureDisplayInTransactionLocked()方法,那該方法是什么時(shí)候會(huì)觸發(fā)調(diào)用呢方援?
???????根據(jù)前面的分析没炒,在創(chuàng)建VirtualDisplay時(shí),會(huì)執(zhí)行到handleDisplayDeviceAddedLocked()犯戏,一起看一下該方法:
1.handleDisplayDeviceAddedLocked()
private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
.....................
mDisplayDevices.add(device);
LogicalDisplay display = addLogicalDisplayLocked(device);
Runnable work = updateDisplayStateLocked(device);
if(work != null) {
work.run();
}
scheduleTraversalLocked(false);
}
???????在該方法內(nèi)部會(huì)創(chuàng)建VirtualDisplayDevice對(duì)應(yīng)的LogicalDisplay送火,繼而分配displayId及l(fā)ayerStack,那創(chuàng)建完后是如何跟目標(biāo)屏建立對(duì)應(yīng)關(guān)系的呢先匪?關(guān)鍵點(diǎn)就在scheduleTraversalLocked(false)种吸,一起看一下:
2.scheduleTraversalLocked()
private void scheduleTraversalLocked(boolean inTraversal) {
if (!mPendingTraversal && mWindowManagerInternal != null) {
mPendingTraversal = true;
if (!inTraversal) {
mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL);
}
}
}
case MSG_REQUEST_TRAVERSAL:
mWindowManagerInternal.requestTraversalFromDisplayManager();
break;
private final class LocalService extends WindowManagerInternal {
@Override
public void requestTraversalFromDisplayManager() {
requestTraversal();
}
}
void requestTraversal() {
synchronized (mWindowMap) {
mWindowPlacerLocked.requestTraversal();
}
}
???????在scheduleTraversalLocked()內(nèi)部發(fā)送 MSG_REQUEST_TRAVERSAL消息,執(zhí)行該消息的時(shí)候就是調(diào)用WMS的LocalService執(zhí)行 requestTraversal()方法呀非,具體執(zhí)行過(guò)程簡(jiǎn)單羅列一下:
WindowSurfacePlacer -> requestTraversal()
WindowSurfacePlacer -> performSurfacePlacement()
WindowSurfacePlacer -> performSurfacePlacementLoop()
RootWindowContainer -> performSurfacePlacement()
void performSurfacePlacement(boolean recoveringMemory) {
...................
mService.openSurfaceTransaction();
try {
applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh);
} catch (RuntimeException e) {
Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
} finally {
mService.closeSurfaceTransaction();
}
......
}
???????可以看到坚俗,在RootWindowContainer內(nèi)部的performSurfacePlacement()會(huì)順序執(zhí)行以下方法:
???????1.mService.openSurfaceTransaction(),通過(guò)SurfaceControl來(lái)通知native開(kāi)始一個(gè)Transaction;
???????2.applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh)來(lái)處理Transaction猖败;
???????3.mService.closeSurfaceTransaction()形耗,通過(guò)SurfaceControl來(lái)通知native(SurfaceFlinger)關(guān)閉一個(gè)Transaction最終來(lái)執(zhí)行合成顯示等工作;
3.applySurfaceChangesTransaction()
private void applySurfaceChangesTransaction(boolean recoveringMemory, int defaultDw,
int defaultDh) {
......................................
// Give the display manager a chance to adjust properties like display rotation if it needs
// to.
mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
}
???????刷新后經(jīng)過(guò)一番調(diào)用辙浑,最終回到DisplayManagerService的performTraversalInTransactionFromWindowManager()方法激涤,該方法會(huì)調(diào)用到performTraversalInTransactionLocked()方法:
4.performTraversalInTransactionLocked()
private void performTraversalInTransactionLocked() {
.....................
// Configure each display device.
final int count = mDisplayDevices.size();
for (int i = 0; i < count; i++) {
DisplayDevice device = mDisplayDevices.get(i);
configureDisplayInTransactionLocked(device);
device.performTraversalInTransactionLocked();
}
......................
}
???????可以看到,在該方法內(nèi)會(huì)遍歷所有的DisplayDevice來(lái)主要干了兩件事:
???????1.執(zhí)行configureDisplayInTransactionLocked()進(jìn)行配置DisplayDevice要顯示的layerStack判呕;
???????2.執(zhí)行performTraversalInTransactionLocked()來(lái)關(guān)聯(lián)Surface倦踢,即數(shù)據(jù)顯示源;
???????先看configureDisplayInTransactionLocked():
5.configureDisplayInTransactionLocked()
private void configureDisplayInTransactionLocked(DisplayDevice device) {
final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0;
LogicalDisplay display = findLogicalDisplayForDeviceLocked(device);
if (!ownContent) {
if (display != null && !display.hasContentLocked()) {
// If the display does not have any content of its own, then
// automatically mirror the default logical display contents.
display = null;
}
if (display == null) {
display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY);
}
}
display.configureDisplayInTransactionLocked(device, info.state == Display.STATE_OFF);
....................
}
???????當(dāng)DisplayDevice對(duì)應(yīng)VirtualDisplayDevice時(shí)侠草,返回的ownContent為false辱挥,即沒(méi)有自己內(nèi)容顯示的,進(jìn)入判斷边涕,通過(guò)display.hasContentLocked()返回false晤碘,所以得到的display為null,接下來(lái)如果display為null功蜓,會(huì)從mLogicalDisplays中取出DEFAULT_DISPLAY賦值給display园爷,那有什么用呢?
???????關(guān)鍵邏輯在display.configureDisplayInTransactionLocked():
6.configureDisplayInTransactionLocked()
public void configureDisplayInTransactionLocked(DisplayDevice device, boolean isBlanked) {
// Set the layer stack.
device.setLayerStackInTransactionLocked(isBlanked ? BLANK_LAYER_STACK : mLayerStack);
.....................
.....................
}
public final void setLayerStackInTransactionLocked(int layerStack) {
if (mCurrentLayerStack != layerStack) {
mCurrentLayerStack = layerStack;
SurfaceControl.setDisplayLayerStack(mDisplayToken, layerStack);
}
}
???????在該方法內(nèi)部執(zhí)行device.setLayerStackInTransactionLocked()式撼,即將VirtualDisplayDevice的layerStack設(shè)置為DEFAULT_DISPLAY對(duì)應(yīng)的layerStack童社,繼而調(diào)用SurfaceControl內(nèi)部的setDisplayLayerStack()方法,mDisplayToken用于唯一標(biāo)識(shí)SurfaceFliger創(chuàng)建的VirtualDisplay著隆,跟隨調(diào)用關(guān)系扰楼,再一起看一下:
public static void setDisplayLayerStack(IBinder displayToken, int layerStack) {
nativeSetDisplayLayerStack(displayToken, layerStack);
}
static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz,jobject tokenObj, jint layerStack) {
sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
SurfaceComposerClient::setDisplayLayerStack(token, layerStack);
}
void SurfaceComposerClient::setDisplayLayerStack(const sp<IBinder>& token,uint32_t layerStack) {
Composer::getInstance().setDisplayLayerStack(token, layerStack);
}
void Composer::setDisplayLayerStack(const sp<IBinder>& token,uint32_t layerStack) {
Mutex::Autolock _l(mLock);
DisplayState& s(getDisplayStateLocked(token));
s.layerStack = layerStack;
s.what |= DisplayState::eLayerStackChanged;
}
???????跟隨調(diào)用關(guān)系,主要有以下幾個(gè)要點(diǎn):
???????getDisplayStateLocked():如果不存在該token對(duì)應(yīng)的 DisplayState就會(huì)為該token創(chuàng)建一個(gè)DisplayState美浦,并保存在mDisplayStates中進(jìn)行管理弦赖;
???????接下來(lái)將layerStack賦值給DisplayyState的layerStack變量,此時(shí)layerStack配置完成浦辨;
???????前面講到蹬竖,在創(chuàng)建VirtualDisplay時(shí)會(huì)傳入Surface,那該Surface是如何與VirtualDisplay進(jìn)行關(guān)聯(lián)的呢荤牍?關(guān)鍵在performTraversalInTransactionLocked()方法:
7.performTraversalInTransactionLocked()
@Override
public void performTraversalInTransactionLocked() {
if ((mPendingChanges & PENDING_RESIZE) != 0) {
SurfaceControl.setDisplaySize(getDisplayTokenLocked(), mWidth, mHeight);
}
if ((mPendingChanges & PENDING_SURFACE_CHANGE) != 0) {
setSurfaceInTransactionLocked(mSurface);
}
mPendingChanges = 0;
}
public final void setSurfaceInTransactionLocked(Surface surface) {
if (mCurrentSurface != surface) {
mCurrentSurface = surface;
SurfaceControl.setDisplaySurface(mDisplayToken, surface);
}
}
???????mSurface是在創(chuàng)建VirtualDisplay時(shí)傳入的案腺,可以是通過(guò)SurfaceView的getSurface()獲取的Surface庆冕,用來(lái)直接顯示康吵;也可以是通過(guò)MediaCodec獲取的Surface,用來(lái)實(shí)現(xiàn)遠(yuǎn)端視頻流傳輸访递;
public static void setDisplaySurface(IBinder displayToken, Surface surface) {
..........
if (surface != null) {
synchronized (surface.mLock) {
nativeSetDisplaySurface(displayToken, surface.mNativeObject);
}
} else {
nativeSetDisplaySurface(displayToken, 0);
}
}
static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,jobject tokenObj, jlong nativeSurfaceObject) {
sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
sp<IGraphicBufferProducer> bufferProducer;
sp<Surface> sur(reinterpret_cast<Surface *>(nativeSurfaceObject));
if (sur != NULL) {
bufferProducer = sur->getIGraphicBufferProducer();
}
status_t err = SurfaceComposerClient::setDisplaySurface(token,
bufferProducer);
}
}
???????bufferProducer主要用于申請(qǐng) Buffer晦嵌,申請(qǐng)Buffer是寫(xiě)入圖形數(shù)據(jù);consumer主要用于消費(fèi)Buffer,消費(fèi)Buffer就是把應(yīng)用寫(xiě)入數(shù)據(jù)準(zhǔn)備好的Buffer取出來(lái)處理惭载;
status_t SurfaceComposerClient::setDisplaySurface(const sp<IBinder>& token,sp<IGraphicBufferProducer> bufferProducer) {
return Composer::getInstance().setDisplaySurface(token, bufferProducer);
}
status_t Composer::setDisplaySurface(const sp<IBinder>& token,sp<IGraphicBufferProducer> bufferProducer) {
DisplayState& s(getDisplayStateLocked(token));
s.surface = bufferProducer;
s.what |= DisplayState::eSurfaceChanged;
return NO_ERROR;
}
???????把 bufferProducer 保存到 DisplayState 的 surface中旱函;
???????經(jīng)過(guò)上面的處理后,為VirtualDisplay配置好了 layerStack (鏡像屏)和bufferProducer描滔,那么接下來(lái)是如何進(jìn)行后續(xù)顯示處理的呢棒妨?
???????前面講到,在RootWindowContainer內(nèi)部的performSurfacePlacement()在執(zhí)行applySurfaceChangesTransaction()完后會(huì)執(zhí)行mService.closeSurfaceTransaction()含长,一起看一下該方法:
8.closeSurfaceTransaction()
void closeSurfaceTransaction() {
try {
synchronized (mWindowMap) {
if (mRoot.mSurfaceTraceEnabled) {
mRoot.mRemoteEventTrace.closeSurfaceTransaction();
}
SurfaceControl.closeTransaction();
}
} finally {
}
}
public static void closeTransaction() {
nativeCloseTransaction(false);
}
static void nativeCloseTransaction(JNIEnv* env, jclass clazz, jboolean sync) {
SurfaceComposerClient::closeGlobalTransaction(sync);
}
void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) {
Composer::closeGlobalTransaction(synchronous);
}
void Composer::closeGlobalTransactionImpl(bool synchronous) {
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
Vector<ComposerState> transaction;
Vector<DisplayState> displayTransaction;
......
{
displayTransaction = mDisplayStates;
}
......
sm->setTransactionState(transaction, displayTransaction, flags); //sm SurfaceFlinger
}
???????sm:指向SurfaceFlinger 代理對(duì)象券腔;mDisplayStates:里面保存了之前創(chuàng)建的VirtualDisplay對(duì)應(yīng)的DisplayState,在DisplayState中保存了layerStack(鏡像屏)和 bufferProducer(寫(xiě)入屏幕數(shù)據(jù))拘泞;
9.setTransactionState()
void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& state,const Vector<DisplayState>& displays,uint32_t flags){
.....
size_t count = displays.size();
for (size_t i=0 ; i<count ; i++) {
const DisplayState& s(displays[i]);
transactionFlags |= setDisplayStateLocked(s);
}
......
setTransactionFlags(transactionFlags);
......
}
???????1.遍歷mDisplayStates執(zhí)行setDisplayStateLocked()更新 mCurrentState.displays 中的數(shù)據(jù)纷纫,通過(guò)token取出 VirtualDisplay然后更新surface和layerStack;
uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s){
ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token);
......
DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx));
if (disp.isValid()) {
const uint32_t what = s.what;
if (what & DisplayState::eSurfaceChanged) {
if (IInterface::asBinder(disp.surface) != IInterface::asBinder(s.surface)) {
disp.surface = s.surface;
flags |= eDisplayTransactionNeeded;
}
}
if (what & DisplayState::eLayerStackChanged) {
if (disp.layerStack != s.layerStack) {
disp.layerStack = s.layerStack;
flags |= eDisplayTransactionNeeded;
}
}
......
}
return flags;
}
???????2.通過(guò)setTransactionFlags()發(fā)起一次刷新陪腌;
uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
signalTransaction();
}
void SurfaceFlinger::signalTransaction() {
mEventQueue.invalidate();
}
void MessageQueue::invalidate() {
mEvents->requestNextVsync();
}
???????SurfaceFlinger 請(qǐng)求下一個(gè)同步幀辱魁,執(zhí)行一次刷新,最終調(diào)用如下: SurfaceFlinger::handleTransaction()-->SurfaceFlinger::handleTransactionLocked()诗鸭;
10.handleTransactionLocked()
void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags){
.......................
.......................
const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
const size_t cc = curr.size();
size_t dc = draw.size();
for (size_t i=0 ; i<cc ; i++) {
if (draw.indexOfKey(curr.keyAt(i)) < 0) {
..................
if (state.isVirtualDisplay()) {
......
if (state.surface != NULL) {
if (mUseHwcVirtualDisplays || mHwc->isUsingVrComposer()) {
.....
displayUtils->initVDSInstance(*mHwc, hwcId, state.surface,dispSurface, producer, bqProducer, bqConsumer,state.displayName, state.isSecure);
}
}
}
......
if (dispSurface != NULL && producer != NULL) {
sp<DisplayDevice> hw =new DisplayDevice(this, state.type, hwcId, state.isSecure, display,
dispSurface, producer,mRenderEngine->getEGLConfig(),
hasWideColorDisplay);
hw->setLayerStack(state.layerStack);
hw->setProjection(state.orientation,state.viewport, state.frame);
hw->setDisplayName(state.displayName);
.......
mDisplays.add(display, hw);
if (!state.isVirtualDisplay()) {
mEventThread->onHotplugReceived(state.type, true);
}
}
}
}
???????先看一下兩個(gè)變量含義:
???????mCurrentState:SurfaceFlinger中最新的狀態(tài)染簇,包括所有的display和所有要繪制的Layer;
???????mDrawingState:SurfaceFlinger中當(dāng)前顯示的狀態(tài)强岸,包括所有的display和所有要繪制的Layer剖笙;
???????通過(guò) mCurrentState 和 mDrawingState 比較是否有增加的display,如果有增加的dislay并且是 VirtualDisplay请唱,首先會(huì)通過(guò) initVDSInstance 函數(shù)創(chuàng)建一個(gè) VirtualDisplaySurface封裝了producer弥咪、consumer以及surface,然后創(chuàng)建一個(gè) DisplayDevice并設(shè)置其 layerStack十绑,最后保存到 mDisplays 中進(jìn)行管理聚至,此時(shí)虛擬屏幕的 DisplayDevice創(chuàng)建好了。
???????在SurfaceFliner刷新所有的Layer到屏幕上顯示之前本橙,需要確定那些Layer應(yīng)該顯示到哪個(gè)屏幕上扳躬,以上邏輯是通過(guò)rebuildLayerStacks()來(lái)進(jìn)行實(shí)現(xiàn)的:
11.rebuildLayerStacks()
void SurfaceFlinger::rebuildLayerStacks() {
......
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
Region opaqueRegion;
Region dirtyRegion;
Vector<sp<Layer>> layersSortedByZ;
Vector<sp<Layer>> layersNeedingFences;
const sp<DisplayDevice>& displayDevice(mDisplays[dpy]);
const Transform& tr(displayDevice->getTransform());
const Rect bounds(displayDevice->getBounds());
if (displayDevice->isDisplayOn()) {
computeVisibleRegions(displayDevice, dirtyRegion, opaqueRegion);
mDrawingState.traverseInZOrder([&](Layer* layer) {
if (layer->belongsToDisplay(displayDevice->getLayerStack(),displayDevice->isPrimary())) {
......................
layersSortedByZ.add(layer);
...........
});
}
displayDevice->setVisibleLayersSortedByZ(layersSortedByZ);
......
}
}
}
bool belongsToDisplay(uint32_t layerStack, bool isPrimaryDisplay) const {
return getLayerStack() == layerStack && (!mPrimaryDisplayOnly || isPrimaryDisplay);
}
???????在該方法內(nèi)部會(huì)遍歷mDisplays來(lái)將要顯示的layer分配到對(duì)應(yīng)的displayDevice上,主要有以下幾個(gè)變量:
???????Layer:對(duì)應(yīng)WMS中的WindowState甚亭;
???????layersSortedByZ:保存Layer的Vector贷币;
???????displayDevice->getLayerStack():創(chuàng)建VirtualDisplayDevice時(shí)為VirtualDisplay分配的LayerStack;
???????belongsToDisplay():判斷Layer的layerStack是否和 displayDevice的LayerStack一致亏狰,如果一致是就把該Layer加入到layersSortedByZ中保存役纹;
???????最后把所有要顯示到該display上的Layer (layersSortedByZ) 保存到 displayDevice 中;
???????總結(jié)一下:前面創(chuàng)建的VirtualDisplay的layerStack 對(duì)應(yīng)就是主屏的layerStack暇唾,也就是說(shuō)促脉,此方法會(huì)把所有要顯示到主屏的layer全部都保存到VirtualDisplay 中辰斋,這樣VirtualDisplay就拿到了所有要顯示到主屏的內(nèi)容。
???????關(guān)于錄屏實(shí)現(xiàn)瘸味,可以參考文章Android 屏幕直播分享之MediaProjection和MediaCodec分析宫仗;