美文网首页Android 源码分析
GLUtils.texImage2D的底层调用流程

GLUtils.texImage2D的底层调用流程

作者: 熊皮皮 | 来源:发表于2017-04-19 19:20 被阅读570次

    本文档只是因为维护的Android项目使用了SDK封装的OpenGL接口,想知道底层到底作了哪些操作,纯粹是记录。

    Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
      // 内部调用native_texImage2D
      // native_texImage2D(target, level/*0*/, /*internalformat*/-1, bitmap, /*type*/-1, border/*0*/);
    

    根据AndroidXRef源码参考网站,在/frameworks/base/core/jni/android/opengl/util.cpp的文件将native_texImage2D映射为util_texImage2D。

    static JNINativeMethod gUtilsMethods[] = {
        { "native_getInternalFormat", "(Landroid/graphics/Bitmap;)I", (void*) util_getInternalFormat },
        { "native_getType", "(Landroid/graphics/Bitmap;)I", (void*) util_getType },
        { "native_texImage2D", "(IIILandroid/graphics/Bitmap;II)I", (void*)util_texImage2D },
        { "native_texSubImage2D", "(IIIILandroid/graphics/Bitmap;II)I", (void*)util_texSubImage2D },
        { "setTracingLevel", "(I)V",                        (void*)setTracingLevel },
    };
    

    util_texImage2D函数根据bitmap信息决定通过glCompressedTexImage2D或glTexImage2D上传图像数据到OpenGL服务器端。

    static jint util_texImage2D(JNIEnv *env, jclass clazz,
            jint target, jint level, jint internalformat,
            jobject jbitmap, jint type, jint border)
    {
        SkBitmap bitmap;
        GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
        SkColorType colorType = bitmap.colorType();
        if (internalformat < 0) {
            internalformat = getInternalFormat(colorType);
        }
        if (type < 0) {
            type = getType(colorType);
        }
        int err = checkFormat(colorType, internalformat, type);
        if (err)
            return err;
        bitmap.lockPixels();
        const int w = bitmap.width();
        const int h = bitmap.height();
        const void* p = bitmap.getPixels();
        if (internalformat == GL_PALETTE8_RGBA8_OES) {
            if (sizeof(SkPMColor) != sizeof(uint32_t)) {
                err = -1;
                goto error;
            }
            const size_t size = bitmap.getSize();
            const size_t palette_size = 256*sizeof(SkPMColor);
            const size_t imageSize = size + palette_size;
            void* const data = malloc(imageSize);
            if (data) {
                void* const pixels = (char*)data + palette_size;
                SkColorTable* ctable = bitmap.getColorTable();
                memcpy(data, ctable->readColors(), ctable->count() * sizeof(SkPMColor));
                memcpy(pixels, p, size);
                glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data);
                free(data);
            } else {
                err = -1;
            }
        } else {
            glTexImage2D(target, level, internalformat, w, h, border, internalformat, type, p);
        }
    error:
        bitmap.unlockPixels();
        return err;
    }
    
    static int getInternalFormat(SkColorType colorType)
    {
        switch(colorType) {
            case kAlpha_8_SkColorType:
                return GL_ALPHA;
            case kARGB_4444_SkColorType:
                return GL_RGBA;
            case kN32_SkColorType:
                return GL_RGBA;
            case kIndex_8_SkColorType:
                return GL_PALETTE8_RGBA8_OES;
            case kRGB_565_SkColorType:
                return GL_RGB;
            default:
                return -1;
        }
    }
    
    static int checkFormat(SkColorType colorType, int format, int type)
    {
        switch(colorType) {
            case kIndex_8_SkColorType:
                if (format == GL_PALETTE8_RGBA8_OES)
                    return 0;
            case kN32_SkColorType:
            case kAlpha_8_SkColorType:
                if (type == GL_UNSIGNED_BYTE)
                    return 0;
            case kARGB_4444_SkColorType:
            case kRGB_565_SkColorType:
                switch (type) {
                    case GL_UNSIGNED_SHORT_4_4_4_4:
                    case GL_UNSIGNED_SHORT_5_6_5:
                    case GL_UNSIGNED_SHORT_5_5_5_1:
                        return 0;
                    case GL_UNSIGNED_BYTE:
                        if (format == GL_LUMINANCE_ALPHA)
                            return 0;
                }
                break;
            default:
                break;
        }
        return -1;
    }
    
    static int getType(SkColorType colorType)
    {
        switch(colorType) {
            case kAlpha_8_SkColorType:
                return GL_UNSIGNED_BYTE;
            case kARGB_4444_SkColorType:
                return GL_UNSIGNED_SHORT_4_4_4_4;
            case kN32_SkColorType:
                return GL_UNSIGNED_BYTE;
            case kIndex_8_SkColorType:
                return -1; // No type for compressed data.
            case kRGB_565_SkColorType:
                return GL_UNSIGNED_SHORT_5_6_5;
            default:
                return -1;
        }
    }
    

    相关文章

      网友评论

        本文标题:GLUtils.texImage2D的底层调用流程

        本文链接:https://www.haomeiwen.com/subject/qzmhzttx.html