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