Activty启动到显示的过程[二]
Activity的显示从handleResumeActivity()方法开始。
//ActivityThread.java@Overridepublic void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,String reason) {final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);...if (r.window == null && !a.mFinished && willBeVisible) {r.window = r.activity.getWindow();View decor = r.window.getDecorView();decor.setVisibility(View.INVISIBLE);ViewManager wm = a.getWindowManager();...if (a.mVisibleFromClient) {if (!a.mWindowAdded) {a.mWindowAdded = true;android.util.Log.d(TAG, "linzh handleResumeActivity: l.token = " + l.token);wm.addView(decor, l);} }}...}
拿到对应Activity的的DecorView对象后,通过ViewManager接口的addView()方法开始显示界面的过程。
WindowManagerImpl是ViewManager的实现类,WindowManagerImpl调用WindowManagerGlobal类addView()方法。
addView
// WindowManagerGlobal.java public void addView(View view, ViewGroup.LayoutParams params,Display display, Window parentWindow, int userId) {
参考:https://blog.csdn.net/luoshengyang/article/details/46281499,https://androidperformance.com/2015/08/12/AndroidL-hwui-RenderThread-workflow/#/2-4-swapBuffers ViewRootImpl root;...root = new ViewRootImpl(view.getContext(), display);view.setLayoutParams(wparams);mViews.add(view);mRoots.add(root);mParams.add(wparams);// do this last because it fires off messages to start doing thingstry {root.setView(view, wparams, panelParentView, userId);} catch (RuntimeException e) {// BadTokenException or InvalidDisplayException, clean up.if (index >= 0) {removeViewLocked(index, true);}throw e;}}
ViewRootImpl构造方法中通过WindowManagerGlobal.getWindowSession()方法获取IWindowSession对象,IWindowSession是app进程和WMS(system_server进程)沟通的桥梁。
IWindowSession
// ViewRootImpl.java
public final class ViewRootImpl implements ViewParent,View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {// These can be accessed by any thread, must be protected with a lock.// Surface can never be reassigned or cleared (use Surface.clear()).@UnsupportedAppUsagepublic final Surface mSurface = new Surface();public ViewRootImpl(Context context, Display display) {this(context, display, WindowManagerGlobal.getWindowSession(),false /* useSfChoreographer */);}public ViewRootImpl(Context context, Display display, IWindowSession session) {this(context, display, session, false /* useSfChoreographer */);}public ViewRootImpl(Context context, Display display, IWindowSession session,boolean useSfChoreographer) {mContext = context;mWindowSession = session;mDisplay = display;mBasePackageName = context.getBasePackageName();mThread = Thread.currentThread();mChoreographer = useSfChoreographer? Choreographer.getSfInstance() : Choreographer.getInstance();...}
}
类变量mSurface在声明时就被实例化了,但是此时的mSurface 还没有与底层的surface 关联起来,后面会通过copyFrom 进行关联。
ViewRootImpl构造方法中,初始化mWindowSession(app和WMS建立连接),mThread(确认在主线程更新UI),mChoreographer(与Vsync机制配合,实现统一调度界面绘图)。
sWindowSession是WindowManagerGlobal类的静态变量,使用单例模式初始化,确保一个进程中只存在一个IWindowSession实例。
// WindowManagerGlobal.java
public final class WindowManagerGlobal {@UnsupportedAppUsageprivate static IWindowSession sWindowSession;@UnsupportedAppUsagepublic static IWindowSession getWindowSession() {synchronized (WindowManagerGlobal.class) {if (sWindowSession == null) {try {InputMethodManager.ensureDefaultInstanceForDefaultDisplayIfNecessary();IWindowManager windowManager = getWindowManagerService();sWindowSession = windowManager.openSession(new IWindowSessionCallback.Stub() {@Overridepublic void onAnimatorScaleChanged(float scale) {ValueAnimator.setDurationScale(scale);}});} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}return sWindowSession;}}
}
// WindowManagerService.java @Overridepublic IWindowSession openSession(IWindowSessionCallback callback) {return new Session(this, callback);}// Session.java
class Session extends IWindowSession.Stub implements IBinder.DeathRecipient{final WindowManagerService mService;SurfaceSession mSurfaceSession;...public Session(WindowManagerService service, IWindowSessionCallback callback) {mService = service;...}
}
WMS构建新的IWindowSession实例,Session类实现了IWindowSession.aidl接口,定义了app和WMS交互的接口方法,在构造方法中初始化WindowManagerService对象。还持有SurfaceSession 对象变量mSurfaceSession,mSurfaceSession并不在Session的构造方法中初始化,而是在调用IWindowSession定义的addToDisplayAsUser()方法时,由WMS(system_server进程)初始化。
setView
IWindowSession实例在ViewRootImpl构造方法中初始化好了, 终于开始要构建View了。
在方法开始会调用requestLayout(),然后通过mWindowSession.addToDisplayAsUser()方法初始化IWindowSession实例中的SurfaceSession对象。
后续setFrame()会继续调用requestLayout()方法。
requestLayout()在检查是主线程后(判断当前线程与实例化时是否同一线程),scheduleTraversals()方法中先在当前线程looper中postSyncBarrier()发送同步消息屏障,同步消息将被拖延执行,队列里的异步消息优先执行,通过 postCallback 提交一个任务,mTraversalRunnable是要执行的回调,有了同步消息屏障mTraversalRunnable就会被优先执行。
在安卓4.1之后,为了优化UI效果,安卓引入了Choreographer机制,配置底层上报的VSYNC信号,在收到信号后立即开始下一帧的渲染,保证mTraversalRunnable不被looper中的普通消息阻塞,立即执行渲染动作。
// ViewRootImpl.java
public final class ViewRootImpl implements ViewParent,View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView, int userId) {synchronized (this) {...// Schedule the first layout -before- adding to the window// manager, to make sure we do the relayout before receiving// any other events from the system.requestLayout();...try {mOrigWindowType = mWindowAttributes.type;mAttachInfo.mRecomputeGlobalAttributes = true;collectViewAttributes();adjustLayoutParamsForCompatibility(mWindowAttributes);res = mWindowSession.addToDisplayAsUser(mWindow, mSeq, mWindowAttributes,getHostVisibility(), mDisplay.getDisplayId(), userId, mTmpFrame,mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,mAttachInfo.mDisplayCutout, inputChannel,mTempInsets, mTempControls);setFrame(mTmpFrame);} catch (RemoteException e) {mAdded = false;mView = null;mAttachInfo.mRootView = null;inputChannel = null;mFallbackEventHandler.setView(null);unscheduleTraversals();setAccessibilityFocus(null, null);throw new RuntimeException("Adding window failed", e);} finally {if (restore) {attrs.restore();}}}}@Overridepublic void requestLayout() {if (!mHandlingLayoutInLayoutRequest) {checkThread();mLayoutRequested = true;scheduleTraversals();}}@UnsupportedAppUsagevoid scheduleTraversals() {if (!mTraversalScheduled) {mTraversalScheduled = true;mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);notifyRendererOfFramePending();pokeDrawLockIfNeeded();}}
SurfaceSession
mWindowSession.addToDisplayAsUser()通过WMS的addWindow()方法,实例化WindowState对象,记录到mWindowMap变量中,WindowState是WMS用来管理window而设计的一个类。
// WindowManagerService.java
public class WindowManagerService extends IWindowManager.Stubimplements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {/** Mapping from an IWindow IBinder to the server's Window object. */final HashMap<IBinder, WindowState> mWindowMap = new HashMap<>();public int addWindow(Session session, IWindow client, int seq,LayoutParams attrs, int viewVisibility, int displayId, Rect outFrame,Rect outContentInsets, Rect outStableInsets,DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,InsetsState outInsetsState, InsetsSourceControl[] outActiveControls,int requestUserId) {// 校验token等操作...final WindowState win = new WindowState(this, session, client, token, parentWindow,appOp[0], seq, attrs, viewVisibility, session.mUid, userId,session.mCanAddInternalSystemWindow);...win.attach();mWindowMap.put(client.asBinder(), win);win.initAppOpsState();...}
}
Session类中的mSurfaceSession对象在这里被实例化。
win.attach();调用windowAddedLocked()方法,传入mAttrs.packageName作为参数。
// Session.java
class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {SurfaceSession mSurfaceSession;void windowAddedLocked(String packageName) {mPackageName = packageName;mRelayoutTag = "relayoutWindow: " + mPackageName;if (mSurfaceSession == null) {mSurfaceSession = new SurfaceSession();mService.mSessions.add(this);if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {mService.dispatchNewAnimatorScaleLocked(this);}}mNumWindow++;}
}
SurfaceSession构造方法中通过jni调用nativeCreate(),返回SurfaceComposerClient对象的地址,赋值给mNativeClient变量。
// SurfaceSession.java
public final class SurfaceSession {@UnsupportedAppUsageprivate long mNativeClient; // SurfaceComposerClient*@UnsupportedAppUsagepublic SurfaceSession() {mNativeClient = nativeCreate();}
}// android_view_SufaceSession.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz) {SurfaceComposerClient* client = new SurfaceComposerClient();client->incStrong((void*)nativeCreate);jlong t = reinterpret_cast<jlong>(client);return reinterpret_cast<jlong>(client);
}
实例化一个SurfaceSession对象,nativeCreate()实例化SurfaceComposerClient对象,代表和surfaceflinger服务建立连接了。
到这里准备工作都做好了,就等Choreographer接受VSYNC信号执行mTraversalRunnable。
mTraversalRunnable
mTraversalRunnable被执行后,removeSyncBarrier()先移除looper中的同步屏障,普通的同步消息不再被拖延,performTraversals()先通过relayoutWindow()通知surfaceflinger创建一个surface,ViewRootImpl类的mSurface变量也在relayoutWindow()方法中通过copyFrom()方法和底层的surface对象关联起来。
performMeasure(), performLayout(), performDraw()分别会调用View的onMeasure(), onSizeChanaged(), onLayout(), onDraw()方法,开始画面绘制渲染。
void doTraversal() {if (mTraversalScheduled) {mTraversalScheduled = false;mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);performTraversals();}}private void performTraversals() {...relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);performLayout(lp, mWidth, mHeight);performDraw();...}
SurfaceControl / Surface
SurfaceControl是surface和如何处理surface的元数据(name, width, height, format)的组合。
SurfaceControl类在Java(frameworks/base/core/java/android/view/SurfaceControl.java)和cpp(frameworks/native/libs/gui/SurfaceControl.cpp)中都有实现。
Java层的SurfaceControl主要是对cpp层的SurfaceControl对象的封装,其类变量mNativeObject指向cpp层SurfaceControl对象的引用,mNativeHandle指向cpp层Layer类的内部类Handle,Handle继承了BBinder和LayerCleaner,LayerCleaner在handle被销毁时确保mFlinger->onLayerDestroyed()方法被调用。
// SurfaceControl.java
public final class SurfaceControl implements Parcelable {public long mNativeObject;private long mNativeHandle;private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags,SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView,String callsite){...mNativeObject = nativeCreate(session, name, w, h, format, flags,parent != null ? parent.mNativeObject : 0, metaParcel);mNativeHandle = nativeGetHandle(mNativeObject);}
}
cpp层的SurfaceControl保存了SurfaceComposerClient,Surface,Handle,IGraphicBufferProducer等和surface控制相关的数据。
// SurfaceControl.cpp
class SurfaceControl : public RefBase
{private:sp<SurfaceComposerClient> mClient;sp<IBinder> mHandle;sp<IGraphicBufferProducer> mGraphicBufferProducer;mutable Mutex mLock;mutable sp<Surface> mSurfaceData;SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,const sp<IGraphicBufferProducer>& gbp,uint32_t transform): mClient(client),mHandle(handle),mGraphicBufferProducer(gbp),mTransformHint(transform) {}sp<Surface> SurfaceControl::generateSurfaceLocked() const{// This surface is always consumed by SurfaceFlinger, so the// producerControlledByApp value doesn't matter; using false.mSurfaceData = new Surface(mGraphicBufferProducer, false);return mSurfaceData;}sp<Surface> SurfaceControl::getSurface() const{Mutex::Autolock _l(mLock);if (mSurfaceData == nullptr) {ALOGD("mSurfaceData == nullptr");return generateSurfaceLocked();}return mSurfaceData;}
}
SurfaceControl在ViewRootImpl类的relayoutWindow()方法被初始化后,之前提到的ViewRootImpl类的mSurface变量也通过copyFrom()方法关联到cpp层的Surface对象。
通过SurfaceControl.mNativeObject获取到cpp层的SurfaceControl对象,SurfaceControl.getSurface()返回cpp层的Surface对象。至此Surface对象也准备好了。
// Surface.java
public class Surface implements Parcelable {long mNativeObject; // package scope only for SurfaceControl accesspublic void copyFrom(SurfaceControl other) {long surfaceControlPtr = other.mNativeObject;long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);synchronized (mLock) {if (newNativeObject == mNativeObject) {return;}if (mNativeObject != 0) {nativeRelease(mNativeObject);}setNativeObjectLocked(newNativeObject);}}private void setNativeObjectLocked(long ptr) {if (mNativeObject != ptr) {mNativeObject = ptr;mGenerationId += 1;if (mHwuiContext != null) {mHwuiContext.updateSurface();}}}
}
Layer/Producer/Consumer
SurfaceControl构造方法中nativeCreate()不仅仅创建了native层的SurfaceControl对象,还调用了surfaceflinger的createLayer()方法创建Layer对象。
A Layer is the most important unit of composition. A layer is a combination of a surface and an instance of
SurfaceControl
. Each layer has a set of properties that define how it interacts with other layers. Layer properties are described in the table below.
BufferQueueLayer在onFirstRef()方法中初始化生产者和消费者,消费者设置内容监听ContentsChangedListener。
// frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp
/** A new BufferQueue and a new BufferLayerConsumer are created when the* BufferLayer is first referenced.** This also implements onFrameAvailable(), which notifies SurfaceFlinger* that new data has arrived.*/
void BufferQueueLayer::onFirstRef() {BufferLayer::onFirstRef();// Creates a custom BufferQueue for SurfaceFlingerConsumer to usesp<IGraphicBufferProducer> producer;sp<IGraphicBufferConsumer> consumer;mFlinger->getFactory().createBufferQueue(&producer, &consumer, true);mProducer = mFlinger->getFactory().createMonitoredProducer(producer, mFlinger, this);mConsumer =mFlinger->getFactory().createBufferLayerConsumer(consumer, mFlinger->getRenderEngine(),mTextureName, this);mConsumer->setConsumerUsageBits(getEffectiveUsage(0));mContentsChangedListener = new ContentsChangedListener(this);mConsumer->setContentsChangedListener(mContentsChangedListener);mConsumer->setName(String8(mName.data(), mName.size()));// BufferQueueCore::mMaxDequeuedBufferCount is default to 1if (!mFlinger->isLayerTripleBufferingDisabled()) {mProducer->setMaxDequeuedBufferCount(2);}
}void BufferQueueLayer::ContentsChangedListener::onFrameAvailable(const BufferItem& item) {Mutex::Autolock lock(mMutex);if (mBufferQueueLayer != nullptr) {mBufferQueueLayer->onFrameAvailable(item);}
}
RenderThread
mTraversalRunnable在调用relayoutWindow()方法完成surface对象的初始化后,开始performMeasure(),performLayout()计算View的位置信息,performDraw()开始渲染过程,在硬件加速渲染环境中,Android应用程序窗口的UI渲染是分两步进行的。第一步是构建Display List,发生在应用程序进程的Main Thread中;第二步是渲染Display List,发生在应用程序进程的Render Thread中。
// HardwareRenderer.java
public class HardwareRenderer {private final long mNativeProxy;/** @hide */protected RenderNode mRootNode;public HardwareRenderer() {mRootNode = RenderNode.adopt(nCreateRootRenderNode());mRootNode.setClipToBounds(false);mNativeProxy = nCreateProxy(!mOpaque, mIsWideGamut, mRootNode.mNativeRenderNode);if (mNativeProxy == 0) {throw new OutOfMemoryError("Unable to create hardware renderer");}Cleaner.create(this, new DestroyContextRunnable(mNativeProxy));ProcessInitializer.sInstance.init(mNativeProxy);}
}
ThreadedRenderer继承HardwareRenderer,构造方法中先分配唯一的RenderNode,nCreateProxy()初始化RenderProxy对象,RenderProxy负责native层的渲染RenderNode工作。
先看下RenderProxy的构造函数,一开始创建的RenderNode对象作为参数传递给了mContext(CanvasContext)和mDrawFrameTask。
//frameworks/base/libs/hwui/renderthread/RenderProxy.cpp
RenderProxy::RenderProxy(bool translucent, RenderNode* rootRenderNode,IContextFactory* contextFactory): mRenderThread(RenderThread::getInstance()), mContext(nullptr) {mContext = mRenderThread.queue().runSync([&]() -> CanvasContext* {return CanvasContext::create(mRenderThread, translucent, rootRenderNode, contextFactory);});mDrawFrameTask.setContext(&mRenderThread, mContext, rootRenderNode);
}
CanvasContext判断渲染类型选择SkiaOpenGLPipeline或是SkiaVulkanPipeline
//frameworks/base/libs/hwui/renderthread/CanvasContext.cpp
CanvasContext* CanvasContext::create(RenderThread& thread, bool translucent,RenderNode* rootRenderNode, IContextFactory* contextFactory) {auto renderType = Properties::getRenderPipelineType();switch (renderType) {case RenderPipelineType::SkiaGL:return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,std::make_unique<skiapipeline::SkiaOpenGLPipeline>(thread));case RenderPipelineType::SkiaVulkan:return new CanvasContext(thread, translucent, rootRenderNode, contextFactory,std::make_unique<skiapipeline::SkiaVulkanPipeline>(thread));default:LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t)renderType);break;}return nullptr;
}CanvasContext::CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,IContextFactory* contextFactory,std::unique_ptr<IRenderPipeline> renderPipeline): mRenderThread(thread), mGenerationID(0), mOpaque(!translucent), mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord())), mJankTracker(&thread.globalProfileData()), mProfiler(mJankTracker.frames(), thread.timeLord().frameIntervalNanos()), mContentDrawBounds(0, 0, 0, 0), mRenderPipeline(std::move(renderPipeline)) {rootRenderNode->makeRoot();mRenderNodes.emplace_back(rootRenderNode);mProfiler.setDensity(DeviceInfo::getDensity());setRenderAheadDepth(Properties::defaultRenderAhead);
}
到这里native层的RenderNode,RenderProxy,CanvasContext,IRenderPipeline等对象都初始化完成。
ThreadedRenderer开始调用draw()方法开始RenderNode的渲染工作。
// ThreadedRenderer.java
public final class ThreadedRenderer extends HardwareRenderer {void draw(View view, AttachInfo attachInfo, DrawCallbacks callbacks) {final Choreographer choreographer = attachInfo.mViewRootImpl.mChoreographer;choreographer.mFrameInfo.markDrawStart();updateRootDisplayList(view, callbacks);int syncResult = syncAndDrawFrame(choreographer.mFrameInfo);...}
}
updateRootDisplayList()构建参数view描述的视图的Display List,即DecorView的DisplayList。构建好的这个DisplayList可以通过调用参数view描述的视图的成员函数getDisplayList()获得的一个RenderNode来描述。
syncAndDrawFrame()调用的是native方法nSyncAndDrawFrame(),主要逻辑操作在DrawFrameTask::run()方法,DrawFrameTask运行在RenderThread(下图1927)上,而不是UIThread(下图1905)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZaPy8juV-1678103236257)(/home/lin/Nutstore Files/我的坚果云/notes/activity/2022-07-27 16-42-23屏幕截图.png)]
//frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp
void DrawFrameTask::run() {ATRACE_NAME("DrawFrame");bool canUnblockUiThread;bool canDrawThisFrame;{TreeInfo info(TreeInfo::MODE_FULL, *mContext);canUnblockUiThread = syncFrameState(info);canDrawThisFrame = info.out.canDrawThisFrame;if (mFrameCompleteCallback) {mContext->addFrameCompleteListener(std::move(mFrameCompleteCallback));mFrameCompleteCallback = nullptr;}}// Grab a copy of everything we needCanvasContext* context = mContext;std::function<void(int64_t)> callback = std::move(mFrameCallback);mFrameCallback = nullptr;// From this point on anything in "this" is *UNSAFE TO ACCESS*if (canUnblockUiThread) {unblockUiThread();}// Even if we aren't drawing this vsync pulse the next frame number will still be accurateif (CC_UNLIKELY(callback)) {context->enqueueFrameWork([callback, frameNr = context->getFrameNumber()]() { callback(frameNr); });}if (CC_LIKELY(canDrawThisFrame)) {context->draw();} else {// wait on fences so tasks don't overlap next framecontext->waitOnFences();}if (!canUnblockUiThread) {unblockUiThread();}
}
syncFrameState()通过DecorView的RenderNode对象(HardwareRenderer.mRootNode)将应用程序窗口的DisplayList、RenderProperty以及DisplayList引用的Bitmap等信息从MainThread同步到RenderThread中。注意,在这个同步过程中,MainThread是处于等待状态的。
如果成员函数syncFrameState能顺利地完成信息同步,那么它的返回值canUnblockUiThread就会等于true,表示在Render Thread渲染应用程序窗口的下一帧之前,就可以唤醒Main Thread了。否则的话,就要等到Render Thread渲染应用程序窗口的下一帧之后,才能唤醒Main Thread。唤醒Render Thread是通过调用成员函数unblockUiThread来完成的。
context->draw(),调用成员变量mContext描述的一个CanvasContext对象的成员函数draw()渲染应用程序窗口的DisplayList。
//frameworks/base/libs/hwui/renderthread/CanvasContext.cppvoid CanvasContext::draw() {SkRect dirty;mDamageAccumulator.finish(&dirty);SkRect windowDirty = computeDirtyRect(frame, &dirty);bool drew = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry, &mLayerUpdateQueue,mContentDrawBounds, mOpaque, mLightInfo, mRenderNodes,&(profiler()));waitOnFences();bool didSwap =mRenderPipeline->swapBuffers(frame, drew, windowDirty, mCurrentFrameInfo, &requireSwap);mIsDirty = false;if (requireSwap) {...}...mRenderThread.cacheManager().onFrameCompleted();
}
computeDirtyRect()计算脏区,mRenderPipeline->draw()开始渲染工作,mRenderPipeline->swapBuffers()后面会通过EglManager等处理,queueBuffer() 入队列这个buffer,将前面已经绘制好的图形缓冲区提交给SurfaceFlinger合成和显示,SurfaceFlinger在消费者onFrameAvailable()后开始接手工作。
参考:
https://blog.csdn.net/luoshengyang/article/details/46281499,
https://androidperformance.com/2015/08/12/AndroidL-hwui-RenderThread-workflow/#/2-4-swapBuffers
SurfaceView/TextureView
-
SurfaceView
-
具有独立的surface对象,对应WMS和SurfaceFlinger而言它就如同是一个DecorView,在WMS中有一个对应的WindowState,在SurfaceFlinger中有一个对应的Layer。
-
用来描述SurfaceView的Layer或者LayerBuffer的Z轴位置是小于用来其宿主Activity窗口的Layer的Z轴位置的,SurfaceView的onAttachedToWindow()方法中会请求宿主DecorView一块透明区域以显示SurfaceView画面。
public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCallback {final Surface mSurface = new Surface(); // Current surface in use@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();getViewRootImpl().addSurfaceChangedCallback(this);mWindowStopped = false;mViewVisibility = getVisibility() == VISIBLE;updateRequestedVisibility();mAttachedToWindow = true;mParent.requestTransparentRegion(SurfaceView.this); //请求透明区域if (!mGlobalListenersAdded) {ViewTreeObserver observer = getViewTreeObserver();observer.addOnScrollChangedListener(mScrollChangedListener);observer.addOnPreDrawListener(mDrawListener);mGlobalListenersAdded = true;}} }
-
SurfaceView的UI绘制可以在独立的线程中进行,这样就可以进行复杂的UI绘制,并且不会影响应用程序的主线程响应用户输入。
-
-
TextureView
TextureView是对SurfaceTexture的包装,SurfaceTexture构造方法中通过nativeInit()实例化native层的SurfaceTexture对象和生产者Producer,消费者Consumer。
//SurfaceTexture.cpp
static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jboolean isDetached,jint texName, jboolean singleBufferMode, jobject weakThiz)
{sp<IGraphicBufferProducer> producer;sp<IGraphicBufferConsumer> consumer;BufferQueue::createBufferQueue(&producer, &consumer);if (singleBufferMode) {consumer->setMaxBufferCount(1);}sp<SurfaceTexture> surfaceTexture;if (isDetached) {surfaceTexture = new SurfaceTexture(consumer, GL_TEXTURE_EXTERNAL_OES,true, !singleBufferMode);} else {surfaceTexture = new SurfaceTexture(consumer, texName,GL_TEXTURE_EXTERNAL_OES, true, !singleBufferMode);}SurfaceTexture_setSurfaceTexture(env, thiz, surfaceTexture);SurfaceTexture_setProducer(env, thiz, producer);surfaceTexture->setFrameAvailableListener(ctx);SurfaceTexture_setFrameAvailableListener(env, thiz, ctx);
}
SurfaceTexture对图像流的处理并不直接显示,而是转为GL外部纹理,用于图像流数据的二次处理。
TextureView就是对SurfaceTexture的二次处理,将纹理数据输出为View显示出来,TextureView覆盖了View的 draw() 方法。
//TextureView.java @Overridepublic final void draw(Canvas canvas) {// NOTE: Maintain this carefully (see View#draw)mPrivateFlags = (mPrivateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;/* Simplify drawing to guarantee the layer is the only thing drawn - so e.g. no background,scrolling, or fading edges. This guarantees all drawing is in the layer, so drawingproperties (alpha, layer paint) affect all of the content of a TextureView. */if (canvas.isHardwareAccelerated()) {RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;TextureLayer layer = getTextureLayer();if (layer != null) {applyUpdate();applyTransformMatrix();mLayer.setLayerPaint(mLayerPaint); // ensure layer paint is up to daterecordingCanvas.drawTextureLayer(layer);}}}
可以看到TextureView必须工作在硬件加速的环境,通过 hwui 中的RenderThread渲染绘制图像,或者什么也不会做。
流程图: