Chinaunix首页 | 论坛 | 博客
  • 博客访问: 278015
  • 博文数量: 95
  • 博客积分: 2047
  • 博客等级: 大尉
  • 技术积分: 1022
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-14 16:18
文章分类

全部博文(95)

文章存档

2013年(1)

2011年(94)

我的朋友

分类: 嵌入式

2011-08-27 10:47:07

Copybit调研报告2

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, ©Bits)
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(src->handle);

        copybit_image_t dimg;
        dimg.w = dst->width;
        dimg.h = dst->height;
        dimg.format = dst->format;
        dimg.handle = const_cast(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
很奇怪,这儿竟然也用了copybit

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

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

Rockie Cheng 
阅读(728) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~