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/system_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}, {"d3d11", EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE},
26 {"gl", EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE}, {"gles", EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE},
27 {"null", EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE}, {"vulkan", EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE}};
28
GetDisplayTypeFromArg(const char * displayTypeArg)29 EGLint GetDisplayTypeFromArg(const char *displayTypeArg)
30 {
31 for (const auto &displayTypeInfo : kDisplayTypes)
32 {
33 if (strcmp(displayTypeInfo.first, displayTypeArg) == 0)
34 {
35 std::cout << "Using ANGLE back-end API: " << displayTypeInfo.first << std::endl;
36 return displayTypeInfo.second;
37 }
38 }
39
40 std::cout << "Unknown ANGLE back-end API: " << displayTypeArg << std::endl;
41 return EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
42 }
43 } // anonymous namespace
44
SampleApplication(std::string name,int argc,char ** argv,EGLint glesMajorVersion,EGLint glesMinorVersion,uint32_t width,uint32_t height)45 SampleApplication::SampleApplication(std::string name,
46 int argc,
47 char **argv,
48 EGLint glesMajorVersion,
49 EGLint glesMinorVersion,
50 uint32_t width,
51 uint32_t height)
52 : mName(std::move(name)),
53 mWidth(width),
54 mHeight(height),
55 mRunning(false),
56 mEGLWindow(nullptr),
57 mOSWindow(nullptr)
58 {
59 mPlatformParams.renderer = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
60
61 if (argc > 1 && strncmp(argv[1], kUseAngleArg, strlen(kUseAngleArg)) == 0)
62 {
63 mPlatformParams.renderer = GetDisplayTypeFromArg(argv[1] + strlen(kUseAngleArg));
64 }
65
66 // Load EGL library so we can initialize the display.
67 mEntryPointsLib.reset(
68 angle::OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, angle::SearchType::ApplicationDir));
69
70 mEGLWindow = EGLWindow::New(glesMajorVersion, glesMinorVersion);
71 mTimer.reset(CreateTimer());
72 mOSWindow = OSWindow::New();
73 }
74
~SampleApplication()75 SampleApplication::~SampleApplication()
76 {
77 EGLWindow::Delete(&mEGLWindow);
78 OSWindow::Delete(&mOSWindow);
79 }
80
initialize()81 bool SampleApplication::initialize()
82 {
83 return true;
84 }
85
destroy()86 void SampleApplication::destroy() {}
87
step(float dt,double totalTime)88 void SampleApplication::step(float dt, double totalTime) {}
89
draw()90 void SampleApplication::draw() {}
91
swap()92 void SampleApplication::swap()
93 {
94 mEGLWindow->swap();
95 }
96
getWindow() const97 OSWindow *SampleApplication::getWindow() const
98 {
99 return mOSWindow;
100 }
101
getConfig() const102 EGLConfig SampleApplication::getConfig() const
103 {
104 return mEGLWindow->getConfig();
105 }
106
getDisplay() const107 EGLDisplay SampleApplication::getDisplay() const
108 {
109 return mEGLWindow->getDisplay();
110 }
111
getSurface() const112 EGLSurface SampleApplication::getSurface() const
113 {
114 return mEGLWindow->getSurface();
115 }
116
getContext() const117 EGLContext SampleApplication::getContext() const
118 {
119 return mEGLWindow->getContext();
120 }
121
run()122 int SampleApplication::run()
123 {
124 if (!mOSWindow->initialize(mName, mWidth, mHeight))
125 {
126 return -1;
127 }
128
129 mOSWindow->setVisible(true);
130
131 ConfigParameters configParams;
132 configParams.redBits = 8;
133 configParams.greenBits = 8;
134 configParams.blueBits = 8;
135 configParams.alphaBits = 8;
136 configParams.depthBits = 24;
137 configParams.stencilBits = 8;
138
139 if (!mEGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), mPlatformParams, configParams))
140 {
141 return -1;
142 }
143
144 // Disable vsync
145 if (!mEGLWindow->setSwapInterval(0))
146 {
147 return -1;
148 }
149
150 angle::LoadGLES(eglGetProcAddress);
151
152 mRunning = true;
153 int result = 0;
154
155 if (!initialize())
156 {
157 mRunning = false;
158 result = -1;
159 }
160
161 mTimer->start();
162 double prevTime = 0.0;
163
164 while (mRunning)
165 {
166 double elapsedTime = mTimer->getElapsedTime();
167 double deltaTime = elapsedTime - prevTime;
168
169 step(static_cast<float>(deltaTime), elapsedTime);
170
171 // Clear events that the application did not process from this frame
172 Event event;
173 while (popEvent(&event))
174 {
175 // If the application did not catch a close event, close now
176 if (event.Type == Event::EVENT_CLOSED)
177 {
178 exit();
179 }
180 }
181
182 if (!mRunning)
183 {
184 break;
185 }
186
187 draw();
188 swap();
189
190 mOSWindow->messageLoop();
191
192 prevTime = elapsedTime;
193 }
194
195 destroy();
196 mEGLWindow->destroyGL();
197 mOSWindow->destroy();
198
199 return result;
200 }
201
exit()202 void SampleApplication::exit()
203 {
204 mRunning = false;
205 }
206
popEvent(Event * event)207 bool SampleApplication::popEvent(Event *event)
208 {
209 return mOSWindow->popEvent(event);
210 }
211