blob: 64034e880042d6f59dd1b2306ab3d7e2ea445d5a [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include <private/dvr/buffer_hub_queue_producer.h>
2
3#include <base/logging.h>
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -07004#include <gui/IProducerListener.h>
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08005#include <gui/Surface.h>
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -07006
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08007#include <gtest/gtest.h>
8
9namespace android {
10namespace dvr {
11
12namespace {
13
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -070014// Default dimensions before setDefaultBufferSize is called by the consumer.
15constexpr uint32_t kDefaultWidth = 1;
16constexpr uint32_t kDefaultHeight = 1;
Alex Vakulenkoe4eec202017-01-27 14:41:04 -080017
Jiwen 'Steve' Cai1601bcf2017-03-24 14:03:06 -070018// Default format before setDefaultBufferFormat is called by the consumer.
19constexpr PixelFormat kDefaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
20constexpr int kDefaultConsumerUsageBits = 0;
21
22// Default transform hint before setTransformHint is called by the consumer.
23constexpr uint32_t kDefaultTransformHint = 0;
24
25constexpr int kTestApi = NATIVE_WINDOW_API_CPU;
26constexpr int kTestApiOther = NATIVE_WINDOW_API_EGL;
27constexpr int kTestApiInvalid = 0xDEADBEEF;
28constexpr int kTestProducerUsageBits = 0;
29constexpr bool kTestControlledByApp = true;
30
31// Builder pattern to slightly vary *almost* correct input
32// -- avoids copying and pasting
33struct QueueBufferInputBuilder {
34 IGraphicBufferProducer::QueueBufferInput build() {
35 return IGraphicBufferProducer::QueueBufferInput(
36 mTimestamp, mIsAutoTimestamp, mDataSpace, mCrop, mScalingMode,
37 mTransform, mFence);
38 }
39
40 QueueBufferInputBuilder& setTimestamp(int64_t timestamp) {
41 this->mTimestamp = timestamp;
42 return *this;
43 }
44
45 QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) {
46 this->mIsAutoTimestamp = isAutoTimestamp;
47 return *this;
48 }
49
50 QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
51 this->mDataSpace = dataSpace;
52 return *this;
53 }
54
55 QueueBufferInputBuilder& setCrop(Rect crop) {
56 this->mCrop = crop;
57 return *this;
58 }
59
60 QueueBufferInputBuilder& setScalingMode(int scalingMode) {
61 this->mScalingMode = scalingMode;
62 return *this;
63 }
64
65 QueueBufferInputBuilder& setTransform(uint32_t transform) {
66 this->mTransform = transform;
67 return *this;
68 }
69
70 QueueBufferInputBuilder& setFence(sp<Fence> fence) {
71 this->mFence = fence;
72 return *this;
73 }
74
75 private:
76 int64_t mTimestamp{1384888611};
77 bool mIsAutoTimestamp{false};
78 android_dataspace mDataSpace{HAL_DATASPACE_UNKNOWN};
79 Rect mCrop{Rect(kDefaultWidth, kDefaultHeight)};
80 int mScalingMode{0};
81 uint32_t mTransform{0};
82 sp<Fence> mFence{Fence::NO_FENCE};
83};
84
85// This is a test that covers our implementation of bufferhubqueue-based
86// IGraphicBufferProducer.
87class BufferHubQueueProducerTest : public ::testing::Test {
88 protected:
89 virtual void SetUp() {
90 const ::testing::TestInfo* const testInfo =
91 ::testing::UnitTest::GetInstance()->current_test_info();
92 ALOGD_IF(TRACE, "Begin test: %s.%s", testInfo->test_case_name(),
93 testInfo->name());
94
95 auto core = BufferHubQueueCore::Create();
96 mProducer = new BufferHubQueueProducer(core);
97 ASSERT_TRUE(mProducer != nullptr);
98 mSurface = new Surface(mProducer, true);
99 ASSERT_TRUE(mSurface != nullptr);
100 }
101
102 // Connect to a producer in a 'correct' fashion.
103 void ConnectProducer() {
104 IGraphicBufferProducer::QueueBufferOutput output;
105 // Can connect the first time.
106 ASSERT_EQ(NO_ERROR, mProducer->connect(kDummyListener, kTestApi,
107 kTestControlledByApp, &output));
108 }
109
110 // Dequeue a buffer in a 'correct' fashion.
111 // Precondition: Producer is connected.
112 void DequeueBuffer(int* outSlot) {
113 sp<Fence> fence;
114 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(outSlot, &fence));
115 }
116
117 void DequeueBuffer(int* outSlot, sp<Fence>* outFence) {
118 ASSERT_NE(nullptr, outSlot);
119 ASSERT_NE(nullptr, outFence);
120
121 int ret = mProducer->dequeueBuffer(outSlot, outFence, kDefaultWidth,
122 kDefaultHeight, kDefaultFormat,
123 kTestProducerUsageBits, nullptr);
124 // BUFFER_NEEDS_REALLOCATION can be either on or off.
125 ASSERT_EQ(0, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & ret);
126
127 // Slot number should be in boundary.
128 ASSERT_LE(0, *outSlot);
129 ASSERT_GT(BufferQueueDefs::NUM_BUFFER_SLOTS, *outSlot);
130 }
131
132 // Create a generic "valid" input for queueBuffer
133 // -- uses the default buffer format, width, etc.
134 static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
135 return QueueBufferInputBuilder().build();
136 }
137
138 const sp<IProducerListener> kDummyListener{new DummyProducerListener};
139
140 sp<BufferHubQueueProducer> mProducer;
141 sp<Surface> mSurface;
142};
143
144TEST_F(BufferHubQueueProducerTest, ConnectFirst_ReturnsError) {
145 IGraphicBufferProducer::QueueBufferOutput output;
146
147 // NULL output returns BAD_VALUE
148 EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApi,
149 kTestControlledByApp, nullptr));
150
151 // Invalid API returns bad value
152 EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApiInvalid,
153 kTestControlledByApp, &output));
154}
155
156TEST_F(BufferHubQueueProducerTest, ConnectAgain_ReturnsError) {
157 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
158
159 // Can't connect when there is already a producer connected.
160 IGraphicBufferProducer::QueueBufferOutput output;
161 EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApi,
162 kTestControlledByApp, &output));
163}
164
165TEST_F(BufferHubQueueProducerTest, Disconnect_Succeeds) {
166 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
167
168 ASSERT_EQ(NO_ERROR, mProducer->disconnect(kTestApi));
169}
170
171TEST_F(BufferHubQueueProducerTest, Disconnect_ReturnsError) {
172 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
173
174 // Must disconnect with same API number
175 EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiOther));
176 // API must not be out of range
177 EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiInvalid));
178}
179
180TEST_F(BufferHubQueueProducerTest, Query_Succeeds) {
181 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
182
183 int32_t value = -1;
184 EXPECT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_WIDTH, &value));
185 EXPECT_EQ(kDefaultWidth, static_cast<uint32_t>(value));
186
187 EXPECT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
188 EXPECT_EQ(kDefaultHeight, static_cast<uint32_t>(value));
189
190 EXPECT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_FORMAT, &value));
191 EXPECT_EQ(kDefaultFormat, value);
192
193 EXPECT_EQ(NO_ERROR,
194 mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value));
195 EXPECT_LE(0, value);
196 EXPECT_GE(BufferQueueDefs::NUM_BUFFER_SLOTS, static_cast<size_t>(value));
197
198 EXPECT_EQ(NO_ERROR,
199 mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value));
200 EXPECT_FALSE(value); // Can't run behind when we haven't touched the queue
201
202 EXPECT_EQ(NO_ERROR,
203 mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value));
204 EXPECT_EQ(kDefaultConsumerUsageBits, value);
205}
206
207TEST_F(BufferHubQueueProducerTest, Query_ReturnsError) {
208 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
209
210 // One past the end of the last 'query' enum value. Update this if we add more
211 // enums.
212 const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1;
213
214 int value;
215 // What was out of range
216 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ -1, &value));
217 EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ 0xDEADBEEF, &value));
218 EXPECT_EQ(BAD_VALUE,
219 mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value));
220
221 // Some enums from window.h are 'invalid'
222 EXPECT_EQ(BAD_VALUE,
223 mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value));
224 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value));
225 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value));
226 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value));
227 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value));
228
229 // Value was NULL
230 EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/ NULL));
231}
232
233TEST_F(BufferHubQueueProducerTest, Queue_Succeeds) {
234 int slot = -1;
235
236 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
237 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
238
239 // Request the buffer (pre-requisite for queueing)
240 sp<GraphicBuffer> buffer;
241 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
242
243 // A generic "valid" input
244 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
245 IGraphicBufferProducer::QueueBufferOutput output;
246
247 // Queue the buffer back into the BQ
248 ASSERT_EQ(NO_ERROR, mProducer->queueBuffer(slot, input, &output));
249
250 EXPECT_EQ(kDefaultWidth, output.width);
251 EXPECT_EQ(kDefaultHeight, output.height);
252 EXPECT_EQ(kDefaultTransformHint, output.transformHint);
253
254 // BufferHubQueue delivers buffers to consumer immediately.
255 EXPECT_EQ(0u, output.numPendingBuffers);
256
257 // Note that BufferHubQueue doesn't support nextFrameNumber as it seems to
258 // be a SurfaceFlinger specific optimization.
259 EXPECT_EQ(0u, output.nextFrameNumber);
260
261 // Buffer was not in the dequeued state
262 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
263}
264
265// Test invalid slot number
266TEST_F(BufferHubQueueProducerTest, QueueInvalidSlot_ReturnsError) {
267 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
268
269 // A generic "valid" input
270 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
271 IGraphicBufferProducer::QueueBufferOutput output;
272
273 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ -1, input, &output));
274 EXPECT_EQ(BAD_VALUE,
275 mProducer->queueBuffer(/*slot*/ 0xDEADBEEF, input, &output));
276 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueueDefs::NUM_BUFFER_SLOTS,
277 input, &output));
278}
279
280// Slot was not in the dequeued state (all slots start out in Free state)
281TEST_F(BufferHubQueueProducerTest, QueueNotDequeued_ReturnsError) {
282 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
283
284 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
285 IGraphicBufferProducer::QueueBufferOutput output;
286
287 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ 0, input, &output));
288}
289
290// Slot was enqueued without requesting a buffer
291TEST_F(BufferHubQueueProducerTest, QueueNotRequested_ReturnsError) {
292 int slot = -1;
293
294 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
295 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
296
297 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
298 IGraphicBufferProducer::QueueBufferOutput output;
299
300 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
301}
302
303// Test when fence was NULL
304TEST_F(BufferHubQueueProducerTest, QueueNoFence_ReturnsError) {
305 int slot = -1;
306
307 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
308 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
309
310 sp<GraphicBuffer> buffer;
311 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
312
313 sp<Fence> nullFence = NULL;
314
315 IGraphicBufferProducer::QueueBufferInput input =
316 QueueBufferInputBuilder().setFence(nullFence).build();
317 IGraphicBufferProducer::QueueBufferOutput output;
318
319 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
320}
321
322// Test scaling mode was invalid
323TEST_F(BufferHubQueueProducerTest, QueueTestInvalidScalingMode_ReturnsError) {
324 int slot = -1;
325
326 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
327 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
328
329 sp<GraphicBuffer> buffer;
330 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
331
332 IGraphicBufferProducer::QueueBufferInput input =
333 QueueBufferInputBuilder().setScalingMode(-1).build();
334 IGraphicBufferProducer::QueueBufferOutput output;
335
336 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
337
338 input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build();
339
340 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
341}
342
343// Test crop rect is out of bounds of the buffer dimensions
344TEST_F(BufferHubQueueProducerTest, QueueCropOutOfBounds_ReturnsError) {
345 int slot = -1;
346
347 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
348 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
349
350 sp<GraphicBuffer> buffer;
351 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
352
353 IGraphicBufferProducer::QueueBufferInput input =
354 QueueBufferInputBuilder()
355 .setCrop(Rect(kDefaultWidth + 1, kDefaultHeight + 1))
356 .build();
357 IGraphicBufferProducer::QueueBufferOutput output;
358
359 EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
360}
361
362TEST_F(BufferHubQueueProducerTest, CancelBuffer_Succeeds) {
363 int slot = -1;
364 sp<Fence> fence;
365
366 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
367 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence));
368
369 // Should be able to cancel buffer after a dequeue.
370 EXPECT_EQ(NO_ERROR, mProducer->cancelBuffer(slot, fence));
371}
372
373TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Succeeds) {
374 return;
375 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
376
377 int minUndequeuedBuffers;
378 ASSERT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
379 &minUndequeuedBuffers));
380
381 const int minBuffers = 1;
382 const int maxBuffers =
383 BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
384
385 ASSERT_EQ(NO_ERROR, mProducer->setAsyncMode(false))
386 << "async mode: " << false;
387 ASSERT_EQ(NO_ERROR, mProducer->setMaxDequeuedBufferCount(minBuffers))
388 << "bufferCount: " << minBuffers;
389
390 // Should now be able to dequeue up to minBuffers times
391 // Should now be able to dequeue up to maxBuffers times
392 int slot = -1;
393 for (int i = 0; i < minBuffers; ++i) {
394 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
395 }
396
397 ASSERT_EQ(NO_ERROR, mProducer->setMaxDequeuedBufferCount(maxBuffers));
398
399 // queue the first buffer to enable max dequeued buffer count checking
400 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
401 IGraphicBufferProducer::QueueBufferOutput output;
402 sp<GraphicBuffer> buffer;
403 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
404 ASSERT_EQ(NO_ERROR, mProducer->queueBuffer(slot, input, &output));
405
406 sp<Fence> fence;
407 for (int i = 0; i < maxBuffers; ++i) {
408 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence));
409 }
410
411 // Cancel a buffer, so we can decrease the buffer count
412 ASSERT_EQ(NO_ERROR, mProducer->cancelBuffer(slot, fence));
413
414 // Should now be able to decrease the max dequeued count by 1
415 ASSERT_EQ(NO_ERROR, mProducer->setMaxDequeuedBufferCount(maxBuffers - 1));
416}
417
418TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Fails) {
419 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
420
421 int minUndequeuedBuffers;
422 ASSERT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
423 &minUndequeuedBuffers));
424
425 const int minBuffers = 1;
426 const int maxBuffers =
427 BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
428
429 ASSERT_EQ(NO_ERROR, mProducer->setAsyncMode(false))
430 << "async mode: " << false;
431 // Buffer count was out of range
432 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(0))
433 << "bufferCount: " << 0;
434 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(maxBuffers + 1))
435 << "bufferCount: " << maxBuffers + 1;
436
437 // Set max dequeue count to 2
438 ASSERT_EQ(NO_ERROR, mProducer->setMaxDequeuedBufferCount(2));
439 // Dequeue 2 buffers
440 int slot = -1;
441 sp<Fence> fence;
442 for (int i = 0; i < 2; i++) {
443 ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
444 (mProducer->dequeueBuffer(
445 &slot, &fence, kDefaultWidth, kDefaultHeight,
446 kDefaultFormat, kTestProducerUsageBits, nullptr)))
447 << "slot: " << slot;
448 }
449
450 // Client has too many buffers dequeued
451 EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1))
452 << "bufferCount: " << minBuffers;
453}
454
455TEST_F(BufferHubQueueProducerTest,
456 DisconnectedProducerReturnsError_dequeueBuffer) {
457 int slot = -1;
458 sp<Fence> fence;
459
460 ASSERT_EQ(NO_INIT, mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth,
461 kDefaultHeight, kDefaultFormat,
462 kTestProducerUsageBits, nullptr));
463}
464
465TEST_F(BufferHubQueueProducerTest,
466 DisconnectedProducerReturnsError_requestBuffer) {
467 int slot = -1;
468 sp<GraphicBuffer> buffer;
469
470 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
471 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
472
473 // Shouldn't be able to request buffer after disconnect.
474 ASSERT_EQ(NO_ERROR, mProducer->disconnect(kTestApi));
475 ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer));
476}
477
478TEST_F(BufferHubQueueProducerTest,
479 DisconnectedProducerReturnsError_queueBuffer) {
480 int slot = -1;
481 sp<GraphicBuffer> buffer;
482
483 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
484 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
485 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
486
487 // A generic "valid" input
488 IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
489 IGraphicBufferProducer::QueueBufferOutput output;
490
491 // Shouldn't be able to queue buffer after disconnect.
492 ASSERT_EQ(NO_ERROR, mProducer->disconnect(kTestApi));
493 ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output));
494}
495
496TEST_F(BufferHubQueueProducerTest,
497 DisconnectedProducerReturnsError_cancelBuffer) {
498 int slot = -1;
499 sp<GraphicBuffer> buffer;
500
501 ASSERT_NO_FATAL_FAILURE(ConnectProducer());
502 ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
503 ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
504
505 // Shouldn't be able to cancel buffer after disconnect.
506 ASSERT_EQ(NO_ERROR, mProducer->disconnect(kTestApi));
507 ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, Fence::NO_FENCE));
Alex Vakulenkoe4eec202017-01-27 14:41:04 -0800508}
509
510} // namespace
511
512} // namespace dvr
513} // namespace android