• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "common/debug.h"
10 #include "util/EGLWindow.h"
11 #include "util/gles_loader_autogen.h"
12 #include "util/random_utils.h"
13 #include "util/shader_utils.h"
14 #include "util/test_utils.h"
15 #include "util/util_gl.h"
16 
17 #include <string.h>
18 #include <iostream>
19 #include <utility>
20 
21 #if defined(ANGLE_PLATFORM_WINDOWS)
22 #    include "util/windows/WGLWindow.h"
23 #endif  // defined(ANGLE_PLATFORM_WINDOWS)
24 
25 namespace
26 {
27 const char *kUseAngleArg = "--use-angle=";
28 const char *kUseGlArg    = "--use-gl=native";
29 }  // anonymous namespace
30 
IsGLExtensionEnabled(const std::string & extName)31 bool IsGLExtensionEnabled(const std::string &extName)
32 {
33     return angle::CheckExtensionExists(reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)),
34                                        extName);
35 }
36 
SampleApplication(std::string name,int argc,char ** argv,ClientType clientType,uint32_t width,uint32_t height)37 SampleApplication::SampleApplication(std::string name,
38                                      int argc,
39                                      char **argv,
40                                      ClientType clientType,
41                                      uint32_t width,
42                                      uint32_t height)
43     : mName(std::move(name)),
44       mWidth(width),
45       mHeight(height),
46       mRunning(false),
47       mFrameCount(0),
48       mGLWindow(nullptr),
49       mEGLWindow(nullptr),
50       mOSWindow(nullptr),
51       mDriverType(angle::GLESDriverType::AngleEGL)
52 {
53     mPlatformParams.renderer = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
54     bool useNativeGL         = false;
55 
56     for (int argIndex = 1; argIndex < argc; argIndex++)
57     {
58         if (strncmp(argv[argIndex], kUseAngleArg, strlen(kUseAngleArg)) == 0)
59         {
60             const char *arg = argv[argIndex] + strlen(kUseAngleArg);
61             mPlatformParams.renderer =
62                 angle::GetPlatformANGLETypeFromArg(arg, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE);
63             mPlatformParams.deviceType = angle::GetANGLEDeviceTypeFromArg(
64                 arg, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE);
65         }
66 
67         if (strncmp(argv[argIndex], kUseGlArg, strlen(kUseGlArg)) == 0)
68         {
69             useNativeGL = true;
70         }
71     }
72 
73     EGLenum eglClientType = EGL_OPENGL_ES_API;
74     EGLint glMajorVersion = 2;
75     EGLint glMinorVersion = 0;
76     EGLint profileMask    = 0;
77 
78     switch (clientType)
79     {
80         case ClientType::ES1:
81             glMajorVersion = 1;
82             break;
83         case ClientType::ES2:
84             break;
85         case ClientType::ES3_0:
86             glMajorVersion = 3;
87             break;
88         case ClientType::ES3_1:
89             glMajorVersion = 3;
90             glMinorVersion = 1;
91             break;
92         case ClientType::GL3_3_CORE:
93             eglClientType  = EGL_OPENGL_API;
94             glMajorVersion = 3;
95             glMinorVersion = 3;
96             profileMask    = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT;
97             break;
98         case ClientType::GL3_3_COMPATIBILITY:
99             eglClientType  = EGL_OPENGL_API;
100             glMajorVersion = 3;
101             glMinorVersion = 3;
102             profileMask    = EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT;
103             break;
104         case ClientType::GL4_6_CORE:
105             eglClientType  = EGL_OPENGL_API;
106             glMajorVersion = 4;
107             glMinorVersion = 6;
108             profileMask    = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT;
109             break;
110         case ClientType::GL4_6_COMPATIBILITY:
111             eglClientType  = EGL_OPENGL_API;
112             glMajorVersion = 4;
113             glMinorVersion = 6;
114             profileMask    = EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT;
115             break;
116         default:
117             UNREACHABLE();
118     }
119 
120     mOSWindow = OSWindow::New();
121 
122     // Load EGL library so we can initialize the display.
123     if (useNativeGL)
124     {
125 #if defined(ANGLE_PLATFORM_WINDOWS)
126         mGLWindow = WGLWindow::New(eglClientType, glMajorVersion, glMinorVersion, profileMask);
127         mEntryPointsLib.reset(angle::OpenSharedLibrary("opengl32", angle::SearchType::SystemDir));
128         mDriverType = angle::GLESDriverType::SystemWGL;
129 #else
130         mGLWindow = EGLWindow::New(eglClientType, glMajorVersion, glMinorVersion, profileMask);
131         mEntryPointsLib.reset(angle::OpenSharedLibraryWithExtension(
132             angle::GetNativeEGLLibraryNameWithExtension(), angle::SearchType::SystemDir));
133         mDriverType = angle::GLESDriverType::SystemEGL;
134 #endif  // defined(ANGLE_PLATFORM_WINDOWS)
135     }
136     else
137     {
138 #if defined(ANGLE_EXPOSE_WGL_ENTRY_POINTS)
139         mGLWindow = WGLWindow::New(eglClientType, glMajorVersion, glMinorVersion, profileMask);
140         mEntryPointsLib.reset(angle::OpenSharedLibrary("opengl32", angle::SearchType::ModuleDir));
141         mDriverType = angle::GLESDriverType::SystemWGL;
142 #else
143         mGLWindow   = mEGLWindow =
144             EGLWindow::New(eglClientType, glMajorVersion, glMinorVersion, profileMask);
145         mEntryPointsLib.reset(
146             angle::OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, angle::SearchType::ModuleDir));
147 #endif  // defined(ANGLE_EXPOSE_WGL_ENTRY_POINTS)
148     }
149 }
150 
~SampleApplication()151 SampleApplication::~SampleApplication()
152 {
153     GLWindowBase::Delete(&mGLWindow);
154     OSWindow::Delete(&mOSWindow);
155 }
156 
initialize()157 bool SampleApplication::initialize()
158 {
159     return true;
160 }
161 
destroy()162 void SampleApplication::destroy() {}
163 
step(float dt,double totalTime)164 void SampleApplication::step(float dt, double totalTime) {}
165 
draw()166 void SampleApplication::draw() {}
167 
swap()168 void SampleApplication::swap()
169 {
170     mGLWindow->swap();
171 }
172 
getWindow() const173 OSWindow *SampleApplication::getWindow() const
174 {
175     return mOSWindow;
176 }
177 
getConfig() const178 EGLConfig SampleApplication::getConfig() const
179 {
180     ASSERT(mEGLWindow);
181     return mEGLWindow->getConfig();
182 }
183 
getDisplay() const184 EGLDisplay SampleApplication::getDisplay() const
185 {
186     ASSERT(mEGLWindow);
187     return mEGLWindow->getDisplay();
188 }
189 
getSurface() const190 EGLSurface SampleApplication::getSurface() const
191 {
192     ASSERT(mEGLWindow);
193     return mEGLWindow->getSurface();
194 }
195 
getContext() const196 EGLContext SampleApplication::getContext() const
197 {
198     ASSERT(mEGLWindow);
199     return mEGLWindow->getContext();
200 }
201 
run()202 int SampleApplication::run()
203 {
204     if (!mOSWindow->initialize(mName, mWidth, mHeight))
205     {
206         return -1;
207     }
208 
209     mOSWindow->setVisible(true);
210 
211     ConfigParameters configParams;
212     configParams.redBits     = 8;
213     configParams.greenBits   = 8;
214     configParams.blueBits    = 8;
215     configParams.alphaBits   = 8;
216     configParams.depthBits   = 24;
217     configParams.stencilBits = 8;
218 
219     if (!mGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), mDriverType, mPlatformParams,
220                                  configParams))
221     {
222         return -1;
223     }
224 
225     // Disable vsync
226     if (!mGLWindow->setSwapInterval(0))
227     {
228         return -1;
229     }
230 
231     mRunning   = true;
232     int result = 0;
233 
234 #if defined(ANGLE_ENABLE_ASSERTS)
235     if (IsGLExtensionEnabled("GL_KHR_debug"))
236     {
237         EnableDebugCallback(nullptr, nullptr);
238     }
239 #endif
240 
241     if (!initialize())
242     {
243         mRunning = false;
244         result   = -1;
245     }
246 
247     mTimer.start();
248     double prevTime = 0.0;
249 
250     while (mRunning)
251     {
252         double elapsedTime = mTimer.getElapsedWallClockTime();
253         double deltaTime   = elapsedTime - prevTime;
254 
255         step(static_cast<float>(deltaTime), elapsedTime);
256 
257         // Clear events that the application did not process from this frame
258         Event event;
259         while (popEvent(&event))
260         {
261             // If the application did not catch a close event, close now
262             switch (event.Type)
263             {
264                 case Event::EVENT_CLOSED:
265                     exit();
266                     break;
267                 case Event::EVENT_KEY_RELEASED:
268                     onKeyUp(event.Key);
269                     break;
270                 case Event::EVENT_KEY_PRESSED:
271                     onKeyDown(event.Key);
272                     break;
273                 default:
274                     break;
275             }
276         }
277 
278         if (!mRunning)
279         {
280             break;
281         }
282 
283         draw();
284         swap();
285 
286         mOSWindow->messageLoop();
287 
288         prevTime = elapsedTime;
289 
290         mFrameCount++;
291 
292         if (mFrameCount % 100 == 0)
293         {
294             printf("Rate: %0.2lf frames / second\n",
295                    static_cast<double>(mFrameCount) / mTimer.getElapsedWallClockTime());
296         }
297     }
298 
299     destroy();
300     mGLWindow->destroyGL();
301     mOSWindow->destroy();
302 
303     return result;
304 }
305 
exit()306 void SampleApplication::exit()
307 {
308     mRunning = false;
309 }
310 
popEvent(Event * event)311 bool SampleApplication::popEvent(Event *event)
312 {
313     return mOSWindow->popEvent(event);
314 }
315 
onKeyUp(const Event::KeyEvent & keyEvent)316 void SampleApplication::onKeyUp(const Event::KeyEvent &keyEvent)
317 {
318     // Default no-op.
319 }
320 
onKeyDown(const Event::KeyEvent & keyEvent)321 void SampleApplication::onKeyDown(const Event::KeyEvent &keyEvent)
322 {
323     // Default no-op.
324 }
325