android - OpenGL ES 纹理内存

标签 android opengl-es

我正在尝试优化我的原生 Android 应用程序中的纹理内存消耗。我有两个计数器:第一个是我自己的,每次调用 TexImage 时都会递增:

g_cbTextureMemory += ImageLineBytes(Format, width) * height;

你可能假设 TexImage 为纹理调用了一次,在我的真实代码中,当前图像大小比添加新图像大小减少,如果纹理重新分配,但实际上没有发生重新分配。

第二个来自系统:

adb shell dumpsys meminfo my.app.name

它给出了这样的东西:

    ** MEMINFO in pid 3269 [my.app.name] **
                    native   dalvik    other    total
            size:    39320[*]  6663      N/A    45983
       allocated:    21453     3945      N/A    25398
            free:       34     2718      N/A     2752
           (Pss):     6281     3078    40643    50002
  (shared dirty):     2240     4968    12108    19316
    (priv dirty):     6232     2684    17948    26864

之后我执行以下操作:我将 所有 纹理替换为 1x1(通过将虚拟 1x1 图像发送到 glTexImage)。我看到 meminfo 给出了另一个结果,差异单元格 [*] 在 22Mb 上发生了变化。但是我的计数器显示我有 25Mb 的纹理,所以我预计有 25Mb。

那么转储纹理内存消耗隐藏在哪里?要清楚,对于 1x1 纹理转储是:

    ** MEMINFO in pid 3269 [my.app.name] **
                    native   dalvik    other    total
            size:    16892     5575      N/A    22467
       allocated:    13211     3574      N/A    16785
            free:      208     2001      N/A     2209
           (Pss):     6273     3122    17016    26411
  (shared dirty):     2252     5032    10756    18040
   (priv dirty):      6224     2588     5848    14660

为什么我没有得到 25Mb?是统计误差吗? native 堆是否包含纹理内存(似乎是)?或者对于某些格式,Android 的内部格式可能与我发送的不同?例如,R8G8B8 转换为更优化的东西(似乎不是)?可能一切都好,并且有合理的解释?

最佳答案

这里有几个问题。

我假设您通过比较“大小”行得到 22MB 的差异。这是进程总共请求的内存量。有两个因素可以促成此值。

首先,该区域中的许多虚拟页面可能(而且很可能)尚未分配给物理内存。物理分配仅在进程实际引用以前未使用的虚拟页面时发生。在这种情况下,MMU 会导致 CPU 陷入内核,然后内核会找到并分配一个物理页面来支持虚拟页面。因此,进程的大小可能远远超过可用的物理 RAM,即使在没有交换空间的可移植 Android 设备上也是如此,只要这些页面中的大部分从未被引用。

影响进程大小的第二个因素是 C 库(或 Dalvik VM,或任何用户空间内存管理)将请求比应用程序请求的更大的内存块。这样做是出于性能原因,因为可以在不进行系统调用的情况下频繁分配/取消分配小缓冲区。因此,上面的大小参数并不能很好地指示进程实际使用的内存——它只能作为一个粗略的上限。事实上,“已分配”行可以更好地指示应用程序使用的最大内存,因为它跟踪实际引用的页面。

无论如何,据我所知,您通过 glTexImage 发送到 OpenGL 的任何纹理都被复制到一个单独的内存区域。这可能在图形硬件本身上,或者作为内核空间中内核视频驱动程序的一部分。无论哪种方式,使用的纹理内存都不会反射(reflect)在您的应用程序中。

希望对您有所帮助。

关于android - OpenGL ES 纹理内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4659655/

相关文章:

android - Fedora命令行使用android sdk安装eclipse

android - Locale FRENCH 与 Locale FRANCE 之间的区别

Android Facebook SDK 让用户无法登录?

java - 如何检查 3D 对象是否与 OpenGL ES 2 中的射线相交 - Android

使用 android :entries ="@array/some_array" used 微调器时 Android Studio 0.3.6 呈现问题

iPhone OpenGL ES 单 View 还是多 View ?

ios - 如何在 OpenGL es 应用程序中使用键盘

iphone - GLSL ES 1.1 中卷积的高效邻域纹理访问

android - 何时调用 glMatrixMode()

javascript - 如何将我的 JavaScript Web 应用程序转换为 Android 应用程序?