• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // EGLDebugTest.cpp:
7 //   Tests of EGL_KHR_debug extension
8 
9 #include <gtest/gtest.h>
10 
11 #include "test_utils/ANGLETest.h"
12 #include "test_utils/angle_test_configs.h"
13 #include "util/EGLWindow.h"
14 
15 namespace angle
16 {
17 class EGLDebugTest : public ANGLETest
18 {
19   protected:
testTearDown()20     void testTearDown() override { eglDebugMessageControlKHR(nullptr, nullptr); }
21 
hasExtension() const22     bool hasExtension() const { return IsEGLClientExtensionEnabled("EGL_KHR_debug"); }
23 
StubCallback(EGLenum error,const char * command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char * message)24     static void EGLAPIENTRY StubCallback(EGLenum error,
25                                          const char *command,
26                                          EGLint messageType,
27                                          EGLLabelKHR threadLabel,
28                                          EGLLabelKHR objectLabel,
29                                          const char *message)
30     {}
31 
CheckBadBindAPIError(EGLenum error,const char * command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char * message)32     static void EGLAPIENTRY CheckBadBindAPIError(EGLenum error,
33                                                  const char *command,
34                                                  EGLint messageType,
35                                                  EGLLabelKHR threadLabel,
36                                                  EGLLabelKHR objectLabel,
37                                                  const char *message)
38     {
39         EXPECT_STREQ("eglBindAPI", command);
40         ASSERT_EGLENUM_EQ(EGL_BAD_PARAMETER, error);
41         EXPECT_STREQ("Thread", static_cast<const char *>(threadLabel));
42     }
43 
EGLAttribToDebugCallback(EGLAttrib attrib)44     static EGLDEBUGPROCKHR EGLAttribToDebugCallback(EGLAttrib attrib)
45     {
46         return reinterpret_cast<EGLDEBUGPROCKHR>(static_cast<uintptr_t>(attrib));
47     }
48 
DebugCallbackToEGLAttrib(EGLDEBUGPROCKHR callback)49     static EGLAttrib DebugCallbackToEGLAttrib(EGLDEBUGPROCKHR callback)
50     {
51         return static_cast<EGLAttrib>(reinterpret_cast<intptr_t>(callback));
52     }
53 };
54 
55 // Test that the extension is always available (it is implemented in ANGLE's frontend).
TEST_P(EGLDebugTest,ExtensionAlwaysAvailable)56 TEST_P(EGLDebugTest, ExtensionAlwaysAvailable)
57 {
58     ASSERT_TRUE(hasExtension());
59 }
60 
61 // Check that the default message filters and callbacks are correct
TEST_P(EGLDebugTest,DefaultParameters)62 TEST_P(EGLDebugTest, DefaultParameters)
63 {
64     ANGLE_SKIP_TEST_IF(!hasExtension());
65 
66     EXPECT_EQ(static_cast<EGLint>(EGL_SUCCESS), eglDebugMessageControlKHR(nullptr, nullptr));
67 
68     EGLAttrib result = 0;
69 
70     EXPECT_EGL_TRUE(eglQueryDebugKHR(EGL_DEBUG_MSG_ERROR_KHR, &result));
71     EXPECT_EGL_TRUE(result);
72 
73     EXPECT_EGL_TRUE(eglQueryDebugKHR(EGL_DEBUG_MSG_WARN_KHR, &result));
74     EXPECT_EGL_FALSE(result);
75 
76     EXPECT_EGL_TRUE(eglQueryDebugKHR(EGL_DEBUG_MSG_INFO_KHR, &result));
77     EXPECT_EGL_FALSE(result);
78 
79     EXPECT_EGL_TRUE(eglQueryDebugKHR(EGL_DEBUG_CALLBACK_KHR, &result));
80     EXPECT_EQ(nullptr, EGLAttribToDebugCallback(result));
81 }
82 
83 // Check that the message control and callback parameters can be set and then queried back
TEST_P(EGLDebugTest,SetMessageControl)84 TEST_P(EGLDebugTest, SetMessageControl)
85 {
86     ANGLE_SKIP_TEST_IF(!hasExtension());
87 
88     EGLAttrib controls[] = {
89         EGL_DEBUG_MSG_CRITICAL_KHR,
90         EGL_FALSE,
91         // EGL_DEBUG_MSG_ERROR_KHR left unset
92         EGL_DEBUG_MSG_WARN_KHR,
93         EGL_TRUE,
94         EGL_DEBUG_MSG_INFO_KHR,
95         EGL_FALSE,
96         EGL_NONE,
97         EGL_NONE,
98     };
99 
100     EXPECT_EQ(static_cast<EGLint>(EGL_SUCCESS), eglDebugMessageControlKHR(&StubCallback, controls));
101 
102     EGLAttrib result = 0;
103 
104     EXPECT_EGL_TRUE(eglQueryDebugKHR(EGL_DEBUG_MSG_CRITICAL_KHR, &result));
105     EXPECT_EGL_FALSE(result);
106 
107     EXPECT_EGL_TRUE(eglQueryDebugKHR(EGL_DEBUG_MSG_ERROR_KHR, &result));
108     EXPECT_EGL_TRUE(result);
109 
110     EXPECT_EGL_TRUE(eglQueryDebugKHR(EGL_DEBUG_MSG_WARN_KHR, &result));
111     EXPECT_EGL_TRUE(result);
112 
113     EXPECT_EGL_TRUE(eglQueryDebugKHR(EGL_DEBUG_MSG_INFO_KHR, &result));
114     EXPECT_EGL_FALSE(result);
115 
116     EXPECT_EGL_TRUE(eglQueryDebugKHR(EGL_DEBUG_CALLBACK_KHR, &result));
117     EXPECT_EQ(DebugCallbackToEGLAttrib(&StubCallback), result);
118 }
119 
120 // Set a thread label and then trigger a callback to verify the callback parameters are correct
TEST_P(EGLDebugTest,CorrectCallbackParameters)121 TEST_P(EGLDebugTest, CorrectCallbackParameters)
122 {
123     ANGLE_SKIP_TEST_IF(!hasExtension());
124 
125     EXPECT_EQ(static_cast<EGLint>(EGL_SUCCESS), eglDebugMessageControlKHR(nullptr, nullptr));
126 
127     EXPECT_EQ(EGL_SUCCESS, eglLabelObjectKHR(EGL_NO_DISPLAY, EGL_OBJECT_THREAD_KHR, nullptr,
128                                              const_cast<char *>("Thread")));
129 
130     // Enable all messages
131     EGLAttrib controls[] = {
132         EGL_DEBUG_MSG_CRITICAL_KHR,
133         EGL_TRUE,
134         EGL_DEBUG_MSG_ERROR_KHR,
135         EGL_TRUE,
136         EGL_DEBUG_MSG_WARN_KHR,
137         EGL_TRUE,
138         EGL_DEBUG_MSG_INFO_KHR,
139         EGL_TRUE,
140         EGL_NONE,
141         EGL_NONE,
142     };
143 
144     EXPECT_EQ(static_cast<EGLint>(EGL_SUCCESS),
145               eglDebugMessageControlKHR(&CheckBadBindAPIError, controls));
146 
147     // Generate an error and trigger the callback
148     EXPECT_EGL_FALSE(eglBindAPI(0xBADDBADD));
149 }
150 
151 // Test that labels can be set and that errors are generated if the wrong object type is used
TEST_P(EGLDebugTest,SetLabel)152 TEST_P(EGLDebugTest, SetLabel)
153 {
154     ANGLE_SKIP_TEST_IF(!hasExtension());
155 
156     EXPECT_EQ(static_cast<EGLint>(EGL_SUCCESS), eglDebugMessageControlKHR(nullptr, nullptr));
157 
158     // Display display and object must be equal when setting a display label
159     EXPECT_EQ(static_cast<EGLint>(EGL_SUCCESS),
160               eglLabelObjectKHR(getEGLWindow()->getDisplay(), EGL_OBJECT_DISPLAY_KHR,
161                                 getEGLWindow()->getDisplay(), const_cast<char *>("Display")));
162     EXPECT_NE(static_cast<EGLint>(EGL_SUCCESS),
163               eglLabelObjectKHR(nullptr, EGL_OBJECT_DISPLAY_KHR, getEGLWindow()->getDisplay(),
164                                 const_cast<char *>("Display")));
165 
166     //  Set a surface label
167     EXPECT_EQ(static_cast<EGLint>(EGL_SUCCESS),
168               eglLabelObjectKHR(getEGLWindow()->getDisplay(), EGL_OBJECT_SURFACE_KHR,
169                                 getEGLWindow()->getSurface(), const_cast<char *>("Surface")));
170     EXPECT_EGL_ERROR(EGL_SUCCESS);
171 
172     // Provide a surface but use an image label type
173     EXPECT_EQ(static_cast<EGLint>(EGL_BAD_PARAMETER),
174               eglLabelObjectKHR(getEGLWindow()->getDisplay(), EGL_OBJECT_IMAGE_KHR,
175                                 getEGLWindow()->getSurface(), const_cast<char *>("Image")));
176     EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
177 }
178 
179 ANGLE_INSTANTIATE_TEST(EGLDebugTest,
180                        ES2_D3D9(),
181                        ES2_D3D11(),
182                        ES3_D3D11(),
183                        ES2_OPENGL(),
184                        ES3_OPENGL(),
185                        ES2_VULKAN());
186 
187 }  // namespace angle
188