1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef GPU_COMMAND_BUFFER_COMMON_LOGGING_H_
6#define GPU_COMMAND_BUFFER_COMMON_LOGGING_H_
7
8#include <assert.h>
9
10#include <ostream>
11
12#include "gpu/command_buffer/common/gles2_utils_export.h"
13
14// Windows defines an ERROR macro.
15#ifdef ERROR
16#undef ERROR
17#endif
18
19namespace gpu {
20
21// Members are uppercase instead of kCamelCase for consistency with base log
22// severity enum.
23enum LogLevel {
24  INFO,
25  WARNING,
26  ERROR,
27  FATAL
28};
29
30// This is a very simple logger for use in command buffer code. Common and
31// command buffer code cannot be dependent on base. It just outputs the message
32// to stderr.
33class GLES2_UTILS_EXPORT Logger {
34 public:
35  Logger(bool condition, LogLevel level)
36      : condition_(condition),
37        level_(level) {
38  }
39
40  template <typename X>
41  static Logger CheckTrue(const X& x,
42                          const char* file, int line,
43                          const char* x_name,
44                          const char* check_name) {
45    if (!!x)
46        return Logger(true, FATAL);
47
48    return Logger(false, FATAL)
49        << file << "(" << line << "): " << check_name
50        << "(" << x_name << " (" << x << ")) failed. ";
51  }
52
53  template <typename X, typename Y>
54  static Logger CheckEqual(const X& x, const Y& y,
55                           const char* file, int line,
56                           const char* x_name, const char* y_name,
57                           const char* check_name) {
58    if (x == y)
59        return Logger(true, FATAL);
60
61    return Logger(false, FATAL)
62        << file << "(" << line << "): " << check_name
63        << "(" << x_name << " (" << x << "), "
64        << y_name << "(" << y << ")) failed. ";
65  }
66
67  template <typename X, typename Y>
68  static Logger CheckNotEqual(const X& x, const Y& y,
69                              const char* file, int line,
70                              const char* x_name, const char* y_name,
71                              const char* check_name) {
72    if (x != y)
73        return Logger(true, FATAL);
74
75    return Logger(false, FATAL)
76        << file << "(" << line << "): " << check_name
77        << "(" << x_name << " (" << x << "), "
78        << y_name << "(" << y << ")) failed. ";
79  }
80
81  template <typename X, typename Y>
82  static Logger CheckLessThan(const X& x, const Y& y,
83                              const char* file, int line,
84                              const char* x_name, const char* y_name,
85                              const char* check_name) {
86    if (x < y)
87        return Logger(true, FATAL);
88
89    return Logger(false, FATAL)
90        << file << "(" << line << "): " << check_name
91        << "(" << x_name << " (" << x << "), "
92        << y_name << "(" << y << ")) failed. ";
93  }
94
95  template <typename X, typename Y>
96  static Logger CheckGreaterThan(const X& x, const Y& y,
97                                 const char* file, int line,
98                                 const char* x_name, const char* y_name,
99                                 const char* check_name) {
100    if (x > y)
101        return Logger(true, FATAL);
102
103    return Logger(false, FATAL)
104        << file << "(" << line << "): " << check_name
105        << "(" << x_name << " (" << x << "), "
106        << y_name << "(" << y << ")) failed. ";
107  }
108
109  template <typename X, typename Y>
110  static Logger CheckLessEqual(const X& x, const Y& y,
111                               const char* file, int line,
112                               const char* x_name, const char* y_name,
113                               const char* check_name) {
114    if (x <= y)
115        return Logger(true, FATAL);
116
117    return Logger(false, FATAL)
118        << file << "(" << line << "): " << check_name
119        << "(" << x_name << " (" << x << "), "
120        << y_name << "(" << y << ")) failed. ";
121  }
122
123  template <typename X, typename Y>
124  static Logger CheckGreaterEqual(const X& x, const Y& y,
125                                  const char* file, int line,
126                                  const char* x_name, const char* y_name,
127                                  const char* check_name) {
128    if (x >= y)
129        return Logger(true, FATAL);
130
131    return Logger(false, FATAL)
132        << file << "(" << line << "): " << check_name
133        << "(" << x_name << " (" << x << "), "
134        << y_name << "(" << y << ")) failed. ";
135  }
136
137  // Retrieves the stream that we write to. This header cannot depend on
138  // <iostream> because that will add static initializers to all files that
139  // include this header.
140  std::ostream& stream();
141
142  ~Logger();
143
144  template <typename T>
145  Logger& operator<<(const T& value) {
146    if (!condition_)
147      stream() << value;
148    return *this;
149  }
150
151 private:
152  Logger(const Logger& logger)
153      : condition_(logger.condition_),
154        level_(logger.level_) {
155  }
156
157  const bool condition_;
158  const LogLevel level_;
159};
160
161}  // namespace gpu
162
163#define GPU_CHECK(X) ::gpu::Logger::CheckTrue( \
164    (X), __FILE__, __LINE__, #X, "GPU_CHECK")
165#define GPU_CHECK_EQ(X, Y) ::gpu::Logger::CheckEqual( \
166    (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_CHECK_EQ")
167#define GPU_CHECK_NE(X, Y) ::gpu::Logger::CheckNotEqual( \
168    (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_CHECK_NE")
169#define GPU_CHECK_GT(X, Y) ::gpu::Logger::CheckGreaterThan( \
170    (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_CHECK_GT")
171#define GPU_CHECK_LT(X, Y) ::gpu::Logger::CheckLessThan( \
172    (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_CHECK_LT")
173#define GPU_CHECK_GE(X, Y) ::gpu::Logger::CheckGreaterEqual( \
174    (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_CHECK_GE")
175#define GPU_CHECK_LE(X, Y) ::gpu::Logger::CheckLessEqual( \
176    (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_CHECK_LE")
177#define GPU_LOG(LEVEL) ::gpu::Logger(false, LEVEL)
178
179
180#if defined(NDEBUG)
181#define GPU_DEBUG_IS_ON false
182#else
183#define GPU_DEBUG_IS_ON true
184#endif
185
186
187#define GPU_DCHECK(X) \
188  if (GPU_DEBUG_IS_ON) \
189    ::gpu::Logger::CheckTrue( \
190        (X), __FILE__, __LINE__, #X, "GPU_DCHECK")
191#define GPU_DCHECK_EQ(X, Y) \
192  if (GPU_DEBUG_IS_ON) \
193    ::gpu::Logger::CheckEqual( \
194        (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_DCHECK_EQ")
195#define GPU_DCHECK_NE(X, Y) \
196  if (GPU_DEBUG_IS_ON) \
197    ::gpu::Logger::CheckNotEqual( \
198        (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_DCHECK_NE")
199#define GPU_DCHECK_GT(X, Y) \
200  if (GPU_DEBUG_IS_ON) \
201    ::gpu::Logger::CheckGreaterThan( \
202        (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_DCHECK_GT")
203#define GPU_DCHECK_LT(X, Y) \
204  if (GPU_DEBUG_IS_ON) \
205    ::gpu::Logger::CheckLessThan( \
206        (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_DCHECK_LT")
207#define GPU_DCHECK_GE(X, Y) \
208  if (GPU_DEBUG_IS_ON) \
209    ::gpu::Logger::CheckGreaterEqual( \
210        (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_DCHECK_GE")
211#define GPU_DCHECK_LE(X, Y) \
212  if (GPU_DEBUG_IS_ON) \
213    ::gpu::Logger::CheckLessEqual( \
214        (X), (Y), __FILE__, __LINE__, #X, #Y, "GPU_DCHECK_LE")
215#define GPU_DLOG(LEVEL) if (GPU_DEBUG_IS_ON) ::gpu::Logger(true, LEVEL)
216
217
218
219#define GPU_NOTREACHED() GPU_DCHECK(false)
220
221#endif  // GPU_COMMAND_BUFFER_COMMON_LOGGING_H_
222