1 // Copyright (C) 2020 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 <gtest/gtest.h>
16
17 #include "GfxStreamBackend.h"
18 #include "OSWindow.h"
19 #include "base/System.h"
20
21 class GfxStreamBackendTest : public ::testing::Test {
22 private:
sWriteFence(void * cookie,uint32_t fence)23 static void sWriteFence(void* cookie, uint32_t fence) {
24 uint32_t current = *(uint32_t*)cookie;
25 if (current < fence)
26 *(uint32_t*)(cookie) = fence;
27 }
28
29 protected:
30 uint32_t cookie;
31 static const bool useWindow;
32 struct virgl_renderer_callbacks callbacks;
33 struct gfxstream_callbacks gfxstreamcallbacks;
34 static constexpr uint32_t width = 256;
35 static constexpr uint32_t height = 256;
36 static std::unique_ptr<OSWindow> window;
37
GfxStreamBackendTest()38 GfxStreamBackendTest()
39 : cookie(0),
40 callbacks({
41 0,
42 sWriteFence,
43 0,
44 0,
45 0,
46 }),
47 gfxstreamcallbacks({
48 0,
49 0,
50 0,
51 }) {}
52
SetUpTestSuite()53 static void SetUpTestSuite() {
54 if (useWindow) {
55 window.reset(CreateOSWindow());
56 }
57 }
58
TearDownTestSuite()59 static void TearDownTestSuite() { window.reset(nullptr); }
60
SetUp()61 void SetUp() override {
62 android::base::setEnvironmentVariable("ANDROID_GFXSTREAM_EGL", "1");
63 if (useWindow) {
64 window->initialize("GfxStreamBackendTestWindow", width, height);
65 window->setVisible(true);
66 window->messageLoop();
67 }
68 }
69
TearDown()70 void TearDown() override {
71 if (useWindow) {
72 window->destroy();
73 }
74 gfxstream_backend_teardown();
75 }
76 };
77
78 std::unique_ptr<OSWindow> GfxStreamBackendTest::window = nullptr;
79
80 const bool GfxStreamBackendTest::useWindow =
81 android::base::getEnvironmentVariable("ANDROID_EMU_TEST_WITH_WINDOW") == "1";
82
TEST_F(GfxStreamBackendTest,Init)83 TEST_F(GfxStreamBackendTest, Init) {
84 gfxstream_backend_init(width, height, 0, &cookie,
85 GFXSTREAM_RENDERER_FLAGS_USE_SURFACELESS_BIT |
86 GFXSTREAM_RENDERER_FLAGS_NO_VK_BIT,
87 &callbacks, &gfxstreamcallbacks);
88 }
89
TEST_F(GfxStreamBackendTest,InitOpenGLWindow)90 TEST_F(GfxStreamBackendTest, InitOpenGLWindow) {
91 if (!useWindow) {
92 return;
93 }
94 gfxstream_backend_init(width, height, 0, &cookie,
95 GFXSTREAM_RENDERER_FLAGS_NO_VK_BIT, &callbacks,
96 &gfxstreamcallbacks);
97 gfxstream_backend_setup_window(window->getFramebufferNativeWindow(), 0, 0,
98 width, height, width, height);
99 }
100
TEST_F(GfxStreamBackendTest,SimpleFlush)101 TEST_F(GfxStreamBackendTest, SimpleFlush) {
102 gfxstream_backend_init(width, height, 0, &cookie,
103 GFXSTREAM_RENDERER_FLAGS_USE_SURFACELESS_BIT |
104 GFXSTREAM_RENDERER_FLAGS_NO_VK_BIT,
105 &callbacks, &gfxstreamcallbacks);
106
107 const uint32_t res_id = 8;
108 struct virgl_renderer_resource_create_args create_resource_args = {
109 .handle = res_id,
110 .target = 2, // PIPE_TEXTURE_2D
111 .format = VIRGL_FORMAT_R8G8B8A8_UNORM,
112 .bind = VIRGL_BIND_SAMPLER_VIEW | VIRGL_BIND_SCANOUT |
113 VIRGL_BIND_SHARED,
114 .width = width,
115 .height = height,
116 .depth = 1,
117 .array_size = 1,
118 .last_level = 0,
119 .nr_samples = 0,
120 .flags = 0,
121 };
122 EXPECT_EQ(
123 pipe_virgl_renderer_resource_create(&create_resource_args, NULL, 0),
124 0);
125 // R8G8B8A8 is used, so 4 bytes per pixel
126 auto fb = std::make_unique<uint32_t[]>(width * height);
127 EXPECT_NE(fb, nullptr);
128 stream_renderer_flush_resource_and_readback(res_id, 0, 0, width, height,
129 fb.get(), width * height);
130 }
131
132 // Tests compile and link only.
TEST_F(GfxStreamBackendTest,DISABLED_ApiCallLinkTest)133 TEST_F(GfxStreamBackendTest, DISABLED_ApiCallLinkTest) {
134 gfxstream_backend_init(width, height, 0, &cookie,
135 GFXSTREAM_RENDERER_FLAGS_USE_SURFACELESS_BIT |
136 GFXSTREAM_RENDERER_FLAGS_NO_VK_BIT,
137 &callbacks, &gfxstreamcallbacks);
138
139 const uint32_t res_id = 8;
140 struct virgl_renderer_resource_create_args create_resource_args = {
141 .handle = res_id,
142 .target = 2, // PIPE_TEXTURE_2D
143 .format = VIRGL_FORMAT_R8G8B8A8_UNORM,
144 .bind = VIRGL_BIND_SAMPLER_VIEW | VIRGL_BIND_SCANOUT |
145 VIRGL_BIND_SHARED,
146 .width = width,
147 .height = height,
148 .depth = 1,
149 .array_size = 1,
150 .last_level = 0,
151 .nr_samples = 0,
152 .flags = 0,
153 };
154 EXPECT_EQ(
155 pipe_virgl_renderer_resource_create(&create_resource_args, NULL, 0),
156 0);
157 // R8G8B8A8 is used, so 4 bytes per pixel
158 auto fb = std::make_unique<uint32_t[]>(width * height);
159 EXPECT_NE(fb, nullptr);
160 stream_renderer_flush_resource_and_readback(res_id, 0, 0, width, height,
161 fb.get(), width * height);
162
163 virtio_goldfish_pipe_reset(0, 0);
164 pipe_virgl_renderer_init(0, 0, 0);
165 pipe_virgl_renderer_poll();
166 pipe_virgl_renderer_get_cursor_data(0, 0, 0);
167 pipe_virgl_renderer_resource_unref(0);
168 pipe_virgl_renderer_context_create(0, 0, 0);
169 pipe_virgl_renderer_context_destroy(0);
170 pipe_virgl_renderer_submit_cmd(0, 0, 0);
171 pipe_virgl_renderer_transfer_read_iov(0, 0, 0, 0, 0, 0, 0, 0, 0);
172 pipe_virgl_renderer_transfer_write_iov(0, 0, 0, 0, 0, 0, 0, 0, 0);
173
174 pipe_virgl_renderer_get_cap_set(0, 0, 0);
175 pipe_virgl_renderer_fill_caps(0, 0, 0);
176
177 pipe_virgl_renderer_resource_attach_iov(0, 0, 0);
178 pipe_virgl_renderer_resource_detach_iov(0, 0, 0);
179 pipe_virgl_renderer_create_fence(0, 0);
180 pipe_virgl_renderer_force_ctx_0();
181 pipe_virgl_renderer_ctx_attach_resource(0, 0);
182 pipe_virgl_renderer_ctx_detach_resource(0, 0);
183 pipe_virgl_renderer_resource_get_info(0, 0);
184 }
185