注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

永恒的遗失古都-亚特兰蒂斯

一个游戏开发者的个人博客。

 
 
 

日志

 
 

理解OpenGL ES:多线程编译shader  

2015-12-12 14:47:35|  分类: 图形渲染 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
下面是前几天开发过程中的记录:
问题
当前游戏Loading时间过慢,经过检查PreWarmShader消耗过多。其中定点到glCompileShader函数阻塞。

解决方案
首先想到的就是将shader进行简化,但是效果实在甚微。
于是考虑将shader分线程进行compile
1>创建新线程CSThread(容易)
2>为CSThread创建一个环状队列(容易)
3>将render线程中的shaderCompile部分进行拆分,立刻需要使用的shader,依然保留在render线程中,需要预编译的shader丢到CSThread等待队列中(顺利)
4>CSThread创建新的context(不顺利)
    首先考虑的是两个线程公用一个context,使用glMakeCurrent进行线程绑定,但是引发的问题是一旦glMakeCurrent(null,null)将context从render线程解绑,就会导致render失效,这是openGLES机制引发的,glMakeCurrent(null,null)会导致驱动丢弃所有未完成的操作,结果就是渲染失效。
    于是创建了两个context,想共用同一个surface,结果发现屏幕黑掉了,因为CSThread没有任何东西需要提交到surface,但是当surface提交到前台时候,会是黑屏。
    于是每个线程单独一个context,每个context创建一个自己的surface,结果crash,因为eglCreateWindowSurface限制每个dispaly只允许有一个有效surface。
    于是第二个context创建一个eglCreatePbufferSurface,永不提交该surface,结果运行时crash,因为两个context中数据不可交互,包括VBO这些。
    于是使用sharedContext,终于成功……
    所以这里的核心流程如下,重心就两块:
    - eglGetDisplay( EGL_DEFAULT_DISPLAY );
    - eglInitialize( display, 0, 0 );
    - eglChooseConfig( display, configs );
    - eglGetConfigAttrib( selectConfig );
    - pSurface = eglCreatePbufferSurface( display, selectConfig ); // 注意,这里不再是eglCreateWindowSurface。
    - csContext = eglCreateContext( display, selectConfig, renderContext, EGL_CONTEXT_CLIENT_VERSION ); // 注意,第三个参数使用renderContext,而非null,这样就启动了shareContext。
    - eglMakeCurrent(display, pSurface, pSurface, csContext);
    ... your code here
    - eglDestroyContext( display, csContext );    // 这里建议在第二个线程销毁后调用。
5> 然后我把所有的shader都丢给CSThread处理,结果有很轻度的Loading加速。
6> 我将shader分为两组,一组继续render线程处理,一组给新的CSThread处理,最终得到了良好效果。
    举例:render线程原本有两个任务    - 实际的render到屏幕,假设消耗2s - 编译shader,假设消耗20s。
    我进行第5步骤后,CSThread编译shader 20s,render线程只做一件事就是render到屏幕2s,因为是多线程并行,所以累计消耗为20s。
    我进行第6步骤后,CSThread编译一半的shader 10s,render线程两个任务 - 实际的render到屏幕2s + 编译一半的shader 10s,实际消耗12s。如果shader分配的更合理的话,则最佳可能优化到11秒。
  评论这张
 
阅读(37)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017