opengl 源码分析常见问题

Opengl 一些问题解答

为什么opengl 不能跨线程

  大家有没有想过这个问题,网上给出的答案其实看得不太明白,接下来我们看源码让你知道

C
EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
{
    const egl::Config *config = mConfigSet.get(configHandle);
    gl::Context *context = glCreateContext(config, shareContext, notifyResets, robustAccess);
    return context;
}
gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
{
    return new gl::Context(config, shareContext, notifyResets, robustAccess);
}

EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
{
    ...
    glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
}
void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
{
    gl::makeCurrent(context, display, surface);
}
void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
{
    Current *current = (Current*)TlsGetValue(currentTLS);

    current->context = context;
    current->display = display;
}

通过上边源码可以看到, 它是把context 放入到thread local中去,这就是不能夸线程根本原因,在做opengl 一些操作的时候,首先去线程中取context, 如果夸了线程取的context就不是之前使用的context导致了crash,这个希望大家要明确知道

纹理是什么

C++
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screenWidth, screenHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

 

 glGenTextures(GLsizei n, GLuint* textures)

   这个textures返回的 是int值,具体是什么?

   要想知道这个答案要看下opengles的源码:

C
void __stdcall glGenTextures(GLsizei n, GLuint* textures)
{
         gl::Context *context = gl::getNonLostContext();
         for (int i = 0; i < n; i++)
         {
             textures[i] = context->createTexture();
         }
}
    GLuint Context::createTexture()
    {
        return mResourceManager->createTexture();
    }
        GLuint ResourceManager::createTexture()
        {
            GLuint handle = mTextureHandleAllocator.allocate();
            mTextureMap[handle] = NULL;
            return handle;
        }
       
            GLuint HandleAllocator::allocate()
            {
                /*
                 typedef std::vector<GLuint> HandleList;
                HandleList mFreeValues;
                */
                if (mFreeValues.size())
                {
                    GLuint handle = mFreeValues.back();
                    mFreeValues.pop_back();
                    return handle;
                }
                return mNextValue++;
            }
     

通过上边源码也可以看出来, 首先创建纹理的时候会从当前线程的threadlocal取出context,再从context取出来mResourceManager,在从mResourcManager取出一个空隙的ID,也就说这个gentexutre只是拿到一个id,其他什么都没干

纹理绑定到底干了些啥

C
void __stdcall glBindTexture(GLenum target, GLuint texture)
{
    EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
    gl::Context *context = gl::getNonLostContext();
    gl::Texture *textureObject = context->getTexture(texture);   
    switch (target)
    {
         case GL_TEXTURE_2D:
              context->bindTexture2D(texture);
             return;
    }
}
    Texture *Context::getTexture(GLuint handle)
    {
        return mResourceManager->getTexture(handle);
    }
        Texture *ResourceManager::getTexture(unsigned int handle)
        {
            if (handle == 0) return NULL;
       
            TextureMap::iterator texture = mTextureMap.find(handle);
            if (texture == mTextureMap.end())
            {
                return NULL;
            }
            else
            {
                return texture->second;
            }
        }
    void Context::bindTexture2D(GLuint texture)
    {
        mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
        //    BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF];

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值