前面的文章介绍了制作的首要流程和基础组件,包括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);
}
}
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);
}
当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 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);
}
}
...
}
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);
}
这儿调用了很多的native函数来进行初始化
2.1 ProcessInitializer.sInstance.initUsingContext
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;
}
获取默认显示器,然后调用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);
}
将显示器的信息保存到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);
}
生成一个RootRenderNode目标,并回来其指针给java层,java层结构一个RenderNode目标来持有这个指针,
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;
}
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;
}
结构出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的时分,会初始化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承继自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;
}
此刻RenderThread就绪,等候Queue里呈现使命。
2.5 创立CanvasContext
上面介绍了CanvasContext的结构是这样的:
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;
}
它首要依据系统特点装备,如果是运用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就具有了制作的才能,比方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;
}
这儿调用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);
}
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_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); }
});
}
经过王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 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);
}
赋值给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);
}
它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;
}
- 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);
}
因而其实仍是调用到了Surface的dequeueBufferInternal来履行dequeueBuffer。只不过这儿经过了ReliableSurface一层封装,记载一下mHasDequeuedBuffer = true。
3.3 setupPipelineSurface
这一步将ANativeWindow设置到pipeline
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;
完成的是依据系统特点设置的,可能是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;
}
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;
}
ELGSurface是一个指针
frameworks/native/opengl/include/EGL/eglext.h
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);
}
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;
platform又是别的一个结构体类型platform_impl_t
struct platform_impl_t {
#include "platform_entries.in"
};
frameworks/native/opengl/libs/platform_entries.in
EGL_ENTRY(EGLSurface, eglCreateWindowSurface, EGLDisplay, EGLConfig, NativeWindowType, const EGLint*)
frameworks/native/opengl/libs/hooks.h
#define EGL_ENTRY(_r, _api, ...) _r (*(_api))(__VA_ARGS__);
打开就等于:
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;
}
持续调用了eglCreateWindowSurfaceTmpl来生成EGLSurface。 这个函数的最终一个参数cnx->egl.eglCreateWindowSurface是一个办法指针。在上面的代码有列出,其中cnx->egl是一个egl_t类型的结构体,界说也是在hooks里,
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 *)
打开之后,成果如下:
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 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);
这儿能够看到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老皮!!!欢迎大家来找我探讨沟通