前面的文章介绍了绘制的主要流程和基础组件,包括Vsync的主要流程,Surface的创建流程,Canvas相关的组件,现在可以开始绘制了。前面的文章已经分析过,现在默认是开启硬件加速的,因此会使用HardwareRenderer来进行绘制,涉及的内容较多,本文仅介绍HardwareRenderer的初始化流程。
1. ViewRootImpl
HardwareRendererder的初始化是再ViewRootImpl在完成的,再setView方法中,会调用enableHardwareAcceleration方法:
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView, int userId) {if (mSurfaceHolder == null) {enableHardwareAcceleration(attrs);}}public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView, int userId) { if (mSurfaceHolder == null) { enableHardwareAcceleration(attrs); } }public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView, int userId) { if (mSurfaceHolder == null) { enableHardwareAcceleration(attrs); } }
private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {...mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent, attrs.getTitle().toString());...}private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) { ... mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent, attrs.getTitle().toString()); ... }private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) { ... mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent, attrs.getTitle().toString()); ... }
frameworks/base/core/java/android/view/ThreadedRenderer.java
public static ThreadedRenderer create(Context context, boolean translucent, String name) {return new ThreadedRenderer(context, translucent, name);}public static ThreadedRenderer create(Context context, boolean translucent, String name) { return new ThreadedRenderer(context, translucent, name); }public static ThreadedRenderer create(Context context, boolean translucent, String name) { return new ThreadedRenderer(context, translucent, name); }
当relayoutWindow完成后,初始化了BlastBufferQueue,然后通过这个queue创建出了一个新的Surface,然后复制给到ViewRootImpl的mSurface,从而mSurface变成可用状态。
private void performTraversals() {...relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);...if (surfaceCreated) {...if (mAttachInfo.mThreadedRenderer != null) {...hwInitialized = mAttachInfo.mThreadedRenderer.initialize(mSurface);if (hwInitialized && (host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) {// Don't pre-allocate if transparent regions// are requested as they may not be neededmAttachInfo.mThreadedRenderer.allocateBuffers();}...}} else {....}...private void performTraversals() { ... relayoutResult = relayoutWindow(params, viewVisibility, insetsPending); ... if (surfaceCreated) { ... if (mAttachInfo.mThreadedRenderer != null) { ... hwInitialized = mAttachInfo.mThreadedRenderer.initialize(mSurface); if (hwInitialized && (host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) { // Don't pre-allocate if transparent regions // are requested as they may not be needed mAttachInfo.mThreadedRenderer.allocateBuffers(); } ... } } else { .... } ...private void performTraversals() { ... relayoutResult = relayoutWindow(params, viewVisibility, insetsPending); ... if (surfaceCreated) { ... if (mAttachInfo.mThreadedRenderer != null) { ... hwInitialized = mAttachInfo.mThreadedRenderer.initialize(mSurface); if (hwInitialized && (host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) { // Don't pre-allocate if transparent regions // are requested as they may not be needed mAttachInfo.mThreadedRenderer.allocateBuffers(); } ... } } else { .... } ...
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending) throws RemoteException {...int relayoutResult = mWindowSession.relayout(mWindow, params,,,,);if (mSurfaceControl.isValid()) {final Surface blastSurface = getOrCreateBLASTSurface();// If blastSurface == null that means it hasn't changed since the last time we// called. In this situation, avoid calling transferFrom as we would then// inc the generation ID and cause EGL resources to be recreated.if (blastSurface != null) {mSurface.transferFrom(blastSurface);}}if (mAttachInfo.mThreadedRenderer != null) {...mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl);}}...}private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending) throws RemoteException { ... int relayoutResult = mWindowSession.relayout(mWindow, params,,,,); if (mSurfaceControl.isValid()) { final Surface blastSurface = getOrCreateBLASTSurface(); // If blastSurface == null that means it hasn't changed since the last time we // called. In this situation, avoid calling transferFrom as we would then // inc the generation ID and cause EGL resources to be recreated. if (blastSurface != null) { mSurface.transferFrom(blastSurface); } } if (mAttachInfo.mThreadedRenderer != null) { ... mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl); } } ... }private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility, boolean insetsPending) throws RemoteException { ... int relayoutResult = mWindowSession.relayout(mWindow, params,,,,); if (mSurfaceControl.isValid()) { final Surface blastSurface = getOrCreateBLASTSurface(); // If blastSurface == null that means it hasn't changed since the last time we // called. In this situation, avoid calling transferFrom as we would then // inc the generation ID and cause EGL resources to be recreated. if (blastSurface != null) { mSurface.transferFrom(blastSurface); } } if (mAttachInfo.mThreadedRenderer != null) { ... mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl); } } ... }
performTraversals 这里有两个步骤
- 调用relayoutWindow去生成有效的SurfaceControl,然后调用AttachInfo.mThreadedRenderer.setSurfaceControl方法设置到mThreadedRenderer
- relayout结束后,生成有效的Surface,然后调用mThreadedRenderer.initialize进行初始化,接着调用了allocateBuffers来分图形缓存。因此初始化中,我们主来分析这几个方法。
2. ThreadedRenderer构造方法
ThreadedRenderer继承自HardwareRenderer,因此构造方法直接进入HardwareRenderer的构造方法
frameworks/base/graphics/java/android/graphics/HardwareRenderer.java
public HardwareRenderer() {ProcessInitializer.sInstance.initUsingContext();mRootNode = RenderNode.adopt(nCreateRootRenderNode());mRootNode.setClipToBounds(false);mNativeProxy = nCreateProxy(!mOpaque, mRootNode.mNativeRenderNode);if (mNativeProxy == 0) {throw new OutOfMemoryError("Unable to create hardware renderer");}Cleaner.create(this, new DestroyContextRunnable(mNativeProxy));ProcessInitializer.sInstance.init(mNativeProxy);}public HardwareRenderer() { ProcessInitializer.sInstance.initUsingContext(); mRootNode = RenderNode.adopt(nCreateRootRenderNode()); mRootNode.setClipToBounds(false); mNativeProxy = nCreateProxy(!mOpaque, mRootNode.mNativeRenderNode); if (mNativeProxy == 0) { throw new OutOfMemoryError("Unable to create hardware renderer"); } Cleaner.create(this, new DestroyContextRunnable(mNativeProxy)); ProcessInitializer.sInstance.init(mNativeProxy); }public HardwareRenderer() { ProcessInitializer.sInstance.initUsingContext(); mRootNode = RenderNode.adopt(nCreateRootRenderNode()); mRootNode.setClipToBounds(false); mNativeProxy = nCreateProxy(!mOpaque, mRootNode.mNativeRenderNode); if (mNativeProxy == 0) { throw new OutOfMemoryError("Unable to create hardware renderer"); } Cleaner.create(this, new DestroyContextRunnable(mNativeProxy)); ProcessInitializer.sInstance.init(mNativeProxy); }
这里调用了很多的native函数来进行初始化
2.1 ProcessInitializer.sInstance.initUsingContext
synchronized void initUsingContext() {if (mContext == null) return;initDisplayInfo();nSetIsHighEndGfx(ActivityManager.isHighEndGfx());mContext = null;}synchronized void initUsingContext() { if (mContext == null) return; initDisplayInfo(); nSetIsHighEndGfx(ActivityManager.isHighEndGfx()); mContext = null; }synchronized void initUsingContext() { if (mContext == null) return; initDisplayInfo(); nSetIsHighEndGfx(ActivityManager.isHighEndGfx()); mContext = null; }
调用initDisplayInfo初始化DisplayInfo
private void initDisplayInfo() {DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);Display display = dm.getDisplay(Display.DEFAULT_DISPLAY);Mode activeMode = display.getMode();nInitDisplayInfo(activeMode.getPhysicalWidth(), activeMode.getPhysicalHeight(),display.getRefreshRate(), wideColorDataspace.mNativeDataspace,display.getAppVsyncOffsetNanos(), display.getPresentationDeadlineNanos());mDisplayInitialized = true;}private void initDisplayInfo() { DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); Display display = dm.getDisplay(Display.DEFAULT_DISPLAY); Mode activeMode = display.getMode(); nInitDisplayInfo(activeMode.getPhysicalWidth(), activeMode.getPhysicalHeight(), display.getRefreshRate(), wideColorDataspace.mNativeDataspace, display.getAppVsyncOffsetNanos(), display.getPresentationDeadlineNanos()); mDisplayInitialized = true; }private void initDisplayInfo() { DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); Display display = dm.getDisplay(Display.DEFAULT_DISPLAY); Mode activeMode = display.getMode(); nInitDisplayInfo(activeMode.getPhysicalWidth(), activeMode.getPhysicalHeight(), display.getRefreshRate(), wideColorDataspace.mNativeDataspace, display.getAppVsyncOffsetNanos(), display.getPresentationDeadlineNanos()); mDisplayInitialized = true; }
获取默认显示器,然后调用nInitDisplayInfo,传入的物理宽度,长度,刷新率等信息。
frameworks/base/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
static void android_view_ThreadedRenderer_initDisplayInfo(JNIEnv*, jclass, jint physicalWidth,jint physicalHeight, jfloat refreshRate,jint wideColorDataspace,jlong appVsyncOffsetNanos,jlong presentationDeadlineNanos) {DeviceInfo::setWidth(physicalWidth);DeviceInfo::setHeight(physicalHeight);DeviceInfo::setRefreshRate(refreshRate);DeviceInfo::setWideColorDataspace(static_cast<ADataSpace>(wideColorDataspace));DeviceInfo::setAppVsyncOffsetNanos(appVsyncOffsetNanos);DeviceInfo::setPresentationDeadlineNanos(presentationDeadlineNanos);}static void android_view_ThreadedRenderer_initDisplayInfo(JNIEnv*, jclass, jint physicalWidth, jint physicalHeight, jfloat refreshRate, jint wideColorDataspace, jlong appVsyncOffsetNanos, jlong presentationDeadlineNanos) { DeviceInfo::setWidth(physicalWidth); DeviceInfo::setHeight(physicalHeight); DeviceInfo::setRefreshRate(refreshRate); DeviceInfo::setWideColorDataspace(static_cast<ADataSpace>(wideColorDataspace)); DeviceInfo::setAppVsyncOffsetNanos(appVsyncOffsetNanos); DeviceInfo::setPresentationDeadlineNanos(presentationDeadlineNanos); }static void android_view_ThreadedRenderer_initDisplayInfo(JNIEnv*, jclass, jint physicalWidth, jint physicalHeight, jfloat refreshRate, jint wideColorDataspace, jlong appVsyncOffsetNanos, jlong presentationDeadlineNanos) { DeviceInfo::setWidth(physicalWidth); DeviceInfo::setHeight(physicalHeight); DeviceInfo::setRefreshRate(refreshRate); DeviceInfo::setWideColorDataspace(static_cast<ADataSpace>(wideColorDataspace)); DeviceInfo::setAppVsyncOffsetNanos(appVsyncOffsetNanos); DeviceInfo::setPresentationDeadlineNanos(presentationDeadlineNanos); }
将显示器的信息保存到DeviceInfo,因此在底层后续就可以知道显示器的这些信息。
2.2 初始化RootRenderNode
调用jni方法nCreateRootRenderNode来生成RootRenderNode的对象
static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) {RootRenderNode* node = new RootRenderNode(std::make_unique<JvmErrorReporter>(env));node->incStrong(0);node->setName("RootRenderNode");return reinterpret_cast<jlong>(node);}static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) { RootRenderNode* node = new RootRenderNode(std::make_unique<JvmErrorReporter>(env)); node->incStrong(0); node->setName("RootRenderNode"); return reinterpret_cast<jlong>(node); }static jlong android_view_ThreadedRenderer_createRootRenderNode(JNIEnv* env, jobject clazz) { RootRenderNode* node = new RootRenderNode(std::make_unique<JvmErrorReporter>(env)); node->incStrong(0); node->setName("RootRenderNode"); return reinterpret_cast<jlong>(node); }
生成一个RootRenderNode对象,并返回其指针给java层,java层构造一个RenderNode对象来持有这个指针,
public static RenderNode adopt(long nativePtr) {return new RenderNode(nativePtr);}public static RenderNode adopt(long nativePtr) { return new RenderNode(nativePtr); }public static RenderNode adopt(long nativePtr) { return new RenderNode(nativePtr); }
将这个对象赋值给mRootNode。RenderNode的构造方法如下:
private RenderNode(long nativePtr) {mNativeRenderNode = nativePtr;NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);mAnimationHost = null;}private RenderNode(long nativePtr) { mNativeRenderNode = nativePtr; NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode); mAnimationHost = null; }private RenderNode(long nativePtr) { mNativeRenderNode = nativePtr; NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode); mAnimationHost = null; }
2.3 创建RenderProxy
调用nCreateProxy来创建一个RenderProxy,RenderProxy是向上提供API,其内部真正起作用的是RenderThread 和DrawFrameTask, RenderProxy的大部分方法都会通过向ReaderThread的工作队列里添加任务去执行,或者通过DrawFrameTask 去绘制一帧。
static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz,jboolean translucent, jlong rootRenderNodePtr) {RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr);ContextFactoryImpl factory(rootRenderNode);RenderProxy* proxy = new RenderProxy(translucent, rootRenderNode, &factory);return (jlong) proxy;}static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz, jboolean translucent, jlong rootRenderNodePtr) { RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr); ContextFactoryImpl factory(rootRenderNode); RenderProxy* proxy = new RenderProxy(translucent, rootRenderNode, &factory); return (jlong) proxy; }static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz, jboolean translucent, jlong rootRenderNodePtr) { RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootRenderNodePtr); ContextFactoryImpl factory(rootRenderNode); RenderProxy* proxy = new RenderProxy(translucent, rootRenderNode, &factory); return (jlong) proxy; }
构造出RenderProxy对象,然后将这个指针保存到HardwareRender的mNativeProxy字段。
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,pthread_gettid_np(pthread_self()), getRenderThreadTid());}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, pthread_gettid_np(pthread_self()), getRenderThreadTid()); }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, pthread_gettid_np(pthread_self()), getRenderThreadTid()); }
构造RenderProxy的时候,会初始化RenderThread 和CanvasContext. 创建CanvasContext的时候,调用了mRenderThread.queue().runSync方法,这个类似Handler的runWithScissors,需要lamda执行完才返回。最后将renderThread,canvasContex和rootRenderNode设置到mDrawFrameTask。
2.4 创建RenderThread
RenderThread是一个无限循环的线程,它有一个queue来接受任务,有任务来时唤醒线程进行执行。这在HardwareRender初始化时需要将RenderThread初始化。这是一个单例对象,通过RenderThread::getInstance()来获取创建好的对象。
frameworks/base/libs/hwui/renderthread/RenderThread.cpp
RenderThread& RenderThread::getInstance() {[[clang::no_destroy]] static sp<RenderThread> sInstance = []() {sp<RenderThread> thread = sp<RenderThread>::make();thread->start("RenderThread");return thread;}();gHasRenderThreadInstance = true;return *sInstance;}RenderThread::RenderThread(): ThreadBase(), mVsyncSource(nullptr), mVsyncRequested(false), mFrameCallbackTaskPending(false), mRenderState(nullptr), mEglManager(nullptr), mFunctorManager(WebViewFunctorManager::instance()), mGlobalProfileData(mJankDataMutex) {Properties::load();}RenderThread& RenderThread::getInstance() { [[clang::no_destroy]] static sp<RenderThread> sInstance = []() { sp<RenderThread> thread = sp<RenderThread>::make(); thread->start("RenderThread"); return thread; }(); gHasRenderThreadInstance = true; return *sInstance; } RenderThread::RenderThread() : ThreadBase() , mVsyncSource(nullptr) , mVsyncRequested(false) , mFrameCallbackTaskPending(false) , mRenderState(nullptr) , mEglManager(nullptr) , mFunctorManager(WebViewFunctorManager::instance()) , mGlobalProfileData(mJankDataMutex) { Properties::load(); }RenderThread& RenderThread::getInstance() { [[clang::no_destroy]] static sp<RenderThread> sInstance = []() { sp<RenderThread> thread = sp<RenderThread>::make(); thread->start("RenderThread"); return thread; }(); gHasRenderThreadInstance = true; return *sInstance; } RenderThread::RenderThread() : ThreadBase() , mVsyncSource(nullptr) , mVsyncRequested(false) , mFrameCallbackTaskPending(false) , mRenderState(nullptr) , mEglManager(nullptr) , mFunctorManager(WebViewFunctorManager::instance()) , mGlobalProfileData(mJankDataMutex) { Properties::load(); }
RenderThread继承自ThreadBase,当调用start启动线程的时候,会执行threadLoop方法:
bool RenderThread::threadLoop() {setpriority(PRIO_PROCESS, 0, PRIORITY_DISPLAY);Looper::setForThread(mLooper);if (gOnStartHook) {gOnStartHook("RenderThread");}initThreadLocals();while (true) {waitForWork();processQueue();...}return false;}bool RenderThread::threadLoop() { setpriority(PRIO_PROCESS, 0, PRIORITY_DISPLAY); Looper::setForThread(mLooper); if (gOnStartHook) { gOnStartHook("RenderThread"); } initThreadLocals(); while (true) { waitForWork(); processQueue(); ... } return false; }bool RenderThread::threadLoop() { setpriority(PRIO_PROCESS, 0, PRIORITY_DISPLAY); Looper::setForThread(mLooper); if (gOnStartHook) { gOnStartHook("RenderThread"); } initThreadLocals(); while (true) { waitForWork(); processQueue(); ... } return false; }
此时RenderThread就绪,等待Queue里出现任务。
2.5 创建CanvasContext
上面介绍了CanvasContext的构造是这样的:
mContext = mRenderThread.queue().runSync([&]() -> CanvasContext* {return CanvasContext::create(mRenderThread, translucent, rootRenderNode, contextFactory);});mContext = mRenderThread.queue().runSync([&]() -> CanvasContext* { return CanvasContext::create(mRenderThread, translucent, rootRenderNode, contextFactory); });mContext = mRenderThread.queue().runSync([&]() -> CanvasContext* { return CanvasContext::create(mRenderThread, translucent, rootRenderNode, contextFactory); });
最终调用的是一个create方法:
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::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::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; }
它首先根据系统属性配置,如果是使用SkialGL绘制的话,生成一个SkiaOpenGLPipeline对象,如果使用SkiaVulkan的话,就创建一个SkiaVulkanPipeline,当pipeline创建好后,用于生成CanvasContext。
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());}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()); }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()); }
这样CanvasContext就拥有了绘制的能力,比如RenderThread提供异步的绘制能力,mRenderPipeline提供图形绘制能力,rootRenderNode提供绘制内容。因此CanvasContext融合了绘制所需要各种的组件。
到这里HardwareRender的构造就完成了,它创建了底层的RenderProxy,启动了RenderThread,以及初始化了CanvaContext以及RenderPipeline。
3 HardwareRender的初始化
前面以及介绍了,HardwareRender对象创好出来之后,需要进行初始化,为其提供绘制所需的Surface。
boolean initialize(Surface surface) throws OutOfResourcesException {boolean status = !mInitialized;mInitialized = true;updateEnabledState(surface);setSurface(surface);return status;}boolean initialize(Surface surface) throws OutOfResourcesException { boolean status = !mInitialized; mInitialized = true; updateEnabledState(surface); setSurface(surface); return status; }boolean initialize(Surface surface) throws OutOfResourcesException { boolean status = !mInitialized; mInitialized = true; updateEnabledState(surface); setSurface(surface); return status; }
这里调用setSurface方法来这设置,从而进入到这个native方法
public void setSurface(@Nullable Surface surface, boolean discardBuffer) {if (surface != null && !surface.isValid()) {throw new IllegalArgumentException("Surface is invalid. surface.isValid() == false.");}nSetSurface(mNativeProxy, surface, discardBuffer);}public void setSurface(@Nullable Surface surface, boolean discardBuffer) { if (surface != null && !surface.isValid()) { throw new IllegalArgumentException("Surface is invalid. surface.isValid() == false."); } nSetSurface(mNativeProxy, surface, discardBuffer); }public void setSurface(@Nullable Surface surface, boolean discardBuffer) { if (surface != null && !surface.isValid()) { throw new IllegalArgumentException("Surface is invalid. surface.isValid() == false."); } nSetSurface(mNativeProxy, surface, discardBuffer); }
static void android_view_ThreadedRenderer_setSurface(JNIEnv* env, jobject clazz, jlong proxyPtr, jobject jsurface, jboolean discardBuffer) {RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);ANativeWindow* window = nullptr;if (jsurface) {window = fromSurface(env, jsurface);}bool enableTimeout = true;if (discardBuffer) {// Currently only Surface#lockHardwareCanvas takes this pathenableTimeout = false;proxy->setSwapBehavior(SwapBehavior::kSwap_discardBuffer);}proxy->setSurface(window, enableTimeout);if (window) {ANativeWindow_release(window);}}static void android_view_ThreadedRenderer_setSurface(JNIEnv* env, jobject clazz, jlong proxyPtr, jobject jsurface, jboolean discardBuffer) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); ANativeWindow* window = nullptr; if (jsurface) { window = fromSurface(env, jsurface); } bool enableTimeout = true; if (discardBuffer) { // Currently only Surface#lockHardwareCanvas takes this path enableTimeout = false; proxy->setSwapBehavior(SwapBehavior::kSwap_discardBuffer); } proxy->setSurface(window, enableTimeout); if (window) { ANativeWindow_release(window); } }static void android_view_ThreadedRenderer_setSurface(JNIEnv* env, jobject clazz, jlong proxyPtr, jobject jsurface, jboolean discardBuffer) { RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr); ANativeWindow* window = nullptr; if (jsurface) { window = fromSurface(env, jsurface); } bool enableTimeout = true; if (discardBuffer) { // Currently only Surface#lockHardwareCanvas takes this path enableTimeout = false; proxy->setSwapBehavior(SwapBehavior::kSwap_discardBuffer); } proxy->setSurface(window, enableTimeout); if (window) { ANativeWindow_release(window); } }
在这里我们看到将一个Surface转换成了一个ANativeWindow,我们前面介绍过,Surface是继承自ANativeWindow的,而fromSurface函数是定义window.h的方法ANativeWindow_fromSurface,它只是作了一个类型转换,其实返回的就还是Surface本身。
frameworks/base/native/android/native_window_jni.cpp
ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface) {sp<ANativeWindow> win = android_view_Surface_getNativeWindow(env, surface);if (win != NULL) {ANativeWindow_acquire(win.get());}return win.get();}ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface) { sp<ANativeWindow> win = android_view_Surface_getNativeWindow(env, surface); if (win != NULL) { ANativeWindow_acquire(win.get()); } return win.get(); }ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface) { sp<ANativeWindow> win = android_view_Surface_getNativeWindow(env, surface); if (win != NULL) { ANativeWindow_acquire(win.get()); } return win.get(); }
ANativeWindow_acquire 和ANativeWindow_release 是分别作引用计数的增加和减少。在转换成了ANativeWinwodw之后,设置到proxy去
void RenderProxy::setSurface(ANativeWindow* window, bool enableTimeout) {if (window) { ANativeWindow_acquire(window); }mRenderThread.queue().post([this, win = window, enableTimeout]() mutable {mContext->setSurface(win, enableTimeout);if (win) { ANativeWindow_release(win); }});}void RenderProxy::setSurface(ANativeWindow* window, bool enableTimeout) { if (window) { ANativeWindow_acquire(window); } mRenderThread.queue().post([this, win = window, enableTimeout]() mutable { mContext->setSurface(win, enableTimeout); if (win) { ANativeWindow_release(win); } }); }void RenderProxy::setSurface(ANativeWindow* window, bool enableTimeout) { if (window) { ANativeWindow_acquire(window); } mRenderThread.queue().post([this, win = window, enableTimeout]() mutable { mContext->setSurface(win, enableTimeout); if (win) { ANativeWindow_release(win); } }); }
通过王renderThread的队列中post一个任务来,将ANativeWindow 设置的到CanvasContext
void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) {ATRACE_CALL();if (window) {mNativeSurface = std::make_unique<ReliableSurface>(window);mNativeSurface->init();if (enableTimeout) {// TODO: Fix error handling & re-shorten timeoutANativeWindow_setDequeueTimeout(window, 4000_ms);}} else {mNativeSurface = nullptr;}setupPipelineSurface();}void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) { ATRACE_CALL(); if (window) { mNativeSurface = std::make_unique<ReliableSurface>(window); mNativeSurface->init(); if (enableTimeout) { // TODO: Fix error handling & re-shorten timeout ANativeWindow_setDequeueTimeout(window, 4000_ms); } } else { mNativeSurface = nullptr; } setupPipelineSurface(); }void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) { ATRACE_CALL(); if (window) { mNativeSurface = std::make_unique<ReliableSurface>(window); mNativeSurface->init(); if (enableTimeout) { // TODO: Fix error handling & re-shorten timeout ANativeWindow_setDequeueTimeout(window, 4000_ms); } } else { mNativeSurface = nullptr; } setupPipelineSurface(); }
在这里先 创建一个ReliableSurface来包装window,接着调用init进行初始化,enableTimeout为true,于是设置dequeue的超时为4秒钟,然后在调用setupPipelineSurface开启绘制流水线。我们来一步步分析一下
3.1 ReliableSurface
它的构造很简单
frameworks/base/libs/hwui/renderthread/ReliableSurface.cpp
ReliableSurface::ReliableSurface(ANativeWindow* window) : mWindow(window) {LOG_ALWAYS_FATAL_IF(!mWindow, "Error, unable to wrap a nullptr");ANativeWindow_acquire(mWindow);}ReliableSurface::ReliableSurface(ANativeWindow* window) : mWindow(window) { LOG_ALWAYS_FATAL_IF(!mWindow, "Error, unable to wrap a nullptr"); ANativeWindow_acquire(mWindow); }ReliableSurface::ReliableSurface(ANativeWindow* window) : mWindow(window) { LOG_ALWAYS_FATAL_IF(!mWindow, "Error, unable to wrap a nullptr"); ANativeWindow_acquire(mWindow); }
赋值给mWindow,然后增加引用计数
3.2 ReliableSurface.init
void ReliableSurface::init() {int result = ANativeWindow_setCancelBufferInterceptor(mWindow, hook_cancelBuffer, this);LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set cancelBuffer interceptor: error = %d",result);result = ANativeWindow_setDequeueBufferInterceptor(mWindow, hook_dequeueBuffer, this);LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set dequeueBuffer interceptor: error = %d",result);result = ANativeWindow_setQueueBufferInterceptor(mWindow, hook_queueBuffer, this);LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set queueBuffer interceptor: error = %d",result);result = ANativeWindow_setPerformInterceptor(mWindow, hook_perform, this);LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set perform interceptor: error = %d",result);result = ANativeWindow_setQueryInterceptor(mWindow, hook_query, this);LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set query interceptor: error = %d",result);}void ReliableSurface::init() { int result = ANativeWindow_setCancelBufferInterceptor(mWindow, hook_cancelBuffer, this); LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set cancelBuffer interceptor: error = %d", result); result = ANativeWindow_setDequeueBufferInterceptor(mWindow, hook_dequeueBuffer, this); LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set dequeueBuffer interceptor: error = %d", result); result = ANativeWindow_setQueueBufferInterceptor(mWindow, hook_queueBuffer, this); LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set queueBuffer interceptor: error = %d", result); result = ANativeWindow_setPerformInterceptor(mWindow, hook_perform, this); LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set perform interceptor: error = %d", result); result = ANativeWindow_setQueryInterceptor(mWindow, hook_query, this); LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set query interceptor: error = %d", result); }void ReliableSurface::init() { int result = ANativeWindow_setCancelBufferInterceptor(mWindow, hook_cancelBuffer, this); LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set cancelBuffer interceptor: error = %d", result); result = ANativeWindow_setDequeueBufferInterceptor(mWindow, hook_dequeueBuffer, this); LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set dequeueBuffer interceptor: error = %d", result); result = ANativeWindow_setQueueBufferInterceptor(mWindow, hook_queueBuffer, this); LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set queueBuffer interceptor: error = %d", result); result = ANativeWindow_setPerformInterceptor(mWindow, hook_perform, this); LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set perform interceptor: error = %d", result); result = ANativeWindow_setQueryInterceptor(mWindow, hook_query, this); LOG_ALWAYS_FATAL_IF(result != NO_ERROR, "Failed to set query interceptor: error = %d", result); }
它init为ANativeWindow设置了5个拦截器,这个连接器在Surface本身的hook函数中执行,所以dequeueBuffer, queueBuffer,perform 和query方法都会转到到ReliableSurface来执行,我们分析一下hook_dequeueBuffer方法的拦截机制
int ReliableSurface::hook_dequeueBuffer(ANativeWindow* window,ANativeWindow_dequeueBufferFn dequeueBuffer, void* data,ANativeWindowBuffer** buffer, int* fenceFd) {ReliableSurface* rs = reinterpret_cast<ReliableSurface*>(data);{std::lock_guard _lock{rs->mMutex};if (rs->mReservedBuffer) {*buffer = rs->mReservedBuffer;*fenceFd = rs->mReservedFenceFd.release();rs->mReservedBuffer = nullptr;return OK;}}int result = dequeueBuffer(window, buffer, fenceFd);if (result != OK) {ALOGW("dequeueBuffer failed, error = %d; switching to fallback", result);*buffer = rs->acquireFallbackBuffer(result);*fenceFd = -1;return *buffer ? OK : INVALID_OPERATION;} else {std::lock_guard _lock{rs->mMutex};rs->mHasDequeuedBuffer = true;}return OK;}int ReliableSurface::hook_dequeueBuffer(ANativeWindow* window, ANativeWindow_dequeueBufferFn dequeueBuffer, void* data, ANativeWindowBuffer** buffer, int* fenceFd) { ReliableSurface* rs = reinterpret_cast<ReliableSurface*>(data); { std::lock_guard _lock{rs->mMutex}; if (rs->mReservedBuffer) { *buffer = rs->mReservedBuffer; *fenceFd = rs->mReservedFenceFd.release(); rs->mReservedBuffer = nullptr; return OK; } } int result = dequeueBuffer(window, buffer, fenceFd); if (result != OK) { ALOGW("dequeueBuffer failed, error = %d; switching to fallback", result); *buffer = rs->acquireFallbackBuffer(result); *fenceFd = -1; return *buffer ? OK : INVALID_OPERATION; } else { std::lock_guard _lock{rs->mMutex}; rs->mHasDequeuedBuffer = true; } return OK; }int ReliableSurface::hook_dequeueBuffer(ANativeWindow* window, ANativeWindow_dequeueBufferFn dequeueBuffer, void* data, ANativeWindowBuffer** buffer, int* fenceFd) { ReliableSurface* rs = reinterpret_cast<ReliableSurface*>(data); { std::lock_guard _lock{rs->mMutex}; if (rs->mReservedBuffer) { *buffer = rs->mReservedBuffer; *fenceFd = rs->mReservedFenceFd.release(); rs->mReservedBuffer = nullptr; return OK; } } int result = dequeueBuffer(window, buffer, fenceFd); if (result != OK) { ALOGW("dequeueBuffer failed, error = %d; switching to fallback", result); *buffer = rs->acquireFallbackBuffer(result); *fenceFd = -1; return *buffer ? OK : INVALID_OPERATION; } else { std::lock_guard _lock{rs->mMutex}; rs->mHasDequeuedBuffer = true; } return OK; }
- data 是注册回调的时候,传入的this,因此可以转回ReliableSurface。
- 调用dequeueBuffer方法,这个dequeueBuffer方法是surface中在调用这个拦截器是传入的方法指针dequeueBufferInternal。
frameworks/native/libs/gui/Surface.cpp
int Surface::hook_dequeueBuffer(ANativeWindow* window,ANativeWindowBuffer** buffer, int* fenceFd) {Surface* c = getSelf(window);{std::shared_lock<std::shared_mutex> lock(c->mInterceptorMutex);if (c->mDequeueInterceptor != nullptr) {auto interceptor = c->mDequeueInterceptor;auto data = c->mDequeueInterceptorData;return interceptor(window, Surface::dequeueBufferInternal, data, buffer, fenceFd);}}return c->dequeueBuffer(buffer, fenceFd);}int Surface::hook_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd) { Surface* c = getSelf(window); { std::shared_lock<std::shared_mutex> lock(c->mInterceptorMutex); if (c->mDequeueInterceptor != nullptr) { auto interceptor = c->mDequeueInterceptor; auto data = c->mDequeueInterceptorData; return interceptor(window, Surface::dequeueBufferInternal, data, buffer, fenceFd); } } return c->dequeueBuffer(buffer, fenceFd); }int Surface::hook_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd) { Surface* c = getSelf(window); { std::shared_lock<std::shared_mutex> lock(c->mInterceptorMutex); if (c->mDequeueInterceptor != nullptr) { auto interceptor = c->mDequeueInterceptor; auto data = c->mDequeueInterceptorData; return interceptor(window, Surface::dequeueBufferInternal, data, buffer, fenceFd); } } return c->dequeueBuffer(buffer, fenceFd); }
因此其实还是调用到了Surface的dequeueBufferInternal来执行dequeueBuffer。只不过这里经过了ReliableSurface一层封装,记录一下mHasDequeuedBuffer = true。
3.3 setupPipelineSurface
这一步将ANativeWindow设置到pipeline
void CanvasContext::setupPipelineSurface() {bool hasSurface = mRenderPipeline->setSurface(mNativeSurface ? mNativeSurface->getNativeWindow() : nullptr, mSwapBehavior);...}void CanvasContext::setupPipelineSurface() { bool hasSurface = mRenderPipeline->setSurface( mNativeSurface ? mNativeSurface->getNativeWindow() : nullptr, mSwapBehavior); ... }void CanvasContext::setupPipelineSurface() { bool hasSurface = mRenderPipeline->setSurface( mNativeSurface ? mNativeSurface->getNativeWindow() : nullptr, mSwapBehavior); ... }
mRenderPipeline的类型是SkiaPipeline,而SkiaPipeline是继承自IRenderPipeline,setSurface也是定义在IRenderPipeline
frameworks/base/libs/hwui/renderthread/IRenderPipeline.h
virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior) = 0;virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior) = 0;virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior) = 0;
实现的是根据系统属性设置的,可能是SkiaOpenGLPipeline和SkiaVulkanPipeline,我们分析一下SkiaOpenGLPipeline
frameworks/base/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior) {if (mEglSurface != EGL_NO_SURFACE) {mEglManager.destroySurface(mEglSurface);mEglSurface = EGL_NO_SURFACE;}if (surface) {mRenderThread.requireGlContext();auto newSurface = mEglManager.createSurface(surface, mColorMode, mSurfaceColorSpace);if (!newSurface) {return false;}mEglSurface = newSurface.unwrap();}if (mEglSurface != EGL_NO_SURFACE) {const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer);mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer);return true;}return false;}bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior) { if (mEglSurface != EGL_NO_SURFACE) { mEglManager.destroySurface(mEglSurface); mEglSurface = EGL_NO_SURFACE; } if (surface) { mRenderThread.requireGlContext(); auto newSurface = mEglManager.createSurface(surface, mColorMode, mSurfaceColorSpace); if (!newSurface) { return false; } mEglSurface = newSurface.unwrap(); } if (mEglSurface != EGL_NO_SURFACE) { const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer); mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer); return true; } return false; }bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior) { if (mEglSurface != EGL_NO_SURFACE) { mEglManager.destroySurface(mEglSurface); mEglSurface = EGL_NO_SURFACE; } if (surface) { mRenderThread.requireGlContext(); auto newSurface = mEglManager.createSurface(surface, mColorMode, mSurfaceColorSpace); if (!newSurface) { return false; } mEglSurface = newSurface.unwrap(); } if (mEglSurface != EGL_NO_SURFACE) { const bool preserveBuffer = (swapBehavior != SwapBehavior::kSwap_discardBuffer); mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer); return true; } return false; }
mRenderThread.requireGlContext(); 将会为RenderThread创建好使用OpenGL进行GPU绘制的上下文
接着调用mEglManager的createSurface方法,传入ANativeWindow,生成一个EGLSurface。EGL 是OpenGL 与 Android 窗口的桥接。
frameworks/base/libs/hwui/renderthread/EglManager.cpp
Result<EGLSurface, EGLint> EglManager::createSurface(EGLNativeWindowType window,ColorMode colorMode,sk_sp<SkColorSpace> colorSpace) {...EGLSurface surface = eglCreateWindowSurface(mEglDisplay, config, window, attribs);if (surface == EGL_NO_SURFACE) {return Error<EGLint>{eglGetError()};}...return surface;}Result<EGLSurface, EGLint> EglManager::createSurface(EGLNativeWindowType window, ColorMode colorMode, sk_sp<SkColorSpace> colorSpace) { ... EGLSurface surface = eglCreateWindowSurface(mEglDisplay, config, window, attribs); if (surface == EGL_NO_SURFACE) { return Error<EGLint>{eglGetError()}; } ... return surface; }Result<EGLSurface, EGLint> EglManager::createSurface(EGLNativeWindowType window, ColorMode colorMode, sk_sp<SkColorSpace> colorSpace) { ... EGLSurface surface = eglCreateWindowSurface(mEglDisplay, config, window, attribs); if (surface == EGL_NO_SURFACE) { return Error<EGLint>{eglGetError()}; } ... return surface; }
ELGSurface是一个指针
frameworks/native/opengl/include/EGL/eglext.h
typedef void *EGLSurface;typedef void *EGLSurface;typedef void *EGLSurface;
eglCreateWindowSurface的实现如下
frameworks/native/opengl/libs/EGL/eglApi.cpp
EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window,const EGLint* attrib_list) {clearError();egl_connection_t* const cnx = &gEGLImpl;return cnx->platform.eglCreateWindowSurface(dpy, config, window, attrib_list);}EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint* attrib_list) { clearError(); egl_connection_t* const cnx = &gEGLImpl; return cnx->platform.eglCreateWindowSurface(dpy, config, window, attrib_list); }EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint* attrib_list) { clearError(); egl_connection_t* const cnx = &gEGLImpl; return cnx->platform.eglCreateWindowSurface(dpy, config, window, attrib_list); }
egl_connection_t的定义在这个头文件:
frameworks/native/opengl/libs/EGL/egldefs.h
struct egl_connection_t {...egl_t egl;platform_impl_t platform;...};extern egl_connection_t gEGLImpl;struct egl_connection_t { ... egl_t egl; platform_impl_t platform; ... }; extern egl_connection_t gEGLImpl;struct egl_connection_t { ... egl_t egl; platform_impl_t platform; ... }; extern egl_connection_t gEGLImpl;
platform又是另外一个结构体类型platform_impl_t
struct platform_impl_t {#include "platform_entries.in"};struct platform_impl_t { #include "platform_entries.in" };struct platform_impl_t { #include "platform_entries.in" };
frameworks/native/opengl/libs/platform_entries.in
EGL_ENTRY(EGLSurface, eglCreateWindowSurface, EGLDisplay, EGLConfig, NativeWindowType, const EGLint*)EGL_ENTRY(EGLSurface, eglCreateWindowSurface, EGLDisplay, EGLConfig, NativeWindowType, const EGLint*)EGL_ENTRY(EGLSurface, eglCreateWindowSurface, EGLDisplay, EGLConfig, NativeWindowType, const EGLint*)
frameworks/native/opengl/libs/hooks.h
#define EGL_ENTRY(_r, _api, ...) _r (*(_api))(__VA_ARGS__);#define EGL_ENTRY(_r, _api, ...) _r (*(_api))(__VA_ARGS__);#define EGL_ENTRY(_r, _api, ...) _r (*(_api))(__VA_ARGS__);
展开就等于:
EGLSurface *(eglCreateWindowSurface)(EGLDisplay, EGLConfig, NativeWindowType, const EGLint *)EGLSurface *(eglCreateWindowSurface)(EGLDisplay, EGLConfig, NativeWindowType, const EGLint *)EGLSurface *(eglCreateWindowSurface)(EGLDisplay, EGLConfig, NativeWindowType, const EGLint *)
这个函数的实现在这里
frameworks/native/opengl/libs/EGL/egl_platform_entries.cpp
static const implementation_map_t sPlatformImplMap[] = {...{ "eglCreateWindowSurface", (EGLFuncPointer)&eglCreateWindowSurfaceImpl },...}EGLSurface eglCreateWindowSurfaceImpl(EGLDisplay dpy, EGLConfig config, NativeWindowType window,const EGLint* attrib_list) {egl_connection_t* cnx = nullptr;egl_display_t* dp = validate_display_connection(dpy, &cnx);if (dp) {return eglCreateWindowSurfaceTmpl<EGLint, PFNEGLCREATEWINDOWSURFACEPROC>(dp, cnx, config, window, attrib_list,cnx->egl.eglCreateWindowSurface);}return EGL_NO_SURFACE;}static const implementation_map_t sPlatformImplMap[] = { ... { "eglCreateWindowSurface", (EGLFuncPointer)&eglCreateWindowSurfaceImpl }, ... } EGLSurface eglCreateWindowSurfaceImpl(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint* attrib_list) { egl_connection_t* cnx = nullptr; egl_display_t* dp = validate_display_connection(dpy, &cnx); if (dp) { return eglCreateWindowSurfaceTmpl< EGLint, PFNEGLCREATEWINDOWSURFACEPROC>(dp, cnx, config, window, attrib_list, cnx->egl.eglCreateWindowSurface); } return EGL_NO_SURFACE; }static const implementation_map_t sPlatformImplMap[] = { ... { "eglCreateWindowSurface", (EGLFuncPointer)&eglCreateWindowSurfaceImpl }, ... } EGLSurface eglCreateWindowSurfaceImpl(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint* attrib_list) { egl_connection_t* cnx = nullptr; egl_display_t* dp = validate_display_connection(dpy, &cnx); if (dp) { return eglCreateWindowSurfaceTmpl< EGLint, PFNEGLCREATEWINDOWSURFACEPROC>(dp, cnx, config, window, attrib_list, cnx->egl.eglCreateWindowSurface); } return EGL_NO_SURFACE; }
继续调用了eglCreateWindowSurfaceTmpl来生成EGLSurface。 这个函数的最后一个参数cnx->egl.eglCreateWindowSurface是一个方法指针。在上面的代码有列出,其中cnx->egl是一个egl_t类型的结构体,定义也是在hooks里,
struct egl_t {#include "EGL/egl_entries.in"};struct egl_t { #include "EGL/egl_entries.in" };struct egl_t { #include "EGL/egl_entries.in" };
frameworks/native/opengl/libs/EGL/egl_entries.in“`
EGL_ENTRY(EGLSurface, eglCreateWindowSurface, EGLDisplay, EGLConfig, NativeWindowType, const EGLint *)EGL_ENTRY(EGLSurface, eglCreateWindowSurface, EGLDisplay, EGLConfig, NativeWindowType, const EGLint *)EGL_ENTRY(EGLSurface, eglCreateWindowSurface, EGLDisplay, EGLConfig, NativeWindowType, const EGLint *)
展开之后,结果如下:
EGLSurface *(eglCreateWindowSurface)(EGLDisplay, EGLConfig, NativeWindowType, const EGLint *)EGLSurface *(eglCreateWindowSurface)(EGLDisplay, EGLConfig, NativeWindowType, const EGLint *)EGLSurface *(eglCreateWindowSurface)(EGLDisplay, EGLConfig, NativeWindowType, const EGLint *)
因此调用eglCreateWindowSurfaceTmpl方法的最后一个参数就是这个函数。我看一下这个函数
frameworks/native/opengl/libs/EGL/egl_platform_entries.cpp
template <typename AttrType, typename CreateFuncType>EGLSurface eglCreateWindowSurfaceTmpl(egl_display_t* dp, egl_connection_t* cnx, EGLConfig config,ANativeWindow* window, const AttrType* attrib_list,CreateFuncType createWindowSurfaceFunc) {...window->query(window, NATIVE_WINDOW_IS_VALID, &value);if (!value) {return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);}....int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);...int err = native_window_set_buffers_format(window, format);....window->setSwapInterval(window, 1);EGLSurface surface = createWindowSurfaceFunc(iDpy, config, window, attrib_list);if (surface != EGL_NO_SURFACE) {egl_surface_t* s = new egl_surface_t(dp, config, window, surface,getReportedColorSpace(colorSpace), cnx);return s;}// EGLSurface creation failedif (!cnx->useAngle) {native_window_set_buffers_format(window, 0);native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);}return EGL_NO_SURFACE;}template <typename AttrType, typename CreateFuncType> EGLSurface eglCreateWindowSurfaceTmpl(egl_display_t* dp, egl_connection_t* cnx, EGLConfig config, ANativeWindow* window, const AttrType* attrib_list, CreateFuncType createWindowSurfaceFunc) { ... window->query(window, NATIVE_WINDOW_IS_VALID, &value); if (!value) { return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } .... int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); ... int err = native_window_set_buffers_format(window, format); .... window->setSwapInterval(window, 1); EGLSurface surface = createWindowSurfaceFunc(iDpy, config, window, attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t* s = new egl_surface_t(dp, config, window, surface, getReportedColorSpace(colorSpace), cnx); return s; } // EGLSurface creation failed if (!cnx->useAngle) { native_window_set_buffers_format(window, 0); native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); } return EGL_NO_SURFACE; }template <typename AttrType, typename CreateFuncType> EGLSurface eglCreateWindowSurfaceTmpl(egl_display_t* dp, egl_connection_t* cnx, EGLConfig config, ANativeWindow* window, const AttrType* attrib_list, CreateFuncType createWindowSurfaceFunc) { ... window->query(window, NATIVE_WINDOW_IS_VALID, &value); if (!value) { return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } .... int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL); ... int err = native_window_set_buffers_format(window, format); .... window->setSwapInterval(window, 1); EGLSurface surface = createWindowSurfaceFunc(iDpy, config, window, attrib_list); if (surface != EGL_NO_SURFACE) { egl_surface_t* s = new egl_surface_t(dp, config, window, surface, getReportedColorSpace(colorSpace), cnx); return s; } // EGLSurface creation failed if (!cnx->useAngle) { native_window_set_buffers_format(window, 0); native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); } return EGL_NO_SURFACE; }
这里先对window作了一些操作,比如native_window_api_connect, 它会执行Surface的perform方法,最后调用到Surface的connect方法,但是因为现在BufferQueue是由App进程自己管理了,因此connect里并没有IPC的调用。最后执行createWindowSurfaceFunc函数来生成EGLSurface,然后包装成egl_surface_t_返回去。_createWindowSurfaceFunc* 是来自于cnx->egl. 这个egl是全局的,它是在初始化时,加载EGL驱动的时候赋值的,具体的逻辑比较复杂,所以它的内容就不再此处展开了。
frameworks/native/opengl/libs/EGL/egl_object.h.
class egl_surface_t : public egl_object_t {...egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface,EGLint colorSpace, egl_connection_t const* cnx);class egl_surface_t : public egl_object_t { ... egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface, EGLint colorSpace, egl_connection_t const* cnx);class egl_surface_t : public egl_object_t { ... egl_surface_t(egl_display_t* dpy, EGLConfig config, EGLNativeWindowType win, EGLSurface surface, EGLint colorSpace, egl_connection_t const* cnx);
这里可以看到egl_surface_t的定义,因为EGLSurface仅仅是一个指针,因此可以返回这个对象,同时我们也知道了后面使用的EGLSurface本质上是一个egl_surface_t对象。
4 总结
HardrwareRender的初始化需要从Java层传入Surface,这个Surface在C层将以ANativeWindow的形式被使用。 在初始化后,C
层会创建一个RenderProxy,启动一个RenderThread以及创建CanvasContext,它包含一个RenderPipeline,RenderPipeline通过EGLManager生成EGLSuface,它的类型只一个指针,实际指向一个egl_surface_t结构体,最终这个EGLSurfacec实际持有这个Surface对象,从而为后面通过EGL绘制搭建好环境。
?关注公众号:Android老皮!!!欢迎大家来找我探讨交流?