SurfaceFlinger 分析 一
来源:互联网 发布:风行直播软件下载 编辑:程序博客网 时间:2024/06/05 19:17
SurfaceFlinger
1. SurfaceFlinger启动流程
SurfaceFlinger 线程启动是由kenerl加载init.rc文件后, 执行system/bin文件夹下的可执行文件: surfaceflinger, 启动main函数:
先见时序图:
启动main函数后创建自己的线程, 并限定binder线程最大为4个, 初始话后加入线程池:
ProcessState::self()->setThreadPoolMaxThreadCount(4); // 设置最大线程数 sp<ProcessState> ps(ProcessState::self()); ps->startThreadPool();
初始化的第一部分:
Main函数调用surface flinger的init函数, 对EGL, RenderEngine 等初始化:
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(mEGLDisplay, NULL, NULL); // EGL 的初始化动作 sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync, vsyncPhaseOffsetNs, true, "app"); // 虚拟化Vsync App UI部分 mEventThread = new EventThread(vsyncSrc); sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync, sfVsyncPhaseOffsetNs, true, "sf"); // 虚拟化Vsync SF合成部分 mSFEventThread = new EventThread(sfVsyncSrc); mEventQueue.setEventThread(mSFEventThread); // Initialize the H/W composer object. There may or may not be an // actual hardware composer underneath. mHwc = DisplayUtils::getInstance()->getHWCInstance(this, *static_cast<HWComposer::EventHandler *>(this)); // 初始化hardwarecomposer // get a RenderEngine for the given display / config (can't fail) mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID()); // retrieve the EGL context that was selected/created mEGLContext = mRenderEngine->getEGLContext(); LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT, "couldn't create EGLContext");
(1) . EGL的初始就不说了, 有意思的是 google 实例了两个不同的VsyncSource : vsyncSrc 与 sfvsyncSrc 一个是app ui的vsync另一个是surfaceflinger合成的vsync, 他们只是将hardware层传过来的vsync虚拟化了.
他们根据sfVsyncPhaseOffsetNs 与 vsyncPhaseOffsetNs 两个相对偏移量将
app UI绘制 与 SF合成区分
其中Phase Offset 1, 2 的值可以改变, 这样做的目的是避免了因同时唤醒app UI 渲染和SF合成是造成对CPU资源的抢占.
(2) . 接下来启动上述EventThread.
EventThread的构造函数只是初始化一些数据, 重要的是它的onFirstRef函数(使用强指针时, 就会触发onFirstRef函数 )
void EventThread::onFirstRef() { run("EventThread", PRIORITY_URGENT_DISPLAY+PRIORITY_MORE_FAVORABLE);}
Run 启动threadloop: 其中一个重要的函数: waitForEvent,
( 3 ) . HWcomposer初始化:
HWComposer::HWComposer( const sp<SurfaceFlinger>& flinger, EventHandler& handler) : mFlinger(flinger),mFbDev(0), mHwc(0), mNumDisplays(1), mCBContext(new cb_context), mEventHandler(handler), mDebugForceFakeVSync(false){ ... ... // Note: some devices may insist that the FB HAL be opened before HWC. int fberr = loadFbHalModule(); // 加载准备framebuffer hal模块, 最终加载gralloc.XX.so动态库 loadHwcModule(); // 加载准备硬件加速模块 最终会加载各平台对应的hwcomposer.XX.so动态库 ... ... if (needVSyncThread) { // we don't have VSYNC support, we need to fake it mVSyncThread = new VSyncThread(*this); // Vsync周期控制 }}
HWcomposer 的初始化其中两个很重要的工作就是加载FB HAL与 Hwc 模块, 它们为数据在硬件合成方面做准备工作
( 4 ) . 根据EGL display与 像素格式创建RenderEngine, 并获取当前EGLContext
接下来看初始化的第二部分:
// initialize our non-virtual displays for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i); // set-up the displays that are already connected if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) { // All non-virtual displays are currently considered secure. bool isSecure = true; createBuiltinDisplayLocked(type); wp<IBinder> token = mBuiltinDisplays[i]; sp<IGraphicBufferProducer> producer; sp<IGraphicBufferConsumer> consumer; BufferQueue::createBufferQueue(&producer, &consumer, new GraphicBufferAlloc()); sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, consumer); int32_t hwcId = allocateHwcDisplayId(type); sp<DisplayDevice> hw = new DisplayDevice(this, type, hwcId, mHwc->getFormat(hwcId), isSecure, token, fbs, producer, mRenderEngine->getEGLConfig()); if (i > DisplayDevice::DISPLAY_PRIMARY) { // FIXME: currently we don't get blank/unblank requests // for displays other than the main display, so we always // assume a connected display is unblanked. ALOGD("marking display %zu as acquired/unblanked", i); hw->setPowerMode(HWC_POWER_MODE_NORMAL); } // When a non-virtual display device is added at boot time, // update the active config by querying HWC otherwise the // default config (config 0) will be used. int activeConfig = mHwc->getActiveConfig(hwcId); if (activeConfig >= 0) { hw->setActiveConfig(activeConfig); } mDisplays.add(token, hw); } }
( 1 ) . 初始化BufferQueue, 这个Queue是生产者IGraphicBufferProducer 与 消费者IGraphicBufferConsumer 的关键桥梁,
( 2 ) . 创建一个FramebufferSurface
( 3 ) . 初始化各个DisplayDevice, 每个显示设备都会封装为一个DisplayDevice, 如HDMI等
DisplayDevice::DisplayDevice( const sp<SurfaceFlinger>& flinger, DisplayType type, int32_t hwcId, int format, bool isSecure, const wp<IBinder>& displayToken, const sp<DisplaySurface>& displaySurface, const sp<IGraphicBufferProducer>& producer, EGLConfig config) : lastCompositionHadVisibleLayers(false), mFlinger(flinger), mType(type), mHwcDisplayId(hwcId), mDisplayToken(displayToken), mDisplaySurface(displaySurface), mDisplay(EGL_NO_DISPLAY), mSurface(EGL_NO_SURFACE), mDisplayWidth(), mDisplayHeight(), mFormat(), mFlags(), mPageFlipCount(), mIsSecure(isSecure), mSecureLayerVisible(false), mLayerStack(NO_LAYER_STACK), mOrientation(), mPowerMode(HWC_POWER_MODE_OFF), mActiveConfig(0){ Surface* surface; mNativeWindow = surface = new Surface(producer, false); // 创建一个surface ANativeWindow* const window = mNativeWindow.get(); // 获取一个本地窗口 char property[PROPERTY_VALUE_MAX]; /* * Create our display's surface */ EGLSurface eglSurface; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (config == EGL_NO_CONFIG) { config = RenderEngine::chooseEglConfig(display, format); } eglSurface = eglCreateWindowSurface(display, config, window, NULL); eglQuerySurface(display, eglSurface, EGL_WIDTH, &mDisplayWidth); eglQuerySurface(display, eglSurface, EGL_HEIGHT, &mDisplayHeight); // Make sure that composition can never be stalled by a virtual display // consumer that isn't processing buffers fast enough. We have to do this // in two places: // * Here, in case the display is composed entirely by HWC. // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the // window's swap interval in eglMakeCurrent, so they'll override the // interval we set here. if (mType >= DisplayDevice::DISPLAY_VIRTUAL) window->setSwapInterval(window, 0); mConfig = config; mDisplay = display; mSurface = eglSurface; mFormat = format; mPageFlipCount = 0; mViewport.makeInvalid(); mFrame.makeInvalid(); // virtual displays are always considered enabled mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ? HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF; // Name the display. The name will be replaced shortly if the display // was created with createDisplay(). switch (mType) { case DISPLAY_PRIMARY: mDisplayName = "Built-in Screen"; break; case DISPLAY_EXTERNAL: mDisplayName = "HDMI Screen"; break; default: mDisplayName = "Virtual Screen"; // e.g. Overlay #n break; } mPanelInverseMounted = false; // Check if panel is inverse mounted (contents show up HV flipped) property_get("persist.panel.inversemounted", property, "0"); mPanelInverseMounted = !!atoi(property); // initialize the display orientation transform. setProjection(DisplayState::eOrientationDefault, mViewport, mFrame); #ifdef NUM_FRAMEBUFFER_SURFACE_BUFFERS surface->allocateBuffers();#endif}
初始化第三部分:
// make the GLContext current so that we can create textures when creating Layers // (which may happens before we render something) getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); mEventControlThread = new EventControlThread(this); mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY); // set a fake vsync period if there is no HWComposer if (mHwc->initCheck() != NO_ERROR) { mPrimaryDispSync.setPeriod(16666667); } // initialize our drawing state mDrawingState = mCurrentState; // set initial conditions (e.g. unblank default device) initializeDisplays(); // 设置初始的layer数据 // start boot animation startBootAnim(); // 开机动画设置
在SurfaceFlinger init完成之后, 会执行它的run函数, 使之进入死循环,去等待vsync信号: waitForEvent()
总结:
至此SurfaceFlinger的初始话工作完成, 但这才是开始, android的surface系统值得我们去深究, 去探索.
- SurfaceFlinger 分析 一
- SurfaceFlinger启动过程分析(一)
- SurfaceFlinger启动过程分析(一)
- SurfaceFlinger启动过程分析(一)
- Android -- SurfaceFlinger 概要分析系列 (一)
- SurfaceFlinger启动过程分析(一)
- Android -- SurfaceFlinger 概要分析系列 (一)
- surfaceflinger启动过程分析
- Surfaceflinger process流程分析
- surfaceflinger 工作流程分析
- SurfaceFlinger启动过程分析
- SurfaceFlinger启动过程分析
- SurfaceFlinger启动过程分析
- Surfaceflinger process流程分析
- SurfaceFlinger启动过程分析
- Android -- SurfaceFlinger 分析
- SurfaceFlinger旋转流程分析
- Android SurfaceFlinger分析
- poj 3278 水bfs
- MYSQL索引优化
- #pragma once与 #ifndef的区别
- OpenSSLX509证书操作函数
- 蓝桥杯 高斯日记
- SurfaceFlinger 分析 一
- Classifying MNIST digits using Logistic Regression
- WebView使用基础
- collectionview cell 拖动
- XML CDATA
- Android 仿QQ好友分组列表、ExpandableListView的使用详解
- [LeetCode][1]Two Sum解析 -Java实现
- HTTP及XMLHTTP状态代码一览
- C++:文件流读写