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 = false;
20 #endif
21 } // namespace angle
22
23 namespace egl
24 {
25 namespace
26 {
27 Debug *sDebug = nullptr;
28 } // namespace
29
Thread()30 Thread::Thread()
31 : mLabel(nullptr),
32 mError(EGL_SUCCESS),
33 mAPI(EGL_OPENGL_ES_API),
34 mContext(static_cast<gl::Context *>(EGL_NO_CONTEXT))
35 {}
36
setLabel(EGLLabelKHR label)37 void Thread::setLabel(EGLLabelKHR label)
38 {
39 mLabel = label;
40 }
41
getLabel() const42 EGLLabelKHR Thread::getLabel() const
43 {
44 return mLabel;
45 }
46
setSuccess()47 void Thread::setSuccess()
48 {
49 mError = EGL_SUCCESS;
50 }
51
setError(EGLint error,const char * command,const LabeledObject * object,const char * message)52 void Thread::setError(EGLint error,
53 const char *command,
54 const LabeledObject *object,
55 const char *message)
56 {
57 mError = error;
58 if (error != EGL_SUCCESS && message)
59 {
60 EnsureDebugAllocated();
61 sDebug->insertMessage(error, command, ErrorCodeToMessageType(error), getLabel(),
62 object ? object->getLabel() : nullptr, message);
63 }
64 }
65
setError(const Error & error,const char * command,const LabeledObject * object)66 void Thread::setError(const Error &error, const char *command, const LabeledObject *object)
67 {
68 mError = error.getCode();
69 if (error.isError() && !error.getMessage().empty())
70 {
71 EnsureDebugAllocated();
72 sDebug->insertMessage(error.getCode(), command, ErrorCodeToMessageType(error.getCode()),
73 getLabel(), object ? object->getLabel() : nullptr,
74 error.getMessage());
75 }
76 }
77
getError() const78 EGLint Thread::getError() const
79 {
80 return mError;
81 }
82
setAPI(EGLenum api)83 void Thread::setAPI(EGLenum api)
84 {
85 mAPI = api;
86 }
87
getAPI() const88 EGLenum Thread::getAPI() const
89 {
90 return mAPI;
91 }
92
setCurrent(gl::Context * context)93 void Thread::setCurrent(gl::Context *context)
94 {
95 mContext = context;
96 if (mContext)
97 {
98 ASSERT(mContext->getDisplay());
99 }
100 }
101
getCurrentDrawSurface() const102 Surface *Thread::getCurrentDrawSurface() const
103 {
104 if (mContext)
105 {
106 return mContext->getCurrentDrawSurface();
107 }
108 return nullptr;
109 }
110
getCurrentReadSurface() const111 Surface *Thread::getCurrentReadSurface() const
112 {
113 if (mContext)
114 {
115 return mContext->getCurrentReadSurface();
116 }
117 return nullptr;
118 }
119
getContext() const120 gl::Context *Thread::getContext() const
121 {
122 return mContext;
123 }
124
getDisplay() const125 Display *Thread::getDisplay() const
126 {
127 if (mContext)
128 {
129 return mContext->getDisplay();
130 }
131 return nullptr;
132 }
133
EnsureDebugAllocated()134 void EnsureDebugAllocated()
135 {
136 // All EGL calls use a global lock, this is thread safe
137 if (sDebug == nullptr)
138 {
139 sDebug = new Debug();
140 }
141 }
142
DeallocateDebug()143 void DeallocateDebug()
144 {
145 SafeDelete(sDebug);
146 }
147
GetDebug()148 Debug *GetDebug()
149 {
150 EnsureDebugAllocated();
151 return sDebug;
152 }
153 } // namespace egl
154