• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "AHardwareBufferTest.h"
18 
19 #include <errno.h>
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <sys/un.h>
23 #include <unistd.h>
24 
25 #include <sstream>
26 #include <string>
27 
28 #include <android/hardware_buffer.h>
29 #define LOG_TAG "AHardwareBufferTest"
30 #include "NativeTestHelper.h"
31 
32 namespace android {
33 
34 //#define LOG_NDEBUG 0
35 
36 #define BAD_VALUE -EINVAL
37 #define NO_ERROR 0
38 
BuildHexFailureMessage(uint64_t expected,uint64_t actual,const char * type)39 static std::string BuildHexFailureMessage(uint64_t expected,
40         uint64_t actual, const char* type) {
41     std::ostringstream ss;
42     ss << type << " 0x" << std::hex << actual
43             << " does not match expected " << type << " 0x" << std::hex
44             << expected;
45     return ss.str();
46 }
47 
BuildFailureMessage(uint32_t expected,uint32_t actual,const char * type)48 static std::string BuildFailureMessage(uint32_t expected,
49         uint32_t actual, const char* type) {
50     std::ostringstream ss;
51     ss << "Buffer " << type << " do not match" << ": " << actual << " != " << expected;
52     return ss.str();
53 }
54 
CheckAHardwareBufferMatchesDesc(AHardwareBuffer * abuffer,const AHardwareBuffer_Desc & desc)55 static std::string CheckAHardwareBufferMatchesDesc(
56         AHardwareBuffer* abuffer, const AHardwareBuffer_Desc& desc) {
57     AHardwareBuffer_Desc bufferDesc;
58     AHardwareBuffer_describe(abuffer, &bufferDesc);
59     if (bufferDesc.width != desc.width)
60         return BuildFailureMessage(desc.width, bufferDesc.width, "widths");
61     if (bufferDesc.height != desc.height)
62         return BuildFailureMessage(desc.height, bufferDesc.height, "heights");
63     if (bufferDesc.layers != desc.layers)
64         return BuildFailureMessage(desc.layers, bufferDesc.layers, "layers");
65     if (bufferDesc.usage != desc.usage)
66         return BuildHexFailureMessage(desc.usage, bufferDesc.usage, "usage");
67     if (bufferDesc.format != desc.format)
68         return BuildFailureMessage(desc.format, bufferDesc.format, "formats");
69     return std::string();
70 }
71 
SetUp()72 bool AHardwareBufferTest::SetUp() { return true; }
73 
TearDown()74 void AHardwareBufferTest::TearDown() {}
75 
76 // Test that passing in NULL values to allocate works as expected.
testAHardwareBuffer_allocate_FailsWithNullInput(JNIEnv * env)77 void AHardwareBufferTest::testAHardwareBuffer_allocate_FailsWithNullInput(JNIEnv* env) {
78     AHardwareBuffer* buffer;
79     AHardwareBuffer_Desc desc;
80 
81     memset(&desc, 0, sizeof(AHardwareBuffer_Desc));
82 
83     int res = AHardwareBuffer_allocate(&desc, NULL);
84     ASSERT_EQ(BAD_VALUE, res);
85     res = AHardwareBuffer_allocate(NULL, &buffer);
86     ASSERT_EQ(BAD_VALUE, res);
87     res = AHardwareBuffer_allocate(NULL, NULL);
88     ASSERT_EQ(BAD_VALUE, res);
89 }
90 
91 // Test that passing in NULL values to allocate works as expected.
testAHardwareBuffer_allocate_BlobFormatRequiresHeight1(JNIEnv * env)92 void AHardwareBufferTest::testAHardwareBuffer_allocate_BlobFormatRequiresHeight1(JNIEnv* env) {
93     AHardwareBuffer* buffer;
94     AHardwareBuffer_Desc desc = {};
95 
96     desc.width = 2;
97     desc.height = 4;
98     desc.layers = 1;
99     desc.usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY;
100     desc.format = AHARDWAREBUFFER_FORMAT_BLOB;
101     int res = AHardwareBuffer_allocate(&desc, &buffer);
102     ASSERT_EQ(BAD_VALUE, res);
103 
104     desc.height = 1;
105     res = AHardwareBuffer_allocate(&desc, &buffer);
106     ASSERT_EQ(NO_ERROR, res);
107     ASSERT_EQ(std::string(), CheckAHardwareBufferMatchesDesc(buffer, desc));
108     AHardwareBuffer_release(buffer);
109     buffer = NULL;
110 }
111 
112 // Test that allocate can create an AHardwareBuffer correctly.
testAHardwareBuffer_allocate_Succeeds(JNIEnv * env)113 void AHardwareBufferTest::testAHardwareBuffer_allocate_Succeeds(JNIEnv* env) {
114     AHardwareBuffer* buffer = NULL;
115     AHardwareBuffer_Desc desc = {};
116 
117     desc.width = 2;
118     desc.height = 4;
119     desc.layers = 1;
120     desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
121     desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
122     int res = AHardwareBuffer_allocate(&desc, &buffer);
123     ASSERT_EQ(NO_ERROR, res);
124     ASSERT_EQ(std::string(), CheckAHardwareBufferMatchesDesc(buffer, desc));
125     AHardwareBuffer_release(buffer);
126     buffer = NULL;
127 
128     desc.width = 4;
129     desc.height = 12;
130     desc.layers = 1;
131     desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
132     desc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
133     res = AHardwareBuffer_allocate(&desc, &buffer);
134     ASSERT_EQ(NO_ERROR, res);
135     ASSERT_EQ(std::string(), CheckAHardwareBufferMatchesDesc(buffer, desc));
136     AHardwareBuffer_release(buffer);
137 }
138 
testAHardwareBuffer_describe_Succeeds(JNIEnv * env)139 void AHardwareBufferTest::testAHardwareBuffer_describe_Succeeds(JNIEnv* env) {
140     AHardwareBuffer* buffer = NULL;
141     AHardwareBuffer_Desc desc = {};
142 
143     desc.width = 2;
144     desc.height = 4;
145     desc.layers = 1;
146     desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
147     desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
148     int res = AHardwareBuffer_allocate(&desc, &buffer);
149     ASSERT_EQ(NO_ERROR, res);
150 
151     AHardwareBuffer_Desc expected_desc;
152     memset(&expected_desc, 0, sizeof(AHardwareBuffer_Desc));
153     AHardwareBuffer_describe(NULL, &desc);
154     ASSERT_EQ(0U, expected_desc.width);
155     AHardwareBuffer_describe(buffer, NULL);
156     ASSERT_EQ(0U, expected_desc.width);
157     AHardwareBuffer_describe(buffer, &desc);
158     ASSERT_EQ(std::string(), CheckAHardwareBufferMatchesDesc(buffer, desc));
159 
160     AHardwareBuffer_release(buffer);
161 }
162 
163 struct ClientData {
164     int fd;
165     JNIEnv* env;
166     AHardwareBuffer* buffer;
ClientDataandroid::ClientData167     ClientData(int fd_in, JNIEnv* env_in, AHardwareBuffer* buffer_in)
168             : fd(fd_in), env(env_in), buffer(buffer_in) {}
169 };
170 
clientFunction(void * data)171 static void* clientFunction(void* data) {
172     ClientData* pdata = reinterpret_cast<ClientData*>(data);
173     int err = AHardwareBuffer_sendHandleToUnixSocket(pdata->buffer, pdata->fd);
174     if (err != NO_ERROR) {
175         fail(pdata->env, "Error sending handle to socket: %d", err);
176     }
177     close(pdata->fd);
178     return 0;
179 }
180 
testAHardwareBuffer_SendAndRecv_Succeeds(JNIEnv * env)181 void AHardwareBufferTest::testAHardwareBuffer_SendAndRecv_Succeeds(JNIEnv* env) {
182     AHardwareBuffer* buffer = NULL;
183     AHardwareBuffer_Desc desc = {};
184 
185     desc.width = 2;
186     desc.height = 4;
187     desc.layers = 1;
188     desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
189     desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
190 
191     // Test that an invalid buffer fails.
192     int err = AHardwareBuffer_sendHandleToUnixSocket(NULL, 0);
193     ASSERT_EQ(BAD_VALUE, err);
194     err = 0;
195     err = AHardwareBuffer_sendHandleToUnixSocket(buffer, 0);
196     ASSERT_EQ(BAD_VALUE, err);
197 
198     // Allocate the buffer.
199     err = AHardwareBuffer_allocate(&desc, &buffer);
200     ASSERT_EQ(NO_ERROR, err);
201 
202     int fds[2];
203     err = socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds);
204 
205     // Launch a client that will send the buffer back.
206     ClientData data(fds[1], env, buffer);
207     pthread_t thread;
208     ASSERT_EQ(0, pthread_create(&thread, NULL, clientFunction, &data));
209 
210     // Receive the buffer.
211     err = AHardwareBuffer_recvHandleFromUnixSocket(fds[0], NULL);
212     ASSERT_EQ(BAD_VALUE, err);
213 
214     AHardwareBuffer* received = NULL;
215     err = AHardwareBuffer_recvHandleFromUnixSocket(fds[0], &received);
216     ASSERT_EQ(NO_ERROR, err);
217     ASSERT_TRUE(received != NULL);
218     ASSERT_EQ(std::string(), CheckAHardwareBufferMatchesDesc(received, desc));
219 
220     void* ret_val;
221     ASSERT_EQ(0, pthread_join(thread, &ret_val));
222     ASSERT_EQ(NULL, ret_val);
223     close(fds[0]);
224 
225     AHardwareBuffer_release(buffer);
226     AHardwareBuffer_release(received);
227 }
228 
testAHardwareBuffer_Lock_and_Unlock_Succeed(JNIEnv * env)229 void AHardwareBufferTest::testAHardwareBuffer_Lock_and_Unlock_Succeed(JNIEnv* env) {
230     AHardwareBuffer* buffer = NULL;
231     AHardwareBuffer_Desc desc = {};
232 
233     desc.width = 2;
234     desc.height = 4;
235     desc.layers = 1;
236     desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_CPU_READ_RARELY;
237     desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
238 
239     // Test that an invalid buffer fails.
240     int err = AHardwareBuffer_lock(NULL, 0, -1, NULL, NULL);
241     ASSERT_EQ(BAD_VALUE, err);
242     err = 0;
243 
244     // Allocate the buffer.
245     err = AHardwareBuffer_allocate(&desc, &buffer);
246     ASSERT_EQ(NO_ERROR, err);
247     void* bufferData = NULL;
248     err = AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, -1,
249           NULL, &bufferData);
250     ASSERT_EQ(NO_ERROR, err);
251     ASSERT_TRUE(bufferData != NULL);
252     int32_t fence = -1;
253     err = AHardwareBuffer_unlock(buffer, &fence);
254 
255     AHardwareBuffer_release(buffer);
256 }
257 
testAHardwareBufferSupportsLayeredBuffersForVr(JNIEnv * env)258 void AHardwareBufferTest::testAHardwareBufferSupportsLayeredBuffersForVr(JNIEnv* env) {
259     AHardwareBuffer* buffer = NULL;
260     AHardwareBuffer_Desc desc = {};
261 
262     desc.width = 2;
263     desc.height = 4;
264     desc.layers = 2;
265     desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
266     desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
267     int res = AHardwareBuffer_allocate(&desc, &buffer);
268     ASSERT_EQ(NO_ERROR, res);
269     ASSERT_EQ(std::string(), CheckAHardwareBufferMatchesDesc(buffer, desc));
270     AHardwareBuffer_release(buffer);
271     buffer = NULL;
272 
273     desc.width = 4;
274     desc.height = 12;
275     desc.layers = 3;
276     desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
277     desc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
278     res = AHardwareBuffer_allocate(&desc, &buffer);
279     ASSERT_EQ(NO_ERROR, res);
280     ASSERT_EQ(std::string(), CheckAHardwareBufferMatchesDesc(buffer, desc));
281 }
282 
283 } // namespace android
284