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
diff --git a/src/common/debug.h b/src/common/debug.h
index b7024e0..0bb2f57 100644
--- a/src/common/debug.h
+++ b/src/common/debug.h
@@ -11,6 +11,10 @@
 
 #include <assert.h>
 #include <stdio.h>
+
+#include <ios>
+#include <iomanip>
+#include <sstream>
 #include <string>
 
 #include "common/angleutils.h"
@@ -22,17 +26,6 @@
 namespace gl
 {
 
-enum MessageType
-{
-    MESSAGE_TRACE,
-    MESSAGE_FIXME,
-    MESSAGE_ERR,
-    MESSAGE_EVENT,
-};
-
-// Outputs text to the debugging log, or the debugging window
-void trace(bool traceInDebugOnly, MessageType messageType, const char *format, ...);
-
 // Pairs a D3D begin event with an end event.
 class ScopedPerfEventHelper : angle::NonCopyable
 {
@@ -41,6 +34,14 @@
     ~ScopedPerfEventHelper();
 };
 
+using LogSeverity = int;
+// Note: the log severities are used to index into the array of names,
+// see g_logSeverityNames.
+constexpr LogSeverity LOG_EVENT          = 0;
+constexpr LogSeverity LOG_WARN           = 1;
+constexpr LogSeverity LOG_ERR            = 2;
+constexpr LogSeverity LOG_NUM_SEVERITIES = 3;
+
 // Wraps the D3D9/D3D11 debug annotation functions.
 class DebugAnnotator : angle::NonCopyable
 {
@@ -51,12 +52,26 @@
     virtual void endEvent() = 0;
     virtual void setMarker(const wchar_t *markerName) = 0;
     virtual bool getStatus() = 0;
+    // Log Message Handler that gets passed every log message before
+    // it's sent to other log destinations (if any).
+    // Returns true to signal that it handled the message and the message
+    // should not be sent to other log destinations.
+    virtual bool logMessage(LogSeverity severity,
+                            const char *function,
+                            int line,
+                            size_t message_start,
+                            const std::string &str)
+    {
+        return false;
+    }
 };
 
 void InitializeDebugAnnotations(DebugAnnotator *debugAnnotator);
 void UninitializeDebugAnnotations();
 bool DebugAnnotationsActive();
 
+namespace priv
+{
 // This class is used to explicitly ignore values in the conditional logging macros. This avoids
 // compiler warnings like "value computed is not used" and "statement has no effect".
 class LogMessageVoidify
@@ -70,6 +85,110 @@
 // This can be any ostream, it is unused, but needs to be a valid reference.
 std::ostream &DummyStream();
 
+// Used by ANGLE_LOG_IS_ON to lazy-evaluate stream arguments.
+bool ShouldCreateLogMessage(LogSeverity severity);
+
+// This class more or less represents a particular log message.  You
+// create an instance of LogMessage and then stream stuff to it.
+// When you finish streaming to it, ~LogMessage is called and the
+// full message gets streamed to the appropriate destination.
+//
+// You shouldn't actually use LogMessage's constructor to log things,
+// though.  You should use the ERR() and WARN() macros.
+class LogMessage : angle::NonCopyable
+{
+  public:
+    // Used for ANGLE_LOG(severity).
+    LogMessage(const char *function, int line, LogSeverity severity);
+    ~LogMessage();
+    std::ostream &stream() { return mStream; }
+
+  private:
+    void init(const char *function, int line);
+
+    LogSeverity mSeverity;
+    std::ostringstream mStream;
+    size_t mMessageStart;  // Offset of the start of the message (past prefix info).
+    // The function and line information passed in to the constructor.
+    const char *mFunction;
+    const int mLine;
+};
+
+template <int N, typename T>
+std::ostream &FmtHex(std::ostream &os, T value)
+{
+    os << "0x";
+
+    std::ios_base::fmtflags oldFlags = os.flags();
+    std::streamsize oldWidth         = os.width();
+    std::ostream::char_type oldFill  = os.fill();
+
+    os << std::hex << std::uppercase << std::setw(N) << std::setfill('0') << value;
+
+    os.flags(oldFlags);
+    os.width(oldWidth);
+    os.fill(oldFill);
+
+    return os;
+}
+}  // namespace priv
+
+#if defined(ANGLE_PLATFORM_WINDOWS)
+class FmtHR
+{
+  public:
+    explicit FmtHR(HRESULT hresult) : mHR(hresult) {}
+  private:
+    HRESULT mHR;
+    friend std::ostream &operator<<(std::ostream &os, const FmtHR &fmt);
+};
+#endif  // defined(ANGLE_PLATFORM_WINDOWS)
+
+template <typename T>
+std::ostream &FmtHexShort(std::ostream &os, T value)
+{
+    return priv::FmtHex<4>(os, value);
+}
+
+template <typename T>
+std::ostream &FmtHexInt(std::ostream &os, T value)
+{
+    return priv::FmtHex<8>(os, value);
+}
+
+// A few definitions of macros that don't generate much code. These are used
+// by ANGLE_LOG(). Since these are used all over our code, it's
+// better to have compact code for these operations.
+#define COMPACT_ANGLE_LOG_EX_EVENT(ClassName, ...) \
+    ::gl::priv::ClassName(__FUNCTION__, __LINE__, ::gl::LOG_EVENT, ##__VA_ARGS__)
+#define COMPACT_ANGLE_LOG_EX_WARN(ClassName, ...) \
+    ::gl::priv::ClassName(__FUNCTION__, __LINE__, ::gl::LOG_WARN, ##__VA_ARGS__)
+#define COMPACT_ANGLE_LOG_EX_ERR(ClassName, ...) \
+    ::gl::priv::ClassName(__FUNCTION__, __LINE__, ::gl::LOG_ERR, ##__VA_ARGS__)
+
+#define COMPACT_ANGLE_LOG_EVENT COMPACT_ANGLE_LOG_EX_EVENT(LogMessage)
+#define COMPACT_ANGLE_LOG_WARN COMPACT_ANGLE_LOG_EX_WARN(LogMessage)
+#define COMPACT_ANGLE_LOG_ERR COMPACT_ANGLE_LOG_EX_ERR(LogMessage)
+
+#define ANGLE_LOG_IS_ON(severity) (::gl::priv::ShouldCreateLogMessage(::gl::LOG_##severity))
+
+// Helper macro which avoids evaluating the arguments to a stream if the condition doesn't hold.
+// Condition is evaluated once and only once.
+#define ANGLE_LAZY_STREAM(stream, condition) \
+    !(condition) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify() & (stream)
+
+// We use the preprocessor's merging operator, "##", so that, e.g.,
+// ANGLE_LOG(EVENT) becomes the token COMPACT_ANGLE_LOG_EVENT.  There's some funny
+// subtle difference between ostream member streaming functions (e.g.,
+// ostream::operator<<(int) and ostream non-member streaming functions
+// (e.g., ::operator<<(ostream&, string&): it turns out that it's
+// impossible to stream something like a string directly to an unnamed
+// ostream. We employ a neat hack by calling the stream() member
+// function of LogMessage which seems to avoid the problem.
+#define ANGLE_LOG_STREAM(severity) COMPACT_ANGLE_LOG_##severity.stream()
+
+#define ANGLE_LOG(severity) ANGLE_LAZY_STREAM(ANGLE_LOG_STREAM(severity), ANGLE_LOG_IS_ON(severity))
+
 }  // namespace gl
 
 #if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
@@ -81,26 +200,8 @@
 #define ANGLE_ENABLE_ASSERTS
 #endif
 
-// A macro to output a trace of a function call and its arguments to the debugging log
-#if defined(ANGLE_TRACE_ENABLED)
-#define TRACE(message, ...) gl::trace(true, gl::MESSAGE_TRACE, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#else
-#define TRACE(message, ...) (void(0))
-#endif
-
-// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing.
-#if defined(ANGLE_TRACE_ENABLED)
-#define FIXME(message, ...) gl::trace(false, gl::MESSAGE_FIXME, "fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#else
-#define FIXME(message, ...) (void(0))
-#endif
-
-// A macro to output a function call and its arguments to the debugging log, in case of error.
-#if defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ENABLE_ASSERTS)
-#define ERR(message, ...) gl::trace(false, gl::MESSAGE_ERR, "err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
-#else
-#define ERR(message, ...) (void(0))
-#endif
+#define WARN() ANGLE_LOG(WARN)
+#define ERR() ANGLE_LOG(ERR)
 
 // A macro to log a performance event around a scope.
 #if defined(ANGLE_TRACE_ENABLED)
@@ -130,11 +231,6 @@
 #define ANGLE_ASSERT_IMPL(expression) ANGLE_CRASH()
 #endif  // !defined(NDEBUG)
 
-// Helper macro which avoids evaluating the arguments to a stream if the condition doesn't hold.
-// Condition is evaluated once and only once.
-#define ANGLE_LAZY_STREAM(stream, condition) \
-    !(condition) ? static_cast<void>(0) : ::gl::LogMessageVoidify() & (stream)
-
 #if defined(NDEBUG) && !defined(ANGLE_ENABLE_ASSERTS)
 #define ANGLE_ASSERTS_ON 0
 #else
@@ -143,13 +239,13 @@
 
 // A macro asserting a condition and outputting failures to the debug log
 #if ANGLE_ASSERTS_ON
-#define ASSERT(expression)                                                                      \
-    (expression ? static_cast<void>(0)                                                          \
-                : (ERR("\t! Assert failed in %s(%d): %s", __FUNCTION__, __LINE__, #expression), \
-                   ANGLE_ASSERT_IMPL(expression)))
+#define ASSERT(expression)                                                                         \
+    (expression ? static_cast<void>(0) : ((ERR() << "\t! Assert failed in " << __FUNCTION__ << "(" \
+                                                 << __LINE__ << "): " << #expression),             \
+                                          ANGLE_ASSERT_IMPL(expression)))
 #else
-#define ASSERT(condition)                                                           \
-    ANGLE_LAZY_STREAM(::gl::DummyStream(), ANGLE_ASSERTS_ON ? !(condition) : false) \
+#define ASSERT(condition)                                                                 \
+    ANGLE_LAZY_STREAM(::gl::priv::DummyStream(), ANGLE_ASSERTS_ON ? !(condition) : false) \
         << "Check failed: " #condition ". "
 #endif  // ANGLE_ASSERTS_ON
 
@@ -160,15 +256,27 @@
 #define NOASSERT_UNIMPLEMENTED 1
 #endif
 
-#define UNIMPLEMENTED()                                           \
-    {                                                             \
-        ERR("\t! Unimplemented: %s(%d)", __FUNCTION__, __LINE__); \
-        ASSERT(NOASSERT_UNIMPLEMENTED);                           \
-    }                                                             \
+#if defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ASSERTS_ON)
+#define UNIMPLEMENTED()                                                           \
+    {                                                                             \
+        ERR() << "\t! Unimplemented: " << __FUNCTION__ << "(" << __LINE__ << ")"; \
+        ASSERT(NOASSERT_UNIMPLEMENTED);                                           \
+    }                                                                             \
     ANGLE_EMPTY_STATEMENT
 
 // A macro for code which is not expected to be reached under valid assumptions
-#define UNREACHABLE() \
-    (ERR("\t! Unreachable reached: %s(%d)", __FUNCTION__, __LINE__), ASSERT(false))
+#define UNREACHABLE()                                                                  \
+    ((ERR() << "\t! Unreachable reached: " << __FUNCTION__ << "(" << __LINE__ << ")"), \
+     ASSERT(false))
+#else
+#define UNIMPLEMENTED()                 \
+    {                                   \
+        ASSERT(NOASSERT_UNIMPLEMENTED); \
+    }                                   \
+    ANGLE_EMPTY_STATEMENT
+
+// A macro for code which is not expected to be reached under valid assumptions
+#define UNREACHABLE() ASSERT(false)
+#endif  // defined(ANGLE_TRACE_ENABLED) || defined(ANGLE_ENABLE_ASSERTS)
 
 #endif   // COMMON_DEBUG_H_
diff --git a/src/libANGLE/Display.cpp b/src/libANGLE/Display.cpp
index 69c1af0..d1dec21 100644
--- a/src/libANGLE/Display.cpp
+++ b/src/libANGLE/Display.cpp
@@ -80,19 +80,18 @@
 
 void DefaultPlatform::logError(const char *errorMessage)
 {
-    ERR("%s", errorMessage);
+    ERR() << errorMessage;
 }
 
 void DefaultPlatform::logWarning(const char *warningMessage)
 {
-    // TODO(jmadill): Fix this
-    ERR("%s", warningMessage);
+    WARN() << warningMessage;
 }
 
 void DefaultPlatform::logInfo(const char *infoMessage)
 {
     // Uncomment this if you want Vulkan spam.
-    // ERR("%s", infoMessage);
+    // WARN() << infoMessage;
 }
 
 }  // namespace angle
diff --git a/src/libANGLE/Error.cpp b/src/libANGLE/Error.cpp
index d40dc59..33cab98 100644
--- a/src/libANGLE/Error.cpp
+++ b/src/libANGLE/Error.cpp
@@ -10,6 +10,7 @@
 #include "libANGLE/Error.h"
 
 #include "common/angleutils.h"
+#include "common/debug.h"
 
 #include <cstdarg>
 
@@ -70,6 +71,11 @@
     return !(*this == other);
 }
 
+std::ostream &operator<<(std::ostream &os, const Error &err)
+{
+    return gl::FmtHexShort(os, err.getCode());
+}
+
 namespace priv
 {
 template <GLenum EnumT>
@@ -130,4 +136,8 @@
     return *mMessage;
 }
 
+std::ostream &operator<<(std::ostream &os, const Error &err)
+{
+    return gl::FmtHexShort(os, err.getCode());
+}
 }
diff --git a/src/libANGLE/Error.h b/src/libANGLE/Error.h
index 3b9b681..bce4cd2 100644
--- a/src/libANGLE/Error.h
+++ b/src/libANGLE/Error.h
@@ -13,8 +13,9 @@
 #include "common/angleutils.h"
 #include <EGL/egl.h>
 
-#include <string>
 #include <memory>
+#include <ostream>
+#include <string>
 
 namespace angle
 {
@@ -70,6 +71,8 @@
   private:
     void createMessageString() const;
 
+    friend std::ostream &operator<<(std::ostream &os, const Error &err);
+
     GLenum mCode;
     GLuint mID;
     mutable std::unique_ptr<std::string> mMessage;
@@ -167,6 +170,8 @@
   private:
     void createMessageString() const;
 
+    friend std::ostream &operator<<(std::ostream &os, const Error &err);
+
     EGLint mCode;
     EGLint mID;
     mutable std::unique_ptr<std::string> mMessage;
diff --git a/src/libANGLE/Shader.cpp b/src/libANGLE/Shader.cpp
index a4c6895..34f30dd 100644
--- a/src/libANGLE/Shader.cpp
+++ b/src/libANGLE/Shader.cpp
@@ -281,7 +281,7 @@
     if (!result)
     {
         mInfoLog = sh::GetInfoLog(compilerHandle);
-        TRACE("\n%s", mInfoLog.c_str());
+        WARN() << std::endl << mInfoLog;
         mCompiled = false;
         return;
     }
diff --git a/src/libANGLE/formatutils.cpp b/src/libANGLE/formatutils.cpp
index 6692d3f..928d055 100644
--- a/src/libANGLE/formatutils.cpp
+++ b/src/libANGLE/formatutils.cpp
@@ -6,8 +6,9 @@
 
 // formatutils.cpp: Queries for GL image formats.
 
-#include "common/mathutil.h"
 #include "libANGLE/formatutils.h"
+
+#include "common/mathutil.h"
 #include "libANGLE/Context.h"
 #include "libANGLE/Framebuffer.h"
 
@@ -286,6 +287,12 @@
     return invalid;
 }
 
+std::ostream &operator<<(std::ostream &os, const Format &fmt)
+{
+    // TODO(ynovikov): return string representation when available
+    return FmtHexShort(os, fmt.asSized());
+}
+
 bool InternalFormat::operator==(const InternalFormat &other) const
 {
     // We assume there are no duplicates.
diff --git a/src/libANGLE/formatutils.h b/src/libANGLE/formatutils.h
index f107bac..85b2378 100644
--- a/src/libANGLE/formatutils.h
+++ b/src/libANGLE/formatutils.h
@@ -10,6 +10,7 @@
 #define LIBANGLE_FORMATUTILS_H_
 
 #include <cstddef>
+#include <ostream>
 #include <stdint.h>
 
 #include "angle_gl.h"
@@ -137,6 +138,8 @@
     static Format Invalid();
     static bool SameSized(const Format &a, const Format &b);
 
+    friend std::ostream &operator<<(std::ostream &os, const Format &fmt);
+
     // This is the sized info.
     const InternalFormat *info;
     GLenum format;
diff --git a/src/libANGLE/renderer/d3d/HLSLCompiler.cpp b/src/libANGLE/renderer/d3d/HLSLCompiler.cpp
index 58746bc..3b4d638 100644
--- a/src/libANGLE/renderer/d3d/HLSLCompiler.cpp
+++ b/src/libANGLE/renderer/d3d/HLSLCompiler.cpp
@@ -136,7 +136,7 @@
 
     if (!mD3DCompilerModule)
     {
-        ERR("D3D compiler module not found.");
+        ERR() << "D3D compiler module not found.";
         return gl::Error(GL_OUT_OF_MEMORY, "D3D compiler module not found.");
     }
 
@@ -217,8 +217,8 @@
             SafeRelease(errorMessage);
 
             infoLog.appendSanitized(message.c_str());
-            TRACE("\n%s", hlsl.c_str());
-            TRACE("\n%s", message.c_str());
+            WARN() << std::endl << hlsl;
+            WARN() << std::endl << message;
 
             if ((message.find("error X3531:") != std::string::npos ||  // "can't unroll loops marked with loop attribute"
                  message.find("error X4014:") != std::string::npos) && // "cannot have gradient operations inside loops with divergent flow control",
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index b826bbc..85acde7 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -1188,9 +1188,8 @@
     }
     else if (!infoLog)
     {
-        std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3);
-        tempInfoLog.getLog(static_cast<GLsizei>(tempInfoLog.getLength()), NULL, &tempCharBuffer[0]);
-        ERR("Error compiling dynamic pixel executable:\n%s\n", &tempCharBuffer[0]);
+        ERR() << "Error compiling dynamic pixel executable:" << std::endl
+              << tempInfoLog.str() << std::endl;
     }
 
     *outExectuable = pixelExecutable;
@@ -1234,9 +1233,8 @@
     }
     else if (!infoLog)
     {
-        std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3);
-        tempInfoLog.getLog(static_cast<GLsizei>(tempInfoLog.getLength()), NULL, &tempCharBuffer[0]);
-        ERR("Error compiling dynamic vertex executable:\n%s\n", &tempCharBuffer[0]);
+        ERR() << "Error compiling dynamic vertex executable:" << std::endl
+              << tempInfoLog.str() << std::endl;
     }
 
     *outExectuable = vertexExecutable;
@@ -1285,9 +1283,8 @@
 
     if (!infoLog && error.isError())
     {
-        std::vector<char> tempCharBuffer(tempInfoLog.getLength() + 3);
-        tempInfoLog.getLog(static_cast<GLsizei>(tempInfoLog.getLength()), NULL, &tempCharBuffer[0]);
-        ERR("Error compiling dynamic geometry executable:\n%s\n", &tempCharBuffer[0]);
+        ERR() << "Error compiling dynamic geometry executable:" << std::endl
+              << tempInfoLog.str() << std::endl;
     }
 
     if (geometryExecutable != nullptr)
@@ -1454,9 +1451,8 @@
 
     if (computeExecutable == nullptr)
     {
-        std::vector<char> tempCharBuffer(infoLog.getLength() + 3);
-        infoLog.getLog(static_cast<GLsizei>(infoLog.getLength()), nullptr, &tempCharBuffer[0]);
-        ERR("Error compiling dynamic compute executable:\n%s\n", &tempCharBuffer[0]);
+        ERR() << "Error compiling dynamic compute executable:" << std::endl
+              << infoLog.str() << std::endl;
     }
     else
     {
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.cpp b/src/libANGLE/renderer/d3d/RendererD3D.cpp
index 729d7c8..87efeb8 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.cpp
+++ b/src/libANGLE/renderer/d3d/RendererD3D.cpp
@@ -184,7 +184,7 @@
         {
             // This is stictly speaking not an error, but developers should be
             // notified of risking undefined behavior.
-            ERR("Point rendering without writing to gl_PointSize.");
+            ERR() << "Point rendering without writing to gl_PointSize.";
 
             return true;
         }
diff --git a/src/libANGLE/renderer/d3d/VertexDataManager.cpp b/src/libANGLE/renderer/d3d/VertexDataManager.cpp
index 89dd4fa..72329d7 100644
--- a/src/libANGLE/renderer/d3d/VertexDataManager.cpp
+++ b/src/libANGLE/renderer/d3d/VertexDataManager.cpp
@@ -85,7 +85,7 @@
         auto errorOrElementSize = factory->getVertexSpaceRequired(attrib, 1, 0);
         if (errorOrElementSize.isError())
         {
-            ERR("Unlogged error in DirectStoragePossible.");
+            ERR() << "Unlogged error in DirectStoragePossible.";
             return false;
         }
 
@@ -194,7 +194,7 @@
 
     if (!mStreamingBuffer)
     {
-        ERR("Failed to allocate the streaming vertex buffer.");
+        ERR() << "Failed to allocate the streaming vertex buffer.";
     }
 }
 
diff --git a/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp b/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
index d106468..67ac491 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Clear11.cpp
@@ -286,11 +286,11 @@
                   formatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
                   formatInfo.componentType == GL_SIGNED_NORMALIZED))
             {
-                ERR("It is undefined behaviour to clear a render buffer which is not normalized "
-                    "fixed point or floating-"
-                    "point to floating point values (color attachment %u has internal format "
-                    "0x%X).",
-                    colorAttachmentIndex, attachment.getFormat().asSized());
+                ERR() << "It is undefined behaviour to clear a render buffer which is not "
+                         "normalized fixed point or floating-point to floating point values (color "
+                         "attachment "
+                      << colorAttachmentIndex << " has internal format " << attachment.getFormat()
+                      << ").";
             }
 
             if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) &&
@@ -618,7 +618,7 @@
         HRESULT result               = device->CreateBlendState(&blendDesc, &blendState);
         if (FAILED(result) || !blendState)
         {
-            ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result);
+            ERR() << "Unable to create a ID3D11BlendState, " << gl::FmtHR(result) << ".";
             return nullptr;
         }
 
@@ -664,7 +664,7 @@
         HRESULT result                   = device->CreateDepthStencilState(&dsDesc, &dsState);
         if (FAILED(result) || !dsState)
         {
-            ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
+            ERR() << "Unable to create a ID3D11DepthStencilState, " << gl::FmtHR(result) << ".";
             return nullptr;
         }
 
diff --git a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
index 89d5dc6..dcc0733 100644
--- a/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/InputLayoutCache.cpp
@@ -513,8 +513,8 @@
                                         &inputLayout));
             if (mLayoutMap.size() >= mCacheSize)
             {
-                TRACE("Overflowed the limit of %u input layouts, purging half the cache.",
-                      mCacheSize);
+                WARN() << "Overflowed the limit of " << mCacheSize
+                       << " input layouts, purging half the cache.";
 
                 // Randomly release every second element
                 auto it = mLayoutMap.begin();
diff --git a/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp b/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp
index 329cd5e..1d664b7 100644
--- a/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/RenderStateCache.cpp
@@ -132,8 +132,8 @@
     {
         if (mBlendStateCache.size() >= kMaxBlendStates)
         {
-            TRACE("Overflowed the limit of %u blend states, removing the least recently used "
-                  "to make room.", kMaxBlendStates);
+            WARN() << "Overflowed the limit of " << kMaxBlendStates
+                   << " blend states, removing the least recently used to make room.";
 
             BlendStateMap::iterator leastRecentlyUsed = mBlendStateCache.begin();
             for (BlendStateMap::iterator i = mBlendStateCache.begin(); i != mBlendStateCache.end(); i++)
@@ -226,8 +226,8 @@
     {
         if (mRasterizerStateCache.size() >= kMaxRasterizerStates)
         {
-            TRACE("Overflowed the limit of %u rasterizer states, removing the least recently used "
-                  "to make room.", kMaxRasterizerStates);
+            WARN() << "Overflowed the limit of " << kMaxRasterizerStates
+                   << " rasterizer states, removing the least recently used to make room.";
 
             RasterizerStateMap::iterator leastRecentlyUsed = mRasterizerStateCache.begin();
             for (RasterizerStateMap::iterator i = mRasterizerStateCache.begin(); i != mRasterizerStateCache.end(); i++)
@@ -333,10 +333,8 @@
 
     if (mDepthStencilStateCache.size() >= kMaxDepthStencilStates)
     {
-        TRACE(
-            "Overflowed the limit of %u depth stencil states, removing the least recently used "
-            "to make room.",
-            kMaxDepthStencilStates);
+        WARN() << "Overflowed the limit of " << kMaxDepthStencilStates
+               << " depth stencil states, removing the least recently used to make room.";
 
         auto leastRecentlyUsed = mDepthStencilStateCache.begin();
         for (auto i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++)
@@ -414,8 +412,8 @@
     {
         if (mSamplerStateCache.size() >= kMaxSamplerStates)
         {
-            TRACE("Overflowed the limit of %u sampler states, removing the least recently used "
-                  "to make room.", kMaxSamplerStates);
+            WARN() << "Overflowed the limit of " << kMaxSamplerStates
+                   << " sampler states, removing the least recently used to make room.";
 
             SamplerStateMap::iterator leastRecentlyUsed = mSamplerStateCache.begin();
             for (SamplerStateMap::iterator i = mSamplerStateCache.begin(); i != mSamplerStateCache.end(); i++)
diff --git a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
index 8a20d4e..d36675d 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp
@@ -9,7 +9,6 @@
 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
 
 #include <EGL/eglext.h>
-#include <iomanip>
 #include <sstream>
 #include <versionhelpers.h>
 
@@ -733,7 +732,7 @@
 
         if (!mDevice || FAILED(result))
         {
-            ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n");
+            ERR() << "Failed creating Debug D3D11 device - falling back to release runtime.";
         }
 
         if (!mDevice || FAILED(result))
@@ -869,7 +868,7 @@
     if (FAILED(hr))
     {
         mRenderer11DeviceCaps.driverVersion.reset();
-        ERR("Error querying driver version from DXGI Adapter.");
+        ERR() << "Error querying driver version from DXGI Adapter.";
     }
     else
     {
@@ -2651,7 +2650,7 @@
 
     if (isLost)
     {
-        ERR("The D3D11 device was removed: 0x%08X", result);
+        ERR() << "The D3D11 device was removed, " << gl::FmtHR(result);
     }
 
     return isLost;
@@ -2761,7 +2760,7 @@
 
     if (result.isError())
     {
-        ERR("Could not reinitialize D3D11 device: %08X", result.getCode());
+        ERR() << "Could not reinitialize D3D11 device: " << result;
         return false;
     }
 
diff --git a/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp b/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
index a410c42..e9bcbf0 100644
--- a/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/SwapChain11.cpp
@@ -227,7 +227,7 @@
 
         if (FAILED(result))
         {
-            ERR("Could not create offscreen texture: %08lX", result);
+            ERR() << "Could not create offscreen texture, " << gl::FmtHR(result);
             release();
 
             if (d3d11::isDeviceLostError(result))
@@ -251,7 +251,7 @@
             // Fall back to no share handle on failure
             if (FAILED(result))
             {
-                ERR("Could not query offscreen texture resource: %08lX", result);
+                ERR() << "Could not query offscreen texture resource, " << gl::FmtHR(result);
             }
             else
             {
@@ -261,7 +261,7 @@
                 if (FAILED(result))
                 {
                     mShareHandle = NULL;
-                    ERR("Could not get offscreen texture shared handle: %08lX", result);
+                    ERR() << "Could not get offscreen texture shared handle, " << gl::FmtHR(result);
                 }
             }
         }
@@ -348,7 +348,8 @@
             device->CreateTexture2D(&depthStencilTextureDesc, NULL, &mDepthStencilTexture);
         if (FAILED(result))
         {
-            ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
+            ERR() << "Could not create depthstencil surface for new swap chain, "
+                  << gl::FmtHR(result);
             release();
 
             if (d3d11::isDeviceLostError(result))
@@ -423,7 +424,7 @@
     HRESULT result = mSwapChain->GetDesc(&desc);
     if (FAILED(result))
     {
-        ERR("Error reading swap chain description: 0x%08X", result);
+        ERR() << "Error reading swap chain description, " << gl::FmtHR(result);
         release();
         return EGL_BAD_ALLOC;
     }
@@ -432,7 +433,7 @@
 
     if (FAILED(result))
     {
-        ERR("Error resizing swap chain buffers: 0x%08X", result);
+        ERR() << "Error resizing swap chain buffers, " << gl::FmtHR(result);
         release();
 
         if (d3d11::isDeviceLostError(result))
@@ -523,7 +524,8 @@
 
         if (FAILED(result))
         {
-            ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
+            ERR() << "Could not create additional swap chains or offscreen surfaces, "
+                  << gl::FmtHR(result);
             release();
 
             if (d3d11::isDeviceLostError(result))
@@ -810,18 +812,18 @@
 
     if (result == DXGI_ERROR_DEVICE_REMOVED)
     {
-        ERR("Present failed: the D3D11 device was removed: 0x%08X",
-            mRenderer->getDevice()->GetDeviceRemovedReason());
+        ERR() << "Present failed: the D3D11 device was removed, "
+              << gl::FmtHR(mRenderer->getDevice()->GetDeviceRemovedReason());
         return EGL_CONTEXT_LOST;
     }
     else if (result == DXGI_ERROR_DEVICE_RESET)
     {
-        ERR("Present failed: the D3D11 device was reset from a bad command.");
+        ERR() << "Present failed: the D3D11 device was reset from a bad command.";
         return EGL_CONTEXT_LOST;
     }
     else if (FAILED(result))
     {
-        ERR("Present failed with error code 0x%08X", result);
+        ERR() << "Present failed with " << gl::FmtHR(result);
     }
 
     mNativeWindow->commitChange();
diff --git a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
index 8a4d79d..5d01dfc 100644
--- a/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/TextureStorage11.cpp
@@ -790,7 +790,7 @@
                 if (error.isError())
                 {
                     // TODO: Find a way to report this back to the context
-                    ERR("Error initialization texture storage: %x", error.getCode());
+                    ERR() << "Error initialization texture storage: " << error;
                 }
             }
         }
diff --git a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
index 24c7fe2..fe0d6da 100644
--- a/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/renderer11_utils.cpp
@@ -61,7 +61,7 @@
             else
             {
                 // TODO(jmadill): find out why we fail this call sometimes in FL9_3
-                // ERR("Error checking format support for format 0x%x", dxgiFormat);
+                // ERR() << "Error checking format support for format 0x" << std::hex << dxgiFormat;
             }
         }
 
diff --git a/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp b/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
index 0211e68..36e4bd0 100644
--- a/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.cpp
@@ -64,7 +64,8 @@
         // A EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty can't both be specified
         if (mSwapChainScaleSpecified && mSwapChainSizeSpecified)
         {
-            ERR("It is invalid to specify both an EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty.");
+            ERR() << "It is invalid to specify both an EGLRenderSurfaceSizeProperty and a "
+                     "EGLRenderResolutionScaleProperty.";
             return false;
         }
     }
diff --git a/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp b/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
index 5bf67f9..cc81521 100644
--- a/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.cpp
@@ -83,7 +83,8 @@
     // considered invalid.
     if (SUCCEEDED(result) && !hasEglNativeWindowPropertyKey)
     {
-        ERR("Could not find EGLNativeWindowTypeProperty in IPropertySet. Valid EGLNativeWindowTypeProperty values include ICoreWindow");
+        ERR() << "Could not find EGLNativeWindowTypeProperty in IPropertySet. Valid "
+                 "EGLNativeWindowTypeProperty values include ICoreWindow";
         return false;
     }
 
diff --git a/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.cpp b/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.cpp
index a5ce4ca..2ef2235 100644
--- a/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.cpp
@@ -62,9 +62,8 @@
     }
     else
     {
-        ERR(
-            "Invalid IInspectable EGLNativeWindowType detected. Valid IInspectables include "
-            "ICoreWindow, ISwapChainPanel and IPropertySet");
+        ERR() << "Invalid IInspectable EGLNativeWindowType detected. Valid IInspectables include "
+                 "ICoreWindow, ISwapChainPanel and IPropertySet";
     }
 
     return false;
diff --git a/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp b/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
index 1dae1ad..0887257 100644
--- a/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.cpp
@@ -78,7 +78,8 @@
             // unrecoverable state (probably deadlocked). We therefore terminate the application
             // entirely. This also prevents stack corruption if the async operation is eventually
             // run.
-            ERR("Timeout waiting for async action on UI thread. The UI thread might be blocked.");
+            ERR()
+                << "Timeout waiting for async action on UI thread. The UI thread might be blocked.";
             std::terminate();
             return E_FAIL;
         }
@@ -132,7 +133,8 @@
         // A EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty can't both be specified
         if (mSwapChainScaleSpecified && mSwapChainSizeSpecified)
         {
-            ERR("It is invalid to specify both an EGLRenderSurfaceSizeProperty and a EGLRenderResolutionScaleProperty.");
+            ERR() << "It is invalid to specify both an EGLRenderSurfaceSizeProperty and a "
+                     "EGLRenderResolutionScaleProperty.";
             return false;
         }
     }
@@ -352,4 +354,4 @@
 
     return result;
 }
-}
\ No newline at end of file
+}
diff --git a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
index 680c47f..9f76331 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp
@@ -2258,13 +2258,13 @@
 
     if (FAILED(result))
     {
-        ERR("Reset/ResetEx failed multiple times: 0x%08X", result);
+        ERR() << "Reset/ResetEx failed multiple times, " << gl::FmtHR(result);
         return false;
     }
 
     if (removedDevice && lost)
     {
-        ERR("Device lost reset failed multiple times");
+        ERR() << "Device lost reset failed multiple times";
         return false;
     }
 
diff --git a/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp b/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp
index 013b30f..17ece72 100644
--- a/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp
@@ -750,7 +750,7 @@
 {
     if (enabled)
     {
-        FIXME("Sample alpha to coverage is unimplemented.");
+        UNREACHABLE();
     }
 }
 
diff --git a/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp b/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
index 7e6948e..abf4846 100644
--- a/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp
@@ -7,11 +7,12 @@
 // SwapChain9.cpp: Implements a back-end specific class for the D3D9 swap chain.
 
 #include "libANGLE/renderer/d3d/d3d9/SwapChain9.h"
-#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
+
+#include "libANGLE/features.h"
 #include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
 #include "libANGLE/renderer/d3d/d3d9/NativeWindow9.h"
 #include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
-#include "libANGLE/features.h"
+#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
 
 namespace rx
 {
@@ -126,7 +127,7 @@
                                        &mOffscreenTexture, pShareHandle);
         if (FAILED(result))
         {
-            ERR("Could not create offscreen texture: %08lX", result);
+            ERR() << "Could not create offscreen texture, " << gl::FmtHR(result);
             release();
 
             if (d3d9::isDeviceLostError(result))
@@ -212,7 +213,8 @@
         {
             ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST);
 
-            ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
+            ERR() << "Could not create additional swap chains or offscreen surfaces, "
+                  << gl::FmtHR(result);
             release();
 
             if (d3d9::isDeviceLostError(result))
@@ -240,7 +242,8 @@
         {
             ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);
 
-            ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
+            ERR() << "Could not create depthstencil surface for new swap chain, "
+                  << gl::FmtHR(result);
             release();
 
             if (d3d9::isDeviceLostError(result))
diff --git a/src/libANGLE/renderer/gl/ProgramGL.cpp b/src/libANGLE/renderer/gl/ProgramGL.cpp
index 7da6c98..3769811 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -612,7 +612,7 @@
             warning = "Program link failed unexpectedly with no info log.";
         }
         ANGLEPlatformCurrent()->logWarning(warning.c_str());
-        TRACE("\n%s", warning.c_str());
+        WARN() << std::endl << warning;
 
         // TODO, return GL_OUT_OF_MEMORY or just fail the link? This is an unexpected case
         return false;
diff --git a/src/libANGLE/renderer/gl/RendererGL.cpp b/src/libANGLE/renderer/gl/RendererGL.cpp
index 7865ee2..55b9f12 100644
--- a/src/libANGLE/renderer/gl/RendererGL.cpp
+++ b/src/libANGLE/renderer/gl/RendererGL.cpp
@@ -93,8 +93,12 @@
       default:                             severityText = "UNKNOWN";      break;
     }
 
-    ERR("\n\tSource: %s\n\tType: %s\n\tID: %d\n\tSeverity: %s\n\tMessage: %s", sourceText.c_str(), typeText.c_str(), id,
-        severityText.c_str(), message);
+    ERR() << std::endl
+          << "\tSource: " << sourceText << std::endl
+          << "\tType: " << typeText << std::endl
+          << "\tID: " << id << std::endl
+          << "\tSeverity: " << severityText << std::endl
+          << "\tMessage: " << message;
 }
 #endif
 
diff --git a/src/libANGLE/renderer/gl/ShaderGL.cpp b/src/libANGLE/renderer/gl/ShaderGL.cpp
index 9c62b03..8fc7d46 100644
--- a/src/libANGLE/renderer/gl/ShaderGL.cpp
+++ b/src/libANGLE/renderer/gl/ShaderGL.cpp
@@ -128,11 +128,11 @@
             mShaderID = 0;
 
             *infoLog = &buf[0];
-            TRACE("\n%s", infoLog->c_str());
+            WARN() << std::endl << *infoLog;
         }
         else
         {
-            TRACE("\nShader compilation failed with no info log.");
+            WARN() << std::endl << "Shader compilation failed with no info log.";
         }
         return false;
     }
diff --git a/src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp b/src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp
index ecb58f9..364def9 100644
--- a/src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp
+++ b/src/libANGLE/renderer/gl/egl/SurfaceEGL.cpp
@@ -94,7 +94,7 @@
     EGLBoolean success = mEGL->swapInterval(interval);
     if (success == EGL_FALSE)
     {
-        ERR("eglSwapInterval error 0x%04x", mEGL->getError());
+        ERR() << "eglSwapInterval error " << egl::Error(mEGL->getError());
         ASSERT(false);
     }
 }
diff --git a/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp b/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp
index dad50b8..9ff8c01 100644
--- a/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp
+++ b/src/libANGLE/renderer/gl/egl/android/DisplayAndroid.cpp
@@ -115,7 +115,7 @@
     EGLBoolean success = mEGL->makeCurrent(EGL_NO_SURFACE, EGL_NO_CONTEXT);
     if (success == EGL_FALSE)
     {
-        ERR("eglMakeCurrent error 0x%04x", mEGL->getError());
+        ERR() << "eglMakeCurrent error " << egl::Error(mEGL->getError());
     }
 
     if (mDummyPbuffer != EGL_NO_SURFACE)
@@ -124,7 +124,7 @@
         mDummyPbuffer = EGL_NO_SURFACE;
         if (success == EGL_FALSE)
         {
-            ERR("eglDestroySurface error 0x%04x", mEGL->getError());
+            ERR() << "eglDestroySurface error " << egl::Error(mEGL->getError());
         }
     }
 
@@ -134,14 +134,14 @@
         mContext = EGL_NO_CONTEXT;
         if (success == EGL_FALSE)
         {
-            ERR("eglDestroyContext error 0x%04x", mEGL->getError());
+            ERR() << "eglDestroyContext error " << egl::Error(mEGL->getError());
         }
     }
 
     egl::Error result = mEGL->terminate();
     if (result.isError())
     {
-        ERR("eglTerminate error 0x%04x", result.getCode());
+        ERR() << "eglTerminate error " << result;
     }
 
     SafeDelete(mEGL);
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index f07b216..7547da3 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -3159,8 +3159,8 @@
         {
             if (!context->getExtensions().webglCompatibility)
             {
-                ERR("This ANGLE implementation does not support separate front/back stencil "
-                    "writemasks, reference values, or stencil mask values.");
+                ERR() << "This ANGLE implementation does not support separate front/back stencil "
+                         "writemasks, reference values, or stencil mask values.";
             }
             context->handleError(Error(GL_INVALID_OPERATION));
             return false;
@@ -4611,7 +4611,7 @@
 
         // We also output an error message to the debugger window if tracing is active, so that
         // developers can see the error message.
-        ERR("%s", errorMessage);
+        ERR() << errorMessage;
         return false;
     }
 
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index dc2a008..13fcfe6 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -1910,8 +1910,8 @@
                                   dstX0, dstY0, dstX1, dstY1))
                 {
                     // only whole-buffer copies are permitted
-                    ERR("Only whole-buffer depth and stencil blits are supported by this "
-                        "implementation.");
+                    ERR() << "Only whole-buffer depth and stencil blits are supported by this "
+                             "implementation.";
                     context->handleError(Error(GL_INVALID_OPERATION));
                     return false;
                 }
@@ -3839,9 +3839,9 @@
 
         if (constantColorUsed && constantAlphaUsed)
         {
-            ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
-                "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
-                "implementation.");
+            ERR() << "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
+                     "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
+                     "implementation.";
             context->handleError(Error(GL_INVALID_OPERATION,
                                        "Simultaneous use of "
                                        "GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
diff --git a/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
index 88ef79a..4a74867 100644
--- a/src/libGLESv2/entry_points_gles_2_0_ext.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
@@ -680,7 +680,7 @@
                 context->handleError(Error(GL_INVALID_OPERATION, errorMessage));
 
                 // We also output an error message to the debugger window if tracing is active, so that developers can see the error message.
-                ERR("%s", errorMessage);
+                ERR() << errorMessage;
 
                 return;
             }
diff --git a/src/libGLESv2/global_state.cpp b/src/libGLESv2/global_state.cpp
index bc776b1..c5f3dfe 100644
--- a/src/libGLESv2/global_state.cpp
+++ b/src/libGLESv2/global_state.cpp
@@ -50,7 +50,7 @@
     Thread *thread = new Thread();
     if (!SetTLSValue(threadTLS, thread))
     {
-        ERR("Could not set thread local storage.");
+        ERR() << "Could not set thread local storage.";
         return nullptr;
     }