背景:

做opengl 跨线程渲染的时候,避免了不了使用Fence机制其使用也很简单,今天我们就从源码角度看下Fence到底做了啥

Fence

C++
GL_APICALL GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags)
GL_APICALL void GL_APIENTRY glDeleteSync(GLsync sync)
GL_APICALL GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)

今天就从这个3个方法来看下源码里具体的实现

glFenceSync

C++
GL_APICALL GLsync GL_APIENTRY glFenceSync(GLenum condition, GLbitfield flags)

{
        TRACE("(GLenum condition = 0x%X, GLbitfield flags = %X)", condition, flags);

es2::Context *context = es2::getContext();

if(context)
        {
                return context->createFenceSync(condition, flags);
        }

return nullptr;
}

createFenceSync

C++
GLsync Context::createFenceSync(GLenum condition, GLbitfield flags)
{
        GLuint handle = mResourceManager->createFenceSync(condition, flags);

return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
}
    GLuint ResourceManager::createFenceSync(GLenum condition, GLbitfield flags)
    {
            GLuint name = mFenceSyncNameSpace.allocate();
   
            FenceSync *fenceSync = new FenceSync(name, condition, flags);
            fenceSync->addRef();
   
            mFenceSyncNameSpace.insert(name, fenceSync);
   
            return name;
    }

可以看的出来这个fenc指针最终存储在mResourceManager这个对象里边,而mResourceManager是可以通过共享context被另外一个线程context持有的,所以fence指针另外线程是可以访问到的

glClientWaitSync

一般AddFence后会在另外一个线程调用glClientWaitSync 等待完成,那我们就看下它是怎么实现的

C++
GL_APICALL GLenum GL_APIENTRY glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
{
        TRACE("(GLsync sync = %p, GLbitfield flags = %X, GLuint64 timeout = %llu)", sync, flags, timeout);

if((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
        {
                error(GL_INVALID_VALUE);
        }

es2::Context *context = es2::getContext();

if(context)
        {
                es2::FenceSync *fenceSyncObject = context->getFenceSync(sync);

if(fenceSyncObject)
                {
                        return fenceSyncObject->clientWait(flags, timeout);
                }
                else
                {
                        return error(GL_INVALID_VALUE, GL_FALSE);
                }
        }

return GL_FALSE;
}

接下来看下fenceSyncObject->clientWait这个实现

C++
GLenum FenceSync::clientWait(GLbitfield flags, GLuint64 timeout)
{
        // The current assumtion is that no matter where the fence is placed, it is
        // done by the time it is tested, which is similar to Context::flush(), since
        // we don't queue anything without processing it as fast as possible.
        return GL_ALREADY_SIGNALED;
}

我看到这个开源库是没实现这个方法的,这里比较遗憾

glDeleteSync

这个就很简单了

C++
GL_APICALL void GL_APIENTRY glDeleteSync(GLsync sync)
{
        TRACE("(GLsync sync = %p)", sync);

es2::Context *context = es2::getContext();

if(context)
        {
                context->deleteFenceSync(sync);
        }
}
    void Context::deleteFenceSync(GLsync fenceSync)
    {
            // The spec specifies the underlying Fence object is not deleted until all current
            // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
            // and since our API is currently designed for being called from a single thread, we can delete
            // the fence immediately.
            mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
    }
        void ResourceManager::deleteFenceSync(GLuint fenceSync)
        {
                FenceSync *fenceObject = mFenceSyncNameSpace.remove(fenceSync);
       
                if(fenceObject)
                {
                        fenceObject->release();
                }
        }
            void Object::release()
            {
                    if(dereference() == 0)
                    {
                            delete this;
                    }
            }

当引用计数是0的时候,会清楚这个资源,也就是一旦调用Delete共享context线程,与原线程都不用使用了Fence了

Opengl Fence 内部实现相关推荐

  1. 【OpenGL ES】OpenGL ES简介

    [参考-khronos]https://www.khronos.org/opengles/ 1.简介 OpenGL ES(OpenGL for Embeded System)是OpenGL(Open ...

  2. OpenGL ES 3.0 基础知识

    首先要了解OpenGL的图形管线有哪些内容,再分别去了解其中的相关的关系: 管线分别包括了顶点缓冲区/数组对象,定点着色器,纹理,片段着色器,变换反馈,图元装配,光栅化,逐片段操作,帧缓冲区.其中顶点 ...

  3. C#中使用tao.opengl绘制三维模型

    一.tao.Opengl技术简介 Opengl是一种C风格的图形库,即opengl中没有类和对象,只有大量的函数.Opengl在内部就是一个状态机,利用不同的函数来修改opengl状态机的状态,以达到 ...

  4. OpenGL ES 简单教程

    OpenGL ES 简单教程 2014-04-24 13:35 佚名 apkbus 字号:T | T 什么是OpenGL ES?OpenGL ES (为OpenGL for Embedded Syst ...

  5. OpenGL开发之旅基础知识介绍

    最近由于手机项目中需要用到OpenGL ES的知识,所以这段时间正在研究OpenGL的相关知识.因为OpenGL ES是OpenGL的剪裁版本,所以我直接从OpenGL入手,然后再去看OpenGL E ...

  6. tao.Opengl

    一.tao.Opengl技术简介 Opengl是一种C风格的图形库,即opengl中没有类和对象,只有大量的函数.Opengl在内部就是一个状态机,利用不同的函数来修改opengl状态机的状态,以达到 ...

  7. tao.opengl + C#

    一.tao.Opengl技术简介 Opengl是一种C风格的图形库,即opengl中没有类和对象,只有大量的函数.Opengl在内部就是一个状态机,利用不同的函数来修改opengl状态机的状态,以达到 ...

  8. 1、OPenGL ES - 简介、iOS中GLKit简单应用

    OPenGL ES -  简介.iOS中GLKit简单应用 一.OPenGL ES 1.简介: OpenGL ES 是以手持和嵌入式为目标的高级的3D图形应用程序编程接口(API),OpenGL ES ...

  9. OPenGL学习--库介绍

    文章目录 一.什么是OpenGL 二.OpenGL的由来 三.工具库 3.1.窗口管理 3.2.glut 3.3.freeglut 3.4.glfw 3.5.函数加载 3.6.glew 3.7.gla ...

最新文章

  1. 怎样将无线路由做成无线AP
  2. [Leetcode] Combinations 组合数
  3. css火狐 hover 图片会重新请求,在“unhovering”之后使CSS Hover状态保持不变
  4. Java之美之设计模式
  5. 问题 B: 分组统计
  6. 第一篇:数据库基本管理(mysql)
  7. shell编程之特殊变量
  8. Windows中各类画面源的截取和合成方法总结
  9. CS144 计算机网络实验 lab3 笔记
  10. 二进制,逆向工程,深入理解计算机系统
  11. 高数七重积分的总结_高数下册总结
  12. 精通 CSS+DIV 网页样式与布局 158
  13. 【矩阵论】矩阵微积分的一些公式
  14. 浙江师范大学数学与计算机科学学院仇秋生,仇秋生 中文主页 浙江师范大学教师个人主页系统...
  15. php html5定位,HTML HTML5 地理定位 - 闪电教程JSRUN
  16. Python与Arduino绘制超声波雷达扫描
  17. 轻松高效搭建可视化数据网站
  18. A non-optional actual argument must be present when invoking a procedure with an explicit interface
  19. 一文读懂:快速入门机器学习,基础向
  20. word用户名的修改

热门文章

  1. matlab学习——摄氏度与华氏度的转换
  2. 如何利用STP理论实践品牌定位?
  3. c语言图形学彩球上浮,计算机图形学 弹跳的彩球动画.doc
  4. 雪花算法自定义解决时钟回拨问题
  5. Android一个界面实现标准体重计算器
  6. MSP432P401R学习笔记
  7. [附源码]java毕业设计学生宿舍设备报修
  8. 2015初三计算机考试题答案,2015初中生计算机考试年试题及答案.doc
  9. 女程序媛为什么不在公司找对象?
  10. ANSYS Workbench中各种设置选项都不理解怎么办?(附实例surface effect)