1cb93a386Sopenharmony_ci// 2cb93a386Sopenharmony_ci// Copyright 2015 The ANGLE Project Authors. All rights reserved. 3cb93a386Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 4cb93a386Sopenharmony_ci// found in the LICENSE file. 5cb93a386Sopenharmony_ci// 6cb93a386Sopenharmony_ci 7cb93a386Sopenharmony_ci// Debug.cpp: Defines debug state used for GL_KHR_debug 8cb93a386Sopenharmony_ci 9cb93a386Sopenharmony_ci#include "libANGLE/Debug.h" 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "common/debug.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ci#include <algorithm> 14cb93a386Sopenharmony_ci#include <tuple> 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_cinamespace 17cb93a386Sopenharmony_ci{ 18cb93a386Sopenharmony_ciconst char *GLSeverityToString(GLenum severity) 19cb93a386Sopenharmony_ci{ 20cb93a386Sopenharmony_ci switch (severity) 21cb93a386Sopenharmony_ci { 22cb93a386Sopenharmony_ci case GL_DEBUG_SEVERITY_HIGH: 23cb93a386Sopenharmony_ci return "HIGH"; 24cb93a386Sopenharmony_ci case GL_DEBUG_SEVERITY_MEDIUM: 25cb93a386Sopenharmony_ci return "MEDIUM"; 26cb93a386Sopenharmony_ci case GL_DEBUG_SEVERITY_LOW: 27cb93a386Sopenharmony_ci return "LOW"; 28cb93a386Sopenharmony_ci case GL_DEBUG_SEVERITY_NOTIFICATION: 29cb93a386Sopenharmony_ci default: 30cb93a386Sopenharmony_ci return "NOTIFICATION"; 31cb93a386Sopenharmony_ci } 32cb93a386Sopenharmony_ci} 33cb93a386Sopenharmony_ci 34cb93a386Sopenharmony_ciconst char *EGLMessageTypeToString(egl::MessageType messageType) 35cb93a386Sopenharmony_ci{ 36cb93a386Sopenharmony_ci switch (messageType) 37cb93a386Sopenharmony_ci { 38cb93a386Sopenharmony_ci case egl::MessageType::Critical: 39cb93a386Sopenharmony_ci return "CRITICAL"; 40cb93a386Sopenharmony_ci case egl::MessageType::Error: 41cb93a386Sopenharmony_ci return "ERROR"; 42cb93a386Sopenharmony_ci case egl::MessageType::Warn: 43cb93a386Sopenharmony_ci return "WARNING"; 44cb93a386Sopenharmony_ci case egl::MessageType::Info: 45cb93a386Sopenharmony_ci default: 46cb93a386Sopenharmony_ci return "INFO"; 47cb93a386Sopenharmony_ci } 48cb93a386Sopenharmony_ci} 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ciconst char *GLMessageTypeToString(GLenum type) 51cb93a386Sopenharmony_ci{ 52cb93a386Sopenharmony_ci switch (type) 53cb93a386Sopenharmony_ci { 54cb93a386Sopenharmony_ci case GL_DEBUG_TYPE_ERROR: 55cb93a386Sopenharmony_ci return "error"; 56cb93a386Sopenharmony_ci case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: 57cb93a386Sopenharmony_ci return "deprecated behavior"; 58cb93a386Sopenharmony_ci case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: 59cb93a386Sopenharmony_ci return "undefined behavior"; 60cb93a386Sopenharmony_ci case GL_DEBUG_TYPE_PORTABILITY: 61cb93a386Sopenharmony_ci return "portability"; 62cb93a386Sopenharmony_ci case GL_DEBUG_TYPE_PERFORMANCE: 63cb93a386Sopenharmony_ci return "performance"; 64cb93a386Sopenharmony_ci case GL_DEBUG_TYPE_MARKER: 65cb93a386Sopenharmony_ci return "marker"; 66cb93a386Sopenharmony_ci case GL_DEBUG_TYPE_PUSH_GROUP: 67cb93a386Sopenharmony_ci return "start of group"; 68cb93a386Sopenharmony_ci case GL_DEBUG_TYPE_POP_GROUP: 69cb93a386Sopenharmony_ci return "end of group"; 70cb93a386Sopenharmony_ci case GL_DEBUG_TYPE_OTHER: 71cb93a386Sopenharmony_ci default: 72cb93a386Sopenharmony_ci return "other message"; 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci} 75cb93a386Sopenharmony_ci} // namespace 76cb93a386Sopenharmony_ci 77cb93a386Sopenharmony_cinamespace gl 78cb93a386Sopenharmony_ci{ 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ciDebug::Control::Control() {} 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ciDebug::Control::~Control() {} 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_ciDebug::Control::Control(const Control &other) = default; 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ciDebug::Group::Group() {} 87cb93a386Sopenharmony_ci 88cb93a386Sopenharmony_ciDebug::Group::~Group() {} 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_ciDebug::Group::Group(const Group &other) = default; 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ciDebug::Debug(bool initialDebugState) 93cb93a386Sopenharmony_ci : mOutputEnabled(initialDebugState), 94cb93a386Sopenharmony_ci mCallbackFunction(nullptr), 95cb93a386Sopenharmony_ci mCallbackUserParam(nullptr), 96cb93a386Sopenharmony_ci mMessages(), 97cb93a386Sopenharmony_ci mMaxLoggedMessages(0), 98cb93a386Sopenharmony_ci mOutputSynchronous(false), 99cb93a386Sopenharmony_ci mGroups() 100cb93a386Sopenharmony_ci{ 101cb93a386Sopenharmony_ci pushDefaultGroup(); 102cb93a386Sopenharmony_ci} 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_ciDebug::~Debug() {} 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_civoid Debug::setMaxLoggedMessages(GLuint maxLoggedMessages) 107cb93a386Sopenharmony_ci{ 108cb93a386Sopenharmony_ci mMaxLoggedMessages = maxLoggedMessages; 109cb93a386Sopenharmony_ci} 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_civoid Debug::setOutputEnabled(bool enabled) 112cb93a386Sopenharmony_ci{ 113cb93a386Sopenharmony_ci mOutputEnabled = enabled; 114cb93a386Sopenharmony_ci} 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_cibool Debug::isOutputEnabled() const 117cb93a386Sopenharmony_ci{ 118cb93a386Sopenharmony_ci return mOutputEnabled; 119cb93a386Sopenharmony_ci} 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_civoid Debug::setOutputSynchronous(bool synchronous) 122cb93a386Sopenharmony_ci{ 123cb93a386Sopenharmony_ci mOutputSynchronous = synchronous; 124cb93a386Sopenharmony_ci} 125cb93a386Sopenharmony_ci 126cb93a386Sopenharmony_cibool Debug::isOutputSynchronous() const 127cb93a386Sopenharmony_ci{ 128cb93a386Sopenharmony_ci return mOutputSynchronous; 129cb93a386Sopenharmony_ci} 130cb93a386Sopenharmony_ci 131cb93a386Sopenharmony_civoid Debug::setCallback(GLDEBUGPROCKHR callback, const void *userParam) 132cb93a386Sopenharmony_ci{ 133cb93a386Sopenharmony_ci mCallbackFunction = callback; 134cb93a386Sopenharmony_ci mCallbackUserParam = userParam; 135cb93a386Sopenharmony_ci} 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ciGLDEBUGPROCKHR Debug::getCallback() const 138cb93a386Sopenharmony_ci{ 139cb93a386Sopenharmony_ci return mCallbackFunction; 140cb93a386Sopenharmony_ci} 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ciconst void *Debug::getUserParam() const 143cb93a386Sopenharmony_ci{ 144cb93a386Sopenharmony_ci return mCallbackUserParam; 145cb93a386Sopenharmony_ci} 146cb93a386Sopenharmony_ci 147cb93a386Sopenharmony_civoid Debug::insertMessage(GLenum source, 148cb93a386Sopenharmony_ci GLenum type, 149cb93a386Sopenharmony_ci GLuint id, 150cb93a386Sopenharmony_ci GLenum severity, 151cb93a386Sopenharmony_ci const std::string &message, 152cb93a386Sopenharmony_ci gl::LogSeverity logSeverity, 153cb93a386Sopenharmony_ci angle::EntryPoint entryPoint) const 154cb93a386Sopenharmony_ci{ 155cb93a386Sopenharmony_ci std::string messageCopy(message); 156cb93a386Sopenharmony_ci insertMessage(source, type, id, severity, std::move(messageCopy), logSeverity, entryPoint); 157cb93a386Sopenharmony_ci} 158cb93a386Sopenharmony_ci 159cb93a386Sopenharmony_civoid Debug::insertMessage(GLenum source, 160cb93a386Sopenharmony_ci GLenum type, 161cb93a386Sopenharmony_ci GLuint id, 162cb93a386Sopenharmony_ci GLenum severity, 163cb93a386Sopenharmony_ci std::string &&message, 164cb93a386Sopenharmony_ci gl::LogSeverity logSeverity, 165cb93a386Sopenharmony_ci angle::EntryPoint entryPoint) const 166cb93a386Sopenharmony_ci{ 167cb93a386Sopenharmony_ci { 168cb93a386Sopenharmony_ci // output all messages to the debug log 169cb93a386Sopenharmony_ci const char *messageTypeString = GLMessageTypeToString(type); 170cb93a386Sopenharmony_ci const char *severityString = GLSeverityToString(severity); 171cb93a386Sopenharmony_ci std::ostringstream messageStream; 172cb93a386Sopenharmony_ci if (entryPoint != angle::EntryPoint::GLInvalid) 173cb93a386Sopenharmony_ci { 174cb93a386Sopenharmony_ci messageStream << GetEntryPointName(entryPoint) << ": "; 175cb93a386Sopenharmony_ci } 176cb93a386Sopenharmony_ci messageStream << "GL " << messageTypeString << ": " << severityString << ": " << message; 177cb93a386Sopenharmony_ci switch (logSeverity) 178cb93a386Sopenharmony_ci { 179cb93a386Sopenharmony_ci case gl::LOG_FATAL: 180cb93a386Sopenharmony_ci FATAL() << messageStream.str(); 181cb93a386Sopenharmony_ci break; 182cb93a386Sopenharmony_ci case gl::LOG_ERR: 183cb93a386Sopenharmony_ci ERR() << messageStream.str(); 184cb93a386Sopenharmony_ci break; 185cb93a386Sopenharmony_ci case gl::LOG_WARN: 186cb93a386Sopenharmony_ci WARN() << messageStream.str(); 187cb93a386Sopenharmony_ci break; 188cb93a386Sopenharmony_ci case gl::LOG_INFO: 189cb93a386Sopenharmony_ci INFO() << messageStream.str(); 190cb93a386Sopenharmony_ci break; 191cb93a386Sopenharmony_ci case gl::LOG_EVENT: 192cb93a386Sopenharmony_ci ANGLE_LOG(EVENT) << messageStream.str(); 193cb93a386Sopenharmony_ci break; 194cb93a386Sopenharmony_ci } 195cb93a386Sopenharmony_ci } 196cb93a386Sopenharmony_ci 197cb93a386Sopenharmony_ci if (!isMessageEnabled(source, type, id, severity)) 198cb93a386Sopenharmony_ci { 199cb93a386Sopenharmony_ci return; 200cb93a386Sopenharmony_ci } 201cb93a386Sopenharmony_ci 202cb93a386Sopenharmony_ci if (mCallbackFunction != nullptr) 203cb93a386Sopenharmony_ci { 204cb93a386Sopenharmony_ci // TODO(geofflang) Check the synchronous flag and potentially flush messages from another 205cb93a386Sopenharmony_ci // thread. 206cb93a386Sopenharmony_ci mCallbackFunction(source, type, id, severity, static_cast<GLsizei>(message.length()), 207cb93a386Sopenharmony_ci message.c_str(), mCallbackUserParam); 208cb93a386Sopenharmony_ci } 209cb93a386Sopenharmony_ci else 210cb93a386Sopenharmony_ci { 211cb93a386Sopenharmony_ci if (mMessages.size() >= mMaxLoggedMessages) 212cb93a386Sopenharmony_ci { 213cb93a386Sopenharmony_ci // Drop messages over the limit 214cb93a386Sopenharmony_ci return; 215cb93a386Sopenharmony_ci } 216cb93a386Sopenharmony_ci 217cb93a386Sopenharmony_ci Message m; 218cb93a386Sopenharmony_ci m.source = source; 219cb93a386Sopenharmony_ci m.type = type; 220cb93a386Sopenharmony_ci m.id = id; 221cb93a386Sopenharmony_ci m.severity = severity; 222cb93a386Sopenharmony_ci m.message = std::move(message); 223cb93a386Sopenharmony_ci 224cb93a386Sopenharmony_ci mMessages.push_back(std::move(m)); 225cb93a386Sopenharmony_ci } 226cb93a386Sopenharmony_ci} 227cb93a386Sopenharmony_ci 228cb93a386Sopenharmony_cisize_t Debug::getMessages(GLuint count, 229cb93a386Sopenharmony_ci GLsizei bufSize, 230cb93a386Sopenharmony_ci GLenum *sources, 231cb93a386Sopenharmony_ci GLenum *types, 232cb93a386Sopenharmony_ci GLuint *ids, 233cb93a386Sopenharmony_ci GLenum *severities, 234cb93a386Sopenharmony_ci GLsizei *lengths, 235cb93a386Sopenharmony_ci GLchar *messageLog) 236cb93a386Sopenharmony_ci{ 237cb93a386Sopenharmony_ci size_t messageCount = 0; 238cb93a386Sopenharmony_ci size_t messageStringIndex = 0; 239cb93a386Sopenharmony_ci while (messageCount <= count && !mMessages.empty()) 240cb93a386Sopenharmony_ci { 241cb93a386Sopenharmony_ci const Message &m = mMessages.front(); 242cb93a386Sopenharmony_ci 243cb93a386Sopenharmony_ci if (messageLog != nullptr) 244cb93a386Sopenharmony_ci { 245cb93a386Sopenharmony_ci // Check that this message can fit in the message buffer 246cb93a386Sopenharmony_ci if (messageStringIndex + m.message.length() + 1 > static_cast<size_t>(bufSize)) 247cb93a386Sopenharmony_ci { 248cb93a386Sopenharmony_ci break; 249cb93a386Sopenharmony_ci } 250cb93a386Sopenharmony_ci 251cb93a386Sopenharmony_ci std::copy(m.message.begin(), m.message.end(), messageLog + messageStringIndex); 252cb93a386Sopenharmony_ci messageStringIndex += m.message.length(); 253cb93a386Sopenharmony_ci 254cb93a386Sopenharmony_ci messageLog[messageStringIndex] = '\0'; 255cb93a386Sopenharmony_ci messageStringIndex += 1; 256cb93a386Sopenharmony_ci } 257cb93a386Sopenharmony_ci 258cb93a386Sopenharmony_ci if (sources != nullptr) 259cb93a386Sopenharmony_ci { 260cb93a386Sopenharmony_ci sources[messageCount] = m.source; 261cb93a386Sopenharmony_ci } 262cb93a386Sopenharmony_ci 263cb93a386Sopenharmony_ci if (types != nullptr) 264cb93a386Sopenharmony_ci { 265cb93a386Sopenharmony_ci types[messageCount] = m.type; 266cb93a386Sopenharmony_ci } 267cb93a386Sopenharmony_ci 268cb93a386Sopenharmony_ci if (ids != nullptr) 269cb93a386Sopenharmony_ci { 270cb93a386Sopenharmony_ci ids[messageCount] = m.id; 271cb93a386Sopenharmony_ci } 272cb93a386Sopenharmony_ci 273cb93a386Sopenharmony_ci if (severities != nullptr) 274cb93a386Sopenharmony_ci { 275cb93a386Sopenharmony_ci severities[messageCount] = m.severity; 276cb93a386Sopenharmony_ci } 277cb93a386Sopenharmony_ci 278cb93a386Sopenharmony_ci if (lengths != nullptr) 279cb93a386Sopenharmony_ci { 280cb93a386Sopenharmony_ci lengths[messageCount] = static_cast<GLsizei>(m.message.length()) + 1; 281cb93a386Sopenharmony_ci } 282cb93a386Sopenharmony_ci 283cb93a386Sopenharmony_ci mMessages.pop_front(); 284cb93a386Sopenharmony_ci 285cb93a386Sopenharmony_ci messageCount++; 286cb93a386Sopenharmony_ci } 287cb93a386Sopenharmony_ci 288cb93a386Sopenharmony_ci return messageCount; 289cb93a386Sopenharmony_ci} 290cb93a386Sopenharmony_ci 291cb93a386Sopenharmony_cisize_t Debug::getNextMessageLength() const 292cb93a386Sopenharmony_ci{ 293cb93a386Sopenharmony_ci return mMessages.empty() ? 0 : mMessages.front().message.length() + 1; 294cb93a386Sopenharmony_ci} 295cb93a386Sopenharmony_ci 296cb93a386Sopenharmony_cisize_t Debug::getMessageCount() const 297cb93a386Sopenharmony_ci{ 298cb93a386Sopenharmony_ci return mMessages.size(); 299cb93a386Sopenharmony_ci} 300cb93a386Sopenharmony_ci 301cb93a386Sopenharmony_civoid Debug::setMessageControl(GLenum source, 302cb93a386Sopenharmony_ci GLenum type, 303cb93a386Sopenharmony_ci GLenum severity, 304cb93a386Sopenharmony_ci std::vector<GLuint> &&ids, 305cb93a386Sopenharmony_ci bool enabled) 306cb93a386Sopenharmony_ci{ 307cb93a386Sopenharmony_ci Control c; 308cb93a386Sopenharmony_ci c.source = source; 309cb93a386Sopenharmony_ci c.type = type; 310cb93a386Sopenharmony_ci c.severity = severity; 311cb93a386Sopenharmony_ci c.ids = std::move(ids); 312cb93a386Sopenharmony_ci c.enabled = enabled; 313cb93a386Sopenharmony_ci 314cb93a386Sopenharmony_ci auto &controls = mGroups.back().controls; 315cb93a386Sopenharmony_ci controls.push_back(std::move(c)); 316cb93a386Sopenharmony_ci} 317cb93a386Sopenharmony_ci 318cb93a386Sopenharmony_civoid Debug::pushGroup(GLenum source, GLuint id, std::string &&message) 319cb93a386Sopenharmony_ci{ 320cb93a386Sopenharmony_ci insertMessage(source, GL_DEBUG_TYPE_PUSH_GROUP, id, GL_DEBUG_SEVERITY_NOTIFICATION, 321cb93a386Sopenharmony_ci std::string(message), gl::LOG_INFO, angle::EntryPoint::GLPushDebugGroup); 322cb93a386Sopenharmony_ci 323cb93a386Sopenharmony_ci Group g; 324cb93a386Sopenharmony_ci g.source = source; 325cb93a386Sopenharmony_ci g.id = id; 326cb93a386Sopenharmony_ci g.message = std::move(message); 327cb93a386Sopenharmony_ci mGroups.push_back(std::move(g)); 328cb93a386Sopenharmony_ci} 329cb93a386Sopenharmony_ci 330cb93a386Sopenharmony_civoid Debug::popGroup() 331cb93a386Sopenharmony_ci{ 332cb93a386Sopenharmony_ci // Make sure the default group is not about to be popped 333cb93a386Sopenharmony_ci ASSERT(mGroups.size() > 1); 334cb93a386Sopenharmony_ci 335cb93a386Sopenharmony_ci Group g = mGroups.back(); 336cb93a386Sopenharmony_ci mGroups.pop_back(); 337cb93a386Sopenharmony_ci 338cb93a386Sopenharmony_ci insertMessage(g.source, GL_DEBUG_TYPE_POP_GROUP, g.id, GL_DEBUG_SEVERITY_NOTIFICATION, 339cb93a386Sopenharmony_ci g.message, gl::LOG_INFO, angle::EntryPoint::GLPopDebugGroup); 340cb93a386Sopenharmony_ci} 341cb93a386Sopenharmony_ci 342cb93a386Sopenharmony_cisize_t Debug::getGroupStackDepth() const 343cb93a386Sopenharmony_ci{ 344cb93a386Sopenharmony_ci return mGroups.size(); 345cb93a386Sopenharmony_ci} 346cb93a386Sopenharmony_ci 347cb93a386Sopenharmony_civoid Debug::insertPerfWarning(GLenum severity, const char *message, uint32_t *repeatCount) const 348cb93a386Sopenharmony_ci{ 349cb93a386Sopenharmony_ci bool repeatLast; 350cb93a386Sopenharmony_ci 351cb93a386Sopenharmony_ci { 352cb93a386Sopenharmony_ci constexpr uint32_t kMaxRepeat = 4; 353cb93a386Sopenharmony_ci std::lock_guard<std::mutex> lock(GetDebugMutex()); 354cb93a386Sopenharmony_ci 355cb93a386Sopenharmony_ci if (*repeatCount >= kMaxRepeat) 356cb93a386Sopenharmony_ci { 357cb93a386Sopenharmony_ci return; 358cb93a386Sopenharmony_ci } 359cb93a386Sopenharmony_ci 360cb93a386Sopenharmony_ci ++*repeatCount; 361cb93a386Sopenharmony_ci repeatLast = (*repeatCount == kMaxRepeat); 362cb93a386Sopenharmony_ci } 363cb93a386Sopenharmony_ci 364cb93a386Sopenharmony_ci std::string msg = message; 365cb93a386Sopenharmony_ci if (repeatLast) 366cb93a386Sopenharmony_ci { 367cb93a386Sopenharmony_ci msg += " (this message will no longer repeat)"; 368cb93a386Sopenharmony_ci } 369cb93a386Sopenharmony_ci 370cb93a386Sopenharmony_ci // Release the lock before we call insertMessage. It will re-acquire the lock. 371cb93a386Sopenharmony_ci insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_PERFORMANCE, 0, severity, std::move(msg), 372cb93a386Sopenharmony_ci gl::LOG_INFO, angle::EntryPoint::GLInvalid); 373cb93a386Sopenharmony_ci} 374cb93a386Sopenharmony_ci 375cb93a386Sopenharmony_cibool Debug::isMessageEnabled(GLenum source, GLenum type, GLuint id, GLenum severity) const 376cb93a386Sopenharmony_ci{ 377cb93a386Sopenharmony_ci if (!mOutputEnabled) 378cb93a386Sopenharmony_ci { 379cb93a386Sopenharmony_ci return false; 380cb93a386Sopenharmony_ci } 381cb93a386Sopenharmony_ci 382cb93a386Sopenharmony_ci for (auto groupIter = mGroups.rbegin(); groupIter != mGroups.rend(); groupIter++) 383cb93a386Sopenharmony_ci { 384cb93a386Sopenharmony_ci const auto &controls = groupIter->controls; 385cb93a386Sopenharmony_ci for (auto controlIter = controls.rbegin(); controlIter != controls.rend(); controlIter++) 386cb93a386Sopenharmony_ci { 387cb93a386Sopenharmony_ci const auto &control = *controlIter; 388cb93a386Sopenharmony_ci 389cb93a386Sopenharmony_ci if (control.source != GL_DONT_CARE && control.source != source) 390cb93a386Sopenharmony_ci { 391cb93a386Sopenharmony_ci continue; 392cb93a386Sopenharmony_ci } 393cb93a386Sopenharmony_ci 394cb93a386Sopenharmony_ci if (control.type != GL_DONT_CARE && control.type != type) 395cb93a386Sopenharmony_ci { 396cb93a386Sopenharmony_ci continue; 397cb93a386Sopenharmony_ci } 398cb93a386Sopenharmony_ci 399cb93a386Sopenharmony_ci if (control.severity != GL_DONT_CARE && control.severity != severity) 400cb93a386Sopenharmony_ci { 401cb93a386Sopenharmony_ci continue; 402cb93a386Sopenharmony_ci } 403cb93a386Sopenharmony_ci 404cb93a386Sopenharmony_ci if (!control.ids.empty() && 405cb93a386Sopenharmony_ci std::find(control.ids.begin(), control.ids.end(), id) == control.ids.end()) 406cb93a386Sopenharmony_ci { 407cb93a386Sopenharmony_ci continue; 408cb93a386Sopenharmony_ci } 409cb93a386Sopenharmony_ci 410cb93a386Sopenharmony_ci return control.enabled; 411cb93a386Sopenharmony_ci } 412cb93a386Sopenharmony_ci } 413cb93a386Sopenharmony_ci 414cb93a386Sopenharmony_ci return true; 415cb93a386Sopenharmony_ci} 416cb93a386Sopenharmony_ci 417cb93a386Sopenharmony_civoid Debug::pushDefaultGroup() 418cb93a386Sopenharmony_ci{ 419cb93a386Sopenharmony_ci Group g; 420cb93a386Sopenharmony_ci g.source = GL_NONE; 421cb93a386Sopenharmony_ci g.id = 0; 422cb93a386Sopenharmony_ci g.message = ""; 423cb93a386Sopenharmony_ci 424cb93a386Sopenharmony_ci Control c0; 425cb93a386Sopenharmony_ci c0.source = GL_DONT_CARE; 426cb93a386Sopenharmony_ci c0.type = GL_DONT_CARE; 427cb93a386Sopenharmony_ci c0.severity = GL_DONT_CARE; 428cb93a386Sopenharmony_ci c0.enabled = true; 429cb93a386Sopenharmony_ci g.controls.push_back(std::move(c0)); 430cb93a386Sopenharmony_ci 431cb93a386Sopenharmony_ci Control c1; 432cb93a386Sopenharmony_ci c1.source = GL_DONT_CARE; 433cb93a386Sopenharmony_ci c1.type = GL_DONT_CARE; 434cb93a386Sopenharmony_ci c1.severity = GL_DEBUG_SEVERITY_LOW; 435cb93a386Sopenharmony_ci c1.enabled = false; 436cb93a386Sopenharmony_ci g.controls.push_back(std::move(c1)); 437cb93a386Sopenharmony_ci 438cb93a386Sopenharmony_ci mGroups.push_back(std::move(g)); 439cb93a386Sopenharmony_ci} 440cb93a386Sopenharmony_ci} // namespace gl 441cb93a386Sopenharmony_ci 442cb93a386Sopenharmony_cinamespace egl 443cb93a386Sopenharmony_ci{ 444cb93a386Sopenharmony_ci 445cb93a386Sopenharmony_cinamespace 446cb93a386Sopenharmony_ci{ 447cb93a386Sopenharmony_ciangle::PackedEnumBitSet<MessageType> GetDefaultMessageTypeBits() 448cb93a386Sopenharmony_ci{ 449cb93a386Sopenharmony_ci angle::PackedEnumBitSet<MessageType> result; 450cb93a386Sopenharmony_ci result.set(MessageType::Critical); 451cb93a386Sopenharmony_ci result.set(MessageType::Error); 452cb93a386Sopenharmony_ci return result; 453cb93a386Sopenharmony_ci} 454cb93a386Sopenharmony_ci} // anonymous namespace 455cb93a386Sopenharmony_ci 456cb93a386Sopenharmony_ciDebug::Debug() : mCallback(nullptr), mEnabledMessageTypes(GetDefaultMessageTypeBits()) {} 457cb93a386Sopenharmony_ci 458cb93a386Sopenharmony_civoid Debug::setCallback(EGLDEBUGPROCKHR callback, const AttributeMap &attribs) 459cb93a386Sopenharmony_ci{ 460cb93a386Sopenharmony_ci mCallback = callback; 461cb93a386Sopenharmony_ci 462cb93a386Sopenharmony_ci const angle::PackedEnumBitSet<MessageType> defaultMessageTypes = GetDefaultMessageTypeBits(); 463cb93a386Sopenharmony_ci if (mCallback != nullptr) 464cb93a386Sopenharmony_ci { 465cb93a386Sopenharmony_ci for (MessageType messageType : angle::AllEnums<MessageType>()) 466cb93a386Sopenharmony_ci { 467cb93a386Sopenharmony_ci mEnabledMessageTypes[messageType] = 468cb93a386Sopenharmony_ci (attribs.getAsInt(egl::ToEGLenum(messageType), defaultMessageTypes[messageType]) == 469cb93a386Sopenharmony_ci EGL_TRUE); 470cb93a386Sopenharmony_ci } 471cb93a386Sopenharmony_ci } 472cb93a386Sopenharmony_ci} 473cb93a386Sopenharmony_ci 474cb93a386Sopenharmony_ciEGLDEBUGPROCKHR Debug::getCallback() const 475cb93a386Sopenharmony_ci{ 476cb93a386Sopenharmony_ci return mCallback; 477cb93a386Sopenharmony_ci} 478cb93a386Sopenharmony_ci 479cb93a386Sopenharmony_cibool Debug::isMessageTypeEnabled(MessageType type) const 480cb93a386Sopenharmony_ci{ 481cb93a386Sopenharmony_ci return mEnabledMessageTypes[type]; 482cb93a386Sopenharmony_ci} 483cb93a386Sopenharmony_ci 484cb93a386Sopenharmony_civoid Debug::insertMessage(EGLenum error, 485cb93a386Sopenharmony_ci const char *command, 486cb93a386Sopenharmony_ci MessageType messageType, 487cb93a386Sopenharmony_ci EGLLabelKHR threadLabel, 488cb93a386Sopenharmony_ci EGLLabelKHR objectLabel, 489cb93a386Sopenharmony_ci const std::string &message) const 490cb93a386Sopenharmony_ci{ 491cb93a386Sopenharmony_ci { 492cb93a386Sopenharmony_ci // output all messages to the debug log 493cb93a386Sopenharmony_ci const char *messageTypeString = EGLMessageTypeToString(messageType); 494cb93a386Sopenharmony_ci std::ostringstream messageStream; 495cb93a386Sopenharmony_ci messageStream << "EGL " << messageTypeString << ": " << command << ": " << message; 496cb93a386Sopenharmony_ci INFO() << messageStream.str(); 497cb93a386Sopenharmony_ci } 498cb93a386Sopenharmony_ci 499cb93a386Sopenharmony_ci // TODO(geofflang): Lock before checking the callback. http://anglebug.com/2464 500cb93a386Sopenharmony_ci if (mCallback && isMessageTypeEnabled(messageType)) 501cb93a386Sopenharmony_ci { 502cb93a386Sopenharmony_ci mCallback(error, command, egl::ToEGLenum(messageType), threadLabel, objectLabel, 503cb93a386Sopenharmony_ci message.c_str()); 504cb93a386Sopenharmony_ci } 505cb93a386Sopenharmony_ci} 506cb93a386Sopenharmony_ci 507cb93a386Sopenharmony_ci} // namespace egl 508