How To Share A Renderscript Allocation With Opengl In Android
Solution 1:
Specify USAGE_IO_OUTPUT when you create the Allocation. Assuming you are generating the texture data in a script you would also add USAGE_SCRIPT. You can then call
Allocation.setSurface(theGLSurface)
to link the allocation to a texture. Each time you want to update the texture with the contents of the script you need to call.
Allocation.ioSend()
This will move the data without making extra copies.
Solution 2:
You have phrased the question in terms of transforming an Allocation into a texture, but it's easier to think of creating a texture then granting the Allocation ownership of that texture. This way, you would know the texture ID before passing it to the Allocation. Beware: the Allocation has the power to radically change properties of the texture.
Step by step:
Create a GL texture
Create a SurfaceTexture using its ID
Create an Allocation with usage
Allocation.USAGE_IO_OUTPUT | Allocation.USAGE_SCRIPT
Pass the SurfaceTexture to the Allocation with
setSurface()
Put data in the Allocation
Call
ioSend()
on the Allocation to update the textureRepeat steps 5 and 6 as often as you want to update the texture
I am very far from a GL expert, so step 2 is frankly conjecture.
Below is an adaptation of the HelloCompute sample in which I replace
displayout
with a TextureView,
which is a View that handily creates a texture and a SurfaceTexture for me.
From then on I follow the steps above.
package com.example.android.rs.hellocompute;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.os.Bundle;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.Type;
import android.view.Surface;
import android.view.Surface.OutOfResourcesException;
import android.view.TextureView;
import android.widget.ImageView;
publicclassHelloComputeextendsActivity {
private Bitmap mBitmapIn;
private RenderScript mRS;
private ScriptC_mono mScript;
private Allocation mSurfaceAllocation;
private Allocation mCanvasAllocation;
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mBitmapIn = loadBitmap(R.drawable.data);
intx= mBitmapIn.getWidth();
inty= mBitmapIn.getHeight();
ImageViewin= (ImageView) findViewById(R.id.displayin);
in.setImageBitmap(mBitmapIn);
mRS = RenderScript.create(this);
mScript = newScriptC_mono(mRS, getResources(), R.raw.mono);
mCanvasAllocation = Allocation.createTyped(mRS,
newType.Builder(mRS, Element.RGBA_8888(mRS))
.setX(x).setY(y).create(),
Allocation.USAGE_IO_INPUT | Allocation.USAGE_SCRIPT);
mSurfaceAllocation = Allocation.createTyped(mRS,
newType.Builder(mRS, Element.RGBA_8888(mRS))
.setX(x).setY(y).create(),
Allocation.USAGE_IO_OUTPUT | Allocation.USAGE_SCRIPT);
TextureViewmTextureView= (TextureView) findViewById(R.id.displayout);
mTextureView.setSurfaceTextureListener(
newTextureView.SurfaceTextureListener() {
@OverridepublicvoidonSurfaceTextureAvailable(SurfaceTexture s,
int w, int h) {
if(s != null) mSurfaceAllocation.setSurface(newSurface(s));
mScript.forEach_root(mCanvasAllocation, mSurfaceAllocation);
mSurfaceAllocation.ioSend();
}
@OverridepublicvoidonSurfaceTextureUpdated(SurfaceTexture s) {
}
@OverridepublicvoidonSurfaceTextureSizeChanged(SurfaceTexture s,
int w, int h) {
if(s != null) mSurfaceAllocation.setSurface(newSurface(s));
}
@OverridepublicbooleanonSurfaceTextureDestroyed(SurfaceTexture s) {
mSurfaceAllocation.setSurface(null);
returntrue;
}
});
try {
Surfacesurface= mCanvasAllocation.getSurface();
Canvascanvas= surface.lockCanvas(newRect(0,0,100,100));
canvas.drawBitmap(mBitmapIn, 0, 0, newPaint());
surface.unlockCanvasAndPost(canvas);
mCanvasAllocation.ioReceive();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (OutOfResourcesException e) {
e.printStackTrace();
}
}
private Bitmap loadBitmap(int resource) {
final BitmapFactory.Optionsoptions=newBitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
return BitmapFactory.decodeResource(getResources(), resource, options);
}
}
Post a Comment for "How To Share A Renderscript Allocation With Opengl In Android"