android中图像的显示是通过HWComposer合成的,(不支持硬件composer的不考虑,现在基本都支持)。 硬件支持合成就是你输入多路视频,图像信号,出来一路合成好的数据。
硬件合成只支持有限的记录信号,所有如何存在太多的信号,需要先通过软件进行合成,surfaceflinger是通过gpu合成的。
SurfaceFlinger::init(){
//包装了硬件合成的硬件抽象层
mHwc
=
new
HWComposer
(
this
,
*
static_cast
<
HWComposer
::
EventHandler
*>(
this
));
//初始化部分
for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
bool isSecure = true;
createBuiltinDisplayLocked(type);
wp<IBinder> token = mBuiltinDisplays[i];
sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc());
//数据加工好了以后FramebufferSurface内部把他送给HWComposer
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, bq);
//数据生产者,每个屏幕都有一个,以后在这个屏幕上的绘制都是操作了bq
//DisplayDevice就是bufferqueue的生产者
sp<DisplayDevice> hw = new DisplayDevice(this, type, allocateHwcDisplayId(type), isSecure, token,
fbs, bq,
mEGLConfig);
if (i > DisplayDevice::DISPLAY_PRIMARY) {
hw->acquireScreen();
}
mDisplays.add(token, hw);
}
}
}
VSYNC信号来了后会触发doComposition的调用
void SurfaceFlinger::doComposition() {
const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
const sp<DisplayDevice>& hw(mDisplays[dpy]);
if (hw->canDraw()){
//这个屏幕是否可以绘制,有可能屏幕关闭了,那就没必要绘制了
const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
//绘制到硬件抽象层的frametarget中
doDisplayComposition(hw, dirtyRegion);
}
hw->compositionComplete();
}
//硬件抽象composer进行合成
postFramebuffer();
}
void SurfaceFlinger::postFramebuffer()
{
HWComposer& hwc(getHwComposer());
if (hwc.initCheck() == NO_ERROR) {
if (!hwc.supportsFramebufferTarget()) {
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
}
//上面DisplayDevice已经把需要glex合成的图像层,合成到FramebufferTarget中了
//调用硬件合成,
hwc.commit();
}
}
status_t
HWComposer
::
commit
() {
if
(
mHwc
) {
//硬件合成到屏幕上
err
=
mHwc
->
set
(
mHwc
,
mNumDisplays
,
mLists
);
}
return
(
status_t
)
err
;
}
//绘制到bufferqueue
void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
const Region& inDirtyRegion)
{
//绘制到
FrambufferSurface的后台缓冲区中
doComposeSurfaces(hw, dirtyRegion);
//opengles 绘制到FrambufferSurface的BufferQueue中
//反转缓冲区
hw->swapBuffers(getHwComposer());
}
void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
{
RenderEngine& engine(getRenderEngine());
bool hasGlesComposition = hwc.hasGlesComposition(id);
if (hasGlesComposition) {
//把当前屏幕的eglsurface设置未当前表面,以后就绘制到这里面了啊
if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) {
return;
}
}
const size_t count = layers.size();
for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
const sp<Layer>& layer(layers[i]);
//一层一层的绘制到hw的EglSurface中,硬件合成的层不需要绘制的
layer->draw(hw, clip);
}
}
Surfaceflinnger中创建的FramebufferSurface,Bufferqueue的消费者
class FramebufferSurface : public ConsumerBase, public DisplaySurface
//ConsumerBase包装了BufferQueue的消费监听逻辑,只要重载onFrameAvailable,onBuffersReleased
//有数据要消费的时候会主动调用
ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& consumer, bool controlledByApp ){
//监听bufferqueue是否准备好数据了
wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
}
void ConsumerBase::onFrameAvailable() {
sp<FrameAvailableListener> listener;
{
Mutex::Autolock lock(mMutex);
listener = mFrameAvailableListener.promote();
}
//转发到外部通知一下
if (listener != NULL) {
listener->onFrameAvailable();
}
}
void ConsumerBase::onBuffersReleased() {
Mutex::Autolock lock(mMutex);
//当buffer消费完成后,会清空本类保存的缓存数据
uint32_t mask = 0;
mConsumer->getReleasedBuffers(&mask);
for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
if (mask & (1 << i)) {
freeBufferLocked(i);
}
}
}
status_t ConsumerBase::acquireBufferLocked(BufferQueue::BufferItem *item,
nsecs_t presentWhen) {
//获取准备好的数据
status_t err = mConsumer->acquireBuffer(item, presentWhen);
if (err != NO_ERROR) {
return err;
}
//保存到当前类的缓存中
if (item->mGraphicBuffer != NULL) {
mSlots[item->mBuf].mGraphicBuffer = item->mGraphicBuffer;
}
mSlots[item->mBuf].mFrameNumber = item->mFrameNumber;
mSlots[item->mBuf].mFence = item->mFence;
return OK;
}
-------------------------------------------------------------------------------
class FramebufferSurface : public ConsumerBase,
public DisplaySurface {
void FramebufferSurface::onFrameAvailable() {//重载了这个方法,
//获取准备好的buffer
sp<GraphicBuffer> buf;
sp<Fence> acquireFence;
status_t err = nextBuffer(buf, acquireFence);
if (err != NO_ERROR) {
return;
}
//buffer添加到HWComposer的FrameBufferTagert中
err = mHwc.fbPost(mDisplayType, acquireFence, buf);
}
status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
Mutex::Autolock lock(mMutex);
//获取准备好的buffer
BufferQueue::BufferItem item;
status_t err = acquireBufferLocked(&item, 0);
//保存到当前值中,
mCurrentBufferSlot = item.mBuf;
mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
outFence = item.mFence;
outBuffer = mCurrentBuffer;
return NO_ERROR;
}
//DisplayDevice数据的生产者
DisplayDevice::DisplayDevice(
const sp<SurfaceFlinger>& flinger,
DisplayType type,
int32_t hwcId,
bool isSecure,
const wp<IBinder>& displayToken,
const sp<DisplaySurface>& displaySurface,
const sp<IGraphicBufferProducer>& producer,
EGLConfig config)
{
//通过这个producer创建一个本地窗口mNativeWindow
mNativeWindow = new Surface(producer, false);
ANativeWindow* const window = mNativeWindow.get();
int format;
window->query(window, NATIVE_WINDOW_FORMAT, &format);
if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
window->setSwapInterval(window, 0);
EGLSurface surface;
EGLint w, h;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
//本地窗口创建surface,以后操作这个surface会间接填充BufferQueue
// 需要eglSwapeBuffer(display,surface)
//
surface = eglCreateWindowSurface(display, config, window, NULL);
eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth);
eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
mDisplay = display;
mSurface = surface;
mFormat = format;
mPageFlipCount = 0;
mViewport.makeInvalid();
mFrame.makeInvalid();
}