硬件加速活动 - 如何获得OpenGL纹理大小限制?

时间:2011-09-15 09:53:29

标签: android android-3.0-honeycomb hardware-acceleration

我正在尝试在Honeycomb中启用hw加速,并在Canvas上显示一些Bitmaps。 一切正常,但对于大位图(一维中> 2048),我在日志中出错:

OpenGLRenderer:位图太大而无法上传到纹理

我知道这是因为hw限制,如果启用了hw加速,可以通过减少最大位图大小来解决它(通过View.isHardwareAccelerated()检查)。

我的问题是:如何轻松确定硬件可用于位图绘制的最大纹理大小。 2048似乎是对我的设备的限制,但在不同的设备上可能会有所不同。

编辑:我不是创建OpenGL应用程序,只是普通应用程序,它可以利用hw加速。因此我根本不熟悉OpenGL,我只是在日志中看到OpenGL相关的错误,并期待解决它。

4 个答案:

答案 0 :(得分:65)

目前最低限制是2048px(即硬件必须支持纹理至少2048x2048。)在ICS中,我们将在Canvas类中引入一个新的API,它将为您提供以下信息:
Canvas.getMaximumBitmapWidth()Canvas.getMaximumBitmapHeight()

答案 1 :(得分:16)

获得最大允许大小的另一种方法是遍历所有EGL10配置并跟踪最大尺寸。

public static int getMaxTextureSize() {
    // Safe minimum default size
    final int IMAGE_MAX_BITMAP_DIMENSION = 2048;

    // Get EGL Display
    EGL10 egl = (EGL10) EGLContext.getEGL();
    EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);

    // Initialise
    int[] version = new int[2];
    egl.eglInitialize(display, version);

    // Query total number of configurations
    int[] totalConfigurations = new int[1];
    egl.eglGetConfigs(display, null, 0, totalConfigurations);

    // Query actual list configurations
    EGLConfig[] configurationsList = new EGLConfig[totalConfigurations[0]];
    egl.eglGetConfigs(display, configurationsList, totalConfigurations[0], totalConfigurations);

    int[] textureSize = new int[1];
    int maximumTextureSize = 0;

    // Iterate through all the configurations to located the maximum texture size
    for (int i = 0; i < totalConfigurations[0]; i++) {
        // Only need to check for width since opengl textures are always squared
        egl.eglGetConfigAttrib(display, configurationsList[i], EGL10.EGL_MAX_PBUFFER_WIDTH, textureSize);

        // Keep track of the maximum texture size
        if (maximumTextureSize < textureSize[0])
            maximumTextureSize = textureSize[0];
    }

    // Release
    egl.eglTerminate(display);

    // Return largest texture size found, or default
    return Math.max(maximumTextureSize, IMAGE_MAX_BITMAP_DIMENSION);
}

从我的测试来看,这非常可靠,并且不需要您创建实例。 性能方面,我在Note 2上执行了18毫秒,在G3上只执行了4毫秒。

答案 2 :(得分:6)

如果您想动态了解设备的纹理大小限制(因为它会根据设备而改变),您必须调用此方法:

int[] maxTextureSize = new int[1];
gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0);

不要忘记,对于某些设备(例如Nexus One),纹理大小必须是2的幂!

我知道在上次更新此主题后很长一段时间我的回答...抱歉

答案 3 :(得分:3)

根据规范,使用glGetIntegerv调用GL_MAX_TEXTURE_SIZE

  

GL_MAX_TEXTURE_SIZE参数返回一个值。该值粗略估计了GL可以处理的最大纹理。该值必须至少为64。

http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml