Android GPU合成

1 FramebufferSurface 概述

   FramebufferSurface 根据名字解析:

  1: Surface 说明它是一个Surface, 那么它就会拥有一个 BufferQuere, 用于显示。

  2: FrameBuffer 这和 Linux 的 framebuffer 是完全不同的。 但是作用有些类似, SurfaceFlinger 在上面作画, 并把它交给HWC, 最终由HWC负责真正的显示。

1.1 FrameBufferSurface创建

SurfaceFlinger启动时会在SurfaceFlinger::init()中通过processDisplayHotplugEventsLocked()->processDisplayChangesLocked()->processDisplayAdded(displayToken, curr[i])中:

 
900  void SurfaceFlinger::init() {
.....
924      mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
925      mCompositionEngine->getHwComposer().setConfiguration(this, getBE().mComposerSequenceId);
926      // Process any initial hotplug and resulting display changes.
927      processDisplayHotplugEventsLocked();
928      const auto display = getDefaultDisplayDeviceLocked();

        processDisplayAdded()方法如下,其创建了BufferQueue和FrameBufferSurface,简单理解为连接上了显示屏幕(Display),那就要给准备一个BufferQueue,以便GPU合成图层时,可以向这个BufferQueue索要GraphicBuffer来存储合成后的数据,再呈现到屏幕上去。

3209  void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
3210                                           const DisplayDeviceState& state) {
        .....
3265      sp<compositionengine::DisplaySurface> displaySurface;
3266      sp<IGraphicBufferProducer> producer;
       //创建BufferQueue,获取到生产者和消费者,而且消费者不是SurfaceFlinger。
3267      sp<IGraphicBufferProducer> bqProducer;
3268      sp<IGraphicBufferConsumer> bqConsumer;
3269      getFactory().createBufferQueue(&bqProducer, &bqConsumer, /*consumerIsSurfaceFlinger =*/false);
3270  
3271      std::optional<DisplayId> displayId = compositionDisplay->getId();
3272  
3273      if (state.isVirtual()) {//虚拟屏幕
3274          sp<VirtualDisplaySurface> vds =
3275                  new VirtualDisplaySurface(getHwComposer(), displayId, state.surface,
3276                                            bqProducer, bqConsumer, state.displayName,
3277                                            state.isSecure);
3278  
3279          displaySurface = vds;
3280          producer = vds;
3281      } else {
3282          ALOGE_IF(state.surface != nullptr,
3283                   "adding a supported display, but rendering "
3284                   "surface is provided (%p), ignoring it",
3285                   state.surface.get());
3286  
3287          LOG_ALWAYS_FATAL_IF(!displayId);
        //创建了FrameBufferSurface对象,及继承自compositionengine::DisplaySurface
        //FrameBufferSurface作为消费者的角色工作,消费SF GPU合成后的数据
3288          displaySurface = new FramebufferSurface(getHwComposer(), *displayId, bqConsumer,
3289                                                  maxGraphicsWidth, maxGraphicsHeight);
3290          producer = bqProducer;
3291      }
3292  
3293      LOG_FATAL_IF(!displaySurface);
//创建DisplayDevice,其又去创建RenderSurface,作为生产者角色工作,displaySurface就是FramebufferSurface对象
3294      const auto display = setupNewDisplayDeviceInternal(displayToken, compositionDisplay, state,
3295                                                         displaySurface, producer);
3296      mDisplays.emplace(displayToken, display);
        .....

然后FrameBufferSurface的构造函数,只是一些设置,初始化一些成员:

 
59  FramebufferSurface::FramebufferSurface(HWComposer& hwc, DisplayId displayId,
60                                         const sp<IGraphicBufferConsumer>& consumer,
61                                         uint32_t maxWidth, uint32_t maxHeight)
62        : ConsumerBase(consumer),
63          mDisplayId(displayId),
64          mMaxWidth(maxWidth),
65          mMaxHeight(maxHeight),
66          mCurrentBufferSlot(-1),
67          mCurrentBuffer(),
68          mCurrentFence(Fence::NO_FENCE),
69          mHwc(hwc),
70          mHasPendingRelease(false),
71          mPreviousBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
72          mPreviousBuffer() {
73      ALOGV("Creating for display %s", to_string(displayId).c_str());
74  
75      mName = "FramebufferSurface";
76      mConsumer->setConsumerName(mName);
77      mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
78                                         GRALLOC_USAGE_HW_RENDER |
79                                         GRALLOC_USAGE_HW_COMPOSER);
80      const auto& activeConfig = mHwc.getActiveConfig(displayId);
81      ui::Size limitedSize =
82              limitFramebufferSize(activeConfig->getWidth(), activeConfig->getHeight());
83      mConsumer->setDefaultBufferSize(limitedSize.width, limitedSize.height);
84      mConsumer->setMaxAcquiredBufferCount(
85              SurfaceFlinger::maxFrameBufferAcquiredBuffers - 1);
86  }

再进到surfaceflinger::setupNewDisplayDeviceInternal()中:

 
3123  sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
3124          const wp<IBinder>& displayToken,
3125          std::shared_ptr<compositionengine::Display> compositionDisplay,
3126          const DisplayDeviceState& state,
3127          const sp<compositionengine::DisplaySurface>& displaySurface,
3128          const sp<IGraphicBufferProducer>& producer) {
    .....
3133      creationArgs.displaySurface = displaySurface;
    .....
     //创建对应的surface
3163      auto nativeWindowSurface = getFactory().createNativeWindowSurface(producer);
3164      auto nativeWindow = nativeWindowSurface->getNativeWindow();
3165      creationArgs.nativeWindow = nativeWindow;
3166  
3167      // Make sure that composition can never be stalled by a virtual display
3168      // consumer that isn't processing buffers fast enough. We have to do this
3169      // here, in case the display is composed entirely by HWC.
3170      if (state.isVirtual()) {
3171          nativeWindow->setSwapInterval(nativeWindow.get(), 0);
3172      }
    .....
3180      sp<DisplayDevice> display = getFactory().createDisplayDevice(creationArgs);
3181  
    .....
3196      if (!state.isVirtual()) {
3197          LOG_ALWAYS_FATAL_IF(!displayId);
3198          auto activeConfigId = HwcConfigIndexType(getHwComposer().getActiveConfigIndex(*displayId));
3199          display->setActiveConfig(activeConfigId);
3200      }
    .....
3205  
3206      return display;
3207  }

1.2 RenderSurface创建

        接下来就是DisplayDevice的构造函数了,里面主要是创建了RenderSurface对象,然后对其初始化。

57  DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args)
58        : mFlinger(args.flinger),
59          mDisplayToken(args.displayToken),
60          mSequenceId(args.sequenceId),
61          mConnectionType(args.connectionType),
62          mCompositionDisplay{args.compositionDisplay},
63          mPhysicalOrientation(args.physicalOrientation),
64          mIsPrimary(args.isPrimary),
65          mIsPowerModeOverride(false){
66      mCompositionDisplay->editState().isSecure = args.isSecure;
         //创建RenderSurface,args.nativewindow即为producer,指向生产者
67      mCompositionDisplay->createRenderSurface(
68              compositionengine::RenderSurfaceCreationArgs{ANativeWindow_getWidth(
69                                                                   args.nativeWindow.get()),
70                                                           ANativeWindow_getHeight(
71                                                                   args.nativeWindow.get()),
72                                                           args.nativeWindow, args.displaySurface});
        .....
85  
86      if (!mCompositionDisplay->isValid()) {
87          ALOGE("Composition Display did not validate!");
88      }
89         //初始化RenderSurface
90      mCompositionDisplay->getRenderSurface()->initialize();
91  
92      setPowerMode(args.initialPowerMode);
93  
94      // initialize the display orientation transform.
95      setProjection(ui::ROTATION_0, Rect::INVALID_RECT, Rect::INVALID_RECT);
96  }

        RenderSurface作为生产者角色工作,构造函数如下,其成员displaysurface就是上面SurfaceFlinger创建的FramebufferSurface对象,也就是作为生产者的RenderSurface中持有消费者的引用displaySurface,可以呼叫FramebufferSurface的方法。

58  RenderSurface::RenderSurface(const CompositionEngine& compositionEngine, Display& display,
59                               const RenderSurfaceCreationArgs& args)
60        : mCompositionEngine(compositionEngine),
61          mDisplay(display),
62          mNativeWindow(args.nativeWindow),
63          mDisplaySurface(args.displaySurface),
64          mSize(args.displayWidth, args.displayHeight) {
65      LOG_ALWAYS_FATAL_IF(!mNativeWindow);
66  }

        RenderSurface::initialize() 方法就是作为producer去和Bufferqueue建立connect(这里不太清楚,更倾向于将NativeWindow和Displaydevice的BufferQueue建立联系,之后应该produder就可以 dequeue buffer 了),并设置format为RGBA_8888,设置usage为GRALLOC_USAGE_HW_RENDER。

77  void RenderSurface::initialize() {
78      ANativeWindow* const window = mNativeWindow.get();
79  
80      int status = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
81      ALOGE_IF(status != NO_ERROR, "Unable to connect BQ producer: %d", status);
82      status = native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
83      ALOGE_IF(status != NO_ERROR, "Unable to set BQ format to RGBA888: %d", status);
84      status = native_window_set_usage(window, GRALLOC_USAGE_HW_RENDER);
85      ALOGE_IF(status != NO_ERROR, "Unable to set BQ usage bits for GPU rendering: %d", status);
86  }

2 SurfaceFlinger驱动FramebufferSurface

2.1 FramebufferSurface 与 DisplayDevice 的关系

        FramebufferSurface作为BufferQueue的Consumer端,DisplayDevice中的EGLSurface作为BufferQueue的 Producer端。

   下面主要是Client合成逻辑,首先Display交换buffer:

802  void Output::finishFrame(const compositionengine::CompositionRefreshArgs& refreshArgs) {
803      ATRACE_CALL();
804      ALOGV(__FUNCTION__);
805  
806      if (!getState().isEnabled) {
807          return;
808      }
809  
810      // Repaint the framebuffer (if needed), getting the optional fence for when
811      // the composition completes.
812      auto optReadyFence = composeSurfaces(Region::INVALID_REGION, refreshArgs);
813      if (!optReadyFence) {
814          return;
815      }
816  
817      // swap buffers (presentation)
818      mRenderSurface->queueBuffer(std::move(*optReadyFence));
819  }

        如果Client合成,调用queuebuffer,queue到FrameBufferSurface的BufferQueue中。

172  void RenderSurface::queueBuffer(base::unique_fd readyFence) {173      auto& state = mDisplay.getState();
174  175  176      if (state.usesClientComposition || state.flipClientTarget || mFlipClientTarget) {
177          // hasFlipClientTargetRequest could return true even if we haven't178          // dequeued a buffer before. Try dequeueing one if we don't have a179          // buffer ready.180          if (mGraphicBuffer == nullptr) {
181              ALOGI("Attempting to queue a client composited buffer without one "182                    "previously dequeued for display [%s]. Attempting to dequeue "183                    "a scratch buffer now",
184                    mDisplay.getName().c_str());
185              // We shouldn't deadlock here, since mGraphicBuffer == nullptr only186              // after a successful call to queueBuffer, or if dequeueBuffer has187              // never been called.188              base::unique_fd unused;
189              dequeueBuffer(&unused);
190          }
191  192          if (mGraphicBuffer == nullptr) {
193              ALOGE("No buffer is ready for display [%s]", mDisplay.getName().c_str());
194          } else {
195              status_t result =
196                      mNativeWindow->queueBuffer(mNativeWindow.get(),
197                                                 mGraphicBuffer->getNativeBuffer(),
198                                                 mFlipClientTarget ? -1 : dup(readyFence));
199              if (result != NO_ERROR) {
200                  ALOGE("Error when queueing buffer for display [%s]: %d", mDisplay.getName().c_str(),
201                        result);
202                  // We risk blocking on dequeueBuffer if the primary display failed203                  // to queue up its buffer, so crash here.204                  if (!mDisplay.isVirtual()) {
205                      LOG_ALWAYS_FATAL("ANativeWindow::queueBuffer failed with error: %d", result);
206                  } else {
207                      mNativeWindow->cancelBuffer(mNativeWindow.get(),
208                                                  mGraphicBuffer->getNativeBuffer(),
209                                                  mFlipClientTarget ? -1 : dup(readyFence));
210                  }
211              }
212  213              mGraphicBuffer = nullptr;
214          }
215      }
216  217      status_t result = mDisplaySurface->advanceFrame();
218      if (result != NO_ERROR) {
219          ALOGE("[%s] failed pushing new frame to HWC: %d", mDisplay.getName().c_str(), result);
220      }
221  }

        mDisplaySurface的advanceFrame方法,虚显用的是VirtualDisplaySurface,非虚显用的FrameBufferSurface。advanceFrame()获取FBTarget的数据:

101  status_t FramebufferSurface::advanceFrame() {
102      uint32_t slot = 0;
103      sp<GraphicBuffer> buf;
104      sp<Fence> acquireFence(Fence::NO_FENCE);
105      Dataspace dataspace = Dataspace::UNKNOWN;
106      status_t result = nextBuffer(slot, buf, acquireFence, dataspace);
107      mDataSpace = dataspace;
108      if (result != NO_ERROR) {
109          ALOGE("error latching next FramebufferSurface buffer: %s (%d)",
110                  strerror(-result), result);
111      }
112      return result;
113  }

主要在nextBuffer函数中完成:

115  status_t FramebufferSurface::nextBuffer(uint32_t& outSlot,
116          sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence,
117          Dataspace& outDataspace) {
118      Mutex::Autolock lock(mMutex);
119  
120      BufferItem item;
121      status_t err = acquireBufferLocked(&item, 0);
122      if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
123          mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, &outSlot, &outBuffer);
124          return NO_ERROR;
125      } else if (err != NO_ERROR) {
126          ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err);
127          return err;
128      }
129  
130      // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot
131      // then we may have acquired the slot we already own.  If we had released
132      // our current buffer before we call acquireBuffer then that release call
133      // would have returned STALE_BUFFER_SLOT, and we would have called
134      // freeBufferLocked on that slot.  Because the buffer slot has already
135      // been overwritten with the new buffer all we have to do is skip the
136      // releaseBuffer call and we should be in the same state we'd be in if we
137      // had released the old buffer first.
138      if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT &&
139          item.mSlot != mCurrentBufferSlot) {
140          mHasPendingRelease = true;
141          mPreviousBufferSlot = mCurrentBufferSlot;
142          mPreviousBuffer = mCurrentBuffer;
143      }
144      mCurrentBufferSlot = item.mSlot;
145      mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
146      mCurrentFence = item.mFence;
147  
148      outFence = item.mFence;
149      mHwcBufferCache.getHwcBuffer(mCurrentBufferSlot, mCurrentBuffer, &outSlot, &outBuffer);
150      outDataspace = static_cast<Dataspace>(item.mDataSpace);
151      status_t result = mHwc.setClientTarget(mDisplayId, outSlot, outFence, outBuffer, outDataspace);
152      if (result != NO_ERROR) {
153          ALOGE("error posting framebuffer: %d", result);
154          return result;
155      }
156  
157      return NO_ERROR;
158  }
159  

nextBuffer函数中:

  • 获取一个Buffer

        如果是Client合成,调用queueBuffer,queue到FrameBufferSurface的BufferQueue中。这里的acquireBufferLocked将从BufferQueue中获取一个Buffer。

  • 替换Buffer

        当前Buffer的序号mCurrentBufferSlot,当前Buffer mCurrentBuffer,对应的Fence mCurrentFence;如果新获取到的Buffer不一样,释放旧的。Buffer都被cache到mHwcBufferCache中。

  • 将FBTarget设置给HWC

        关键代码mHwc.setClientTarget。

477  status_t HWComposer::setClientTarget(DisplayId displayId, uint32_t slot,
478                                       const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
479                                       ui::Dataspace dataspace) {
480      RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
481  
482      ALOGV("%s for display %s", __FUNCTION__, to_string(displayId).c_str());
483      auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
484      auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
485      RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
486      return NO_ERROR;
487  }

        其中会把刚才acquire的GraphicBuffer连带acquireFence通过调用setClientTarget设到HWC的ClientTarget Layer。HWC进行最后合成处理的前提是CLIENT图层的acquireFence及FramebufferTarget的acquireFence都被触发。

2.2 dump分析

如下是concept上dump出来的Composition RenderSurface State的信息,

  mConsumerName=FramebufferSurface;

  consumer=[669:/system/bin/surfaceflinger]

  producer=[623:vendor.qti.hardware.display.composer-service]

由于surfaceFlinger::onComposerHalHotplug是HWC回调过来的,所以代码执行在vendor.qti.hardware.display.composer-service进程中,BufferQueueProducer::connect中记录的mConnnectedPid就是composer service的PID。

在dump BufferQueue的信息时,根据PID获取的producer name也是HWC进程。

147  void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const {
148      std::lock_guard<std::mutex> lock(mMutex);
        .....
173      int32_t pid = getpid();
174      getProcessName(mConnectedPid, producerProcName);
175      getProcessName(pid, consumerProcName);

3.Client合成

        Client端合成,本质是采用GPU进程合成,SurfaceFlinger中封装了RenderEngine进行具体的实现,相关的代码在如下位置:

frameworks/native/services/surfaceflinger/RenderEngine

        RenderEngine 是对GPU渲染的封装,包括了 EGLDisplay,EGLContext, EGLConfig,EGLSurface。注意每个Display的EGLSurface不是同一个,各自有各自的EGLSurface。

        GLES20RenderEngine 继承RenderEngine,是GELS的2.0版本实现。其Program采用ProgramCache进行cache。状态用Description进描述。

        每个BufferLayer 都有专门的Texture进行纹理的描述,GLES20RenderEngine 支持纹理贴图。合成时,将GraphicBuffer转换为纹理,进行混合

Client端GPU合成相关的流程如下:

3.1 创建 RenderEngine

RenderEngine 是在SurfaceFlinger初始化时,创建的。

Android 10:

void SurfaceFlinger::init() {
    ... ...
    getBE().mRenderEngine = RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
            hasWideColorDisplay ? RenderEngine::WIDE_COLOR_SUPPORT : 0);

Android 11:

void SurfaceFlinger::init() {
// Get a RenderEngine for the given display / config (can't fail)
906      // TODO(b/77156734): We need to stop casting and use HAL types when possible.
907      // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
908      mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(
909              renderengine::RenderEngineCreationArgs::Builder()
910                  .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
911                  .setImageCacheSize(maxFrameBufferAcquiredBuffers)
912                  .setUseColorManagerment(useColorManagement)
913                  .setEnableProtectedContext(enable_protected_contents(false))
914                  .setPrecacheToneMapperShaderOnly(false)
915                  .setSupportsBackgroundBlur(mSupportsBlur)
916                  .setContextPriority(useContextPriority
917                          ? renderengine::RenderEngine::ContextPriority::HIGH
918                          : renderengine::RenderEngine::ContextPriority::MEDIUM)
919                  .build()));

RenderEngine的初始化过程,就是GPU渲染初始化的过程,其大概的流程如下:

  1. 创建 EGLDisplay(eglGetDisplay)

  2. 初始化 EGLDisplay(eglInitialize)

  3. 选择 EGLConfig(chooseEglConfig)

  4. 获取renderableType( eglGetConfigAttrib)

  5. 初始化Context属性( contextAttributes)

  6. 创建EGLContext( eglCreateContext)

  7. 创建 PBuffer( eglCreatePbufferSurface)

  8. MakeCurrent( eglMakeCurrent这是为虚拟的PBuffercheck状态。)

  9. 创建RenderEngine( 这里,目前值支持GELS2.0,对应的Render GLES20RenderEngine)

  10. 设置设置EGL信息( 将创建的EGL对象设置到我们创建的GLES20RenderEngine中。)

27  std::unique_ptr<impl::RenderEngine> RenderEngine::create(const RenderEngineCreationArgs& args) {
28      char prop[PROPERTY_VALUE_MAX];
29      property_get(PROPERTY_DEBUG_RENDERENGINE_BACKEND, prop, "gles");
30      if (strcmp(prop, "gles") == 0) {
31          ALOGD("RenderEngine GLES Backend");
               //创建GLESRenderEngine对象
32          return renderengine::gl::GLESRenderEngine::create(args);
33      }
34      ALOGE("UNKNOWN BackendType: %s, create GLES RenderEngine.", prop);
35      return renderengine::gl::GLESRenderEngine::create(args);
36  }
std::unique_ptr<GLESRenderEngine> GLESRenderEngine::create(const RenderEngineCreationArgs& args) {
205      // initialize EGL for the default display
            //获得EGDLdisplay
206      EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
207      if (!eglInitialize(display, nullptr, nullptr)) {
208          LOG_ALWAYS_FATAL("failed to initialize EGL");
209      }
210       //查询EGL版本信息
211      const auto eglVersion = eglQueryStringImplementationANDROID(display, EGL_VERSION);
212      if (!eglVersion) {
213          checkGlError(__FUNCTION__, __LINE__);
214          LOG_ALWAYS_FATAL("eglQueryStringImplementationANDROID(EGL_VERSION) failed");
215      }
216          //查询EGL支持哪些扩展
217      const auto eglExtensions = eglQueryStringImplementationANDROID(display, EGL_EXTENSIONS);
218      if (!eglExtensions) {
219          checkGlError(__FUNCTION__, __LINE__);
220          LOG_ALWAYS_FATAL("eglQueryStringImplementationANDROID(EGL_EXTENSIONS) failed");
221      }
222          //根据支持的扩展设置属性,目前来看都为true
223      GLExtensions& extensions = GLExtensions::getInstance();
224      extensions.initWithEGLStrings(eglVersion, eglExtensions);
225  
226      // The code assumes that ES2 or later is available if this extension is
227      // supported.
228      EGLConfig config = EGL_NO_CONFIG;
229      if (!extensions.hasNoConfigContext()) {
230          config = chooseEglConfig(display, args.pixelFormat, /*logConfig*/ true);
231      }
232  
233      bool useContextPriority =
234              extensions.hasContextPriority() && args.contextPriority == ContextPriority::HIGH;
235      EGLContext protectedContext = EGL_NO_CONTEXT;
236      if (args.enableProtectedContext && extensions.hasProtectedContent()) {
237          protectedContext = createEglContext(display, config, nullptr, useContextPriority,
238                                              Protection::PROTECTED);
239          ALOGE_IF(protectedContext == EGL_NO_CONTEXT, "Can't create protected context");
240      }
241        //创建非protect的EglContext
242      EGLContext ctxt = createEglContext(display, config, protectedContext, useContextPriority,
243                                         Protection::UNPROTECTED);
244  
245      // if can't create a GL context, we can only abort.
246      LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed");
247  
248      EGLSurface dummy = EGL_NO_SURFACE;
            //支持该属性,不走if逻辑
249      if (!extensions.hasSurfacelessContext()) {
250          dummy = createDummyEglPbufferSurface(display, config, args.pixelFormat,
251                                               Protection::UNPROTECTED);
252          LOG_ALWAYS_FATAL_IF(dummy == EGL_NO_SURFACE, "can't create dummy pbuffer");
253      }
            //eglMakeCurrent将EGLDisplay和EglContext绑定
254      EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt);
255      LOG_ALWAYS_FATAL_IF(!success, "can't make dummy pbuffer current");
256      extensions.initWithGLStrings(glGetString(GL_VENDOR), glGetString(GL_RENDERER),
257                                   glGetString(GL_VERSION), glGetString(GL_EXTENSIONS));
258  
259      EGLSurface protectedDummy = EGL_NO_SURFACE;
260      if (protectedContext != EGL_NO_CONTEXT && !extensions.hasSurfacelessContext()) {
261          protectedDummy = createDummyEglPbufferSurface(display, config, args.pixelFormat,
262                                                        Protection::PROTECTED);
263          ALOGE_IF(protectedDummy == EGL_NO_SURFACE, "can't create protected dummy pbuffer");
264      }
265  
266      // now figure out what version of GL did we actually get
267      GlesVersion version = parseGlesVersion(extensions.getVersion());
268  
269      LOG_ALWAYS_FATAL_IF(args.supportsBackgroundBlur && version < GLES_VERSION_3_0,
270          "Blurs require OpenGL ES 3.0. Please unset ro.surface_flinger.supports_background_blur");
271  
272      // initialize the renderer while GL is current
273      std::unique_ptr<GLESRenderEngine> engine;
274      switch (version) {
275          case GLES_VERSION_1_0:
276          case GLES_VERSION_1_1:
277              LOG_ALWAYS_FATAL("SurfaceFlinger requires OpenGL ES 2.0 minimum to run.");
278              break;
279          case GLES_VERSION_2_0:
280          case GLES_VERSION_3_0:
281              engine = std::make_unique<GLESRenderEngine>(args, display, config, ctxt, dummy,
282                                                          protectedContext, protectedDummy);
283              break;
284      }
        .....
294      return engine;
295  }

        上述在启动之初就搭建好了EGL环境,并将当前线程与context绑定,为后面使用gl命令做好准备,然后创建了ImageManager线程,这个线程是管理输入Buffer的EGLImage,然后创建了GLFrameBuffer,用来操作输出的buffer。

3.2 应用buffer传入RenderEngine

        输入的Buffer是通过BufferLayer的prepareClientComposition()方法设到RenderEngine里面。

144  std::optional<compositionengine::LayerFE::LayerSettings> BufferLayer::prepareClientComposition(
145          compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) {
146      ATRACE_CALL();
147  
148      std::optional<compositionengine::LayerFE::LayerSettings> result =
149              Layer::prepareClientComposition(targetSettings);
150      if (!result) {
151          return result;
152      }
153  
        .....
189      const State& s(getDrawingState());
           //应用queue过来的buffer
190      layer.source.buffer.buffer = mBufferInfo.mBuffer;
191      layer.source.buffer.isOpaque = isOpaque(s);
            //acquirefence
192      layer.source.buffer.fence = mBufferInfo.mFence;
             //创建BufferQueueLayer时创建的texture ID
193      layer.source.buffer.textureName = mTextureName;
194      layer.source.buffer.usePremultipliedAlpha = getPremultipledAlpha();
195      layer.source.buffer.isY410BT2020 = isHdrY410();
        .......
268      return layer;
269  }

        至此,SurfaceFlinger调到RenderEngine里面,SurfaeFlinger的display和outputlayer的

        上面输入的纹理是在创建BufferQueueLayer时就已经对各个layer创建了纹理ID,为这里GPU合成做准备。

 
4852  status_t SurfaceFlinger::createBufferQueueLayer(const sp<Client>& client, std::string name,
4853                                                  uint32_t w, uint32_t h, uint32_t flags,
4854                                                  LayerMetadata metadata, PixelFormat& format,
4855                                                  sp<IBinder>* handle,
4856                                                  sp<IGraphicBufferProducer>* gbp,
4857                                                  sp<Layer>* outLayer) {
4858      // initialize the surfaces
4859      switch (format) {
4860      case PIXEL_FORMAT_TRANSPARENT:
4861      case PIXEL_FORMAT_TRANSLUCENT:
4862          format = PIXEL_FORMAT_RGBA_8888;
4863          break;
4864      case PIXEL_FORMAT_OPAQUE:
4865          format = PIXEL_FORMAT_RGBX_8888;
4866          break;
4867      }
4868  
4869      sp<BufferQueueLayer> layer;
4870      LayerCreationArgs args(this, client, std::move(name), w, h, flags, std::move(metadata));
4871      args.textureName = getNewTexture();
            .......
4887      ALOGE_IF(err, "createBufferQueueLayer() failed (%s)", strerror(-err));
4888      return err;
4889  }

866  uint32_t SurfaceFlinger::getNewTexture() {
867      {
868          std::lock_guard lock(mTexturePoolMutex);
869          if (!mTexturePool.empty()) {
870              uint32_t name = mTexturePool.back();
871              mTexturePool.pop_back();
872              ATRACE_INT("TexturePoolSize", mTexturePool.size());
873              return name;
874          }
875  
876          // The pool was too small, so increase it for the future
877          ++mTexturePoolSize;
878      }
879  
880      // The pool was empty, so we need to get a new texture name directly using a
881      // blocking call to the main thread
882      return schedule([this] {
883                 uint32_t name = 0;
884                 getRenderEngine().genTextures(1, &name);
885                 return name;
886             })
887              .get();
888  }

Android中的SurfaceView合成**主要涉及到SurfaceFlinger和硬件合成(HWC)等组件的配合工作**。 在Android系统中,SurfaceView是一种特殊的视图,它使用一个独立的绘图Surface来渲染内容。这个Surface由SurfaceFlinger服务直接管理,而不是通过常规的视图层次结构。以下是一些关键点: 1. **SurfaceFlinger的角色**:SurfaceFlinger是一个系统服务,负责接受来自多个源的数据缓冲区,对它们进行合成,然后发送到显示设备。它处理屏幕上的各种层,包括状态栏、导航栏以及应用界面等。 2. **合成方式**:合成可以在Client端(使用GPU)或Device端(使用HWC硬件)完成。SurfaceFlinger主要负责Client端的合成工作,通过RenderEngine利用GPU来进行合成。 3. **SurfaceView的优势**:使用SurfaceView进行渲染时,可以直接将缓冲区合成到屏幕上,这样可以避免额外的合成步骤,提高效率。 4. **HWC的作用**:Hardware Composer HAL(HWC)是与SurfaceFlinger配合使用的硬件抽象层,它负责确定合成缓冲区的最有效方法,并实际执行合成过程。 5. **合成流程**:当Buffer放入BufferQueue队列后,Consumer端的FrameListener会通过frameAvailableListener通知Consumer,然后进行相应的处理。 综上所述,Android SurfaceView的合成是一个复杂的过程,涉及多个系统组件和服务的协同工作。了解这些机制有助于更好地理解Android图形系统的工作原理。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值