Android下SF合成流程重学习之GPU合成

打印 上一主题 下一主题

主题 551|帖子 551|积分 1653

    Android下SF合成流程重学习之GPU合成



弁言

SurfaceFlinger中的图层选择GPU合成(CLIENT合成方式)时,会把待合成的图层Layers通过renderengine(SkiaGLRenderEngine)绘制到一块GraphicBuffer中,然后把这块GraphicBuffer图形缓存通过调用setClientTarget传递给HWC模块,HWC进一步处置惩罚后把这个GraphicBuffer中的图像呈现到屏幕上。
本篇文章,我们先聚焦如下量点做介绍:


  • 用于存储GPU合成后的图形数据的GraphicBuffer是从那里来的
  • GPU合成中,SF实行的主要逻辑是什么





一.从dumpsys SurfaceFlinger中的信息谈起

如果你检察过dumpsys SurfaceFlinger的信息,也许你注意过一些GraphicBufferAllocator/GraphicBufferMapper打印出的一些信息,这些信息记载了所有通过Gralloc模块allocate和import的图形缓存的信息。
如下是在我的平台下截取的dumpsys SurfaceFlinger部门信息:
  1. GraphicBufferAllocator buffers:
  2.     Handle |        Size |     W (Stride) x H | Layers |   Format |      Usage | Requestor
  3. 0xf3042b90 | 8100.00 KiB | 1920 (1920) x 1080 |      1 |        1 | 0x    1b00 | FramebufferSurface
  4. 0xf3042f30 | 8100.00 KiB | 1920 (1920) x 1080 |      1 |        1 | 0x    1b00 | FramebufferSurface
  5. 0xf3046020 | 8100.00 KiB | 1920 (1920) x 1080 |      1 |        1 | 0x    1b00 | FramebufferSurface
  6. Total allocated by GraphicBufferAllocator (estimate): 24300.00 KB
  7. Imported gralloc buffers:
  8. + name:FramebufferSurface, id:e100000000, size:8.3e+03KiB, w/h:780x438, usage: 0x40001b00, req fmt:5, fourcc/mod:875713089/576460752303423505, dataspace: 0x0, compressed: true
  9.         planes: B/G/R/A:         w/h:780x440, stride:1e00 bytes, size:818000
  10. + name:FramebufferSurface, id:e100000001, size:8.3e+03KiB, w/h:780x438, usage: 0x40001b00, req fmt:5, fourcc/mod:875713089/576460752303423505, dataspace: 0x0, compressed: true
  11.         planes: B/G/R/A:         w/h:780x440, stride:1e00 bytes, size:818000
  12. + name:FramebufferSurface, id:e100000002, size:8.3e+03KiB, w/h:780x438, usage: 0x40001b00, req fmt:5, fourcc/mod:875713089/576460752303423505, dataspace: 0x0, compressed: true
  13.         planes: B/G/R/A:         w/h:780x440, stride:1e00 bytes, size:818000
  14. Total imported by gralloc: 5e+04KiB
复制代码
上面的信息中可以看到一些儿冥冥之中貌似、好像、好像很有意思的字眼:FramebufferSurface。
作为Requestor的FramebufferSurface去请求分配了三块图形缓存,还规定了width、height、format、usage等信息。
如上你看到的这3块GraphicBuffer,就是用来存储CPU合成后的图形数据的



二.SF为GPU合成做的准备

俗话说的好,不打没有准备的仗。SF也是云云,为了做好GPU的合成,SF会在启动的时候就搭建好EGL环境,为后续GPU合成做好准备。详细逻辑如下:
  1. 文件:frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
  2. void SurfaceFlinger::init() {
  3.     ALOGI(  "SurfaceFlinger's main thread ready to run. "
  4.             "Initializing graphics H/W...");
  5.     Mutex::Autolock _l(mStateLock);
  6.     // Get a RenderEngine for the given display / config (can't fail)
  7.     // TODO(b/77156734): We need to stop casting and use HAL types when possible.
  8.     // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
  9.     // 创建RenderEngine对象
  10.     mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(
  11.             renderengine::RenderEngineCreationArgs::Builder()
  12.                 .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
  13.                 .setImageCacheSize(maxFrameBufferAcquiredBuffers)
  14.                 .setUseColorManagerment(useColorManagement)
  15.                 .setEnableProtectedContext(enable_protected_contents(false))
  16.                 .setPrecacheToneMapperShaderOnly(false)
  17.                 .setSupportsBackgroundBlur(mSupportsBlur)
  18.                 .setContextPriority(useContextPriority
  19.                         ? renderengine::RenderEngine::ContextPriority::HIGH
  20.                         : renderengine::RenderEngine::ContextPriority::MEDIUM)
  21.                 .build()));
  22. 文件:frameworks/native/libs/renderengine/RenderEngine.cpp
  23. std::unique_ptr<impl::RenderEngine> RenderEngine::create(const RenderEngineCreationArgs& args) {
  24.     char prop[PROPERTY_VALUE_MAX];
  25.      // 如果PROPERTY_DEBUG_RENDERENGINE_BACKEND 属性不设,则默认是gles类型
  26.     property_get(PROPERTY_DEBUG_RENDERENGINE_BACKEND, prop, "gles");
  27.     if (strcmp(prop, "gles") == 0) {
  28.         ALOGD("RenderEngine GLES Backend");
  29.         // 创建GLESRenderEngine对象
  30.         return renderengine::gl::GLESRenderEngine::create(args);
  31.     }
  32.     ALOGE("UNKNOWN BackendType: %s, create GLES RenderEngine.", prop);
  33.     return renderengine::gl::GLESRenderEngine::create(args);
  34. }
  35. 文件:frameworks/native/libs/renderengine/gl/GLESRenderEngine.cpp
  36. std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCreationArgs& args) {
  37.     // initialize EGL for the default display
  38.     // 获得EGLDisplay
  39.     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  40.     if (!eglInitialize(display, nullptr, nullptr)) {
  41.         LOG_ALWAYS_FATAL("failed to initialize EGL");
  42.     }
  43.      // 查询EGL版本信息
  44.     const auto eglVersion = eglQueryStringImplementationANDROID(display, EGL_VERSION);
  45.     if (!eglVersion) {
  46.         checkGlError(__FUNCTION__, __LINE__);
  47.         LOG_ALWAYS_FATAL("eglQueryStringImplementationANDROID(EGL_VERSION) failed");
  48.     }
  49.     //查询EGL支持哪些拓展
  50.     const auto eglExtensions = eglQueryStringImplementationANDROID(display, EGL_EXTENSIONS);
  51.     if (!eglExtensions) {
  52.         checkGlError(__FUNCTION__, __LINE__);
  53.         LOG_ALWAYS_FATAL("eglQueryStringImplementationANDROID(EGL_EXTENSIONS) failed");
  54.     }
  55.     //根据支持的拓展设置属性,目前来看所有的属性都为true
  56.     GLExtensions& extensions = GLExtensions::getInstance();
  57.     extensions.initWithEGLStrings(eglVersion, eglExtensions);
  58.     // The code assumes that ES2 or later is available if this extension is
  59.     // supported.
  60.     EGLConfig config = EGL_NO_CONFIG;
  61.     if (!extensions.hasNoConfigContext()) {
  62.         config = chooseEglConfig(display, args.pixelFormat, /*logConfig*/ true);
  63.     }
  64.     bool useContextPriority =
  65.             extensions.hasContextPriority() && args.contextPriority == ContextPriority::HIGH;
  66.     EGLContext protectedContext = EGL_NO_CONTEXT;
  67.     if (args.enableProtectedContext && extensions.hasProtectedContent()) {
  68.         protectedContext = createEglContext(display, config, nullptr, useContextPriority,
  69.                                             Protection::PROTECTED);
  70.         ALOGE_IF(protectedContext == EGL_NO_CONTEXT, "Can't create protected context");
  71.     }
  72.     // 创建非protect的EglContext
  73.     EGLContext ctxt = createEglContext(display, config, protectedContext, useContextPriority,
  74.                                        Protection::UNPROTECTED);
  75.     LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed");
  76.     EGLSurface dummy = EGL_NO_SURFACE;
  77.      // 支持该属性,不走if逻辑
  78.     if (!extensions.hasSurfacelessContext()) {
  79.         dummy = createDummyEglPbufferSurface(display, config, args.pixelFormat,
  80.                                              Protection::UNPROTECTED);
  81.         LOG_ALWAYS_FATAL_IF(dummy == EGL_NO_SURFACE, "can't create dummy pbuffer");
  82.     }
  83.     // eglMakeCurrent 将 EGLDisplay和EglContext 绑定
  84.     EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt);
  85.     LOG_ALWAYS_FATAL_IF(!success, "can't make dummy pbuffer current");
  86.     ...
  87.     std::unique_ptr<GLESRenderEngine> engine;
  88.     switch (version) {
  89.         case GLES_VERSION_1_0:
  90.         case GLES_VERSION_1_1:
  91.             LOG_ALWAYS_FATAL("SurfaceFlinger requires OpenGL ES 2.0 minimum to run.");
  92.             break;
  93.         case GLES_VERSION_2_0:
  94.         case GLES_VERSION_3_0:
  95.             // GLESRenderEngine 初始化
  96.             engine = std::make_unique<GLESRenderEngine>(args, display, config, ctxt, dummy,
  97.                                                         protectedContext, protectedDummy);
  98.             break;
  99.     }
  100. ...
  101. }
  102. GLESRenderEngine::GLESRenderEngine(const RenderEngineCreationArgs& args, EGLDisplay display,
  103.                                    EGLConfig config, EGLContext ctxt, EGLSurface dummy,
  104.                                    EGLContext protectedContext, EGLSurface protectedDummy)
  105.       : renderengine::impl::RenderEngine(args),
  106.         mEGLDisplay(display),
  107.         mEGLConfig(config),
  108.         mEGLContext(ctxt),
  109.         mDummySurface(dummy),
  110.         mProtectedEGLContext(protectedContext),
  111.         mProtectedDummySurface(protectedDummy),
  112.         mVpWidth(0),
  113.         mVpHeight(0),
  114.         mFramebufferImageCacheSize(args.imageCacheSize),
  115.         mUseColorManagement(args.useColorManagement) {
  116.     // 查询可支持最大的纹理尺寸和视图大小
  117.     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
  118.     glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
  119.     //像素数据按4字节对齐
  120.     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
  121.     glPixelStorei(GL_PACK_ALIGNMENT, 4);
  122.     ...
  123.       // 色彩空间相关设置,遇到具体场景再分析
  124.      if (mUseColorManagement) {
  125.         const ColorSpace srgb(ColorSpace::sRGB());
  126.         const ColorSpace displayP3(ColorSpace::DisplayP3());
  127.         const ColorSpace bt2020(ColorSpace::BT2020());
  128.         // no chromatic adaptation needed since all color spaces use D65 for their white points.
  129.         mSrgbToXyz = mat4(srgb.getRGBtoXYZ());
  130.         mDisplayP3ToXyz = mat4(displayP3.getRGBtoXYZ());
  131.         mBt2020ToXyz = mat4(bt2020.getRGBtoXYZ());
  132.         mXyzToSrgb = mat4(srgb.getXYZtoRGB());
  133.         mXyzToDisplayP3 = mat4(displayP3.getXYZtoRGB());
  134.         mXyzToBt2020 = mat4(bt2020.getXYZtoRGB());
  135.         // Compute sRGB to Display P3 and BT2020 transform matrix.
  136.         // NOTE: For now, we are limiting output wide color space support to
  137.         // Display-P3 and BT2020 only.
  138.         mSrgbToDisplayP3 = mXyzToDisplayP3 * mSrgbToXyz;
  139.         mSrgbToBt2020 = mXyzToBt2020 * mSrgbToXyz;
  140.         // Compute Display P3 to sRGB and BT2020 transform matrix.
  141.         mDisplayP3ToSrgb = mXyzToSrgb * mDisplayP3ToXyz;
  142.         mDisplayP3ToBt2020 = mXyzToBt2020 * mDisplayP3ToXyz;
  143.         // Compute BT2020 to sRGB and Display P3 transform matrix
  144.         mBt2020ToSrgb = mXyzToSrgb * mBt2020ToXyz;
  145.         mBt2020ToDisplayP3 = mXyzToDisplayP3 * mBt2020ToXyz;
  146.     }
  147.     ...
  148.      // 涉及到有模糊的layer,具体场景再分析
  149.     if (args.supportsBackgroundBlur) {
  150.         mBlurFilter = new BlurFilter(*this);
  151.         checkErrors("BlurFilter creation");
  152.     }
  153.     // 创建ImageManager 线程,这个线程是管理输入的mEGLImage
  154.     mImageManager = std::make_unique<ImageManager>(this);
  155.     mImageManager->initThread();
  156.     //创建GLFramebuffer
  157.     mDrawingBuffer = createFramebuffer();
  158.     ...
  159. }
  160.    
  161. 文件:frameworks/native/libs/renderengine/gl/GLFramebuffer.cpp
  162. // 创建了一个纹理ID mTextureName,和 fb ID mFramebufferName
  163. GLFramebuffer::GLFramebuffer(GLESRenderEngine& engine)
  164.       : mEngine(engine), mEGLDisplay(engine.getEGLDisplay()), mEGLImage(EGL_NO_IMAGE_KHR) {
  165.     glGenTextures(1, &mTextureName);
  166.     glGenFramebuffers(1, &mFramebufferName);
  167. }
复制代码
通过上述的代码我们可以看到在启动之初就搭建好了EGL环境,并将当火线程与context绑定,为背面利用gl下令做好准备,然后创建了ImageManager 线程,这个线程是管理输入Buffer的EGLImage,然后创建了GLFrameBuffer,用来操作输出的buffer。
并且有一点我们必要特别注意,在在创建BufferQueueLayer时就已经对各个layer创建了纹理ID,为背面走GPU合成做准备。如下:
  1. 文件:frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
  2. status_t SurfaceFlinger::createBufferQueueLayer(const sp<Client>& client, std::string name,
  3.                                                 uint32_t w, uint32_t h, uint32_t flags,
  4.                                                 LayerMetadata metadata, PixelFormat& format,
  5.                                                 sp<IBinder>* handle,
  6.                                                 sp<IGraphicBufferProducer>* gbp,
  7.                                                 sp<Layer>* outLayer) {
  8.     ...
  9.    
  10.     args.textureName = getNewTexture();
  11.     ...
  12. }
  13. uint32_t SurfaceFlinger::getNewTexture() {
  14.     {
  15.         std::lock_guard lock(mTexturePoolMutex);
  16.         if (!mTexturePool.empty()) {
  17.             uint32_t name = mTexturePool.back();
  18.             mTexturePool.pop_back();
  19.             ATRACE_INT("TexturePoolSize", mTexturePool.size());
  20.             return name;
  21.         }
  22.         // The pool was too small, so increase it for the future
  23.         ++mTexturePoolSize;
  24.     }
  25.     // The pool was empty, so we need to get a new texture name directly using a
  26.     // blocking call to the main thread
  27.     // 每个layer,调用glGenTextures 生成纹理ID,schedule运行在sf主线程
  28.     return schedule([this] {
  29.                uint32_t name = 0;
  30.                getRenderEngine().genTextures(1, &name);
  31.                return name;
  32.            })
  33.             .get();
  34. }
复制代码



三.创建与初始化FramebufferSurface的流程

FramebufferSurface的初始化逻辑必要从SurfaceFlinger的初始化谈起,我们知道在SurfaceFlinger::init()中会去注册HWC的回调函数mCompositionEngine->getHwComposer().setCallback(this),当第一次注册callback时,onComposerHalHotplug()会立即在调用registerCallback()的线程中被调用,并跨进程回调到SurfaceFlinger:nComposerHalHotplug。然后一腾飞奔:

SurfaceFlinger::processDisplayAdded这个方法中去创建了BufferQueue和FramebufferSurface,简单理解为连接上了表现屏幕(Display),那就要给准备一个BufferQueue,以便GPU合成UI等图层时,可以向这个BufferQueue索要GraphicBuffer来存储合成后的图形数据,再呈现到屏幕上去(我的傻瓜式理解)
摘取关键代码如下:
  1. [/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp]
  2. void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
  3.                                          const DisplayDeviceState& state) {
  4.     ......
  5.     sp<compositionengine::DisplaySurface> displaySurface;
  6.     sp<IGraphicBufferProducer> producer;
  7.     // 创建BufferQueue,获取到生产者和消费者,而且消费者不是SurfaceFlinger哦
  8.     sp<IGraphicBufferProducer> bqProducer;
  9.     sp<IGraphicBufferConsumer> bqConsumer;
  10.     getFactory().createBufferQueue(&bqProducer, &bqConsumer, /*consumerIsSurfaceFlinger =*/false);
  11.     if (state.isVirtual()) { // 虚拟屏幕,不管它
  12.         const auto displayId = VirtualDisplayId::tryCast(compositionDisplay->getId());
  13.         LOG_FATAL_IF(!displayId);
  14.         auto surface = sp<VirtualDisplaySurface>::make(getHwComposer(), *displayId, state.surface,
  15.                                                        bqProducer, bqConsumer, state.displayName);
  16.         displaySurface = surface;
  17.         producer = std::move(surface);
  18.     } else { // 看这个case
  19.         ALOGE_IF(state.surface != nullptr,
  20.                  "adding a supported display, but rendering "
  21.                  "surface is provided (%p), ignoring it",
  22.                  state.surface.get());
  23.         const auto displayId = PhysicalDisplayId::tryCast(compositionDisplay->getId());
  24.         LOG_FATAL_IF(!displayId);
  25.         // 创建了FramebufferSurface对象,FramebufferSurface继承自compositionengine::DisplaySurface
  26.         // FramebufferSurface是作为消费者的角色工作的,消费SF GPU合成后的图形数据
  27.         displaySurface =
  28.                 sp<FramebufferSurface>::make(getHwComposer(), *displayId, bqConsumer,
  29.                                              state.physical->activeMode->getSize(),
  30.                                              ui::Size(maxGraphicsWidth, maxGraphicsHeight));
  31.         producer = bqProducer;
  32.     }
  33.     LOG_FATAL_IF(!displaySurface);
  34.     // 创建DisplayDevice,其又去创建RenderSurface,作为生产者角色工作,displaySurface就是FramebufferSurface对象
  35.     const auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay),
  36.                                                        state, displaySurface, producer);
  37.     mDisplays.emplace(displayToken, display);
  38.     ......
  39. }
复制代码
瞅一瞅 FramebufferSuraface的构造函数,没啥复杂的,就是一些设置,初始化一些成员。
  1. FramebufferSurface::FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displayId,
  2.                                        const sp<IGraphicBufferConsumer>& consumer,
  3.                                        const ui::Size& size, const ui::Size& maxSize)
  4.       : ConsumerBase(consumer),
  5.         mDisplayId(displayId),
  6.         mMaxSize(maxSize),
  7.         mCurrentBufferSlot(-1),
  8.         mCurrentBuffer(),
  9.         mCurrentFence(Fence::NO_FENCE),
  10.         mHwc(hwc),
  11.         mHasPendingRelease(false),
  12.         mPreviousBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
  13.         mPreviousBuffer() {
  14.     ALOGV("Creating for display %s", to_string(displayId).c_str());
  15.     mName = "FramebufferSurface";
  16.     mConsumer->setConsumerName(mName); // 设置消费者的名字是 "FramebufferSurface"
  17.     mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |  // 设置usage
  18.                                        GRALLOC_USAGE_HW_RENDER |
  19.                                        GRALLOC_USAGE_HW_COMPOSER);
  20.     const auto limitedSize = limitSize(size);
  21.     mConsumer->setDefaultBufferSize(limitedSize.width, limitedSize.height); // 设置buffer 大小
  22.     mConsumer->setMaxAcquiredBufferCount(
  23.             SurfaceFlinger::maxFrameBufferAcquiredBuffers - 1);
  24. }
复制代码
再进到SurfaceFlinger::setupNewDisplayDeviceInternal中看看相关的逻辑:
  1. [/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp]
  2. sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
  3.         const wp<IBinder>& displayToken,
  4.         std::shared_ptr<compositionengine::Display> compositionDisplay,
  5.         const DisplayDeviceState& state,
  6.         const sp<compositionengine::DisplaySurface>& displaySurface,
  7.         const sp<IGraphicBufferProducer>& producer) {
  8.     ......
  9.     creationArgs.displaySurface = displaySurface;  // displaySurface就是FramebufferSurface对象   
  10.     // producer是前面processDisplayAdded中创建的
  11.     auto nativeWindowSurface = getFactory().createNativeWindowSurface(producer);
  12.     auto nativeWindow = nativeWindowSurface->getNativeWindow();
  13.     creationArgs.nativeWindow = nativeWindow;
  14.     ....
  15.     // 前面一大坨代码是在初始话creationArgs,这些参数用来创建DisplayDevice
  16.     // creationArgs.nativeWindow会把前面创建的producer关联到了DisplayDevice
  17.     sp<DisplayDevice> display = getFactory().createDisplayDevice(creationArgs);
  18.     // 后面一大坨,对display进行了些设置
  19.     if (!state.isVirtual()) {
  20.         display->setActiveMode(state.physical->activeMode->getId());
  21.         display->setDeviceProductInfo(state.physical->deviceProductInfo);
  22.     }
  23.     ....
  24. }
复制代码
接下来就是 DisplayDevice 的构造函数了,里面主要是创建了RenderSurface对象,然后对其举行初始化
  1. [/frameworks/native/services/surfaceflinger/DisplayDevice.cpp]
  2. DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args)
  3.       : mFlinger(args.flinger),
  4.         mHwComposer(args.hwComposer),
  5.         mDisplayToken(args.displayToken),
  6.         mSequenceId(args.sequenceId),
  7.         mConnectionType(args.connectionType),
  8.         mCompositionDisplay{args.compositionDisplay},
  9.         mPhysicalOrientation(args.physicalOrientation),
  10.         mSupportedModes(std::move(args.supportedModes)),
  11.         mIsPrimary(args.isPrimary) {
  12.     mCompositionDisplay->editState().isSecure = args.isSecure;
  13.     // 创建RenderSurface,args.nativeWindow 即为producer,指向生产者
  14.     mCompositionDisplay->createRenderSurface(
  15.             compositionengine::RenderSurfaceCreationArgsBuilder()
  16.                     .setDisplayWidth(ANativeWindow_getWidth(args.nativeWindow.get()))
  17.                     .setDisplayHeight(ANativeWindow_getHeight(args.nativeWindow.get()))
  18.                     .setNativeWindow(std::move(args.nativeWindow))
  19.                     .setDisplaySurface(std::move(args.displaySurface)) // displaySurface就是FramebufferSurface对象
  20.                     .setMaxTextureCacheSize(
  21.                             static_cast<size_t>(SurfaceFlinger::maxFrameBufferAcquiredBuffers))
  22.                     .build());
  23.     if (!mFlinger->mDisableClientCompositionCache &&
  24.         SurfaceFlinger::maxFrameBufferAcquiredBuffers > 0) {
  25.         mCompositionDisplay->createClientCompositionCache(
  26.                 static_cast<uint32_t>(SurfaceFlinger::maxFrameBufferAcquiredBuffers));
  27.     }
  28.     mCompositionDisplay->createDisplayColorProfile(
  29.             compositionengine::DisplayColorProfileCreationArgs{args.hasWideColorGamut,
  30.                                                                std::move(args.hdrCapabilities),
  31.                                                                args.supportedPerFrameMetadata,
  32.                                                                args.hwcColorModes});
  33.     if (!mCompositionDisplay->isValid()) {
  34.         ALOGE("Composition Display did not validate!");
  35.     }
  36.     // 初始化RenderSurface
  37.     mCompositionDisplay->getRenderSurface()->initialize();
  38.     setPowerMode(args.initialPowerMode);
  39.     // initialize the display orientation transform.
  40.     setProjection(ui::ROTATION_0, Rect::INVALID_RECT, Rect::INVALID_RECT);
  41. }
复制代码
RenderSurface作为生产者的角色工作,构造函数如下,留意启成员displaySurface就是SurfaceFlinger中创建的FramebufferSurface对象
也就是 作为生产者的RenderSurface中持有 消耗者的引用 displaySurface,可以呼叫FramebufferSurface的方法。
  1. [ /frameworks/native/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp]
  2. RenderSurface::RenderSurface(const CompositionEngine& compositionEngine, Display& display,
  3.                              const RenderSurfaceCreationArgs& args)
  4.       : mCompositionEngine(compositionEngine),
  5.         mDisplay(display),
  6.         mNativeWindow(args.nativeWindow),
  7.         mDisplaySurface(args.displaySurface),  // displaySurface就是FramebufferSurface对象
  8.         mSize(args.displayWidth, args.displayHeight),
  9.         mMaxTextureCacheSize(args.maxTextureCacheSize) {
  10.     LOG_ALWAYS_FATAL_IF(!mNativeWindow);
  11. }
复制代码
我们看看他的RenderSurface::initialize()方法
  1. [/frameworks/native/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp]
  2. void RenderSurface::initialize() {
  3.     ANativeWindow* const window = mNativeWindow.get();
  4.     int status = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
  5.     ALOGE_IF(status != NO_ERROR, "Unable to connect BQ producer: %d", status);
  6.     status = native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
  7.     ALOGE_IF(status != NO_ERROR, "Unable to set BQ format to RGBA888: %d", status);
  8.     status = native_window_set_usage(window, DEFAULT_USAGE);
  9.     ALOGE_IF(status != NO_ERROR, "Unable to set BQ usage bits for GPU rendering: %d", status);
  10. }
复制代码
上述方法也很简单,就是作为producer去和BufferQueue创建connect,并设置format为RGBA_8888,设置usage为GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE
为了验证上述分析的流程是精确的,我在BufferQueueProducer::connect中加log来打印调用栈的信息,如下,是不是和分析的一样啊
  1. 11-13 00:52:58.497   227   227 D BufferQueueProducer: connect[1303] /vendor/bin/hw/android.hardware.graphics.composer@2.4-service start
  2. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#00 pc 0005e77f  /system/lib/libgui.so (android::BufferQueueProducer::connect(android::sp<android::IProducerListener> const&, int, bool, android::IGraphicBufferProducer::QueueBufferOutput*)+1282)
  3. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#01 pc 000a276b  /system/lib/libgui.so (android::Surface::connect(int, android::sp<android::IProducerListener> const&, bool)+138)
  4. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#02 pc 0009de41  /system/lib/libgui.so (android::Surface::hook_perform(ANativeWindow*, int, ...)+128)
  5. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#03 pc 00121b1d  /system/bin/surfaceflinger (android::compositionengine::impl::RenderSurface::initialize()+12)
  6. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#04 pc 00083cc5  /system/bin/surfaceflinger (android::DisplayDevice::DisplayDevice(android::DisplayDeviceCreationArgs&)+1168)
  7. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#05 pc 000d8bed  /system/bin/surfaceflinger (android::SurfaceFlinger::processDisplayAdded(android::wp<android::IBinder> const&, android::DisplayDeviceState const&)+4440)
  8. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#06 pc 000d0db5  /system/bin/surfaceflinger (android::SurfaceFlinger::processDisplayChangesLocked()+2436)
  9. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#07 pc 000cef6b  /system/bin/surfaceflinger (android::SurfaceFlinger::processDisplayHotplugEventsLocked()+6422)
  10. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#08 pc 000d2c7f  /system/bin/surfaceflinger (android::SurfaceFlinger::onComposerHalHotplug(unsigned long long, android::hardware::graphics::composer::V2_1::IComposerCallback::Connection)+334)
  11. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#09 pc 0009afab  /system/bin/surfaceflinger (_ZN7android12_GLOBAL__N_122ComposerCallbackBridge9onHotplugEyNS_8hardware8graphics8composer4V2_117IComposerCallback10ConnectionE$d689f7ac1c60e4abeed02ca92a51bdcd+20)
  12. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#10 pc 0001bb97  /system/lib/android.hardware.graphics.composer@2.1.so (android::hardware::graphics::composer::V2_1::BnHwComposerCallback::_hidl_onHotplug(android::hidl::base::V1_0::BnHwBase*, android::hardware::Parcel const&, android::hardware::Parcel*, std::__1::function<void (android::hardware::Parcel&)>)+166)
  13. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#11 pc 000275e9  /system/lib/android.hardware.graphics.composer@2.4.so (android::hardware::graphics::composer::V2_4::BnHwComposerCallback::onTransact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+228)
  14. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#12 pc 00054779  /system/lib/libhidlbase.so (android::hardware::BHwBinder::transact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+96)
  15. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#13 pc 0004fc67  /system/lib/libhidlbase.so (android::hardware::IPCThreadState::transact(int, unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int)+2174)
  16. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#14 pc 0004f2e5  /system/lib/libhidlbase.so (android::hardware::BpHwBinder::transact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+36)
  17. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#15 pc 0002bdf1  /system/lib/android.hardware.graphics.composer@2.4.so (android::hardware::graphics::composer::V2_4::BpHwComposerClient::_hidl_registerCallback_2_4(android::hardware::IInterface*, android::hardware::details::HidlInstrumentor*, android::sp<android::hardware::graphics::composer::V2_4::IComposerCallback> const&)+296)
  18. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#16 pc 0002ed8d  /system/lib/android.hardware.graphics.composer@2.4.so (android::hardware::graphics::composer::V2_4::BpHwComposerClient::registerCallback_2_4(android::sp<android::hardware::graphics::composer::V2_4::IComposerCallback> const&)+34)
  19. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#17 pc 00085627  /system/bin/surfaceflinger (android::Hwc2::impl::Composer::registerCallback(android::sp<android::hardware::graphics::composer::V2_4::IComposerCallback> const&)+98)
  20. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#18 pc 00092d63  /system/bin/surfaceflinger (android::impl::HWComposer::setCallback(android::HWC2::ComposerCallback*)+2206)
  21. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#19 pc 000cd35b  /system/bin/surfaceflinger (android::SurfaceFlinger::init()+438)
  22. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#20 pc 000feb03  /system/bin/surfaceflinger (main+862)
  23. 11-13 00:52:58.581   227   227 E BufferQueueProducer: stackdump:#21 pc 0003253b  /apex/com.android.runtime/lib/bionic/libc.so (__libc_init+54)
  24. 11-13 00:52:58.582   227   227 D BufferQueueProducer: connect[1307] /vendor/bin/hw/android.hardware.graphics.composer@2.4-service end
复制代码
这里有一个小细节要留意下,由于SurfaceFlinger:nComposerHalHotplug是HWC回调过来的,以是代码实行是在android.hardware.graphics.composer@2.4-service这个进程中的。
BufferQueueProducer::connect中记载的mConnectedPid就是composer service的PID
  1. [ /frameworks/native/libs/gui/BufferQueueProducer.cpp]
  2. mCore->mConnectedPid = BufferQueueThreadState::getCallingPid();
复制代码
在dump BufferQueue的信息时,根据PID获取的 producer name 也就是 android.hardware.graphics.composer@2.4-service
  1. [/frameworks/native/libs/gui/BufferQueueCore.cpp]
  2. void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const {
  3.     ...
  4.     getProcessName(mConnectedPid, producerProcName);
  5.     getProcessName(pid, consumerProcName);
  6.     ....
  7. }
复制代码
如下是我的平台dumpsys SurfaceFlinger的信息打印出来的Composition RenderSurface State的信息,看看是不是和代码的设置都有对应起来:
  1. mConsumerName=FramebufferSurface
  2. producer=[342:/vendor/bin/hw/android.hardware.graphics.composer@2.4-service]
  3. consumer=[223:/system/bin/surfaceflinger])
复制代码
format/size/usage也都可以对应到代码的设置
  1.    Composition RenderSurface State:
  2.    size=[1920 1080] ANativeWindow=0xef2c3278 (format 1) flips=605
  3.   FramebufferSurface: dataspace: Default(0)
  4.    mAbandoned=0
  5.    - BufferQueue mMaxAcquiredBufferCount=2 mMaxDequeuedBufferCount=1
  6.      mDequeueBufferCannotBlock=0 mAsyncMode=0
  7.      mQueueBufferCanDrop=0 mLegacyBufferDrop=1
  8.      default-size=[1920x1080] default-format=1      transform-hint=00 frame-counter=580
  9.      mTransformHintInUse=00 mAutoPrerotation=0
  10.    FIFO(0):
  11.    (mConsumerName=FramebufferSurface, mConnectedApi=1, mConsumerUsageBits=6656, mId=df00000000, producer=[342:/vendor/bin/hw/android.hardware.graphics.composer@2.4-service], consumer=[223:/system/bin/surfaceflinger])
  12.    Slots:
  13.     >[01:0xeec82110] state=ACQUIRED 0xef4429c0 frame=2 [1920x1080:1920,  1]
  14.     >[02:0xeec806f0] state=ACQUIRED 0xef443100 frame=580 [1920x1080:1920,  1]
  15.      [00:0xeec81f00] state=FREE     0xef440580 frame=579 [1920x1080:1920,  1]
复制代码



四.关于RenderSurface和FramebufferSurface小结


上述内容中出现的一些字眼,不禁令人”瞎想连篇“
SurfaceFlinger创建了BufferQueue ==> Producer & Consumer
创建了RenderSurface作为生产者,它持有Producer
创建了FramebufferSurface作为消耗者,它持有Consumer
前面分析BufferQueue的工作原理时,有讲过:
生产者不停的dequeueBuffer & queueBuffer ; 而消耗者不停的acquireBuffer & releaseBuffer ,这样图像缓存就在 生产者 – BufferQueue – 消耗者 间流转起来了。
看看作为生产者的RenderSurface中方法:
  1. [/frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h]
  2. /**
  3. * Encapsulates everything for composing to a render surface with RenderEngine
  4. */
  5. class RenderSurface {
  6.     ....
  7.     // Allocates a buffer as scratch space for GPU composition
  8.     virtual std::shared_ptr<renderengine::ExternalTexture> dequeueBuffer(
  9.             base::unique_fd* bufferFence) = 0;
  10.     // Queues the drawn buffer for consumption by HWC. readyFence is the fence
  11.     // which will fire when the buffer is ready for consumption.
  12.     virtual void queueBuffer(base::unique_fd readyFence) = 0;
  13.     ...
  14. };
复制代码
熟悉的味道:
dequeueBuffer : 分配一个缓冲区作为GPU合成的暂存空间
queueBuffer : 入队列已绘制好的图形缓存供HWC利用
同样如果去检察作为消耗者的FramebufferSurface也会看到acquireBuffer & releaseBuffer的调用,如下:
  1. [/frameworks/native/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp]
  2. status_t FramebufferSurface::nextBuffer(uint32_t& outSlot,
  3.         sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence,
  4.         Dataspace& outDataspace) {
  5.     Mutex::Autolock lock(mMutex);
  6.     BufferItem item;
  7.     status_t err = acquireBufferLocked(&item, 0); // 获取待显示的buffer
  8.     ...
  9.     status_t result = mHwc.setClientTarget(mDisplayId, outSlot, outFence, outBuffer, outDataspace); // 传递给HWC进一步处理显示
  10.     return NO_ERROR;
  11. }
复制代码
以是,末了我们大概会有这样一种逻辑处置惩罚流程:


  • 当必要GPU合成时,会通过生产者RenderSurface::dequeueBuffer请求一块图形缓存,然后GPU就合成/画图,把数据保存到这块图形缓存中,通过RenderSurface::queueBuffer提交这块缓存
  • 调用mDisplaySurface->advanceFrame()通知消耗者来消耗:
    1. FramebufferSurface::advanceFrame ==>FramebufferSurface::nextBuffer ==> acquireBufferLocked
    复制代码
  • 去请求可用的图形缓存,这个buffer中存储有GPU合成的结果,然后通过setClientTarget把这个buffer传递给HWC做处置惩罚表现。



五.SF处置惩罚GPU合成流程分析

还记得我们前面分析到的Output::prepareFrame吗,其如果存在GPU合成,会实行如下的相关逻辑:
  1. Output::prepareFrame()
  2.     Display::chooseCompositionStrategy
  3.         Output::chooseCompositionStrategy()
  4.         hwc.getDeviceCompositionChanges
  5.         
  6.         
  7. status_t HWComposer::getDeviceCompositionChanges(
  8.         DisplayId displayId, bool frameUsesClientComposition,
  9.         std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
  10.    
  11.     ...
  12.     if (!frameUsesClientComposition) {
  13.         sp<Fence> outPresentFence;
  14.         uint32_t state = UINT32_MAX;
  15.         /**
  16.          * @brief
  17.          * 如果所有的layer都能走device合成
  18.          * 则在hwc里面直接present,若有不支持
  19.          * device合成的情况,则走GPU合成,会走validate逻辑
  20.          */
  21.         error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
  22.         if (!hasChangesError(error)) {
  23.             RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR);
  24.         }
  25.         if (state == 1) { //Present Succeeded.
  26.             //present成功,数据直接提交给了hwc
  27.             std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
  28.             error = hwcDisplay->getReleaseFences(&releaseFences);
  29.             displayData.releaseFences = std::move(releaseFences);
  30.             displayData.lastPresentFence = outPresentFence;
  31.             displayData.validateWasSkipped = true;
  32.             displayData.presentError = error;
  33.             return NO_ERROR;
  34.         }
  35.         // Present failed but Validate ran.
  36.     } else {
  37.         error = hwcDisplay->validate(&numTypes, &numRequests);
  38.     }
  39.     ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
  40.     if (!hasChangesError(error)) {
  41.         RETURN_IF_HWC_ERROR_FOR("validate", error, displayId, BAD_INDEX);
  42.     }
  43.     android::HWComposer::DeviceRequestedChanges::ChangedTypes changedTypes;
  44.     changedTypes.reserve(numTypes);
  45.     error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
  46.     RETURN_IF_HWC_ERROR_FOR("getChangedCompositionTypes", error, displayId, BAD_INDEX);
  47.     auto displayRequests = static_cast<hal::DisplayRequest>(0);
  48.     android::HWComposer::DeviceRequestedChanges::LayerRequests layerRequests;
  49.     layerRequests.reserve(numRequests);
  50.     error = hwcDisplay->getRequests(&displayRequests, &layerRequests);
  51.     RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX);
  52.     DeviceRequestedChanges::ClientTargetProperty clientTargetProperty;
  53.     error = hwcDisplay->getClientTargetProperty(&clientTargetProperty);
  54.     outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
  55.                                                std::move(layerRequests),
  56.                                                std::move(clientTargetProperty)});
  57.     //接收hwc反馈回来的,主要是支持device和gpu合成的情况
  58.     error = hwcDisplay->acceptChanges();
  59.     RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX);
  60.     return NO_ERROR;
  61. }
复制代码
前面我们也分析到了Output::finishFrame,此中的composeSurfaces是GPU合成的核心:
  1. void Output::finishFrame(const compositionengine::CompositionRefreshArgs& refreshArgs) {
  2.     ...
  3.     auto optReadyFence = composeSurfaces(Region::INVALID_REGION, refreshArgs);
  4.     if (!optReadyFence) {
  5.         return;
  6.     }
  7.     // swap buffers (presentation)
  8.     mRenderSurface->queueBuffer(std::move(*optReadyFence));
  9. }
复制代码



5.1 Output::composeSurfaces

这里我们先重点来看composeSurfaces这个函数,看下走GPU合成的逻辑:
  1. 文件:frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp
  2. std::optional<base::unique_fd> Output::composeSurfaces(
  3.         const Region& debugRegion, const compositionengine::CompositionRefreshArgs& refreshArgs) {
  4. ...
  5.     base::unique_fd fd;
  6.     sp<GraphicBuffer> buf;
  7.     // If we aren't doing client composition on this output, but do have a
  8.     // flipClientTarget request for this frame on this output, we still need to
  9.     // dequeue a buffer.
  10.     if (hasClientComposition || outputState.flipClientTarget) {
  11.         // dequeueBuffer一块Buffer,这块Buffer作为输出
  12.         buf = mRenderSurface->dequeueBuffer(&fd);
  13.         if (buf == nullptr) {
  14.             ALOGW("Dequeuing buffer for display [%s] failed, bailing out of "
  15.                   "client composition for this frame",
  16.                   mName.c_str());
  17.             return {};
  18.         }
  19.     }
  20.     base::unique_fd readyFence;
  21.     // GPU合成时不返回
  22.     if (!hasClientComposition) {
  23.         setExpensiveRenderingExpected(false);
  24.         return readyFence;
  25.     }
  26.     ALOGV("hasClientComposition");
  27.      // 设置clientCompositionDisplay,这个是display相关参数
  28.     renderengine::DisplaySettings clientCompositionDisplay;
  29.     clientCompositionDisplay.physicalDisplay = outputState.destinationClip;
  30.     clientCompositionDisplay.clip = outputState.sourceClip;
  31.     clientCompositionDisplay.orientation = outputState.orientation;
  32.     clientCompositionDisplay.outputDataspace = mDisplayColorProfile->hasWideColorGamut()
  33.        ? outputState.dataspace
  34.             : ui::Dataspace::UNKNOWN;
  35.     clientCompositionDisplay.maxLuminance =
  36.             mDisplayColorProfile->getHdrCapabilities().getDesiredMaxLuminance();
  37.     // Compute the global color transform matrix.
  38.     if (!outputState.usesDeviceComposition && !getSkipColorTransform()) {
  39.         clientCompositionDisplay.colorTransform = outputState.colorTransformMatrix;
  40.     }
  41.     // Note: Updated by generateClientCompositionRequests
  42.     clientCompositionDisplay.clearRegion = Region::INVALID_REGION;
  43.     // Generate the client composition requests for the layers on this output.
  44.     // 设置clientCompositionLayers , 这个是layer的相关参数
  45.     std::vector<LayerFE::LayerSettings> clientCompositionLayers =
  46.             generateClientCompositionRequests(supportsProtectedContent,
  47.                                               clientCompositionDisplay.clearRegion,
  48.                                               clientCompositionDisplay.outputDataspace);
  49.     appendRegionFlashRequests(debugRegion, clientCompositionLayers);
  50.     // Check if the client composition requests were rendered into the provided graphic buffer. If
  51.     // so, we can reuse the buffer and avoid client composition.
  52.     // 如果cache里有相同的Buffer,则不需要重复draw一次
  53.     if (mClientCompositionRequestCache) {
  54.         if (mClientCompositionRequestCache->exists(buf->getId(), clientCompositionDisplay,
  55.                                                    clientCompositionLayers)) {
  56.             outputCompositionState.reusedClientComposition = true;
  57.             setExpensiveRenderingExpected(false);
  58.             return readyFence;
  59.         }
  60.         mClientCompositionRequestCache->add(buf->getId(), clientCompositionDisplay,
  61.                                             clientCompositionLayers);
  62.     }
  63.     // We boost GPU frequency here because there will be color spaces conversion
  64.     // or complex GPU shaders and it's expensive. We boost the GPU frequency so that
  65.     // GPU composition can finish in time. We must reset GPU frequency afterwards,
  66.     // because high frequency consumes extra battery.
  67.     // 针对有模糊layer和有复杂颜色空间转换的场景,给GPU进行提频
  68.     const bool expensiveBlurs =
  69.             refreshArgs.blursAreExpensive && mLayerRequestingBackgroundBlur != nullptr;
  70.     const bool expensiveRenderingExpected =
  71.             clientCompositionDisplay.outputDataspace == ui::Dataspace::DISPLAY_P3 || expensiveBlurs;
  72.     if (expensiveRenderingExpected) {
  73.         setExpensiveRenderingExpected(true);
  74.     }
  75.     // 将clientCompositionLayers 里面的内容插入到clientCompositionLayerPointers,实质内容相同
  76.     std::vector<const renderengine::LayerSettings*> clientCompositionLayerPointers;
  77.     clientCompositionLayerPointers.reserve(clientCompositionLayers.size());
  78.     std::transform(clientCompositionLayers.begin(), clientCompositionLayers.end(),
  79.                    std::back_inserter(clientCompositionLayerPointers),
  80.                    [](LayerFE::LayerSettings& settings) -> renderengine::LayerSettings* {
  81.                        return &settings;
  82.                    });
  83.     const nsecs_t renderEngineStart = systemTime();
  84.     // GPU合成,主要逻辑在drawLayers里面
  85.     status_t status =
  86.             renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayerPointers,
  87.                                     buf->getNativeBuffer(), /*useFramebufferCache=*/true,
  88.                                     std::move(fd), &readyFence);
  89.    ...
  90. }
  91. std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests(
  92.         bool supportsProtectedContent, Region& clearRegion, ui::Dataspace outputDataspace) {
  93.     std::vector<LayerFE::LayerSettings> clientCompositionLayers;
  94.     ALOGV("Rendering client layers");
  95.     const auto& outputState = getState();
  96.     const Region viewportRegion(outputState.viewport);
  97.     const bool useIdentityTransform = false;
  98.     bool firstLayer = true;
  99.     // Used when a layer clears part of the buffer.
  100.     Region dummyRegion;
  101.     for (auto* layer : getOutputLayersOrderedByZ()) {
  102.         const auto& layerState = layer->getState();
  103.         const auto* layerFEState = layer->getLayerFE().getCompositionState();
  104.         auto& layerFE = layer->getLayerFE();
  105.         const Region clip(viewportRegion.intersect(layerState.visibleRegion));
  106.         ALOGV("Layer: %s", layerFE.getDebugName());
  107.         if (clip.isEmpty()) {
  108.             ALOGV("  Skipping for empty clip");
  109.             firstLayer = false;
  110.             continue;
  111.         }
  112.         const bool clientComposition = layer->requiresClientComposition();
  113.         // We clear the client target for non-client composed layers if
  114.         // requested by the HWC. We skip this if the layer is not an opaque
  115.         // rectangle, as by definition the layer must blend with whatever is
  116.         // underneath. We also skip the first layer as the buffer target is
  117.         // guaranteed to start out cleared.
  118.         const bool clearClientComposition =
  119.                 layerState.clearClientTarget && layerFEState->isOpaque && !firstLayer;
  120.         ALOGV("  Composition type: client %d clear %d", clientComposition, clearClientComposition);
  121.         // If the layer casts a shadow but the content casting the shadow is occluded, skip
  122.         // composing the non-shadow content and only draw the shadows.
  123.         const bool realContentIsVisible = clientComposition &&
  124.                 !layerState.visibleRegion.subtract(layerState.shadowRegion).isEmpty();
  125.         if (clientComposition || clearClientComposition) {
  126.             compositionengine::LayerFE::ClientCompositionTargetSettings targetSettings{
  127.                     clip,
  128.                     useIdentityTransform,
  129.                     layer->needsFiltering() || outputState.needsFiltering,
  130.                     outputState.isSecure,
  131.                     supportsProtectedContent,
  132.                     clientComposition ? clearRegion : dummyRegion,
  133.                     outputState.viewport,
  134.                     outputDataspace,
  135.                     realContentIsVisible,
  136.                     !clientComposition, /* clearContent  */
  137.             };
  138.             std::vector<LayerFE::LayerSettings> results =
  139.                     layerFE.prepareClientCompositionList(targetSettings);
  140.             if (realContentIsVisible && !results.empty()) {
  141.                 layer->editState().clientCompositionTimestamp = systemTime();
  142.             }
  143.             clientCompositionLayers.insert(clientCompositionLayers.end(),
  144.                                            std::make_move_iterator(results.begin()),
  145.                                            std::make_move_iterator(results.end()));
  146.             results.clear();
  147.         }
  148.         firstLayer = false;
  149.     }
  150.     return clientCompositionLayers;
  151. }
复制代码
输入的Buffer是通过BufferLayer的prepareClientComposition 函数设到RenderEngine里面的,如下:
  1. 文件:frameworks/native/services/surfaceflinger/BufferLayer.cpp
  2. std::optional<compositionengine::LayerFE::LayerSettings> BufferLayer::prepareClientComposition(
  3.         compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) {
  4.     ATRACE_CALL();
  5.     std::optional<compositionengine::LayerFE::LayerSettings> result =
  6.             Layer::prepareClientComposition(targetSettings);
  7.      ...
  8.     const State& s(getDrawingState());
  9.     // 应用queue过来的Buffer
  10.     layer.source.buffer.buffer = mBufferInfo.mBuffer;
  11.     layer.source.buffer.isOpaque = isOpaque(s);
  12.      // acquire fence
  13.     layer.source.buffer.fence = mBufferInfo.mFence;
  14.     // 创建BufferQueueLayer时创建的texture ID
  15.     layer.source.buffer.textureName = mTextureName;
  16.     ...
  17. }
复制代码
至此,SurfaceFlinger调到RenderEngine里面,SurfaceFlinger的display和outputlayer的信息传到了RenderEngine,这些都是GPU合成必要的信息,然后来看下drawLayers的流程。

5.2 GLESRenderEngine::drawLayers


  1. 文件:frameworks/native/libs/renderengine/gl/GLESRenderEngine.cpp
  2. status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
  3.                                       const std::vector<const LayerSettings*>& layers,
  4.                                       ANativeWindowBuffer* const buffer,
  5.                                       const bool useFramebufferCache, base::unique_fd&& bufferFence,
  6.                                       base::unique_fd* drawFence) {
  7.     ATRACE_CALL();
  8.     if (layers.empty()) {
  9.         ALOGV("Drawing empty layer stack");
  10.         return NO_ERROR;
  11.     }
  12.      // 要等前一帧的release fence
  13.     if (bufferFence.get() >= 0) {
  14.         // Duplicate the fence for passing to waitFence.
  15.         base::unique_fd bufferFenceDup(dup(bufferFence.get()));
  16.         if (bufferFenceDup < 0 || !waitFence(std::move(bufferFenceDup))) {
  17.             ATRACE_NAME("Waiting before draw");
  18.             sync_wait(bufferFence.get(), -1);
  19.         }
  20.     }
  21.     if (buffer == nullptr) {
  22.         ALOGE("No output buffer provided. Aborting GPU composition.");
  23.         return BAD_VALUE;
  24.     }
  25.     std::unique_ptr<BindNativeBufferAsFramebuffer> fbo;
  26.     ...
  27.     if (blurLayersSize == 0) {
  28.          // 将dequeue出来的buffer绑定到FB上面,作为fbo
  29.         fbo = std::make_unique<BindNativeBufferAsFramebuffer>(*this, buffer, useFramebufferCache);
  30. 文件:frameworks/native/libs/renderengine/gl/include/renderengine/RenderEngine.h
  31. class BindNativeBufferAsFramebuffer {
  32. public:
  33.     BindNativeBufferAsFramebuffer(RenderEngine& engine, ANativeWindowBuffer* buffer,
  34.                                   const bool useFramebufferCache)
  35.           : mEngine(engine), mFramebuffer(mEngine.getFramebufferForDrawing()), mStatus(NO_ERROR) {
  36.         mStatus = mFramebuffer->setNativeWindowBuffer(buffer, mEngine.isProtected(),
  37.                                                       useFramebufferCache)
  38.                 ? mEngine.bindFrameBuffer(mFramebuffer)
  39.                 : NO_MEMORY;
  40.     }
  41.     ~BindNativeBufferAsFramebuffer() {
  42.         mFramebuffer->setNativeWindowBuffer(nullptr, false, /*arbitrary*/ true);
  43.         mEngine.unbindFrameBuffer(mFramebuffer);
  44.     }
  45.     status_t getStatus() const { return mStatus; }
  46. private:
  47.     RenderEngine& mEngine;
  48.     Framebuffer* mFramebuffer;
  49.     status_t mStatus;
  50. };
  51. 文件: frameworks/native/libs/renderengine/gl/GLFramebuffer.cpp
  52. bool GLFramebuffer::setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer, bool isProtected,
  53.                                           const bool useFramebufferCache) {
  54.     ATRACE_CALL();
  55.     if (mEGLImage != EGL_NO_IMAGE_KHR) {
  56.         if (!usingFramebufferCache) {
  57.             eglDestroyImageKHR(mEGLDisplay, mEGLImage);
  58.             DEBUG_EGL_IMAGE_TRACKER_DESTROY();
  59.         }
  60.         mEGLImage = EGL_NO_IMAGE_KHR;
  61.         mBufferWidth = 0;
  62.         mBufferHeight = 0;
  63.     }
  64.     if (nativeBuffer) {
  65.         mEGLImage = mEngine.createFramebufferImageIfNeeded(nativeBuffer, isProtected,
  66.                                                            useFramebufferCache);
  67.         if (mEGLImage == EGL_NO_IMAGE_KHR) {
  68.             return false;
  69.         }
  70.         usingFramebufferCache = useFramebufferCache;
  71.         mBufferWidth = nativeBuffer->width;
  72.         mBufferHeight = nativeBuffer->height;
  73.     }
  74.     return true;
  75. }
  76. 文件:frameworks/native/libs/renderengine/gl/GLESRenderEngine.cpp
  77. GLImageKHR GLESRenderEngine::createFramebufferImageIfNeeded(ANativeWindowBuffer* nativeBuffer,
  78.                                                              bool isProtected,
  79.                                                              bool useFramebufferCache) {
  80.     // buffer类型转换,将ANativeWindowBuffer 转换成 GraphicsBuffer
  81.     sp<GraphicBuffer> graphicBuffer = GraphicBuffer::from(nativeBuffer);
  82.       //使用cache,如果有一样的image,就直接返回
  83.      if (useFramebufferCache) {
  84.         std::lock_guard<std::mutex> lock(mFramebufferImageCacheMutex);
  85.         for (const auto& image : mFramebufferImageCache) {
  86.             if (image.first == graphicBuffer->getId()) {
  87.                 return image.second;
  88.             }
  89.         }
  90.     }
  91.     EGLint attributes[] = {
  92.             isProtected ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
  93.             isProtected ? EGL_TRUE : EGL_NONE,
  94.             EGL_NONE,
  95.     };
  96.     // 将dequeue出来的buffer作为参数创建 EGLImage
  97.     EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
  98.                                           nativeBuffer, attributes);
  99.     if (useFramebufferCache) {
  100.         if (image != EGL_NO_IMAGE_KHR) {
  101.             std::lock_guard<std::mutex> lock(mFramebufferImageCacheMutex);
  102.             if (mFramebufferImageCache.size() >= mFramebufferImageCacheSize) {
  103.                 EGLImageKHR expired = mFramebufferImageCache.front().second;
  104.                 mFramebufferImageCache.pop_front();
  105.                 eglDestroyImageKHR(mEGLDisplay, expired);
  106.                 DEBUG_EGL_IMAGE_TRACKER_DESTROY();
  107.             }
  108.              // 把image放到mFramebufferImageCache 里面
  109.             mFramebufferImageCache.push_back({graphicBuffer->getId(), image});
  110.         }
  111.     }
  112.     if (image != EGL_NO_IMAGE_KHR) {
  113.         DEBUG_EGL_IMAGE_TRACKER_CREATE();
  114.     }
  115.     return image;
  116. }
  117. status_t GLESRenderEngine::bindFrameBuffer(Framebuffer* framebuffer) {
  118.     ATRACE_CALL();               
  119.     GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(framebuffer);
  120.     // 上一步创建的EGLImage
  121.     EGLImageKHR eglImage = glFramebuffer->getEGLImage();
  122.      // 创建RenderEngine 时就已经创建好的 texture id和 fb id
  123.     uint32_t textureName = glFramebuffer->getTextureName();
  124.     uint32_t framebufferName = glFramebuffer->getFramebufferName();
  125.     // Bind the texture and turn our EGLImage into a texture
  126.     // 绑定texture,后面的操作将作用在这上面
  127.     glBindTexture(GL_TEXTURE_2D, textureName);
  128.      // 根据EGLImage 创建一个 2D texture
  129.     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)eglImage);
  130.     // Bind the Framebuffer to render into
  131.     glBindFramebuffer(GL_FRAMEBUFFER, framebufferName);
  132.     // 将纹理附着在帧缓存上面,渲染到farmeBuffer
  133.     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureName, 0);
  134.     uint32_t glStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  135.     ALOGE_IF(glStatus != GL_FRAMEBUFFER_COMPLETE_OES, "glCheckFramebufferStatusOES error %d",
  136.              glStatus);
  137.     return glStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE;
  138. }
复制代码
起首将dequeue出来的buffer通过eglCreateImageKHR做成image,然后通过glEGLImageTargetTexture2DOES根据image创建一个2D的纹理,再通过glFramebufferTexture2D把纹理附着在帧缓存上面。setViewportAndProjection 设置视图和投影矩阵。
  1. 文件:frameworks/native/libs/renderengine/gl/GLESRenderEngine.cpp
  2. status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
  3.                                       const std::vector<const LayerSettings*>& layers,
  4.                                       ANativeWindowBuffer* const buffer,
  5.                                       const bool useFramebufferCache, base::unique_fd&& bufferFence,
  6.                                       base::unique_fd* drawFence) {
  7.          ...
  8.          // 设置顶点和纹理坐标的size
  9.          Mesh mesh = Mesh::Builder()
  10.                         .setPrimitive(Mesh::TRIANGLE_FAN)
  11.                         .setVertices(4 /* count */, 2 /* size */)
  12.                         .setTexCoords(2 /* size */)
  13.                         .setCropCoords(2 /* size */)
  14.                         .build();
  15.          for (auto const layer : layers) {
  16.           //遍历outputlayer
  17.              ...
  18.           //获取layer的大小
  19.         const FloatRect bounds = layer->geometry.boundaries;
  20.         Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
  21.         // 设置顶点的坐标,逆时针方向
  22.         position[0] = vec2(bounds.left, bounds.top);
  23.         position[1] = vec2(bounds.left, bounds.bottom);
  24.         position[2] = vec2(bounds.right, bounds.bottom);
  25.         position[3] = vec2(bounds.right, bounds.top);
  26.          //设置crop的坐标
  27.         setupLayerCropping(*layer, mesh);
  28.         // 设置颜色矩阵
  29.         setColorTransform(display.colorTransform * layer->colorTransform);
  30.         ...
  31.         // Buffer相关设置
  32.         if (layer->source.buffer.buffer != nullptr) {
  33.             disableTexture = false;
  34.             isOpaque = layer->source.buffer.isOpaque;
  35.              // layer的buffer,理解为输入的buffer
  36.             sp<GraphicBuffer> gBuf = layer->source.buffer.buffer;
  37.             // textureName是创建BufferQueuelayer时生成的,用来标识这个layer,
  38.             // fence是acquire fence
  39.             bindExternalTextureBuffer(layer->source.buffer.textureName, gBuf,
  40.                                       layer->source.buffer.fence);
  41.             ...
  42.             // 设置纹理坐标,也是逆时针
  43.             renderengine::Mesh::VertexArray<vec2> texCoords(mesh.getTexCoordArray<vec2>());
  44.             texCoords[0] = vec2(0.0, 0.0);
  45.             texCoords[1] = vec2(0.0, 1.0);
  46.             texCoords[2] = vec2(1.0, 1.0);
  47.             texCoords[3] = vec2(1.0, 0.0);
  48.            // 设置纹理的参数,glTexParameteri
  49.             setupLayerTexturing(texture);
  50.         }
  51. status_t GLESRenderEngine::bindExternalTextureBuffer(uint32_t texName,
  52.                                                      const sp<GraphicBuffer>& buffer,
  53.                                                      const sp<Fence>& bufferFence) {
  54.     if (buffer == nullptr) {
  55.         return BAD_VALUE;
  56.     }
  57.     ATRACE_CALL();
  58.     bool found = false;
  59.     {
  60.         // 在ImageCache里面找有没有相同的buffer
  61.         std::lock_guard<std::mutex> lock(mRenderingMutex);
  62.         auto cachedImage = mImageCache.find(buffer->getId());
  63.         found = (cachedImage != mImageCache.end());
  64.     }
  65.     // If we couldn't find the image in the cache at this time, then either
  66.     // SurfaceFlinger messed up registering the buffer ahead of time or we got
  67.     // backed up creating other EGLImages.
  68.     if (!found) {
  69.         //如果ImageCache里面没有则需要重新创建一个EGLImage,创建输入的EGLImage是在ImageManager线程里面,利用notify唤醒机制
  70.         status_t cacheResult = mImageManager->cache(buffer);
  71.         if (cacheResult != NO_ERROR) {
  72.             return cacheResult;
  73.         }
  74.     }
  75.     ...
  76.         // 把EGLImage转换成纹理,类型为GL_TEXTURE_EXTERNAL_OES
  77.         bindExternalTextureImage(texName, *cachedImage->second);
  78.         mTextureView.insert_or_assign(texName, buffer->getId());
  79.     }
  80. }
  81. void GLESRenderEngine::bindExternalTextureImage(uint32_t texName, const Image& image) {
  82.     ATRACE_CALL();
  83.     const GLImage& glImage = static_cast<const GLImage&>(image);
  84.     const GLenum target = GL_TEXTURE_EXTERNAL_OES;
  85.      //绑定纹理,纹理ID为texName
  86.     glBindTexture(target, texName);
  87.     if (glImage.getEGLImage() != EGL_NO_IMAGE_KHR) {
  88.         // 把EGLImage转换成纹理,纹理ID为texName
  89.         glEGLImageTargetTexture2DOES(target, static_cast<GLeglImageOES>(glImage.getEGLImage()));
  90.     }
  91. }
复制代码


至此,将输入和输出的Buffer都生成了纹理对应,以及设置了纹理的坐标和顶点的坐标,接下来就要利用shader举行绘制了。
  1. 文件:frameworks/native/libs/renderengine/gl/GLESRenderEngine.cpp
  2. void GLESRenderEngine::drawMesh(const Mesh& mesh) {
  3.     ATRACE_CALL();
  4.     if (mesh.getTexCoordsSize()) {
  5.         //开启顶点着色器属性,,目的是能在顶点着色器中访问顶点的属性数据
  6.         glEnableVertexAttribArray(Program::texCoords);
  7.        // 给顶点着色器传纹理的坐标
  8.         glVertexAttribPointer(Program::texCoords, mesh.getTexCoordsSize(), GL_FLOAT, GL_FALSE,
  9.                               mesh.getByteStride(), mesh.getTexCoords());
  10.     }
  11.     //给顶点着色器传顶点的坐标
  12.     glVertexAttribPointer(Program::position, mesh.getVertexSize(), GL_FLOAT, GL_FALSE,
  13.                           mesh.getByteStride(), mesh.getPositions());
  14.     ...
  15.     // 创建顶点和片段着色器,将顶点属性设和一些常量参数设到shader里面
  16.     ProgramCache::getInstance().useProgram(mInProtectedContext ? mProtectedEGLContext : mEGLContext,
  17.                                            managedState);
  18.     ...
  19.     // 调GPU去draw
  20.     glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
  21.     ...
  22. }
  23. 文件:frameworks/native/libs/renderengine/gl/ProgramCache.cpp
  24. void ProgramCache::useProgram(EGLContext context, const Description& description) {
  25.     //设置key值,根据不同的key值创建不同的shader
  26.     Key needs(computeKey(description));   
  27.     // look-up the program in the cache
  28.     auto& cache = mCaches[context];
  29.     auto it = cache.find(needs);
  30.     if (it == cache.end()) {
  31.         // we didn't find our program, so generate one...
  32.         nsecs_t time = systemTime();
  33.         // 如果cache里面没有相同的program则重新创建一个
  34.         it = cache.emplace(needs, generateProgram(needs)).first;
  35.         time = systemTime() - time;
  36.         ALOGV(">>> generated new program for context %p: needs=%08X, time=%u ms (%zu programs)",
  37.               context, needs.mKey, uint32_t(ns2ms(time)), cache.size());
  38.     }   
  39.    
  40.     // here we have a suitable program for this description
  41.     std::unique_ptr<Program>& program = it->second;
  42.     if (program->isValid()) {
  43.         program->use();
  44.         program->setUniforms(description);
  45.     }
  46. }
  47. std::unique_ptr<Program> ProgramCache::generateProgram(const Key& needs) {
  48.     ATRACE_CALL();
  49.     // 创建顶点着色器
  50.     String8 vs = generateVertexShader(needs);
  51.     // 创建片段着色器
  52.     String8 fs = generateFragmentShader(needs);
  53.      // 链接和编译着色器
  54.     return std::make_unique<Program>(needs, vs.string(), fs.string());
  55. }
  56. String8 ProgramCache::generateVertexShader(const Key& needs) {
  57.     Formatter vs;
  58.     if (needs.hasTextureCoords()) {
  59.          // attribute属性通过glVertexAttribPointer设置,varying 表示输出给片段着色器的数据
  60.         vs << "attribute vec4 texCoords;"
  61.            << "varying vec2 outTexCoords;";
  62.     }
  63.     ...
  64.     vs << "attribute vec4 position;"
  65.        << "uniform mat4 projection;"
  66.        << "uniform mat4 texture;"
  67.        << "void main(void) {" << indent << "gl_Position = projection * position;";
  68.     if (needs.hasTextureCoords()) {
  69.         vs << "outTexCoords = (texture * texCoords).st;";
  70.     }
  71.     ...
  72.     return vs.getString();
  73. }
  74. String8 ProgramCache::generateFragmentShader(const Key& needs) {
  75.     Formatter fs;
  76.     if (needs.getTextureTarget() == Key::TEXTURE_EXT) {
  77.         fs << "#extension GL_OES_EGL_image_external : require";
  78.     }
  79.     // default precision is required-ish in fragment shaders
  80.     fs << "precision mediump float;";
  81.     if (needs.getTextureTarget() == Key::TEXTURE_EXT) {
  82.         fs << "uniform samplerExternalOES sampler;";
  83.     } else if (needs.getTextureTarget() == Key::TEXTURE_2D) {
  84.         fs << "uniform sampler2D sampler;";
  85.     }
  86.     if (needs.hasTextureCoords()) {
  87.         fs << "varying vec2 outTexCoords;";
  88.     }
  89.     ...
  90.     fs << "void main(void) {" << indent;
  91.     ...
  92.         if (needs.isTexturing()) {
  93.             // 输出像素的颜色值
  94.             fs << "gl_FragColor = texture2D(sampler, outTexCoords);"
  95.     ...
  96. }
  97. 文件: frameworks/native/libs/renderengine/gl/Program.cpp
  98. Program::Program(const ProgramCache::Key& /*needs*/, const char* vertex, const char* fragment)
  99.       : mInitialized(false) {
  100.     // 编译顶点和片段着色器
  101.     GLuint vertexId = buildShader(vertex, GL_VERTEX_SHADER);
  102.     GLuint fragmentId = buildShader(fragment, GL_FRAGMENT_SHADER);
  103.     // 创建programID
  104.     GLuint programId = glCreateProgram();
  105.     // 将顶点和片段着色器链接到programe
  106.     glAttachShader(programId, vertexId);
  107.     glAttachShader(programId, fragmentId);
  108.     // 将着色器里面的属性和自定义的属性变量绑定
  109.     glBindAttribLocation(programId, position, "position");
  110.     glBindAttribLocation(programId, texCoords, "texCoords");
  111.     glBindAttribLocation(programId, cropCoords, "cropCoords");
  112.     glBindAttribLocation(programId, shadowColor, "shadowColor");
  113.     glBindAttribLocation(programId, shadowParams, "shadowParams");
  114.     glLinkProgram(programId);
  115.     GLint status;
  116.     glGetProgramiv(programId, GL_LINK_STATUS, &status);
  117.     ...
  118.         mProgram = programId;
  119.         mVertexShader = vertexId;
  120.         mFragmentShader = fragmentId;
  121.         mInitialized = true;
  122.         //获得着色器里面uniform变量的位置
  123.         mProjectionMatrixLoc = glGetUniformLocation(programId, "projection");
  124.         mTextureMatrixLoc = glGetUniformLocation(programId, "texture");
  125.         ...
  126.         // set-up the default values for our uniforms
  127.         glUseProgram(programId);
  128.         glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, mat4().asArray());
  129.         glEnableVertexAttribArray(0);
  130. }
  131. void Program::use() {
  132.     // Program生效
  133.     glUseProgram(mProgram);
  134. }
  135. void Program::setUniforms(const Description& desc) {
  136.     // TODO: we should have a mechanism here to not always reset uniforms that
  137.     // didn't change for this program.
  138.     // 根据uniform的位置,给uniform变量设置,设到shader里面
  139.     if (mSamplerLoc >= 0) {
  140.         glUniform1i(mSamplerLoc, 0);
  141.         glUniformMatrix4fv(mTextureMatrixLoc, 1, GL_FALSE, desc.texture.getMatrix().asArray());
  142.     }
  143.    ...
  144.        glUniformMatrix4fv(mProjectionMatrixLoc, 1, GL_FALSE, desc.projectionMatrix.asArray());
  145.     }
复制代码
末了调用glDrawArrays,利用GPU来绘制,可见对于GPU来说,输入都是一幅幅纹理,然后在着色器里面控制末了pixel的位置坐标和颜色值。
利用GPU绘制往往伴随着一个acquire fence,看下acquire fence的生。

  1. 文件: frameworks/native/libs/renderengine/gl/GLESRenderEngine.cpp
  2. base::unique_fd GLESRenderEngine::flush() {
  3.     ATRACE_CALL();
  4.     if (!GLExtensions::getInstance().hasNativeFenceSync()) {
  5.         return base::unique_fd();
  6.     }
  7.     // 创建一个EGLSync对象,用来标识GPU是否绘制完
  8.     EGLSyncKHR sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
  9.     if (sync == EGL_NO_SYNC_KHR) {
  10.         ALOGW("failed to create EGL native fence sync: %#x", eglGetError());
  11.         return base::unique_fd();
  12.     }
  13.     // native fence fd will not be populated until flush() is done.
  14.     // 将gl command命令全部刷给GPU
  15.     glFlush();
  16.     // get the fence fd
  17.      //获得android 使用的fence fd
  18.     base::unique_fd fenceFd(eglDupNativeFenceFDANDROID(mEGLDisplay, sync));
  19.     eglDestroySyncKHR(mEGLDisplay, sync);
  20.     if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
  21.         ALOGW("failed to dup EGL native fence sync: %#x", eglGetError());
  22.     }
  23.     // Only trace if we have a valid fence, as current usage falls back to
  24.     // calling finish() if the fence fd is invalid.
  25.     if (CC_UNLIKELY(mTraceGpuCompletion && mFlushTracer) && fenceFd.get() >= 0) {
  26.         mFlushTracer->queueSync(eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, nullptr));
  27.     }
  28.     return fenceFd;
  29. }
复制代码
到这里,CPU将下令全部给到GPU了,然后GPU本身去draw,CPU继续往下运行。
回到finishFrame 函数,获得GPU合成的fence后,会实行queueBuffer操作。


5.3 Output::finishFrame

我们继续回到finishFrame,通过前面的composeSurfaces我们完成了对目标Buffer的GPU合成,此时我们会接着会实行queueBuffer操作,取出GPU合成之后的buffer:
  1. 文件:frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp
  2. void Output::finishFrame(const compositionengine::CompositionRefreshArgs& refreshArgs) {
  3.     ATRACE_CALL();
  4.     ALOGV(__FUNCTION__);
  5.     if (!getState().isEnabled) {
  6.         return;
  7.     }
  8.     // Repaint the framebuffer (if needed), getting the optional fence for when
  9.     // the composition completes.
  10.     auto optReadyFence = composeSurfaces(Region::INVALID_REGION, refreshArgs);
  11.     if (!optReadyFence) {
  12.         return;
  13.     }
  14.     // swap buffers (presentation)
  15.     mRenderSurface->queueBuffer(std::move(*optReadyFence));
  16. }
  17. 文件:frameworks/native/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
  18. void RenderSurface::queueBuffer(base::unique_fd readyFence) {
  19.     auto& state = mDisplay.getState();
  20.          ...
  21.    
  22.         if (mGraphicBuffer == nullptr) {
  23.             ALOGE("No buffer is ready for display [%s]", mDisplay.getName().c_str());
  24.         } else {
  25.             status_t result =
  26.                     // mGraphicBuffer->getNativeBuffer() 是GPU输出的Buffer,可以理解为GPU将内容合成到该Buffer上
  27.                     mNativeWindow->queueBuffer(mNativeWindow.get(),
  28.                                                mGraphicBuffer->getNativeBuffer(), dup(readyFence));
  29.             if (result != NO_ERROR) {
  30.                 ALOGE("Error when queueing buffer for display [%s]: %d", mDisplay.getName().c_str(),
  31.                       result);
  32.                 // We risk blocking on dequeueBuffer if the primary display failed
  33.                 // to queue up its buffer, so crash here.
  34.                 if (!mDisplay.isVirtual()) {
  35.                     LOG_ALWAYS_FATAL("ANativeWindow::queueBuffer failed with error: %d", result);
  36.                 } else {
  37.                     mNativeWindow->cancelBuffer(mNativeWindow.get(),
  38.                                                 mGraphicBuffer->getNativeBuffer(), dup(readyFence));
  39.                 }
  40.             }
  41.             mGraphicBuffer = nullptr;
  42.         }
  43.     }
  44.     // 消费Buffer
  45.     status_t result = mDisplaySurface->advanceFrame();
  46.     if (result != NO_ERROR) {
  47.         ALOGE("[%s] failed pushing new frame to HWC: %d", mDisplay.getName().c_str(), result);
  48.     }
  49. }
  50. 文件:frameworks/native/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
  51. status_t FramebufferSurface::advanceFrame() {
  52.     uint32_t slot = 0;
  53.     sp<GraphicBuffer> buf;
  54.     sp<Fence> acquireFence(Fence::NO_FENCE);   
  55.     Dataspace dataspace = Dataspace::UNKNOWN;
  56.     // 消费这块Buffer
  57.     status_t result = nextBuffer(slot, buf, acquireFence, dataspace);
  58.     mDataSpace = dataspace;
  59.     if (result != NO_ERROR) {
  60.         ALOGE("error latching next FramebufferSurface buffer: %s (%d)",
  61.                 strerror(-result), result);
  62.     }
  63.     return result;
  64. }
  65. status_t FramebufferSurface::nextBuffer(uint32_t& outSlot,
  66.         sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence,
  67.         Dataspace& outDataspace) {
  68.     Mutex::Autolock lock(mMutex);
  69.     BufferItem item;
  70.     // acquire Buffer
  71.     status_t err = acquireBufferLocked(&item, 0);
  72.     ...
  73.     if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT &&
  74.         item.mSlot != mCurrentBufferSlot) {
  75.         mHasPendingRelease = true;
  76.         mPreviousBufferSlot = mCurrentBufferSlot;
  77.         mPreviousBuffer = mCurrentBuffer;
  78.     }
  79.     //更新当前的Buffer和fence信息
  80.     mCurrentBufferSlot = item.mSlot;
  81.     mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
  82.     mCurrentFence = item.mFence;
  83.     outFence = item.mFence;
  84.     mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, &outSlot, &outBuffer);
  85.     outDataspace = static_cast<Dataspace>(item.mDataSpace);
  86.      // 将GPU输出的Buffer和fence给到hwc
  87.     status_t result = mHwc.setClientTarget(mDisplayId, outSlot, outFence, outBuffer, outDataspace);
  88.     if (result != NO_ERROR) {
  89.         ALOGE("error posting framebuffer: %d", result);
  90.         return result;
  91.     }
  92.     return NO_ERROR;
  93. }
复制代码
GPU合成的Buffer通过setClientTarget 设给hwc,有GPU合成的layer必要先validate再present,以是还必要再present一次,逻辑在postFramebuffer 里面。

5.4 Output::postFramebuffer


  1. 文件:frameworks/native/services/surfaceflinger/CompositionEngine/src/Output.cpp
  2. void Output::postFramebuffer() {
  3.     ATRACE_CALL();
  4.     ALOGV(__FUNCTION__);
  5.    ...
  6.     auto frame = presentAndGetFrameFences();
  7.     mRenderSurface->onPresentDisplayCompleted();
  8.     ...
  9. }
  10.    
  11. 文件:frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
  12. status_t HWComposer::presentAndGetReleaseFences(DisplayId displayId) {
  13.     ATRACE_CALL();
  14.    
  15.     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
  16.         
  17.     auto& displayData = mDisplayData[displayId];
  18.     auto& hwcDisplay = displayData.hwcDisplay;
  19.    
  20.      ...
  21.     // GPU合成时执行present,返回present fence
  22.     auto error = hwcDisplay->present(&displayData.lastPresentFence);
  23.     RETURN_IF_HWC_ERROR_FOR("present", error, displayId, UNKNOWN_ERROR);
  24.     std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
  25.     // 从hwc里面获得release fence
  26.     error = hwcDisplay->getReleaseFences(&releaseFences);
  27.     RETURN_IF_HWC_ERROR_FOR("getReleaseFences", error, displayId, UNKNOWN_ERROR);
  28.     displayData.releaseFences = std::move(releaseFences);
  29.     return NO_ERROR;
  30. }
  31. 文件: frameworks/native/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
  32. void FramebufferSurface::onFrameCommitted() {
  33.     if (mHasPendingRelease) {
  34.         sp<Fence> fence = mHwc.getPresentFence(mDisplayId);
  35.         if (fence->isValid()) {
  36.             // 更新BufferSlot的 fence
  37.             status_t result = addReleaseFence(mPreviousBufferSlot,
  38.                     mPreviousBuffer, fence);
  39.             ALOGE_IF(result != NO_ERROR, "onFrameCommitted: failed to add the"
  40.                     " fence: %s (%d)", strerror(-result), result);
  41.         }
  42.         // 释放之前的Buffer
  43.         status_t result = releaseBufferLocked(mPreviousBufferSlot, mPreviousBuffer);
  44.         ALOGE_IF(result != NO_ERROR, "onFrameCommitted: error releasing buffer:"
  45.                 " %s (%d)", strerror(-result), result);
  46.    
  47.         mPreviousBuffer.clear();
  48.         mHasPendingRelease = false;
  49.     }
  50. }
复制代码
至此GPU合成的layer通过present调到hwc,hwc再实行commit上屏,此中有一些fence同步的代码,就先不分析了。



写在末了

好了今天的博客Android下SF合成流程重学习之GPU合成就到这里了。总之,青山不改绿水长流先到这里了。如果本博客对你有所资助,麻烦关注大概点个赞,如果觉得很烂也可以踩一脚!谢谢各位了!!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

愛在花開的季節

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表