android NDK 可能实现最快的 2D 帧速率,我的尝试包括在内,有更好的选择吗?

2024-02-04

android NDK 可能实现最快的 2D 帧速率,我的尝试包括在内,有更好的选择吗?

我使用 NDK 和 OpenGL ES 2.0 将帧显示为 GL_TRIANGLE_STRIP 上的纹理。 这是在 HTC Desire 上完成的,其硬件与 Nexus One 相同。 我尝试加载多个 GL_RGBA 纹理并在纹理之间切换,因为单个纹理的正常填充率低得令人失望:

  • 1 个纹理:4.78 fps
  • 2 个纹理:19.68 fps
  • 3 个纹理:20.18 fps
  • 4 个纹理:28.52 fps
  • 5 个纹理:29.01 fps
  • 6 个纹理:30.32 fps

我认为即使 30.32 fps RGBA 仍然太慢。

那么这是实现最快 2D 帧速率(相同质量)的方法吗? 有什么建议可以加快速度吗?

这是相关代码,它基于 hello-gl2 NDK 示例:

=== GL2JNIView.java :

init(false, 0, 0);
ConfigChooser(5, 6, 5, 0, depth, stencil);

=== gl_code.cpp :

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include <android/log.h>

#include <stdlib.h>
#include <time.h>

typedef unsigned char byte;

static int view_width, view_height;
static byte* framebuffer;
static int framebuffer_size;
static GLuint texture_id[6];
static const char* vertexSrc =
 "precision highp float;\n"
 "precision highp int;\n"
 "attribute vec4 vertexCoords;\n"
 "attribute vec2 textureCoords;\n"
 "varying vec2 f_textureCoords;\n"
 "void main() {\n"
 "  f_textureCoords = textureCoords;\n"
 "  gl_Position = vertexCoords;\n"
 "}\n";
static const char* fragmentSrc  =
 "precision highp float;\n"
 "precision highp int;\n"
 "uniform sampler2D texture;\n"
 "varying vec2 f_textureCoords;\n"
 "void main() {\n"
 "  gl_FragColor = texture2D(texture, f_textureCoords);\n"
 "}\n";
static GLuint shaderProgram;
static GLint attrib_vertexCoords;
static GLint attrib_textureCoords;
static GLint uniform_texture;
static const GLfloat vertexCoords[] = {-1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0};
static const GLfloat textureCoords[] = {0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0};

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height) {
 view_width = width;
 view_height = height;

 framebuffer_size = 4*view_width*view_height;
 framebuffer = (byte*)calloc(framebuffer_size, sizeof(byte));
 for (int i = 0; i < framebuffer_size; i++) framebuffer[i] = 0;

 glViewport(0, 0, view_width, view_height);

 glGenTextures(6, &texture_id[0]);
 glActiveTexture(GL_TEXTURE0);
 glBindTexture(GL_TEXTURE_2D, texture_id[0]);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
 glActiveTexture(GL_TEXTURE1);
 glBindTexture(GL_TEXTURE_2D, texture_id[1]);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
 glActiveTexture(GL_TEXTURE2);
 glBindTexture(GL_TEXTURE_2D, texture_id[2]);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
 glActiveTexture(GL_TEXTURE3);
 glBindTexture(GL_TEXTURE_2D, texture_id[3]);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
 glActiveTexture(GL_TEXTURE4);
 glBindTexture(GL_TEXTURE_2D, texture_id[4]);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
 glActiveTexture(GL_TEXTURE5);
 glBindTexture(GL_TEXTURE_2D, texture_id[5]);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);

 shaderProgram = glCreateProgram();
  GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
  glShaderSource(vertexShader, 1, &vertexSrc, NULL);
  glCompileShader(vertexShader);
 glAttachShader(shaderProgram, vertexShader);
  GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(fragmentShader, 1, &fragmentSrc, NULL);
  glCompileShader(fragmentShader);
 glAttachShader(shaderProgram, fragmentShader);
 glLinkProgram(shaderProgram);
 glUseProgram(shaderProgram);

 uniform_texture = glGetUniformLocation(shaderProgram, "texture");
 glUniform1i(uniform_texture, 0);

 attrib_vertexCoords = glGetAttribLocation(shaderProgram, "vertexCoords");
 glEnableVertexAttribArray(attrib_vertexCoords);
 glVertexAttribPointer(attrib_vertexCoords, 2, GL_FLOAT, GL_FALSE, 0, vertexCoords);

 attrib_textureCoords = glGetAttribLocation(shaderProgram, "textureCoords");
 glEnableVertexAttribArray(attrib_textureCoords);
 glVertexAttribPointer(attrib_textureCoords, 2, GL_FLOAT, GL_FALSE, 0, textureCoords);
}

JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj) {
 static int frame_count = 0;
 static clock_t last_time = clock();
 static int last_frame_count = 0;

 frame_count++;
 if (clock()-last_time > 1e7) {
  __android_log_print(ANDROID_LOG_INFO, "libgl2jni", "fps: %f", ((float)frame_count-last_frame_count)/(clock()-last_time)*1e6);
  last_time = clock();
  last_frame_count = frame_count;
 }

 static byte val = 0;
 val++;
 if (val == 256) val = 0;
 for (int i = 0; i < framebuffer_size; i++) framebuffer[i] = val;

 int tst = frame_count%6;
 if (tst == 0) {
  glActiveTexture(GL_TEXTURE0);
 } else if (tst == 1) {
  glActiveTexture(GL_TEXTURE1);
 } else if (tst == 2) {
  glActiveTexture(GL_TEXTURE2);
 } else if (tst == 3) {
  glActiveTexture(GL_TEXTURE3);
 } else if (tst == 4) {
  glActiveTexture(GL_TEXTURE4);
 } else if (tst == 5) {
  glActiveTexture(GL_TEXTURE5);
 }
 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

我意识到你的问题相当老了,你可能已经解决了它或转向其他问题,但如果其他人遇到这个问题,我会给出建议。

首先,glTexImage2D要求图形子系统在每次调用它时执行纹理对象的内存释放和重新分配,因为纹理参数可能会在调用之间发生变化。优化的驱动程序可能会查看宽度、高度和格式,如果它们都相同,则可以跳过重新分配,但 Android 驱动程序实现者实际上不太可能这样做。

为了完全避免纹理重新分配,您可以使用glTexSubImage2D替换完整位图或其中的一部分。如果将其与上述纹理缓冲方案结合起来,您应该会看到相当大的速度提升。您甚至可以扩展它来检测显示器的修改区域,并仅更新帧之间已更改的矩形部分。

总而言之,将纹理初始化代码更改为调用glTexImage2D使用 NULL 位图指针,因此 OpenGL 只为纹理分配内存,并且实际上不会将任何数据复制到其中,如下所示:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, view_width, view_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

然后使用以下命令更新游戏循环中的每一帧:

glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, view_width, view_height, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android NDK 可能实现最快的 2D 帧速率,我的尝试包括在内,有更好的选择吗? 的相关文章

  • JKS、BKS 和 PKCS12 文件格式

    我正在设置一个无头服务器 该服务器使用用户提供的数据 JS CSS HTML 密钥库 为 Android 构建 Phonegap 混合应用程序 我想进行一些基本的客户端检查 以确保上传的密钥库有效 对于 JKS 文件 我发现可以通过确保提供
  • 启动画面反应本机后出现白屏

    编辑 似乎是因为 MainActivity 加载太重而生成白屏 我设法首先使用本机启动屏幕来解决 然后在本机被杀死后立即基于下一个插件的 js 实现 我做了一些修改完美匹配两个启动画面https github com crazycodebo
  • 如何在 Android 中以编程方式配置启动器活动?

    我正在开发一个具有两项活动的应用程序 LoginActivity and MainActivity 当用户首次打开应用程序时 他将登录并且他的凭据 用户名和令牌 保存在Preferences 现在 如果用户再次打开应用程序MainActiv
  • 卡片视图工具栏

    我有一个包含 CardView 的 RecyclerView 我想向每个 CardView 添加一个工具栏 其外观和行为类似于主工具栏 图标 标题 按钮 按钮 菜单 我从这里看到了 http blog grafixartist com cr
  • 无法打开本地终端

    我尝试在 Android Studio 中初始化我的终端 但它给了我错误 它说 无法打开本地终端 java io IOException 无法创建 PTY 我的电脑运行的是 Windows 10 如何解决这个问题 当您从 Github 存储
  • 如何防止 Activity 在后退操作时重新加载

    我有连接到互联网以获取数据的应用程序 我可以多层次访问数据 假设我从第 3 级开始 在第 4 级我决定返回 每当我按回之前的活动时 就会从互联网重新加载数据 有可能阻止这种情况吗 我尝试以单顶模式运行该活动 将数据加载代码移至 single
  • 要在进程中运行 dex,Gradle 守护进程需要更大的堆。目前有 910 MB

    实际上主要错误是 java exe完成非零退出值 1 首先我告诉你安装 studio 后遇到的每个问题 三天前 我刚刚安装了 android studio 并创建了新项目 1 首先它抛出错误 插件太旧 请更新到更新的版本 在谷歌上搜索后我改
  • 尝试使用掩码裁剪位图会抛出 IllegalArgumentException:

    我正在使用以下代码 public void cropSelection Bitmap bitmap annotationBitmap copy annotationBitmap getConfig true Canvas canvas ne
  • 使用 appcelerator titan 在 android 中后退按钮退出应用程序

    我是钛开发的新手 在本机 android 中 如果我们按下后退按钮 则仅当前活动将被关闭 并且它将返回到上一个活动 但是当我使用 Titanium 在 Android 中按下后退按钮时 它会从应用程序退出 我怎样才能改变这种行为 有两种类型
  • 无法解析配置“:app:debugRuntimeClasspath”的所有文件。问题

    我的 android studio 遇到了下一个问题 导致 org gradle api internal artifacts ivyservice DefaultLenientConfiguration ArtifactResolveEx
  • Android 可检查子菜单选项

    所以我有一个用于选项菜单项的子菜单 我想要一个可检查条目的列表 用户可以根据需要选择 取消选择多个条目 我无法解决的唯一问题是如何防止单击其中一个复选框时关闭选项菜单 我看到 PerformShortcut 有一个 FLAG PERFORM
  • 无法调整 Android React Native 模块中线性布局子项的大小

    完整代码在这里 https github com sbaar ResizableLLRN 这里有关于 java 中正确行为和 React Native 中错误行为的视频 https drive google com file d 0Bxl2
  • 创建用于 Android 库分发的 JAR

    我正在开发一个 android 库 并希望导出一个 JAR 文件 我可以分发该文件供其他人在他们的应用程序中使用 我不想分发源代码 因为它包含有关发布到我的网络服务器的详细信息 我尝试使用在 bin 目录中创建的 JAR 文件并将该 jar
  • Android Youtube API 可用吗? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有适用于 Android 的 YouTube API 吗 如果不是 除了通过网络浏览器之外 如何从 Yo
  • Android 如何从我的应用程序使用 SD 卡中的文件路径预览图像

    文件存在于sdcard image jpg我想创建我自己的应用程序 活动 按下按钮时 需要使用内置图像查看器显示存储在 SD 卡中的图像 按图像查看器中的后退按钮后 它应该返回到我正在运行的应用程序 需要一些帮助 您可以为此创建一个具有适当
  • 如何将 currentTimeMillis 转换为可读的日期格式? [复制]

    这个问题在这里已经有答案了 我想用currentTimeMillis两次 这样我就可以计算持续时间 但我也想以用户可读的格式显示时间和日期 我遇到了麻烦currentTimeMillis有利于计算 但我看不到内置函数可以转换为合适的时间或时
  • Android Windows:它们何时以及如何创建?

    我已经阅读了标准的 Windows 相关文档并翻阅了 一堆源代码 试图理解 Android 如何以及何时 窗口已创建 我相信我已经拥抱它并愿意 对其进行验证或更正 据我所知 只有两种方法可以获得 Window 对象的句柄 1 Activit
  • Activity 上的 OnTouchListener 从不调用

    我使用了这段代码 但是当我在运行时单击活动时 它永远不会在 OnTouch 方法中命中 有人可以指导我我做错了什么吗 我需要设置此活动的内容视图吗 实际上我想要用户在执行过程中触摸的活动的坐标 public class TouchTestA
  • 动画结束后更改视图位置

    我开发了一个基于ViewGroup我的问题是我需要在动画结束后保存项目的位置 我打了电话setFillAfter true 在我创建的动画对象中AnimationListener并在其中onAnimationEnd方法调用View layo
  • 如何为背景图像添加内边距

    我有一个LinearLayout其中有一个背景图像 一个 9 修补的 png 文件 如何向左和右添加填充 以使背景图像不占据整个宽度 我努力了android paddingLeft and android paddingRight 但这并没

随机推荐

  • “这个”阴影是个好主意吗?

    隐藏类变量的情况在 Java 中很常见 Eclipse 将愉快地生成以下代码 public class TestClass private int value private String test public TestClass int
  • 将数据库设置从 application.ini 中取出并放入环境中

    在基于 Zend 的应用程序的传统编码中 数据库设置存储在 application ini 中 这会存储每个应用程序的设置 StackOverflow 上是否有人探索过将数据库设置从 application ini 移动到环境中的可能性 例
  • Picasso 库无法在 Android 上从 SD 卡加载图像

    我从图像库的路径中获取一个文件 并尝试将其加载到图像视图 如下所示 文件路径为 storage sdcard0 DCIM Camera 1436267579864 jpg 我也尝试传递 Uri 我也有 SD 卡的读取权限 它最终在onErr
  • 如何通过IP获取时区[重复]

    这个问题在这里已经有答案了 我有一个注册 通过它我可以获得注册用户的IP地址 我想通过用户的 IP 地址获取用户的时区 就像在 jquery 中我们可以得到这样的结果jquery 中的时区 http pellepim bitbucket o
  • 如何获取 .NET 中的资源监视器值?

    我需要获取 Windows 7 资源监视器中的一些值 特别是每个进程的内存使用情况 CPU 和带宽 我研究了 PerformanceCounter 类 但没有找到深入到进程级别的方法 资源监视器正是我正在寻找的东西 在你问之前 我知道这是重
  • raise StopIteration 和生成器中的 return 语句有什么区别?

    我很好奇使用之间的区别raise StopIteration and a return生成器中的语句 例如 这两个函数有什么区别吗 def my generator0 n for i in range n yield i if i gt 5
  • 安装 pydev 时出错[重复]

    这个问题在这里已经有答案了 我安装了 eclipse 3 7 并且想从 help gt install new software 从 pydev org updates 安装 pydev 但我不断收到错误 An error occurred
  • Python描述符与属性[重复]

    这个问题在这里已经有答案了 我对何时使用属性和描述符感到困惑 我读到属性是一个专门的描述符 有人可以发布这是如何工作的吗 您应该阅读有关描述符实际是什么的文档 Cliff s Notes 版本 描述符是一种低级机制 可让您挂钩正在访问的对象
  • Rails 5 资产未在生产中加载

    我最近更新了 Rails 应用程序中的一些软件包 但现在我的资产无法提供服务 相反 我收到以下错误 Failed to load resource the server responded with a status of 404 Not
  • 制作 VB-dll 并将其加载到 C++ 应用程序中

    我有一个问题已经困扰了整整一周 但我自己无法解决 我一直在谷歌搜索 并在各种论坛中搜索 我发现了很多 这可能有用 尝试过 但没有 没有成功 如果有人有任何线索 请帮助我 我从外部源获得了许多用 VB 编写的类和函数 我需要能够在 C 应用程
  • 从文件中读取特殊字符 - Java

    我正在从具有以下属性的文本文件中读取数据 编码 ANSI文件类型 电脑 现在 该文件包含许多特殊字符 例如度数符号 等 我正在使用以下代码读取该文件 File file new File C X Y SpecialCharacter txt
  • OpenCV VideoCapture 从视频中删除 Alpha 通道

    我有带有 Alpha 通道的视频 我尝试将其放置在另一个视频上 如下所示 public static void overlayImage Mat background Mat foreground Mat output Point loca
  • Javascript Date 对象返回 1969 年 12 月 31 日

    If you are using a date in the form of milliseconds does it need to be converted to a string in order for the Date objec
  • Python 多处理进程无声地崩溃

    我正在使用Python 2 7 3 我使用子类化了一些代码multiprocessing Process对象 如果我的子类 Process 对象中的代码没有错误 则一切运行正常 但是 如果我的子类 Process 对象中的代码存在错误 它们
  • 美化 NSArray 和 NSDictionary 的 NSLog

    我正在处理深度嵌套的 NSArray 和 NSDictionary 至少可以说这是非常耗时的 data objectatindex 0 valueForKey blah 等等 有谁知道一个很好的 iOS 类别来递归记录结构 突出显示类型并显
  • 我可以直接使用 CLion 调试库 (DLL) 吗?

    我正在使用 CLion IDE 处理多个 CMake 项目 这些项目以库作为输出目标 在我的特殊情况下是 DLL 因为我在 Windows 上 现在 直接调试 运行某些方法将非常方便 例如使用使用 CLion 的配置 这可能吗 如果没有 调
  • Android 11 - ROOT:挂载 /system 失败,在 /proc/system 中找不到

    我的操作系统是 PixysOS Android 11 当我做 mount o rw remount system 它失败了 mount system not in proc mounts 但通常它是有效的 我也在android 9中测试过
  • Gson Java 保留关键字

    我有一些 JSON 我正在使用 Gson 反序列化 resp posts public true 我的问题是public是一个Java关键字 那么我如何在我的类中创建一个与publicJSON 中的字段 您可以使用 gson 为您的字段使用
  • 如何在 docker-compose 中运行多个 JVM 参数?

    我从以下答案中得到了 JVM 参数列表https stackoverflow com a 35108974 7809534 https stackoverflow com a 35108974 7809534 Dcom sun manage
  • android NDK 可能实现最快的 2D 帧速率,我的尝试包括在内,有更好的选择吗?

    android NDK 可能实现最快的 2D 帧速率 我的尝试包括在内 有更好的选择吗 我使用 NDK 和 OpenGL ES 2 0 将帧显示为 GL TRIANGLE STRIP 上的纹理 这是在 HTC Desire 上完成的 其硬件