xref: /aosp_15_r20/external/angle/samples/multi_window/MultiWindow.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker #include "SampleApplication.h"
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include <algorithm>
10*8975f5c5SAndroid Build Coastguard Worker #include <cmath>
11*8975f5c5SAndroid Build Coastguard Worker #include <vector>
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker #include "util/Matrix.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "util/random_utils.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "util/shader_utils.h"
16*8975f5c5SAndroid Build Coastguard Worker 
17*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
18*8975f5c5SAndroid Build Coastguard Worker 
19*8975f5c5SAndroid Build Coastguard Worker class MultiWindowSample : public SampleApplication
20*8975f5c5SAndroid Build Coastguard Worker {
21*8975f5c5SAndroid Build Coastguard Worker   public:
MultiWindowSample(int argc,char ** argv)22*8975f5c5SAndroid Build Coastguard Worker     MultiWindowSample(int argc, char **argv)
23*8975f5c5SAndroid Build Coastguard Worker         : SampleApplication("MultiWindow", argc, argv, ClientType::ES2, 256, 256)
24*8975f5c5SAndroid Build Coastguard Worker     {}
25*8975f5c5SAndroid Build Coastguard Worker 
initialize()26*8975f5c5SAndroid Build Coastguard Worker     bool initialize() override
27*8975f5c5SAndroid Build Coastguard Worker     {
28*8975f5c5SAndroid Build Coastguard Worker         constexpr char kVS[] = R"(attribute vec4 vPosition;
29*8975f5c5SAndroid Build Coastguard Worker void main()
30*8975f5c5SAndroid Build Coastguard Worker {
31*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vPosition;
32*8975f5c5SAndroid Build Coastguard Worker })";
33*8975f5c5SAndroid Build Coastguard Worker 
34*8975f5c5SAndroid Build Coastguard Worker         constexpr char kFS[] = R"(precision mediump float;
35*8975f5c5SAndroid Build Coastguard Worker void main()
36*8975f5c5SAndroid Build Coastguard Worker {
37*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
38*8975f5c5SAndroid Build Coastguard Worker })";
39*8975f5c5SAndroid Build Coastguard Worker 
40*8975f5c5SAndroid Build Coastguard Worker         mProgram = CompileProgram(kVS, kFS);
41*8975f5c5SAndroid Build Coastguard Worker         if (!mProgram)
42*8975f5c5SAndroid Build Coastguard Worker         {
43*8975f5c5SAndroid Build Coastguard Worker             return false;
44*8975f5c5SAndroid Build Coastguard Worker         }
45*8975f5c5SAndroid Build Coastguard Worker 
46*8975f5c5SAndroid Build Coastguard Worker         // Set an initial rotation
47*8975f5c5SAndroid Build Coastguard Worker         mRotation = 45.0f;
48*8975f5c5SAndroid Build Coastguard Worker 
49*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
50*8975f5c5SAndroid Build Coastguard Worker 
51*8975f5c5SAndroid Build Coastguard Worker         window rootWindow;
52*8975f5c5SAndroid Build Coastguard Worker         rootWindow.osWindow = getWindow();
53*8975f5c5SAndroid Build Coastguard Worker         rootWindow.surface  = getSurface();
54*8975f5c5SAndroid Build Coastguard Worker         mWindows.push_back(rootWindow);
55*8975f5c5SAndroid Build Coastguard Worker 
56*8975f5c5SAndroid Build Coastguard Worker         const size_t numWindows = 5;
57*8975f5c5SAndroid Build Coastguard Worker         for (size_t i = 1; i < numWindows; i++)
58*8975f5c5SAndroid Build Coastguard Worker         {
59*8975f5c5SAndroid Build Coastguard Worker             window window;
60*8975f5c5SAndroid Build Coastguard Worker 
61*8975f5c5SAndroid Build Coastguard Worker             window.osWindow = OSWindow::New();
62*8975f5c5SAndroid Build Coastguard Worker             if (!window.osWindow->initialize("MultiWindow", 256, 256))
63*8975f5c5SAndroid Build Coastguard Worker             {
64*8975f5c5SAndroid Build Coastguard Worker                 return false;
65*8975f5c5SAndroid Build Coastguard Worker             }
66*8975f5c5SAndroid Build Coastguard Worker 
67*8975f5c5SAndroid Build Coastguard Worker             window.surface = eglCreateWindowSurface(getDisplay(), getConfig(),
68*8975f5c5SAndroid Build Coastguard Worker                                                     window.osWindow->getNativeWindow(), nullptr);
69*8975f5c5SAndroid Build Coastguard Worker             if (window.surface == EGL_NO_SURFACE)
70*8975f5c5SAndroid Build Coastguard Worker             {
71*8975f5c5SAndroid Build Coastguard Worker                 return false;
72*8975f5c5SAndroid Build Coastguard Worker             }
73*8975f5c5SAndroid Build Coastguard Worker 
74*8975f5c5SAndroid Build Coastguard Worker             window.osWindow->setVisible(true);
75*8975f5c5SAndroid Build Coastguard Worker 
76*8975f5c5SAndroid Build Coastguard Worker             mWindows.push_back(window);
77*8975f5c5SAndroid Build Coastguard Worker         }
78*8975f5c5SAndroid Build Coastguard Worker 
79*8975f5c5SAndroid Build Coastguard Worker         int baseX = rootWindow.osWindow->getX();
80*8975f5c5SAndroid Build Coastguard Worker         int baseY = rootWindow.osWindow->getY();
81*8975f5c5SAndroid Build Coastguard Worker         for (auto &window : mWindows)
82*8975f5c5SAndroid Build Coastguard Worker         {
83*8975f5c5SAndroid Build Coastguard Worker             int x      = baseX + mRNG.randomIntBetween(0, 512);
84*8975f5c5SAndroid Build Coastguard Worker             int y      = baseY + mRNG.randomIntBetween(0, 512);
85*8975f5c5SAndroid Build Coastguard Worker             int width  = mRNG.randomIntBetween(128, 512);
86*8975f5c5SAndroid Build Coastguard Worker             int height = mRNG.randomIntBetween(128, 512);
87*8975f5c5SAndroid Build Coastguard Worker             window.osWindow->setPosition(x, y);
88*8975f5c5SAndroid Build Coastguard Worker             window.osWindow->resize(width, height);
89*8975f5c5SAndroid Build Coastguard Worker         }
90*8975f5c5SAndroid Build Coastguard Worker 
91*8975f5c5SAndroid Build Coastguard Worker         return true;
92*8975f5c5SAndroid Build Coastguard Worker     }
93*8975f5c5SAndroid Build Coastguard Worker 
destroy()94*8975f5c5SAndroid Build Coastguard Worker     void destroy() override { glDeleteProgram(mProgram); }
95*8975f5c5SAndroid Build Coastguard Worker 
step(float dt,double totalTime)96*8975f5c5SAndroid Build Coastguard Worker     void step(float dt, double totalTime) override
97*8975f5c5SAndroid Build Coastguard Worker     {
98*8975f5c5SAndroid Build Coastguard Worker         mRotation = fmod(mRotation + (dt * 40.0f), 360.0f);
99*8975f5c5SAndroid Build Coastguard Worker 
100*8975f5c5SAndroid Build Coastguard Worker         for (auto &window : mWindows)
101*8975f5c5SAndroid Build Coastguard Worker         {
102*8975f5c5SAndroid Build Coastguard Worker             window.osWindow->messageLoop();
103*8975f5c5SAndroid Build Coastguard Worker         }
104*8975f5c5SAndroid Build Coastguard Worker     }
105*8975f5c5SAndroid Build Coastguard Worker 
draw()106*8975f5c5SAndroid Build Coastguard Worker     void draw() override
107*8975f5c5SAndroid Build Coastguard Worker     {
108*8975f5c5SAndroid Build Coastguard Worker         OSWindow *rootWindow = mWindows[0].osWindow;
109*8975f5c5SAndroid Build Coastguard Worker         int left             = rootWindow->getX();
110*8975f5c5SAndroid Build Coastguard Worker         int right            = rootWindow->getX() + rootWindow->getWidth();
111*8975f5c5SAndroid Build Coastguard Worker         int top              = rootWindow->getY();
112*8975f5c5SAndroid Build Coastguard Worker         int bottom           = rootWindow->getY() + rootWindow->getHeight();
113*8975f5c5SAndroid Build Coastguard Worker 
114*8975f5c5SAndroid Build Coastguard Worker         for (auto &windowRecord : mWindows)
115*8975f5c5SAndroid Build Coastguard Worker         {
116*8975f5c5SAndroid Build Coastguard Worker             OSWindow *window = windowRecord.osWindow;
117*8975f5c5SAndroid Build Coastguard Worker             left             = std::min(left, window->getX());
118*8975f5c5SAndroid Build Coastguard Worker             right            = std::max(right, window->getX() + window->getWidth());
119*8975f5c5SAndroid Build Coastguard Worker             top              = std::min(top, window->getY());
120*8975f5c5SAndroid Build Coastguard Worker             bottom           = std::max(bottom, window->getY() + window->getHeight());
121*8975f5c5SAndroid Build Coastguard Worker         }
122*8975f5c5SAndroid Build Coastguard Worker 
123*8975f5c5SAndroid Build Coastguard Worker         float midX = (left + right) * 0.5f;
124*8975f5c5SAndroid Build Coastguard Worker         float midY = (top + bottom) * 0.5f;
125*8975f5c5SAndroid Build Coastguard Worker 
126*8975f5c5SAndroid Build Coastguard Worker         Matrix4 modelMatrix = Matrix4::translate(Vector3(midX, midY, 0.0f)) *
127*8975f5c5SAndroid Build Coastguard Worker                               Matrix4::rotate(mRotation, Vector3(0.0f, 0.0f, 1.0f)) *
128*8975f5c5SAndroid Build Coastguard Worker                               Matrix4::translate(Vector3(-midX, -midY, 0.0f));
129*8975f5c5SAndroid Build Coastguard Worker         Matrix4 viewMatrix = Matrix4::identity();
130*8975f5c5SAndroid Build Coastguard Worker 
131*8975f5c5SAndroid Build Coastguard Worker         for (auto &windowRecord : mWindows)
132*8975f5c5SAndroid Build Coastguard Worker         {
133*8975f5c5SAndroid Build Coastguard Worker             OSWindow *window   = windowRecord.osWindow;
134*8975f5c5SAndroid Build Coastguard Worker             EGLSurface surface = windowRecord.surface;
135*8975f5c5SAndroid Build Coastguard Worker 
136*8975f5c5SAndroid Build Coastguard Worker             eglMakeCurrent(getDisplay(), surface, surface, getContext());
137*8975f5c5SAndroid Build Coastguard Worker 
138*8975f5c5SAndroid Build Coastguard Worker             Matrix4 orthoMatrix =
139*8975f5c5SAndroid Build Coastguard Worker                 Matrix4::ortho(static_cast<float>(window->getX()),
140*8975f5c5SAndroid Build Coastguard Worker                                static_cast<float>(window->getX() + window->getWidth()),
141*8975f5c5SAndroid Build Coastguard Worker                                static_cast<float>(window->getY() + window->getHeight()),
142*8975f5c5SAndroid Build Coastguard Worker                                static_cast<float>(window->getY()), 0.0f, 1.0f);
143*8975f5c5SAndroid Build Coastguard Worker             Matrix4 mvpMatrix = orthoMatrix * viewMatrix * modelMatrix;
144*8975f5c5SAndroid Build Coastguard Worker 
145*8975f5c5SAndroid Build Coastguard Worker             Vector3 vertices[] = {
146*8975f5c5SAndroid Build Coastguard Worker                 Matrix4::transform(mvpMatrix, Vector4(midX, static_cast<float>(top), 0.0f, 1.0f)),
147*8975f5c5SAndroid Build Coastguard Worker                 Matrix4::transform(mvpMatrix, Vector4(static_cast<float>(left),
148*8975f5c5SAndroid Build Coastguard Worker                                                       static_cast<float>(bottom), 0.0f, 1.0f)),
149*8975f5c5SAndroid Build Coastguard Worker                 Matrix4::transform(mvpMatrix, Vector4(static_cast<float>(right),
150*8975f5c5SAndroid Build Coastguard Worker                                                       static_cast<float>(bottom), 0.0f, 1.0f)),
151*8975f5c5SAndroid Build Coastguard Worker             };
152*8975f5c5SAndroid Build Coastguard Worker 
153*8975f5c5SAndroid Build Coastguard Worker             // Set the viewport
154*8975f5c5SAndroid Build Coastguard Worker             glViewport(0, 0, window->getWidth(), window->getHeight());
155*8975f5c5SAndroid Build Coastguard Worker 
156*8975f5c5SAndroid Build Coastguard Worker             // Clear the color buffer
157*8975f5c5SAndroid Build Coastguard Worker             glClear(GL_COLOR_BUFFER_BIT);
158*8975f5c5SAndroid Build Coastguard Worker 
159*8975f5c5SAndroid Build Coastguard Worker             // Use the program object
160*8975f5c5SAndroid Build Coastguard Worker             glUseProgram(mProgram);
161*8975f5c5SAndroid Build Coastguard Worker 
162*8975f5c5SAndroid Build Coastguard Worker             // Load the vertex data
163*8975f5c5SAndroid Build Coastguard Worker             glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices[0].data());
164*8975f5c5SAndroid Build Coastguard Worker             glEnableVertexAttribArray(0);
165*8975f5c5SAndroid Build Coastguard Worker 
166*8975f5c5SAndroid Build Coastguard Worker             glDrawArrays(GL_TRIANGLES, 0, 3);
167*8975f5c5SAndroid Build Coastguard Worker 
168*8975f5c5SAndroid Build Coastguard Worker             eglSwapBuffers(getDisplay(), surface);
169*8975f5c5SAndroid Build Coastguard Worker         }
170*8975f5c5SAndroid Build Coastguard Worker     }
171*8975f5c5SAndroid Build Coastguard Worker 
172*8975f5c5SAndroid Build Coastguard Worker     // Override swap to do nothing as we already swapped the root
173*8975f5c5SAndroid Build Coastguard Worker     // window in draw() and swapping another time would invalidate
174*8975f5c5SAndroid Build Coastguard Worker     // the content of the default framebuffer.
swap()175*8975f5c5SAndroid Build Coastguard Worker     void swap() override {}
176*8975f5c5SAndroid Build Coastguard Worker 
177*8975f5c5SAndroid Build Coastguard Worker   private:
178*8975f5c5SAndroid Build Coastguard Worker     // Handle to a program object
179*8975f5c5SAndroid Build Coastguard Worker     GLuint mProgram;
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker     // Current rotation
182*8975f5c5SAndroid Build Coastguard Worker     float mRotation;
183*8975f5c5SAndroid Build Coastguard Worker 
184*8975f5c5SAndroid Build Coastguard Worker     // Window and surface data
185*8975f5c5SAndroid Build Coastguard Worker     struct window
186*8975f5c5SAndroid Build Coastguard Worker     {
187*8975f5c5SAndroid Build Coastguard Worker         OSWindow *osWindow;
188*8975f5c5SAndroid Build Coastguard Worker         EGLSurface surface;
189*8975f5c5SAndroid Build Coastguard Worker     };
190*8975f5c5SAndroid Build Coastguard Worker     std::vector<window> mWindows;
191*8975f5c5SAndroid Build Coastguard Worker 
192*8975f5c5SAndroid Build Coastguard Worker     RNG mRNG;
193*8975f5c5SAndroid Build Coastguard Worker };
194*8975f5c5SAndroid Build Coastguard Worker 
main(int argc,char ** argv)195*8975f5c5SAndroid Build Coastguard Worker int main(int argc, char **argv)
196*8975f5c5SAndroid Build Coastguard Worker {
197*8975f5c5SAndroid Build Coastguard Worker     MultiWindowSample app(argc, argv);
198*8975f5c5SAndroid Build Coastguard Worker     return app.run();
199*8975f5c5SAndroid Build Coastguard Worker }
200