appspell/ShaderView

Throws an exception if the same bitmap is passed multiple times

Closed this issue · 3 comments

I've put this code in the onBindViewHolder function in a recycler view, and it keeps throwing exceptions about the bitmap being recycled.

shaderView.shaderParams?.updateParam(
    "albedo", Param(
        Param.ValueType.SAMPLER_2D,
        value = TextureParam(
            bitmap = lastCoverBitmap,
            textureSlot = GLES30.GL_TEXTURE0
        )
    )
)

The exception:

java.lang.IllegalArgumentException: bitmap is recycled
    at android.opengl.GLUtils.texImage2D(GLUtils.java:152)
    at com.appspell.shaderview.ext.TextureKt.toGlTexture(Texture.kt:66)
    at com.appspell.shaderview.gl.params.ShaderParamsImpl.bindTextures(ShaderParamsImpl.kt:153)
    at com.appspell.shaderview.gl.params.ShaderParamsImpl.bindParams(ShaderParamsImpl.kt:74)
    at com.appspell.shaderview.gl.shader.GLShaderImpl.bindParams(GLShaderImpl.kt:89)
    at com.appspell.shaderview.ShaderView.initShaders(ShaderView.kt:177)
    at com.appspell.shaderview.ShaderView.access$initShaders(ShaderView.kt:28)
    at com.appspell.shaderview.ShaderView$rendererListener$1.onSurfaceCreated(ShaderView.kt:92)
    at com.appspell.shaderview.gl.render.GLQuadRenderImpl.onSurfaceCreated(GLQuadRender.kt:90)
    at com.appspell.shaderview.gl.view.GLTextureView$GLThread.guardedRun(GLTextureView.kt:1507)
    at com.appspell.shaderview.gl.view.GLTextureView$GLThread.run(GLTextureView.kt:1223)

I'm not sure yet, but maybe it's caused by bitmap?.toGlTexture(needToRecycle = true, textureParam.textureSlot) in the ShaderParamsImpl.bindTextures function
Maybe I'll try to fix it myself, but can't promise anything

UPDATE:
I forked the repo and tried to fix it, but have no idea of how to test it, cause it seems incompatible with jitpack, and jfrog/jcenter seems like it's a paid service, idk

Should I open a pull request, even though I haven't tested it?

Should I open a pull request, even though I haven't tested it?

@leoxshn please, open, I will test it. Sorry for the long delay with the answer.

@leoxshn
I didn't expect that it's needed to change bitmap for each onBind().
Could you describe your use case where you need to update the bitmap on each binding?

Nevertheless, I've added a new API:

Bitmap:

shaderView?.shaderParams?.updateValue2D("albedo", bitmap)

or for drawable:

shaderParams?.updateValue2D("albedo", R.drawable.albedo)

Here is a PR: https://github.com/appspell/ShaderView/pull/9/files

Could you describe your use case where you need to update the bitmap on each binding?

I was making an android launcher, that has a feed, where one of the cards is a music player, and wanted to use a shader to stretch the music covers to fit the card without distorting them in an ugly way, and also add a little blur.

Thanks a lot for the new API

Also I don't technically update it for each onBind() anymore, just when the cover changes