return (status_t)err; }
我们继续看doComposeSurfaces函数,下面这个函数当cur!=end代表起码有两个以上图层,然后遍历图层,当layer是HWC_FRAMEBUFFER代表是需要egl合成的,而HWC_FRAMEBUFFER_TARGET是egl合成后使用的直接就跳了,HWC_CURSOR_OVERLAY和HWC_OVERLAY是用HWC模块(硬件合成)的,也就不用调用Layer的draw方法。而如果图层只要1个或者没有,那么直接使用egl合成。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 HWComposer::LayerListIterator cur = hwc.begin(id); const HWComposer::LayerListIterator end = hwc.end(id); ......
const Vector< sp
const Transform& tr = hw->getTransform(); if (cur != end) { //代表起码有两个以上图层 // we're using h/w composer
for (size_t i=0 ; i
const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); if (!clip.isEmpty()) {
switch (cur->getCompositionType()) { case HWC_CURSOR_OVERLAY: case HWC_OVERLAY: {
const Layer::State& state(layer->getDrawingState()); if ((cur->getHints() & HWC_HINT_CLEAR_FB) && i
&& layer->isOpaque(state) && (state.alpha == 0xFF) && hasGlesComposition) {
// never clear the very first layer since we're // guaranteed the FB is already cleared layer->clearWithOpenGL(hw, clip); }
break; }
case HWC_FRAMEBUFFER: {
layer->draw(hw, clip);//只有是HWC_FRAMEBUFFER才会调用Layer的draw合成
break; }
case HWC_FRAMEBUFFER_TARGET: {
// this should not happen as the iterator shouldn't // let us get there.
ALOGW(\found in hwc list
(index=%zu)\
break; } } }
layer->setAcquireFence(hw, *cur); } } else {
// we're not using h/w composer
for (size_t i=0 ; i const sp tr.transform(layer->visibleRegion))); if (!clip.isEmpty()) { layer->draw(hw, clip); } } } // disable scissor at the end of the frame engine.disableScissor(); return true; } Layer的draw我们就不看了主要是使用egl合成纹理,但是有一点疑问,我们从来没有把layer中的mActiveBuffer放到egl中去,那么egl又是怎么合成各个layer的呢,我想肯定客户进程在绘制各个layer的时候,也是用egl绘制的,所有后面合成的时候egl有各个layer的buffer。 后面我们再来看下DisplayDevice::swapBuffers函数,是使用eglSwapBuffers来把egl合成的数据放到mSurface中去。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 void DisplayDevice::swapBuffers(HWComposer& hwc) const { // We need to call eglSwapBuffers() if: // (1) we don't have a hardware composer, or // (2) we did GLES composition this frame, and either // (a) we have framebuffer target support (not present on legacy // devices, where HWComposer::commit() handles things); or // (b) this is a virtual display if (hwc.initCheck() != NO_ERROR || (hwc.hasGlesComposition(mHwcDisplayId) && (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) { EGLBoolean success = eglSwapBuffers(mDisplay, mSurface); if (!success) { EGLint error = eglGetError(); if (error == EGL_CONTEXT_LOST || mType == DisplayDevice::DISPLAY_PRIMARY) { LOG_ALWAYS_FATAL(\ mDisplay, mSurface, error); } else { ALOGE(\ mDisplay, mSurface, error); } } } else if(hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL) { EGLBoolean success = eglSwapBuffersVIV(mDisplay, mSurface); if (!success) { EGLint error = eglGetError(); ALOGE(\ mDisplay, mSurface, error); } } status_t result = mDisplaySurface->advanceFrame(); if (result != NO_ERROR) { ALOGE(\ mDisplayName.string(), result); } } 二、FramebufferSurface收到egl合成数据 之前分析DisplayDevice时候,还分析了FramebufferSurface,我们这里再来看下。 在SurfaceFlinger.cpp中的init函数,在创建DisplayDevice之前,我们先调用createBufferQueue来创建了一个buffer的生产者和消费者,然后把消费者放入了FramebufferSurface,生产者放入了DisplayDevice中。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 sp BufferQueue::createBufferQueue(&producer, &consumer, new GraphicBufferAlloc()); sp int32_t hwcId = allocateHwcDisplayId(type); sp type, hwcId, mHwc->getFormat(hwcId), isSecure, token, fbs, producer, mRenderEngine->getEGLConfig()); 我们先来看生产者,下面是DisplayDevice的构造函数,生产者作为参数直接新建了一个Surface,然后把这个Surface作为参数调用eglCreateWindowSurface返回的就是mSurface,之前我们分析最后egl合成的数据时调用eglSwapBuffers并且把数据放到mSurface,这样最后肯定就到消费者(FramebufferSurface)去了。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 mNativeWindow = new Surface(producer, false); ANativeWindow* const window = mNativeWindow.get(); /* * Create our display's surface */ EGLSurface surface; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (config == EGL_NO_CONFIG) { config = RenderEngine::chooseEglConfig(display, format); } surface = eglCreateWindowSurface(display, config, window, NULL); 最后到消费者那端的onFrameAvailable,也就是FramebufferSurface的onFrameAvailable中,我们现在来分析下这个过程,也就解答了一个onFrameAvailable的疑惑。 FramebufferSurface的父类是ConsumerBase类,我们来看其构造函数。先是构造了mConsumer,这里其实就是BufferQueueConsumer类,后面调用了其consumerConnect方法。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 ConsumerBase::ConsumerBase(const sp mAbandoned(false), mConsumer(bufferQueue) { mName = String8::format(\ wp sp status_t err = mConsumer->consumerConnect(proxy, controlledByApp); if (err != NO_ERROR) { CB_LOGE(\ strerror(-err), err); } else { mConsumer->setConsumerName(mName); } } 我们来看下BufferQueueConsumer类的consumerConnect方法,就是调用了connect方法。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 virtual status_t consumerConnect(const sp return connect(consumer, controlledByApp); } 这个方法中将mCore->mConsumerListener = consumerListener,这个mCore就是BufferQueueCore类。我们再从ConsumerBase的构造函数看这个consumerListener参数其实就是FrameBufferSurface对象本身。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 status_t BufferQueueConsumer::connect( const sp if (consumerListener == NULL) { BQ_LOGE(\ return BAD_VALUE; } BQ_LOGV(\ controlledByApp ? \ Mutex::Autolock lock(mCore->mMutex); if (mCore->mIsAbandoned) { BQ_LOGE(\ return NO_INIT; } mCore->mConsumerListener = consumerListener;//设置回调 mCore->mConsumerControlledByApp = controlledByApp; return NO_ERROR; } 我们再看BufferQueueProducer::queueBuffer函数,这个函数应该是生产者已经使用好buffer了,这个使用会调用如下代码这个listener就是BufferQueueCore的mConsumerListener,传输的数据时BufferItem。再传之前把BufferItem的mGraphicBuffer清了,因为消费者可以自己获取buffer,不用通过BufferItem传。 [cpp] view plain copy 在CODE上查看代码片派生到我的代码片 item.mGraphicBuffer.clear(); item.mSlot = BufferItem::INVALID_BUFFER_SLOT; // Call back without the main BufferQueue lock held, but with the callback // lock held so we can ensure that callbacks occur in order