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