StreamSplitter_test.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. * Copyright 2014 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. #define LOG_TAG "StreamSplitter_test"
  17. //#define LOG_NDEBUG 0
  18. #include <gui/BufferItem.h>
  19. #include <gui/BufferQueue.h>
  20. #include <gui/IConsumerListener.h>
  21. #include <gui/ISurfaceComposer.h>
  22. #include <gui/StreamSplitter.h>
  23. #include <private/gui/ComposerService.h>
  24. #include <gtest/gtest.h>
  25. namespace android {
  26. class StreamSplitterTest : public ::testing::Test {
  27. protected:
  28. StreamSplitterTest() {
  29. const ::testing::TestInfo* const testInfo =
  30. ::testing::UnitTest::GetInstance()->current_test_info();
  31. ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
  32. testInfo->name());
  33. }
  34. ~StreamSplitterTest() {
  35. const ::testing::TestInfo* const testInfo =
  36. ::testing::UnitTest::GetInstance()->current_test_info();
  37. ALOGV("End test: %s.%s", testInfo->test_case_name(),
  38. testInfo->name());
  39. }
  40. };
  41. struct DummyListener : public BnConsumerListener {
  42. virtual void onFrameAvailable(const BufferItem& /* item */) {}
  43. virtual void onBuffersReleased() {}
  44. virtual void onSidebandStreamChanged() {}
  45. };
  46. class CountedAllocator : public BnGraphicBufferAlloc {
  47. public:
  48. CountedAllocator() : mAllocCount(0) {
  49. sp<ISurfaceComposer> composer(ComposerService::getComposerService());
  50. mAllocator = composer->createGraphicBufferAlloc();
  51. }
  52. virtual ~CountedAllocator() {}
  53. virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
  54. PixelFormat format, uint32_t usage, status_t* error) {
  55. ++mAllocCount;
  56. sp<GraphicBuffer> buffer = mAllocator->createGraphicBuffer(w, h, format,
  57. usage, error);
  58. return buffer;
  59. }
  60. int getAllocCount() const { return mAllocCount; }
  61. private:
  62. sp<IGraphicBufferAlloc> mAllocator;
  63. int mAllocCount;
  64. };
  65. static const uint32_t TEST_DATA = 0x12345678u;
  66. TEST_F(StreamSplitterTest, OneInputOneOutput) {
  67. sp<CountedAllocator> allocator(new CountedAllocator);
  68. sp<IGraphicBufferProducer> inputProducer;
  69. sp<IGraphicBufferConsumer> inputConsumer;
  70. BufferQueue::createBufferQueue(&inputProducer, &inputConsumer, allocator);
  71. sp<IGraphicBufferProducer> outputProducer;
  72. sp<IGraphicBufferConsumer> outputConsumer;
  73. BufferQueue::createBufferQueue(&outputProducer, &outputConsumer, allocator);
  74. ASSERT_EQ(OK, outputConsumer->consumerConnect(new DummyListener, false));
  75. sp<StreamSplitter> splitter;
  76. status_t status = StreamSplitter::createSplitter(inputConsumer, &splitter);
  77. ASSERT_EQ(OK, status);
  78. ASSERT_EQ(OK, splitter->addOutput(outputProducer));
  79. IGraphicBufferProducer::QueueBufferOutput qbOutput;
  80. ASSERT_EQ(OK, inputProducer->connect(new DummyProducerListener,
  81. NATIVE_WINDOW_API_CPU, false, &qbOutput));
  82. int slot;
  83. sp<Fence> fence;
  84. sp<GraphicBuffer> buffer;
  85. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  86. inputProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
  87. GRALLOC_USAGE_SW_WRITE_OFTEN));
  88. ASSERT_EQ(OK, inputProducer->requestBuffer(slot, &buffer));
  89. uint32_t* dataIn;
  90. ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
  91. reinterpret_cast<void**>(&dataIn)));
  92. *dataIn = TEST_DATA;
  93. ASSERT_EQ(OK, buffer->unlock());
  94. IGraphicBufferProducer::QueueBufferInput qbInput(0, false,
  95. HAL_DATASPACE_UNKNOWN,
  96. Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false,
  97. Fence::NO_FENCE);
  98. ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput));
  99. BufferItem item;
  100. ASSERT_EQ(OK, outputConsumer->acquireBuffer(&item, 0));
  101. uint32_t* dataOut;
  102. ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
  103. reinterpret_cast<void**>(&dataOut)));
  104. ASSERT_EQ(*dataOut, TEST_DATA);
  105. ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
  106. ASSERT_EQ(OK, outputConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
  107. EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
  108. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  109. inputProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
  110. GRALLOC_USAGE_SW_WRITE_OFTEN));
  111. ASSERT_EQ(1, allocator->getAllocCount());
  112. }
  113. TEST_F(StreamSplitterTest, OneInputMultipleOutputs) {
  114. const int NUM_OUTPUTS = 4;
  115. sp<CountedAllocator> allocator(new CountedAllocator);
  116. sp<IGraphicBufferProducer> inputProducer;
  117. sp<IGraphicBufferConsumer> inputConsumer;
  118. BufferQueue::createBufferQueue(&inputProducer, &inputConsumer, allocator);
  119. sp<IGraphicBufferProducer> outputProducers[NUM_OUTPUTS] = {};
  120. sp<IGraphicBufferConsumer> outputConsumers[NUM_OUTPUTS] = {};
  121. for (int output = 0; output < NUM_OUTPUTS; ++output) {
  122. BufferQueue::createBufferQueue(&outputProducers[output],
  123. &outputConsumers[output], allocator);
  124. ASSERT_EQ(OK, outputConsumers[output]->consumerConnect(
  125. new DummyListener, false));
  126. }
  127. sp<StreamSplitter> splitter;
  128. status_t status = StreamSplitter::createSplitter(inputConsumer, &splitter);
  129. ASSERT_EQ(OK, status);
  130. for (int output = 0; output < NUM_OUTPUTS; ++output) {
  131. ASSERT_EQ(OK, splitter->addOutput(outputProducers[output]));
  132. }
  133. IGraphicBufferProducer::QueueBufferOutput qbOutput;
  134. ASSERT_EQ(OK, inputProducer->connect(new DummyProducerListener,
  135. NATIVE_WINDOW_API_CPU, false, &qbOutput));
  136. int slot;
  137. sp<Fence> fence;
  138. sp<GraphicBuffer> buffer;
  139. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  140. inputProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
  141. GRALLOC_USAGE_SW_WRITE_OFTEN));
  142. ASSERT_EQ(OK, inputProducer->requestBuffer(slot, &buffer));
  143. uint32_t* dataIn;
  144. ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
  145. reinterpret_cast<void**>(&dataIn)));
  146. *dataIn = TEST_DATA;
  147. ASSERT_EQ(OK, buffer->unlock());
  148. IGraphicBufferProducer::QueueBufferInput qbInput(0, false,
  149. HAL_DATASPACE_UNKNOWN,
  150. Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false,
  151. Fence::NO_FENCE);
  152. ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput));
  153. for (int output = 0; output < NUM_OUTPUTS; ++output) {
  154. BufferItem item;
  155. ASSERT_EQ(OK, outputConsumers[output]->acquireBuffer(&item, 0));
  156. uint32_t* dataOut;
  157. ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
  158. reinterpret_cast<void**>(&dataOut)));
  159. ASSERT_EQ(*dataOut, TEST_DATA);
  160. ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
  161. ASSERT_EQ(OK, outputConsumers[output]->releaseBuffer(item.mBuf,
  162. item.mFrameNumber, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR,
  163. Fence::NO_FENCE));
  164. }
  165. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  166. inputProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
  167. GRALLOC_USAGE_SW_WRITE_OFTEN));
  168. ASSERT_EQ(1, allocator->getAllocCount());
  169. }
  170. TEST_F(StreamSplitterTest, OutputAbandonment) {
  171. sp<IGraphicBufferProducer> inputProducer;
  172. sp<IGraphicBufferConsumer> inputConsumer;
  173. BufferQueue::createBufferQueue(&inputProducer, &inputConsumer);
  174. sp<IGraphicBufferProducer> outputProducer;
  175. sp<IGraphicBufferConsumer> outputConsumer;
  176. BufferQueue::createBufferQueue(&outputProducer, &outputConsumer);
  177. ASSERT_EQ(OK, outputConsumer->consumerConnect(new DummyListener, false));
  178. sp<StreamSplitter> splitter;
  179. status_t status = StreamSplitter::createSplitter(inputConsumer, &splitter);
  180. ASSERT_EQ(OK, status);
  181. ASSERT_EQ(OK, splitter->addOutput(outputProducer));
  182. IGraphicBufferProducer::QueueBufferOutput qbOutput;
  183. ASSERT_EQ(OK, inputProducer->connect(new DummyProducerListener,
  184. NATIVE_WINDOW_API_CPU, false, &qbOutput));
  185. int slot;
  186. sp<Fence> fence;
  187. sp<GraphicBuffer> buffer;
  188. ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
  189. inputProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
  190. GRALLOC_USAGE_SW_WRITE_OFTEN));
  191. ASSERT_EQ(OK, inputProducer->requestBuffer(slot, &buffer));
  192. // Abandon the output
  193. outputConsumer->consumerDisconnect();
  194. IGraphicBufferProducer::QueueBufferInput qbInput(0, false,
  195. HAL_DATASPACE_UNKNOWN,
  196. Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false,
  197. Fence::NO_FENCE);
  198. ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput));
  199. // Input should be abandoned
  200. ASSERT_EQ(NO_INIT, inputProducer->dequeueBuffer(&slot, &fence, false, 0, 0,
  201. 0, GRALLOC_USAGE_SW_WRITE_OFTEN));
  202. }
  203. } // namespace android