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 =
216         createTestTextureRGBA8888SingleColor(mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
217     mFb->readColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forRead.data(),
218                          forRead.size());
219 
220     EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(), forRead.data()));
221 
222     mFb->closeColorBuffer(handle);
223 }
224 
TEST_F(FrameBufferTest,CreateOpenUpdateCloseColorBuffer_ReadYUV420)225 TEST_F(FrameBufferTest, CreateOpenUpdateCloseColorBuffer_ReadYUV420) {
226     HandleType handle = mFb->createColorBuffer(mWidth, mHeight, GL_RGBA,
227                                                FRAMEWORK_FORMAT_YUV_420_888);
228     EXPECT_NE(0, handle);
229     EXPECT_EQ(0, mFb->openColorBuffer(handle));
230 
231     TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
232     mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA,
233                            GL_UNSIGNED_BYTE, forUpdate.data());
234 
235     TestTexture forRead = createTestPatternRGBA8888(mWidth, mHeight);
236     memset(forRead.data(), 0x0, mWidth * mHeight * 3 / 2);
237     mFb->readColorBufferYUV(handle, 0, 0, mWidth, mHeight, forRead.data(),
238                             mWidth * mHeight * 3 / 2);
239 
240     EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
241                              forRead.data()));
242     memset(forRead.data(), 0xff, mWidth * mHeight * 3 / 2);
243     mFb->readColorBufferYUV(handle, 0, 0, mWidth, mHeight, forRead.data(),
244                             mWidth * mHeight * 3 / 2);
245 
246     EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
247                              forRead.data()));
248 
249     mFb->closeColorBuffer(handle);
250 }
251 
TEST_F(FrameBufferTest,CreateOpenUpdateCloseColorBuffer_ReadNV12)252 TEST_F(FrameBufferTest, CreateOpenUpdateCloseColorBuffer_ReadNV12) {
253     HandleType handle = mFb->createColorBuffer(mWidth, mHeight, GL_RGBA,
254                                                FRAMEWORK_FORMAT_NV12);
255     EXPECT_NE(0, handle);
256     EXPECT_EQ(0, mFb->openColorBuffer(handle));
257 
258     TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
259     mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA,
260                            GL_UNSIGNED_BYTE, forUpdate.data());
261 
262     TestTexture forRead = createTestPatternRGBA8888(mWidth, mHeight);
263     memset(forRead.data(), 0x0, mWidth * mHeight * 3 / 2);
264     mFb->readColorBufferYUV(handle, 0, 0, mWidth, mHeight, forRead.data(),
265                             mWidth * mHeight * 3 / 2);
266 
267     EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
268                              forRead.data()));
269     memset(forRead.data(), 0xff, mWidth * mHeight * 3 / 2);
270     mFb->readColorBufferYUV(handle, 0, 0, mWidth, mHeight, forRead.data(),
271                             mWidth * mHeight * 3 / 2);
272 
273     EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
274                              forRead.data()));
275 
276     mFb->closeColorBuffer(handle);
277 }
278 
TEST_F(FrameBufferTest,CreateOpenUpdateCloseColorBuffer_ReadNV12TOYUV420)279 TEST_F(FrameBufferTest, CreateOpenUpdateCloseColorBuffer_ReadNV12TOYUV420) {
280     // nv12
281     mWidth = 8;
282     mHeight = 8;
283     HandleType handle_nv12 = mFb->createColorBuffer(mWidth, mHeight, GL_RGBA,
284                                                     FRAMEWORK_FORMAT_NV12);
285     EXPECT_NE(0, handle_nv12);
286     EXPECT_EQ(0, mFb->openColorBuffer(handle_nv12));
287 
288     uint8_t forUpdate[] = {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                            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
291                            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
292                            2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
293                            2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3};
294 
295     uint8_t golden[] = {
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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
298             1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
299             1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
300             3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
301     };
302 
303     mFb->updateColorBuffer(handle_nv12, 0, 0, mWidth, mHeight, GL_RGBA,
304                            GL_UNSIGNED_BYTE, forUpdate);
305 
306     // yuv420
307     HandleType handle_yuv420 = mFb->createColorBuffer(
308             mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_YUV_420_888);
309     EXPECT_NE(0, handle_yuv420);
310     EXPECT_EQ(0, mFb->openColorBuffer(handle_yuv420));
311 
312     uint32_t textures[2] = {1, 2};
313 
314     mFb->swapTexturesAndUpdateColorBuffer(handle_nv12, 0, 0, mWidth, mHeight,
315                                           GL_RGBA, GL_UNSIGNED_BYTE,
316                                           FRAMEWORK_FORMAT_NV12, textures);
317     mFb->swapTexturesAndUpdateColorBuffer(handle_yuv420, 0, 0, mWidth, mHeight,
318                                           GL_RGBA, GL_UNSIGNED_BYTE,
319                                           FRAMEWORK_FORMAT_NV12, textures);
320 
321     uint8_t forRead[sizeof(golden)];
322     memset(forRead, 0x0, mWidth * mHeight * 3 / 2);
323     mFb->readColorBufferYUV(handle_yuv420, 0, 0, mWidth, mHeight, forRead,
324                             mWidth * mHeight * 3 / 2);
325 
326     EXPECT_TRUE(
327             ImageMatches(mWidth, mHeight * 3 / 2, 1, mWidth, golden, forRead));
328 
329     mFb->closeColorBuffer(handle_nv12);
330     mFb->closeColorBuffer(handle_yuv420);
331 }
332 
TEST_F(FrameBufferTest,CreateOpenUpdateCloseColorBuffer_ReadYV12)333 TEST_F(FrameBufferTest, CreateOpenUpdateCloseColorBuffer_ReadYV12) {
334     mWidth = 20 * 16;
335     HandleType handle = mFb->createColorBuffer(mWidth, mHeight, GL_RGBA,
336                                                FRAMEWORK_FORMAT_YV12);
337     EXPECT_NE(0, handle);
338     EXPECT_EQ(0, mFb->openColorBuffer(handle));
339 
340     TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
341     mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA,
342                            GL_UNSIGNED_BYTE, forUpdate.data());
343 
344     TestTexture forRead = createTestPatternRGBA8888(mWidth, mHeight);
345     memset(forRead.data(), 0x0, mWidth * mHeight * 3 / 2);
346     mFb->readColorBufferYUV(handle, 0, 0, mWidth, mHeight, forRead.data(),
347                             mWidth * mHeight * 3 / 2);
348 
349     EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
350                              forRead.data()));
351     memset(forRead.data(), 0xff, mWidth * mHeight * 3 / 2);
352     mFb->readColorBufferYUV(handle, 0, 0, mWidth, mHeight, forRead.data(),
353                             mWidth * mHeight * 3 / 2);
354 
355     EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
356                              forRead.data()));
357 
358     mFb->closeColorBuffer(handle);
359 }
360 
361 // bug: 110105029
362 // Tests that color buffer updates should not fail if there is a format change.
363 // Needed to accomodate format-changing behavior from the guest gralloc.
TEST_F(FrameBufferTest,CreateOpenUpdateCloseColorBuffer_FormatChange)364 TEST_F(FrameBufferTest, CreateOpenUpdateCloseColorBuffer_FormatChange) {
365     HandleType handle =
366         mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
367     EXPECT_NE(0, handle);
368     EXPECT_EQ(0, mFb->openColorBuffer(handle));
369 
370     TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
371     mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate.data());
372 
373     TestTexture forRead =
374         createTestTextureRGBA8888SingleColor(mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
375     mFb->readColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forRead.data(),
376                          forRead.size());
377 
378     EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(),
379                              forRead.data()));
380 
381     mFb->closeColorBuffer(handle);
382 }
383 
384 // Tests obtaining EGL configs from FrameBuffer.
TEST_F(FrameBufferTest,Configs)385 TEST_F(FrameBufferTest, Configs) {
386     const EmulatedEglConfigList* configs = mFb->getConfigs();
387     EXPECT_GE(configs->size(), 0);
388 }
389 
390 // Tests creating GL context from FrameBuffer.
TEST_F(FrameBufferTest,CreateEmulatedEglContext)391 TEST_F(FrameBufferTest, CreateEmulatedEglContext) {
392     HandleType handle = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
393     EXPECT_NE(0, handle);
394 }
395 
396 // Tests creating window surface from FrameBuffer.
TEST_F(FrameBufferTest,CreateEmulatedEglWindowSurface)397 TEST_F(FrameBufferTest, CreateEmulatedEglWindowSurface) {
398     HandleType handle = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
399     EXPECT_NE(0, handle);
400 }
401 
402 // Tests eglMakeCurrent from FrameBuffer.
TEST_F(FrameBufferTest,CreateBindEmulatedEglContext)403 TEST_F(FrameBufferTest, CreateBindEmulatedEglContext) {
404     HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
405     HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
406     EXPECT_TRUE(mFb->bindContext(context, surface, surface));
407 }
408 
409 // A basic blit test that simulates what the guest system does in one pass
410 // of draw + eglSwapBuffers:
411 // 1. Draws in OpenGL with glClear.
412 // 2. Calls flushEmulatedEglWindowSurfaceColorBuffer(), which is the "backing operation" of
413 // ANativeWindow::queueBuffer in the guest.
414 // 3. Calls post() with the resulting color buffer, the backing operation of fb device "post"
415 // in the guest.
TEST_F(FrameBufferTest,BasicBlit)416 TEST_F(FrameBufferTest, BasicBlit) {
417     auto gl = LazyLoadedGLESv2Dispatch::get();
418 
419     HandleType colorBuffer =
420         mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
421     HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
422     HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
423 
424     EXPECT_TRUE(mFb->bindContext(context, surface, surface));
425     EXPECT_TRUE(mFb->setEmulatedEglWindowSurfaceColorBuffer(surface, colorBuffer));
426 
427     float colors[3][4] = {
428         { 1.0f, 0.0f, 0.0f, 1.0f},
429         { 0.0f, 1.0f, 0.0f, 1.0f},
430         { 0.0f, 0.0f, 1.0f, 1.0f},
431     };
432 
433     for (int i = 0; i < 3; i++) {
434         float* color = colors[i];
435 
436         gl->glClearColor(color[0], color[1], color[2], color[3]);
437         gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
438         mFb->flushEmulatedEglWindowSurfaceColorBuffer(surface);
439 
440         TestTexture targetBuffer =
441             createTestTextureRGBA8888SingleColor(
442                 mWidth, mHeight, color[0], color[1], color[2], color[3]);
443 
444         TestTexture forRead =
445             createTestTextureRGBA8888SingleColor(
446                 mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
447 
448         mFb->readColorBuffer(colorBuffer, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE,
449                              forRead.data(), forRead.size());
450 
451         EXPECT_TRUE(
452             ImageMatches(
453                 mWidth, mHeight, 4, mWidth,
454                 targetBuffer.data(), forRead.data()));
455 
456         if (mUseSubWindow) {
457             mFb->post(colorBuffer);
458             mWindow->messageLoop();
459         }
460     }
461 
462     EXPECT_TRUE(mFb->bindContext(0, 0, 0));
463     mFb->closeColorBuffer(colorBuffer);
464     mFb->closeColorBuffer(colorBuffer);
465     mFb->destroyEmulatedEglWindowSurface(surface);
466 }
467 
468 // Tests that snapshot works with an empty FrameBuffer.
TEST_F(FrameBufferTest,SnapshotSmokeTest)469 TEST_F(FrameBufferTest, SnapshotSmokeTest) {
470     saveSnapshot();
471     loadSnapshot();
472 }
473 
474 // Tests that the snapshot restores the clear color state, by changing the clear
475 // color in between save and load. If this fails, it means failure to restore a
476 // number of different states from GL contexts.
TEST_F(FrameBufferTest,SnapshotPreserveColorClear)477 TEST_F(FrameBufferTest, SnapshotPreserveColorClear) {
478     HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
479     HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
480     EXPECT_TRUE(mFb->bindContext(context, surface, surface));
481 
482     auto gl = LazyLoadedGLESv2Dispatch::get();
483     gl->glClearColor(1, 1, 1, 1);
484     gl->glClear(GL_COLOR_BUFFER_BIT);
485     EXPECT_TRUE(compareGlobalGlFloatv(gl, GL_COLOR_CLEAR_VALUE, {1, 1, 1, 1}));
486 
487     saveSnapshot();
488 
489     gl->glClearColor(0.5, 0.5, 0.5, 0.5);
490     EXPECT_TRUE(compareGlobalGlFloatv(gl, GL_COLOR_CLEAR_VALUE,
491                                       {0.5, 0.5, 0.5, 0.5}));
492 
493     loadSnapshot();
494     EXPECT_TRUE(mFb->bindContext(context, surface, surface));
495 
496     EXPECT_TRUE(compareGlobalGlFloatv(gl, GL_COLOR_CLEAR_VALUE, {1, 1, 1, 1}));
497 }
498 
499 // Tests that snapshot works to save the state of a single ColorBuffer; we
500 // upload a test pattern to the ColorBuffer, take a snapshot, load it, and
501 // verify that the contents are the same.
TEST_F(FrameBufferTest,SnapshotSingleColorBuffer)502 TEST_F(FrameBufferTest, SnapshotSingleColorBuffer) {
503     HandleType handle =
504         mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
505 
506     TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
507     mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate.data());
508 
509     saveSnapshot();
510     loadSnapshot();
511 
512     TestTexture forRead =
513         createTestTextureRGBA8888SingleColor(mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
514     mFb->readColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forRead.data(),
515                          forRead.size());
516 
517     EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(), forRead.data()));
518 
519     mFb->closeColorBuffer(handle);
520 }
521 
522 // bug: 111360779
523 // Tests that the ColorBuffer is successfully updated even if a reformat happens
524 // on restore; the reformat may mess up the texture restore logic.
525 // In ColorBuffer::subUpdate, this test is known to fail if touch() is moved after the reformat.
TEST_F(FrameBufferTest,SnapshotColorBufferSubUpdateRestore)526 TEST_F(FrameBufferTest, SnapshotColorBufferSubUpdateRestore) {
527     HandleType handle =
528         mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
529 
530     saveSnapshot();
531     loadSnapshot();
532 
533     TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
534     mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate.data());
535 
536     TestTexture forRead =
537         createTestTextureRGBA8888SingleColor(mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
538     mFb->readColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forRead.data(),
539                          forRead.size());
540 
541     EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(), forRead.data()));
542 
543     mFb->closeColorBuffer(handle);
544 }
545 
546 // bug: 111558407
547 // Tests that ColorBuffer's blit path is retained on save/restore.
TEST_F(FrameBufferTest,SnapshotFastBlitRestore)548 TEST_F(FrameBufferTest, SnapshotFastBlitRestore) {
549     HandleType handle = mFb->createColorBuffer(mWidth, mHeight, GL_RGBA,
550                                                FRAMEWORK_FORMAT_GL_COMPATIBLE);
551 
552     EXPECT_TRUE(mFb->isFastBlitSupported());
553 
554     mFb->lock();
555     EXPECT_EQ(mFb->isFastBlitSupported(), mFb->findColorBuffer(handle)->glOpIsFastBlitSupported());
556     mFb->unlock();
557 
558     saveSnapshot();
559     loadSnapshot();
560 
561     mFb->lock();
562     EXPECT_EQ(mFb->isFastBlitSupported(), mFb->findColorBuffer(handle)->glOpIsFastBlitSupported());
563     mFb->unlock();
564 
565     mFb->closeColorBuffer(handle);
566 }
567 
568 // Tests rate of draw calls with no guest/host communication, but with translator.
569 static constexpr uint32_t kDrawCallLimit = 50000;
570 
TEST_F(FrameBufferTest,DrawCallRate)571 TEST_F(FrameBufferTest, DrawCallRate) {
572     HandleType colorBuffer =
573         mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
574     HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
575     HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
576 
577     EXPECT_TRUE(mFb->bindContext(context, surface, surface));
578     EXPECT_TRUE(mFb->setEmulatedEglWindowSurfaceColorBuffer(surface, colorBuffer));
579 
580     auto gl = LazyLoadedGLESv2Dispatch::get();
581 
582     constexpr char vshaderSrc[] = R"(#version 300 es
583     precision highp float;
584 
585     layout (location = 0) in vec2 pos;
586     layout (location = 1) in vec3 color;
587 
588     uniform mat4 transform;
589 
590     out vec3 color_varying;
591 
592     void main() {
593         gl_Position = transform * vec4(pos, 0.0, 1.0);
594         color_varying = (transform * vec4(color, 1.0)).xyz;
595     }
596     )";
597     constexpr char fshaderSrc[] = R"(#version 300 es
598     precision highp float;
599 
600     in vec3 color_varying;
601 
602     out vec4 fragColor;
603 
604     void main() {
605         fragColor = vec4(color_varying, 1.0);
606     }
607     )";
608 
609     GLuint program = compileAndLinkShaderProgram(vshaderSrc, fshaderSrc);
610 
611     GLint transformLoc = gl->glGetUniformLocation(program, "transform");
612 
613     struct VertexAttributes {
614         float position[2];
615         float color[3];
616     };
617 
618     const VertexAttributes vertexAttrs[] = {
619         { { -0.5f, -0.5f,}, { 0.2, 0.1, 0.9, }, },
620         { { 0.5f, -0.5f,}, { 0.8, 0.3, 0.1,}, },
621         { { 0.0f, 0.5f,}, { 0.1, 0.9, 0.6,}, },
622     };
623 
624     GLuint buffer;
625     gl->glGenBuffers(1, &buffer);
626     gl->glBindBuffer(GL_ARRAY_BUFFER, buffer);
627     gl->glBufferData(GL_ARRAY_BUFFER, sizeof(vertexAttrs), vertexAttrs,
628                      GL_STATIC_DRAW);
629 
630     gl->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE,
631                           sizeof(VertexAttributes), 0);
632     gl->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE,
633                               sizeof(VertexAttributes),
634                               (GLvoid*)offsetof(VertexAttributes, color));
635     gl->glEnableVertexAttribArray(0);
636     gl->glEnableVertexAttribArray(1);
637 
638     gl->glUseProgram(program);
639 
640     gl->glClearColor(0.2f, 0.2f, 0.3f, 0.0f);
641     gl->glViewport(0, 0, 1, 1);
642 
643     float matrix[16] = {
644         1.0f, 0.0f, 0.0f, 0.0f,
645         0.0f, 1.0f, 0.0f, 0.0f,
646         0.0f, 0.0f, 1.0f, 0.0f,
647         0.0f, 0.0f, 0.0f, 1.0f,
648     };
649 
650     gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
651 
652     uint32_t drawCount = 0;
653 
654     auto cpuTimeStart = android::base::cpuTime();
655 
656 fprintf(stderr, "%s: transform loc %d\n", __func__, transformLoc);
657 
658     while (drawCount < kDrawCallLimit) {
659         gl->glUniformMatrix4fv(transformLoc, 1, GL_FALSE, matrix);
660         gl->glBindBuffer(GL_ARRAY_BUFFER, buffer);
661         gl->glDrawArrays(GL_TRIANGLES, 0, 3);
662         ++drawCount;
663     }
664 
665     gl->glFinish();
666 
667     auto cpuTime = android::base::cpuTime() - cpuTimeStart;
668 
669     uint64_t duration_us = cpuTime.wall_time_us;
670     // uint64_t duration_cpu_us = cpuTime.usageUs();
671 
672     float ms = duration_us / 1000.0f;
673     float sec = duration_us / 1000000.0f;
674     float drawCallHz = (float)kDrawCallLimit / sec;
675 
676     printf("Drew %u times in %f ms. Rate: %f Hz\n", kDrawCallLimit, ms, drawCallHz);
677 
678     // android::perflogger::logDrawCallOverheadTest(
679     //     (const char*)gl->glGetString(GL_VENDOR),
680     //     (const char*)gl->glGetString(GL_RENDERER),
681     //     (const char*)gl->glGetString(GL_VERSION),
682     //     "drawArrays", "decoder",
683     //     kDrawCallLimit,
684     //     (long)drawCallHz,
685     //     duration_us,
686     //     duration_cpu_us);
687 
688     EXPECT_TRUE(mFb->bindContext(0, 0, 0));
689     mFb->closeColorBuffer(colorBuffer);
690     mFb->closeColorBuffer(colorBuffer);
691     mFb->destroyEmulatedEglWindowSurface(surface);
692 }
693 
694 // Tests rate of draw calls with only the host driver and no translator.
TEST_F(FrameBufferTest,HostDrawCallRate)695 TEST_F(FrameBufferTest, HostDrawCallRate) {
696     HandleType colorBuffer =
697         mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
698     HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
699     HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
700 
701     EXPECT_TRUE(mFb->bindContext(context, surface, surface));
702     EXPECT_TRUE(mFb->setEmulatedEglWindowSurfaceColorBuffer(surface, colorBuffer));
703 
704     auto gl = LazyLoadedGLESv2Dispatch::get();
705 
706     uint64_t duration_us, duration_cpu_us;
707     gl->glTestHostDriverPerformance(kDrawCallLimit, &duration_us, &duration_cpu_us);
708 
709     float ms = duration_us / 1000.0f;
710     float sec = duration_us / 1000000.0f;
711     float drawCallHz = kDrawCallLimit / sec;
712 
713     printf("Drew %u times in %f ms. Rate: %f Hz\n", kDrawCallLimit, ms, drawCallHz);
714 
715     // android::perflogger::logDrawCallOverheadTest(
716     //     (const char*)gl->glGetString(GL_VENDOR),
717     //     (const char*)gl->glGetString(GL_RENDERER),
718     //     (const char*)gl->glGetString(GL_VERSION),
719     //     "drawArrays", "host",
720     //     kDrawCallLimit,
721     //     (long)drawCallHz,
722     //     duration_us,
723     //     duration_cpu_us);
724 
725     EXPECT_TRUE(mFb->bindContext(0, 0, 0));
726     mFb->closeColorBuffer(colorBuffer);
727     mFb->closeColorBuffer(colorBuffer);
728     mFb->destroyEmulatedEglWindowSurface(surface);
729 }
730 
731 // Tests Vulkan interop query.
TEST_F(FrameBufferTest,VulkanInteropQuery)732 TEST_F(FrameBufferTest, VulkanInteropQuery) {
733     auto egl = LazyLoadedEGLDispatch::get();
734 
735     EXPECT_NE(nullptr, egl->eglQueryVulkanInteropSupportANDROID);
736 
737     EGLBoolean supported =
738         egl->eglQueryVulkanInteropSupportANDROID();
739 
740     // Disregard the result for now
741     (void)supported;
742 }
743 
744 // Tests ColorBuffer with GL_BGRA input.
TEST_F(FrameBufferTest,CreateColorBufferBGRA)745 TEST_F(FrameBufferTest, CreateColorBufferBGRA) {
746     HandleType handle =
747         mFb->createColorBuffer(mWidth, mHeight, GL_BGRA_EXT, FRAMEWORK_FORMAT_GL_COMPATIBLE);
748     EXPECT_NE(0, handle);
749     // FramBuffer::finalize handles color buffer destruction here
750 }
751 
752 // Test ColorBuffer with GL_RGBA, but read back as GL_BGRA, so that R/B are switched.
753 // TODO: This doesn't work on NVIDIA EGL, it issues GL_INVALID_OPERATION if the format doesn't match.
TEST_F(FrameBufferTest,DISABLED_ReadColorBufferSwitchRedBlue)754 TEST_F(FrameBufferTest, DISABLED_ReadColorBufferSwitchRedBlue) {
755     HandleType handle =
756         mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
757     EXPECT_NE(0, handle);
758     EXPECT_EQ(0, mFb->openColorBuffer(handle));
759 
760     TestTexture forUpdate = createTestPatternRGBA8888(mWidth, mHeight);
761     mFb->updateColorBuffer(handle, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate.data());
762 
763     TestTexture forRead =
764         createTestTextureRGBA8888SingleColor(mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
765     // Switch red and blue
766     mFb->readColorBuffer(handle, 0, 0, mWidth, mHeight, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
767                          forRead.data(), forRead.size());
768 
769     // Switch them back, so we get the original image
770     uint8_t* forReadBytes = forRead.data();
771 
772     for (uint32_t row = 0; row < mHeight; ++row) {
773         for (uint32_t col = 0; col < mWidth; ++col) {
774             uint8_t* pixel = forReadBytes + mWidth * 4 * row + col * 4;
775             // In RGBA8:
776             //    3 2 1 0
777             // 0xAABBGGRR on little endian systems
778             // R component: pixel[0]
779             // B component: pixel[2]
780             uint8_t r = pixel[0];
781             uint8_t b = pixel[2];
782             pixel[0] = b;
783             pixel[2] = r;
784         }
785     }
786 
787     EXPECT_TRUE(ImageMatches(mWidth, mHeight, 4, mWidth, forUpdate.data(), forRead.data()));
788 
789     mFb->closeColorBuffer(handle);
790 }
791 
TEST_F(FrameBufferTest,CreateMultiDisplay)792 TEST_F(FrameBufferTest, CreateMultiDisplay) {
793     uint32_t id = 1;
794     mFb->createDisplay(&id);
795     EXPECT_EQ(0, mFb->createDisplay(&id));
796     EXPECT_EQ(0, mFb->destroyDisplay(id));
797 }
798 
TEST_F(FrameBufferTest,BindMultiDisplayColorBuffer)799 TEST_F(FrameBufferTest, BindMultiDisplayColorBuffer) {
800     uint32_t id = 2;
801     EXPECT_EQ(0, mFb->createDisplay(&id));
802     uint32_t handle =
803         mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
804     EXPECT_NE(0, handle);
805     EXPECT_EQ(0, mFb->setDisplayColorBuffer(id, handle));
806     uint32_t getHandle = 0;
807     mFb->getDisplayColorBuffer(id, &getHandle);
808     EXPECT_EQ(handle, getHandle);
809     uint32_t getId = 0;
810     mFb->getColorBufferDisplay(handle, &getId);
811     EXPECT_EQ(id, getId);
812     mFb->closeColorBuffer(handle);
813     EXPECT_EQ(0, mFb->destroyDisplay(id));
814 }
815 
TEST_F(FrameBufferTest,SetMultiDisplayPosition)816 TEST_F(FrameBufferTest, SetMultiDisplayPosition) {
817     uint32_t id = FrameBuffer::s_invalidIdMultiDisplay;
818     mFb->createDisplay(&id);
819     EXPECT_NE(0, id);
820     uint32_t w = mWidth / 2, h = mHeight / 2;
821     EXPECT_EQ(0, mFb->setDisplayPose(id, -1, -1, w, h));
822     int32_t x, y;
823     uint32_t width, height;
824     EXPECT_EQ(0, mFb->getDisplayPose(id, &x, &y, &width, &height));
825     EXPECT_EQ(w, width);
826     EXPECT_EQ(h, height);
827     EXPECT_EQ(0, mFb->destroyDisplay(id));
828 }
829 
TEST_F(FrameBufferTest,ComposeMultiDisplay)830 TEST_F(FrameBufferTest, ComposeMultiDisplay) {
831     LazyLoadedGLESv2Dispatch::get();
832 
833     HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
834     HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
835     EXPECT_TRUE(mFb->bindContext(context, surface, surface));
836 
837     HandleType cb0 =
838         mFb->createColorBuffer(mWidth/2, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
839     TestTexture forUpdate0 = createTestTextureRGBA8888SingleColor(mWidth/2, mHeight, 1.0f, 1.0f, 1.0f, 1.0f);
840     EXPECT_EQ(0, mFb->openColorBuffer(cb0));
841     mFb->updateColorBuffer(cb0, 0, 0, mWidth/2, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate0.data());
842 
843     uint32_t cb1 =
844         mFb->createColorBuffer(mWidth/2, mHeight/2, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
845     EXPECT_EQ(0, mFb->openColorBuffer(cb1));
846     TestTexture forUpdate1 = createTestTextureRGBA8888SingleColor(mWidth/2, mHeight/2, 1.0f, 0.0f, 0.0f, 1.0f);
847     mFb->updateColorBuffer(cb1, 0, 0, mWidth/2, mHeight/2, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate1.data());
848 
849     uint32_t cb2 =
850         mFb->createColorBuffer(mWidth/4, mHeight/2, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
851     EXPECT_EQ(0, mFb->openColorBuffer(cb2));
852     TestTexture forUpdate2 = createTestTextureRGBA8888SingleColor(mWidth/4, mHeight/2, 0.0f, 1.0f, 0.0f, 1.0f);
853     mFb->updateColorBuffer(cb2, 0, 0, mWidth/4, mHeight/2, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate2.data());
854 
855     uint32_t cb3 =
856         mFb->createColorBuffer(mWidth/4, mHeight/4, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
857     EXPECT_EQ(0, mFb->openColorBuffer(cb3));
858     TestTexture forUpdate3 = createTestTextureRGBA8888SingleColor(mWidth/4, mHeight/4, 0.0f, 0.0f, 1.0f, 1.0f);
859     mFb->updateColorBuffer(cb3, 0, 0, mWidth/4, mHeight/4, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate3.data());
860 
861     FrameBuffer::DisplayInfo info[] =
862     {{cb1, -1, -1, (uint32_t)mWidth/2, (uint32_t)mHeight/2, 240},
863      {cb2, -1, -1, (uint32_t)mWidth/4, (uint32_t)mHeight/2, 240},
864      {cb3, -1, -1, (uint32_t)mWidth/4, (uint32_t)mHeight/4, 240}};
865 
866     uint32_t ids[] = {1, 2, 3};
867     for (uint32_t i = 0; i < 3 ; i++) {
868         EXPECT_EQ(0, mFb->createDisplay(&ids[i]));
869         EXPECT_EQ(0, mFb->setDisplayPose(ids[i], info[i].pos_x, info[i].pos_y,
870                                          info[i].width, info[i].height));
871         EXPECT_EQ(0, mFb->setDisplayColorBuffer(ids[i], info[i].cb));
872     }
873 
874     if (mUseSubWindow) {
875         mFb->post(cb0);
876         mWindow->messageLoop();
877     }
878 
879     EXPECT_TRUE(mFb->bindContext(0, 0, 0));
880     mFb->closeColorBuffer(cb0);
881     mFb->closeColorBuffer(cb1);
882     mFb->closeColorBuffer(cb2);
883     mFb->closeColorBuffer(cb3);
884     mFb->destroyDisplay(ids[0]);
885     mFb->destroyDisplay(ids[1]);
886     mFb->destroyDisplay(ids[2]);
887     mFb->destroyEmulatedEglWindowSurface(surface);
888 }
889 
890 #ifdef GFXSTREAM_HAS_X11
891 // Tests basic pixmap import. Can we import a native pixmap and successfully
892 // upload and read back some color?
TEST_F(FrameBufferTest,PixmapImport_Basic)893 TEST_F(FrameBufferTest, PixmapImport_Basic) {
894     const int kWidth = 16;
895     const int kHeight = 16;
896     const int kBytesPerPixel = 4;
897 
898     // Only run this test on display :0.
899     auto disp =  android::base::getEnvironmentVariable("DISPLAY");
900     if (disp != ":0" ) {
901         fprintf(stderr, "%s: Wawrning: Skipping test because DISPLAY is [%s] (not :0)\n", __func__,
902                 disp.c_str());
903         return;
904     }
905 
906     void* pixmap = createNativePixmap(kWidth, kHeight, kBytesPerPixel);
907     EXPECT_NE(nullptr, pixmap);
908 
909     HandleType cb =
910         mFb->createColorBuffer(kWidth, kHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
911     TestTexture forUpdate = createTestTextureRGBA8888SingleColor(kWidth, kHeight, 1.0f, 0.0f, 1.0f, 1.0f);
912     EXPECT_EQ(0, mFb->openColorBuffer(cb));
913     mFb->updateColorBuffer(cb, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, forUpdate.data());
914 
915     EXPECT_TRUE(mFb->platformImportResource(cb, RESOURCE_TYPE_EGL_NATIVE_PIXMAP|RESOURCE_USE_PRESERVE, pixmap));
916 
917     TestTexture forRead =
918         createTestTextureRGBA8888SingleColor(kWidth, kHeight, 0.0f, 0.0f, 0.0f, 0.0f);
919     mFb->readColorBuffer(cb, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, forRead.data(),
920                          forRead.size());
921 
922     EXPECT_TRUE(ImageMatches(kWidth, kHeight, 4, kWidth, forUpdate.data(), forRead.data()));
923 
924     mFb->closeColorBuffer(cb);
925 
926     freeNativePixmap(pixmap);
927 }
928 
929 // Similar to BasicBlit, except the color buffer is backed by a pixmap.
930 // Can we render to the pixmap and read back contents?
TEST_F(FrameBufferTest,PixmapImport_Blit)931 TEST_F(FrameBufferTest, PixmapImport_Blit) {
932     // Only run this test on display :0.
933     auto disp =  android::base::getEnvironmentVariable("DISPLAY");
934     if (disp != ":0" ) {
935         fprintf(stderr, "%s: Wawrning: Skipping test because DISPLAY is [%s] (not :0)\n", __func__,
936                 disp.c_str());
937         return;
938     }
939 
940     auto gl = LazyLoadedGLESv2Dispatch::get();
941 
942     void* pixmap = createNativePixmap(mWidth, mHeight, 4);
943     EXPECT_NE(nullptr, pixmap);
944 
945     HandleType colorBuffer =
946         mFb->createColorBuffer(mWidth, mHeight, GL_RGBA, FRAMEWORK_FORMAT_GL_COMPATIBLE);
947 
948     EXPECT_TRUE(mFb->platformImportResource(colorBuffer, RESOURCE_TYPE_EGL_NATIVE_PIXMAP, pixmap));
949 
950     HandleType context = mFb->createEmulatedEglContext(0, 0, GLESApi_3_0);
951     HandleType surface = mFb->createEmulatedEglWindowSurface(0, mWidth, mHeight);
952 
953     EXPECT_TRUE(mFb->bindContext(context, surface, surface));
954     EXPECT_TRUE(mFb->setEmulatedEglWindowSurfaceColorBuffer(surface, colorBuffer));
955 
956     float colors[3][4] = {
957         { 1.0f, 0.0f, 0.0f, 1.0f},
958         { 0.0f, 1.0f, 0.0f, 1.0f},
959         { 0.0f, 0.0f, 1.0f, 1.0f},
960     };
961 
962     for (int i = 0; i < 3; i++) {
963         float* color = colors[i];
964 
965         gl->glClearColor(color[0], color[1], color[2], color[3]);
966         gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
967         mFb->flushEmulatedEglWindowSurfaceColorBuffer(surface);
968 
969         TestTexture targetBuffer =
970             createTestTextureRGBA8888SingleColor(
971                 mWidth, mHeight, color[0], color[1], color[2], color[3]);
972 
973         TestTexture forRead =
974             createTestTextureRGBA8888SingleColor(
975                 mWidth, mHeight, 0.0f, 0.0f, 0.0f, 0.0f);
976 
977         mFb->readColorBuffer(colorBuffer, 0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE,
978                              forRead.data(), forRead.size());
979 
980         EXPECT_TRUE(
981             ImageMatches(
982                 mWidth, mHeight, 4, mWidth,
983                 targetBuffer.data(), forRead.data()));
984 
985         if (mUseSubWindow) {
986             mFb->post(colorBuffer);
987             mWindow->messageLoop();
988         }
989     }
990 
991     EXPECT_TRUE(mFb->bindContext(0, 0, 0));
992     mFb->closeColorBuffer(colorBuffer);
993     mFb->closeColorBuffer(colorBuffer);
994     mFb->destroyEmulatedEglWindowSurface(surface);
995 
996     freeNativePixmap(pixmap);
997 }
998 #endif
999 
1000 }  // namespace
1001 }  // namespace gfxstream
1002