blob: c50121ea7f80634db6a8672a917776b244996672 [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -04001//
2// Copyright 2015 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
Corentin Wallezd3970de2015-05-14 11:07:48 -04007#include "test_utils/ANGLETest.h"
Geoff Langd1913172013-10-18 16:15:10 -04008
Jamie Madillcfd6b2b2016-02-08 12:50:38 -05009#include "random_utils.h"
Jamie Madillcfd6b2b2016-02-08 12:50:38 -050010
Jamie Madillfa05f602015-05-07 13:47:11 -040011using namespace angle;
Jamie Madill94203b32014-10-02 10:44:16 -040012
Jamie Madillcfd6b2b2016-02-08 12:50:38 -050013namespace
14{
15
16Vector4 RandomVec4(int seed, float minValue, float maxValue)
17{
18 RNG rng(seed);
19 srand(seed);
20 return Vector4(
21 rng.randomFloatBetween(minValue, maxValue), rng.randomFloatBetween(minValue, maxValue),
22 rng.randomFloatBetween(minValue, maxValue), rng.randomFloatBetween(minValue, maxValue));
23}
24
25GLColor Vec4ToColor(const Vector4 &vec)
26{
27 GLColor color;
Corentin Wallez922cbfc2016-11-25 16:23:18 -050028 color.R = static_cast<uint8_t>(vec.x() * 255.0f);
29 color.G = static_cast<uint8_t>(vec.y() * 255.0f);
30 color.B = static_cast<uint8_t>(vec.z() * 255.0f);
31 color.A = static_cast<uint8_t>(vec.w() * 255.0f);
Jamie Madillcfd6b2b2016-02-08 12:50:38 -050032 return color;
33};
34
Jamie Madill94203b32014-10-02 10:44:16 -040035class ClearTestBase : public ANGLETest
Geoff Langd1913172013-10-18 16:15:10 -040036{
Jamie Madill94203b32014-10-02 10:44:16 -040037 protected:
Jamie Madillcfd6b2b2016-02-08 12:50:38 -050038 ClearTestBase() : mProgram(0)
Geoff Langd1913172013-10-18 16:15:10 -040039 {
40 setWindowWidth(128);
41 setWindowHeight(128);
Geoff Langefc551f2013-10-31 10:20:28 -040042 setConfigRedBits(8);
43 setConfigGreenBits(8);
44 setConfigBlueBits(8);
45 setConfigAlphaBits(8);
46 setConfigDepthBits(24);
Geoff Langd1913172013-10-18 16:15:10 -040047 }
48
Jamie Madillcfd6b2b2016-02-08 12:50:38 -050049 void SetUp() override
Geoff Langd1913172013-10-18 16:15:10 -040050 {
51 ANGLETest::SetUp();
52
Jamie Madillcfd6b2b2016-02-08 12:50:38 -050053 mFBOs.resize(2, 0);
54 glGenFramebuffers(2, mFBOs.data());
55
56 ASSERT_GL_NO_ERROR();
57 }
58
59 void TearDown() override
60 {
61 glDeleteProgram(mProgram);
62
63 if (!mFBOs.empty())
64 {
65 glDeleteFramebuffers(static_cast<GLsizei>(mFBOs.size()), mFBOs.data());
66 }
67
68 if (!mTextures.empty())
69 {
70 glDeleteTextures(static_cast<GLsizei>(mTextures.size()), mTextures.data());
71 }
72
73 ANGLETest::TearDown();
74 }
75
76 void setupDefaultProgram()
77 {
Olli Etuahoa20af6d2017-09-18 13:32:29 +030078 const std::string vertexShaderSource =
79 R"(precision highp float;
Geoff Langd1913172013-10-18 16:15:10 -040080 attribute vec4 position;
81
82 void main()
83 {
84 gl_Position = position;
Olli Etuahoa20af6d2017-09-18 13:32:29 +030085 })";
Geoff Langd1913172013-10-18 16:15:10 -040086
Olli Etuahoa20af6d2017-09-18 13:32:29 +030087 const std::string fragmentShaderSource =
88 R"(precision highp float;
Geoff Langd1913172013-10-18 16:15:10 -040089
90 void main()
91 {
92 gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +030093 })";
Geoff Langd1913172013-10-18 16:15:10 -040094
Jamie Madill5599c8f2014-08-26 13:16:39 -040095 mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madillcfd6b2b2016-02-08 12:50:38 -050096 ASSERT_NE(0u, mProgram);
Geoff Langd1913172013-10-18 16:15:10 -040097 }
98
99 GLuint mProgram;
Jamie Madillcfd6b2b2016-02-08 12:50:38 -0500100 std::vector<GLuint> mFBOs;
101 std::vector<GLuint> mTextures;
Geoff Langd1913172013-10-18 16:15:10 -0400102};
103
Jamie Madillfa05f602015-05-07 13:47:11 -0400104class ClearTest : public ClearTestBase {};
105class ClearTestES3 : public ClearTestBase {};
Jamie Madill94203b32014-10-02 10:44:16 -0400106
Geoff Langafd7f0a2015-09-09 15:33:31 -0400107// Test clearing the default framebuffer
108TEST_P(ClearTest, DefaultFramebuffer)
109{
110 glClearColor(0.25f, 0.5f, 0.5f, 0.5f);
111 glClear(GL_COLOR_BUFFER_BIT);
112 EXPECT_PIXEL_NEAR(0, 0, 64, 128, 128, 128, 1.0);
113}
114
115// Test clearing a RGBA8 Framebuffer
116TEST_P(ClearTest, RGBA8Framebuffer)
117{
Jamie Madillcfd6b2b2016-02-08 12:50:38 -0500118 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
Geoff Langafd7f0a2015-09-09 15:33:31 -0400119
120 GLuint texture;
121 glGenTextures(1, &texture);
122
123 glBindTexture(GL_TEXTURE_2D, texture);
124 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
125 GL_UNSIGNED_BYTE, nullptr);
126 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
127
128 glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
129 glClear(GL_COLOR_BUFFER_BIT);
130
131 EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0);
132}
133
Jamie Madillfa05f602015-05-07 13:47:11 -0400134TEST_P(ClearTest, ClearIssue)
Geoff Langd1913172013-10-18 16:15:10 -0400135{
Geoff Langd1913172013-10-18 16:15:10 -0400136 glEnable(GL_DEPTH_TEST);
137 glDepthFunc(GL_LEQUAL);
138
139 glClearColor(0.0, 1.0, 0.0, 1.0);
140 glClearDepthf(0.0);
141 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
142
143 EXPECT_GL_NO_ERROR();
144
Jamie Madillcfd6b2b2016-02-08 12:50:38 -0500145 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
Geoff Langd1913172013-10-18 16:15:10 -0400146
147 GLuint rbo;
148 glGenRenderbuffers(1, &rbo);
149 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
150 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, 16, 16);
151
152 EXPECT_GL_NO_ERROR();
153
154 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
155
156 EXPECT_GL_NO_ERROR();
157
158 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
159 glClearDepthf(1.0f);
160 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
161
162 EXPECT_GL_NO_ERROR();
163
164 glBindFramebuffer(GL_FRAMEBUFFER, 0);
165 glBindBuffer(GL_ARRAY_BUFFER, 0);
166
Jamie Madillcfd6b2b2016-02-08 12:50:38 -0500167 setupDefaultProgram();
Geoff Langd1913172013-10-18 16:15:10 -0400168 drawQuad(mProgram, "position", 0.5f);
169
170 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
171}
Jamie Madilla09403c2014-07-21 10:03:36 -0400172
173// Requires ES3
174// This tests a bug where in a masked clear when calling "ClearBuffer", we would
175// mistakenly clear every channel (including the masked-out ones)
Jamie Madillfa05f602015-05-07 13:47:11 -0400176TEST_P(ClearTestES3, MaskedClearBufferBug)
Jamie Madilla09403c2014-07-21 10:03:36 -0400177{
178 unsigned char pixelData[] = { 255, 255, 255, 255 };
179
Jamie Madillcfd6b2b2016-02-08 12:50:38 -0500180 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
Jamie Madilla09403c2014-07-21 10:03:36 -0400181
182 GLuint textures[2];
183 glGenTextures(2, &textures[0]);
184
185 glBindTexture(GL_TEXTURE_2D, textures[0]);
186 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
187 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
188
189 glBindTexture(GL_TEXTURE_2D, textures[1]);
190 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
191 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0);
192
193 ASSERT_GL_NO_ERROR();
194 EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
195
196 float clearValue[] = { 0, 0.5f, 0.5f, 1.0f };
197 GLenum drawBuffers[] = { GL_NONE, GL_COLOR_ATTACHMENT1 };
198 glDrawBuffers(2, drawBuffers);
199 glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
200 glClearBufferfv(GL_COLOR, 1, clearValue);
201
202 ASSERT_GL_NO_ERROR();
203 EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
204
Jamie Madillcb34ea52015-12-11 16:01:18 -0500205 glReadBuffer(GL_COLOR_ATTACHMENT1);
206 ASSERT_GL_NO_ERROR();
Jamie Madill9abdc2d2014-11-05 16:13:22 -0500207
Jamie Madill9abdc2d2014-11-05 16:13:22 -0500208 EXPECT_PIXEL_NEAR(0, 0, 0, 127, 255, 255, 1);
Jamie Madillc4833262014-09-18 16:18:26 -0400209
210 glDeleteTextures(2, textures);
211}
212
Jamie Madillfa05f602015-05-07 13:47:11 -0400213TEST_P(ClearTestES3, BadFBOSerialBug)
Jamie Madillc4833262014-09-18 16:18:26 -0400214{
215 // First make a simple framebuffer, and clear it to green
Jamie Madillcfd6b2b2016-02-08 12:50:38 -0500216 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
Jamie Madillc4833262014-09-18 16:18:26 -0400217
218 GLuint textures[2];
219 glGenTextures(2, &textures[0]);
220
221 glBindTexture(GL_TEXTURE_2D, textures[0]);
222 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
223 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
224
225 GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 };
226 glDrawBuffers(1, drawBuffers);
227
228 float clearValues1[] = { 0.0f, 1.0f, 0.0f, 1.0f };
229 glClearBufferfv(GL_COLOR, 0, clearValues1);
230
231 ASSERT_GL_NO_ERROR();
232 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
233
234 // Next make a second framebuffer, and draw it to red
235 // (Triggers bad applied render target serial)
236 GLuint fbo2;
237 glGenFramebuffers(1, &fbo2);
238 ASSERT_GL_NO_ERROR();
239
240 glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
241
242 glBindTexture(GL_TEXTURE_2D, textures[1]);
243 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
244 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
245
246 glDrawBuffers(1, drawBuffers);
247
Jamie Madillcfd6b2b2016-02-08 12:50:38 -0500248 setupDefaultProgram();
Jamie Madillc4833262014-09-18 16:18:26 -0400249 drawQuad(mProgram, "position", 0.5f);
250
251 ASSERT_GL_NO_ERROR();
252 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
253
254 // Check that the first framebuffer is still green.
Jamie Madillcfd6b2b2016-02-08 12:50:38 -0500255 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
Jamie Madillc4833262014-09-18 16:18:26 -0400256 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
257
258 glDeleteTextures(2, textures);
259 glDeleteFramebuffers(1, &fbo2);
Jamie Madilla09403c2014-07-21 10:03:36 -0400260}
Jamie Madillfa05f602015-05-07 13:47:11 -0400261
Geoff Langafd7f0a2015-09-09 15:33:31 -0400262// Test that SRGB framebuffers clear to the linearized clear color
263TEST_P(ClearTestES3, SRGBClear)
264{
265 // First make a simple framebuffer, and clear it
Jamie Madillcfd6b2b2016-02-08 12:50:38 -0500266 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
Geoff Langafd7f0a2015-09-09 15:33:31 -0400267
268 GLuint texture;
269 glGenTextures(1, &texture);
270
271 glBindTexture(GL_TEXTURE_2D, texture);
272 glTexStorage2D(GL_TEXTURE_2D, 1, GL_SRGB8_ALPHA8, getWindowWidth(), getWindowHeight());
273 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
274
275 glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
276 glClear(GL_COLOR_BUFFER_BIT);
277
278 EXPECT_PIXEL_NEAR(0, 0, 188, 188, 188, 128, 1.0);
279}
280
281// Test that framebuffers with mixed SRGB/Linear attachments clear to the correct color for each
282// attachment
283TEST_P(ClearTestES3, MixedSRGBClear)
284{
Jamie Madillcfd6b2b2016-02-08 12:50:38 -0500285 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
Geoff Langafd7f0a2015-09-09 15:33:31 -0400286
287 GLuint textures[2];
288 glGenTextures(2, &textures[0]);
289
290 glBindTexture(GL_TEXTURE_2D, textures[0]);
291 glTexStorage2D(GL_TEXTURE_2D, 1, GL_SRGB8_ALPHA8, getWindowWidth(), getWindowHeight());
292 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
293
294 glBindTexture(GL_TEXTURE_2D, textures[1]);
295 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
296 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0);
297
298 GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
299 glDrawBuffers(2, drawBuffers);
300
301 // Clear both textures
302 glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
303 glClear(GL_COLOR_BUFFER_BIT);
304
305 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
306 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0);
307
308 // Check value of texture0
309 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
310 EXPECT_PIXEL_NEAR(0, 0, 188, 188, 188, 128, 1.0);
311
312 // Check value of texture1
313 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
314 EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0);
315}
316
Jamie Madillcfd6b2b2016-02-08 12:50:38 -0500317// This test covers a D3D11 bug where calling ClearRenderTargetView sometimes wouldn't sync
318// before a draw call. The test draws small quads to a larger FBO (the default back buffer).
319// Before each blit to the back buffer it clears the quad to a certain color using
320// ClearBufferfv to give a solid color. The sync problem goes away if we insert a call to
321// flush or finish after ClearBufferfv or each draw.
322TEST_P(ClearTestES3, RepeatedClear)
323{
Jamie Madillcfd6b2b2016-02-08 12:50:38 -0500324 const std::string &vertexSource =
325 "#version 300 es\n"
326 "in highp vec2 position;\n"
327 "out highp vec2 v_coord;\n"
328 "void main(void)\n"
329 "{\n"
330 " gl_Position = vec4(position, 0, 1);\n"
331 " vec2 texCoord = (position * 0.5) + 0.5;\n"
332 " v_coord = texCoord;\n"
333 "}\n";
334
335 const std::string &fragmentSource =
336 "#version 300 es\n"
337 "in highp vec2 v_coord;\n"
338 "out highp vec4 color;\n"
339 "uniform sampler2D tex;\n"
340 "void main()\n"
341 "{\n"
342 " color = texture(tex, v_coord);\n"
343 "}\n";
344
345 mProgram = CompileProgram(vertexSource, fragmentSource);
346 ASSERT_NE(0u, mProgram);
347
348 mTextures.resize(1, 0);
349 glGenTextures(1, mTextures.data());
350
351 GLenum format = GL_RGBA8;
352 const int numRowsCols = 3;
353 const int cellSize = 32;
354 const int fboSize = cellSize;
355 const int backFBOSize = cellSize * numRowsCols;
356 const float fmtValueMin = 0.0f;
357 const float fmtValueMax = 1.0f;
358
359 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
360 glTexStorage2D(GL_TEXTURE_2D, 1, format, fboSize, fboSize);
361 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
362 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
363 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
364 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
365 ASSERT_GL_NO_ERROR();
366
367 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
368 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
369 ASSERT_GL_NO_ERROR();
370
371 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
372
373 // larger fbo bound -- clear to transparent black
374 glUseProgram(mProgram);
375 GLint uniLoc = glGetUniformLocation(mProgram, "tex");
376 ASSERT_NE(-1, uniLoc);
377 glUniform1i(uniLoc, 0);
378 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
379
380 GLint positionLocation = glGetAttribLocation(mProgram, "position");
381 ASSERT_NE(-1, positionLocation);
382
383 glUseProgram(mProgram);
384
385 for (int cellY = 0; cellY < numRowsCols; cellY++)
386 {
387 for (int cellX = 0; cellX < numRowsCols; cellX++)
388 {
389 int seed = cellX + cellY * numRowsCols;
390 const Vector4 color = RandomVec4(seed, fmtValueMin, fmtValueMax);
391
392 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
393 glClearBufferfv(GL_COLOR, 0, color.data());
394
395 glBindFramebuffer(GL_FRAMEBUFFER, 0);
396
397 // Method 1: Set viewport and draw full-viewport quad
398 glViewport(cellX * cellSize, cellY * cellSize, cellSize, cellSize);
399 drawQuad(mProgram, "position", 0.5f);
400
401 // Uncommenting the glFinish call seems to make the test pass.
402 // glFinish();
403 }
404 }
405
406 std::vector<GLColor> pixelData(backFBOSize * backFBOSize);
407 glReadPixels(0, 0, backFBOSize, backFBOSize, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
408
409 for (int cellY = 0; cellY < numRowsCols; cellY++)
410 {
411 for (int cellX = 0; cellX < numRowsCols; cellX++)
412 {
413 int seed = cellX + cellY * numRowsCols;
414 const Vector4 color = RandomVec4(seed, fmtValueMin, fmtValueMax);
415 GLColor expectedColor = Vec4ToColor(color);
416
417 int testN = cellX * cellSize + cellY * backFBOSize * cellSize + backFBOSize + 1;
418 GLColor actualColor = pixelData[testN];
419 EXPECT_NEAR(expectedColor.R, actualColor.R, 1);
420 EXPECT_NEAR(expectedColor.G, actualColor.G, 1);
421 EXPECT_NEAR(expectedColor.B, actualColor.B, 1);
422 EXPECT_NEAR(expectedColor.A, actualColor.A, 1);
423 }
424 }
425
426 ASSERT_GL_NO_ERROR();
427}
428
Jamie Madillfa05f602015-05-07 13:47:11 -0400429// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -0500430ANGLE_INSTANTIATE_TEST(ClearTest,
431 ES2_D3D9(),
432 ES2_D3D11(),
433 ES3_D3D11(),
434 ES2_OPENGL(),
435 ES3_OPENGL(),
436 ES2_OPENGLES(),
437 ES3_OPENGLES());
438ANGLE_INSTANTIATE_TEST(ClearTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Jamie Madillcfd6b2b2016-02-08 12:50:38 -0500439
440} // anonymous namespace