简体   繁体   English

如何在定时器中使用 OpenGL

[英]How to use OpenGL with Timer

The following code works when I load all bitmaps beforehand (with testing data)当我预先加载所有位图(带有测试数据)时,以下代码有效

for (bitmap in bitmaps){
  feedInOpenGL(bitmap)  
}

But when I try to create the bitmap using a timer,但是当我尝试使用计时器创建位图时,

timer!!.scheduleAtFixedRate(object : TimerTask() {
            override fun run() {
                if (!recording) return
                val bitmap = getNextBitmap()
                feedInOpenGL(bitmap)
            }
        }, 0, frameDuration)

I cannot stop the MediaMuxer anymore.我再也无法停止 MediaMuxer。 When I try to stop it, it get当我试图阻止它时,它得到

D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.tolotra.screenrecordexample, PID: 31248
    java.lang.IllegalStateException: Failed to stop the muxer
        at android.media.MediaMuxer.nativeStop(Native Method)
        at android.media.MediaMuxer.stop(MediaMuxer.java:454)
        at com.tolotra.screen_recorder.VideoBuilder._cleanUp(VideoBuilder.kt:292)
        at com.tolotra.screen_recorder.VideoBuilder.finish(VideoBuilder.kt:95)
        at com.tolotra.screen_recorder.ScreenRecorder$stop$1.run(ScreenRecorder.kt:156)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6734)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

After digging, I read somewhere挖掘后,我在某处阅读

OpenGL always operates on a context that is made "current" and the context holds data in thread-local storage. OpenGL 始终在“当前”上下文上运行,并且该上下文将数据保存在线程本地存储中。 This means it's thread-specific.这意味着它是特定于线程的。 Therefore you always need to be aware from which thread you're calling the OpenGL functions.因此,您始终需要了解从哪个线程调用 OpenGL 函数。

So I suspect that the problem is that my timer is the issue because it creates a new thread every time.所以我怀疑问题在于我的计时器是问题,因为它每次都会创建一个新线程。

If my suspicion is true, how to I make this work with a timer ?如果我的怀疑是真的,我如何使用计时器进行这项工作?

The solution is to Run the OpenGL/MediaMuxer/MediaEncoder setup/start/stop and timer callback on the same thread.解决方案是在同一线程上运行 OpenGL/MediaMuxer/MediaEncoder setup/start/stop 和计时器回调。 This is achieved using single threaded executor这是使用单线程执行器实现的

tpe = Executors.newSingleThreadExecutor()
        tpe?.submit(Runnable {
            this.recording = true;
            _startRecorderWorker();
        })

And in the timer在计时器中

 timer!!.scheduleAtFixedRate(object : TimerTask() {
            override fun run() {
                if (!recording) return;
                tpe?.submit(Runnable {
                    loop()
                })

            }
        }, 0, frameDuration)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM