1*8975f5c5SAndroid Build Coastguard Worker // 2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2020 The ANGLE Project Authors. All rights reserved. 3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker // 6*8975f5c5SAndroid Build Coastguard Worker // InfoLog.h: Defines the gl::InfoLog class to handle the logs generated when 7*8975f5c5SAndroid Build Coastguard Worker // compiling/linking shaders so useful error messages can be returned to the caller. 8*8975f5c5SAndroid Build Coastguard Worker 9*8975f5c5SAndroid Build Coastguard Worker #ifndef LIBANGLE_INFOLOG_H_ 10*8975f5c5SAndroid Build Coastguard Worker #define LIBANGLE_INFOLOG_H_ 11*8975f5c5SAndroid Build Coastguard Worker 12*8975f5c5SAndroid Build Coastguard Worker namespace gl 13*8975f5c5SAndroid Build Coastguard Worker { 14*8975f5c5SAndroid Build Coastguard Worker 15*8975f5c5SAndroid Build Coastguard Worker class InfoLog : angle::NonCopyable 16*8975f5c5SAndroid Build Coastguard Worker { 17*8975f5c5SAndroid Build Coastguard Worker public: 18*8975f5c5SAndroid Build Coastguard Worker InfoLog(); 19*8975f5c5SAndroid Build Coastguard Worker ~InfoLog(); 20*8975f5c5SAndroid Build Coastguard Worker 21*8975f5c5SAndroid Build Coastguard Worker size_t getLength() const; 22*8975f5c5SAndroid Build Coastguard Worker void getLog(GLsizei bufSize, GLsizei *length, char *infoLog) const; 23*8975f5c5SAndroid Build Coastguard Worker 24*8975f5c5SAndroid Build Coastguard Worker void appendSanitized(const char *message); 25*8975f5c5SAndroid Build Coastguard Worker void reset(); 26*8975f5c5SAndroid Build Coastguard Worker 27*8975f5c5SAndroid Build Coastguard Worker // This helper class ensures we append a newline after writing a line. 28*8975f5c5SAndroid Build Coastguard Worker class StreamHelper : angle::NonCopyable 29*8975f5c5SAndroid Build Coastguard Worker { 30*8975f5c5SAndroid Build Coastguard Worker public: StreamHelper(StreamHelper && rhs)31*8975f5c5SAndroid Build Coastguard Worker StreamHelper(StreamHelper &&rhs) : mStream(rhs.mStream) { rhs.mStream = nullptr; } 32*8975f5c5SAndroid Build Coastguard Worker 33*8975f5c5SAndroid Build Coastguard Worker StreamHelper &operator=(StreamHelper &&rhs) 34*8975f5c5SAndroid Build Coastguard Worker { 35*8975f5c5SAndroid Build Coastguard Worker std::swap(mStream, rhs.mStream); 36*8975f5c5SAndroid Build Coastguard Worker return *this; 37*8975f5c5SAndroid Build Coastguard Worker } 38*8975f5c5SAndroid Build Coastguard Worker ~StreamHelper()39*8975f5c5SAndroid Build Coastguard Worker ~StreamHelper() 40*8975f5c5SAndroid Build Coastguard Worker { 41*8975f5c5SAndroid Build Coastguard Worker // Write newline when destroyed on the stack 42*8975f5c5SAndroid Build Coastguard Worker if (mStream && !mStream->str().empty()) 43*8975f5c5SAndroid Build Coastguard Worker { 44*8975f5c5SAndroid Build Coastguard Worker (*mStream) << std::endl; 45*8975f5c5SAndroid Build Coastguard Worker } 46*8975f5c5SAndroid Build Coastguard Worker } 47*8975f5c5SAndroid Build Coastguard Worker 48*8975f5c5SAndroid Build Coastguard Worker template <typename T> 49*8975f5c5SAndroid Build Coastguard Worker StreamHelper &operator<<(const T &value) 50*8975f5c5SAndroid Build Coastguard Worker { 51*8975f5c5SAndroid Build Coastguard Worker (*mStream) << value; 52*8975f5c5SAndroid Build Coastguard Worker return *this; 53*8975f5c5SAndroid Build Coastguard Worker } 54*8975f5c5SAndroid Build Coastguard Worker 55*8975f5c5SAndroid Build Coastguard Worker private: 56*8975f5c5SAndroid Build Coastguard Worker friend class InfoLog; 57*8975f5c5SAndroid Build Coastguard Worker StreamHelper(std::stringstream * stream)58*8975f5c5SAndroid Build Coastguard Worker StreamHelper(std::stringstream *stream) : mStream(stream) { ASSERT(stream); } 59*8975f5c5SAndroid Build Coastguard Worker 60*8975f5c5SAndroid Build Coastguard Worker std::stringstream *mStream; 61*8975f5c5SAndroid Build Coastguard Worker }; 62*8975f5c5SAndroid Build Coastguard Worker 63*8975f5c5SAndroid Build Coastguard Worker template <typename T> 64*8975f5c5SAndroid Build Coastguard Worker StreamHelper operator<<(const T &value) 65*8975f5c5SAndroid Build Coastguard Worker { 66*8975f5c5SAndroid Build Coastguard Worker ensureInitialized(); 67*8975f5c5SAndroid Build Coastguard Worker StreamHelper helper(mLazyStream.get()); 68*8975f5c5SAndroid Build Coastguard Worker helper << value; 69*8975f5c5SAndroid Build Coastguard Worker return helper; 70*8975f5c5SAndroid Build Coastguard Worker } 71*8975f5c5SAndroid Build Coastguard Worker str()72*8975f5c5SAndroid Build Coastguard Worker std::string str() const { return mLazyStream ? mLazyStream->str() : ""; } 73*8975f5c5SAndroid Build Coastguard Worker 74*8975f5c5SAndroid Build Coastguard Worker bool empty() const; 75*8975f5c5SAndroid Build Coastguard Worker 76*8975f5c5SAndroid Build Coastguard Worker private: ensureInitialized()77*8975f5c5SAndroid Build Coastguard Worker void ensureInitialized() 78*8975f5c5SAndroid Build Coastguard Worker { 79*8975f5c5SAndroid Build Coastguard Worker if (!mLazyStream) 80*8975f5c5SAndroid Build Coastguard Worker { 81*8975f5c5SAndroid Build Coastguard Worker mLazyStream.reset(new std::stringstream()); 82*8975f5c5SAndroid Build Coastguard Worker } 83*8975f5c5SAndroid Build Coastguard Worker } 84*8975f5c5SAndroid Build Coastguard Worker 85*8975f5c5SAndroid Build Coastguard Worker std::unique_ptr<std::stringstream> mLazyStream; 86*8975f5c5SAndroid Build Coastguard Worker }; 87*8975f5c5SAndroid Build Coastguard Worker 88*8975f5c5SAndroid Build Coastguard Worker } // namespace gl 89*8975f5c5SAndroid Build Coastguard Worker 90*8975f5c5SAndroid Build Coastguard Worker #endif // LIBANGLE_INFOLOG_H_ 91