Android绘制系统


基于Android4.4源码

SurfaceFlinger绘制测试Demo

在Android系统中SurfaceFlinger是窗口系统,Surface代表一个窗口。SurfaceFlinger采用C/S架构,需通过客户端与SurfaceFlinger通信,对窗口进行相关操作。使用SurfaceFlinger绘制图像,首先需要创建一个Surface对象,再对Surface对象进行操作即可。具体有以下步骤

  1. 创建Surface对象
  2. 调用surface->lock对象获取Buffer
  3. 将图像数据填充到Buffer
  4. 调用surface->unlockAndPost发送数据到缓存
//step1
sp<SurfaceControl> control = mSession->createSurface(String8("MyWindow"),  width, height, PIXEL_FORMAT_RGB_565);
sp<Surface> s = control->getSurface();

//step2
ANativeWindow_Buffer outBuffer;
Rect dirtyRect(0, 0, 480, 320);
status_t err = surface->lock(&outBuffer, &dirtyRect);

//step3
SkBitmap bitmap;
ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
bitmap.setConfig(convertPixelFormat(outBuffer.format), outBuffer.width, outBuffer.height, bpr);
SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap));
//相关绘制图像代码
.....
//step4
surface->unlockAndPost();

SurfaceFlinger系统工作流程

1、客户端侧相关实现

1. 创建SurfaceControl

SurfaceControl由SurfaceComposerClient::createSurface方法生成,在其内部调用了Client::createSurface方法,获取到了IGraphicBufferProducer代理对象,该对象即BufferQueue,handle是SurfaceFlinger层的Layer对象,并将这两个参数作为形参传递给了SurfaceControl的构造函数,生成了一个SurfaceControl对象。

sp<SurfaceControl> control = mSession->createSurface(String8("MyWindow"),  width, height, PIXEL_FORMAT_RGB_565);

SurfaceComposerClient.cpp文件实现如下

//SurfaceComposerClient.cpp
sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
{
    sp<SurfaceControl> sur;
    if (mStatus == NO_ERROR) {
        sp<IBinder> handle;
        sp<IGraphicBufferProducer> gbp;
        status_t err = mClient->createSurface(name, w, h, format, flags,  &handle, &gbp);
        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
        if (err == NO_ERROR) {
            sur = new SurfaceControl(this, handle, gbp);
        }
    }
    return sur;
}
2. 创建Surface对象

该对应由SurfaceControl::getSurface方法生成,将mGrahicBufferProducer对象(即BufferQueue)传递给Surface的构造函数,生成一个Surface对象。

sp<Surface> s = control->getSurface();

SurfaceControl.cpp实现如下

//SurfaceControl.cpp
sp<Surface> SurfaceControl::getSurface() const
{
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == 0) {
        // This surface is always consumed by SurfaceFlinger, so the
        // producerControlledByApp value doesn't matter; using false.
        mSurfaceData = new Surface(mGraphicBufferProducer, false);
    }
    return mSurfaceData;
}

2、服务端侧相关实现

1. 创建Layer对象

调用Client::createSurface方法会生成一个Layer对象。Client通过进程通信调用SurfaceFlinger::createLayer方法,根据类型创建何种类型Layer,最终new出来一个Layer对象。Layer内部会生成一个BufferQueue对象,并将BufferQueue的代理对象返回给客户端,客户端相关图像由BufferQueue传递给Layer,交给SurfaceFlinger进行相关合成送显。
Layer对象实现了SurfaceFlingerConsumer::FrameAvailableListener,并在创建BufferQueue时进行注册,当BufferQueue有数据时,会回调Layer的onFrameAvailable方法。

//Client.cpp
status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
{
    result = flinger->createLayer(name, client, w, h, format, flags, handle, gbp);
}

//SurfaceFlinger.cpp
status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client, const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format, sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
{
    *outLayer = new Layer(this, client, name, w, h, flags);
    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
    if (err == NO_ERROR) {
        *handle = (*outLayer)->getHandle();
        //BufferQueue
        *gbp = (*outLayer)->getBufferQueue();
    }
    return err;
}

Layer创建BufferQueue对象,并将自己注册到BufferQueue,当BufferQueue有数据时可及时响应。

//Layer.cpp
void Layer::onFirstRef() {
    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    mBufferQueue = new SurfaceTextureLayer(mFlinger);
    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
    //注册有数据时回调
    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
    mSurfaceFlingerConsumer->setName(mName);
}
2. 数据合成

Layer的onFrameAvailable方法会给SurfaceFlinger发消息,最终SurfaceFlinger会调用handleMessageRefresh方法进行Layer合成送显等操作。

//SurfaceFlinger.cpp
void SurfaceFlinger::handleMessageRefresh() {
    ATRACE_CALL();
    preComposition();
    rebuildLayerStacks();
    setUpHWComposer();
    doDebugFlashRegions();
    doComposition();
    postComposition();
}

void SurfaceFlinger::preComposition()
{
    bool needExtraInvalidate = false;
    const LayerVector& layers(mDrawingState.layersSortedByZ);
    const size_t count = layers.size();
    for (size_t i=0 ; i<count ; i++) {
        if (layers[i]->onPreComposition()) {
            needExtraInvalidate = true;
        }
    }
    if (needExtraInvalidate) {
        signalLayerUpdate();
    }
}


void SurfaceFlinger::setUpHWComposer() {
    HWComposer& hwc(getHwComposer());
    if (hwc.initCheck() == NO_ERROR) {
        // set the per-frame data
        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
            sp<const DisplayDevice> hw(mDisplays[dpy]);
                for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
                    /*
                     * update the per-frame h/w composer data for each layer
                     * and build the transparent region of the FB
                     */
                    const sp<Layer>& layer(currentLayers[i]);
                    //将Layer的数据传递给DisplayService
                    layer->setPerFrameData(hw, *cur);
                }
            }
        }

        status_t err = hwc.prepare();
        ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));

        for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
            sp<const DisplayDevice> hw(mDisplays[dpy]);
            hw->prepareFrame(hwc);
        }
    }
}

void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
{   
        // we're using h/w composer
        for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
            const sp<Layer>& layer(layers[i]);
            const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
            if (!clip.isEmpty()) {
                switch (cur->getCompositionType()) {
                    case HWC_FRAMEBUFFER: {
                    	//调用Layer::draw方法进行绘制
                        layer->draw(hw, clip);
                        break;
                    }
                }
            }
            layer->setAcquireFence(hw, *cur);
        }
}

void SurfaceFlinger::postComposition()
{
    const LayerVector& layers(mDrawingState.layersSortedByZ);
    const size_t count = layers.size();
    for (size_t i=0 ; i<count ; i++) {
        layers[i]->onPostComposition();
    }
}   

最终会调用Layer的onDraw方法,使用DisplayDevice进行绘制。
SurfaceFlingerConsumer继承GLConsumer内部持有Layer的BufferQueue,即给上层Surface使用的BufferQueue。

//Layer.cpp
void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
{
    // Bind the current buffer to the GL texture, and wait for it to be
    // ready for us to draw into.
    status_t err = mSurfaceFlingerConsumer->bindTextureImage();
    RenderEngine& engine(mFlinger->getRenderEngine());
    drawWithOpenGL(hw, clip);
    engine.disableTexturing();
}

//SurfaceFlingerConsumer.cpp
status_t SurfaceFlingerConsumer::bindTextureImage()
{
    Mutex::Autolock lock(mMutex);

    return bindTextureImageLocked();
}
//Consumer.cpp
status_t GLConsumer::bindTextureImageLocked() {
    EGLImageKHR image = mEglSlots[mCurrentTexture].mEglImage;
    glEGLImageTargetTexture2DOES(mTexTarget, (GLeglImageOES)image);
}
status_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item)
{
    int buf = item.mBuf;

    // If the mEglSlot entry is empty, create an EGLImage for the gralloc
    // buffer currently in the slot in ConsumerBase.
    //
    // We may have to do this even when item.mGraphicBuffer == NULL (which
    // means the buffer was previously acquired), if we destroyed the
    // EGLImage when detaching from a context but the buffer has not been
    // re-allocated.
    if (mEglSlots[buf].mEglImage == EGL_NO_IMAGE_KHR) {
        EGLImageKHR image = createImage(mEglDisplay, mSlots[buf].mGraphicBuffer, item.mCrop);
        mEglSlots[buf].mEglImage = image;
        mEglSlots[buf].mCropRect = item.mCrop;
    }

    // Do whatever sync ops we need to do before releasing the old slot.
    err = syncForReleaseLocked(mEglDisplay);
 
    // Update the GLConsumer state.
    mCurrentTexture = buf;
    mCurrentTextureBuf = mSlots[buf].mGraphicBuffer;
    mCurrentCrop = item.mCrop;
    mCurrentTransform = item.mTransform;
    mCurrentScalingMode = item.mScalingMode;
    mCurrentTimestamp = item.mTimestamp;
    mCurrentFence = item.mFence;
    mCurrentFrameNumber = item.mFrameNumber;
}

Region Layer::latchBuffer(bool& recomputeVisibleRegions)
{
    status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r);
}   

status_t SurfaceFlingerConsumer::updateTexImage(BufferRejecter* rejecter)
{
    BufferQueue::BufferItem item;

    // Acquire the next buffer.
    // In asynchronous mode the list is guaranteed to be one buffer
    // deep, while in synchronous mode we use the oldest buffer.
    err = acquireBufferLocked(&item, computeExpectedPresent()); 
    // Release the previous buffer.
    err = updateAndReleaseLocked(item);
}    

status_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item)
{
    status_t err = NO_ERROR;
    int buf = item.mBuf;
    // If the mEglSlot entry is empty, create an EGLImage for the gralloc
    // buffer currently in the slot in ConsumerBase.
    //
    // We may have to do this even when item.mGraphicBuffer == NULL (which
    // means the buffer was previously acquired), if we destroyed the
    // EGLImage when detaching from a context but the buffer has not been
    // re-allocated.
    if (mEglSlots[buf].mEglImage == EGL_NO_IMAGE_KHR) {
        EGLImageKHR image = createImage(mEglDisplay, mSlots[buf].mGraphicBuffer, item.mCrop);
        mEglSlots[buf].mEglImage = image;
        mEglSlots[buf].mCropRect = item.mCrop;
    }
  • 23
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值