渲染脚本渲染在Android上比OpenGL渲染慢很多

2024-05-06

背景:

我想根据Android相机应用程序的代码添加实时滤镜。但Android相机应用程序的架构是基于OpenGL ES 1.x。我需要使用着色器来自定义我们的过滤器实现。然而,将相机应用程序更新到OpenGL ES 2.0太困难了。然后我必须找到一些其他方法来实现实时滤镜而不是OpenGL。经过一番研究后我决定使用渲染脚本。

PROBLEM:

我已经通过渲染脚本编写了一个简单过滤器的演示。它表明fps比OpenGL实现的要低得多。大约 5 fps 与 15 fps。

问题:

  1. Android官方场外表示:RenderScript运行时将在设备上所有可用的处理器(例如多核CPU、GPU或DSP)上并行工作,让您专注于表达算法而不是调度工作或负载平衡。那么为什么渲染脚本执行速度较慢呢?

  2. 如果渲染脚本不能满足我的要求,有更好的方法吗?

代码详细信息:

你好,我和提问者在同一个团队。我们想编写一个基于渲染脚本的实时滤镜相机。在我们的测试演示项目中,我们使用一个简单的过滤器:添加了覆盖过滤器 ScriptC 脚本的 YuvToRGB IntrinsicScript。 在OpenGL版本中,我们将相机数据设置为纹理,并使用着色器进行图像过滤处理。像这样:

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureYHandle);
    GLES20.glUniform1i(shader.uniforms.get("uTextureY"), 0);
    GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, mTextureWidth,
            mTextureHeight, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE,
            mPixelsYBuffer.position(0));

在RenderScript版本中,我们将相机数据设置为Allocation,并使用script-kernals进行图像过滤处理。像这样:

    // The belowing code is from onPreviewFrame(byte[] data, Camera camera) which gives the camera frame data 
    byte[] imageData = datas[0];
    long timeBegin = System.currentTimeMillis();
    mYUVInAllocation.copyFrom(imageData);

    mYuv.setInput(mYUVInAllocation);
    mYuv.forEach(mRGBAAllocationA);
    // To make sure the process of YUVtoRGBA has finished!
    mRGBAAllocationA.copyTo(mOutBitmap);    
    Log.e(TAG, "RS time: YUV to RGBA : " + String.valueOf((System.currentTimeMillis() - timeBegin)));   

    mLayerScript.forEach_overlay(mRGBAAllocationA, mRGBAAllocationB);
    mRGBAAllocationB.copyTo(mOutBitmap);    
    Log.e(TAG, "RS time: overlay : " + String.valueOf((System.currentTimeMillis() - timeBegin)));

    mCameraSurPreview.refresh(mOutBitmap, mCameraDisplayOrientation, timeBegin);

这两个问题是: (1) RenderScript 进程似乎比 OpenGL 进程慢。 (2)根据我们的时间日志,使用内部脚本的YUV到RGBA的过程非常快,大约需要6ms;但是使用scriptC的overlay过程非常慢,大约需要180ms。这是怎么发生的?

这是我们使用的脚本(pLayScript)的rs内核代码:

#pragma version(1)
#pragma rs java_package_name(**.renderscript)
#pragma stateFragment(parent)

#include "rs_graphics.rsh"

static rs_allocation layer;
static uint32_t dimX;
static uint32_t dimY;

void setLayer(rs_allocation layer1) {
    layer = layer1;
}

void setBitmapDim(uint32_t dimX1, uint32_t dimY1) {
    dimX = dimX1;
    dimY = dimY1;
}

static float BlendOverlayf(float base, float blend) {
    return (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)));
}

static float3 BlendOverlay(float3 base, float3 blend) {
    float3 blendOverLayPixel = {BlendOverlayf(base.r, blend.r), BlendOverlayf(base.g, blend.g), BlendOverlayf(base.b, blend.b)};
    return blendOverLayPixel;
}

uchar4 __attribute__((kernel)) overlay(uchar4 in, uint32_t x, uint32_t y) {
    float4 inPixel = rsUnpackColor8888(in);

    uint32_t layerDimX = rsAllocationGetDimX(layer);
    uint32_t layerDimY = rsAllocationGetDimY(layer);

    uint32_t layerX = x * layerDimX / dimX;
    uint32_t layerY = y * layerDimY / dimY;

    uchar4* p = (uchar4*)rsGetElementAt(layer, layerX, layerY);
    float4 layerPixel = rsUnpackColor8888(*p);

    float3 color = BlendOverlay(inPixel.rgb, layerPixel.rgb);

    float4 outf = {color.r, color.g, color.b, inPixel.a};
    uchar4 outc = rsPackColorTo8888(outf.r, outf.g, outf.b, outf.a);

    return outc;
}

Renderscript 不使用任何 GPU 或 DSP 内核。这是谷歌故意模糊的文档所助长的一种常见误解。 Renderscript 曾经有一个 OpenGL ES 接口,但已被弃用,并且从未用于动画壁纸之外的其他用途。 Renderscript 将使用多个 CPU 核心(如果可用),但我怀疑 Renderscript 将被 OpenCL 取代。

查看 Android SDK 中的 Effects 类和 Effects 演示。它展示了如何使用 OpenGL ES 2.0 着色器将效果应用于图像,而无需编写 OpenGL ES 代码。

http://software.intel.com/en-us/articles/porting-opengl-games-to-android-on-intel-atom-processors-part-1 http://software.intel.com/en-us/articles/porting-opengl-games-to-android-on-intel-atom-processors-part-1

UPDATE:

当我学会回答问题比提出问题更多时,这真是太棒了,这里就是这种情况。从缺乏答案可以看出,Renderscript 在 Google 之外几乎没有使用,因为它的奇怪架构忽略了 OpenCL 等行业标准,而且几乎不存在关于其实际工作原理的文档。 尽管如此,我的回答确实引起了 Renderscrpt 开发团队的罕见回应,其中仅包含一个实际包含有关 renderscript 的任何有用信息的链接 - PowerVR GPU 供应商 IMG 的 Alexandru Voica 撰写的这篇文章:

http://withimagination.imgtec.com/index.php/powervr/running-renderscript-efficiently-with-powervr-gpus-on-android http://withimagination.imgtec.com/index.php/powervr/running-renderscript-efficiently-with-powervr-gpus-on-android

那篇文章有一些对我来说是新的好信息。有更多人发表评论,表示 Renderscript 代码在 GPU 上实际运行时遇到困难。

但是,我错误地认为 Google 不再开发 Renderscript。尽管我声明“Renderscript 不使用任何 GPU 或 DSP 内核”。直到最近,情况都是如此,我了解到,从果冻豆版本之一开始,这种情况已经发生了变化。 如果 Renderscript 开发人员之一能够解释这一点,那就太好了。或者即使他们有一个公共网页来解释或列出 实际上支持哪些 GPU 以及如何判断您的代码是否真正在 GPU 上运行。

我的观点是,Google 最终将用 OpenCL 取代 Renderscript,我不会投入时间用它进行开发。

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

渲染脚本渲染在Android上比OpenGL渲染慢很多 的相关文章

  • 如何在 Android 上为 Facebook 的应用程序制作新菜单? [复制]

    这个问题在这里已经有答案了 可能的重复 Android facebook 风格幻灯片 https stackoverflow com questions 8657894 android facebook style slide 最近 Fac
  • 使用kivy/python访问android手电筒(相机LED闪光灯)

    我不知道如何使用 python 或 kivy 访问 android 上的 led 灯 我尝试安装 python for android 以便能够将 android 模块导入到我的代码中 但不是找不到模块 我按照此处的说明克隆了 python
  • 动态添加 TextView - Android

    如何动态添加 TextView 到此 注释掉的代码不起作用 public class myTextSwitcher extends Activity private TextView myText public myTextSwitcher
  • android 4 中的 android RadioButton 问题

    我有一个简单的应用程序 屏幕是在相对布局内构建的 我还有 LinearLayout s 其中之一显示 2 个 RadioButton s 如下所示
  • 如何处理 Jetpack Compose 中的导航?

    在 Jetpack Compose 中 导航应该如何完成 所有 并不多 示例 包括来自 Google 的官方示例 都使用密封类并加载新屏幕以响应观察当前屏幕的变化 这确实 有点 有效 但不提供导航返回堆栈 并且手机的后退按钮完全不知道 只是
  • 使用应用程序上下文滑动图像加载

    我在我的 Android 应用程序中使用 glide 进行图像加载 为了避免任何崩溃 我正在使用应用程序上下文加载图像 这对应用程序和内存的性能有何影响 这对应用程序和内存的性能有何影响 Glide提供了这么多 with 方法是有原因的 它
  • 在 CustomAdapters 中使用条件 if(view==null)

    我正在为 ListView 编写一个自定义适配器 它扩展了 BaseAdapter 并在此方法中 Override public View getView int position View convertView ViewGroup pa
  • 如何安全地更改Android Studio中的项目名称?

    我想更改Android Studio中的项目名称 我在 Stackoverflow 上找到了一些答案 但它对我不起作用 请给我推荐一些合适的解决方案 目前我正在使用 Android Studio 2 3 永远感谢 您需要执行几个步骤 首先转
  • 找不到具有不同构建变量的包名称“....”的匹配客户端

    我想实现推送通知 我添加到项目级别 dependencies classpath com android tools build gradle 2 2 2 classpath com google gms google services 3
  • 反序列化时出现 Gson 异常(无参数构造函数不存在)

    我遇到了一个问题 该问题仅在 5000 台设备中的 10 台中出现 无法用我的模拟器和测试设备重现它 这似乎是一个非常具体的问题 仅涉及少数设备 我所拥有的只是堆栈跟踪和我的代码 因此 我正在针对黑洞进行开发 只有在 GooglePlay
  • Firebase 实时数据库 .info/connected 本应为 True 时为 False

    我有一个 Android 服务 它的调用地址为onCreate FirebaseDatabase database FirebaseDatabase getInstance database getReference info connec
  • Android中如何检测程序的终止?

    当 Windows 程序终止时 它会调用事件处理程序 例如 OnClose OnDestroy 和析构函数 Destroy 当我想保存一些 INI 设置时 这些地方就是我要保存的地方 我为所有这些事件编写了事件处理程序 但当我终止程序时它们
  • 如何使用远程 URL 在 Android 模拟器中播放 mp4 视频?

    如何使用远程 URL 在 Android 模拟器中播放 mp4 视频 我使用了以下代码 但此代码给我错误 抱歉 该视频无法播放 07 05 16 58 19 525 INFO AwesomePlayer 34 mConnectingData
  • android,如何重命名文件?

    在我的应用程序中 我需要录制视频 在开始录制之前 我为其指定名称和目录 录制完成后 用户可以重命名其文件 我写了以下代码 但似乎不起作用 当用户输入文件名并单击按钮时 我将执行以下操作 private void setFileName St
  • VideoView中的seekTo

    我在寻找视频时遇到问题 我的应用程序应该从上次停止的位置恢复视频 所以我这样做 videoView seekTo bookmark videoView start 然而 当它播放时 我听到视频开头的声音大约 1 2 秒 只有在该视频寻找到正
  • 在没有 SurfaceView 的 Android 上获取 GPU 信息

    在Android上 有没有一种方法可以在不创建SurfaceView的情况下获取GPU信息 我不想使用 OpenGL 绘制任何内容 但我只需要获取硬件信息 例如供应商 OpenGL ES 版本 可用扩展等 抱歉 我不知道如何在 Androi
  • 如何在不打开浏览器的情况下查看 Android 应用程序中的网页?

    嘿 我正在开发一个 Android 应用程序 我想连接到该应用程序内的网络 不过 我在某种程度上尝试过 WebView 但它在我的目录中显示的文件很好 但当连接到 google com 时 它显示错误 然后我添加了这个文件
  • 在大画布上滚动

    我需要一些帮助来了解滚动绘制到 Android 画布上的项目的基础知识 假设我想创建一个时间线 其中 0 处的时间是可视化的顶部 并且随着时间的增加 时间线继续呈现在上一个点下方 如果我想在 Android 上渲染它 我知道我可以通过重写
  • java.io.IOException:Android Firebase 中的 FIS_AUTH_ERROR 但调试模式正常

    我在检索 firebase 令牌时遇到以下问题 FirebaseMessaging getInstance getToken 在调试模式下 我获取令牌并将其发送到服务器 在运行模式下 应用程序工作正常 它已发布 但我无法获取令牌 因为我已经
  • Android:如何实现“分布式控制”

    对于与 Android 开发者论坛的交叉发帖表示歉意 那里没有收到任何答复 我有一个有趣的设计挑战 我有一个前端 Activity 和一个后端 用本机 C C 编写 代码 后端是一个复杂的对象 它部分控制 应用程序流程一旦启动就在它自己的线

随机推荐

  • 变基后无法推送到分支

    我们使用 git 并有一个 master 分支和开发人员分支 我需要添加一个新功能 然后将提交重新设置为 master 然后将 master 推送到 CI 服务器 问题是 如果我在变基期间发生冲突 我无法在变基完成后推送到我的远程开发人员分
  • 使用 SearchView 后重置操作栏

    我在用着SearchView小部件以在我的应用程序中启用搜索 首次单击搜索图标后 SearchView小部件会扩展到搜索字段 并且应用程序图标旁边会显示 后退 箭头 如果我单击应用程序图标 操作栏将恢复到初始状态 没有 后退 箭头 并且Se
  • 如何在 R 中使用相对路径从 mac 上的目录读取数据?

    我正在编写需要同时适用于 Mac 和 Windows 用户的代码 所有用户的计算机上都有 google 驱动器目录的本地副本 我有一段代码可以自动将工作目录设置为源文件位置 我们将此目录称为 directory1 在directory1 中
  • 用户输入时的空闲时间

    我遇到的问题是一个搜索函数 它应该调用我的doSearch 用户在我的系统中停止输入至少 100 毫秒后的方法 input q field 我试图通过使用这个逻辑来实现这一点answer https stackoverflow com a
  • 检测“文件下载”弹出窗口何时关闭

    我有一个网页 用 JSF 制作 其中一些链接允许用户获取 PDF 文件 当用户点击这样的链接时 会显示一个等待弹出窗口 它是一个模式面板 因为 PDF 的生成可能很长 并且一旦创建文件 IE 就会显示 文件下载 弹出窗口 建议 打开 保存
  • 从 GetLastError() 函数返回的错误代码中获取文本

    我需要获取从 GetLastError 函数获得的错误代码的文本 我看到了一些示例 但我想要一个获取代码并返回字符串的函数 谢谢大家 我猜你想要这样的东西 DWORD dwLastError GetLastError TCHAR lpBuf
  • RxJava - 链接请求和更新 UI

    我遇到的问题是这样的 我需要向服务器执行几个请求 下一个请求取决于前一个请求的结果 它们看起来像这样 缩写 Observable
  • 如何调试(最好在 IDE 中)MSBuild 脚本?

    我们非常广泛地使用 MSBuild 作为我们持续集成过程的一部分 虽然它非常强大 我们几乎可以在其中完成所有构建 测试和部署 利用一些自定义任务 我们发现使用标签对其进行调试是一种痛苦 并且不能总是为我们提供足够的信息 我发现 http w
  • 调用事件,h(args) 与 EventName?.Invoke()

    我总是这样调用事件 void onSomeEvent string someArg var h this EventName if h null h this new MyEventArgs someArg 今天 VS 2015 告诉我这可
  • 为什么 getSession() 在短时间内间隔的后续请求中不返回相同的会话?

    我正在发送一个 getJSON HTTP GET 请求两次 使用不同的数据 一次又一次 假设我们有 request1 和 request2 我可以在 FF 和 Chrome 的开发者工具中看到我有相同的cookie JSESSIONID F
  • 使用 leaflet.js 在点周围添加设定大小的正方形多边形

    有点奇怪 希望有人能帮忙 在传单中 一旦用户输入了纬度 经度并向地图添加了一个点 我希望能够在该点周围添加一个 10 公里的正方形 我尝试四处寻找计算方法来找到 x 公里外的正方形角点 但没有挖出任何东西 但肯定有更简单的方法 有人有想法吗
  • 如何在 Django 中创建多选框?

    我正在尝试创建多选框字段来自姜戈选择 2 https github com applegrew django select2库如下图所示 我使用了下一个代码 但它返回简单的选择多个小部件 我想我忘了补充一些东西 我的错误在哪里 有人可以告诉
  • 使用 stringstreams 将字符串转换为 __uint128_t

    我正在尝试从字符串中提取不同类型的数据 void readHeader char buf BUFFSIZE std istringstream hdr buf uint128 t id client hdr gt gt id client
  • C++:初始化结构体并设置函数指针

    我正在尝试使用函数指针初始化结构 但是除非使用全局函数完成 否则我很难这样做 以下代码有效 float tester float v return 2 0f v struct MyClass Example typedef float My
  • 为什么 Visual Studio 2019 不会运行我的单元测试?

    我在 VS2019 中看到 NUnit 测试的一些非常奇怪的行为 而相同的解决方案在 VS2017 中运行良好 我的脑海里有几个 NUnit 测试项目 在安装了 NUnit Runner 扩展的 VS2017 中 我可以在 测试资源管理器
  • 使用 java 执行 Matlab 函数

    我正在编写一个应用程序 它使用 matlab 进行图像处理 然后使用 Java 接口显示结果 由于某些原因 我必须同时使用 Java 和 Matlab 如何在java中使用matlab函数 如何创建和访问界面 MATLAB控制 http m
  • 有没有办法通过 Outlook API 获取建议的联系人?

    我目前正在开发一个应用程序来获取我的 Microsoft 帐户中的联系人 问题是 与 Google 不同 当我向新联系人发送电子邮件或从新联系人接收电子邮件时 该电子邮件不会复制到 我的联系人 中 因此我无法通过该电子邮件https out
  • 如何修复 Visual Studio Code 终端中的“分段错误”错误?

    在 Windows 10 上 我安装了 Visual Studio Code 当我打开终端 Git Bash 并输入less watch compiler 我收到错误 分段故障 但是如果我转到 Git Bash 终端本身 在 Visual
  • 重新创建 Siri 按钮发光动画

    有没有办法复制 Siri 按钮发光动画 它看起来绝对华丽 但我现在不知道如何开始 是否有在线预格式化的旋转PNG 或者是用CoreAnimation完成的 我相信 Siri 动画是用 CAEmitterLayer 和 CAEmitterCe
  • 渲染脚本渲染在Android上比OpenGL渲染慢很多

    背景 我想根据Android相机应用程序的代码添加实时滤镜 但Android相机应用程序的架构是基于OpenGL ES 1 x 我需要使用着色器来自定义我们的过滤器实现 然而 将相机应用程序更新到OpenGL ES 2 0太困难了 然后我必