blob: b1f5d083c7a3c2227e56a28934650b499def3caa [file] [log] [blame]
Igor Murashkin7ea777f2013-11-18 16:58:36 -08001/*
2 * Copyright (C) 2013 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#define LOG_TAG "IGraphicBufferProducer_test"
18//#define LOG_NDEBUG 0
19
Nolan Scobie9c427942023-05-01 16:41:28 -040020#include "Constants.h"
Peiyong Lind8460c82020-07-28 16:04:22 -070021#include "MockConsumer.h"
Brian Anderson5ea5e592016-12-01 16:54:33 -080022
Igor Murashkin7ea777f2013-11-18 16:58:36 -080023#include <gtest/gtest.h>
24
25#include <utils/String8.h>
26#include <utils/threads.h>
27
28#include <ui/GraphicBuffer.h>
Igor Murashkin7ea777f2013-11-18 16:58:36 -080029
30#include <gui/BufferQueue.h>
Dan Stozaf0eaf252014-03-21 13:05:51 -070031#include <gui/IProducerListener.h>
Igor Murashkin7ea777f2013-11-18 16:58:36 -080032
Mathias Agopian6a3c05b2017-04-27 20:06:55 -070033#include <system/window.h>
34
Igor Murashkin7ea777f2013-11-18 16:58:36 -080035#include <vector>
36
37#define ASSERT_OK(x) ASSERT_EQ(OK, (x))
38#define EXPECT_OK(x) EXPECT_EQ(OK, (x))
39
Dan Stozaf0eaf252014-03-21 13:05:51 -070040#define TEST_TOKEN ((IProducerListener*)(NULL))
Igor Murashkin7ea777f2013-11-18 16:58:36 -080041#define TEST_API NATIVE_WINDOW_API_CPU
42#define TEST_API_OTHER NATIVE_WINDOW_API_EGL // valid API that's not TEST_API
43#define TEST_CONTROLLED_BY_APP false
Igor Murashkin7ea777f2013-11-18 16:58:36 -080044
Igor Murashkin7ea777f2013-11-18 16:58:36 -080045namespace android {
46
47namespace {
Dan Stozaf8cebe52015-04-20 12:09:38 -070048 // Default dimensions before setDefaultBufferSize is called
49 const uint32_t DEFAULT_WIDTH = 1;
50 const uint32_t DEFAULT_HEIGHT = 1;
51
52 // Default format before setDefaultBufferFormat is called
53 const PixelFormat DEFAULT_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888;
54
55 // Default transform hint before setTransformHint is called
56 const uint32_t DEFAULT_TRANSFORM_HINT = 0;
57
58 // TODO: Make these constants in header
59 const int DEFAULT_CONSUMER_USAGE_BITS = 0;
60
61 // Parameters for a generic "valid" input for queueBuffer.
62 const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611;
63 const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false;
64 const android_dataspace QUEUE_BUFFER_INPUT_DATASPACE = HAL_DATASPACE_UNKNOWN;
65 const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT);
66 const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0;
67 const int QUEUE_BUFFER_INPUT_TRANSFORM = 0;
Dan Stozaf8cebe52015-04-20 12:09:38 -070068 const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE;
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +070069 const uint32_t QUEUE_BUFFER_INPUT_STICKY_TRANSFORM = 0;
70 const bool QUEUE_BUFFER_INPUT_GET_TIMESTAMPS = 0;
71 const int QUEUE_BUFFER_INPUT_SLOT = -1;
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -080072
73 // Enums to control which IGraphicBufferProducer backend to test.
74 enum IGraphicBufferProducerTestCode {
75 USE_BUFFER_QUEUE_PRODUCER = 0,
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -080076 };
Igor Murashkin7ea777f2013-11-18 16:58:36 -080077}; // namespace anonymous
78
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -080079class IGraphicBufferProducerTest : public ::testing::TestWithParam<uint32_t> {
Igor Murashkin7ea777f2013-11-18 16:58:36 -080080protected:
81
82 IGraphicBufferProducerTest() {}
83
84 virtual void SetUp() {
Peiyong Lind8460c82020-07-28 16:04:22 -070085 mMC = new MockConsumer;
Igor Murashkin7ea777f2013-11-18 16:58:36 -080086
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -080087 switch (GetParam()) {
88 case USE_BUFFER_QUEUE_PRODUCER: {
89 BufferQueue::createBufferQueue(&mProducer, &mConsumer);
90 break;
91 }
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -080092 default: {
93 // Should never reach here.
94 LOG_ALWAYS_FATAL("Invalid test params: %u", GetParam());
95 break;
96 }
97 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -080098
99 // Test check: Can't connect producer if no consumer yet
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800100 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
101 // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
102 ASSERT_EQ(NO_INIT, TryConnectProducer());
103 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800104
105 // Must connect consumer before producer connects will succeed.
Peiyong Lind8460c82020-07-28 16:04:22 -0700106 ASSERT_OK(mConsumer->consumerConnect(mMC, /*controlledByApp*/ false));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800107 }
108
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800109 status_t TryConnectProducer() {
110 IGraphicBufferProducer::QueueBufferOutput output;
111 return mProducer->connect(TEST_TOKEN,
112 TEST_API,
113 TEST_CONTROLLED_BY_APP,
114 &output);
115 // TODO: use params to vary token, api, producercontrolledbyapp, etc
116 }
117
118 // Connect to a producer in a 'correct' fashion.
119 // Precondition: Consumer is connected.
120 void ConnectProducer() {
121 ASSERT_OK(TryConnectProducer());
122 }
123
124 // Create a generic "valid" input for queueBuffer
125 // -- uses the default buffer format, width, etc.
126 static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
127 return QueueBufferInputBuilder().build();
128 }
129
130 // Builder pattern to slightly vary *almost* correct input
131 // -- avoids copying and pasting
132 struct QueueBufferInputBuilder {
133 QueueBufferInputBuilder() {
134 timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP;
135 isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP;
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800136 dataSpace = QUEUE_BUFFER_INPUT_DATASPACE;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800137 crop = QUEUE_BUFFER_INPUT_RECT;
138 scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE;
139 transform = QUEUE_BUFFER_INPUT_TRANSFORM;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800140 fence = QUEUE_BUFFER_INPUT_FENCE;
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700141 stickyTransform = QUEUE_BUFFER_INPUT_STICKY_TRANSFORM;
142 getTimestamps = QUEUE_BUFFER_INPUT_GET_TIMESTAMPS;
143 slot = QUEUE_BUFFER_INPUT_SLOT;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800144 }
145
146 IGraphicBufferProducer::QueueBufferInput build() {
147 return IGraphicBufferProducer::QueueBufferInput(
148 timestamp,
149 isAutoTimestamp,
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800150 dataSpace,
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800151 crop,
152 scalingMode,
153 transform,
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700154 fence,
155 stickyTransform,
156 getTimestamps,
157 slot);
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800158 }
159
160 QueueBufferInputBuilder& setTimestamp(int64_t timestamp) {
161 this->timestamp = timestamp;
162 return *this;
163 }
164
165 QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) {
166 this->isAutoTimestamp = isAutoTimestamp;
167 return *this;
168 }
169
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800170 QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
171 this->dataSpace = dataSpace;
172 return *this;
173 }
174
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800175 QueueBufferInputBuilder& setCrop(Rect crop) {
176 this->crop = crop;
177 return *this;
178 }
179
180 QueueBufferInputBuilder& setScalingMode(int scalingMode) {
181 this->scalingMode = scalingMode;
182 return *this;
183 }
184
185 QueueBufferInputBuilder& setTransform(uint32_t transform) {
186 this->transform = transform;
187 return *this;
188 }
189
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800190 QueueBufferInputBuilder& setFence(sp<Fence> fence) {
191 this->fence = fence;
192 return *this;
193 }
194
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700195 QueueBufferInputBuilder& setStickyTransform(uint32_t stickyTransform) {
196 this->stickyTransform = stickyTransform;
197 return *this;
198 }
199
200 QueueBufferInputBuilder& setGetTimestamps(bool getTimestamps) {
201 this->getTimestamps = getTimestamps;
202 return *this;
203 }
204
205 QueueBufferInputBuilder& setSlot(int slot) {
206 this->slot = slot;
207 return *this;
208 }
209
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800210 private:
211 int64_t timestamp;
212 bool isAutoTimestamp;
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800213 android_dataspace dataSpace;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800214 Rect crop;
215 int scalingMode;
216 uint32_t transform;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800217 sp<Fence> fence;
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700218 uint32_t stickyTransform;
219 bool getTimestamps;
220 int slot;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800221 }; // struct QueueBufferInputBuilder
222
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700223 status_t dequeueBuffer(uint32_t w, uint32_t h, uint32_t format, uint32_t usage,
224 IGraphicBufferProducer::DequeueBufferOutput* result) {
225 result->result =
226 mProducer->dequeueBuffer(&result->slot, &result->fence, w, h, format, usage,
227 &result->bufferAge, nullptr);
228 return result->result;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800229 }
230
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700231 void setupDequeueRequestBuffer(int *slot, sp<Fence> *fence,
232 sp<GraphicBuffer> *buffer)
233 {
Yi Konga03e0442018-07-17 11:16:57 -0700234 ASSERT_TRUE(slot != nullptr);
235 ASSERT_TRUE(fence != nullptr);
236 ASSERT_TRUE(buffer != nullptr);
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700237
238 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
239
Ian Elliottd11b0442017-07-18 11:05:49 -0600240
241 ASSERT_EQ(OK,
242 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
243 (mProducer->dequeueBuffer(slot, fence, DEFAULT_WIDTH, DEFAULT_HEIGHT,
244 DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS,
245 nullptr, nullptr)));
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700246
247 EXPECT_LE(0, *slot);
248 EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, *slot);
249
250 // Request the buffer (pre-requisite for queueing)
251 ASSERT_OK(mProducer->requestBuffer(*slot, buffer));
252 }
253
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800254private: // hide from test body
Peiyong Lind8460c82020-07-28 16:04:22 -0700255 sp<MockConsumer> mMC;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800256
257protected: // accessible from test body
258 sp<IGraphicBufferProducer> mProducer;
259 sp<IGraphicBufferConsumer> mConsumer;
260};
261
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800262TEST_P(IGraphicBufferProducerTest, ConnectFirst_ReturnsError) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800263 IGraphicBufferProducer::QueueBufferOutput output;
264
265 // NULL output returns BAD_VALUE
266 EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
267 TEST_API,
268 TEST_CONTROLLED_BY_APP,
Yi Konga03e0442018-07-17 11:16:57 -0700269 /*output*/nullptr));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800270
271 // Invalid API returns bad value
272 EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
273 /*api*/0xDEADBEEF,
274 TEST_CONTROLLED_BY_APP,
275 &output));
276
277 // TODO: get a token from a dead process somehow
278}
279
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800280TEST_P(IGraphicBufferProducerTest, ConnectAgain_ReturnsError) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800281 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
282
283 // Can't connect when there is already a producer connected
284 IGraphicBufferProducer::QueueBufferOutput output;
285 EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
286 TEST_API,
287 TEST_CONTROLLED_BY_APP,
288 &output));
289
290 ASSERT_OK(mConsumer->consumerDisconnect());
291 // Can't connect when IGBP is abandoned
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800292 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
293 // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
294 EXPECT_EQ(NO_INIT, mProducer->connect(TEST_TOKEN,
295 TEST_API,
296 TEST_CONTROLLED_BY_APP,
297 &output));
298 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800299}
300
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800301TEST_P(IGraphicBufferProducerTest, Disconnect_Succeeds) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800302 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
303
304 ASSERT_OK(mProducer->disconnect(TEST_API));
305}
306
307
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800308TEST_P(IGraphicBufferProducerTest, Disconnect_ReturnsError) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800309 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
310
311 // Must disconnect with same API number
312 ASSERT_EQ(BAD_VALUE, mProducer->disconnect(TEST_API_OTHER));
313 // API must not be out of range
314 ASSERT_EQ(BAD_VALUE, mProducer->disconnect(/*api*/0xDEADBEEF));
315
316 // TODO: somehow kill mProducer so that this returns DEAD_OBJECT
317}
318
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800319TEST_P(IGraphicBufferProducerTest, Query_Succeeds) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800320 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
321
Dan Stozaf8cebe52015-04-20 12:09:38 -0700322 int32_t value = -1;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800323 EXPECT_OK(mProducer->query(NATIVE_WINDOW_WIDTH, &value));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700324 EXPECT_EQ(DEFAULT_WIDTH, static_cast<uint32_t>(value));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800325
326 EXPECT_OK(mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700327 EXPECT_EQ(DEFAULT_HEIGHT, static_cast<uint32_t>(value));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800328
329 EXPECT_OK(mProducer->query(NATIVE_WINDOW_FORMAT, &value));
330 EXPECT_EQ(DEFAULT_FORMAT, value);
331
332 EXPECT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value));
333 EXPECT_LE(0, value);
334 EXPECT_GE(BufferQueue::NUM_BUFFER_SLOTS, value);
335
336 EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value));
337 EXPECT_FALSE(value); // Can't run behind when we haven't touched the queue
338
339 EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value));
340 EXPECT_EQ(DEFAULT_CONSUMER_USAGE_BITS, value);
341
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700342 { // Test the batched version
343 std::vector<int32_t> inputs = {
344 NATIVE_WINDOW_WIDTH,
345 NATIVE_WINDOW_HEIGHT,
346 NATIVE_WINDOW_FORMAT,
347 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
348 NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND,
349 NATIVE_WINDOW_CONSUMER_USAGE_BITS };
350 using QueryOutput = IGraphicBufferProducer::QueryOutput;
351 std::vector<QueryOutput> outputs;
352 EXPECT_OK(mProducer->query(inputs, &outputs));
353 EXPECT_EQ(DEFAULT_WIDTH, static_cast<uint32_t>(outputs[0].value));
354 EXPECT_EQ(DEFAULT_HEIGHT, static_cast<uint32_t>(outputs[1].value));
355 EXPECT_EQ(DEFAULT_FORMAT, outputs[2].value);
356 EXPECT_LE(0, outputs[3].value);
357 EXPECT_FALSE(outputs[4].value);
358 EXPECT_EQ(DEFAULT_CONSUMER_USAGE_BITS, outputs[5].value);
359 for (const QueryOutput& output : outputs) {
360 EXPECT_OK(output.result);
361 }
362 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800363}
364
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800365TEST_P(IGraphicBufferProducerTest, Query_ReturnsError) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800366 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
367
368 // One past the end of the last 'query' enum value. Update this if we add more enums.
Michael Lentined8ead0c2015-05-19 15:23:43 -0700369 const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800370
371 int value;
372 // What was out of range
373 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/-1, &value));
374 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/0xDEADBEEF, &value));
375 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value));
376
377 // Some enums from window.h are 'invalid'
378 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value));
379 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value));
380 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value));
381 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value));
382 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value));
383 // TODO: Consider documented the above enums as unsupported or make a new enum for IGBP
384
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700385 { // Test the batched version
386 std::vector<int32_t> inputs = {
387 -1,
388 static_cast<int32_t>(0xDEADBEEF),
389 NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE,
390 NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
391 NATIVE_WINDOW_CONCRETE_TYPE,
392 NATIVE_WINDOW_DEFAULT_WIDTH,
393 NATIVE_WINDOW_DEFAULT_HEIGHT,
394 NATIVE_WINDOW_TRANSFORM_HINT};
395 using QueryOutput = IGraphicBufferProducer::QueryOutput;
396 std::vector<QueryOutput> outputs;
397 EXPECT_OK(mProducer->query(inputs, &outputs));
398 for (const QueryOutput& output : outputs) {
399 EXPECT_EQ(BAD_VALUE, output.result);
400 }
401 }
402
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800403 // Value was NULL
Yi Konga03e0442018-07-17 11:16:57 -0700404 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/nullptr));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800405
406 ASSERT_OK(mConsumer->consumerDisconnect());
407
408 // BQ was abandoned
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800409 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
410 // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
411 EXPECT_EQ(NO_INIT, mProducer->query(NATIVE_WINDOW_FORMAT, &value));
412 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800413
414 // TODO: other things in window.h that are supported by Surface::query
415 // but not by BufferQueue::query
416}
417
418// TODO: queue under more complicated situations not involving just a single buffer
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800419TEST_P(IGraphicBufferProducerTest, Queue_Succeeds) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800420 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
421
422 int dequeuedSlot = -1;
423 sp<Fence> dequeuedFence;
424
Ian Elliottd11b0442017-07-18 11:05:49 -0600425 ASSERT_EQ(OK,
426 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
427 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
428 DEFAULT_HEIGHT, DEFAULT_FORMAT,
429 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800430
431 EXPECT_LE(0, dequeuedSlot);
432 EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, dequeuedSlot);
433
434 // Request the buffer (pre-requisite for queueing)
435 sp<GraphicBuffer> dequeuedBuffer;
436 ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
437
438 // A generic "valid" input
439 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
440 IGraphicBufferProducer::QueueBufferOutput output;
441
442 // Queue the buffer back into the BQ
443 ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output));
444
445 {
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700446 EXPECT_EQ(DEFAULT_WIDTH, output.width);
447 EXPECT_EQ(DEFAULT_HEIGHT, output.height);
448 EXPECT_EQ(DEFAULT_TRANSFORM_HINT, output.transformHint);
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800449
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700450 // Since queueBuffer was called exactly once
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800451 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
452 // TODO(b/70041889): BufferHubProducer need to support metadata: numPendingBuffers
453 EXPECT_EQ(1u, output.numPendingBuffers);
454 // TODO(b/70041952): BufferHubProducer need to support metadata: nextFrameNumber
455 EXPECT_EQ(2u, output.nextFrameNumber);
456 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800457 }
458
459 // Buffer was not in the dequeued state
460 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700461
462 { // Test batched methods
463 constexpr size_t BATCH_SIZE = 4;
464
465 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(BATCH_SIZE));
466 // Dequeue
467 using DequeueBufferInput = IGraphicBufferProducer::DequeueBufferInput;
468 using DequeueBufferOutput = IGraphicBufferProducer::DequeueBufferOutput;
469 DequeueBufferInput dequeueInput;
470 dequeueInput.width = DEFAULT_WIDTH;
471 dequeueInput.height = DEFAULT_HEIGHT;
472 dequeueInput.format = DEFAULT_FORMAT;
473 dequeueInput.usage = TEST_PRODUCER_USAGE_BITS;
474 dequeueInput.getTimestamps = false;
475 std::vector<DequeueBufferInput> dequeueInputs(BATCH_SIZE, dequeueInput);
476 std::vector<DequeueBufferOutput> dequeueOutputs;
477 EXPECT_OK(mProducer->dequeueBuffers(dequeueInputs, &dequeueOutputs));
478 ASSERT_EQ(dequeueInputs.size(), dequeueOutputs.size());
479
480 // Request
481 std::vector<int32_t> requestInputs;
482 requestInputs.reserve(BATCH_SIZE);
483 for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
484 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
485 dequeueOutput.result);
486 requestInputs.emplace_back(dequeueOutput.slot);
487 }
488 using RequestBufferOutput = IGraphicBufferProducer::RequestBufferOutput;
489 std::vector<RequestBufferOutput> requestOutputs;
490 EXPECT_OK(mProducer->requestBuffers(requestInputs, &requestOutputs));
491 ASSERT_EQ(requestInputs.size(), requestOutputs.size());
492 for (const RequestBufferOutput& requestOutput : requestOutputs) {
493 EXPECT_OK(requestOutput.result);
494 }
495
496 // Queue
497 using QueueBufferInput = IGraphicBufferProducer::QueueBufferInput;
498 using QueueBufferOutput = IGraphicBufferProducer::QueueBufferOutput;
499 std::vector<QueueBufferInput> queueInputs;
500 queueInputs.reserve(BATCH_SIZE);
501 for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
502 queueInputs.emplace_back(CreateBufferInput()).slot =
503 dequeueOutput.slot;
504 }
505 std::vector<QueueBufferOutput> queueOutputs;
506 EXPECT_OK(mProducer->queueBuffers(queueInputs, &queueOutputs));
507 ASSERT_EQ(queueInputs.size(), queueOutputs.size());
508 for (const QueueBufferOutput& queueOutput : queueOutputs) {
509 EXPECT_OK(queueOutput.result);
510 }
511
512 // Re-queue
513 EXPECT_OK(mProducer->queueBuffers(queueInputs, &queueOutputs));
514 ASSERT_EQ(queueInputs.size(), queueOutputs.size());
515 for (const QueueBufferOutput& queueOutput : queueOutputs) {
516 EXPECT_EQ(BAD_VALUE, queueOutput.result);
517 }
518 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800519}
520
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800521TEST_P(IGraphicBufferProducerTest, Queue_ReturnsError) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800522 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
523
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700524 using QueueBufferInput = IGraphicBufferProducer::QueueBufferInput;
525 using QueueBufferOutput = IGraphicBufferProducer::QueueBufferOutput;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800526 // Invalid slot number
527 {
528 // A generic "valid" input
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700529 QueueBufferInput input = CreateBufferInput();
530 QueueBufferOutput output;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800531
532 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/-1, input, &output));
533 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0xDEADBEEF, input, &output));
534 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueue::NUM_BUFFER_SLOTS,
535 input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700536
537 { // Test with the batched version
538 constexpr size_t BATCH_SIZE = 16;
539 input.slot = -1;
540 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
541 std::vector<QueueBufferOutput> outputs;
542 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
543 ASSERT_EQ(inputs.size(), outputs.size());
544 for (const QueueBufferOutput& output : outputs) {
545 EXPECT_EQ(BAD_VALUE, output.result);
546 }
547 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800548 }
549
550 // Slot was not in the dequeued state (all slots start out in Free state)
551 {
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700552 QueueBufferInput input = CreateBufferInput();
553 QueueBufferOutput output;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800554
555 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700556
557 { // Test with the batched version
558 constexpr size_t BATCH_SIZE = 16;
559 input.slot = 0;
560 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
561 std::vector<QueueBufferOutput> outputs;
562 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
563 ASSERT_EQ(inputs.size(), outputs.size());
564 for (const QueueBufferOutput& output : outputs) {
565 EXPECT_EQ(BAD_VALUE, output.result);
566 }
567 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800568 }
569
570 // Put the slot into the "dequeued" state for the rest of the test
571 int dequeuedSlot = -1;
572 sp<Fence> dequeuedFence;
573
Ian Elliottd11b0442017-07-18 11:05:49 -0600574 ASSERT_EQ(OK,
575 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
576 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
577 DEFAULT_HEIGHT, DEFAULT_FORMAT,
578 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800579
580 // Slot was enqueued without requesting a buffer
581 {
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700582 QueueBufferInput input = CreateBufferInput();
583 QueueBufferOutput output;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800584
585 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700586
587 { // Test with the batched version
588 constexpr size_t BATCH_SIZE = 16;
589 input.slot = dequeuedSlot;
590 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
591 std::vector<QueueBufferOutput> outputs;
592 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
593 ASSERT_EQ(inputs.size(), outputs.size());
594 for (const QueueBufferOutput& output : outputs) {
595 EXPECT_EQ(BAD_VALUE, output.result);
596 }
597 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800598 }
599
600 // Request the buffer so that the rest of the tests don't fail on earlier checks.
601 sp<GraphicBuffer> dequeuedBuffer;
602 ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
603
604 // Fence was NULL
605 {
Yi Konga03e0442018-07-17 11:16:57 -0700606 sp<Fence> nullFence = nullptr;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800607
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700608 QueueBufferInput input =
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800609 QueueBufferInputBuilder().setFence(nullFence).build();
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700610 QueueBufferOutput output;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800611
612 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700613
614 { // Test with the batched version
615 constexpr size_t BATCH_SIZE = 16;
616 input.slot = dequeuedSlot;
617 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
618 std::vector<QueueBufferOutput> outputs;
619 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
620 ASSERT_EQ(inputs.size(), outputs.size());
621 for (const QueueBufferOutput& output : outputs) {
622 EXPECT_EQ(BAD_VALUE, output.result);
623 }
624 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800625 }
626
627 // Scaling mode was unknown
628 {
629 IGraphicBufferProducer::QueueBufferInput input =
630 QueueBufferInputBuilder().setScalingMode(-1).build();
631 IGraphicBufferProducer::QueueBufferOutput output;
632
633 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
634
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700635 { // Test with the batched version
636 constexpr size_t BATCH_SIZE = 16;
637 input.slot = dequeuedSlot;
638 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
639 std::vector<QueueBufferOutput> outputs;
640 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
641 ASSERT_EQ(inputs.size(), outputs.size());
642 for (const QueueBufferOutput& output : outputs) {
643 EXPECT_EQ(BAD_VALUE, output.result);
644 }
645 }
646
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800647 input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build();
648
649 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700650
651 { // Test with the batched version
652 constexpr size_t BATCH_SIZE = 16;
653 input.slot = dequeuedSlot;
654 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
655 std::vector<QueueBufferOutput> outputs;
656 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
657 ASSERT_EQ(inputs.size(), outputs.size());
658 for (const QueueBufferOutput& output : outputs) {
659 EXPECT_EQ(BAD_VALUE, output.result);
660 }
661 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800662 }
663
664 // Crop rect is out of bounds of the buffer dimensions
665 {
666 IGraphicBufferProducer::QueueBufferInput input =
667 QueueBufferInputBuilder().setCrop(Rect(DEFAULT_WIDTH + 1, DEFAULT_HEIGHT + 1))
668 .build();
669 IGraphicBufferProducer::QueueBufferOutput output;
670
671 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700672
673 { // Test with the batched version
674 constexpr size_t BATCH_SIZE = 16;
675 input.slot = dequeuedSlot;
676 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
677 std::vector<QueueBufferOutput> outputs;
678 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
679 ASSERT_EQ(inputs.size(), outputs.size());
680 for (const QueueBufferOutput& output : outputs) {
681 EXPECT_EQ(BAD_VALUE, output.result);
682 }
683 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800684 }
685
686 // Abandon the buffer queue so that the last test fails
687 ASSERT_OK(mConsumer->consumerDisconnect());
688
689 // The buffer queue has been abandoned.
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800690 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800691 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
692 IGraphicBufferProducer::QueueBufferOutput output;
693
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800694 // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800695 EXPECT_EQ(NO_INIT, mProducer->queueBuffer(dequeuedSlot, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700696
697 { // Test with the batched version
698 constexpr size_t BATCH_SIZE = 16;
699 input.slot = dequeuedSlot;
700 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
701 std::vector<QueueBufferOutput> outputs;
702 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
703 ASSERT_EQ(inputs.size(), outputs.size());
704 for (const QueueBufferOutput& output : outputs) {
705 EXPECT_EQ(NO_INIT, output.result);
706 }
707 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800708 }
709}
710
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800711TEST_P(IGraphicBufferProducerTest, CancelBuffer_DoesntCrash) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800712 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
713
714 int dequeuedSlot = -1;
715 sp<Fence> dequeuedFence;
716
Ian Elliottd11b0442017-07-18 11:05:49 -0600717 ASSERT_EQ(OK,
718 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
719 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
720 DEFAULT_HEIGHT, DEFAULT_FORMAT,
721 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800722
723 // No return code, but at least test that it doesn't blow up...
724 // TODO: add a return code
725 mProducer->cancelBuffer(dequeuedSlot, dequeuedFence);
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700726
727 { // Test batched methods
728 constexpr size_t BATCH_SIZE = 4;
729 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(BATCH_SIZE));
730
731 // Dequeue
732 using DequeueBufferInput = IGraphicBufferProducer::DequeueBufferInput;
733 using DequeueBufferOutput = IGraphicBufferProducer::DequeueBufferOutput;
734 DequeueBufferInput dequeueInput;
735 dequeueInput.width = DEFAULT_WIDTH;
736 dequeueInput.height = DEFAULT_HEIGHT;
737 dequeueInput.format = DEFAULT_FORMAT;
738 dequeueInput.usage = TEST_PRODUCER_USAGE_BITS;
739 dequeueInput.getTimestamps = false;
740 std::vector<DequeueBufferInput> dequeueInputs(BATCH_SIZE, dequeueInput);
741 std::vector<DequeueBufferOutput> dequeueOutputs;
742 EXPECT_OK(mProducer->dequeueBuffers(dequeueInputs, &dequeueOutputs));
743 ASSERT_EQ(dequeueInputs.size(), dequeueOutputs.size());
744
745 // Cancel
746 using CancelBufferInput = IGraphicBufferProducer::CancelBufferInput;
747 std::vector<CancelBufferInput> cancelInputs;
748 cancelInputs.reserve(BATCH_SIZE);
749 for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
750 ASSERT_EQ(OK,
751 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
752 dequeueOutput.result);
753 CancelBufferInput& cancelInput = cancelInputs.emplace_back();
754 cancelInput.slot = dequeueOutput.slot;
755 cancelInput.fence = dequeueOutput.fence;
756 }
757 std::vector<status_t> cancelOutputs;
758 EXPECT_OK(mProducer->cancelBuffers(cancelInputs, &cancelOutputs));
759 ASSERT_EQ(cancelInputs.size(), cancelOutputs.size());
760 for (status_t result : cancelOutputs) {
761 EXPECT_OK(result);
762 }
763 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800764}
765
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800766TEST_P(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Succeeds) {
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700767 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
Pablo Ceballosfa455352015-08-12 17:47:47 -0700768 int minUndequeuedBuffers;
769 ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
770 &minUndequeuedBuffers));
771
772 const int minBuffers = 1;
773 const int maxBuffers = BufferQueue::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
774
775 ASSERT_OK(mProducer->setAsyncMode(false)) << "async mode: " << false;
776 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(minBuffers))
777 << "bufferCount: " << minBuffers;
778
Pablo Ceballosfa455352015-08-12 17:47:47 -0700779 // Should now be able to dequeue up to minBuffers times
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700780 IGraphicBufferProducer::DequeueBufferOutput result;
Pablo Ceballosfa455352015-08-12 17:47:47 -0700781 for (int i = 0; i < minBuffers; ++i) {
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700782 EXPECT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700783 (dequeueBuffer(DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700784 TEST_PRODUCER_USAGE_BITS, &result)))
Pablo Ceballosfa455352015-08-12 17:47:47 -0700785 << "iteration: " << i << ", slot: " << result.slot;
Pablo Ceballosfa455352015-08-12 17:47:47 -0700786 }
787
788 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(maxBuffers));
789
Pablo Ceballos72daab62015-12-07 16:38:43 -0800790 // queue the first buffer to enable max dequeued buffer count checking
791 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
792 IGraphicBufferProducer::QueueBufferOutput output;
793 sp<GraphicBuffer> buffer;
794 ASSERT_OK(mProducer->requestBuffer(result.slot, &buffer));
795 ASSERT_OK(mProducer->queueBuffer(result.slot, input, &output));
796
Pablo Ceballosfa455352015-08-12 17:47:47 -0700797 // Should now be able to dequeue up to maxBuffers times
Pablo Ceballos72daab62015-12-07 16:38:43 -0800798 int dequeuedSlot = -1;
799 sp<Fence> dequeuedFence;
Pablo Ceballosfa455352015-08-12 17:47:47 -0700800 for (int i = 0; i < maxBuffers; ++i) {
Ian Elliottd11b0442017-07-18 11:05:49 -0600801 EXPECT_EQ(OK,
802 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
803 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
804 DEFAULT_HEIGHT, DEFAULT_FORMAT,
805 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
Pablo Ceballosfa455352015-08-12 17:47:47 -0700806 << "iteration: " << i << ", slot: " << dequeuedSlot;
807 }
Pablo Ceballos72daab62015-12-07 16:38:43 -0800808
809 // Cancel a buffer, so we can decrease the buffer count
810 ASSERT_OK(mProducer->cancelBuffer(dequeuedSlot, dequeuedFence));
811
812 // Should now be able to decrease the max dequeued count by 1
813 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(maxBuffers-1));
Pablo Ceballosfa455352015-08-12 17:47:47 -0700814}
815
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800816TEST_P(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Fails) {
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700817 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
Pablo Ceballosfa455352015-08-12 17:47:47 -0700818 int minUndequeuedBuffers;
819 ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
820 &minUndequeuedBuffers));
821
822 const int minBuffers = 1;
823 const int maxBuffers = BufferQueue::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
824
825 ASSERT_OK(mProducer->setAsyncMode(false)) << "async mode: " << false;
826 // Buffer count was out of range
827 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(0))
828 << "bufferCount: " << 0;
829 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(maxBuffers + 1))
830 << "bufferCount: " << maxBuffers + 1;
831
Pablo Ceballos72daab62015-12-07 16:38:43 -0800832 // Set max dequeue count to 2
833 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(2));
834 // Dequeue 2 buffers
835 int dequeuedSlot = -1;
836 sp<Fence> dequeuedFence;
837 for (int i = 0; i < 2; i++) {
Ian Elliottd11b0442017-07-18 11:05:49 -0600838 ASSERT_EQ(OK,
839 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
840 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
841 DEFAULT_HEIGHT, DEFAULT_FORMAT,
842 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
Pablo Ceballosfa455352015-08-12 17:47:47 -0700843 << "slot: " << dequeuedSlot;
844 }
845
Pablo Ceballos72daab62015-12-07 16:38:43 -0800846 // Client has too many buffers dequeued
847 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1))
Pablo Ceballosfa455352015-08-12 17:47:47 -0700848 << "bufferCount: " << minBuffers;
849
850 // Abandon buffer queue
851 ASSERT_OK(mConsumer->consumerDisconnect());
852
853 // Fail because the buffer queue was abandoned
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800854 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
855 // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
856 EXPECT_EQ(NO_INIT, mProducer->setMaxDequeuedBufferCount(minBuffers))
857 << "bufferCount: " << minBuffers;
858 }
Pablo Ceballosfa455352015-08-12 17:47:47 -0700859}
860
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800861TEST_P(IGraphicBufferProducerTest, SetAsyncMode_Succeeds) {
Pablo Ceballosfa455352015-08-12 17:47:47 -0700862 ASSERT_OK(mConsumer->setMaxAcquiredBufferCount(1)) << "maxAcquire: " << 1;
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700863 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
Pablo Ceballosfa455352015-08-12 17:47:47 -0700864 ASSERT_OK(mProducer->setAsyncMode(true)) << "async mode: " << true;
865 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(1)) << "maxDequeue: " << 1;
866
867 int dequeuedSlot = -1;
868 sp<Fence> dequeuedFence;
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700869 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
Pablo Ceballosfa455352015-08-12 17:47:47 -0700870 IGraphicBufferProducer::QueueBufferOutput output;
871 sp<GraphicBuffer> dequeuedBuffer;
872
873 // Should now be able to queue/dequeue as many buffers as we want without
874 // blocking
875 for (int i = 0; i < 5; ++i) {
Ian Elliottd11b0442017-07-18 11:05:49 -0600876 ASSERT_EQ(OK,
877 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
878 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
879 DEFAULT_HEIGHT, DEFAULT_FORMAT,
880 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700881 << "slot : " << dequeuedSlot;
Pablo Ceballosfa455352015-08-12 17:47:47 -0700882 ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
883 ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output));
884 }
885}
886
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800887TEST_P(IGraphicBufferProducerTest, SetAsyncMode_Fails) {
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700888 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
Pablo Ceballosfa455352015-08-12 17:47:47 -0700889 // Prerequisite to fail out a valid setBufferCount call
890 {
891 int dequeuedSlot = -1;
892 sp<Fence> dequeuedFence;
893
Ian Elliottd11b0442017-07-18 11:05:49 -0600894 ASSERT_EQ(OK,
895 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
896 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
897 DEFAULT_HEIGHT, DEFAULT_FORMAT,
898 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700899 << "slot: " << dequeuedSlot;
Pablo Ceballosfa455352015-08-12 17:47:47 -0700900 }
901
Pablo Ceballosfa455352015-08-12 17:47:47 -0700902 // Abandon buffer queue
903 ASSERT_OK(mConsumer->consumerDisconnect());
904
905 // Fail because the buffer queue was abandoned
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800906 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
907 // TODO(b/36724099): Make BufferHub honor producer and consumer connection.
908 EXPECT_EQ(NO_INIT, mProducer->setAsyncMode(false)) << "asyncMode: " << false;
909 }
Pablo Ceballosfa455352015-08-12 17:47:47 -0700910}
911
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800912TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700913 DisconnectedProducerReturnsError_dequeueBuffer) {
914 int slot = -1;
915 sp<Fence> fence;
916
Ian Elliottd11b0442017-07-18 11:05:49 -0600917 ASSERT_EQ(NO_INIT,
918 mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
919 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr));
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700920}
921
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800922TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700923 DisconnectedProducerReturnsError_detachNextBuffer) {
924 sp<Fence> fence;
925 sp<GraphicBuffer> buffer;
926
Jiwen 'Steve' Cai42875352018-04-30 17:55:11 -0700927 ASSERT_EQ(NO_INIT, mProducer->detachNextBuffer(&buffer, &fence));
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700928}
929
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800930TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700931 DisconnectedProducerReturnsError_requestBuffer) {
932 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
933
934 int slot = -1;
935 sp<Fence> fence;
936
Ian Elliottd11b0442017-07-18 11:05:49 -0600937 ASSERT_EQ(OK,
938 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
939 (mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, DEFAULT_HEIGHT,
940 DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS,
941 nullptr, nullptr)));
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700942
943 EXPECT_LE(0, slot);
944 EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, slot);
945
946 ASSERT_OK(mProducer->disconnect(TEST_API));
947
948 sp<GraphicBuffer> buffer;
949
950 ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer));
951}
952
953
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800954TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700955 DisconnectedProducerReturnsError_detachBuffer) {
956 int slot = -1;
957 sp<Fence> fence;
958 sp<GraphicBuffer> buffer;
959
960 setupDequeueRequestBuffer(&slot, &fence, &buffer);
961
962 ASSERT_OK(mProducer->disconnect(TEST_API));
963
Jiwen 'Steve' Cai42875352018-04-30 17:55:11 -0700964 ASSERT_EQ(NO_INIT, mProducer->detachBuffer(slot));
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700965}
966
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800967TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700968 DisconnectedProducerReturnsError_queueBuffer) {
969 int slot = -1;
970 sp<Fence> fence;
971 sp<GraphicBuffer> buffer;
972
973 setupDequeueRequestBuffer(&slot, &fence, &buffer);
974
975 ASSERT_OK(mProducer->disconnect(TEST_API));
976
977 // A generic "valid" input
978 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
979 IGraphicBufferProducer::QueueBufferOutput output;
980
981 ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output));
982}
983
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800984TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700985 DisconnectedProducerReturnsError_cancelBuffer) {
986 int slot = -1;
987 sp<Fence> fence;
988 sp<GraphicBuffer> buffer;
989
990 setupDequeueRequestBuffer(&slot, &fence, &buffer);
991
992 ASSERT_OK(mProducer->disconnect(TEST_API));
993
994 ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, fence));
995}
996
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800997TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700998 DisconnectedProducerReturnsError_attachBuffer) {
999 int slot = -1;
1000 sp<Fence> fence;
1001 sp<GraphicBuffer> buffer;
1002
1003 setupDequeueRequestBuffer(&slot, &fence, &buffer);
Jiwen 'Steve' Cai42875352018-04-30 17:55:11 -07001004 ASSERT_TRUE(buffer != nullptr);
Pablo Ceballos583b1b32015-09-03 18:23:52 -07001005
Jiwen 'Steve' Cai42875352018-04-30 17:55:11 -07001006 ASSERT_OK(mProducer->detachBuffer(slot));
1007 EXPECT_OK(buffer->initCheck());
1008
Pablo Ceballos583b1b32015-09-03 18:23:52 -07001009 ASSERT_OK(mProducer->disconnect(TEST_API));
1010
Jiwen 'Steve' Cai57ae3ee2018-05-03 17:51:52 -07001011 ASSERT_EQ(NO_INIT, mProducer->attachBuffer(&slot, buffer));
1012}
1013
1014TEST_P(IGraphicBufferProducerTest, DetachThenAttach_Succeeds) {
1015 int slot = -1;
1016 sp<Fence> fence;
1017 sp<GraphicBuffer> buffer;
1018
1019 setupDequeueRequestBuffer(&slot, &fence, &buffer);
1020 ASSERT_TRUE(buffer != nullptr);
1021
1022 ASSERT_OK(mProducer->detachBuffer(slot));
1023 EXPECT_OK(buffer->initCheck());
1024
Jiwen 'Steve' Cai57ae3ee2018-05-03 17:51:52 -07001025 EXPECT_OK(mProducer->attachBuffer(&slot, buffer));
Jiwen 'Steve' Cai57ae3ee2018-05-03 17:51:52 -07001026 EXPECT_OK(buffer->initCheck());
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +07001027
1028 ASSERT_OK(mProducer->detachBuffer(slot));
1029
1030 { // Test batched methods
1031 constexpr size_t BATCH_SIZE = 4;
1032 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(BATCH_SIZE));
1033
1034 // Dequeue
1035 using DequeueBufferInput = IGraphicBufferProducer::DequeueBufferInput;
1036 using DequeueBufferOutput = IGraphicBufferProducer::DequeueBufferOutput;
1037 DequeueBufferInput dequeueInput;
1038 dequeueInput.width = DEFAULT_WIDTH;
1039 dequeueInput.height = DEFAULT_HEIGHT;
1040 dequeueInput.format = DEFAULT_FORMAT;
1041 dequeueInput.usage = TEST_PRODUCER_USAGE_BITS;
1042 dequeueInput.getTimestamps = false;
1043 std::vector<DequeueBufferInput> dequeueInputs(BATCH_SIZE, dequeueInput);
1044 std::vector<DequeueBufferOutput> dequeueOutputs;
1045 EXPECT_OK(mProducer->dequeueBuffers(dequeueInputs, &dequeueOutputs));
1046 ASSERT_EQ(dequeueInputs.size(), dequeueOutputs.size());
1047
1048 // Request
1049 std::vector<int32_t> requestInputs;
1050 requestInputs.reserve(BATCH_SIZE);
1051 for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
1052 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
1053 dequeueOutput.result);
1054 requestInputs.emplace_back(dequeueOutput.slot);
1055 }
1056 using RequestBufferOutput = IGraphicBufferProducer::RequestBufferOutput;
1057 std::vector<RequestBufferOutput> requestOutputs;
1058 EXPECT_OK(mProducer->requestBuffers(requestInputs, &requestOutputs));
1059 ASSERT_EQ(requestInputs.size(), requestOutputs.size());
1060 for (const RequestBufferOutput& requestOutput : requestOutputs) {
1061 EXPECT_OK(requestOutput.result);
1062 }
1063
1064 // Detach
1065 std::vector<int32_t> detachInputs;
1066 detachInputs.reserve(BATCH_SIZE);
1067 for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
1068 detachInputs.emplace_back(dequeueOutput.slot);
1069 }
1070 std::vector<status_t> detachOutputs;
1071 EXPECT_OK(mProducer->detachBuffers(detachInputs, &detachOutputs));
1072 ASSERT_EQ(detachInputs.size(), detachOutputs.size());
1073 for (status_t result : detachOutputs) {
1074 EXPECT_OK(result);
1075 }
1076
1077 // Attach
1078 using AttachBufferOutput = IGraphicBufferProducer::AttachBufferOutput;
1079 std::vector<sp<GraphicBuffer>> attachInputs;
1080 attachInputs.reserve(BATCH_SIZE);
1081 for (const RequestBufferOutput& requestOutput : requestOutputs) {
1082 attachInputs.emplace_back(requestOutput.buffer);
1083 }
1084 std::vector<AttachBufferOutput> attachOutputs;
1085 EXPECT_OK(mProducer->attachBuffers(attachInputs, &attachOutputs));
1086 ASSERT_EQ(attachInputs.size(), attachOutputs.size());
1087 for (const AttachBufferOutput& attachOutput : attachOutputs) {
1088 EXPECT_OK(attachOutput.result);
1089 EXPECT_NE(-1, attachOutput.slot);
1090 }
1091 }
Pablo Ceballos583b1b32015-09-03 18:23:52 -07001092}
1093
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -08001094INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest,
1095 ::testing::Values(USE_BUFFER_QUEUE_PRODUCER));
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -08001096
Igor Murashkin7ea777f2013-11-18 16:58:36 -08001097} // namespace android