Android LayerBuffer

  已知Surface对应着SurfaceFlinger管理的一个Layer,而LayerBuffer在C++和java空间中分别对应着ISurfaceComposer.h中的ePushBuffers与Surface.java中的PUSH_BUFFERS类型的Surface。创建LayerBuffer时,会先看是否支持硬件copybit加速:

       if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {  
        copybit_open(module, &mLayer.mBlitEngine);  
    }  
    copybit_device_t* copybit = mLayer.mBlitEngine;  
    ... ...  
    err = initTempBuffer();  
    const NativeBuffer& dst(mTempBuffer);  
    region_iterator clip(Region(Rect(dst.crop.r, dst.crop.b)));  
    copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);  
    copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);  
    copybit->set_parameter(copybit, COPYBIT_DITHER,  COPYBIT_ENABLE);  
    err = copybit->stretch(copybit, &dst.img, &src.img, &dst.crop, &src.crop, &clip); 
否则,就使用mTextureManager.loadTexture(&mTexture, dirty, t)通过glTexSubImage2D或glTexImage2D操作把数据渲染到mTexture贴图上面去的。也就是由OpenGL来做resize。/frameworks/base/services/surfaceflinger/LayerBuffer.cpp

    GGLSurface t;
    t.version = sizeof(GGLSurface);
    t.width = src.crop.r;
    t.height = src.crop.b;
    t.stride = src.img.w;
    t.vstride = src.img.h;
    t.format = src.img.format;
    t.data = (GGLubyte*) src.img.base;
    const Region dirty(Rect(t.width, t.height));
    mTextureManager.loadTexture(&mTexture, dirty, t);
   
    resize操作完成以后,mTexture会被绘制到SurfaceFlinger的共享显存上面,SurfaceFlinger把各个Layer的mTexture进行Compose,然后交给GPU或FrameBuffer。后面的这几步操作是各个Layer都要经历的。
       有一个地方还需要注意一下,上面有这么一句:we can fail here is the passed buffer is purely software。
需要看一下/frameworks/base/media/libstagefright/colorconversion/SoftwareRenderer.cpp中的代码段:

mMemoryHeap = new MemoryHeapBase("/dev/pmem_adsp", 2 * mFrameSize);  
if (mMemoryHeap->heapID() < 0) {  
    LOGI("Creating physical memory heap failed, reverting to regular heap.");  
    mMemoryHeap = new MemoryHeapBase(2 * mFrameSize);  
} else {  
    sp pmemHeap = new MemoryHeapPmem(mMemoryHeap);  
    pmemHeap->slap();  
    mMemoryHeap = pmemHeap;  

可以看到,系统会先尝试使用pmem分配,失败的话,就会在regular heap(常规内存)中分配。如果存放视频帧原始数据(已经在被ColorConversion由decode过的YUV数据转化成RGB55)的内存是在regular heap中分配的话,在LayerBuffer中进行resize时是不会进行硬件copybit加速的。

       综上,如果要实现resize的硬件加速的话,需要做这么几点:
       1、保证内存由pmem分配。
       2、实现gralloc的perform操作。可以参照msm7k的gralloc实现。
       3、硬件copybit加速除了GPU和FB以外再增加对PMEM内存的支持。

       通过1和2让系统知道可以使用硬件加速,3是硬件加速的具体实现。





 

你可能感兴趣的:(Android)