blob: 7c277685bbf86a749158b58a7edcddf462202fe4 [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.
Geoff Lang03053202015-04-09 11:21:13 -04004ANGLE_TYPED_TEST_CASE(PbufferTest, ES2_D3D9, ES2_D3D11, ES2_OPENGL);
Geoff Lang0ca42a52015-04-07 13:47:41 -04005
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
Geoff Lang1c906c22015-04-10 11:26:17 -040058 EGLWindow *window = getEGLWindow();
59
60 EGLint surfaceType = 0;
61 eglGetConfigAttrib(window->getDisplay(), window->getConfig(), EGL_SURFACE_TYPE, &surfaceType);
62 mSupportsPbuffers = (surfaceType & EGL_PBUFFER_BIT) != 0;
63
64 EGLint bindToTextureRGBA = 0;
65 eglGetConfigAttrib(window->getDisplay(), window->getConfig(), EGL_BIND_TO_TEXTURE_RGBA, &bindToTextureRGBA);
66 mSupportsBindTexImage = (bindToTextureRGBA == EGL_TRUE);
67
Geoff Lang0ca42a52015-04-07 13:47:41 -040068 const EGLint pBufferAttributes[] =
69 {
70 EGL_WIDTH, mPbufferSize,
71 EGL_HEIGHT, mPbufferSize,
Geoff Lang1c906c22015-04-10 11:26:17 -040072 EGL_TEXTURE_FORMAT, mSupportsBindTexImage ? EGL_TEXTURE_RGBA : EGL_NO_TEXTURE,
73 EGL_TEXTURE_TARGET, mSupportsBindTexImage ? EGL_TEXTURE_2D : EGL_NO_TEXTURE,
Geoff Lang0ca42a52015-04-07 13:47:41 -040074 EGL_NONE, EGL_NONE,
75 };
76
Geoff Lang0ca42a52015-04-07 13:47:41 -040077 mPbuffer = eglCreatePbufferSurface(window->getDisplay(), window->getConfig(), pBufferAttributes);
Geoff Lang1c906c22015-04-10 11:26:17 -040078 if (mSupportsPbuffers)
79 {
80 ASSERT_NE(mPbuffer, EGL_NO_SURFACE);
81 ASSERT_EGL_SUCCESS();
82 }
83 else
84 {
85 ASSERT_EQ(mPbuffer, EGL_NO_SURFACE);
86 ASSERT_EGL_ERROR(EGL_BAD_MATCH);
87 }
Geoff Lang0ca42a52015-04-07 13:47:41 -040088
Geoff Lang0ca42a52015-04-07 13:47:41 -040089 ASSERT_GL_NO_ERROR();
90 }
91
92 virtual void TearDown()
93 {
94 glDeleteProgram(mTextureProgram);
95
96 EGLWindow *window = getEGLWindow();
97 eglDestroySurface(window->getDisplay(), mPbuffer);
98
99 ANGLETest::TearDown();
100 }
101
102 GLuint mTextureProgram;
103 GLint mTextureUniformLocation;
104
105 const size_t mPbufferSize = 32;
106 EGLSurface mPbuffer;
Geoff Lang1c906c22015-04-10 11:26:17 -0400107 bool mSupportsPbuffers;
108 bool mSupportsBindTexImage;
Geoff Lang0ca42a52015-04-07 13:47:41 -0400109};
110
111// Test clearing a Pbuffer and checking the color is correct
112TYPED_TEST(PbufferTest, Clearing)
113{
Geoff Lang1c906c22015-04-10 11:26:17 -0400114 if (!mSupportsPbuffers)
115 {
116 std::cout << "Test skipped because Pbuffers are not supported." << std::endl;
117 return;
118 }
119
Geoff Lang0ca42a52015-04-07 13:47:41 -0400120 EGLWindow *window = getEGLWindow();
121
122 // Clear the window surface to blue and verify
123 eglMakeCurrent(window->getDisplay(), window->getSurface(), window->getSurface(), window->getContext());
124 ASSERT_EGL_SUCCESS();
125
126 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
127 glClear(GL_COLOR_BUFFER_BIT);
128 ASSERT_GL_NO_ERROR();
129 EXPECT_PIXEL_EQ(window->getWidth() / 2, window->getHeight() / 2, 0, 0, 255, 255);
130
131 // Apply the Pbuffer and clear it to purple and verify
132 eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
133 ASSERT_EGL_SUCCESS();
134
135 glViewport(0, 0, mPbufferSize, mPbufferSize);
136 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
137 glClear(GL_COLOR_BUFFER_BIT);
138 ASSERT_GL_NO_ERROR();
139 EXPECT_PIXEL_EQ(mPbufferSize / 2, mPbufferSize / 2, 255, 0, 255, 255);
140
141 // Rebind the window serfance and verify that it is still blue
142 eglMakeCurrent(window->getDisplay(), window->getSurface(), window->getSurface(), window->getContext());
143 ASSERT_EGL_SUCCESS();
144 EXPECT_PIXEL_EQ(window->getWidth() / 2, window->getHeight() / 2, 0, 0, 255, 255);
145}
146
147// Bind the Pbuffer to a texture and verify it renders correctly
148TYPED_TEST(PbufferTest, BindTexImage)
149{
Geoff Lang1c906c22015-04-10 11:26:17 -0400150 if (!mSupportsPbuffers)
151 {
152 std::cout << "Test skipped because Pbuffers are not supported." << std::endl;
153 return;
154 }
155
156 if (!mSupportsBindTexImage)
157 {
158 std::cout << "Test skipped because Pbuffer does not support binding to RGBA textures." << std::endl;
159 return;
160 }
161
Geoff Lang0ca42a52015-04-07 13:47:41 -0400162 EGLWindow *window = getEGLWindow();
163
164 // Apply the Pbuffer and clear it to purple
165 eglMakeCurrent(window->getDisplay(), mPbuffer, mPbuffer, window->getContext());
166 ASSERT_EGL_SUCCESS();
167
168 glViewport(0, 0, mPbufferSize, mPbufferSize);
169 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
170 glClear(GL_COLOR_BUFFER_BIT);
171 ASSERT_GL_NO_ERROR();
172
173 EXPECT_PIXEL_EQ(mPbufferSize / 2, mPbufferSize / 2, 255, 0, 255, 255);
174
175 // Apply the window surface
176 eglMakeCurrent(window->getDisplay(), window->getSurface(), window->getSurface(), window->getContext());
177
178 // Create a texture and bind the Pbuffer to it
179 GLuint texture = 0;
180 glGenTextures(1, &texture);
181 glBindTexture(GL_TEXTURE_2D, texture);
182 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
183 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
184 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
186 EXPECT_GL_NO_ERROR();
187
188 eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
189 glViewport(0, 0, window->getWidth(), window->getHeight());
190 ASSERT_EGL_SUCCESS();
191
192 // Draw a quad and verify that it is purple
193 glUseProgram(mTextureProgram);
194 glUniform1i(mTextureUniformLocation, 0);
195
196 drawQuad(mTextureProgram, "position", 0.5f);
197 EXPECT_GL_NO_ERROR();
198
199 // Unbind the texture
200 eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
201 ASSERT_EGL_SUCCESS();
202
203 // Verify that purple was drawn
204 EXPECT_PIXEL_EQ(window->getWidth() / 2, window->getHeight() / 2, 255, 0, 255, 255);
205
206 glDeleteTextures(1, &texture);
207}
208
209// Verify that when eglBind/ReleaseTexImage are called, the texture images are freed and their
210// size information is correctly updated.
211TYPED_TEST(PbufferTest, TextureSizeReset)
212{
Geoff Lang1c906c22015-04-10 11:26:17 -0400213 if (!mSupportsPbuffers)
214 {
215 std::cout << "Test skipped because Pbuffers are not supported." << std::endl;
216 return;
217 }
218
219 if (!mSupportsBindTexImage)
220 {
221 std::cout << "Test skipped because Pbuffer does not support binding to RGBA textures." << std::endl;
222 return;
223 }
224
Geoff Lang0ca42a52015-04-07 13:47:41 -0400225 GLuint texture = 0;
226 glGenTextures(1, &texture);
227 glBindTexture(GL_TEXTURE_2D, texture);
228 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
229 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
230 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
231 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
232 EXPECT_GL_NO_ERROR();
233
234 glUseProgram(mTextureProgram);
235 glUniform1i(mTextureUniformLocation, 0);
236
237 // Fill the texture with white pixels
238 std::vector<GLubyte> whitePixels(mPbufferSize * mPbufferSize * 4, 255);
239 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mPbufferSize, mPbufferSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, &whitePixels[0]);
240 EXPECT_GL_NO_ERROR();
241
242 // Draw the white texture and verify that the pixels are correct
243 drawQuad(mTextureProgram, "position", 0.5f);
244 EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
245
246 // Bind the EGL surface and draw with it, results are undefined since nothing has
247 // been written to it
248 EGLWindow *window = getEGLWindow();
249 eglBindTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
250 drawQuad(mTextureProgram, "position", 0.5f);
251 EXPECT_GL_NO_ERROR();
252
253 // Clear the back buffer to a unique color (green)
254 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
255 glClear(GL_COLOR_BUFFER_BIT);
256 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
257
258 // Unbind the EGL surface and try to draw with the texture again, the texture's size should
259 // now be zero and incomplete so the back buffer should be black
260 eglReleaseTexImage(window->getDisplay(), mPbuffer, EGL_BACK_BUFFER);
261 drawQuad(mTextureProgram, "position", 0.5f);
262 EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 255);
263}