1 // Copyright 2019 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef COMMON_LOG_H_ 16 #define COMMON_LOG_H_ 17 18 // Dawn targets shouldn't use iostream or printf directly for several reasons: 19 // - iostream adds static initializers which we want to avoid. 20 // - printf and iostream don't show up in logcat on Android so printf debugging doesn't work but 21 // log-message debugging does. 22 // - log severity helps provide intent compared to a printf. 23 // 24 // Logging should in general be avoided: errors should go through the regular WebGPU error reporting 25 // mechanism and others form of logging should (TODO: eventually) go through the logging dependency 26 // injection, so for example they show up in Chromium's about:gpu page. Nonetheless there are some 27 // cases where logging is necessary and when this file was first introduced we needed to replace all 28 // uses of iostream so we could see them in Android's logcat. 29 // 30 // Regular logging is done using the [Debug|Info|Warning|Error]Log() function this way: 31 // 32 // InfoLog() << things << that << ostringstream << supports; // No need for a std::endl or "\n" 33 // 34 // It creates a LogMessage object that isn't stored anywhere and gets its destructor called 35 // immediately which outputs the stored ostringstream in the right place. 36 // 37 // This file also contains DAWN_DEBUG for "printf debugging" which works on Android and 38 // additionally outputs the file, line and function name. Use it this way: 39 // 40 // // Pepper this throughout code to get a log of the execution 41 // DAWN_DEBUG(); 42 // 43 // // Get more information 44 // DAWN_DEBUG() << texture.GetFormat(); 45 46 #include <sstream> 47 48 namespace dawn { 49 50 // Log levels mostly used to signal intent where the log message is produced and used to route 51 // the message to the correct output. 52 enum class LogSeverity { 53 Debug, 54 Info, 55 Warning, 56 Error, 57 }; 58 59 // Essentially an ostringstream that will print itself in its destructor. 60 class LogMessage { 61 public: 62 LogMessage(LogSeverity severity); 63 ~LogMessage(); 64 65 LogMessage(LogMessage&& other) = default; 66 LogMessage& operator=(LogMessage&& other) = default; 67 68 template <typename T> 69 LogMessage& operator<<(T&& value) { 70 mStream << value; 71 return *this; 72 } 73 74 private: 75 LogMessage(const LogMessage& other) = delete; 76 LogMessage& operator=(const LogMessage& other) = delete; 77 78 LogSeverity mSeverity; 79 std::ostringstream mStream; 80 }; 81 82 // Short-hands to create a LogMessage with the respective severity. 83 LogMessage DebugLog(); 84 LogMessage InfoLog(); 85 LogMessage WarningLog(); 86 LogMessage ErrorLog(); 87 88 // DAWN_DEBUG is a helper macro that creates a DebugLog and outputs file/line/function 89 // information 90 LogMessage DebugLog(const char* file, const char* function, int line); 91 #define DAWN_DEBUG() ::dawn::DebugLog(__FILE__, __func__, __LINE__) 92 93 } // namespace dawn 94 95 #endif // COMMON_LOG_H_ 96