How to share a Renderscript allocation with OpenGL in Android

匿名 (未验证) 提交于 2019-12-03 02:50:02

问题:

I have a Renderscript which processes an image that is given in output to an Allocation. I want to use this Allocation as a texture in my OpenGL program but I don't know how to get a texture ID from the Allocation.

On the other hand, I know I could use a graphic Renderscript, but since it has been deprecated, I guess there must be some other way to achieve the same result.

回答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.



回答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:

  1. Create a GL texture

  2. Create a SurfaceTexture using its ID

  3. Create an Allocation with usage Allocation.USAGE_IO_OUTPUT | Allocation.USAGE_SCRIPT

  4. Pass the SurfaceTexture to the Allocation with setSurface()

  5. Put data in the Allocation

  6. Call ioSend() on the Allocation to update the texture

  7. Repeat 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;  public class HelloCompute extends Activity {     private Bitmap mBitmapIn;      private RenderScript mRS;     private ScriptC_mono mScript;     private Allocation mSurfaceAllocation;     private Allocation mCanvasAllocation;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.main);          mBitmapIn = loadBitmap(R.drawable.data);         int x = mBitmapIn.getWidth();         int y = mBitmapIn.getHeight();          ImageView in = (ImageView) findViewById(R.id.displayin);         in.setImageBitmap(mBitmapIn);          mRS = RenderScript.create(this);         mScript = new ScriptC_mono(mRS, getResources(), R.raw.mono);          mCanvasAllocation = Allocation.createTyped(mRS,                  new Type.Builder(mRS, Element.RGBA_8888(mRS))                     .setX(x).setY(y).create(),                  Allocation.USAGE_IO_INPUT | Allocation.USAGE_SCRIPT);          mSurfaceAllocation = Allocation.createTyped(mRS,                  new Type.Builder(mRS, Element.RGBA_8888(mRS))                     .setX(x).setY(y).create(),                  Allocation.USAGE_IO_OUTPUT | Allocation.USAGE_SCRIPT);          TextureView mTextureView = (TextureView) findViewById(R.id.displayout);         mTextureView.setSurfaceTextureListener(           new TextureView.SurfaceTextureListener() {             @Override             public void onSurfaceTextureAvailable(SurfaceTexture s,                      int w, int h) {                 if(s != null) mSurfaceAllocation.setSurface(new Surface(s));                 mScript.forEach_root(mCanvasAllocation, mSurfaceAllocation);                 mSurfaceAllocation.ioSend();             }              @Override             public void onSurfaceTextureUpdated(SurfaceTexture s) {             }              @Override             public void onSurfaceTextureSizeChanged(SurfaceTexture s,                      int w, int h) {                 if(s != null) mSurfaceAllocation.setSurface(new Surface(s));             }              @Override             public boolean onSurfaceTextureDestroyed(SurfaceTexture s) {                 mSurfaceAllocation.setSurface(null);                 return true;             }         });          try {             Surface surface = mCanvasAllocation.getSurface();             Canvas canvas = surface.lockCanvas(new Rect(0,0,100,100));             canvas.drawBitmap(mBitmapIn, 0, 0, new Paint());             surface.unlockCanvasAndPost(canvas);             mCanvasAllocation.ioReceive();         } catch (IllegalArgumentException e) {             e.printStackTrace();         } catch (OutOfResourcesException e) {             e.printStackTrace();         }     }      private Bitmap loadBitmap(int resource) {         final BitmapFactory.Options options = new BitmapFactory.Options();         options.inPreferredConfig = Bitmap.Config.ARGB_8888;         return BitmapFactory.decodeResource(getResources(), resource, options);     } }


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!