xref: /aosp_15_r20/external/angle/samples/sample_util/SampleApplication.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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     EGLint glMajorVersion = 2;
74     EGLint glMinorVersion = 0;
75 
76     switch (clientType)
77     {
78         case ClientType::ES1:
79             glMajorVersion = 1;
80             break;
81         case ClientType::ES2:
82             break;
83         case ClientType::ES3_0:
84             glMajorVersion = 3;
85             break;
86         case ClientType::ES3_1:
87             glMajorVersion = 3;
88             glMinorVersion = 1;
89             break;
90         default:
91             UNREACHABLE();
92     }
93 
94     mOSWindow = OSWindow::New();
95 
96     // Load EGL library so we can initialize the display.
97     if (useNativeGL)
98     {
99 #if defined(ANGLE_PLATFORM_WINDOWS)
100         mGLWindow = WGLWindow::New(glMajorVersion, glMinorVersion);
101         mEntryPointsLib.reset(angle::OpenSharedLibrary("opengl32", angle::SearchType::SystemDir));
102         mDriverType = angle::GLESDriverType::SystemWGL;
103 #else
104         mGLWindow = EGLWindow::New(glMajorVersion, glMinorVersion);
105         mEntryPointsLib.reset(angle::OpenSharedLibraryWithExtension(
106             angle::GetNativeEGLLibraryNameWithExtension(), angle::SearchType::SystemDir));
107         mDriverType = angle::GLESDriverType::SystemEGL;
108 #endif  // defined(ANGLE_PLATFORM_WINDOWS)
109     }
110     else
111     {
112         mGLWindow = mEGLWindow = EGLWindow::New(glMajorVersion, glMinorVersion);
113         mEntryPointsLib.reset(
114             angle::OpenSharedLibrary(ANGLE_EGL_LIBRARY_NAME, angle::SearchType::ModuleDir));
115     }
116 }
117 
~SampleApplication()118 SampleApplication::~SampleApplication()
119 {
120     GLWindowBase::Delete(&mGLWindow);
121     OSWindow::Delete(&mOSWindow);
122 }
123 
initialize()124 bool SampleApplication::initialize()
125 {
126     return true;
127 }
128 
destroy()129 void SampleApplication::destroy() {}
130 
step(float dt,double totalTime)131 void SampleApplication::step(float dt, double totalTime) {}
132 
draw()133 void SampleApplication::draw() {}
134 
swap()135 void SampleApplication::swap()
136 {
137     mGLWindow->swap();
138 }
139 
getWindow() const140 OSWindow *SampleApplication::getWindow() const
141 {
142     return mOSWindow;
143 }
144 
getConfig() const145 EGLConfig SampleApplication::getConfig() const
146 {
147     ASSERT(mEGLWindow);
148     return mEGLWindow->getConfig();
149 }
150 
getDisplay() const151 EGLDisplay SampleApplication::getDisplay() const
152 {
153     ASSERT(mEGLWindow);
154     return mEGLWindow->getDisplay();
155 }
156 
getSurface() const157 EGLSurface SampleApplication::getSurface() const
158 {
159     ASSERT(mEGLWindow);
160     return mEGLWindow->getSurface();
161 }
162 
getContext() const163 EGLContext SampleApplication::getContext() const
164 {
165     ASSERT(mEGLWindow);
166     return mEGLWindow->getContext();
167 }
168 
run()169 int SampleApplication::run()
170 {
171     if (!mOSWindow->initialize(mName, mWidth, mHeight))
172     {
173         return -1;
174     }
175 
176     mOSWindow->setVisible(true);
177 
178     ConfigParameters configParams;
179     configParams.redBits     = 8;
180     configParams.greenBits   = 8;
181     configParams.blueBits    = 8;
182     configParams.alphaBits   = 8;
183     configParams.depthBits   = 24;
184     configParams.stencilBits = 8;
185 
186     if (!mGLWindow->initializeGL(mOSWindow, mEntryPointsLib.get(), mDriverType, mPlatformParams,
187                                  configParams))
188     {
189         return -1;
190     }
191 
192     // Disable vsync
193     if (!mGLWindow->setSwapInterval(0))
194     {
195         return -1;
196     }
197 
198     mRunning   = true;
199     int result = 0;
200 
201 #if defined(ANGLE_ENABLE_ASSERTS)
202     if (IsGLExtensionEnabled("GL_KHR_debug"))
203     {
204         EnableDebugCallback(nullptr, nullptr);
205     }
206 #endif
207 
208     if (!initialize())
209     {
210         mRunning = false;
211         result   = -1;
212     }
213 
214     mTimer.start();
215     double prevTime = 0.0;
216 
217     while (mRunning)
218     {
219         double elapsedTime = mTimer.getElapsedWallClockTime();
220         double deltaTime   = elapsedTime - prevTime;
221 
222         step(static_cast<float>(deltaTime), elapsedTime);
223 
224         // Clear events that the application did not process from this frame
225         Event event;
226         while (popEvent(&event))
227         {
228             // If the application did not catch a close event, close now
229             switch (event.Type)
230             {
231                 case Event::EVENT_CLOSED:
232                     exit();
233                     break;
234                 case Event::EVENT_KEY_RELEASED:
235                     onKeyUp(event.Key);
236                     break;
237                 case Event::EVENT_KEY_PRESSED:
238                     onKeyDown(event.Key);
239                     break;
240                 default:
241                     break;
242             }
243         }
244 
245         if (!mRunning)
246         {
247             break;
248         }
249 
250         draw();
251         swap();
252 
253         mOSWindow->messageLoop();
254 
255         prevTime = elapsedTime;
256 
257         mFrameCount++;
258 
259         if (mFrameCount % 100 == 0)
260         {
261             printf("Rate: %0.2lf frames / second\n",
262                    static_cast<double>(mFrameCount) / mTimer.getElapsedWallClockTime());
263         }
264     }
265 
266     destroy();
267     mGLWindow->destroyGL();
268     mOSWindow->destroy();
269 
270     return result;
271 }
272 
exit()273 void SampleApplication::exit()
274 {
275     mRunning = false;
276 }
277 
popEvent(Event * event)278 bool SampleApplication::popEvent(Event *event)
279 {
280     return mOSWindow->popEvent(event);
281 }
282 
onKeyUp(const Event::KeyEvent & keyEvent)283 void SampleApplication::onKeyUp(const Event::KeyEvent &keyEvent)
284 {
285     // Default no-op.
286 }
287 
onKeyDown(const Event::KeyEvent & keyEvent)288 void SampleApplication::onKeyDown(const Event::KeyEvent &keyEvent)
289 {
290     // Default no-op.
291 }
292