blob: e6cb89cb833ab4f72fdd2ff51fded9dca81112f6 [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
Peiyong Lind8460c82020-07-28 16:04:22 -070020#include "MockConsumer.h"
Brian Anderson5ea5e592016-12-01 16:54:33 -080021
Igor Murashkin7ea777f2013-11-18 16:58:36 -080022#include <gtest/gtest.h>
23
24#include <utils/String8.h>
25#include <utils/threads.h>
26
27#include <ui/GraphicBuffer.h>
Igor Murashkin7ea777f2013-11-18 16:58:36 -080028
29#include <gui/BufferQueue.h>
Dan Stozaf0eaf252014-03-21 13:05:51 -070030#include <gui/IProducerListener.h>
Igor Murashkin7ea777f2013-11-18 16:58:36 -080031
Mathias Agopian6a3c05b2017-04-27 20:06:55 -070032#include <system/window.h>
33
Igor Murashkin7ea777f2013-11-18 16:58:36 -080034#include <vector>
35
36#define ASSERT_OK(x) ASSERT_EQ(OK, (x))
37#define EXPECT_OK(x) EXPECT_EQ(OK, (x))
38
Dan Stozaf0eaf252014-03-21 13:05:51 -070039#define TEST_TOKEN ((IProducerListener*)(NULL))
Igor Murashkin7ea777f2013-11-18 16:58:36 -080040#define TEST_API NATIVE_WINDOW_API_CPU
41#define TEST_API_OTHER NATIVE_WINDOW_API_EGL // valid API that's not TEST_API
42#define TEST_CONTROLLED_BY_APP false
43#define TEST_PRODUCER_USAGE_BITS (0)
44
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() {
85 const ::testing::TestInfo* const testInfo =
86 ::testing::UnitTest::GetInstance()->current_test_info();
Nolan Scobief50aebc2023-04-13 17:49:18 +000087 ALOGD("Begin test: %s.%s", testInfo->test_case_name(),
Igor Murashkin7ea777f2013-11-18 16:58:36 -080088 testInfo->name());
89
Peiyong Lind8460c82020-07-28 16:04:22 -070090 mMC = new MockConsumer;
Igor Murashkin7ea777f2013-11-18 16:58:36 -080091
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -080092 switch (GetParam()) {
93 case USE_BUFFER_QUEUE_PRODUCER: {
94 BufferQueue::createBufferQueue(&mProducer, &mConsumer);
95 break;
96 }
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -080097 default: {
98 // Should never reach here.
99 LOG_ALWAYS_FATAL("Invalid test params: %u", GetParam());
100 break;
101 }
102 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800103
104 // Test check: Can't connect producer if no consumer yet
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800105 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
106 // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
107 ASSERT_EQ(NO_INIT, TryConnectProducer());
108 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800109
110 // Must connect consumer before producer connects will succeed.
Peiyong Lind8460c82020-07-28 16:04:22 -0700111 ASSERT_OK(mConsumer->consumerConnect(mMC, /*controlledByApp*/ false));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800112 }
113
114 virtual void TearDown() {
115 const ::testing::TestInfo* const testInfo =
116 ::testing::UnitTest::GetInstance()->current_test_info();
Nolan Scobief50aebc2023-04-13 17:49:18 +0000117 ALOGD("End test: %s.%s", testInfo->test_case_name(),
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800118 testInfo->name());
119 }
120
121 status_t TryConnectProducer() {
122 IGraphicBufferProducer::QueueBufferOutput output;
123 return mProducer->connect(TEST_TOKEN,
124 TEST_API,
125 TEST_CONTROLLED_BY_APP,
126 &output);
127 // TODO: use params to vary token, api, producercontrolledbyapp, etc
128 }
129
130 // Connect to a producer in a 'correct' fashion.
131 // Precondition: Consumer is connected.
132 void ConnectProducer() {
133 ASSERT_OK(TryConnectProducer());
134 }
135
136 // Create a generic "valid" input for queueBuffer
137 // -- uses the default buffer format, width, etc.
138 static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
139 return QueueBufferInputBuilder().build();
140 }
141
142 // Builder pattern to slightly vary *almost* correct input
143 // -- avoids copying and pasting
144 struct QueueBufferInputBuilder {
145 QueueBufferInputBuilder() {
146 timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP;
147 isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP;
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800148 dataSpace = QUEUE_BUFFER_INPUT_DATASPACE;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800149 crop = QUEUE_BUFFER_INPUT_RECT;
150 scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE;
151 transform = QUEUE_BUFFER_INPUT_TRANSFORM;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800152 fence = QUEUE_BUFFER_INPUT_FENCE;
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700153 stickyTransform = QUEUE_BUFFER_INPUT_STICKY_TRANSFORM;
154 getTimestamps = QUEUE_BUFFER_INPUT_GET_TIMESTAMPS;
155 slot = QUEUE_BUFFER_INPUT_SLOT;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800156 }
157
158 IGraphicBufferProducer::QueueBufferInput build() {
159 return IGraphicBufferProducer::QueueBufferInput(
160 timestamp,
161 isAutoTimestamp,
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800162 dataSpace,
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800163 crop,
164 scalingMode,
165 transform,
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700166 fence,
167 stickyTransform,
168 getTimestamps,
169 slot);
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800170 }
171
172 QueueBufferInputBuilder& setTimestamp(int64_t timestamp) {
173 this->timestamp = timestamp;
174 return *this;
175 }
176
177 QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) {
178 this->isAutoTimestamp = isAutoTimestamp;
179 return *this;
180 }
181
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800182 QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
183 this->dataSpace = dataSpace;
184 return *this;
185 }
186
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800187 QueueBufferInputBuilder& setCrop(Rect crop) {
188 this->crop = crop;
189 return *this;
190 }
191
192 QueueBufferInputBuilder& setScalingMode(int scalingMode) {
193 this->scalingMode = scalingMode;
194 return *this;
195 }
196
197 QueueBufferInputBuilder& setTransform(uint32_t transform) {
198 this->transform = transform;
199 return *this;
200 }
201
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800202 QueueBufferInputBuilder& setFence(sp<Fence> fence) {
203 this->fence = fence;
204 return *this;
205 }
206
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700207 QueueBufferInputBuilder& setStickyTransform(uint32_t stickyTransform) {
208 this->stickyTransform = stickyTransform;
209 return *this;
210 }
211
212 QueueBufferInputBuilder& setGetTimestamps(bool getTimestamps) {
213 this->getTimestamps = getTimestamps;
214 return *this;
215 }
216
217 QueueBufferInputBuilder& setSlot(int slot) {
218 this->slot = slot;
219 return *this;
220 }
221
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800222 private:
223 int64_t timestamp;
224 bool isAutoTimestamp;
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800225 android_dataspace dataSpace;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800226 Rect crop;
227 int scalingMode;
228 uint32_t transform;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800229 sp<Fence> fence;
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700230 uint32_t stickyTransform;
231 bool getTimestamps;
232 int slot;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800233 }; // struct QueueBufferInputBuilder
234
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700235 status_t dequeueBuffer(uint32_t w, uint32_t h, uint32_t format, uint32_t usage,
236 IGraphicBufferProducer::DequeueBufferOutput* result) {
237 result->result =
238 mProducer->dequeueBuffer(&result->slot, &result->fence, w, h, format, usage,
239 &result->bufferAge, nullptr);
240 return result->result;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800241 }
242
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700243 void setupDequeueRequestBuffer(int *slot, sp<Fence> *fence,
244 sp<GraphicBuffer> *buffer)
245 {
Yi Konga03e0442018-07-17 11:16:57 -0700246 ASSERT_TRUE(slot != nullptr);
247 ASSERT_TRUE(fence != nullptr);
248 ASSERT_TRUE(buffer != nullptr);
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700249
250 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
251
Ian Elliottd11b0442017-07-18 11:05:49 -0600252
253 ASSERT_EQ(OK,
254 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
255 (mProducer->dequeueBuffer(slot, fence, DEFAULT_WIDTH, DEFAULT_HEIGHT,
256 DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS,
257 nullptr, nullptr)));
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700258
259 EXPECT_LE(0, *slot);
260 EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, *slot);
261
262 // Request the buffer (pre-requisite for queueing)
263 ASSERT_OK(mProducer->requestBuffer(*slot, buffer));
264 }
265
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800266private: // hide from test body
Peiyong Lind8460c82020-07-28 16:04:22 -0700267 sp<MockConsumer> mMC;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800268
269protected: // accessible from test body
270 sp<IGraphicBufferProducer> mProducer;
271 sp<IGraphicBufferConsumer> mConsumer;
272};
273
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800274TEST_P(IGraphicBufferProducerTest, ConnectFirst_ReturnsError) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800275 IGraphicBufferProducer::QueueBufferOutput output;
276
277 // NULL output returns BAD_VALUE
278 EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
279 TEST_API,
280 TEST_CONTROLLED_BY_APP,
Yi Konga03e0442018-07-17 11:16:57 -0700281 /*output*/nullptr));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800282
283 // Invalid API returns bad value
284 EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
285 /*api*/0xDEADBEEF,
286 TEST_CONTROLLED_BY_APP,
287 &output));
288
289 // TODO: get a token from a dead process somehow
290}
291
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800292TEST_P(IGraphicBufferProducerTest, ConnectAgain_ReturnsError) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800293 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
294
295 // Can't connect when there is already a producer connected
296 IGraphicBufferProducer::QueueBufferOutput output;
297 EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN,
298 TEST_API,
299 TEST_CONTROLLED_BY_APP,
300 &output));
301
302 ASSERT_OK(mConsumer->consumerDisconnect());
303 // Can't connect when IGBP is abandoned
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800304 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
305 // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
306 EXPECT_EQ(NO_INIT, mProducer->connect(TEST_TOKEN,
307 TEST_API,
308 TEST_CONTROLLED_BY_APP,
309 &output));
310 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800311}
312
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800313TEST_P(IGraphicBufferProducerTest, Disconnect_Succeeds) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800314 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
315
316 ASSERT_OK(mProducer->disconnect(TEST_API));
317}
318
319
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800320TEST_P(IGraphicBufferProducerTest, Disconnect_ReturnsError) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800321 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
322
323 // Must disconnect with same API number
324 ASSERT_EQ(BAD_VALUE, mProducer->disconnect(TEST_API_OTHER));
325 // API must not be out of range
326 ASSERT_EQ(BAD_VALUE, mProducer->disconnect(/*api*/0xDEADBEEF));
327
328 // TODO: somehow kill mProducer so that this returns DEAD_OBJECT
329}
330
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800331TEST_P(IGraphicBufferProducerTest, Query_Succeeds) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800332 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
333
Dan Stozaf8cebe52015-04-20 12:09:38 -0700334 int32_t value = -1;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800335 EXPECT_OK(mProducer->query(NATIVE_WINDOW_WIDTH, &value));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700336 EXPECT_EQ(DEFAULT_WIDTH, static_cast<uint32_t>(value));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800337
338 EXPECT_OK(mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700339 EXPECT_EQ(DEFAULT_HEIGHT, static_cast<uint32_t>(value));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800340
341 EXPECT_OK(mProducer->query(NATIVE_WINDOW_FORMAT, &value));
342 EXPECT_EQ(DEFAULT_FORMAT, value);
343
344 EXPECT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value));
345 EXPECT_LE(0, value);
346 EXPECT_GE(BufferQueue::NUM_BUFFER_SLOTS, value);
347
348 EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value));
349 EXPECT_FALSE(value); // Can't run behind when we haven't touched the queue
350
351 EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value));
352 EXPECT_EQ(DEFAULT_CONSUMER_USAGE_BITS, value);
353
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700354 { // Test the batched version
355 std::vector<int32_t> inputs = {
356 NATIVE_WINDOW_WIDTH,
357 NATIVE_WINDOW_HEIGHT,
358 NATIVE_WINDOW_FORMAT,
359 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
360 NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND,
361 NATIVE_WINDOW_CONSUMER_USAGE_BITS };
362 using QueryOutput = IGraphicBufferProducer::QueryOutput;
363 std::vector<QueryOutput> outputs;
364 EXPECT_OK(mProducer->query(inputs, &outputs));
365 EXPECT_EQ(DEFAULT_WIDTH, static_cast<uint32_t>(outputs[0].value));
366 EXPECT_EQ(DEFAULT_HEIGHT, static_cast<uint32_t>(outputs[1].value));
367 EXPECT_EQ(DEFAULT_FORMAT, outputs[2].value);
368 EXPECT_LE(0, outputs[3].value);
369 EXPECT_FALSE(outputs[4].value);
370 EXPECT_EQ(DEFAULT_CONSUMER_USAGE_BITS, outputs[5].value);
371 for (const QueryOutput& output : outputs) {
372 EXPECT_OK(output.result);
373 }
374 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800375}
376
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800377TEST_P(IGraphicBufferProducerTest, Query_ReturnsError) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800378 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
379
380 // One past the end of the last 'query' enum value. Update this if we add more enums.
Michael Lentined8ead0c2015-05-19 15:23:43 -0700381 const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800382
383 int value;
384 // What was out of range
385 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/-1, &value));
386 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/0xDEADBEEF, &value));
387 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value));
388
389 // Some enums from window.h are 'invalid'
390 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value));
391 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value));
392 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value));
393 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value));
394 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value));
395 // TODO: Consider documented the above enums as unsupported or make a new enum for IGBP
396
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700397 { // Test the batched version
398 std::vector<int32_t> inputs = {
399 -1,
400 static_cast<int32_t>(0xDEADBEEF),
401 NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE,
402 NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER,
403 NATIVE_WINDOW_CONCRETE_TYPE,
404 NATIVE_WINDOW_DEFAULT_WIDTH,
405 NATIVE_WINDOW_DEFAULT_HEIGHT,
406 NATIVE_WINDOW_TRANSFORM_HINT};
407 using QueryOutput = IGraphicBufferProducer::QueryOutput;
408 std::vector<QueryOutput> outputs;
409 EXPECT_OK(mProducer->query(inputs, &outputs));
410 for (const QueryOutput& output : outputs) {
411 EXPECT_EQ(BAD_VALUE, output.result);
412 }
413 }
414
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800415 // Value was NULL
Yi Konga03e0442018-07-17 11:16:57 -0700416 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/nullptr));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800417
418 ASSERT_OK(mConsumer->consumerDisconnect());
419
420 // BQ was abandoned
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800421 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
422 // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
423 EXPECT_EQ(NO_INIT, mProducer->query(NATIVE_WINDOW_FORMAT, &value));
424 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800425
426 // TODO: other things in window.h that are supported by Surface::query
427 // but not by BufferQueue::query
428}
429
430// TODO: queue under more complicated situations not involving just a single buffer
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800431TEST_P(IGraphicBufferProducerTest, Queue_Succeeds) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800432 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
433
434 int dequeuedSlot = -1;
435 sp<Fence> dequeuedFence;
436
Ian Elliottd11b0442017-07-18 11:05:49 -0600437 ASSERT_EQ(OK,
438 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
439 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
440 DEFAULT_HEIGHT, DEFAULT_FORMAT,
441 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800442
443 EXPECT_LE(0, dequeuedSlot);
444 EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, dequeuedSlot);
445
446 // Request the buffer (pre-requisite for queueing)
447 sp<GraphicBuffer> dequeuedBuffer;
448 ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
449
450 // A generic "valid" input
451 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
452 IGraphicBufferProducer::QueueBufferOutput output;
453
454 // Queue the buffer back into the BQ
455 ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output));
456
457 {
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700458 EXPECT_EQ(DEFAULT_WIDTH, output.width);
459 EXPECT_EQ(DEFAULT_HEIGHT, output.height);
460 EXPECT_EQ(DEFAULT_TRANSFORM_HINT, output.transformHint);
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800461
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700462 // Since queueBuffer was called exactly once
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800463 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
464 // TODO(b/70041889): BufferHubProducer need to support metadata: numPendingBuffers
465 EXPECT_EQ(1u, output.numPendingBuffers);
466 // TODO(b/70041952): BufferHubProducer need to support metadata: nextFrameNumber
467 EXPECT_EQ(2u, output.nextFrameNumber);
468 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800469 }
470
471 // Buffer was not in the dequeued state
472 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700473
474 { // Test batched methods
475 constexpr size_t BATCH_SIZE = 4;
476
477 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(BATCH_SIZE));
478 // Dequeue
479 using DequeueBufferInput = IGraphicBufferProducer::DequeueBufferInput;
480 using DequeueBufferOutput = IGraphicBufferProducer::DequeueBufferOutput;
481 DequeueBufferInput dequeueInput;
482 dequeueInput.width = DEFAULT_WIDTH;
483 dequeueInput.height = DEFAULT_HEIGHT;
484 dequeueInput.format = DEFAULT_FORMAT;
485 dequeueInput.usage = TEST_PRODUCER_USAGE_BITS;
486 dequeueInput.getTimestamps = false;
487 std::vector<DequeueBufferInput> dequeueInputs(BATCH_SIZE, dequeueInput);
488 std::vector<DequeueBufferOutput> dequeueOutputs;
489 EXPECT_OK(mProducer->dequeueBuffers(dequeueInputs, &dequeueOutputs));
490 ASSERT_EQ(dequeueInputs.size(), dequeueOutputs.size());
491
492 // Request
493 std::vector<int32_t> requestInputs;
494 requestInputs.reserve(BATCH_SIZE);
495 for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
496 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
497 dequeueOutput.result);
498 requestInputs.emplace_back(dequeueOutput.slot);
499 }
500 using RequestBufferOutput = IGraphicBufferProducer::RequestBufferOutput;
501 std::vector<RequestBufferOutput> requestOutputs;
502 EXPECT_OK(mProducer->requestBuffers(requestInputs, &requestOutputs));
503 ASSERT_EQ(requestInputs.size(), requestOutputs.size());
504 for (const RequestBufferOutput& requestOutput : requestOutputs) {
505 EXPECT_OK(requestOutput.result);
506 }
507
508 // Queue
509 using QueueBufferInput = IGraphicBufferProducer::QueueBufferInput;
510 using QueueBufferOutput = IGraphicBufferProducer::QueueBufferOutput;
511 std::vector<QueueBufferInput> queueInputs;
512 queueInputs.reserve(BATCH_SIZE);
513 for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
514 queueInputs.emplace_back(CreateBufferInput()).slot =
515 dequeueOutput.slot;
516 }
517 std::vector<QueueBufferOutput> queueOutputs;
518 EXPECT_OK(mProducer->queueBuffers(queueInputs, &queueOutputs));
519 ASSERT_EQ(queueInputs.size(), queueOutputs.size());
520 for (const QueueBufferOutput& queueOutput : queueOutputs) {
521 EXPECT_OK(queueOutput.result);
522 }
523
524 // Re-queue
525 EXPECT_OK(mProducer->queueBuffers(queueInputs, &queueOutputs));
526 ASSERT_EQ(queueInputs.size(), queueOutputs.size());
527 for (const QueueBufferOutput& queueOutput : queueOutputs) {
528 EXPECT_EQ(BAD_VALUE, queueOutput.result);
529 }
530 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800531}
532
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800533TEST_P(IGraphicBufferProducerTest, Queue_ReturnsError) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800534 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
535
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700536 using QueueBufferInput = IGraphicBufferProducer::QueueBufferInput;
537 using QueueBufferOutput = IGraphicBufferProducer::QueueBufferOutput;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800538 // Invalid slot number
539 {
540 // A generic "valid" input
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700541 QueueBufferInput input = CreateBufferInput();
542 QueueBufferOutput output;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800543
544 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/-1, input, &output));
545 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0xDEADBEEF, input, &output));
546 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueue::NUM_BUFFER_SLOTS,
547 input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700548
549 { // Test with the batched version
550 constexpr size_t BATCH_SIZE = 16;
551 input.slot = -1;
552 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
553 std::vector<QueueBufferOutput> outputs;
554 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
555 ASSERT_EQ(inputs.size(), outputs.size());
556 for (const QueueBufferOutput& output : outputs) {
557 EXPECT_EQ(BAD_VALUE, output.result);
558 }
559 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800560 }
561
562 // Slot was not in the dequeued state (all slots start out in Free state)
563 {
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700564 QueueBufferInput input = CreateBufferInput();
565 QueueBufferOutput output;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800566
567 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700568
569 { // Test with the batched version
570 constexpr size_t BATCH_SIZE = 16;
571 input.slot = 0;
572 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
573 std::vector<QueueBufferOutput> outputs;
574 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
575 ASSERT_EQ(inputs.size(), outputs.size());
576 for (const QueueBufferOutput& output : outputs) {
577 EXPECT_EQ(BAD_VALUE, output.result);
578 }
579 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800580 }
581
582 // Put the slot into the "dequeued" state for the rest of the test
583 int dequeuedSlot = -1;
584 sp<Fence> dequeuedFence;
585
Ian Elliottd11b0442017-07-18 11:05:49 -0600586 ASSERT_EQ(OK,
587 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
588 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
589 DEFAULT_HEIGHT, DEFAULT_FORMAT,
590 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800591
592 // Slot was enqueued without requesting a buffer
593 {
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700594 QueueBufferInput input = CreateBufferInput();
595 QueueBufferOutput output;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800596
597 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700598
599 { // Test with the batched version
600 constexpr size_t BATCH_SIZE = 16;
601 input.slot = dequeuedSlot;
602 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
603 std::vector<QueueBufferOutput> outputs;
604 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
605 ASSERT_EQ(inputs.size(), outputs.size());
606 for (const QueueBufferOutput& output : outputs) {
607 EXPECT_EQ(BAD_VALUE, output.result);
608 }
609 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800610 }
611
612 // Request the buffer so that the rest of the tests don't fail on earlier checks.
613 sp<GraphicBuffer> dequeuedBuffer;
614 ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
615
616 // Fence was NULL
617 {
Yi Konga03e0442018-07-17 11:16:57 -0700618 sp<Fence> nullFence = nullptr;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800619
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700620 QueueBufferInput input =
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800621 QueueBufferInputBuilder().setFence(nullFence).build();
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700622 QueueBufferOutput output;
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800623
624 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700625
626 { // Test with the batched version
627 constexpr size_t BATCH_SIZE = 16;
628 input.slot = dequeuedSlot;
629 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
630 std::vector<QueueBufferOutput> outputs;
631 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
632 ASSERT_EQ(inputs.size(), outputs.size());
633 for (const QueueBufferOutput& output : outputs) {
634 EXPECT_EQ(BAD_VALUE, output.result);
635 }
636 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800637 }
638
639 // Scaling mode was unknown
640 {
641 IGraphicBufferProducer::QueueBufferInput input =
642 QueueBufferInputBuilder().setScalingMode(-1).build();
643 IGraphicBufferProducer::QueueBufferOutput output;
644
645 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
646
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700647 { // Test with the batched version
648 constexpr size_t BATCH_SIZE = 16;
649 input.slot = dequeuedSlot;
650 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
651 std::vector<QueueBufferOutput> outputs;
652 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
653 ASSERT_EQ(inputs.size(), outputs.size());
654 for (const QueueBufferOutput& output : outputs) {
655 EXPECT_EQ(BAD_VALUE, output.result);
656 }
657 }
658
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800659 input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build();
660
661 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700662
663 { // Test with the batched version
664 constexpr size_t BATCH_SIZE = 16;
665 input.slot = dequeuedSlot;
666 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
667 std::vector<QueueBufferOutput> outputs;
668 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
669 ASSERT_EQ(inputs.size(), outputs.size());
670 for (const QueueBufferOutput& output : outputs) {
671 EXPECT_EQ(BAD_VALUE, output.result);
672 }
673 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800674 }
675
676 // Crop rect is out of bounds of the buffer dimensions
677 {
678 IGraphicBufferProducer::QueueBufferInput input =
679 QueueBufferInputBuilder().setCrop(Rect(DEFAULT_WIDTH + 1, DEFAULT_HEIGHT + 1))
680 .build();
681 IGraphicBufferProducer::QueueBufferOutput output;
682
683 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700684
685 { // Test with the batched version
686 constexpr size_t BATCH_SIZE = 16;
687 input.slot = dequeuedSlot;
688 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
689 std::vector<QueueBufferOutput> outputs;
690 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
691 ASSERT_EQ(inputs.size(), outputs.size());
692 for (const QueueBufferOutput& output : outputs) {
693 EXPECT_EQ(BAD_VALUE, output.result);
694 }
695 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800696 }
697
698 // Abandon the buffer queue so that the last test fails
699 ASSERT_OK(mConsumer->consumerDisconnect());
700
701 // The buffer queue has been abandoned.
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800702 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800703 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
704 IGraphicBufferProducer::QueueBufferOutput output;
705
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800706 // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800707 EXPECT_EQ(NO_INIT, mProducer->queueBuffer(dequeuedSlot, input, &output));
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700708
709 { // Test with the batched version
710 constexpr size_t BATCH_SIZE = 16;
711 input.slot = dequeuedSlot;
712 std::vector<QueueBufferInput> inputs(BATCH_SIZE, input);
713 std::vector<QueueBufferOutput> outputs;
714 EXPECT_OK(mProducer->queueBuffers(inputs, &outputs));
715 ASSERT_EQ(inputs.size(), outputs.size());
716 for (const QueueBufferOutput& output : outputs) {
717 EXPECT_EQ(NO_INIT, output.result);
718 }
719 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800720 }
721}
722
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800723TEST_P(IGraphicBufferProducerTest, CancelBuffer_DoesntCrash) {
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800724 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
725
726 int dequeuedSlot = -1;
727 sp<Fence> dequeuedFence;
728
Ian Elliottd11b0442017-07-18 11:05:49 -0600729 ASSERT_EQ(OK,
730 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
731 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
732 DEFAULT_HEIGHT, DEFAULT_FORMAT,
733 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800734
735 // No return code, but at least test that it doesn't blow up...
736 // TODO: add a return code
737 mProducer->cancelBuffer(dequeuedSlot, dequeuedFence);
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700738
739 { // Test batched methods
740 constexpr size_t BATCH_SIZE = 4;
741 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(BATCH_SIZE));
742
743 // Dequeue
744 using DequeueBufferInput = IGraphicBufferProducer::DequeueBufferInput;
745 using DequeueBufferOutput = IGraphicBufferProducer::DequeueBufferOutput;
746 DequeueBufferInput dequeueInput;
747 dequeueInput.width = DEFAULT_WIDTH;
748 dequeueInput.height = DEFAULT_HEIGHT;
749 dequeueInput.format = DEFAULT_FORMAT;
750 dequeueInput.usage = TEST_PRODUCER_USAGE_BITS;
751 dequeueInput.getTimestamps = false;
752 std::vector<DequeueBufferInput> dequeueInputs(BATCH_SIZE, dequeueInput);
753 std::vector<DequeueBufferOutput> dequeueOutputs;
754 EXPECT_OK(mProducer->dequeueBuffers(dequeueInputs, &dequeueOutputs));
755 ASSERT_EQ(dequeueInputs.size(), dequeueOutputs.size());
756
757 // Cancel
758 using CancelBufferInput = IGraphicBufferProducer::CancelBufferInput;
759 std::vector<CancelBufferInput> cancelInputs;
760 cancelInputs.reserve(BATCH_SIZE);
761 for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
762 ASSERT_EQ(OK,
763 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
764 dequeueOutput.result);
765 CancelBufferInput& cancelInput = cancelInputs.emplace_back();
766 cancelInput.slot = dequeueOutput.slot;
767 cancelInput.fence = dequeueOutput.fence;
768 }
769 std::vector<status_t> cancelOutputs;
770 EXPECT_OK(mProducer->cancelBuffers(cancelInputs, &cancelOutputs));
771 ASSERT_EQ(cancelInputs.size(), cancelOutputs.size());
772 for (status_t result : cancelOutputs) {
773 EXPECT_OK(result);
774 }
775 }
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800776}
777
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800778TEST_P(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Succeeds) {
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700779 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
Pablo Ceballosfa455352015-08-12 17:47:47 -0700780 int minUndequeuedBuffers;
781 ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
782 &minUndequeuedBuffers));
783
784 const int minBuffers = 1;
785 const int maxBuffers = BufferQueue::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
786
787 ASSERT_OK(mProducer->setAsyncMode(false)) << "async mode: " << false;
788 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(minBuffers))
789 << "bufferCount: " << minBuffers;
790
Pablo Ceballosfa455352015-08-12 17:47:47 -0700791 // Should now be able to dequeue up to minBuffers times
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700792 IGraphicBufferProducer::DequeueBufferOutput result;
Pablo Ceballosfa455352015-08-12 17:47:47 -0700793 for (int i = 0; i < minBuffers; ++i) {
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700794 EXPECT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700795 (dequeueBuffer(DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +0700796 TEST_PRODUCER_USAGE_BITS, &result)))
Pablo Ceballosfa455352015-08-12 17:47:47 -0700797 << "iteration: " << i << ", slot: " << result.slot;
Pablo Ceballosfa455352015-08-12 17:47:47 -0700798 }
799
800 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(maxBuffers));
801
Pablo Ceballos72daab62015-12-07 16:38:43 -0800802 // queue the first buffer to enable max dequeued buffer count checking
803 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
804 IGraphicBufferProducer::QueueBufferOutput output;
805 sp<GraphicBuffer> buffer;
806 ASSERT_OK(mProducer->requestBuffer(result.slot, &buffer));
807 ASSERT_OK(mProducer->queueBuffer(result.slot, input, &output));
808
Pablo Ceballosfa455352015-08-12 17:47:47 -0700809 // Should now be able to dequeue up to maxBuffers times
Pablo Ceballos72daab62015-12-07 16:38:43 -0800810 int dequeuedSlot = -1;
811 sp<Fence> dequeuedFence;
Pablo Ceballosfa455352015-08-12 17:47:47 -0700812 for (int i = 0; i < maxBuffers; ++i) {
Ian Elliottd11b0442017-07-18 11:05:49 -0600813 EXPECT_EQ(OK,
814 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
815 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
816 DEFAULT_HEIGHT, DEFAULT_FORMAT,
817 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
Pablo Ceballosfa455352015-08-12 17:47:47 -0700818 << "iteration: " << i << ", slot: " << dequeuedSlot;
819 }
Pablo Ceballos72daab62015-12-07 16:38:43 -0800820
821 // Cancel a buffer, so we can decrease the buffer count
822 ASSERT_OK(mProducer->cancelBuffer(dequeuedSlot, dequeuedFence));
823
824 // Should now be able to decrease the max dequeued count by 1
825 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(maxBuffers-1));
Pablo Ceballosfa455352015-08-12 17:47:47 -0700826}
827
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800828TEST_P(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Fails) {
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700829 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
Pablo Ceballosfa455352015-08-12 17:47:47 -0700830 int minUndequeuedBuffers;
831 ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
832 &minUndequeuedBuffers));
833
834 const int minBuffers = 1;
835 const int maxBuffers = BufferQueue::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
836
837 ASSERT_OK(mProducer->setAsyncMode(false)) << "async mode: " << false;
838 // Buffer count was out of range
839 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(0))
840 << "bufferCount: " << 0;
841 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(maxBuffers + 1))
842 << "bufferCount: " << maxBuffers + 1;
843
Pablo Ceballos72daab62015-12-07 16:38:43 -0800844 // Set max dequeue count to 2
845 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(2));
846 // Dequeue 2 buffers
847 int dequeuedSlot = -1;
848 sp<Fence> dequeuedFence;
849 for (int i = 0; i < 2; i++) {
Ian Elliottd11b0442017-07-18 11:05:49 -0600850 ASSERT_EQ(OK,
851 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
852 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
853 DEFAULT_HEIGHT, DEFAULT_FORMAT,
854 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
Pablo Ceballosfa455352015-08-12 17:47:47 -0700855 << "slot: " << dequeuedSlot;
856 }
857
Pablo Ceballos72daab62015-12-07 16:38:43 -0800858 // Client has too many buffers dequeued
859 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1))
Pablo Ceballosfa455352015-08-12 17:47:47 -0700860 << "bufferCount: " << minBuffers;
861
862 // Abandon buffer queue
863 ASSERT_OK(mConsumer->consumerDisconnect());
864
865 // Fail because the buffer queue was abandoned
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800866 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
867 // TODO(b/73267953): Make BufferHub honor producer and consumer connection.
868 EXPECT_EQ(NO_INIT, mProducer->setMaxDequeuedBufferCount(minBuffers))
869 << "bufferCount: " << minBuffers;
870 }
Pablo Ceballosfa455352015-08-12 17:47:47 -0700871}
872
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800873TEST_P(IGraphicBufferProducerTest, SetAsyncMode_Succeeds) {
Pablo Ceballosfa455352015-08-12 17:47:47 -0700874 ASSERT_OK(mConsumer->setMaxAcquiredBufferCount(1)) << "maxAcquire: " << 1;
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700875 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
Pablo Ceballosfa455352015-08-12 17:47:47 -0700876 ASSERT_OK(mProducer->setAsyncMode(true)) << "async mode: " << true;
877 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(1)) << "maxDequeue: " << 1;
878
879 int dequeuedSlot = -1;
880 sp<Fence> dequeuedFence;
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700881 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
Pablo Ceballosfa455352015-08-12 17:47:47 -0700882 IGraphicBufferProducer::QueueBufferOutput output;
883 sp<GraphicBuffer> dequeuedBuffer;
884
885 // Should now be able to queue/dequeue as many buffers as we want without
886 // blocking
887 for (int i = 0; i < 5; ++i) {
Ian Elliottd11b0442017-07-18 11:05:49 -0600888 ASSERT_EQ(OK,
889 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
890 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
891 DEFAULT_HEIGHT, DEFAULT_FORMAT,
892 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700893 << "slot : " << dequeuedSlot;
Pablo Ceballosfa455352015-08-12 17:47:47 -0700894 ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer));
895 ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output));
896 }
897}
898
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800899TEST_P(IGraphicBufferProducerTest, SetAsyncMode_Fails) {
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700900 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
Pablo Ceballosfa455352015-08-12 17:47:47 -0700901 // Prerequisite to fail out a valid setBufferCount call
902 {
903 int dequeuedSlot = -1;
904 sp<Fence> dequeuedFence;
905
Ian Elliottd11b0442017-07-18 11:05:49 -0600906 ASSERT_EQ(OK,
907 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
908 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, DEFAULT_WIDTH,
909 DEFAULT_HEIGHT, DEFAULT_FORMAT,
910 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr)))
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700911 << "slot: " << dequeuedSlot;
Pablo Ceballosfa455352015-08-12 17:47:47 -0700912 }
913
Pablo Ceballosfa455352015-08-12 17:47:47 -0700914 // Abandon buffer queue
915 ASSERT_OK(mConsumer->consumerDisconnect());
916
917 // Fail because the buffer queue was abandoned
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800918 if (GetParam() == USE_BUFFER_QUEUE_PRODUCER) {
919 // TODO(b/36724099): Make BufferHub honor producer and consumer connection.
920 EXPECT_EQ(NO_INIT, mProducer->setAsyncMode(false)) << "asyncMode: " << false;
921 }
Pablo Ceballosfa455352015-08-12 17:47:47 -0700922}
923
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800924TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700925 DisconnectedProducerReturnsError_dequeueBuffer) {
926 int slot = -1;
927 sp<Fence> fence;
928
Ian Elliottd11b0442017-07-18 11:05:49 -0600929 ASSERT_EQ(NO_INIT,
930 mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT,
931 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr));
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700932}
933
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800934TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700935 DisconnectedProducerReturnsError_detachNextBuffer) {
936 sp<Fence> fence;
937 sp<GraphicBuffer> buffer;
938
Jiwen 'Steve' Cai42875352018-04-30 17:55:11 -0700939 ASSERT_EQ(NO_INIT, mProducer->detachNextBuffer(&buffer, &fence));
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700940}
941
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800942TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700943 DisconnectedProducerReturnsError_requestBuffer) {
944 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
945
946 int slot = -1;
947 sp<Fence> fence;
948
Ian Elliottd11b0442017-07-18 11:05:49 -0600949 ASSERT_EQ(OK,
950 ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
951 (mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, DEFAULT_HEIGHT,
952 DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS,
953 nullptr, nullptr)));
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700954
955 EXPECT_LE(0, slot);
956 EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, slot);
957
958 ASSERT_OK(mProducer->disconnect(TEST_API));
959
960 sp<GraphicBuffer> buffer;
961
962 ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer));
963}
964
965
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800966TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700967 DisconnectedProducerReturnsError_detachBuffer) {
968 int slot = -1;
969 sp<Fence> fence;
970 sp<GraphicBuffer> buffer;
971
972 setupDequeueRequestBuffer(&slot, &fence, &buffer);
973
974 ASSERT_OK(mProducer->disconnect(TEST_API));
975
Jiwen 'Steve' Cai42875352018-04-30 17:55:11 -0700976 ASSERT_EQ(NO_INIT, mProducer->detachBuffer(slot));
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700977}
978
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800979TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700980 DisconnectedProducerReturnsError_queueBuffer) {
981 int slot = -1;
982 sp<Fence> fence;
983 sp<GraphicBuffer> buffer;
984
985 setupDequeueRequestBuffer(&slot, &fence, &buffer);
986
987 ASSERT_OK(mProducer->disconnect(TEST_API));
988
989 // A generic "valid" input
990 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
991 IGraphicBufferProducer::QueueBufferOutput output;
992
993 ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output));
994}
995
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -0800996TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -0700997 DisconnectedProducerReturnsError_cancelBuffer) {
998 int slot = -1;
999 sp<Fence> fence;
1000 sp<GraphicBuffer> buffer;
1001
1002 setupDequeueRequestBuffer(&slot, &fence, &buffer);
1003
1004 ASSERT_OK(mProducer->disconnect(TEST_API));
1005
1006 ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, fence));
1007}
1008
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -08001009TEST_P(IGraphicBufferProducerTest,
Pablo Ceballos583b1b32015-09-03 18:23:52 -07001010 DisconnectedProducerReturnsError_attachBuffer) {
1011 int slot = -1;
1012 sp<Fence> fence;
1013 sp<GraphicBuffer> buffer;
1014
1015 setupDequeueRequestBuffer(&slot, &fence, &buffer);
Jiwen 'Steve' Cai42875352018-04-30 17:55:11 -07001016 ASSERT_TRUE(buffer != nullptr);
Pablo Ceballos583b1b32015-09-03 18:23:52 -07001017
Jiwen 'Steve' Cai42875352018-04-30 17:55:11 -07001018 ASSERT_OK(mProducer->detachBuffer(slot));
1019 EXPECT_OK(buffer->initCheck());
1020
Pablo Ceballos583b1b32015-09-03 18:23:52 -07001021 ASSERT_OK(mProducer->disconnect(TEST_API));
1022
Jiwen 'Steve' Cai57ae3ee2018-05-03 17:51:52 -07001023 ASSERT_EQ(NO_INIT, mProducer->attachBuffer(&slot, buffer));
1024}
1025
1026TEST_P(IGraphicBufferProducerTest, DetachThenAttach_Succeeds) {
1027 int slot = -1;
1028 sp<Fence> fence;
1029 sp<GraphicBuffer> buffer;
1030
1031 setupDequeueRequestBuffer(&slot, &fence, &buffer);
1032 ASSERT_TRUE(buffer != nullptr);
1033
1034 ASSERT_OK(mProducer->detachBuffer(slot));
1035 EXPECT_OK(buffer->initCheck());
1036
Jiwen 'Steve' Cai57ae3ee2018-05-03 17:51:52 -07001037 EXPECT_OK(mProducer->attachBuffer(&slot, buffer));
Jiwen 'Steve' Cai57ae3ee2018-05-03 17:51:52 -07001038 EXPECT_OK(buffer->initCheck());
Yin-Chia Yeh64ee5f52020-01-02 17:53:18 +07001039
1040 ASSERT_OK(mProducer->detachBuffer(slot));
1041
1042 { // Test batched methods
1043 constexpr size_t BATCH_SIZE = 4;
1044 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(BATCH_SIZE));
1045
1046 // Dequeue
1047 using DequeueBufferInput = IGraphicBufferProducer::DequeueBufferInput;
1048 using DequeueBufferOutput = IGraphicBufferProducer::DequeueBufferOutput;
1049 DequeueBufferInput dequeueInput;
1050 dequeueInput.width = DEFAULT_WIDTH;
1051 dequeueInput.height = DEFAULT_HEIGHT;
1052 dequeueInput.format = DEFAULT_FORMAT;
1053 dequeueInput.usage = TEST_PRODUCER_USAGE_BITS;
1054 dequeueInput.getTimestamps = false;
1055 std::vector<DequeueBufferInput> dequeueInputs(BATCH_SIZE, dequeueInput);
1056 std::vector<DequeueBufferOutput> dequeueOutputs;
1057 EXPECT_OK(mProducer->dequeueBuffers(dequeueInputs, &dequeueOutputs));
1058 ASSERT_EQ(dequeueInputs.size(), dequeueOutputs.size());
1059
1060 // Request
1061 std::vector<int32_t> requestInputs;
1062 requestInputs.reserve(BATCH_SIZE);
1063 for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
1064 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
1065 dequeueOutput.result);
1066 requestInputs.emplace_back(dequeueOutput.slot);
1067 }
1068 using RequestBufferOutput = IGraphicBufferProducer::RequestBufferOutput;
1069 std::vector<RequestBufferOutput> requestOutputs;
1070 EXPECT_OK(mProducer->requestBuffers(requestInputs, &requestOutputs));
1071 ASSERT_EQ(requestInputs.size(), requestOutputs.size());
1072 for (const RequestBufferOutput& requestOutput : requestOutputs) {
1073 EXPECT_OK(requestOutput.result);
1074 }
1075
1076 // Detach
1077 std::vector<int32_t> detachInputs;
1078 detachInputs.reserve(BATCH_SIZE);
1079 for (const DequeueBufferOutput& dequeueOutput : dequeueOutputs) {
1080 detachInputs.emplace_back(dequeueOutput.slot);
1081 }
1082 std::vector<status_t> detachOutputs;
1083 EXPECT_OK(mProducer->detachBuffers(detachInputs, &detachOutputs));
1084 ASSERT_EQ(detachInputs.size(), detachOutputs.size());
1085 for (status_t result : detachOutputs) {
1086 EXPECT_OK(result);
1087 }
1088
1089 // Attach
1090 using AttachBufferOutput = IGraphicBufferProducer::AttachBufferOutput;
1091 std::vector<sp<GraphicBuffer>> attachInputs;
1092 attachInputs.reserve(BATCH_SIZE);
1093 for (const RequestBufferOutput& requestOutput : requestOutputs) {
1094 attachInputs.emplace_back(requestOutput.buffer);
1095 }
1096 std::vector<AttachBufferOutput> attachOutputs;
1097 EXPECT_OK(mProducer->attachBuffers(attachInputs, &attachOutputs));
1098 ASSERT_EQ(attachInputs.size(), attachOutputs.size());
1099 for (const AttachBufferOutput& attachOutput : attachOutputs) {
1100 EXPECT_OK(attachOutput.result);
1101 EXPECT_NE(-1, attachOutput.slot);
1102 }
1103 }
Pablo Ceballos583b1b32015-09-03 18:23:52 -07001104}
1105
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -08001106INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest,
1107 ::testing::Values(USE_BUFFER_QUEUE_PRODUCER));
Jiwen 'Steve' Cai22029502018-02-12 22:26:05 -08001108
Igor Murashkin7ea777f2013-11-18 16:58:36 -08001109} // namespace android