zoukankan      html  css  js  c++  java
  • GLSurfaceView queueEvent的作用

    使用OpenGL的时候,我们需要一个工作线程来调用OpenGL方法。GLSurfaceView为此创建了一个独立的渲染线程,这也是所有实现GLSurfaceView.Renderer中的方法(这些方法包装了调用OpenGL的细节,简化了开发)的工作线程。所以我们不需要关心线程相关的东西,只需要编写需要实现的方法即可。

    基于线程原因,我们不能简单的在UI线程中调用OpenGL方法,例如,事件分发的方法中我们直接调用Renderer中的方法。除此之外,我们还需要考虑线程安全问题,即同时被UI线程和OpenGL渲染线程读写的变量。

    使用queueEvent(),则完全不必担心上述问题,因为最终所有方法都是在GLSUrfaceView.Renderer中的方法中调用的,也就是在渲染线程中使用的。

    看看源码中该函数的调用流程:

    /**
     * Queue a runnable to be run on the GL rendering thread. This can be used
     * to communicate with the Renderer on the rendering thread.
     * Must not be called before a renderer has been set.
     * @param r the runnable to be run on the GL rendering thread.
     */
    public void queueEvent(Runnable r) {
        mGLThread.queueEvent(r);
    }

    mGLThread即是渲染线程。从注释中即可知,这个方法是用来和渲染线程进行通信的。

    /**
     * Queue an "event" to be run on the GL rendering thread.
     * @param r the runnable to be run on the GL rendering thread.
     */
    public void queueEvent(Runnable r) {
    
        synchronized(sGLThreadManager) {
            mEventQueue.add(r);
            sGLThreadManager.notifyAll();
        }
    
    }

    这个函数的核心代码就上面这两句。可见,当渲染线程空闲的时候,这个方法可以与渲染线程交互并唤醒渲染线程。

    private ArrayList<Runnable> mEventQueue = new ArrayList<Runnable>();
    
    private void guardedRun() throws InterruptedException {
    
        Runnable event = null;
    
        while (true) {
            synchronized (sGLThreadManager) {
                while (true) {
                    if (mShouldExit) {
                        return;
                    }
    
                    if (! mEventQueue.isEmpty()) {
                        event = mEventQueue.remove(0);
                        break;
                    }
                    
                    ...
                    
                    if (event != null) {
                        event.run();
                        event = null;
                        continue;
                    }    
    
                    ...
                    
                    view.mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig);                
                    
                    ...
                    
                    view.mRenderer.onSurfaceChanged(gl, w, h);
                    
                    ...
                    
                    view.mRenderer.onDrawFrame(gl);

    guardedRun即是渲染线程的工作渲染函数的入口,从上面的函数选摘可知,会在渲染线程的mRenderer方法调用之前调用mEventQueue方法。

    queueEvent的典型用法是根据用户输入改变mRenderer中的状态,然后在mRenderer.onDrawFrame中使用新的状态。

    参考:http://stackoverflow.com/questions/25388929/android-opengl-queueevent-why

  • 相关阅读:
    筛选DataTable行重复
    还原数据库时在向服务器发送请求时发生传输级错误
    not in 语句 要 排除 null情况
    C#实现万年历(农历、节气、节日、星座、星宿、属相、生肖、闰年月、时辰)
    关于Form_Load和Public Form()那些事
    C#多线程编程简述(转载)
    标识列重置
    NET批量大数据插入性能分析及比较
    Asp.net 备份和还原SQL Server及压缩Access数据库
    线性查找(递归)
  • 原文地址:https://www.cnblogs.com/fordreamxin/p/5318843.html
Copyright © 2011-2022 走看看