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