Thread.cpp (3376B)
1 // 2 // Copyright 2016 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // Thread.cpp : Defines the Thread class which represents a global EGL thread. 8 9 #include "libANGLE/Thread.h" 10 11 #include "libANGLE/Context.h" 12 #include "libANGLE/Debug.h" 13 #include "libANGLE/Display.h" 14 #include "libANGLE/Error.h" 15 16 namespace angle 17 { 18 #if defined(ANGLE_USE_ANDROID_TLS_SLOT) 19 bool gUseAndroidOpenGLTlsSlot; 20 #endif 21 22 void PthreadKeyDestructorCallback(void *ptr) 23 { 24 egl::Thread *thread = static_cast<egl::Thread *>(ptr); 25 ASSERT(thread); 26 27 egl::Display::EglDisplaySet displays = egl::Display::GetEglDisplaySet(); 28 for (egl::Display *display : displays) 29 { 30 ASSERT(display); 31 // Perform necessary cleanup. 32 display->threadCleanup(thread); 33 } 34 } 35 } // namespace angle 36 37 namespace egl 38 { 39 namespace 40 { 41 Debug *sDebug = nullptr; 42 } // namespace 43 44 Thread::Thread() 45 : mLabel(nullptr), 46 mError(EGL_SUCCESS), 47 mAPI(EGL_OPENGL_ES_API), 48 mContext(static_cast<gl::Context *>(EGL_NO_CONTEXT)) 49 {} 50 51 void Thread::setLabel(EGLLabelKHR label) 52 { 53 mLabel = label; 54 } 55 56 EGLLabelKHR Thread::getLabel() const 57 { 58 return mLabel; 59 } 60 61 void Thread::setSuccess() 62 { 63 mError = EGL_SUCCESS; 64 } 65 66 void Thread::setError(EGLint error, 67 const char *command, 68 const LabeledObject *object, 69 const char *message) 70 { 71 mError = error; 72 if (error != EGL_SUCCESS && message) 73 { 74 EnsureDebugAllocated(); 75 sDebug->insertMessage(error, command, ErrorCodeToMessageType(error), getLabel(), 76 object ? object->getLabel() : nullptr, message); 77 } 78 } 79 80 void Thread::setError(const Error &error, const char *command, const LabeledObject *object) 81 { 82 mError = error.getCode(); 83 if (error.isError() && !error.getMessage().empty()) 84 { 85 EnsureDebugAllocated(); 86 sDebug->insertMessage(error.getCode(), command, ErrorCodeToMessageType(error.getCode()), 87 getLabel(), object ? object->getLabel() : nullptr, 88 error.getMessage()); 89 } 90 } 91 92 EGLint Thread::getError() const 93 { 94 return mError; 95 } 96 97 void Thread::setAPI(EGLenum api) 98 { 99 mAPI = api; 100 } 101 102 EGLenum Thread::getAPI() const 103 { 104 return mAPI; 105 } 106 107 void Thread::setCurrent(gl::Context *context) 108 { 109 mContext = context; 110 if (mContext) 111 { 112 ASSERT(mContext->getDisplay()); 113 mContext->getDisplay()->addActiveThread(this); 114 } 115 } 116 117 Surface *Thread::getCurrentDrawSurface() const 118 { 119 if (mContext) 120 { 121 return mContext->getCurrentDrawSurface(); 122 } 123 return nullptr; 124 } 125 126 Surface *Thread::getCurrentReadSurface() const 127 { 128 if (mContext) 129 { 130 return mContext->getCurrentReadSurface(); 131 } 132 return nullptr; 133 } 134 135 gl::Context *Thread::getContext() const 136 { 137 return mContext; 138 } 139 140 Display *Thread::getDisplay() const 141 { 142 if (mContext) 143 { 144 return mContext->getDisplay(); 145 } 146 return nullptr; 147 } 148 149 void EnsureDebugAllocated() 150 { 151 // All EGL calls use a global lock, this is thread safe 152 if (sDebug == nullptr) 153 { 154 sDebug = new Debug(); 155 } 156 } 157 158 void DeallocateDebug() 159 { 160 SafeDelete(sDebug); 161 } 162 163 Debug *GetDebug() 164 { 165 EnsureDebugAllocated(); 166 return sDebug; 167 } 168 } // namespace egl