1 //
2 // Copyright 2020 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 // FramebufferObjectTest.cpp: Tests basic usage of OES_framebuffer_object extension.
8
9 #include "test_utils/ANGLETest.h"
10 #include "test_utils/gl_raii.h"
11
12 using namespace angle;
13
14 class FramebufferObjectTest : public ANGLETest<>
15 {
16 protected:
FramebufferObjectTest()17 FramebufferObjectTest()
18 {
19 setWindowWidth(32);
20 setWindowHeight(32);
21 setConfigRedBits(8);
22 setConfigGreenBits(8);
23 setConfigBlueBits(8);
24 setConfigAlphaBits(8);
25 setConfigDepthBits(24);
26 }
27
testSetUp()28 void testSetUp() override
29 {
30 mTexture.reset(new GLTexture());
31 glEnable(GL_TEXTURE_2D);
32 glBindTexture(GL_TEXTURE_2D, mTexture->get());
33 }
34
testTearDown()35 void testTearDown() override { mTexture.reset(); }
36
37 std::unique_ptr<GLTexture> mTexture;
38 };
39
40 // Checks that framebuffer object can be used without GL errors.
TEST_P(FramebufferObjectTest,FramebufferObject)41 TEST_P(FramebufferObjectTest, FramebufferObject)
42 {
43 GLuint fboId;
44 GLint params;
45
46 glGenFramebuffersOES(1, &fboId);
47 EXPECT_GL_NO_ERROR();
48 glIsFramebufferOES(fboId);
49 EXPECT_GL_NO_ERROR();
50 glBindFramebufferOES(GL_FRAMEBUFFER, fboId);
51 EXPECT_GL_NO_ERROR();
52
53 glCheckFramebufferStatusOES(GL_FRAMEBUFFER);
54 EXPECT_GL_NO_ERROR();
55 glGetFramebufferAttachmentParameterivOES(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
56 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, ¶ms);
57 EXPECT_GL_NO_ERROR();
58
59 glBindFramebuffer(GL_FRAMEBUFFER, 0);
60 glDeleteFramebuffersOES(1, &fboId);
61 EXPECT_GL_NO_ERROR();
62 }
63
64 // Checks that texture object can be bound for framebuffer object.
TEST_P(FramebufferObjectTest,TextureObject)65 TEST_P(FramebufferObjectTest, TextureObject)
66 {
67 GLuint fboId;
68
69 glGenFramebuffers(1, &fboId);
70 glBindFramebuffer(GL_FRAMEBUFFER, fboId);
71 glFramebufferTexture2DOES(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture->get(),
72 0);
73 EXPECT_GL_NO_ERROR();
74
75 glBindFramebuffer(GL_FRAMEBUFFER, 0);
76 glDeleteFramebuffers(1, &fboId);
77 }
78
79 // Checks different formats for a texture object bound to a framebuffer object.
TEST_P(FramebufferObjectTest,TextureObjectDifferentFormats)80 TEST_P(FramebufferObjectTest, TextureObjectDifferentFormats)
81 {
82 // http://anglebug.com/42264178
83 ANGLE_SKIP_TEST_IF(IsMac() && IsOpenGL());
84
85 GLuint fboId;
86
87 glGenFramebuffersOES(1, &fboId);
88 glBindFramebufferOES(GL_FRAMEBUFFER_OES, fboId);
89
90 using FormatInfo = std::array<GLenum, 3>;
91 constexpr std::array<FormatInfo, 5> kFormatArrays = {
92 {{GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE},
93 {GL_RGB, GL_RGB, GL_UNSIGNED_BYTE},
94 {GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4},
95 {GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1},
96 {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}}};
97
98 for (const FormatInfo &formatInfo : kFormatArrays)
99 {
100 glTexImage2D(GL_TEXTURE_2D, 0, formatInfo[0], 1, 1, 0, formatInfo[1], formatInfo[2],
101 &GLColor::green);
102 glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D,
103 mTexture->get(), 0);
104 ASSERT_EQ(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES),
105 (GLenum)GL_FRAMEBUFFER_COMPLETE_OES);
106 }
107
108 EXPECT_GL_NO_ERROR();
109
110 glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
111 glDeleteFramebuffersOES(1, &fboId);
112 }
113
114 // Checks that renderbuffer object can be used and can be bound for framebuffer object.
TEST_P(FramebufferObjectTest,RenderbufferObject)115 TEST_P(FramebufferObjectTest, RenderbufferObject)
116 {
117 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_framebuffer_object"));
118
119 GLuint fboId;
120 GLuint rboId;
121 GLint params;
122
123 glGenFramebuffers(1, &fboId);
124 glBindFramebuffer(GL_FRAMEBUFFER, fboId);
125
126 glGenRenderbuffersOES(1, &rboId);
127 EXPECT_GL_NO_ERROR();
128 glIsRenderbufferOES(rboId);
129 EXPECT_GL_NO_ERROR();
130 glBindRenderbufferOES(GL_RENDERBUFFER, rboId);
131 EXPECT_GL_NO_ERROR();
132 glRenderbufferStorageOES(GL_RENDERBUFFER, GL_RGBA4, 32, 32);
133 EXPECT_GL_NO_ERROR();
134 glRenderbufferStorageOES(GL_RENDERBUFFER, GL_RGB5_A1, 32, 32);
135 EXPECT_GL_NO_ERROR();
136 glRenderbufferStorageOES(GL_RENDERBUFFER, GL_RGB565, 32, 32);
137 EXPECT_GL_NO_ERROR();
138 glRenderbufferStorageOES(GL_RENDERBUFFER, GL_RGBA8, 32, 32);
139 EXPECT_GL_NO_ERROR();
140
141 glFramebufferRenderbufferOES(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboId);
142 EXPECT_GL_NO_ERROR();
143 glGetRenderbufferParameterivOES(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, ¶ms);
144 EXPECT_GL_NO_ERROR();
145
146 glBindFramebuffer(GL_FRAMEBUFFER, 0);
147 glDeleteFramebuffers(1, &fboId);
148 glDeleteRenderbuffersOES(1, &rboId);
149 EXPECT_GL_NO_ERROR();
150 }
151
152 // Checks that an RGBA8 renderbuffer object can be used and can be bound for framebuffer object.
TEST_P(FramebufferObjectTest,RGBA8Renderbuffer)153 TEST_P(FramebufferObjectTest, RGBA8Renderbuffer)
154 {
155 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_framebuffer_object"));
156 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_rgba8"));
157
158 GLuint fbo;
159 GLuint rbo;
160
161 glGenFramebuffers(1, &fbo);
162 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
163
164 glGenRenderbuffersOES(1, &rbo);
165 EXPECT_GL_NO_ERROR();
166 glIsRenderbufferOES(rbo);
167 EXPECT_GL_NO_ERROR();
168 glBindRenderbufferOES(GL_RENDERBUFFER, rbo);
169 EXPECT_GL_NO_ERROR();
170 glRenderbufferStorageOES(GL_RENDERBUFFER, GL_RGBA8, 16, 16);
171 EXPECT_GL_NO_ERROR();
172
173 glFramebufferRenderbufferOES(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
174 EXPECT_GL_NO_ERROR();
175
176 glClearColor(1.0, 1.0, 1.0, 1.0);
177 glClear(GL_COLOR_BUFFER_BIT);
178
179 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::white);
180
181 glBindFramebuffer(GL_FRAMEBUFFER, 0);
182 glDeleteFramebuffers(1, &fbo);
183 glDeleteRenderbuffersOES(1, &rbo);
184 EXPECT_GL_NO_ERROR();
185 }
186
187 // Checks that an RGB8 and an RGBA8 renderbuffer object can be used and can be bound for framebuffer
188 // object one after the other.
TEST_P(FramebufferObjectTest,RGB8AndRGBA8Renderbuffers)189 TEST_P(FramebufferObjectTest, RGB8AndRGBA8Renderbuffers)
190 {
191 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_framebuffer_object"));
192 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_rgb8_rgba8"));
193
194 GLuint fbo;
195 GLuint rbo[2];
196
197 glGenFramebuffers(1, &fbo);
198 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
199
200 glGenRenderbuffersOES(2, rbo);
201 EXPECT_GL_NO_ERROR();
202 glBindRenderbufferOES(GL_RENDERBUFFER, rbo[0]);
203 EXPECT_GL_NO_ERROR();
204 glRenderbufferStorageOES(GL_RENDERBUFFER, GL_RGB8, 16, 16);
205 EXPECT_GL_NO_ERROR();
206 glBindRenderbufferOES(GL_RENDERBUFFER, rbo[1]);
207 EXPECT_GL_NO_ERROR();
208 glRenderbufferStorageOES(GL_RENDERBUFFER, GL_RGBA8, 16, 16);
209 EXPECT_GL_NO_ERROR();
210
211 glFramebufferRenderbufferOES(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[0]);
212 EXPECT_GL_NO_ERROR();
213
214 glClearColor(0.0, 1.0, 0.0, 0.1);
215 glClear(GL_COLOR_BUFFER_BIT);
216 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::green);
217
218 glFramebufferRenderbufferOES(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[1]);
219 EXPECT_GL_NO_ERROR();
220
221 glClearColor(1.0, 0.0, 1.0, 1.0);
222 glClear(GL_COLOR_BUFFER_BIT);
223 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::magenta);
224
225 glBindFramebuffer(GL_FRAMEBUFFER, 0);
226 glDeleteFramebuffers(1, &fbo);
227 glDeleteRenderbuffersOES(2, rbo);
228 EXPECT_GL_NO_ERROR();
229 }
230
231 // Checks that generateMipmap can be called without GL errors.
TEST_P(FramebufferObjectTest,GenerateMipmap)232 TEST_P(FramebufferObjectTest, GenerateMipmap)
233 {
234 constexpr uint32_t kSize = 32;
235 std::vector<unsigned char> pixelData(kSize * kSize * 4, 0);
236
237 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
238
239 glGenerateMipmapOES(GL_TEXTURE_2D);
240 EXPECT_GL_NO_ERROR();
241 }
242
243 ANGLE_INSTANTIATE_TEST_ES1(FramebufferObjectTest);