背景:
我想根据 Android 相机应用程序的代码添加实时滤镜。但是Android相机应用程序的架构是基于OpenGL ES 1.x的。我需要使用着色器来自定义我们的过滤器实现。但是,将相机应用程序更新到 OpenGL ES 2.0 太难了。然后我必须找到一些其他方法来实现实时过滤器而不是 OpenGL。经过一番研究,我决定使用渲染脚本。
问题:
我已经通过渲染脚本编写了一个简单的过滤器演示。它表明 fps 比通过 OpenGL 实现它要低得多。大约 5 fps 与 15 fps。
问题:
Android 官方 offsite 说:RenderScript 运行时将跨设备上可用的所有处理器并行工作,例如多核 CPU、GPU 或 DSP,让您专注于表达算法而不是调度工作或负载均衡。那为什么render script执行的比较慢呢?
如果渲染脚本不能满足我的要求,有没有更好的办法?
代码详情:
嗨,我和提问者在同一个团队。我们想编写一个基于渲染脚本的实时滤镜相机。在我们的测试演示项目中,我们使用了一个简单的过滤器:一个添加了覆盖过滤器 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 执行 image-filter-procss。像这样:
// 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) 根据我们的time-log,使用intrinsic script的YUV转RGBA的过程非常快,大约需要6ms;但是使用scriptC的覆盖过程很慢,大约需要180ms。这是怎么发生的?
这里是我们使用的ScriptC(mLayerScript)的rs-kernal代码:
#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 的接口(interface),但是已经被弃用并且除了动画壁纸之外从未被用于太多。 Renderscript 将使用多个 CPU 内核(如果可用),但我怀疑 Renderscript 将被 OpenCL 取代。
查看 Android SDK 中的 Effects 类和 Effects 演示。它展示了如何在不编写 OpenGL ES 代码的情况下使用 OpenGL ES 2.0 着色器将效果应用于图像。
更新:
当我回答一个问题比问一个问题学到更多时,这真是太好了,这里就是这种情况。从缺乏答案可以看出,Renderscript 几乎没有在 Google 之外使用,因为它的奇怪架构忽略了 OpenCL 等行业标准,并且几乎不存在关于它如何实际工作的文档。 尽管如此,我的回答确实引起了 Renderscrpt 开发团队的罕见回应,其中只有一个链接实际上包含有关 renderscript 的任何有用信息——这篇由 PowerVR GPU 供应商 IMG 的 Alexandru Voica 撰写的文章:
那篇文章有一些很好的信息,这对我来说是新的。有更多人在 GPU 上实际运行 Renderscript 代码时遇到问题,他们发表了评论。
但是,我认为 Google 不再开发 Renderscript 是错误的。尽管我声明“Renderscript 不使用任何 GPU 或 DSP 内核”。直到最近才如此,我了解到这已经改变了 Jelly Bean 的一个版本。 如果其中一位 Renderscript 开发人员能够解释这一点,那就太好了。或者即使他们有一个公共(public)网页来解释那个或那个列表 实际支持哪些 GPU,以及如何判断您的代码是否确实在 GPU 上运行。
我的观点是 Google 最终会用 OpenCL 取代 Renderscript,我不会花时间用它进行开发。
关于android - 渲染脚本渲染比 Android 上的 OpenGL 渲染慢很多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21774211/
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
我有一个在Linux服务器上运行的ruby脚本。它不使用rails或任何东西。它基本上是一个命令行ruby脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
//1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路