1 //
2 // Copyright 2013 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
7 #include "SampleApplication.h"
8
9 #include "util/EGLWindow.h"
10 #include "util/gles_loader_autogen.h"
11 #include "util/random_utils.h"
12 #include "util/test_utils.h"
13
14 #include <string.h>
15 #include <iostream>
16 #include <utility>
17
18 namespace
19 {
20 const char *kUseAngleArg = "--use-angle=";
21
22 using DisplayTypeInfo = std::pair<const char *, EGLint>;
23
24 const DisplayTypeInfo kDisplayTypes[] = {
25 {"d3d9", EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE},
26 {"d3d11", EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE},
27 {"gl", EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE},
28 {"gles", EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE},
29 {"metal", EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE},
30 {"null", EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE},
31 {"swiftshader", EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE},
32 {"vulkan", EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE},
33 };
34
GetDisplayTypeFromArg(const char * displayTypeArg)35 EGLint GetDisplayTypeFromArg(const char *displayTypeArg)
36 {
37 for (const auto &displayTypeInfo : kDisplayTypes)
38 {
39 if (strcmp(displayTypeInfo.first, displayTypeArg) == 0)
40 {
41 std::cout << "Using ANGLE back-end API: " << displayTypeInfo.first << std::endl;
42 return displayTypeInfo.second;
43 }
44 }
45
46 std::cout << "Unknown ANGLE back-end API: " << displayTypeArg << std::endl;
47 return EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
48 }
49
GetDeviceTypeFromArg(const char * displayTypeArg)50 EGLint GetDeviceTypeFromArg(const char *displayTypeArg)
51 {
52 if (strcmp(displayTypeArg, "swiftshader") == 0)
53 {
54 return EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE;
55 }
56 else
57 {
58 return EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE;
59 }
60 }
61 } // anonymous namespace
62
SampleApplication(std::string name,int argc,char ** argv,EGLint glesMajorVersion,EGLint glesMinorVersion,uint32_t width,uint32_t height)63 SampleApplication::SampleApplication(std::string name,
64 int argc,
65 char **argv,
66 EGLint glesMajorVersion,
67 EGLint glesMinorVersion,
68 uint32_t width,
69 uint32_t height)
70 : mName(std::move(name)),
71 mWidth(width),
72 mHeight(height),
73 mRunning(false),
74 mEGLWindow(nullptr),
75 mOSWindow(nullptr)
76 {
77 mPlatformParams.renderer = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
78
79 if (argc > 1 && strncmp(argv[1], kUseAngleArg, strlen(kUseAngleArg)) == 0)
80 {
81 const char *arg = argv[1] + strlen(kUseAngleArg);
82 mPlatformParams.renderer = GetDisplayTypeFromArg(arg);
83 mPlatformParams.deviceType = GetDeviceTypeFromArg(arg);
84 }
85
86 // Load EGL library so we can initialize the display.
87 mEntryPointsLib.reset(
88 angle::OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, angle::SearchType::ApplicationDir));
89
90 mEGLWindow = EGLWindow::New(glesMajorVersion, glesMinorVersion);
91 mOSWindow = OSWindow::New();
92 }
93
~SampleApplication()94 SampleApplication::~SampleApplication()
95 {
96 EGLWindow::Delete(&mEGLWindow);
97 OSWindow::Delete(&mOSWindow);
98 }
99
initialize()100 bool SampleApplication::initialize()
101 {
102 return true;
103 }
104
destroy()105 void SampleApplication::destroy() {}
106
step(float dt,double totalTime)107 void SampleApplication::step(float dt, double totalTime) {}
108
draw()109 void SampleApplication::draw() {}
110
swap()111 void SampleApplication::swap()
112 {
113 mEGLWindow->swap();
114 }
115
getWindow() const116 OSWindow *SampleApplication::getWindow() const
117 {
118 return mOSWindow;
119 }
120
getConfig() const121 EGLConfig SampleApplication::getConfig() const
122 {
123 return mEGLWindow->getConfig();
124 }
125
getDisplay() const126 EGLDisplay SampleApplication::getDisplay() const
127 {
128 return mEGLWindow->getDisplay();
129 }
130
getSurface() const131 EGLSurface SampleApplication::getSurface() const
132 {
133 return mEGLWindow->getSurface();
134 }
135
getContext() const136 EGLContext SampleApplication::getContext() const
137 {
138 return mEGLWindow->getContext();
139 }
140
run()141 int SampleApplication::run()
142 {
143 if (!mOSWindow->initialize(mName, mWidth, mHeight))
144 {
145 return -1;
146 }
147
148 mOSWindow->setVisible(true);
149
150 ConfigParameters configParams;
151 configParams.redBits = 8;
152 configParams.greenBits = 8;
153 configParams.blueBits = 8;
154 configParams.alphaBits = 8;
155 configParams.depthBits = 24;
156 configParams.stencilBits = 8;
157
158 if (!mEGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), angle::GLESDriverType::AngleEGL,
159 mPlatformParams, configParams))
160 {
161 return -1;
162 }
163
164 // Disable vsync
165 if (!mEGLWindow->setSwapInterval(0))
166 {
167 return -1;
168 }
169
170 angle::LoadGLES(eglGetProcAddress);
171
172 mRunning = true;
173 int result = 0;
174
175 if (!initialize())
176 {
177 mRunning = false;
178 result = -1;
179 }
180
181 mTimer.start();
182 double prevTime = 0.0;
183
184 while (mRunning)
185 {
186 double elapsedTime = mTimer.getElapsedTime();
187 double deltaTime = elapsedTime - prevTime;
188
189 step(static_cast<float>(deltaTime), elapsedTime);
190
191 // Clear events that the application did not process from this frame
192 Event event;
193 while (popEvent(&event))
194 {
195 // If the application did not catch a close event, close now
196 switch (event.Type)
197 {
198 case Event::EVENT_CLOSED:
199 exit();
200 break;
201 case Event::EVENT_KEY_RELEASED:
202 onKeyUp(event.Key);
203 break;
204 case Event::EVENT_KEY_PRESSED:
205 onKeyDown(event.Key);
206 break;
207 default:
208 break;
209 }
210 }
211
212 if (!mRunning)
213 {
214 break;
215 }
216
217 draw();
218 swap();
219
220 mOSWindow->messageLoop();
221
222 prevTime = elapsedTime;
223 }
224
225 destroy();
226 mEGLWindow->destroyGL();
227 mOSWindow->destroy();
228
229 return result;
230 }
231
exit()232 void SampleApplication::exit()
233 {
234 mRunning = false;
235 }
236
popEvent(Event * event)237 bool SampleApplication::popEvent(Event *event)
238 {
239 return mOSWindow->popEvent(event);
240 }
241
onKeyUp(const Event::KeyEvent & keyEvent)242 void SampleApplication::onKeyUp(const Event::KeyEvent &keyEvent)
243 {
244 // Default no-op.
245 }
246
onKeyDown(const Event::KeyEvent & keyEvent)247 void SampleApplication::onKeyDown(const Event::KeyEvent &keyEvent)
248 {
249 // Default no-op.
250 }
251