1 // Copyright (C) 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "aemu/base/files/PathUtils.h"
16 #include "aemu/base/files/StdioStream.h"
17 #include "aemu/base/GLObjectCounter.h"
18 #include "aemu/base/system/System.h"
19 #include "aemu/base/testing/TestSystem.h"
20 #include "host-common/GraphicsAgentFactory.h"
21 #include "host-common/multi_display_agent.h"
22 #include "host-common/testing/MockGraphicsAgentFactory.h"
23 #include "host-common/window_agent.h"
24 #include "host-common/MultiDisplay.h"
25 #include "host-common/opengl/misc.h"
26 #include "snapshot/TextureLoader.h"
27 #include "snapshot/TextureSaver.h"
28
29 #include "GLSnapshotTesting.h"
30 #include "GLTestUtils.h"
31 #include "Standalone.h"
32
33 #include <gtest/gtest.h>
34 #include <memory>
35
36 #ifdef _MSC_VER
37 #include "aemu/base/msvc.h"
38 #else
39 #include <sys/time.h>
40 #endif
41
42 #ifdef __linux__
43 #include "X11TestingSupport.h"
44 #endif
45
46 namespace gfxstream {
47 namespace {
48
49 using android::base::StdioStream;
50 using android::snapshot::TextureLoader;
51 using android::snapshot::TextureSaver;
52 using gl::EGLDispatch;
53 using gl::EmulatedEglConfigList;
54 using gl::GLESApi_3_0;
55 using gl::LazyLoadedEGLDispatch;
56 using gl::LazyLoadedGLESv2Dispatch;
57
58 class FrameBufferTest : public ::testing::Test {
59 public:
60 FrameBufferTest() = default;
61
62 protected:
63
SetUpTestSuite()64 static void SetUpTestSuite() {
65 android::emulation::injectGraphicsAgents(
66 android::emulation::MockGraphicsAgentFactory());
67 }
68
TearDownTestSuite()69 static void TearDownTestSuite() { }
70
SetUp()71 virtual void SetUp() override {
72 // setupStandaloneLibrarySearchPaths();
73 emugl::setGLObjectCounter(android::base::GLObjectCounter::get());
74 emugl::set_emugl_window_operations(*getGraphicsAgents()->emu);
75 emugl::set_emugl_multi_display_operations(*getGraphicsAgents()->multi_display);
76 const EGLDispatch* egl = LazyLoadedEGLDispatch::get();
77 ASSERT_NE(nullptr, egl);
78 ASSERT_NE(nullptr, LazyLoadedGLESv2Dispatch::get());
79
80 bool useHostGpu = shouldUseHostGpu();
81 mWindow = createOrGetTestWindow(mXOffset, mYOffset, mWidth, mHeight);
82 mUseSubWindow = mWindow != nullptr;
83
84 if (mUseSubWindow) {
85 ASSERT_NE(nullptr, mWindow->getFramebufferNativeWindow());
86
87 EXPECT_TRUE(
88 FrameBuffer::initialize(
89 mWidth, mHeight, {},
90 mUseSubWindow,
91 !useHostGpu /* egl2egl */));
92 mFb = FrameBuffer::getFB();
93 EXPECT_NE(nullptr, mFb);
94
95 mFb->setupSubWindow(
96 (FBNativeWindowType)(uintptr_t)
97 mWindow->getFramebufferNativeWindow(),
98 0, 0,
99 mWidth, mHeight, mWidth, mHeight,
100 mWindow->getDevicePixelRatio(), 0, false, false);
101 mWindow->messageLoop();
102 } else {
103 EXPECT_TRUE(
104 FrameBuffer::initialize(
105 mWidth, mHeight, {},
106 mUseSubWindow,
107 !useHostGpu /* egl2egl */));
108 mFb = FrameBuffer::getFB();
109 ASSERT_NE(nullptr, mFb);
110 }
111 EXPECT_EQ(EGL_SUCCESS, egl->eglGetError());
112
113 mRenderThreadInfo = new RenderThreadInfo();
114 mRenderThreadInfo->initGl();
115
116 // Snapshots
117 mTestSystem.getTempRoot()->makeSubDir("Snapshots");
118 mSnapshotPath = mTestSystem.getTempRoot()->makeSubPath("Snapshots");
119 mTimeStamp = std::to_string(android::base::getUnixTimeUs());
120 mSnapshotFile = android::base::pj({mSnapshotPath, std::string("snapshot_") + mTimeStamp + ".snap"});
121 mTextureFile = android::base::pj({mSnapshotPath, std::string("textures_") + mTimeStamp + ".stex"});
122 }
123
TearDown()124 virtual void TearDown() override {
125 FrameBuffer::finalize();
126 mFb = nullptr;
127
128 delete mRenderThreadInfo;
129 EXPECT_EQ(EGL_SUCCESS, LazyLoadedEGLDispatch::get()->eglGetError())
130 << "FrameBufferTest TearDown found EGL error";
131 }
132
saveSnapshot()133 void saveSnapshot() {
134 std::unique_ptr<StdioStream> m_stream(new StdioStream(
135 android_fopen(mSnapshotFile.c_str(), "wb"), StdioStream::kOwner));
136 std::shared_ptr<TextureSaver> m_texture_saver(new TextureSaver(StdioStream(
137 android_fopen(mTextureFile.c_str(), "wb"), StdioStream::kOwner)));
138 mFb->onSave(m_stream.get(), m_texture_saver);
139
140 m_stream->close();
141 m_texture_saver->done();
142 }
143
loadSnapshot()144 void loadSnapshot() {
145 // unbind so load will destroy previous objects
146 mFb->bindContext(0, 0, 0);
147
148 std::unique_ptr<StdioStream> m_stream(new StdioStream(
149 android_fopen(mSnapshotFile.c_str(), "rb"), StdioStream::kOwner));
150 std::shared_ptr<TextureLoader> m_texture_loader(
151 new TextureLoader(StdioStream(android_fopen(mTextureFile.c_str(), "rb"),
152 StdioStream::kOwner)));
153 mFb->onLoad(m_stream.get(), m_texture_loader);
154 m_stream->close();
155 m_texture_loader->join();
156 }
157
158 bool mUseSubWindow = false;
159 OSWindow* mWindow = nullptr;
160 FrameBuffer* mFb = nullptr;
161 RenderThreadInfo* mRenderThreadInfo = nullptr;
162
163 int mWidth = 256;
164 int mHeight = 256;
165 int mXOffset= 400;
166 int mYOffset= 400;
167
168 android::base::TestSystem mTestSystem;
169 std::string mSnapshotPath;
170 std::string mTimeStamp;
171 std::string mSnapshotFile;
172 std::string mTextureFile;
173 };
174
175 // Tests that framebuffer initialization and finalization works.
TEST_F(FrameBufferTest,FrameBufferBasic)176 TEST_F(FrameBufferTest, FrameBufferBasic) {
177 }
178
179 // Tests the creation of a single color buffer for the framebuffer.
TEST_F(FrameBufferTest,CreateColorBuffer)180 TEST_F(FrameBufferTest, CreateColorBuffer) {
181 HandleType handle =
182 mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
183 EXPECT_NE(0, handle);
184 // FramBuffer::finalize handles color buffer destruction here
185 }
186
187 // Tests both creation and closing a color buffer.
TEST_F(FrameBufferTest,CreateCloseColorBuffer)188 TEST_F(FrameBufferTest, CreateCloseColorBuffer) {
189 HandleType handle =
190 mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
191 EXPECT_NE(0, handle);
192 mFb->closeColorBuffer(handle);
193 }
194
195 // Tests create, open, and close color buffer.
TEST_F(FrameBufferTest,CreateOpenCloseColorBuffer)196 TEST_F(FrameBufferTest, CreateOpenCloseColorBuffer) {
197 HandleType handle =
198 mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
199 EXPECT_NE(0, handle);
200 EXPECT_EQ(0, mFb->openColorBuffer(handle));
201 mFb->closeColorBuffer(handle);
202 }
203
204 // Tests that the color buffer can be update with a test pattern and that
205 // the test pattern can be read back from the color buffer.
TEST_F(FrameBufferTest,CreateOpenUpdateCloseColorBuffer)206 TEST_F(FrameBufferTest, CreateOpenUpdateCloseColorBuffer) {
207 HandleType handle =
208 mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
209 EXPECT_NE(0, handle);
210 EXPECT_EQ(0, mFb->openColorBuffer(handle));
211
212 TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
213 mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate.data());
214
215 TestTexture forRead = createTestTextureRGBA8888SingleColor(mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
216 mFb->readColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forRead.data());
217
218 EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(), forRead.data()));
219
220 mFb->closeColorBuffer(handle);
221 }
222
TEST_F(FrameBufferTest,CreateOpenUpdateCloseColorBuffer_ReadYUV420)223 TEST_F(FrameBufferTest, CreateOpenUpdateCloseColorBuffer_ReadYUV420) {
224 HandleType handle = mFb->createColorBuffer(mWidth, mHeight, GL_RGBA,
225 FRAMEWORK_FORMAT_YUV_420_888);
226 EXPECT_NE(0, handle);
227 EXPECT_EQ(0, mFb->openColorBuffer(handle));
228
229 TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
230 mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA,
231 GL_UNSIGNED_BYTE, forUpdate.data());
232
233 TestTexture forRead = createTestPatternRGBA8888(mWidth, mHeight);
234 memset(forRead.data(), 0x0, mWidth * mHeight * 3 / 2);
235 mFb->readColorBufferYUV(handle, 0, 0, mWidth, mHeight, forRead.data(),
236 mWidth * mHeight * 3 / 2);
237
238 EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
239 forRead.data()));
240 memset(forRead.data(), 0xff, mWidth * mHeight * 3 / 2);
241 mFb->readColorBufferYUV(handle, 0, 0, mWidth, mHeight, forRead.data(),
242 mWidth * mHeight * 3 / 2);
243
244 EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
245 forRead.data()));
246
247 mFb->closeColorBuffer(handle);
248 }
249
TEST_F(FrameBufferTest,CreateOpenUpdateCloseColorBuffer_ReadNV12)250 TEST_F(FrameBufferTest, CreateOpenUpdateCloseColorBuffer_ReadNV12) {
251 HandleType handle = mFb->createColorBuffer(mWidth, mHeight, GL_RGBA,
252 FRAMEWORK_FORMAT_NV12);
253 EXPECT_NE(0, handle);
254 EXPECT_EQ(0, mFb->openColorBuffer(handle));
255
256 TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
257 mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA,
258 GL_UNSIGNED_BYTE, forUpdate.data());
259
260 TestTexture forRead = createTestPatternRGBA8888(mWidth, mHeight);
261 memset(forRead.data(), 0x0, mWidth * mHeight * 3 / 2);
262 mFb->readColorBufferYUV(handle, 0, 0, mWidth, mHeight, forRead.data(),
263 mWidth * mHeight * 3 / 2);
264
265 EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
266 forRead.data()));
267 memset(forRead.data(), 0xff, mWidth * mHeight * 3 / 2);
268 mFb->readColorBufferYUV(handle, 0, 0, mWidth, mHeight, forRead.data(),
269 mWidth * mHeight * 3 / 2);
270
271 EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
272 forRead.data()));
273
274 mFb->closeColorBuffer(handle);
275 }
276
TEST_F(FrameBufferTest,CreateOpenUpdateCloseColorBuffer_ReadNV12TOYUV420)277 TEST_F(FrameBufferTest, CreateOpenUpdateCloseColorBuffer_ReadNV12TOYUV420) {
278 // nv12
279 mWidth = 8;
280 mHeight = 8;
281 HandleType handle_nv12 = mFb->createColorBuffer(mWidth, mHeight, GL_RGBA,
282 FRAMEWORK_FORMAT_NV12);
283 EXPECT_NE(0, handle_nv12);
284 EXPECT_EQ(0, mFb->openColorBuffer(handle_nv12));
285
286 uint8_t forUpdate[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
287 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
288 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
289 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
290 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
291 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3};
292
293 uint8_t golden[] = {
294 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
295 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
296 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
297 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
298 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
299 };
300
301 mFb->updateColorBuffer(handle_nv12, 0, 0, mWidth, mHeight, GL_RGBA,
302 GL_UNSIGNED_BYTE, forUpdate);
303
304 // yuv420
305 HandleType handle_yuv420 = mFb->createColorBuffer(
306 mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_YUV_420_888);
307 EXPECT_NE(0, handle_yuv420);
308 EXPECT_EQ(0, mFb->openColorBuffer(handle_yuv420));
309
310 uint32_t textures[2] = {1, 2};
311
312 mFb->swapTexturesAndUpdateColorBuffer(handle_nv12, 0, 0, mWidth, mHeight,
313 GL_RGBA, GL_UNSIGNED_BYTE,
314 FRAMEWORK_FORMAT_NV12, textures);
315 mFb->swapTexturesAndUpdateColorBuffer(handle_yuv420, 0, 0, mWidth, mHeight,
316 GL_RGBA, GL_UNSIGNED_BYTE,
317 FRAMEWORK_FORMAT_NV12, textures);
318
319 uint8_t forRead[sizeof(golden)];
320 memset(forRead, 0x0, mWidth * mHeight * 3 / 2);
321 mFb->readColorBufferYUV(handle_yuv420, 0, 0, mWidth, mHeight, forRead,
322 mWidth * mHeight * 3 / 2);
323
324 EXPECT_TRUE(
325 ImageMatches(mWidth, mHeight * 3 / 2, 1, mWidth, golden, forRead));
326
327 mFb->closeColorBuffer(handle_nv12);
328 mFb->closeColorBuffer(handle_yuv420);
329 }
330
TEST_F(FrameBufferTest,CreateOpenUpdateCloseColorBuffer_ReadYV12)331 TEST_F(FrameBufferTest, CreateOpenUpdateCloseColorBuffer_ReadYV12) {
332 mWidth = 20 * 16;
333 HandleType handle = mFb->createColorBuffer(mWidth, mHeight, GL_RGBA,
334 FRAMEWORK_FORMAT_YV12);
335 EXPECT_NE(0, handle);
336 EXPECT_EQ(0, mFb->openColorBuffer(handle));
337
338 TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
339 mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA,
340 GL_UNSIGNED_BYTE, forUpdate.data());
341
342 TestTexture forRead = createTestPatternRGBA8888(mWidth, mHeight);
343 memset(forRead.data(), 0x0, mWidth * mHeight * 3 / 2);
344 mFb->readColorBufferYUV(handle, 0, 0, mWidth, mHeight, forRead.data(),
345 mWidth * mHeight * 3 / 2);
346
347 EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
348 forRead.data()));
349 memset(forRead.data(), 0xff, mWidth * mHeight * 3 / 2);
350 mFb->readColorBufferYUV(handle, 0, 0, mWidth, mHeight, forRead.data(),
351 mWidth * mHeight * 3 / 2);
352
353 EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
354 forRead.data()));
355
356 mFb->closeColorBuffer(handle);
357 }
358
359 // bug: 110105029
360 // Tests that color buffer updates should not fail if there is a format change.
361 // Needed to accomodate format-changing behavior from the guest gralloc.
TEST_F(FrameBufferTest,CreateOpenUpdateCloseColorBuffer_FormatChange)362 TEST_F(FrameBufferTest, CreateOpenUpdateCloseColorBuffer_FormatChange) {
363 HandleType handle =
364 mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
365 EXPECT_NE(0, handle);
366 EXPECT_EQ(0, mFb->openColorBuffer(handle));
367
368 TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
369 mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate.data());
370
371 TestTexture forRead = createTestTextureRGBA8888SingleColor(mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
372 mFb->readColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forRead.data());
373
374 EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
375 forRead.data()));
376
377 mFb->closeColorBuffer(handle);
378 }
379
380 // Tests obtaining EGL configs from FrameBuffer.
TEST_F(FrameBufferTest,Configs)381 TEST_F(FrameBufferTest, Configs) {
382 const EmulatedEglConfigList* configs = mFb->getConfigs();
383 EXPECT_GE(configs->size(), 0);
384 }
385
386 // Tests creating GL context from FrameBuffer.
TEST_F(FrameBufferTest,CreateEmulatedEglContext)387 TEST_F(FrameBufferTest, CreateEmulatedEglContext) {
388 HandleType handle = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
389 EXPECT_NE(0, handle);
390 }
391
392 // Tests creating window surface from FrameBuffer.
TEST_F(FrameBufferTest,CreateEmulatedEglWindowSurface)393 TEST_F(FrameBufferTest, CreateEmulatedEglWindowSurface) {
394 HandleType handle = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
395 EXPECT_NE(0, handle);
396 }
397
398 // Tests eglMakeCurrent from FrameBuffer.
TEST_F(FrameBufferTest,CreateBindEmulatedEglContext)399 TEST_F(FrameBufferTest, CreateBindEmulatedEglContext) {
400 HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
401 HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
402 EXPECT_TRUE(mFb->bindContext(context, surface, surface));
403 }
404
405 // A basic blit test that simulates what the guest system does in one pass
406 // of draw + eglSwapBuffers:
407 // 1. Draws in OpenGL with glClear.
408 // 2. Calls flushEmulatedEglWindowSurfaceColorBuffer(), which is the "backing operation" of
409 // ANativeWindow::queueBuffer in the guest.
410 // 3. Calls post() with the resulting color buffer, the backing operation of fb device "post"
411 // in the guest.
TEST_F(FrameBufferTest,BasicBlit)412 TEST_F(FrameBufferTest, BasicBlit) {
413 auto gl = LazyLoadedGLESv2Dispatch::get();
414
415 HandleType colorBuffer =
416 mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
417 HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
418 HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
419
420 EXPECT_TRUE(mFb->bindContext(context, surface, surface));
421 EXPECT_TRUE(mFb->setEmulatedEglWindowSurfaceColorBuffer(surface, colorBuffer));
422
423 float colors[3][4] = {
424 { 1.0f, 0.0f, 0.0f, 1.0f},
425 { 0.0f, 1.0f, 0.0f, 1.0f},
426 { 0.0f, 0.0f, 1.0f, 1.0f},
427 };
428
429 for (int i = 0; i < 3; i++) {
430 float* color = colors[i];
431
432 gl->glClearColor(color[0], color[1], color[2], color[3]);
433 gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
434 mFb->flushEmulatedEglWindowSurfaceColorBuffer(surface);
435
436 TestTexture targetBuffer =
437 createTestTextureRGBA8888SingleColor(
438 mWidth, mHeight, color[0], color[1], color[2], color[3]);
439
440 TestTexture forRead =
441 createTestTextureRGBA8888SingleColor(
442 mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
443
444 mFb->readColorBuffer(
445 colorBuffer, 0, 0, mWidth, mHeight,
446 GL_RGBA, GL_UNSIGNED_BYTE, forRead.data());
447
448 EXPECT_TRUE(
449 ImageMatches(
450 mWidth, mHeight, 4, mWidth,
451 targetBuffer.data(), forRead.data()));
452
453 if (mUseSubWindow) {
454 mFb->post(colorBuffer);
455 mWindow->messageLoop();
456 }
457 }
458
459 EXPECT_TRUE(mFb->bindContext(0, 0, 0));
460 mFb->closeColorBuffer(colorBuffer);
461 mFb->closeColorBuffer(colorBuffer);
462 mFb->destroyEmulatedEglWindowSurface(surface);
463 }
464
465 // Tests that snapshot works with an empty FrameBuffer.
TEST_F(FrameBufferTest,SnapshotSmokeTest)466 TEST_F(FrameBufferTest, SnapshotSmokeTest) {
467 saveSnapshot();
468 loadSnapshot();
469 }
470
471 // Tests that the snapshot restores the clear color state, by changing the clear
472 // color in between save and load. If this fails, it means failure to restore a
473 // number of different states from GL contexts.
TEST_F(FrameBufferTest,SnapshotPreserveColorClear)474 TEST_F(FrameBufferTest, SnapshotPreserveColorClear) {
475 HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
476 HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
477 EXPECT_TRUE(mFb->bindContext(context, surface, surface));
478
479 auto gl = LazyLoadedGLESv2Dispatch::get();
480 gl->glClearColor(1, 1, 1, 1);
481 gl->glClear(GL_COLOR_BUFFER_BIT);
482 EXPECT_TRUE(compareGlobalGlFloatv(gl, GL_COLOR_CLEAR_VALUE, {1, 1, 1, 1}));
483
484 saveSnapshot();
485
486 gl->glClearColor(0.5, 0.5, 0.5, 0.5);
487 EXPECT_TRUE(compareGlobalGlFloatv(gl, GL_COLOR_CLEAR_VALUE,
488 {0.5, 0.5, 0.5, 0.5}));
489
490 loadSnapshot();
491 EXPECT_TRUE(mFb->bindContext(context, surface, surface));
492
493 EXPECT_TRUE(compareGlobalGlFloatv(gl, GL_COLOR_CLEAR_VALUE, {1, 1, 1, 1}));
494 }
495
496 // Tests that snapshot works to save the state of a single ColorBuffer; we
497 // upload a test pattern to the ColorBuffer, take a snapshot, load it, and
498 // verify that the contents are the same.
TEST_F(FrameBufferTest,SnapshotSingleColorBuffer)499 TEST_F(FrameBufferTest, SnapshotSingleColorBuffer) {
500 HandleType handle =
501 mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
502
503 TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
504 mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate.data());
505
506 saveSnapshot();
507 loadSnapshot();
508
509 TestTexture forRead = createTestTextureRGBA8888SingleColor(mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
510 mFb->readColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forRead.data());
511
512 EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(), forRead.data()));
513
514 mFb->closeColorBuffer(handle);
515 }
516
517 // bug: 111360779
518 // Tests that the ColorBuffer is successfully updated even if a reformat happens
519 // on restore; the reformat may mess up the texture restore logic.
520 // In ColorBuffer::subUpdate, this test is known to fail if touch() is moved after the reformat.
TEST_F(FrameBufferTest,SnapshotColorBufferSubUpdateRestore)521 TEST_F(FrameBufferTest, SnapshotColorBufferSubUpdateRestore) {
522 HandleType handle =
523 mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
524
525 saveSnapshot();
526 loadSnapshot();
527
528 TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
529 mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate.data());
530
531 TestTexture forRead = createTestTextureRGBA8888SingleColor(mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
532 mFb->readColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forRead.data());
533
534 EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(), forRead.data()));
535
536 mFb->closeColorBuffer(handle);
537 }
538
539 // bug: 111558407
540 // Tests that ColorBuffer's blit path is retained on save/restore.
TEST_F(FrameBufferTest,SnapshotFastBlitRestore)541 TEST_F(FrameBufferTest, SnapshotFastBlitRestore) {
542 HandleType handle = mFb->createColorBuffer(mWidth, mHeight, GL_RGBA,
543 FRAMEWORK_FORMAT_GL_COMPATIBLE);
544
545 EXPECT_TRUE(mFb->isFastBlitSupported());
546
547 mFb->lock();
548 EXPECT_EQ(mFb->isFastBlitSupported(), mFb->findColorBuffer(handle)->glOpIsFastBlitSupported());
549 mFb->unlock();
550
551 saveSnapshot();
552 loadSnapshot();
553
554 mFb->lock();
555 EXPECT_EQ(mFb->isFastBlitSupported(), mFb->findColorBuffer(handle)->glOpIsFastBlitSupported());
556 mFb->unlock();
557
558 mFb->closeColorBuffer(handle);
559 }
560
561 // Tests rate of draw calls with no guest/host communication, but with translator.
562 static constexpr uint32_t kDrawCallLimit = 50000;
563
TEST_F(FrameBufferTest,DrawCallRate)564 TEST_F(FrameBufferTest, DrawCallRate) {
565 HandleType colorBuffer =
566 mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
567 HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
568 HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
569
570 EXPECT_TRUE(mFb->bindContext(context, surface, surface));
571 EXPECT_TRUE(mFb->setEmulatedEglWindowSurfaceColorBuffer(surface, colorBuffer));
572
573 auto gl = LazyLoadedGLESv2Dispatch::get();
574
575 constexpr char vshaderSrc[] = R"(#version 300 es
576 precision highp float;
577
578 layout (location = 0) in vec2 pos;
579 layout (location = 1) in vec3 color;
580
581 uniform mat4 transform;
582
583 out vec3 color_varying;
584
585 void main() {
586 gl_Position = transform * vec4(pos, 0.0, 1.0);
587 color_varying = (transform * vec4(color, 1.0)).xyz;
588 }
589 )";
590 constexpr char fshaderSrc[] = R"(#version 300 es
591 precision highp float;
592
593 in vec3 color_varying;
594
595 out vec4 fragColor;
596
597 void main() {
598 fragColor = vec4(color_varying, 1.0);
599 }
600 )";
601
602 GLuint program = compileAndLinkShaderProgram(vshaderSrc, fshaderSrc);
603
604 GLint transformLoc = gl->glGetUniformLocation(program, "transform");
605
606 struct VertexAttributes {
607 float position[2];
608 float color[3];
609 };
610
611 const VertexAttributes vertexAttrs[] = {
612 { { -0.5f, -0.5f,}, { 0.2, 0.1, 0.9, }, },
613 { { 0.5f, -0.5f,}, { 0.8, 0.3, 0.1,}, },
614 { { 0.0f, 0.5f,}, { 0.1, 0.9, 0.6,}, },
615 };
616
617 GLuint buffer;
618 gl->glGenBuffers(1, &buffer);
619 gl->glBindBuffer(GL_ARRAY_BUFFER, buffer);
620 gl->glBufferData(GL_ARRAY_BUFFER, sizeof(vertexAttrs), vertexAttrs,
621 GL_STATIC_DRAW);
622
623 gl->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE,
624 sizeof(VertexAttributes), 0);
625 gl->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,
626 sizeof(VertexAttributes),
627 (GLvoid*)offsetof(VertexAttributes, color));
628 gl->glEnableVertexAttribArray(0);
629 gl->glEnableVertexAttribArray(1);
630
631 gl->glUseProgram(program);
632
633 gl->glClearColor(0.2f, 0.2f, 0.3f, 0.0f);
634 gl->glViewport(0, 0, 1, 1);
635
636 float matrix[16] = {
637 1.0f, 0.0f, 0.0f, 0.0f,
638 0.0f, 1.0f, 0.0f, 0.0f,
639 0.0f, 0.0f, 1.0f, 0.0f,
640 0.0f, 0.0f, 0.0f, 1.0f,
641 };
642
643 gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
644
645 uint32_t drawCount = 0;
646
647 auto cpuTimeStart = android::base::cpuTime();
648
649 fprintf(stderr, "%s: transform loc %d\n", __func__, transformLoc);
650
651 while (drawCount < kDrawCallLimit) {
652 gl->glUniformMatrix4fv(transformLoc, 1, GL_FALSE, matrix);
653 gl->glBindBuffer(GL_ARRAY_BUFFER, buffer);
654 gl->glDrawArrays(GL_TRIANGLES, 0, 3);
655 ++drawCount;
656 }
657
658 gl->glFinish();
659
660 auto cpuTime = android::base::cpuTime() - cpuTimeStart;
661
662 uint64_t duration_us = cpuTime.wall_time_us;
663 // uint64_t duration_cpu_us = cpuTime.usageUs();
664
665 float ms = duration_us / 1000.0f;
666 float sec = duration_us / 1000000.0f;
667 float drawCallHz = (float)kDrawCallLimit / sec;
668
669 printf("Drew %u times in %f ms. Rate: %f Hz\n", kDrawCallLimit, ms, drawCallHz);
670
671 // android::perflogger::logDrawCallOverheadTest(
672 // (const char*)gl->glGetString(GL_VENDOR),
673 // (const char*)gl->glGetString(GL_RENDERER),
674 // (const char*)gl->glGetString(GL_VERSION),
675 // "drawArrays", "decoder",
676 // kDrawCallLimit,
677 // (long)drawCallHz,
678 // duration_us,
679 // duration_cpu_us);
680
681 EXPECT_TRUE(mFb->bindContext(0, 0, 0));
682 mFb->closeColorBuffer(colorBuffer);
683 mFb->closeColorBuffer(colorBuffer);
684 mFb->destroyEmulatedEglWindowSurface(surface);
685 }
686
687 // Tests rate of draw calls with only the host driver and no translator.
TEST_F(FrameBufferTest,HostDrawCallRate)688 TEST_F(FrameBufferTest, HostDrawCallRate) {
689 HandleType colorBuffer =
690 mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
691 HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
692 HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
693
694 EXPECT_TRUE(mFb->bindContext(context, surface, surface));
695 EXPECT_TRUE(mFb->setEmulatedEglWindowSurfaceColorBuffer(surface, colorBuffer));
696
697 auto gl = LazyLoadedGLESv2Dispatch::get();
698
699 uint64_t duration_us, duration_cpu_us;
700 gl->glTestHostDriverPerformance(kDrawCallLimit, &duration_us, &duration_cpu_us);
701
702 float ms = duration_us / 1000.0f;
703 float sec = duration_us / 1000000.0f;
704 float drawCallHz = kDrawCallLimit / sec;
705
706 printf("Drew %u times in %f ms. Rate: %f Hz\n", kDrawCallLimit, ms, drawCallHz);
707
708 // android::perflogger::logDrawCallOverheadTest(
709 // (const char*)gl->glGetString(GL_VENDOR),
710 // (const char*)gl->glGetString(GL_RENDERER),
711 // (const char*)gl->glGetString(GL_VERSION),
712 // "drawArrays", "host",
713 // kDrawCallLimit,
714 // (long)drawCallHz,
715 // duration_us,
716 // duration_cpu_us);
717
718 EXPECT_TRUE(mFb->bindContext(0, 0, 0));
719 mFb->closeColorBuffer(colorBuffer);
720 mFb->closeColorBuffer(colorBuffer);
721 mFb->destroyEmulatedEglWindowSurface(surface);
722 }
723
724 // Tests Vulkan interop query.
TEST_F(FrameBufferTest,VulkanInteropQuery)725 TEST_F(FrameBufferTest, VulkanInteropQuery) {
726 auto egl = LazyLoadedEGLDispatch::get();
727
728 EXPECT_NE(nullptr, egl->eglQueryVulkanInteropSupportANDROID);
729
730 EGLBoolean supported =
731 egl->eglQueryVulkanInteropSupportANDROID();
732
733 // Disregard the result for now
734 (void)supported;
735 }
736
737 // Tests ColorBuffer with GL_BGRA input.
TEST_F(FrameBufferTest,CreateColorBufferBGRA)738 TEST_F(FrameBufferTest, CreateColorBufferBGRA) {
739 HandleType handle =
740 mFb->createColorBuffer(mWidth, mHeight, GL_BGRA_EXT, FRAMEWORK_FORMAT_GL_COMPATIBLE);
741 EXPECT_NE(0, handle);
742 // FramBuffer::finalize handles color buffer destruction here
743 }
744
745 // Test ColorBuffer with GL_RGBA, but read back as GL_BGRA, so that R/B are switched.
746 // TODO: This doesn't work on NVIDIA EGL, it issues GL_INVALID_OPERATION if the format doesn't match.
TEST_F(FrameBufferTest,DISABLED_ReadColorBufferSwitchRedBlue)747 TEST_F(FrameBufferTest, DISABLED_ReadColorBufferSwitchRedBlue) {
748 HandleType handle =
749 mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
750 EXPECT_NE(0, handle);
751 EXPECT_EQ(0, mFb->openColorBuffer(handle));
752
753 TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
754 mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate.data());
755
756 TestTexture forRead = createTestTextureRGBA8888SingleColor(mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
757 // Switch red and blue
758 mFb->readColorBuffer(handle, 0, 0, mWidth, mHeight, GL_BGRA_EXT, GL_UNSIGNED_BYTE, forRead.data());
759
760 // Switch them back, so we get the original image
761 uint8_t* forReadBytes = forRead.data();
762
763 for (uint32_t row = 0; row < mHeight; ++row) {
764 for (uint32_t col = 0; col < mWidth; ++col) {
765 uint8_t* pixel = forReadBytes + mWidth * 4 * row + col * 4;
766 // In RGBA8:
767 // 3 2 1 0
768 // 0xAABBGGRR on little endian systems
769 // R component: pixel[0]
770 // B component: pixel[2]
771 uint8_t r = pixel[0];
772 uint8_t b = pixel[2];
773 pixel[0] = b;
774 pixel[2] = r;
775 }
776 }
777
778 EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(), forRead.data()));
779
780 mFb->closeColorBuffer(handle);
781 }
782
TEST_F(FrameBufferTest,CreateMultiDisplay)783 TEST_F(FrameBufferTest, CreateMultiDisplay) {
784 uint32_t id = 1;
785 mFb->createDisplay(&id);
786 EXPECT_EQ(0, mFb->createDisplay(&id));
787 EXPECT_EQ(0, mFb->destroyDisplay(id));
788 }
789
TEST_F(FrameBufferTest,BindMultiDisplayColorBuffer)790 TEST_F(FrameBufferTest, BindMultiDisplayColorBuffer) {
791 uint32_t id = 2;
792 EXPECT_EQ(0, mFb->createDisplay(&id));
793 uint32_t handle =
794 mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
795 EXPECT_NE(0, handle);
796 EXPECT_EQ(0, mFb->setDisplayColorBuffer(id, handle));
797 uint32_t getHandle = 0;
798 mFb->getDisplayColorBuffer(id, &getHandle);
799 EXPECT_EQ(handle, getHandle);
800 uint32_t getId = 0;
801 mFb->getColorBufferDisplay(handle, &getId);
802 EXPECT_EQ(id, getId);
803 mFb->closeColorBuffer(handle);
804 EXPECT_EQ(0, mFb->destroyDisplay(id));
805 }
806
TEST_F(FrameBufferTest,SetMultiDisplayPosition)807 TEST_F(FrameBufferTest, SetMultiDisplayPosition) {
808 uint32_t id = FrameBuffer::s_invalidIdMultiDisplay;
809 mFb->createDisplay(&id);
810 EXPECT_NE(0, id);
811 uint32_t w = mWidth / 2, h = mHeight / 2;
812 EXPECT_EQ(0, mFb->setDisplayPose(id, -1, -1, w, h));
813 int32_t x, y;
814 uint32_t width, height;
815 EXPECT_EQ(0, mFb->getDisplayPose(id, &x, &y, &width, &height));
816 EXPECT_EQ(w, width);
817 EXPECT_EQ(h, height);
818 EXPECT_EQ(0, mFb->destroyDisplay(id));
819 }
820
TEST_F(FrameBufferTest,ComposeMultiDisplay)821 TEST_F(FrameBufferTest, ComposeMultiDisplay) {
822 LazyLoadedGLESv2Dispatch::get();
823
824 HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
825 HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
826 EXPECT_TRUE(mFb->bindContext(context, surface, surface));
827
828 HandleType cb0 =
829 mFb->createColorBuffer(mWidth/2, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
830 TestTexture forUpdate0 = createTestTextureRGBA8888SingleColor(mWidth/2, mHeight, 1.0f, 1.0f, 1.0f, 1.0f);
831 EXPECT_EQ(0, mFb->openColorBuffer(cb0));
832 mFb->updateColorBuffer(cb0, 0, 0, mWidth/2, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate0.data());
833
834 uint32_t cb1 =
835 mFb->createColorBuffer(mWidth/2, mHeight/2, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
836 EXPECT_EQ(0, mFb->openColorBuffer(cb1));
837 TestTexture forUpdate1 = createTestTextureRGBA8888SingleColor(mWidth/2, mHeight/2, 1.0f, 0.0f, 0.0f, 1.0f);
838 mFb->updateColorBuffer(cb1, 0, 0, mWidth/2, mHeight/2, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate1.data());
839
840 uint32_t cb2 =
841 mFb->createColorBuffer(mWidth/4, mHeight/2, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
842 EXPECT_EQ(0, mFb->openColorBuffer(cb2));
843 TestTexture forUpdate2 = createTestTextureRGBA8888SingleColor(mWidth/4, mHeight/2, 0.0f, 1.0f, 0.0f, 1.0f);
844 mFb->updateColorBuffer(cb2, 0, 0, mWidth/4, mHeight/2, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate2.data());
845
846 uint32_t cb3 =
847 mFb->createColorBuffer(mWidth/4, mHeight/4, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
848 EXPECT_EQ(0, mFb->openColorBuffer(cb3));
849 TestTexture forUpdate3 = createTestTextureRGBA8888SingleColor(mWidth/4, mHeight/4, 0.0f, 0.0f, 1.0f, 1.0f);
850 mFb->updateColorBuffer(cb3, 0, 0, mWidth/4, mHeight/4, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate3.data());
851
852 FrameBuffer::DisplayInfo info[] =
853 {{cb1, -1, -1, (uint32_t)mWidth/2, (uint32_t)mHeight/2, 240},
854 {cb2, -1, -1, (uint32_t)mWidth/4, (uint32_t)mHeight/2, 240},
855 {cb3, -1, -1, (uint32_t)mWidth/4, (uint32_t)mHeight/4, 240}};
856
857 uint32_t ids[] = {1, 2, 3};
858 for (uint32_t i = 0; i < 3 ; i++) {
859 EXPECT_EQ(0, mFb->createDisplay(&ids[i]));
860 EXPECT_EQ(0, mFb->setDisplayPose(ids[i], info[i].pos_x, info[i].pos_y,
861 info[i].width, info[i].height));
862 EXPECT_EQ(0, mFb->setDisplayColorBuffer(ids[i], info[i].cb));
863 }
864
865 if (mUseSubWindow) {
866 mFb->post(cb0);
867 mWindow->messageLoop();
868 }
869
870 EXPECT_TRUE(mFb->bindContext(0, 0, 0));
871 mFb->closeColorBuffer(cb0);
872 mFb->closeColorBuffer(cb1);
873 mFb->closeColorBuffer(cb2);
874 mFb->closeColorBuffer(cb3);
875 mFb->destroyDisplay(ids[0]);
876 mFb->destroyDisplay(ids[1]);
877 mFb->destroyDisplay(ids[2]);
878 mFb->destroyEmulatedEglWindowSurface(surface);
879 }
880
881 #ifdef GFXSTREAM_HAS_X11
882 // Tests basic pixmap import. Can we import a native pixmap and successfully
883 // upload and read back some color?
TEST_F(FrameBufferTest,PixmapImport_Basic)884 TEST_F(FrameBufferTest, PixmapImport_Basic) {
885 const int kWidth = 16;
886 const int kHeight = 16;
887 const int kBytesPerPixel = 4;
888
889 // Only run this test on display :0.
890 auto disp = android::base::getEnvironmentVariable("DISPLAY");
891 if (disp != ":0" ) {
892 fprintf(stderr, "%s: Wawrning: Skipping test because DISPLAY is [%s] (not :0)\n", __func__,
893 disp.c_str());
894 return;
895 }
896
897 void* pixmap = createNativePixmap(kWidth, kHeight, kBytesPerPixel);
898 EXPECT_NE(nullptr, pixmap);
899
900 HandleType cb =
901 mFb->createColorBuffer(kWidth, kHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
902 TestTexture forUpdate = createTestTextureRGBA8888SingleColor(kWidth, kHeight, 1.0f, 0.0f, 1.0f, 1.0f);
903 EXPECT_EQ(0, mFb->openColorBuffer(cb));
904 mFb->updateColorBuffer(cb, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate.data());
905
906 EXPECT_TRUE(mFb->platformImportResource(cb, RESOURCE_TYPE_EGL_NATIVE_PIXMAP|RESOURCE_USE_PRESERVE, pixmap));
907
908 TestTexture forRead = createTestTextureRGBA8888SingleColor(kWidth, kHeight, 0.0f, 0.0f, 0.0f, 0.0f);
909 mFb->readColorBuffer(cb, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, forRead.data());
910
911 EXPECT_TRUE(ImageMatches(kWidth, kHeight, 4, kWidth, forUpdate.data(), forRead.data()));
912
913 mFb->closeColorBuffer(cb);
914
915 freeNativePixmap(pixmap);
916 }
917
918 // Similar to BasicBlit, except the color buffer is backed by a pixmap.
919 // Can we render to the pixmap and read back contents?
TEST_F(FrameBufferTest,PixmapImport_Blit)920 TEST_F(FrameBufferTest, PixmapImport_Blit) {
921 // Only run this test on display :0.
922 auto disp = android::base::getEnvironmentVariable("DISPLAY");
923 if (disp != ":0" ) {
924 fprintf(stderr, "%s: Wawrning: Skipping test because DISPLAY is [%s] (not :0)\n", __func__,
925 disp.c_str());
926 return;
927 }
928
929 auto gl = LazyLoadedGLESv2Dispatch::get();
930
931 void* pixmap = createNativePixmap(mWidth, mHeight, 4);
932 EXPECT_NE(nullptr, pixmap);
933
934 HandleType colorBuffer =
935 mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
936
937 EXPECT_TRUE(mFb->platformImportResource(colorBuffer, RESOURCE_TYPE_EGL_NATIVE_PIXMAP, pixmap));
938
939 HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
940 HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
941
942 EXPECT_TRUE(mFb->bindContext(context, surface, surface));
943 EXPECT_TRUE(mFb->setEmulatedEglWindowSurfaceColorBuffer(surface, colorBuffer));
944
945 float colors[3][4] = {
946 { 1.0f, 0.0f, 0.0f, 1.0f},
947 { 0.0f, 1.0f, 0.0f, 1.0f},
948 { 0.0f, 0.0f, 1.0f, 1.0f},
949 };
950
951 for (int i = 0; i < 3; i++) {
952 float* color = colors[i];
953
954 gl->glClearColor(color[0], color[1], color[2], color[3]);
955 gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
956 mFb->flushEmulatedEglWindowSurfaceColorBuffer(surface);
957
958 TestTexture targetBuffer =
959 createTestTextureRGBA8888SingleColor(
960 mWidth, mHeight, color[0], color[1], color[2], color[3]);
961
962 TestTexture forRead =
963 createTestTextureRGBA8888SingleColor(
964 mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
965
966 mFb->readColorBuffer(
967 colorBuffer, 0, 0, mWidth, mHeight,
968 GL_RGBA, GL_UNSIGNED_BYTE, forRead.data());
969
970 EXPECT_TRUE(
971 ImageMatches(
972 mWidth, mHeight, 4, mWidth,
973 targetBuffer.data(), forRead.data()));
974
975 if (mUseSubWindow) {
976 mFb->post(colorBuffer);
977 mWindow->messageLoop();
978 }
979 }
980
981 EXPECT_TRUE(mFb->bindContext(0, 0, 0));
982 mFb->closeColorBuffer(colorBuffer);
983 mFb->closeColorBuffer(colorBuffer);
984 mFb->destroyEmulatedEglWindowSurface(surface);
985
986 freeNativePixmap(pixmap);
987 }
988 #endif
989
990 } // namespace
991 } // namespace gfxstream
992