我是RenderScript的新手并试图处理大小为1920x1280px的图像,这似乎每次都会在logcat上出现以下错误而崩溃
09-04 19:26:04.670: D/dalvikvm(30308): GC_FOR_ALLOC freed 73K, 3% free 6615K/6787K, paused 26ms
09-04 19:26:04.680: I/dalvikvm-heap(30308): Grow heap (frag case) to 14.404MB for 8294416-byte allocation
09-04 19:26:04.690: D/dalvikvm(30308): GC_CONCURRENT freed 2K, 2% free 14713K/14919K, paused 1ms+1ms
09-04 19:26:04.820: D/dalvikvm(30308): GC_FOR_ALLOC freed 0K, 2% free 14713K/14919K, paused 12ms
09-04 19:26:04.820: I/dalvikvm-heap(30308): Grow heap (frag case) to 17.917MB for 3686416-byte allocation
09-04 19:26:04.840: D/dalvikvm(30308): GC_FOR_ALLOC freed 0K, 2% free 18313K/18567K, paused 13ms
09-04 19:26:04.860: D/dalvikvm(30308): GC_CONCURRENT freed 0K, 2% free 18313K/18567K, paused 1ms+2ms
09-04 19:26:05.010: A/libc(30308): Fatal signal 11 (SIGSEGV) at 0x5c41f809 (code=1)
09-04 19:26:05.010: A/libc(30308): Fatal signal 11 (SIGSEGV) at 0x5c41e001 (code=1)
如果我将图像调整为100x56px,则相同的代码可以工作: - (。
请查看下面的代码并建议我需要进行的任何更改,代码基于我在互联网上和其他地方找到的示例。
注意:以下代码并非真正的生产质量。
VDRender.rs的内容
#pragma version(1)
#pragma rs java_package_name(com.iangclifton.tutorials.renderscript);
#include "rs_graphics.rsh"
const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
void root(const uchar4 *v_in, uchar4 *v_out) {
//rsDebug("Called ROOT - ONE", rsUptimeMillis());
float4 f4 = rsUnpackColor8888(*v_in);
float3 mono = dot(f4.rgb, gMonoMult);
*v_out = rsPackColorTo8888(mono);
}
RenderScript101.rs的内容
#pragma version(1)
#pragma rs java_package_name(com.iangclifton.tutorials.renderscript);
#include "rs_graphics.rsh"
float4 gBgColor; // Background color as xyzw 4-part float
rs_allocation gBgImage; // Background image
rs_allocation gVDBgImage; // Background image
rs_sampler gLinearClamp; // Sampler used by the program fragment
rs_program_fragment gSingleTextureFragmentProgram; // fragment shader
rs_program_store gProgramStoreBlendNone; // blend none, depth none program store
rs_program_vertex gProgramVertex; // Default vertex shader
rs_script gVDScript;
static const float3 gBgVertices[4] = {
{ -1.0, -1.0, -1.0 },
{ 1.0, -1.0, -1.0 },
{ 1.0, 1.0, -1.0 },
{-1.0, 1.0, -1.0 }
};
void drawInteger(int value, int x, int y) {
char text[50] = "0";
int index = 0;
if(value != 0) {
index = 49;
text[index] = 0;
while(value > 0) {
index--;
int digitValue = value % 10;
text[index] = '0' + digitValue;
value /= 10;
}
if(value < 0) {
text[index--] = '-';
}
}
rsgDrawText(&text[index], x, y);
}
int64_t gTimeMS = 0;
int64_t updateFPS = 0;
int gFPS = 0;
static void drawBackground() {
if (gBgImage.p != 0) {
//rsgClearColor(gBgColor.x, gBgColor.y, gBgColor.z, gBgColor.w);
rs_matrix4x4 projection, model;
rsMatrixLoadOrtho(&projection, -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f);
rsgProgramVertexLoadProjectionMatrix(&projection);
rsMatrixLoadIdentity(&model);
rsgProgramVertexLoadModelMatrix(&model);
// ----
if(1)
{
rsForEach(gVDScript, gBgImage, gBgImage, NULL);
rsgBindTexture(gSingleTextureFragmentProgram, 0, gBgImage);
}
else
{
rsgBindTexture(gSingleTextureFragmentProgram, 0, gBgImage);
}
//----
rsgDrawQuad(
gBgVertices[0].x, gBgVertices[0].y, gBgVertices[0].z,
gBgVertices[1].x, gBgVertices[1].y, gBgVertices[0].z,
gBgVertices[2].x, gBgVertices[2].y, gBgVertices[0].z,
gBgVertices[3].x, gBgVertices[3].y, gBgVertices[0].z
);
int x = 250;
int y = 150;
int fps = 0;
int64_t t = rsUptimeMillis();
int diff = t - gTimeMS;
fps = 1000 / diff;
gTimeMS = t;
if((t - updateFPS) > 500)
{
gFPS = fps;
updateFPS = t;
}
rsgDrawText("FPS:", x, y);
drawInteger(gFPS, 250+40, 150);
}
}
void init() {
gBgColor = (float4) { 0.0f, 1.0f, 0.0f, 1.0f };
rsDebug("Called init", rsUptimeMillis());
}
int root() {
rsgBindProgramVertex(gProgramVertex);
rsgBindProgramFragment(gSingleTextureFragmentProgram);
rsgBindProgramStore(gProgramStoreBlendNone);
drawBackground();
return 1;
}
RenderScript101RS.java的内容
package com.iangclifton.tutorials.renderscript;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.renderscript.Allocation;
import android.renderscript.Float4;
import android.renderscript.Matrix4f;
import android.renderscript.ProgramFragment;
import android.renderscript.ProgramFragmentFixedFunction;
import android.renderscript.ProgramStore;
import android.renderscript.ProgramVertex;
import android.renderscript.ProgramVertexFixedFunction;
import android.renderscript.RenderScriptGL;
import android.renderscript.Sampler;
/**
* Custom RenderScript helper that simplifies interaction with the RenderScript.
*
* @author Ian G. Clifton
*/
public class RenderScript101RS {
private Sampler mLinearClamp;
private ProgramStore mProgramStoreBlendNone;
private ProgramVertex mProgramVertex;
private RenderScriptGL mRS;
private ScriptC_RenderScript101 mScript;
private ScriptC_VDRender mVDScript;
private ProgramFragment mSingleTextureFragmentProgram;
/**
* Constructs a new helper with RenderScriptGL and Resources references.
*
* @param rs RenderScriptGL reference
* @param res Resources reference
* @param resId int ID of the RenderScript (e.g., R.raw.xyz)
*/
public RenderScript101RS(RenderScriptGL rs, Resources res, int resId, int resId2) {
mRS = rs;
mScript = new ScriptC_RenderScript101(rs, res, resId);
mVDScript = new ScriptC_VDRender(rs, res, resId2);
mScript.set_gVDScript(mVDScript);
initProgramStore();
initSampler();
initProgramFragment();
initProgramVertex();
mRS.bindRootScript(mScript);
}
/**
* Sets a custom background Bitmap on the RenderScript view
*
* @param bitmap Bitmap to use as the background
*/
public void setBackgroundBitmap(Bitmap bitmap) {
if (bitmap == null) {
return;
}
final Allocation bitmapAllocation = Allocation.createFromBitmap(mRS, bitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE);
mScript.set_gBgImage(bitmapAllocation);
//final Allocation bitmapVDAllocation = Allocation.createFromBitmap(mRS, bitmap, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE);
//mScript.set_gVDBgImage(bitmapVDAllocation);
}
/**
* Sets a custom background color on the RenderScript view
*
* @param color Float4 color
*/
public void setBackgroundColor(Float4 color) {
mScript.set_gBgColor(color);
}
/**
* Prepares the ProgramFragment (fragment shader)
*/
private void initProgramFragment() {
final ProgramFragmentFixedFunction.Builder pfBuilder = new ProgramFragmentFixedFunction.Builder(mRS);
pfBuilder.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE, ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
mSingleTextureFragmentProgram = pfBuilder.create();
mScript.set_gSingleTextureFragmentProgram(mSingleTextureFragmentProgram);
}
/**
* Prepares the ProgramStore (controls use of framebuffer such as blending)
*/
private void initProgramStore() {
mProgramStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(mRS);
mScript.set_gProgramStoreBlendNone(mProgramStoreBlendNone);
}
/**
* Prepares the ProgramVertex (vertex shader)
*/
private void initProgramVertex() {
ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
mProgramVertex = pvb.create();
ProgramVertexFixedFunction.Constants pva = new ProgramVertexFixedFunction.Constants(mRS);
((ProgramVertexFixedFunction) mProgramVertex).bindConstants(pva);
Matrix4f proj = new Matrix4f();
proj.loadProjectionNormalized(1, 1);
pva.setProjection(proj);
mScript.set_gProgramVertex(mProgramVertex);
}
/**
* Prepares the Sampler (controls how pixels are pulled from a texture)
*/
private void initSampler() {
mLinearClamp = Sampler.CLAMP_LINEAR(mRS);
mScript.set_gLinearClamp(mLinearClamp);
}
}
RenderScript101View的内容
package com.iangclifton.tutorials.renderscript;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.renderscript.RSSurfaceView;
import android.renderscript.RenderScriptGL;
import android.view.MotionEvent;
/**
* Custom RSSurfaceView that sets up the RenderScript and captures touch events.
*
* @author Ian G. Clifton
*/
public class RenderScript101View extends RSSurfaceView {
private Context mContext;
private RenderScript101RS mRenderScript;
private RenderScriptGL mRS;
/**
* {@inheritDoc}}
*/
public RenderScript101View(Context context) {
super(context);
mContext = context;
ensureRenderScript();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
if (mRenderScript == null) {
return true;
}
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mRenderScript.setBackgroundBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.icon00072half));
}
return true;
}
/**
* Ensures the RenderScriptGL reference has been established and our custom
* RS helper has been created.
*/
private void ensureRenderScript() {
if (mRS == null) {
final RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
mRS = createRenderScriptGL(sc);
}
if (mRenderScript == null) {
mRenderScript = new RenderScript101RS(mRS, mContext.getResources(), R.raw.renderscript101, R.raw.vdrender);
}
}
}
答案 0 :(得分:3)
您的LogCat中没有异常或警告,但我可能知道这个问题。
首先,我甚至没有看你的RenderScript,因为你说它适用于小位图。
在android中,每个VM或进程都有自己的内存部分,这对于位图1920x1080来说基本上是不够的。所以你的logcat应该有一些你可能忽略的提示:
bitmap size exceeds VM budget
我不知道您的实现细节(获取位图表单服务器,本地文件等)。所以我会引导你去Android Bitmap Training。
一般的想法是根据需要加载图像。通过这个:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
关键部分:
options.inJustDecodeBounds = true;
说嘿!不要解码和加载位图。我会对我的Bitmap进行一些设置。