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 帧速率,我的尝试包括在内,有更好的选择吗? 的相关文章

  • 如何为ScrollView放置固定图像背景?

    我应该想要滚动视图滚动 而不是背景中的图像 将图像添加到滚动视图框架之前的视图层次结构的较高位置
  • 如何对这个字符串进行子串化

    我想得到这个字符串的 4 个部分 String string 10 trillion 896 billion 45 million 56873 我需要的4个部分是 10万亿 8960亿 4500万 和 56873 我所做的是删除所有空格 然
  • 如何快速自动发送FCM或APNS消息?

    我正在开发一项后端服务 通过 FCM 或 APNS 向移动应用程序发送推送通知 我想创建一个可以在一分钟内运行的自动化测试 并验证服务器是否可以成功发送通知 请注意 我不一定需要检查通知是否已送达 只需检查 FCM 或 APNS 是否已成功
  • 使用workmanager时Firestore脱机持久性错误

    我正在使用一个WorkManger定期从我的中检索信息Firestore当应用程序处于后台和前台时的数据库 此信息用于根据状态更新 UI 因此不同的状态会添加或删除 UI 的不同部分 第一次运行时效果很好 但是 一旦应用程序处于后台并且Wo
  • 类型容器“Android 依赖项”引用不存在的库 android-support-v7-appcompat/bin/android-support-v7-appcompat.jar

    我在尝试在我的项目中使用 Action Bar Compat 支持库时遇到了某种错误 我不知道出了什么问题 因为我已按照此链接中的说明进行操作 gt http developer android com tools support libr
  • React Native 从 JavaScript 代码内部访问 strings.xml

    有没有办法访问当前值android app src main res values strings xml从 JavaScript 代码内部 我想为每个构建放置不同的端点 URL 但我什至无法检测到反应本机代码内的构建类型 而不必求助于 D
  • Android 30+ 中的视频捕获意图 - 只有所有者才能与待处理项目交互

    我正在尝试在我的应用程序上捕获视频 它可以在 android API 30 以下运行 但不能在 30 以上运行 似乎在 sdk 30 之后 android 不允许完全读取外部存储 作用域存储 我目前遇到这个错误 java lang Ille
  • 找不到 com.google.firebase:firebase-core:9.0.0 [重复]

    这个问题在这里已经有答案了 在遵循有些不一致的指示之后here https firebase google com docs admob android quick start name your project and here http
  • Android 后退按钮无法与 Flutter 选项卡内的导航器配合使用

    我需要在每个选项卡内有一个导航器 因此当我推送新的小部件时 选项卡栏会保留在屏幕上 代码运行得很好 但是 android 后退按钮正在关闭应用程序而不是运行 Navigator pop import package flutter mate
  • 无法获取log.d或输出Robolectrict + gradle

    有没有人能够将 System out 或 Log d 跟踪从 robolectric 测试输出到 gradle 控制台 我在用Robolectric Gradle 测试插件 https github com robolectric robo
  • 如何测试两个大视频是否相同?

    我有一个系统 其中会摄取视频文件 然后启动多个 CPU 密集型任务 由于这些任务的计算成本很高 如果文件已经被处理过 我想跳过处理该文件 视频来自各种来源 因此文件名等不是可行的选择 如果我使用图片 我会比较 MD5 哈希值 但对于 5GB
  • 是否可以将数组或对象添加到 Android 上的 SharedPreferences

    我有一个ArrayList具有名称和图标指针的对象 我想将其保存在SharedPreferences 我能怎么做 注意 我不想使用数据库 无论 API 级别如何 请检查SharedPreferences 中的字符串数组和对象数组 http
  • Android Activity 生命周期函数基础知识

    我正在测试这段代码 它显示活动所处的状态 public class Activity101Activity extends Activity String tag Lifecycle Called when the activity is
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • 尝试在 ubuntu 中编译 android 内核时出错

    我正在尝试从源代码编译 Android 内核 并且我已经下载了所有正确的软件包来执行此操作 但由于某种原因我收到此错误 arm linux androideabi gcc error unrecognized command line op
  • 字符串数组文本格式化

    我有这个字符串 String text Address 1 Street nr 45 Address 2 Street nr 67 Address 3 Street nr 56 n Phone number 000000000 稍后将被使用
  • Android:膨胀布局时出现 StackOverFlowError 和 InvokingTargetException

    首先 对不起我的英语 我在膨胀布局时有一个问题 我有一个自定义视图 从 LinearLayout 扩展而来 称为按钮帮助 我在名为的布局上使用该视图加载活动 我的以下代码在所有设备和模拟器上都能完美运行 但具有 QVGA 屏幕 例如 Sam
  • 将 Intent 包装在 LabeledIntent 中以用于显示目的

    要求 我的应用程序中有一个 共享 按钮 我需要通过 Facebook 分享 我需要选择是否安装原生 Facebook 应用程序 我们的决定是 如果未安装该应用程序 则将用户发送到 facebook com 进行分享 当前状态 我可以检测何时
  • 将两个文本视图并排放置在布局中

    我有两个文本视图 需要在布局中并排放置 并且必须遵守两条规则 Textview2 始终需要完整显示 如果布局中没有足够的空间 则必须裁剪 Textview1 例子 文本视图1 文本视图2 Teeeeeeeeeeeeeeeeeextview1

随机推荐

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

    隐藏类变量的情况在 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 上完成的 其硬件