1 //
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 
7 // WebGLCompatibilityTest.cpp : Tests of the GL_ANGLE_webgl_compatibility extension.
8 
9 #include "test_utils/ANGLETest.h"
10 
11 #include "test_utils/gl_raii.h"
12 
13 namespace angle
14 {
15 
16 class WebGLCompatibilityTest : public ANGLETest
17 {
18   protected:
WebGLCompatibilityTest()19     WebGLCompatibilityTest()
20     {
21         setWindowWidth(128);
22         setWindowHeight(128);
23         setConfigRedBits(8);
24         setConfigGreenBits(8);
25         setConfigBlueBits(8);
26         setConfigAlphaBits(8);
27         setWebGLCompatibilityEnabled(true);
28     }
29 
SetUp()30     void SetUp() override
31     {
32         ANGLETest::SetUp();
33         glEnableExtensionANGLE = reinterpret_cast<PFNGLENABLEEXTENSIONANGLEPROC>(
34             eglGetProcAddress("glEnableExtensionANGLE"));
35     }
36 
TearDown()37     void TearDown() override { ANGLETest::TearDown(); }
38 
39     PFNGLENABLEEXTENSIONANGLEPROC glEnableExtensionANGLE = nullptr;
40 };
41 
42 // Context creation would fail if EGL_ANGLE_create_context_webgl_compatibility was not available so
43 // the GL extension should always be present
TEST_P(WebGLCompatibilityTest,ExtensionStringExposed)44 TEST_P(WebGLCompatibilityTest, ExtensionStringExposed)
45 {
46     EXPECT_TRUE(extensionEnabled("GL_ANGLE_webgl_compatibility"));
47 }
48 
49 // Verify that all extension entry points are available
TEST_P(WebGLCompatibilityTest,EntryPoints)50 TEST_P(WebGLCompatibilityTest, EntryPoints)
51 {
52     if (extensionEnabled("GL_ANGLE_webgl_compatibility"))
53     {
54         EXPECT_NE(nullptr, eglGetProcAddress("glEnableExtensionANGLE"));
55     }
56 }
57 
58 // WebGL 1 allows GL_DEPTH_STENCIL_ATTACHMENT as a valid binding point.  Make sure it is usable,
59 // even in ES2 contexts.
TEST_P(WebGLCompatibilityTest,DepthStencilBindingPoint)60 TEST_P(WebGLCompatibilityTest, DepthStencilBindingPoint)
61 {
62     GLRenderbuffer renderbuffer;
63     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer.get());
64     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 32, 32);
65 
66     GLFramebuffer framebuffer;
67     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
68     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
69                               renderbuffer.get());
70 
71     EXPECT_GL_NO_ERROR();
72 }
73 
74 // Test that attempting to enable an extension that doesn't exist generates GL_INVALID_OPERATION
TEST_P(WebGLCompatibilityTest,EnableExtensionValidation)75 TEST_P(WebGLCompatibilityTest, EnableExtensionValidation)
76 {
77     EXPECT_EQ(GL_FALSE, glEnableExtensionANGLE("invalid_extension_string"));
78     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
79 }
80 
81 // Test enabling the GL_OES_element_index_uint extension
TEST_P(WebGLCompatibilityTest,EnableExtensionUintIndices)82 TEST_P(WebGLCompatibilityTest, EnableExtensionUintIndices)
83 {
84     if (getClientMajorVersion() != 2)
85     {
86         // This test only works on ES2 where uint indices are not available by default
87         return;
88     }
89 
90     EXPECT_FALSE(extensionEnabled("GL_OES_element_index_uint"));
91 
92     GLBuffer indexBuffer;
93     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer.get());
94 
95     GLuint data[] = {0, 1, 2, 1, 3, 2};
96     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
97 
98     ANGLE_GL_PROGRAM(program, "void main() { gl_Position = vec4(0, 0, 0, 1); }",
99                      "void main() { gl_FragColor = vec4(0, 1, 0, 1); }")
100     glUseProgram(program.get());
101 
102     glDrawElements(GL_TRIANGLES, 2, GL_UNSIGNED_INT, nullptr);
103     EXPECT_GL_ERROR(GL_INVALID_ENUM);
104 
105     if (glEnableExtensionANGLE("GL_OES_element_index_uint"))
106     {
107         EXPECT_GL_NO_ERROR();
108         EXPECT_TRUE(extensionEnabled("GL_OES_element_index_uint"));
109 
110         glDrawElements(GL_TRIANGLES, 2, GL_UNSIGNED_INT, nullptr);
111         EXPECT_GL_NO_ERROR();
112     }
113 }
114 
115 // Verify that shaders are of a compatible spec when the extension is enabled.
TEST_P(WebGLCompatibilityTest,ExtensionCompilerSpec)116 TEST_P(WebGLCompatibilityTest, ExtensionCompilerSpec)
117 {
118     EXPECT_TRUE(extensionEnabled("GL_ANGLE_webgl_compatibility"));
119 
120     // Use of reserved _webgl prefix should fail when the shader specification is for WebGL.
121     const std::string &vert =
122         "struct Foo {\n"
123         "    int _webgl_bar;\n"
124         "};\n"
125         "void main()\n"
126         "{\n"
127         "    Foo foo = Foo(1);\n"
128         "}";
129 
130     // Default fragement shader.
131     const std::string &frag =
132         "void main()\n"
133         "{\n"
134         "    gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n"
135         "}";
136 
137     GLuint program = CompileProgram(vert, frag);
138     EXPECT_EQ(0u, program);
139     glDeleteProgram(program);
140 }
141 
142 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
143 // tests should be run against.
144 ANGLE_INSTANTIATE_TEST(WebGLCompatibilityTest,
145                        ES2_D3D9(),
146                        ES2_D3D11(),
147                        ES3_D3D11(),
148                        ES2_D3D11_FL9_3(),
149                        ES2_OPENGL(),
150                        ES3_OPENGL(),
151                        ES2_OPENGLES(),
152                        ES3_OPENGLES());
153 
154 }  // namespace
155