blob: 72379cdf2fa3d2be4e88eee9737832527f88c2c4 [file] [log] [blame]
Geoff Lang0ca42a52015-04-07 13:47:41 -04001#include "ANGLETest.h"
2
3// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
4ANGLE_TYPED_TEST_CASE(PbufferTest, ES2_D3D9, ES2_D3D11);
5
6template<typename T>
7class PbufferTest : public ANGLETest
8{
9 protected:
10 PbufferTest() : ANGLETest(T::GetGlesMajorVersion(), T::GetPlatform())
11 {
12 setWindowWidth(512);
13 setWindowHeight(512);
14 setConfigRedBits(8);
15 setConfigGreenBits(8);
16 setConfigBlueBits(8);
17 setConfigAlphaBits(8);
18 }
19
20 virtual void SetUp()
21 {
22 ANGLETest::SetUp();
23
24 const std::string vsSource = SHADER_SOURCE
25 (
26 precision highp float;
27 attribute vec4 position;
28 varying vec2 texcoord;
29
30 void main()
31 {
32 gl_Position = position;
33 texcoord = (position.xy * 0.5) + 0.5;
34 texcoord.y = 1.0 - texcoord.y;
35 }
36 );
37
38 const std::string textureFSSource = SHADER_SOURCE
39 (
40 precision highp float;
41 uniform sampler2D tex;
42 varying vec2 texcoord;
43
44 void main()
45 {
46 gl_FragColor = texture2D(tex, texcoord);
47 }
48 );
49
50 mTextureProgram = CompileProgram(vsSource, textureFSSource);
51 if (mTextureProgram == 0)
52 {
53 FAIL() << "shader compilation failed.";
54 }
55
56 mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
57
58 const EGLint pBufferAttributes[] =
59 {
60 EGL_WIDTH, mPbufferSize,
61 EGL_HEIGHT, mPbufferSize,
62 EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
63 EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
64 EGL_NONE, EGL_NONE,
65 };
66
67 EGLWindow *window = getEGLWindow();
68 mPbuffer = eglCreatePbufferSurface(window->getDisplay(), window->getConfig(), pBufferAttributes);
69 ASSERT_NE(mPbuffer, EGL_NO_SURFACE);
70
71 ASSERT_EGL_SUCCESS();
72 ASSERT_GL_NO_ERROR();
73 }
74
75 virtual void TearDown()
76 {
77 glDeleteProgram(mTextureProgram);
78
79 EGLWindow *window = getEGLWindow();
80 eglDestroySurface(window->getDisplay(), mPbuffer);
81
82 ANGLETest::TearDown();
83 }
84
85 GLuint mTextureProgram;
86 GLint mTextureUniformLocation;
87
88 const size_t mPbufferSize = 32;
89 EGLSurface mPbuffer;
90};
91
92// Test clearing a Pbuffer and checking the color is correct
93TYPED_TEST(PbufferTest, Clearing)
94{
95 EGLWindow *window = getEGLWindow();
96
97 // Clear the window surface to blue and verify
98 eglMakeCurrent(window->getDisplay(), window->getSurface(), window->getSurface(), window->getContext());
99 ASSERT_EGL_SUCCESS();
100
101 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
102 glClear(GL_COLOR_BUFFER_BIT);
103 ASSERT_GL_NO_ERROR();
104 EXPECT_PIXEL_EQ(window->getWidth() / 2, window->getHeight() / 2, 0, 0, 255, 255);
105
106 // Apply the Pbuffer and clear it to purple and verify
107 eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
108 ASSERT_EGL_SUCCESS();
109
110 glViewport(0, 0, mPbufferSize, mPbufferSize);
111 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
112 glClear(GL_COLOR_BUFFER_BIT);
113 ASSERT_GL_NO_ERROR();
114 EXPECT_PIXEL_EQ(mPbufferSize / 2, mPbufferSize / 2, 255, 0, 255, 255);
115
116 // Rebind the window serfance and verify that it is still blue
117 eglMakeCurrent(window->getDisplay(), window->getSurface(), window->getSurface(), window->getContext());
118 ASSERT_EGL_SUCCESS();
119 EXPECT_PIXEL_EQ(window->getWidth() / 2, window->getHeight() / 2, 0, 0, 255, 255);
120}
121
122// Bind the Pbuffer to a texture and verify it renders correctly
123TYPED_TEST(PbufferTest, BindTexImage)
124{
125 EGLWindow *window = getEGLWindow();
126
127 // Apply the Pbuffer and clear it to purple
128 eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
129 ASSERT_EGL_SUCCESS();
130
131 glViewport(0, 0, mPbufferSize, mPbufferSize);
132 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
133 glClear(GL_COLOR_BUFFER_BIT);
134 ASSERT_GL_NO_ERROR();
135
136 EXPECT_PIXEL_EQ(mPbufferSize / 2, mPbufferSize / 2, 255, 0, 255, 255);
137
138 // Apply the window surface
139 eglMakeCurrent(window->getDisplay(), window->getSurface(), window->getSurface(), window->getContext());
140
141 // Create a texture and bind the Pbuffer to it
142 GLuint texture = 0;
143 glGenTextures(1, &texture);
144 glBindTexture(GL_TEXTURE_2D, texture);
145 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
146 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
147 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
149 EXPECT_GL_NO_ERROR();
150
151 eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
152 glViewport(0, 0, window->getWidth(), window->getHeight());
153 ASSERT_EGL_SUCCESS();
154
155 // Draw a quad and verify that it is purple
156 glUseProgram(mTextureProgram);
157 glUniform1i(mTextureUniformLocation, 0);
158
159 drawQuad(mTextureProgram, "position", 0.5f);
160 EXPECT_GL_NO_ERROR();
161
162 // Unbind the texture
163 eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
164 ASSERT_EGL_SUCCESS();
165
166 // Verify that purple was drawn
167 EXPECT_PIXEL_EQ(window->getWidth() / 2, window->getHeight() / 2, 255, 0, 255, 255);
168
169 glDeleteTextures(1, &texture);
170}
171
172// Verify that when eglBind/ReleaseTexImage are called, the texture images are freed and their
173// size information is correctly updated.
174TYPED_TEST(PbufferTest, TextureSizeReset)
175{
176 GLuint texture = 0;
177 glGenTextures(1, &texture);
178 glBindTexture(GL_TEXTURE_2D, texture);
179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
180 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
181 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
182 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
183 EXPECT_GL_NO_ERROR();
184
185 glUseProgram(mTextureProgram);
186 glUniform1i(mTextureUniformLocation, 0);
187
188 // Fill the texture with white pixels
189 std::vector<GLubyte> whitePixels(mPbufferSize * mPbufferSize * 4, 255);
190 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mPbufferSize, mPbufferSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, &whitePixels[0]);
191 EXPECT_GL_NO_ERROR();
192
193 // Draw the white texture and verify that the pixels are correct
194 drawQuad(mTextureProgram, "position", 0.5f);
195 EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
196
197 // Bind the EGL surface and draw with it, results are undefined since nothing has
198 // been written to it
199 EGLWindow *window = getEGLWindow();
200 eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
201 drawQuad(mTextureProgram, "position", 0.5f);
202 EXPECT_GL_NO_ERROR();
203
204 // Clear the back buffer to a unique color (green)
205 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
206 glClear(GL_COLOR_BUFFER_BIT);
207 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
208
209 // Unbind the EGL surface and try to draw with the texture again, the texture's size should
210 // now be zero and incomplete so the back buffer should be black
211 eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
212 drawQuad(mTextureProgram, "position", 0.5f);
213 EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 255);
214}