Edit

kc3-lang/angle/src/libANGLE/Thread.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2020-09-20 21:59:24
    Hash : cb286073
    Message : Use c++ thread_local for current thread. This solves a race condition using the global context. Sadly we can't use an unprotected variable safely because it can be written/read from multiple threads doing MakeCurrent. Has about a 2 ns regression when tested in Linux/Release per call. "null" benchmark test went from 27 -> 29 ns/iteration. Fixes a TSAN warning that popped up in angle_end2end_tests. Test: DrawCallPerfBenchmark.Run/vulkan_null Test: EGLContextASANTest.DestroyContextInUse/ES3_Vulkan Bug: b/168744561 Change-Id: Ic56f3faae81c1087b942a3cfc0e011b9ab439e0f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2419641 Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>

  • src/libANGLE/Thread.cpp
  • //
    // Copyright 2016 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    // Thread.cpp : Defines the Thread class which represents a global EGL thread.
    
    #include "libANGLE/Thread.h"
    
    #include "libANGLE/Context.h"
    #include "libANGLE/Debug.h"
    #include "libANGLE/Error.h"
    
    namespace angle
    {
    bool gUseAndroidOpenGLTlsSlot;
    }  // namespace angle
    
    namespace egl
    {
    
    Thread::Thread()
        : mLabel(nullptr),
          mError(EGL_SUCCESS),
          mAPI(EGL_OPENGL_ES_API),
          mContext(static_cast<gl::Context *>(EGL_NO_CONTEXT))
    {}
    
    void Thread::setLabel(EGLLabelKHR label)
    {
        mLabel = label;
    }
    
    EGLLabelKHR Thread::getLabel() const
    {
        return mLabel;
    }
    
    void Thread::setSuccess()
    {
        mError = EGL_SUCCESS;
    }
    
    void Thread::setError(const Error &error,
                          const Debug *debug,
                          const char *command,
                          const LabeledObject *object)
    {
        ASSERT(debug != nullptr);
    
        mError = error.getCode();
        if (error.isError() && !error.getMessage().empty())
        {
            debug->insertMessage(error.getCode(), command, ErrorCodeToMessageType(error.getCode()),
                                 getLabel(), object ? object->getLabel() : nullptr, error.getMessage());
        }
    }
    
    EGLint Thread::getError() const
    {
        return mError;
    }
    
    void Thread::setAPI(EGLenum api)
    {
        mAPI = api;
    }
    
    EGLenum Thread::getAPI() const
    {
        return mAPI;
    }
    
    void Thread::setCurrent(gl::Context *context)
    {
        mContext = context;
    }
    
    Surface *Thread::getCurrentDrawSurface() const
    {
        if (mContext)
        {
            return mContext->getCurrentDrawSurface();
        }
        return nullptr;
    }
    
    Surface *Thread::getCurrentReadSurface() const
    {
        if (mContext)
        {
            return mContext->getCurrentReadSurface();
        }
        return nullptr;
    }
    
    gl::Context *Thread::getContext() const
    {
        return mContext;
    }
    
    Display *Thread::getDisplay() const
    {
        if (mContext)
        {
            return mContext->getDisplay();
        }
        return nullptr;
    }
    }  // namespace egl