总结一下对buffer的学习体会

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/daojin505/article/details/76816868

很多人讲lockcanvas,没有讲清楚到底是怎么回事。

 

问题1:lockcanvas出来的canvas到底是什么东西? 里面的位图到底是什么?

问题2:整个android系统到底有多少个Buffer?android的多个进程又是通过什么方式来共享buffer的。

 

先讲一个静态基本概念:

ISurfaceTexture 是一个很关键的概念,建立了客户端Buffer与服务端的连接通道。

在ISurfaceTexture.h文件中可以看到另外一个本地接口BnSurfaceTexture,这个是作为服务器端的接口而存在的。

 

最重要的是如下几个接口。

 

    virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0;

  virtual status_t dequeueBuffer(int *slot, uint32_t w, uint32_t h,
            uint32_t format, uint32_t usage) = 0;

   virtual status_t queueBuffer(int slot, int64_t timestamp,
            uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) = 0;
    virtual void cancelBuffer(int slot) = 0;

 这个四个接口android的帧缓冲的管理方式的关键所在。

Surface_lockCanvas 是个很关键的方法。在android_view_Surface.cpp中:

 按照本人的分析风格,只看关键部分。其余全删除。

static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect)
{
    status_t err = surface->lock(&info, &dirtyRegion);
    SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas);
    SkBitmap bitmap;
     bitmap.setPixels(info.bits);
    nativeCanvas->setBitmapDevice(bitmap);  return canvas;}

非常简单的几句代码,就得到了一个canvas。canvas中的bitmap是从info得到的Pixels。

   所以看到这里。就必须去看这一句。

 

    status_t err = surface->lock(&info, &dirtyRegion);

在目录 frameworks/base/libs/gui/Surface.cpp中,有这么几行:

   

 按照本人的分析风格,只看关键部分。其余全删除。

status_t Surface::lock(SurfaceInfo* other, Region* inOutDirtyRegion) {
    status_t err = SurfaceTextureClient::lock(&outBuffer, inOutDirtyBounds);
}

 这几行代码再简单不过了,只是继续lock而已,一次转发。

 

在目录 frameworks/base/libs/gui/SurfaceTextureClient.cpp中,有这么几行

 按照本人的分析风格,只看关键部分。其余全删除。这段代码重要的不是lockBuffer,lockBuffer的附加效果才是最重要的,也就是dequeueBuffer。

 

status_t SurfaceTextureClient::lock(
        ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
{
        int err = SurfaceTextureClient::connect(NATIVE_WINDOW_API_CPU);
        ANativeWindowBuffer* out;
    status_t err = dequeueBuffer(&out);
        sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
        err = lockBuffer(backBuffer.get());                      
const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
             copyBlt(backBuffer, frontBuffer, copyback);
            void* vaddr;
            status_t res = backBuffer->lock(
                    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
                    newDirtyRegion.bounds(), &vaddr);
            mLockedBuffer = backBuffer;
            outBuffer->width  = backBuffer->width;
            outBuffer->height = backBuffer->height;
            outBuffer->stride = backBuffer->stride;
            outBuffer->format = backBuffer->format;
            outBuffer->bits   = vaddr;
        }
    }
    return err;
}

 上面代码中的lockBuffer一看就猜个大概就是锁住一个临界区域。

int SurfaceTextureClient::lockBuffer(android_native_buffer_t* buffer) {
    LOGV("SurfaceTextureClient::lockBuffer");
    Mutex::Autolock lock(mMutex);
    return OK;
}

 

文件在frameworks/base/include/gui/ISurfaceTexture.h,有几个成员函数:

   virtual status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) = 0;

  virtual status_t dequeueBuffer(int *slot, uint32_t w, uint32_t h,
            uint32_t format, uint32_t usage) = 0;

   virtual status_t queueBuffer(int slot, int64_t timestamp,
            uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) = 0;
    virtual void cancelBuffer(int slot) = 0;

    这仅仅是一些客户端的接口,最终通过

 

class BnSurfaceTexture : public BnInterface<ISurfaceTexture>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};

 

的子类 SurfaceTexture,文件在 目录 frameworks/base/libs/gui/SurfaceTexture.cpp

和frameworks/base/include/gui/SurfaceTexture.h

   

展开阅读全文

没有更多推荐了,返回首页