Replace gl::trace logging with Chromium style logging

Removing one usage of FormatString() and its static buffer.
And preparation for Platform logging.

BUG=angleproject:1660

Change-Id: I58192988ad16196706fe48d0c0ab0fd1a10c0210
Reviewed-on: https://chromium-review.googlesource.com/424173
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Yuly Novikov <ynovikov@chromium.org>
diff --git a/src/common/debug.cpp b/src/common/debug.cpp
index f64d932..48cabb7 100644
--- a/src/common/debug.cpp
+++ b/src/common/debug.cpp
@@ -10,6 +10,7 @@
 
 #include <stdarg.h>
 
+#include <array>
 #include <cstdio>
 #include <fstream>
 #include <iostream>
@@ -25,97 +26,15 @@
 namespace
 {
 
-class FormattedString final : angle::NonCopyable
-{
-  public:
-    FormattedString(const char *format, va_list vararg) : mFormat(format)
-    {
-        va_copy(mVarArg, vararg);
-    }
-
-    const char *c_str() { return str().c_str(); }
-
-    const std::string &str()
-    {
-        if (!mMessage.valid())
-        {
-            mMessage = FormatString(mFormat, mVarArg);
-        }
-        return mMessage.value();
-    }
-
-    size_t length()
-    {
-        c_str();
-        return mMessage.value().length();
-    }
-
-  private:
-    const char *mFormat;
-    va_list mVarArg;
-    Optional<std::string> mMessage;
-};
-enum DebugTraceOutputType
-{
-   DebugTraceOutputTypeNone,
-   DebugTraceOutputTypeSetMarker,
-   DebugTraceOutputTypeBeginEvent
-};
-
 DebugAnnotator *g_debugAnnotator = nullptr;
 
-void output(bool traceInDebugOnly, MessageType messageType, DebugTraceOutputType outputType,
-            const char *format, va_list vararg)
+constexpr std::array<const char *, LOG_NUM_SEVERITIES> g_logSeverityNames = {
+    {"EVENT", "WARN", "ERR"}};
+
+constexpr const char *LogSeverityName(int severity)
 {
-    if (DebugAnnotationsActive())
-    {
-        static std::vector<char> buffer(512);
-        size_t len = FormatStringIntoVector(format, vararg, buffer);
-        std::wstring formattedWideMessage(buffer.begin(), buffer.begin() + len);
-
-        ASSERT(g_debugAnnotator != nullptr);
-        switch (outputType)
-        {
-          case DebugTraceOutputTypeNone:
-            break;
-          case DebugTraceOutputTypeBeginEvent:
-            g_debugAnnotator->beginEvent(formattedWideMessage.c_str());
-            break;
-          case DebugTraceOutputTypeSetMarker:
-            g_debugAnnotator->setMarker(formattedWideMessage.c_str());
-            break;
-        }
-    }
-
-    FormattedString formattedMessage(format, vararg);
-
-    if (messageType == MESSAGE_ERR)
-    {
-        std::cerr << formattedMessage.c_str();
-#if !defined(NDEBUG) && defined(_MSC_VER)
-        OutputDebugStringA(formattedMessage.c_str());
-#endif  // !defined(NDEBUG) && defined(_MSC_VER)
-    }
-
-#if defined(ANGLE_ENABLE_DEBUG_TRACE)
-#if defined(NDEBUG)
-    if (traceInDebugOnly)
-    {
-        return;
-    }
-#endif  // NDEBUG
-    static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
-    if (file)
-    {
-        file.write(formattedMessage.c_str(), formattedMessage.length());
-        file.flush();
-    }
-
-#if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
-    OutputDebugStringA(formattedMessage.c_str());
-#endif  // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER
-
-#endif  // ANGLE_ENABLE_DEBUG_TRACE
+    return (severity >= 0 && severity < LOG_NUM_SEVERITIES) ? g_logSeverityNames[severity]
+                                                            : "UNKNOWN";
 }
 
 } // namespace
@@ -141,14 +60,6 @@
     g_debugAnnotator = nullptr;
 }
 
-void trace(bool traceInDebugOnly, MessageType messageType, const char *format, ...)
-{
-    va_list vararg;
-    va_start(vararg, format);
-    output(traceInDebugOnly, messageType, DebugTraceOutputTypeSetMarker, format, vararg);
-    va_end(vararg);
-}
-
 ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
 {
 #if !defined(ANGLE_ENABLE_DEBUG_TRACE)
@@ -157,9 +68,12 @@
         return;
     }
 #endif // !ANGLE_ENABLE_DEBUG_TRACE
+
     va_list vararg;
     va_start(vararg, format);
-    output(true, MESSAGE_EVENT, DebugTraceOutputTypeBeginEvent, format, vararg);
+    std::vector<char> buffer(512);
+    size_t len = FormatStringIntoVector(format, vararg, buffer);
+    ANGLE_LOG(EVENT) << std::string(&buffer[0], len);
     va_end(vararg);
 }
 
@@ -171,9 +85,105 @@
     }
 }
 
+namespace priv
+{
+
 std::ostream &DummyStream()
 {
     return std::cout;
 }
 
+bool ShouldCreateLogMessage(LogSeverity severity)
+{
+#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
+    return true;
+#elif defined(ANGLE_ENABLE_ASSERTS)
+    return severity == LOG_ERR;
+#else
+    return false;
+#endif
+}
+
+LogMessage::LogMessage(const char *function, int line, LogSeverity severity)
+    : mSeverity(severity), mFunction(function), mLine(line)
+{
+    init(function, line);
+}
+
+LogMessage::~LogMessage()
+{
+    mStream << std::endl;
+    std::string str(mStream.str());
+
+    if (DebugAnnotationsActive())
+    {
+        std::wstring formattedWideMessage(str.begin(), str.end());
+
+        switch (mSeverity)
+        {
+            case LOG_EVENT:
+                g_debugAnnotator->beginEvent(formattedWideMessage.c_str());
+                break;
+            default:
+                g_debugAnnotator->setMarker(formattedWideMessage.c_str());
+                break;
+        }
+    }
+
+    // Give any log message handler first dibs on the message.
+    bool handled = g_debugAnnotator != nullptr &&
+                   g_debugAnnotator->logMessage(mSeverity, mFunction, mLine, mMessageStart, str);
+
+    if (!handled && mSeverity == LOG_ERR)
+    {
+        std::cerr << str;
+#if !defined(NDEBUG) && defined(_MSC_VER)
+        OutputDebugStringA(str.c_str());
+#endif  // !defined(NDEBUG) && defined(_MSC_VER)
+    }
+
+#if defined(ANGLE_ENABLE_DEBUG_TRACE)
+#if defined(NDEBUG)
+    if (mSeverity == LOG_EVENT || mSeverity == LOG_WARN)
+    {
+        return;
+    }
+#endif  // NDEBUG
+    static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
+    if (file)
+    {
+        file.write(str.c_str(), str.length());
+        file.flush();
+    }
+
+#if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
+    OutputDebugStringA(str.c_str());
+#endif  // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER
+
+#endif  // ANGLE_ENABLE_DEBUG_TRACE
+}
+
+// writes the common header info to the stream
+void LogMessage::init(const char *function, int line)
+{
+    if (mSeverity >= 0)
+        mStream << LogSeverityName(mSeverity);
+    else
+        mStream << "VERBOSE" << -mSeverity;
+
+    mStream << ": " << function << "(" << line << "): ";
+
+    mMessageStart = mStream.str().length();
+}
+
+}  // namespace priv
+
+#if defined(ANGLE_PLATFORM_WINDOWS)
+std::ostream &operator<<(std::ostream &os, const FmtHR &fmt)
+{
+    os << "HRESULT: ";
+    return FmtHexInt(os, fmt.mHR);
+}
+#endif  // defined(ANGLE_PLATFORM_WINDOWS)
+
 }  // namespace gl