1/* 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 20#include "DummyConsumer.h" 21 22#include <gtest/gtest.h> 23 24#include <utils/String8.h> 25#include <utils/threads.h> 26 27#include <ui/GraphicBuffer.h> 28 29#include <gui/BufferQueue.h> 30#include <gui/IProducerListener.h> 31 32#include <vector> 33 34#define ASSERT_OK(x) ASSERT_EQ(OK, (x)) 35#define EXPECT_OK(x) EXPECT_EQ(OK, (x)) 36 37#define TEST_TOKEN ((IProducerListener*)(NULL)) 38#define TEST_API NATIVE_WINDOW_API_CPU 39#define TEST_API_OTHER NATIVE_WINDOW_API_EGL // valid API that's not TEST_API 40#define TEST_CONTROLLED_BY_APP false 41#define TEST_PRODUCER_USAGE_BITS (0) 42 43namespace android { 44 45namespace { 46 // Default dimensions before setDefaultBufferSize is called 47 const uint32_t DEFAULT_WIDTH = 1; 48 const uint32_t DEFAULT_HEIGHT = 1; 49 50 // Default format before setDefaultBufferFormat is called 51 const PixelFormat DEFAULT_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888; 52 53 // Default transform hint before setTransformHint is called 54 const uint32_t DEFAULT_TRANSFORM_HINT = 0; 55 56 // TODO: Make these constants in header 57 const int DEFAULT_CONSUMER_USAGE_BITS = 0; 58 59 // Parameters for a generic "valid" input for queueBuffer. 60 const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611; 61 const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false; 62 const android_dataspace QUEUE_BUFFER_INPUT_DATASPACE = HAL_DATASPACE_UNKNOWN; 63 const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT); 64 const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0; 65 const int QUEUE_BUFFER_INPUT_TRANSFORM = 0; 66 const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE; 67}; // namespace anonymous 68 69class IGraphicBufferProducerTest : public ::testing::Test { 70protected: 71 72 IGraphicBufferProducerTest() {} 73 74 virtual void SetUp() { 75 const ::testing::TestInfo* const testInfo = 76 ::testing::UnitTest::GetInstance()->current_test_info(); 77 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), 78 testInfo->name()); 79 80 mDC = new DummyConsumer; 81 82 BufferQueue::createBufferQueue(&mProducer, &mConsumer); 83 84 // Test check: Can't connect producer if no consumer yet 85 ASSERT_EQ(NO_INIT, TryConnectProducer()); 86 87 // Must connect consumer before producer connects will succeed. 88 ASSERT_OK(mConsumer->consumerConnect(mDC, /*controlledByApp*/false)); 89 } 90 91 virtual void TearDown() { 92 const ::testing::TestInfo* const testInfo = 93 ::testing::UnitTest::GetInstance()->current_test_info(); 94 ALOGV("End test: %s.%s", testInfo->test_case_name(), 95 testInfo->name()); 96 } 97 98 status_t TryConnectProducer() { 99 IGraphicBufferProducer::QueueBufferOutput output; 100 return mProducer->connect(TEST_TOKEN, 101 TEST_API, 102 TEST_CONTROLLED_BY_APP, 103 &output); 104 // TODO: use params to vary token, api, producercontrolledbyapp, etc 105 } 106 107 // Connect to a producer in a 'correct' fashion. 108 // Precondition: Consumer is connected. 109 void ConnectProducer() { 110 ASSERT_OK(TryConnectProducer()); 111 } 112 113 // Create a generic "valid" input for queueBuffer 114 // -- uses the default buffer format, width, etc. 115 static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() { 116 return QueueBufferInputBuilder().build(); 117 } 118 119 // Builder pattern to slightly vary *almost* correct input 120 // -- avoids copying and pasting 121 struct QueueBufferInputBuilder { 122 QueueBufferInputBuilder() { 123 timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP; 124 isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP; 125 dataSpace = QUEUE_BUFFER_INPUT_DATASPACE; 126 crop = QUEUE_BUFFER_INPUT_RECT; 127 scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE; 128 transform = QUEUE_BUFFER_INPUT_TRANSFORM; 129 fence = QUEUE_BUFFER_INPUT_FENCE; 130 } 131 132 IGraphicBufferProducer::QueueBufferInput build() { 133 return IGraphicBufferProducer::QueueBufferInput( 134 timestamp, 135 isAutoTimestamp, 136 dataSpace, 137 crop, 138 scalingMode, 139 transform, 140 fence); 141 } 142 143 QueueBufferInputBuilder& setTimestamp(int64_t timestamp) { 144 this->timestamp = timestamp; 145 return *this; 146 } 147 148 QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) { 149 this->isAutoTimestamp = isAutoTimestamp; 150 return *this; 151 } 152 153 QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) { 154 this->dataSpace = dataSpace; 155 return *this; 156 } 157 158 QueueBufferInputBuilder& setCrop(Rect crop) { 159 this->crop = crop; 160 return *this; 161 } 162 163 QueueBufferInputBuilder& setScalingMode(int scalingMode) { 164 this->scalingMode = scalingMode; 165 return *this; 166 } 167 168 QueueBufferInputBuilder& setTransform(uint32_t transform) { 169 this->transform = transform; 170 return *this; 171 } 172 173 QueueBufferInputBuilder& setFence(sp<Fence> fence) { 174 this->fence = fence; 175 return *this; 176 } 177 178 private: 179 int64_t timestamp; 180 bool isAutoTimestamp; 181 android_dataspace dataSpace; 182 Rect crop; 183 int scalingMode; 184 uint32_t transform; 185 sp<Fence> fence; 186 }; // struct QueueBufferInputBuilder 187 188 // To easily store dequeueBuffer results into containers 189 struct DequeueBufferResult { 190 int slot; 191 sp<Fence> fence; 192 }; 193 194 status_t dequeueBuffer(uint32_t w, uint32_t h, uint32_t format, uint32_t usage, DequeueBufferResult* result) { 195 return mProducer->dequeueBuffer(&result->slot, &result->fence, w, h, format, usage, nullptr); 196 } 197 198 void setupDequeueRequestBuffer(int *slot, sp<Fence> *fence, 199 sp<GraphicBuffer> *buffer) 200 { 201 ASSERT_TRUE(slot != NULL); 202 ASSERT_TRUE(fence != NULL); 203 ASSERT_TRUE(buffer != NULL); 204 205 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 206 207 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & 208 (mProducer->dequeueBuffer(slot, fence, DEFAULT_WIDTH, 209 DEFAULT_HEIGHT, DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS, nullptr))); 210 211 EXPECT_LE(0, *slot); 212 EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, *slot); 213 214 // Request the buffer (pre-requisite for queueing) 215 ASSERT_OK(mProducer->requestBuffer(*slot, buffer)); 216 } 217 218private: // hide from test body 219 sp<DummyConsumer> mDC; 220 221protected: // accessible from test body 222 sp<IGraphicBufferProducer> mProducer; 223 sp<IGraphicBufferConsumer> mConsumer; 224}; 225 226TEST_F(IGraphicBufferProducerTest, ConnectFirst_ReturnsError) { 227 IGraphicBufferProducer::QueueBufferOutput output; 228 229 // NULL output returns BAD_VALUE 230 EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN, 231 TEST_API, 232 TEST_CONTROLLED_BY_APP, 233 /*output*/NULL)); 234 235 // Invalid API returns bad value 236 EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN, 237 /*api*/0xDEADBEEF, 238 TEST_CONTROLLED_BY_APP, 239 &output)); 240 241 // TODO: get a token from a dead process somehow 242} 243 244TEST_F(IGraphicBufferProducerTest, ConnectAgain_ReturnsError) { 245 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 246 247 // Can't connect when there is already a producer connected 248 IGraphicBufferProducer::QueueBufferOutput output; 249 EXPECT_EQ(BAD_VALUE, mProducer->connect(TEST_TOKEN, 250 TEST_API, 251 TEST_CONTROLLED_BY_APP, 252 &output)); 253 254 ASSERT_OK(mConsumer->consumerDisconnect()); 255 // Can't connect when IGBP is abandoned 256 EXPECT_EQ(NO_INIT, mProducer->connect(TEST_TOKEN, 257 TEST_API, 258 TEST_CONTROLLED_BY_APP, 259 &output)); 260} 261 262TEST_F(IGraphicBufferProducerTest, Disconnect_Succeeds) { 263 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 264 265 ASSERT_OK(mProducer->disconnect(TEST_API)); 266} 267 268 269TEST_F(IGraphicBufferProducerTest, Disconnect_ReturnsError) { 270 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 271 272 // Must disconnect with same API number 273 ASSERT_EQ(BAD_VALUE, mProducer->disconnect(TEST_API_OTHER)); 274 // API must not be out of range 275 ASSERT_EQ(BAD_VALUE, mProducer->disconnect(/*api*/0xDEADBEEF)); 276 277 // TODO: somehow kill mProducer so that this returns DEAD_OBJECT 278} 279 280TEST_F(IGraphicBufferProducerTest, Query_Succeeds) { 281 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 282 283 int32_t value = -1; 284 EXPECT_OK(mProducer->query(NATIVE_WINDOW_WIDTH, &value)); 285 EXPECT_EQ(DEFAULT_WIDTH, static_cast<uint32_t>(value)); 286 287 EXPECT_OK(mProducer->query(NATIVE_WINDOW_HEIGHT, &value)); 288 EXPECT_EQ(DEFAULT_HEIGHT, static_cast<uint32_t>(value)); 289 290 EXPECT_OK(mProducer->query(NATIVE_WINDOW_FORMAT, &value)); 291 EXPECT_EQ(DEFAULT_FORMAT, value); 292 293 EXPECT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value)); 294 EXPECT_LE(0, value); 295 EXPECT_GE(BufferQueue::NUM_BUFFER_SLOTS, value); 296 297 EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value)); 298 EXPECT_FALSE(value); // Can't run behind when we haven't touched the queue 299 300 EXPECT_OK(mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value)); 301 EXPECT_EQ(DEFAULT_CONSUMER_USAGE_BITS, value); 302 303} 304 305TEST_F(IGraphicBufferProducerTest, Query_ReturnsError) { 306 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 307 308 // One past the end of the last 'query' enum value. Update this if we add more enums. 309 const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1; 310 311 int value; 312 // What was out of range 313 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/-1, &value)); 314 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/0xDEADBEEF, &value)); 315 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value)); 316 317 // Some enums from window.h are 'invalid' 318 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value)); 319 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value)); 320 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value)); 321 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value)); 322 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value)); 323 // TODO: Consider documented the above enums as unsupported or make a new enum for IGBP 324 325 // Value was NULL 326 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/NULL)); 327 328 ASSERT_OK(mConsumer->consumerDisconnect()); 329 330 // BQ was abandoned 331 EXPECT_EQ(NO_INIT, mProducer->query(NATIVE_WINDOW_FORMAT, &value)); 332 333 // TODO: other things in window.h that are supported by Surface::query 334 // but not by BufferQueue::query 335} 336 337// TODO: queue under more complicated situations not involving just a single buffer 338TEST_F(IGraphicBufferProducerTest, Queue_Succeeds) { 339 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 340 341 int dequeuedSlot = -1; 342 sp<Fence> dequeuedFence; 343 344 345 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & 346 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, 347 DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT, 348 TEST_PRODUCER_USAGE_BITS, nullptr))); 349 350 EXPECT_LE(0, dequeuedSlot); 351 EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, dequeuedSlot); 352 353 // Request the buffer (pre-requisite for queueing) 354 sp<GraphicBuffer> dequeuedBuffer; 355 ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer)); 356 357 // A generic "valid" input 358 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 359 IGraphicBufferProducer::QueueBufferOutput output; 360 361 // Queue the buffer back into the BQ 362 ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output)); 363 364 { 365 EXPECT_EQ(DEFAULT_WIDTH, output.width); 366 EXPECT_EQ(DEFAULT_HEIGHT, output.height); 367 EXPECT_EQ(DEFAULT_TRANSFORM_HINT, output.transformHint); 368 // Since queueBuffer was called exactly once 369 EXPECT_EQ(1u, output.numPendingBuffers); 370 EXPECT_EQ(2u, output.nextFrameNumber); 371 } 372 373 // Buffer was not in the dequeued state 374 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output)); 375} 376 377TEST_F(IGraphicBufferProducerTest, Queue_ReturnsError) { 378 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 379 380 // Invalid slot number 381 { 382 // A generic "valid" input 383 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 384 IGraphicBufferProducer::QueueBufferOutput output; 385 386 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/-1, input, &output)); 387 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0xDEADBEEF, input, &output)); 388 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueue::NUM_BUFFER_SLOTS, 389 input, &output)); 390 } 391 392 // Slot was not in the dequeued state (all slots start out in Free state) 393 { 394 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 395 IGraphicBufferProducer::QueueBufferOutput output; 396 397 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/0, input, &output)); 398 } 399 400 // Put the slot into the "dequeued" state for the rest of the test 401 int dequeuedSlot = -1; 402 sp<Fence> dequeuedFence; 403 404 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & 405 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, 406 DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT, 407 TEST_PRODUCER_USAGE_BITS, nullptr))); 408 409 // Slot was enqueued without requesting a buffer 410 { 411 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 412 IGraphicBufferProducer::QueueBufferOutput output; 413 414 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output)); 415 } 416 417 // Request the buffer so that the rest of the tests don't fail on earlier checks. 418 sp<GraphicBuffer> dequeuedBuffer; 419 ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer)); 420 421 // Fence was NULL 422 { 423 sp<Fence> nullFence = NULL; 424 425 IGraphicBufferProducer::QueueBufferInput input = 426 QueueBufferInputBuilder().setFence(nullFence).build(); 427 IGraphicBufferProducer::QueueBufferOutput output; 428 429 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output)); 430 } 431 432 // Scaling mode was unknown 433 { 434 IGraphicBufferProducer::QueueBufferInput input = 435 QueueBufferInputBuilder().setScalingMode(-1).build(); 436 IGraphicBufferProducer::QueueBufferOutput output; 437 438 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output)); 439 440 input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build(); 441 442 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output)); 443 } 444 445 // Crop rect is out of bounds of the buffer dimensions 446 { 447 IGraphicBufferProducer::QueueBufferInput input = 448 QueueBufferInputBuilder().setCrop(Rect(DEFAULT_WIDTH + 1, DEFAULT_HEIGHT + 1)) 449 .build(); 450 IGraphicBufferProducer::QueueBufferOutput output; 451 452 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(dequeuedSlot, input, &output)); 453 } 454 455 // Abandon the buffer queue so that the last test fails 456 ASSERT_OK(mConsumer->consumerDisconnect()); 457 458 // The buffer queue has been abandoned. 459 { 460 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 461 IGraphicBufferProducer::QueueBufferOutput output; 462 463 EXPECT_EQ(NO_INIT, mProducer->queueBuffer(dequeuedSlot, input, &output)); 464 } 465} 466 467TEST_F(IGraphicBufferProducerTest, CancelBuffer_DoesntCrash) { 468 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 469 470 int dequeuedSlot = -1; 471 sp<Fence> dequeuedFence; 472 473 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & 474 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, 475 DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT, 476 TEST_PRODUCER_USAGE_BITS, nullptr))); 477 478 // No return code, but at least test that it doesn't blow up... 479 // TODO: add a return code 480 mProducer->cancelBuffer(dequeuedSlot, dequeuedFence); 481} 482 483TEST_F(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Succeeds) { 484 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 485 int minUndequeuedBuffers; 486 ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 487 &minUndequeuedBuffers)); 488 489 const int minBuffers = 1; 490 const int maxBuffers = BufferQueue::NUM_BUFFER_SLOTS - minUndequeuedBuffers; 491 492 ASSERT_OK(mProducer->setAsyncMode(false)) << "async mode: " << false; 493 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(minBuffers)) 494 << "bufferCount: " << minBuffers; 495 496 // Should now be able to dequeue up to minBuffers times 497 DequeueBufferResult result; 498 for (int i = 0; i < minBuffers; ++i) { 499 500 EXPECT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & 501 (dequeueBuffer(DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT, 502 TEST_PRODUCER_USAGE_BITS, &result))) 503 << "iteration: " << i << ", slot: " << result.slot; 504 } 505 506 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(maxBuffers)); 507 508 // queue the first buffer to enable max dequeued buffer count checking 509 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 510 IGraphicBufferProducer::QueueBufferOutput output; 511 sp<GraphicBuffer> buffer; 512 ASSERT_OK(mProducer->requestBuffer(result.slot, &buffer)); 513 ASSERT_OK(mProducer->queueBuffer(result.slot, input, &output)); 514 515 516 // Should now be able to dequeue up to maxBuffers times 517 int dequeuedSlot = -1; 518 sp<Fence> dequeuedFence; 519 for (int i = 0; i < maxBuffers; ++i) { 520 521 EXPECT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & 522 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, 523 DEFAULT_WIDTH, DEFAULT_HEIGHT, 524 DEFAULT_FORMAT, 525 TEST_PRODUCER_USAGE_BITS, nullptr))) 526 << "iteration: " << i << ", slot: " << dequeuedSlot; 527 } 528 529 // Cancel a buffer, so we can decrease the buffer count 530 ASSERT_OK(mProducer->cancelBuffer(dequeuedSlot, dequeuedFence)); 531 532 // Should now be able to decrease the max dequeued count by 1 533 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(maxBuffers-1)); 534} 535 536TEST_F(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Fails) { 537 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 538 int minUndequeuedBuffers; 539 ASSERT_OK(mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, 540 &minUndequeuedBuffers)); 541 542 const int minBuffers = 1; 543 const int maxBuffers = BufferQueue::NUM_BUFFER_SLOTS - minUndequeuedBuffers; 544 545 ASSERT_OK(mProducer->setAsyncMode(false)) << "async mode: " << false; 546 // Buffer count was out of range 547 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(0)) 548 << "bufferCount: " << 0; 549 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(maxBuffers + 1)) 550 << "bufferCount: " << maxBuffers + 1; 551 552 // Set max dequeue count to 2 553 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(2)); 554 // Dequeue 2 buffers 555 int dequeuedSlot = -1; 556 sp<Fence> dequeuedFence; 557 for (int i = 0; i < 2; i++) { 558 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & 559 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, 560 DEFAULT_WIDTH, DEFAULT_HEIGHT, 561 DEFAULT_FORMAT, 562 TEST_PRODUCER_USAGE_BITS, nullptr))) 563 << "slot: " << dequeuedSlot; 564 } 565 566 // Client has too many buffers dequeued 567 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1)) 568 << "bufferCount: " << minBuffers; 569 570 // Abandon buffer queue 571 ASSERT_OK(mConsumer->consumerDisconnect()); 572 573 // Fail because the buffer queue was abandoned 574 EXPECT_EQ(NO_INIT, mProducer->setMaxDequeuedBufferCount(minBuffers)) 575 << "bufferCount: " << minBuffers; 576 577} 578 579TEST_F(IGraphicBufferProducerTest, SetAsyncMode_Succeeds) { 580 ASSERT_OK(mConsumer->setMaxAcquiredBufferCount(1)) << "maxAcquire: " << 1; 581 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 582 ASSERT_OK(mProducer->setAsyncMode(true)) << "async mode: " << true; 583 ASSERT_OK(mProducer->setMaxDequeuedBufferCount(1)) << "maxDequeue: " << 1; 584 585 int dequeuedSlot = -1; 586 sp<Fence> dequeuedFence; 587 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 588 IGraphicBufferProducer::QueueBufferOutput output; 589 sp<GraphicBuffer> dequeuedBuffer; 590 591 // Should now be able to queue/dequeue as many buffers as we want without 592 // blocking 593 for (int i = 0; i < 5; ++i) { 594 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & 595 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, 596 DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT, 597 TEST_PRODUCER_USAGE_BITS, nullptr))) 598 << "slot : " << dequeuedSlot; 599 ASSERT_OK(mProducer->requestBuffer(dequeuedSlot, &dequeuedBuffer)); 600 ASSERT_OK(mProducer->queueBuffer(dequeuedSlot, input, &output)); 601 } 602} 603 604TEST_F(IGraphicBufferProducerTest, SetAsyncMode_Fails) { 605 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 606 // Prerequisite to fail out a valid setBufferCount call 607 { 608 int dequeuedSlot = -1; 609 sp<Fence> dequeuedFence; 610 611 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & 612 (mProducer->dequeueBuffer(&dequeuedSlot, &dequeuedFence, 613 DEFAULT_WIDTH, DEFAULT_HEIGHT, DEFAULT_FORMAT, 614 TEST_PRODUCER_USAGE_BITS, nullptr))) 615 << "slot: " << dequeuedSlot; 616 } 617 618 // Abandon buffer queue 619 ASSERT_OK(mConsumer->consumerDisconnect()); 620 621 // Fail because the buffer queue was abandoned 622 EXPECT_EQ(NO_INIT, mProducer->setAsyncMode(false)) << "asyncMode: " 623 << false; 624} 625 626TEST_F(IGraphicBufferProducerTest, 627 DisconnectedProducerReturnsError_dequeueBuffer) { 628 int slot = -1; 629 sp<Fence> fence; 630 631 ASSERT_EQ(NO_INIT, mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, 632 DEFAULT_HEIGHT, DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS, nullptr)); 633} 634 635TEST_F(IGraphicBufferProducerTest, 636 DisconnectedProducerReturnsError_detachNextBuffer) { 637 sp<Fence> fence; 638 sp<GraphicBuffer> buffer; 639 640 ASSERT_EQ(NO_INIT, mProducer->detachNextBuffer(&buffer, &fence)); 641} 642 643TEST_F(IGraphicBufferProducerTest, 644 DisconnectedProducerReturnsError_requestBuffer) { 645 ASSERT_NO_FATAL_FAILURE(ConnectProducer()); 646 647 int slot = -1; 648 sp<Fence> fence; 649 650 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & 651 (mProducer->dequeueBuffer(&slot, &fence, DEFAULT_WIDTH, 652 DEFAULT_HEIGHT, DEFAULT_FORMAT, TEST_PRODUCER_USAGE_BITS, 653 nullptr))); 654 655 EXPECT_LE(0, slot); 656 EXPECT_GT(BufferQueue::NUM_BUFFER_SLOTS, slot); 657 658 ASSERT_OK(mProducer->disconnect(TEST_API)); 659 660 sp<GraphicBuffer> buffer; 661 662 ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer)); 663} 664 665 666TEST_F(IGraphicBufferProducerTest, 667 DisconnectedProducerReturnsError_detachBuffer) { 668 int slot = -1; 669 sp<Fence> fence; 670 sp<GraphicBuffer> buffer; 671 672 setupDequeueRequestBuffer(&slot, &fence, &buffer); 673 674 ASSERT_OK(mProducer->disconnect(TEST_API)); 675 676 ASSERT_EQ(NO_INIT, mProducer->detachBuffer(slot)); 677} 678 679TEST_F(IGraphicBufferProducerTest, 680 DisconnectedProducerReturnsError_queueBuffer) { 681 int slot = -1; 682 sp<Fence> fence; 683 sp<GraphicBuffer> buffer; 684 685 setupDequeueRequestBuffer(&slot, &fence, &buffer); 686 687 ASSERT_OK(mProducer->disconnect(TEST_API)); 688 689 // A generic "valid" input 690 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); 691 IGraphicBufferProducer::QueueBufferOutput output; 692 693 ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output)); 694} 695 696TEST_F(IGraphicBufferProducerTest, 697 DisconnectedProducerReturnsError_cancelBuffer) { 698 int slot = -1; 699 sp<Fence> fence; 700 sp<GraphicBuffer> buffer; 701 702 setupDequeueRequestBuffer(&slot, &fence, &buffer); 703 704 ASSERT_OK(mProducer->disconnect(TEST_API)); 705 706 ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, fence)); 707} 708 709TEST_F(IGraphicBufferProducerTest, 710 DisconnectedProducerReturnsError_attachBuffer) { 711 int slot = -1; 712 sp<Fence> fence; 713 sp<GraphicBuffer> buffer; 714 715 setupDequeueRequestBuffer(&slot, &fence, &buffer); 716 717 ASSERT_OK(mProducer->detachBuffer(slot)); 718 719 ASSERT_OK(mProducer->disconnect(TEST_API)); 720 721 ASSERT_EQ(NO_INIT, mProducer->attachBuffer(&slot, buffer)); 722} 723 724} // namespace android 725