1// Copyright 2017 The SwiftShader Authors. All Rights Reserved.
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#include "gtest/gtest.h"
16#include "gmock/gmock.h"
17
18#include <EGL/egl.h>
19#include <GLES2/gl2.h>
20
21#if defined(_WIN32)
22#include <Windows.h>
23#endif
24
25class SwiftShaderTest : public testing::Test
26{
27protected:
28	void SetUp() override
29	{
30		#if defined(_WIN32) && !defined(STANDALONE)
31			// The DLLs are delay loaded (see BUILD.gn), so we can load
32			// the correct ones from Chrome's swiftshader subdirectory.
33			HMODULE libEGL = LoadLibraryA("swiftshader\\libEGL.dll");
34			EXPECT_NE((HMODULE)NULL, libEGL);
35
36			HMODULE libGLESv2 = LoadLibraryA("swiftshader\\libGLESv2.dll");
37			EXPECT_NE((HMODULE)NULL, libGLESv2);
38		#endif
39	}
40};
41
42TEST_F(SwiftShaderTest, Initalization)
43{
44	EXPECT_EQ(EGL_SUCCESS, eglGetError());
45
46	EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
47	EXPECT_EQ(EGL_SUCCESS, eglGetError());
48	EXPECT_NE(EGL_NO_DISPLAY, display);
49
50	eglQueryString(display, EGL_VENDOR);
51	EXPECT_EQ(EGL_NOT_INITIALIZED, eglGetError());
52
53	EGLint major;
54	EGLint minor;
55	EGLBoolean initialized = eglInitialize(display, &major, &minor);
56	EXPECT_EQ(EGL_SUCCESS, eglGetError());
57	EXPECT_EQ((EGLBoolean)EGL_TRUE, initialized);
58	EXPECT_EQ(1, major);
59	EXPECT_EQ(4, minor);
60
61	const char *eglVendor = eglQueryString(display, EGL_VENDOR);
62	EXPECT_EQ(EGL_SUCCESS, eglGetError());
63	EXPECT_STREQ("Google Inc.", eglVendor);
64
65	const char *eglVersion = eglQueryString(display, EGL_VERSION);
66	EXPECT_EQ(EGL_SUCCESS, eglGetError());
67	EXPECT_THAT(eglVersion, testing::HasSubstr("1.4 SwiftShader "));
68
69	eglBindAPI(EGL_OPENGL_ES_API);
70	EXPECT_EQ(EGL_SUCCESS, eglGetError());
71
72	const EGLint configAttributes[] =
73	{
74		EGL_SURFACE_TYPE,		EGL_PBUFFER_BIT,
75		EGL_RENDERABLE_TYPE,	EGL_OPENGL_ES2_BIT,
76		EGL_NONE
77	};
78
79	EGLConfig config;
80	EGLint num_config = -1;
81	EGLBoolean success = eglChooseConfig(display, configAttributes, &config, 1, &num_config);
82	EXPECT_EQ(EGL_SUCCESS, eglGetError());
83	EXPECT_EQ(num_config, 1);
84	EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
85
86	EGLint conformant = 0;
87	eglGetConfigAttrib(display, config, EGL_CONFORMANT, &conformant);
88	EXPECT_EQ(EGL_SUCCESS, eglGetError());
89	EXPECT_TRUE(conformant & EGL_OPENGL_ES2_BIT);
90
91	EGLint renderableType = 0;
92	eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType);
93	EXPECT_EQ(EGL_SUCCESS, eglGetError());
94	EXPECT_TRUE(renderableType & EGL_OPENGL_ES2_BIT);
95
96	EGLint surfaceType = 0;
97	eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &surfaceType);
98	EXPECT_EQ(EGL_SUCCESS, eglGetError());
99	EXPECT_TRUE(surfaceType & EGL_WINDOW_BIT);
100
101	EGLint surfaceAttributes[] =
102	{
103		EGL_WIDTH, 1920,
104		EGL_HEIGHT, 1080,
105		EGL_NONE
106	};
107
108	EGLSurface surface = eglCreatePbufferSurface(display, config, surfaceAttributes);
109	EXPECT_EQ(EGL_SUCCESS, eglGetError());
110	EXPECT_NE(EGL_NO_SURFACE, surface);
111
112	EGLint contextAttributes[] =
113	{
114		EGL_CONTEXT_CLIENT_VERSION, 2,
115		EGL_NONE
116	};
117
118	EGLContext context = eglCreateContext(display, config, NULL, contextAttributes);
119	EXPECT_EQ(EGL_SUCCESS, eglGetError());
120	EXPECT_NE(EGL_NO_CONTEXT, context);
121
122	success = eglMakeCurrent(display, surface, surface, context);
123	EXPECT_EQ(EGL_SUCCESS, eglGetError());
124	EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
125
126	EGLDisplay currentDisplay = eglGetCurrentDisplay();
127	EXPECT_EQ(EGL_SUCCESS, eglGetError());
128	EXPECT_EQ(display, currentDisplay);
129
130	EGLSurface currentDrawSurface = eglGetCurrentSurface(EGL_DRAW);
131	EXPECT_EQ(EGL_SUCCESS, eglGetError());
132	EXPECT_EQ(surface, currentDrawSurface);
133
134	EGLSurface currentReadSurface = eglGetCurrentSurface(EGL_READ);
135	EXPECT_EQ(EGL_SUCCESS, eglGetError());
136	EXPECT_EQ(surface, currentReadSurface);
137
138	EGLContext currentContext = eglGetCurrentContext();
139	EXPECT_EQ(EGL_SUCCESS, eglGetError());
140	EXPECT_EQ(context, currentContext);
141
142	EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
143
144	const GLubyte *glVendor = glGetString(GL_VENDOR);
145	EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
146	EXPECT_STREQ("Google Inc.", (const char*)glVendor);
147
148	const GLubyte *glRenderer = glGetString(GL_RENDERER);
149	EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
150	EXPECT_STREQ("Google SwiftShader", (const char*)glRenderer);
151
152	const GLubyte *glVersion = glGetString(GL_VERSION);
153	EXPECT_EQ((GLenum)GL_NO_ERROR, glGetError());
154	EXPECT_THAT((const char*)glVersion, testing::HasSubstr("OpenGL ES 2.0 SwiftShader "));
155
156	success = eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
157	EXPECT_EQ(EGL_SUCCESS, eglGetError());
158	EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
159
160	currentDisplay = eglGetCurrentDisplay();
161	EXPECT_EQ(EGL_SUCCESS, eglGetError());
162	EXPECT_EQ(EGL_NO_DISPLAY, currentDisplay);
163
164	currentDrawSurface = eglGetCurrentSurface(EGL_DRAW);
165	EXPECT_EQ(EGL_SUCCESS, eglGetError());
166	EXPECT_EQ(EGL_NO_SURFACE, currentDrawSurface);
167
168	currentReadSurface = eglGetCurrentSurface(EGL_READ);
169	EXPECT_EQ(EGL_SUCCESS, eglGetError());
170	EXPECT_EQ(EGL_NO_SURFACE, currentReadSurface);
171
172	currentContext = eglGetCurrentContext();
173	EXPECT_EQ(EGL_SUCCESS, eglGetError());
174	EXPECT_EQ(EGL_NO_CONTEXT, currentContext);
175
176	success = eglDestroyContext(display, context);
177	EXPECT_EQ(EGL_SUCCESS, eglGetError());
178	EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
179
180	success = eglDestroySurface(display, surface);
181	EXPECT_EQ(EGL_SUCCESS, eglGetError());
182	EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
183
184	success = eglTerminate(display);
185	EXPECT_EQ(EGL_SUCCESS, eglGetError());
186	EXPECT_EQ((EGLBoolean)EGL_TRUE, success);
187}
188