xref: /aosp_15_r20/frameworks/native/libs/gui/tests/GLTest.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2013 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include "GLTest.h"
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <gui/Surface.h>
20*38e8c45fSAndroid Build Coastguard Worker 
21*38e8c45fSAndroid Build Coastguard Worker #include <GLES2/gl2.h>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker namespace android {
24*38e8c45fSAndroid Build Coastguard Worker 
25*38e8c45fSAndroid Build Coastguard Worker using Transaction = SurfaceComposerClient::Transaction;
26*38e8c45fSAndroid Build Coastguard Worker 
abs(int value)27*38e8c45fSAndroid Build Coastguard Worker static int abs(int value) {
28*38e8c45fSAndroid Build Coastguard Worker     return value > 0 ? value : -value;
29*38e8c45fSAndroid Build Coastguard Worker }
30*38e8c45fSAndroid Build Coastguard Worker 
SetUp()31*38e8c45fSAndroid Build Coastguard Worker void GLTest::SetUp() {
32*38e8c45fSAndroid Build Coastguard Worker     mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
33*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(EGL_SUCCESS, eglGetError());
34*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay);
35*38e8c45fSAndroid Build Coastguard Worker 
36*38e8c45fSAndroid Build Coastguard Worker     EGLint majorVersion;
37*38e8c45fSAndroid Build Coastguard Worker     EGLint minorVersion;
38*38e8c45fSAndroid Build Coastguard Worker     EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion));
39*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(EGL_SUCCESS, eglGetError());
40*38e8c45fSAndroid Build Coastguard Worker     RecordProperty("EglVersionMajor", majorVersion);
41*38e8c45fSAndroid Build Coastguard Worker     RecordProperty("EglVersionMinor", minorVersion);
42*38e8c45fSAndroid Build Coastguard Worker 
43*38e8c45fSAndroid Build Coastguard Worker     EGLint numConfigs = 0;
44*38e8c45fSAndroid Build Coastguard Worker     EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig, 1,
45*38e8c45fSAndroid Build Coastguard Worker             &numConfigs));
46*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(EGL_SUCCESS, eglGetError());
47*38e8c45fSAndroid Build Coastguard Worker 
48*38e8c45fSAndroid Build Coastguard Worker     char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS");
49*38e8c45fSAndroid Build Coastguard Worker     if (displaySecsEnv != nullptr) {
50*38e8c45fSAndroid Build Coastguard Worker         mDisplaySecs = atoi(displaySecsEnv);
51*38e8c45fSAndroid Build Coastguard Worker         if (mDisplaySecs < 0) {
52*38e8c45fSAndroid Build Coastguard Worker             mDisplaySecs = 0;
53*38e8c45fSAndroid Build Coastguard Worker         }
54*38e8c45fSAndroid Build Coastguard Worker     } else {
55*38e8c45fSAndroid Build Coastguard Worker         mDisplaySecs = 0;
56*38e8c45fSAndroid Build Coastguard Worker     }
57*38e8c45fSAndroid Build Coastguard Worker 
58*38e8c45fSAndroid Build Coastguard Worker     if (mDisplaySecs > 0) {
59*38e8c45fSAndroid Build Coastguard Worker         mComposerClient = new SurfaceComposerClient;
60*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
61*38e8c45fSAndroid Build Coastguard Worker 
62*38e8c45fSAndroid Build Coastguard Worker         mSurfaceControl = mComposerClient->createSurface(
63*38e8c45fSAndroid Build Coastguard Worker                 String8("Test Surface"), getSurfaceWidth(), getSurfaceHeight(),
64*38e8c45fSAndroid Build Coastguard Worker                 PIXEL_FORMAT_RGB_888, 0);
65*38e8c45fSAndroid Build Coastguard Worker 
66*38e8c45fSAndroid Build Coastguard Worker         ASSERT_TRUE(mSurfaceControl != nullptr);
67*38e8c45fSAndroid Build Coastguard Worker         ASSERT_TRUE(mSurfaceControl->isValid());
68*38e8c45fSAndroid Build Coastguard Worker 
69*38e8c45fSAndroid Build Coastguard Worker         Transaction t;
70*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(NO_ERROR, t.setLayer(mSurfaceControl, 0x7FFFFFFF)
71*38e8c45fSAndroid Build Coastguard Worker                 .show(mSurfaceControl)
72*38e8c45fSAndroid Build Coastguard Worker                 .apply());
73*38e8c45fSAndroid Build Coastguard Worker 
74*38e8c45fSAndroid Build Coastguard Worker         sp<ANativeWindow> window = mSurfaceControl->getSurface();
75*38e8c45fSAndroid Build Coastguard Worker         mEglSurface = createWindowSurface(mEglDisplay, mGlConfig, window);
76*38e8c45fSAndroid Build Coastguard Worker     } else {
77*38e8c45fSAndroid Build Coastguard Worker         EGLint pbufferAttribs[] = {
78*38e8c45fSAndroid Build Coastguard Worker             EGL_WIDTH, getSurfaceWidth(),
79*38e8c45fSAndroid Build Coastguard Worker             EGL_HEIGHT, getSurfaceHeight(),
80*38e8c45fSAndroid Build Coastguard Worker             EGL_NONE };
81*38e8c45fSAndroid Build Coastguard Worker 
82*38e8c45fSAndroid Build Coastguard Worker         mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig,
83*38e8c45fSAndroid Build Coastguard Worker                 pbufferAttribs);
84*38e8c45fSAndroid Build Coastguard Worker     }
85*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(EGL_SUCCESS, eglGetError());
86*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(EGL_NO_SURFACE, mEglSurface);
87*38e8c45fSAndroid Build Coastguard Worker 
88*38e8c45fSAndroid Build Coastguard Worker     mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT,
89*38e8c45fSAndroid Build Coastguard Worker             getContextAttribs());
90*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(EGL_SUCCESS, eglGetError());
91*38e8c45fSAndroid Build Coastguard Worker     ASSERT_NE(EGL_NO_CONTEXT, mEglContext);
92*38e8c45fSAndroid Build Coastguard Worker 
93*38e8c45fSAndroid Build Coastguard Worker     EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
94*38e8c45fSAndroid Build Coastguard Worker             mEglContext));
95*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(EGL_SUCCESS, eglGetError());
96*38e8c45fSAndroid Build Coastguard Worker 
97*38e8c45fSAndroid Build Coastguard Worker     EGLint w, h;
98*38e8c45fSAndroid Build Coastguard Worker     EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w));
99*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(EGL_SUCCESS, eglGetError());
100*38e8c45fSAndroid Build Coastguard Worker     EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h));
101*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(EGL_SUCCESS, eglGetError());
102*38e8c45fSAndroid Build Coastguard Worker     RecordProperty("EglSurfaceWidth", w);
103*38e8c45fSAndroid Build Coastguard Worker     RecordProperty("EglSurfaceHeight", h);
104*38e8c45fSAndroid Build Coastguard Worker 
105*38e8c45fSAndroid Build Coastguard Worker     glViewport(0, 0, w, h);
106*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
107*38e8c45fSAndroid Build Coastguard Worker }
108*38e8c45fSAndroid Build Coastguard Worker 
TearDown()109*38e8c45fSAndroid Build Coastguard Worker void GLTest::TearDown() {
110*38e8c45fSAndroid Build Coastguard Worker     // Display the result
111*38e8c45fSAndroid Build Coastguard Worker     if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) {
112*38e8c45fSAndroid Build Coastguard Worker         eglSwapBuffers(mEglDisplay, mEglSurface);
113*38e8c45fSAndroid Build Coastguard Worker         sleep(mDisplaySecs);
114*38e8c45fSAndroid Build Coastguard Worker     }
115*38e8c45fSAndroid Build Coastguard Worker 
116*38e8c45fSAndroid Build Coastguard Worker     if (mComposerClient != nullptr) {
117*38e8c45fSAndroid Build Coastguard Worker         mComposerClient->dispose();
118*38e8c45fSAndroid Build Coastguard Worker     }
119*38e8c45fSAndroid Build Coastguard Worker     if (mEglContext != EGL_NO_CONTEXT) {
120*38e8c45fSAndroid Build Coastguard Worker         eglDestroyContext(mEglDisplay, mEglContext);
121*38e8c45fSAndroid Build Coastguard Worker     }
122*38e8c45fSAndroid Build Coastguard Worker     if (mEglSurface != EGL_NO_SURFACE) {
123*38e8c45fSAndroid Build Coastguard Worker         eglDestroySurface(mEglDisplay, mEglSurface);
124*38e8c45fSAndroid Build Coastguard Worker     }
125*38e8c45fSAndroid Build Coastguard Worker     if (mEglDisplay != EGL_NO_DISPLAY) {
126*38e8c45fSAndroid Build Coastguard Worker         eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
127*38e8c45fSAndroid Build Coastguard Worker                 EGL_NO_CONTEXT);
128*38e8c45fSAndroid Build Coastguard Worker         eglTerminate(mEglDisplay);
129*38e8c45fSAndroid Build Coastguard Worker     }
130*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(EGL_SUCCESS, eglGetError());
131*38e8c45fSAndroid Build Coastguard Worker }
132*38e8c45fSAndroid Build Coastguard Worker 
getConfigAttribs()133*38e8c45fSAndroid Build Coastguard Worker EGLint const* GLTest::getConfigAttribs() {
134*38e8c45fSAndroid Build Coastguard Worker     static const EGLint sDefaultConfigAttribs[] = {
135*38e8c45fSAndroid Build Coastguard Worker         EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
136*38e8c45fSAndroid Build Coastguard Worker         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
137*38e8c45fSAndroid Build Coastguard Worker         EGL_RED_SIZE, 8,
138*38e8c45fSAndroid Build Coastguard Worker         EGL_GREEN_SIZE, 8,
139*38e8c45fSAndroid Build Coastguard Worker         EGL_BLUE_SIZE, 8,
140*38e8c45fSAndroid Build Coastguard Worker         EGL_ALPHA_SIZE, 8,
141*38e8c45fSAndroid Build Coastguard Worker         EGL_DEPTH_SIZE, 16,
142*38e8c45fSAndroid Build Coastguard Worker         EGL_STENCIL_SIZE, 8,
143*38e8c45fSAndroid Build Coastguard Worker         EGL_NONE };
144*38e8c45fSAndroid Build Coastguard Worker 
145*38e8c45fSAndroid Build Coastguard Worker     return sDefaultConfigAttribs;
146*38e8c45fSAndroid Build Coastguard Worker }
147*38e8c45fSAndroid Build Coastguard Worker 
getContextAttribs()148*38e8c45fSAndroid Build Coastguard Worker EGLint const* GLTest::getContextAttribs() {
149*38e8c45fSAndroid Build Coastguard Worker     static const EGLint sDefaultContextAttribs[] = {
150*38e8c45fSAndroid Build Coastguard Worker         EGL_CONTEXT_CLIENT_VERSION, 2,
151*38e8c45fSAndroid Build Coastguard Worker         EGL_NONE };
152*38e8c45fSAndroid Build Coastguard Worker 
153*38e8c45fSAndroid Build Coastguard Worker     return sDefaultContextAttribs;
154*38e8c45fSAndroid Build Coastguard Worker }
155*38e8c45fSAndroid Build Coastguard Worker 
getSurfaceWidth()156*38e8c45fSAndroid Build Coastguard Worker EGLint GLTest::getSurfaceWidth() {
157*38e8c45fSAndroid Build Coastguard Worker     return 512;
158*38e8c45fSAndroid Build Coastguard Worker }
159*38e8c45fSAndroid Build Coastguard Worker 
getSurfaceHeight()160*38e8c45fSAndroid Build Coastguard Worker EGLint GLTest::getSurfaceHeight() {
161*38e8c45fSAndroid Build Coastguard Worker     return 512;
162*38e8c45fSAndroid Build Coastguard Worker }
163*38e8c45fSAndroid Build Coastguard Worker 
createWindowSurface(EGLDisplay display,EGLConfig config,sp<ANativeWindow> & window) const164*38e8c45fSAndroid Build Coastguard Worker EGLSurface GLTest::createWindowSurface(EGLDisplay display, EGLConfig config,
165*38e8c45fSAndroid Build Coastguard Worker                                        sp<ANativeWindow>& window) const {
166*38e8c45fSAndroid Build Coastguard Worker     return eglCreateWindowSurface(display, config, window.get(), nullptr);
167*38e8c45fSAndroid Build Coastguard Worker }
168*38e8c45fSAndroid Build Coastguard Worker 
checkPixel(int x,int y,int r,int g,int b,int a,int tolerance)169*38e8c45fSAndroid Build Coastguard Worker ::testing::AssertionResult GLTest::checkPixel(int x, int y,
170*38e8c45fSAndroid Build Coastguard Worker         int r, int g, int b, int a, int tolerance) {
171*38e8c45fSAndroid Build Coastguard Worker     GLubyte pixel[4];
172*38e8c45fSAndroid Build Coastguard Worker     String8 msg;
173*38e8c45fSAndroid Build Coastguard Worker     glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
174*38e8c45fSAndroid Build Coastguard Worker     GLenum err = glGetError();
175*38e8c45fSAndroid Build Coastguard Worker     if (err != GL_NO_ERROR) {
176*38e8c45fSAndroid Build Coastguard Worker         msg += String8::format("error reading pixel: %#x", err);
177*38e8c45fSAndroid Build Coastguard Worker         while ((err = glGetError()) != GL_NO_ERROR) {
178*38e8c45fSAndroid Build Coastguard Worker             msg += String8::format(", %#x", err);
179*38e8c45fSAndroid Build Coastguard Worker         }
180*38e8c45fSAndroid Build Coastguard Worker         return ::testing::AssertionFailure(::testing::Message(msg.c_str()));
181*38e8c45fSAndroid Build Coastguard Worker     }
182*38e8c45fSAndroid Build Coastguard Worker     if (r >= 0 && abs(r - int(pixel[0])) > tolerance) {
183*38e8c45fSAndroid Build Coastguard Worker         msg += String8::format("r(%d isn't %d)", pixel[0], r);
184*38e8c45fSAndroid Build Coastguard Worker     }
185*38e8c45fSAndroid Build Coastguard Worker     if (g >= 0 && abs(g - int(pixel[1])) > tolerance) {
186*38e8c45fSAndroid Build Coastguard Worker         if (!msg.empty()) {
187*38e8c45fSAndroid Build Coastguard Worker             msg += " ";
188*38e8c45fSAndroid Build Coastguard Worker         }
189*38e8c45fSAndroid Build Coastguard Worker         msg += String8::format("g(%d isn't %d)", pixel[1], g);
190*38e8c45fSAndroid Build Coastguard Worker     }
191*38e8c45fSAndroid Build Coastguard Worker     if (b >= 0 && abs(b - int(pixel[2])) > tolerance) {
192*38e8c45fSAndroid Build Coastguard Worker         if (!msg.empty()) {
193*38e8c45fSAndroid Build Coastguard Worker             msg += " ";
194*38e8c45fSAndroid Build Coastguard Worker         }
195*38e8c45fSAndroid Build Coastguard Worker         msg += String8::format("b(%d isn't %d)", pixel[2], b);
196*38e8c45fSAndroid Build Coastguard Worker     }
197*38e8c45fSAndroid Build Coastguard Worker     if (a >= 0 && abs(a - int(pixel[3])) > tolerance) {
198*38e8c45fSAndroid Build Coastguard Worker         if (!msg.empty()) {
199*38e8c45fSAndroid Build Coastguard Worker             msg += " ";
200*38e8c45fSAndroid Build Coastguard Worker         }
201*38e8c45fSAndroid Build Coastguard Worker         msg += String8::format("a(%d isn't %d)", pixel[3], a);
202*38e8c45fSAndroid Build Coastguard Worker     }
203*38e8c45fSAndroid Build Coastguard Worker     if (!msg.empty()) {
204*38e8c45fSAndroid Build Coastguard Worker         return ::testing::AssertionFailure(::testing::Message(msg.c_str()));
205*38e8c45fSAndroid Build Coastguard Worker     } else {
206*38e8c45fSAndroid Build Coastguard Worker         return ::testing::AssertionSuccess();
207*38e8c45fSAndroid Build Coastguard Worker     }
208*38e8c45fSAndroid Build Coastguard Worker }
209*38e8c45fSAndroid Build Coastguard Worker 
assertRectEq(const Rect & r1,const Rect & r2,int tolerance)210*38e8c45fSAndroid Build Coastguard Worker ::testing::AssertionResult GLTest::assertRectEq(const Rect &r1, const Rect &r2,
211*38e8c45fSAndroid Build Coastguard Worker                                                 int tolerance) {
212*38e8c45fSAndroid Build Coastguard Worker     String8 msg;
213*38e8c45fSAndroid Build Coastguard Worker 
214*38e8c45fSAndroid Build Coastguard Worker     if (abs(r1.left - r2.left) > tolerance) {
215*38e8c45fSAndroid Build Coastguard Worker         msg += String8::format("left(%d isn't %d)", r1.left, r2.left);
216*38e8c45fSAndroid Build Coastguard Worker     }
217*38e8c45fSAndroid Build Coastguard Worker     if (abs(r1.top - r2.top) > tolerance) {
218*38e8c45fSAndroid Build Coastguard Worker         if (!msg.empty()) {
219*38e8c45fSAndroid Build Coastguard Worker             msg += " ";
220*38e8c45fSAndroid Build Coastguard Worker         }
221*38e8c45fSAndroid Build Coastguard Worker         msg += String8::format("top(%d isn't %d)", r1.top, r2.top);
222*38e8c45fSAndroid Build Coastguard Worker     }
223*38e8c45fSAndroid Build Coastguard Worker     if (abs(r1.right - r2.right) > tolerance) {
224*38e8c45fSAndroid Build Coastguard Worker         if (!msg.empty()) {
225*38e8c45fSAndroid Build Coastguard Worker             msg += " ";
226*38e8c45fSAndroid Build Coastguard Worker         }
227*38e8c45fSAndroid Build Coastguard Worker         msg += String8::format("right(%d isn't %d)", r1.right, r2.right);
228*38e8c45fSAndroid Build Coastguard Worker     }
229*38e8c45fSAndroid Build Coastguard Worker     if (abs(r1.bottom - r2.bottom) > tolerance) {
230*38e8c45fSAndroid Build Coastguard Worker         if (!msg.empty()) {
231*38e8c45fSAndroid Build Coastguard Worker             msg += " ";
232*38e8c45fSAndroid Build Coastguard Worker         }
233*38e8c45fSAndroid Build Coastguard Worker         msg += String8::format("bottom(%d isn't %d)", r1.bottom, r2.bottom);
234*38e8c45fSAndroid Build Coastguard Worker     }
235*38e8c45fSAndroid Build Coastguard Worker     if (!msg.empty()) {
236*38e8c45fSAndroid Build Coastguard Worker         msg += String8::format(" R1: [%d %d %d %d] R2: [%d %d %d %d]",
237*38e8c45fSAndroid Build Coastguard Worker                                r1.left, r1.top, r1.right, r1.bottom,
238*38e8c45fSAndroid Build Coastguard Worker                                r2.left, r2.top, r2.right, r2.bottom);
239*38e8c45fSAndroid Build Coastguard Worker         fprintf(stderr, "assertRectEq: %s\n", msg.c_str());
240*38e8c45fSAndroid Build Coastguard Worker         return ::testing::AssertionFailure(::testing::Message(msg.c_str()));
241*38e8c45fSAndroid Build Coastguard Worker     } else {
242*38e8c45fSAndroid Build Coastguard Worker         return ::testing::AssertionSuccess();
243*38e8c45fSAndroid Build Coastguard Worker     }
244*38e8c45fSAndroid Build Coastguard Worker }
245*38e8c45fSAndroid Build Coastguard Worker 
loadShader(GLenum shaderType,const char * pSource,GLuint * outShader)246*38e8c45fSAndroid Build Coastguard Worker void GLTest::loadShader(GLenum shaderType, const char* pSource,
247*38e8c45fSAndroid Build Coastguard Worker         GLuint* outShader) {
248*38e8c45fSAndroid Build Coastguard Worker     GLuint shader = glCreateShader(shaderType);
249*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
250*38e8c45fSAndroid Build Coastguard Worker     if (shader) {
251*38e8c45fSAndroid Build Coastguard Worker         glShaderSource(shader, 1, &pSource, nullptr);
252*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
253*38e8c45fSAndroid Build Coastguard Worker         glCompileShader(shader);
254*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
255*38e8c45fSAndroid Build Coastguard Worker         GLint compiled = 0;
256*38e8c45fSAndroid Build Coastguard Worker         glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
257*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
258*38e8c45fSAndroid Build Coastguard Worker         if (!compiled) {
259*38e8c45fSAndroid Build Coastguard Worker             GLint infoLen = 0;
260*38e8c45fSAndroid Build Coastguard Worker             glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
261*38e8c45fSAndroid Build Coastguard Worker             ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
262*38e8c45fSAndroid Build Coastguard Worker             if (infoLen) {
263*38e8c45fSAndroid Build Coastguard Worker                 char* buf = (char*) malloc(infoLen);
264*38e8c45fSAndroid Build Coastguard Worker                 if (buf) {
265*38e8c45fSAndroid Build Coastguard Worker                     glGetShaderInfoLog(shader, infoLen, nullptr, buf);
266*38e8c45fSAndroid Build Coastguard Worker                     printf("Shader compile log:\n%s\n", buf);
267*38e8c45fSAndroid Build Coastguard Worker                     free(buf);
268*38e8c45fSAndroid Build Coastguard Worker                     FAIL();
269*38e8c45fSAndroid Build Coastguard Worker                 }
270*38e8c45fSAndroid Build Coastguard Worker             } else {
271*38e8c45fSAndroid Build Coastguard Worker                 char* buf = (char*) malloc(0x1000);
272*38e8c45fSAndroid Build Coastguard Worker                 if (buf) {
273*38e8c45fSAndroid Build Coastguard Worker                     glGetShaderInfoLog(shader, 0x1000, nullptr, buf);
274*38e8c45fSAndroid Build Coastguard Worker                     printf("Shader compile log:\n%s\n", buf);
275*38e8c45fSAndroid Build Coastguard Worker                     free(buf);
276*38e8c45fSAndroid Build Coastguard Worker                     FAIL();
277*38e8c45fSAndroid Build Coastguard Worker                 }
278*38e8c45fSAndroid Build Coastguard Worker             }
279*38e8c45fSAndroid Build Coastguard Worker             glDeleteShader(shader);
280*38e8c45fSAndroid Build Coastguard Worker             shader = 0;
281*38e8c45fSAndroid Build Coastguard Worker         }
282*38e8c45fSAndroid Build Coastguard Worker     }
283*38e8c45fSAndroid Build Coastguard Worker     ASSERT_TRUE(shader != 0);
284*38e8c45fSAndroid Build Coastguard Worker     *outShader = shader;
285*38e8c45fSAndroid Build Coastguard Worker }
286*38e8c45fSAndroid Build Coastguard Worker 
createProgram(const char * pVertexSource,const char * pFragmentSource,GLuint * outPgm)287*38e8c45fSAndroid Build Coastguard Worker void GLTest::createProgram(const char* pVertexSource,
288*38e8c45fSAndroid Build Coastguard Worker         const char* pFragmentSource, GLuint* outPgm) {
289*38e8c45fSAndroid Build Coastguard Worker     GLuint vertexShader, fragmentShader;
290*38e8c45fSAndroid Build Coastguard Worker     {
291*38e8c45fSAndroid Build Coastguard Worker         SCOPED_TRACE("compiling vertex shader");
292*38e8c45fSAndroid Build Coastguard Worker         ASSERT_NO_FATAL_FAILURE(loadShader(GL_VERTEX_SHADER, pVertexSource,
293*38e8c45fSAndroid Build Coastguard Worker                 &vertexShader));
294*38e8c45fSAndroid Build Coastguard Worker     }
295*38e8c45fSAndroid Build Coastguard Worker     {
296*38e8c45fSAndroid Build Coastguard Worker         SCOPED_TRACE("compiling fragment shader");
297*38e8c45fSAndroid Build Coastguard Worker         ASSERT_NO_FATAL_FAILURE(loadShader(GL_FRAGMENT_SHADER, pFragmentSource,
298*38e8c45fSAndroid Build Coastguard Worker                 &fragmentShader));
299*38e8c45fSAndroid Build Coastguard Worker     }
300*38e8c45fSAndroid Build Coastguard Worker 
301*38e8c45fSAndroid Build Coastguard Worker     GLuint program = glCreateProgram();
302*38e8c45fSAndroid Build Coastguard Worker     ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
303*38e8c45fSAndroid Build Coastguard Worker     if (program) {
304*38e8c45fSAndroid Build Coastguard Worker         glAttachShader(program, vertexShader);
305*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
306*38e8c45fSAndroid Build Coastguard Worker         glAttachShader(program, fragmentShader);
307*38e8c45fSAndroid Build Coastguard Worker         ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError());
308*38e8c45fSAndroid Build Coastguard Worker         glLinkProgram(program);
309*38e8c45fSAndroid Build Coastguard Worker         GLint linkStatus = GL_FALSE;
310*38e8c45fSAndroid Build Coastguard Worker         glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
311*38e8c45fSAndroid Build Coastguard Worker         if (linkStatus != GL_TRUE) {
312*38e8c45fSAndroid Build Coastguard Worker             GLint bufLength = 0;
313*38e8c45fSAndroid Build Coastguard Worker             glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
314*38e8c45fSAndroid Build Coastguard Worker             if (bufLength) {
315*38e8c45fSAndroid Build Coastguard Worker                 char* buf = (char*) malloc(bufLength);
316*38e8c45fSAndroid Build Coastguard Worker                 if (buf) {
317*38e8c45fSAndroid Build Coastguard Worker                     glGetProgramInfoLog(program, bufLength, nullptr, buf);
318*38e8c45fSAndroid Build Coastguard Worker                     printf("Program link log:\n%s\n", buf);
319*38e8c45fSAndroid Build Coastguard Worker                     free(buf);
320*38e8c45fSAndroid Build Coastguard Worker                     FAIL();
321*38e8c45fSAndroid Build Coastguard Worker                 }
322*38e8c45fSAndroid Build Coastguard Worker             }
323*38e8c45fSAndroid Build Coastguard Worker             glDeleteProgram(program);
324*38e8c45fSAndroid Build Coastguard Worker             program = 0;
325*38e8c45fSAndroid Build Coastguard Worker         }
326*38e8c45fSAndroid Build Coastguard Worker     }
327*38e8c45fSAndroid Build Coastguard Worker     glDeleteShader(vertexShader);
328*38e8c45fSAndroid Build Coastguard Worker     glDeleteShader(fragmentShader);
329*38e8c45fSAndroid Build Coastguard Worker     ASSERT_TRUE(program != 0);
330*38e8c45fSAndroid Build Coastguard Worker     *outPgm = program;
331*38e8c45fSAndroid Build Coastguard Worker }
332*38e8c45fSAndroid Build Coastguard Worker 
333*38e8c45fSAndroid Build Coastguard Worker } // namespace android
334