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