zoukankan      html  css  js  c++  java
  • Copybit调研报告

    http://hi.baidu.com/aokikyon/blog/item/cda01397e76e936154fb964f.html

    Copybit模块在android2.0以后归OpenGL管理,在libagl中专门有一个copybit.cpp文件对其进一步封装并进行管理。
    当然,也有越狱的时候,这个我们在后面讨论,首先还是看看copybit.cpp。

    注意在android.mk中有个宏定义,默认是打开的
    #define LIBAGL_USE_GRALLOC_COPYBITS


    1、libagl/copybit.cpp

    //检查是否有copybit
    static bool checkContext(ogles_context_t* c)

    //copybit进一步封装
    static bool copybit(GLint x, GLint y,
            GLint w, GLint h,
            EGLTextureObject* textureObject,
            const GLint* crop_rect,
            int transform,
            ogles_context_t* c)
    简单工作流程:
    1)将texture转换为copybit格式
    textureToCopyBitImage(&textureObject->surface, opFormat,textureObject->buffer, &src);
    2)如果有alpha值需要倒三次
    copybit->stretch(copybit, &tmpCbImg, &dst, &tmpCbRect, &tmpdrect, &tmp_it);
    copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
    copybit->stretch(copybit, &dst, &tmpCbImg, &tmpdrect, &tmpCbRect, &it);
    3)else如果没有alpha,只需要做一次
    opybit->stretch(copybit, &dst, &src, &drect, &srect, &it);

    //Try to draw a triangle fan with copybit画一个三角扇形,是对copybit函数的进一步封装,较复杂
    bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count)

    //Try to drawTexiOESWithCopybit copybit的简单封装
    bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_context_t* c)

    2、libagl对copybit的调用

    1)打开copybit模块
    State.cpp
    ogles_context_t *ogles_init(size_t extra)
    |
    hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module)
       |
       copybit_open(module, &copyBits)
       c->copybits.blitEngine = copyBits;

    2)操作copybit

    Texture.cpp

    void glDrawTexsvOES(const GLshort* coords)<----这个是API
    void glDrawTexivOES(const GLint* coords)<----这个是API
    void glDrawTexsOES(GLshort x , GLshort y, GLshort z, GLshort w, GLshort h)<----这个是API
    void glDrawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h)<----这个是API
    |
    drawTexiOES(x, y, z, w, h, c);
       |
       drawTexiOESWithCopybit(x, y, z, w, h, c)
        |
        drawTexiOESWithCopybit_impl(x, y, z, w, h, c)

    void glDrawTexfvOES(const GLfloat* coords)<----这个是API
    void glDrawTexxvOES(const GLfixed* coords)<----这个是API
    void glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h)<----这个是API
    void glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h)<----这个是API
    |
    drawTexxOES(x, y, z, w, h, c);
       |
       drawTexiOESWithCopybit(gglFixedToIntRound(x),
                   gglFixedToIntRound(y), gglFixedToIntRound(z),
                   gglFixedToIntRound(w), gglFixedToIntRound(h), c)
        |
        drawTexiOESWithCopybit_impl(x, y, z, w, h, c);

    void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
    |
    tex->try_copybit = true;



    Array.cpp
    void glDrawArrays(GLenum mode, GLint first, GLsizei count) <----这个是API
    |
    void drawPrimitivesTriangleFan(ogles_context_t* c, GLint first, GLsizei count) <----mode6
       |
       drawTriangleFanWithCopybit(c, first, count)
        |
        drawTriangleFanWithCopybit_impl(c, first, count)

    3、copybit的越狱?
    并不是所有代码都使用了封装好的copybit,也并不是仅有opengl能够使用copybit模块,看看下面的:

    1)libagl/egl.cpp 有个copyBIt函数直接用了copybit的blit

    void egl_window_surface_v2_t::copyBlt(
            android_native_buffer_t* dst, void* dst_vaddr,
            android_native_buffer_t* src, void const* src_vaddr,
            const Region& clip)
    {
        // FIXME: use copybit if possible
        // NOTE: dst and src must be the same format
       
        status_t err = NO_ERROR;
        copybit_device_t* const copybit = blitengine;
        if (copybit) {
            copybit_image_t simg;
            simg.w = src->width;
            simg.h = src->height;
            simg.format = src->format;
            simg.handle = const_cast<native_handle_t*>(src->handle);

            copybit_image_t dimg;
            dimg.w = dst->width;
            dimg.h = dst->height;
            dimg.format = dst->format;
            dimg.handle = const_cast<native_handle_t*>(dst->handle);
           
            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
            region_iterator it(clip);
            err = copybit->blit(copybit, &dimg, &simg, &it);
            if (err != NO_ERROR) {
                LOGE("copybit failed (%s)", strerror(err));
            }
        }
    //如果没有则是软件处理的
        if (!copybit || err) {
            Region::const_iterator cur = clip.begin();
            Region::const_iterator end = clip.end();
           
            const size_t bpp = pixelFormatTable[src->format].size;
            const size_t dbpr = dst->stride * bpp;
            const size_t sbpr = src->stride * bpp;

            uint8_t const * const src_bits = (uint8_t const *)src_vaddr;
            uint8_t       * const dst_bits = (uint8_t       *)dst_vaddr;

            while (cur != end) {
                const Rect& r(*cur++);
                ssize_t w = r.right - r.left;
                ssize_t h = r.bottom - r.top;
                if (w <= 0 || h<=0) continue;
                size_t size = w * bpp;
                uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
                uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
                if (dbpr==sbpr && size==sbpr) {
                    size *= h;
                    h = 1;
                }
                do {
                    memcpy(d, s, size);
                    d += dbpr;
                    s += sbpr;
                } while (--h > 0);
            }
        }
    }

    2)frameworks\base\libs\surfaceflinger\Layerbuffer.cpp

    20100610更新

    确认播放视频时会调用到此处,但是传递来的src存在问题,并不包含offset,因此将这块注掉。

    void LayerBuffer::onFirstRef()
    |
    hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module)
            |
       copybit_open(module, &mBlitEngine);

    void LayerBuffer::BufferSource::onDraw(const Region& clip) const
    ...
    #if defined(EGL_ANDROID_image_native_buffer)
        if (mLayer.mFlags & DisplayHardware::DIRECT_TEXTURE) {
            copybit_device_t* copybit = mLayer.mBlitEngine;
            if (copybit) {
                // create our EGLImageKHR the first time
                err = initTempBuffer();
                if (err == NO_ERROR) {
                    // NOTE: Assume the buffer is allocated with the proper USAGE flags
                    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);

                }
            } else {
                err = INVALID_OPERATION;
            }
        }
    #endif
    ...

    3)还有,比如高通的Gralloc模块里面也用到了copybit

    4、调用频率

    今天通过插装的方式测试了启动部分各函数对copybit模块调用频率

    1)drawTexiOES 99% 主要调用copybit模块的函数

    2)egl_window_surface_v2_t::copyBlt 仅有几次调用

    3)LayerBuffer::BufferSource::onDraw 没有调用过,不保证以后不调用

    总之,看了这么多,先写一个copybit模块试试吧。

    btw 编译好的copybit.ky6410.so无法被系统识别?

    修改build.prop ro.product.board=ky6410

    Rockie Cheng

  • 相关阅读:
    C++使用thread类多线程编程
    机器学习: Viola-Jones 人脸检测算法解析(二)
    微服务:ICE 入门之 编译环境搭建
    OpenMP中的同步和互斥
    OpenMP编程的任务调度控制
    机器学习: Viola-Jones 人脸检测算法解析(一)
    并行编程OpenMP基础及简单示例
    漫话中国古代史 —— 大唐
    漫话中国古代史 —— 大唐
    也咬文嚼字
  • 原文地址:https://www.cnblogs.com/leaven/p/1944822.html
Copyright © 2011-2022 走看看