10129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang/*
20129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang * Copyright 2014,2016 The Android Open Source Project
30129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang *
40129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang * Licensed under the Apache License, Version 2.0 (the "License");
50129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang * you may not use this file except in compliance with the License.
60129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang * You may obtain a copy of the License at
70129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang *
80129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang *      http://www.apache.org/licenses/LICENSE-2.0
90129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang *
100129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang * Unless required by applicable law or agreed to in writing, software
110129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang * distributed under the License is distributed on an "AS IS" BASIS,
120129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang * See the License for the specific language governing permissions and
140129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang * limitations under the License.
150129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang */
160129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
170129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang#ifndef ANDROID_SERVERS_STREAMSPLITTER_H
180129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang#define ANDROID_SERVERS_STREAMSPLITTER_H
190129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
200129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang#include <gui/IConsumerListener.h>
210129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang#include <gui/IProducerListener.h>
220129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang#include <gui/BufferItemConsumer.h>
230129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
240129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang#include <utils/Condition.h>
250129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang#include <utils/Mutex.h>
260129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang#include <utils/StrongPointer.h>
270129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang#include <utils/Timers.h>
280129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
29bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang#define SP_LOGV(x, ...) ALOGV("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
30bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang#define SP_LOGI(x, ...) ALOGI("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
31bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang#define SP_LOGW(x, ...) ALOGW("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
32bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang#define SP_LOGE(x, ...) ALOGE("[%s] " x, mConsumerName.string(), ##__VA_ARGS__)
33bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang
340129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wangnamespace android {
350129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
360129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wangclass GraphicBuffer;
370129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wangclass IGraphicBufferConsumer;
380129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wangclass IGraphicBufferProducer;
390129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
400129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang// Camera3StreamSplitter is an autonomous class that manages one input BufferQueue
410129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang// and multiple output BufferQueues. By using the buffer attach and detach logic
420129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang// in BufferQueue, it is able to present the illusion of a single split
430129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang// BufferQueue, where each buffer queued to the input is available to be
440129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang// acquired by each of the outputs, and is able to be dequeued by the input
450129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang// again only once all of the outputs have released it.
460129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wangclass Camera3StreamSplitter : public BnConsumerListener {
470129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wangpublic:
480129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
490129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // Constructor
500129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    Camera3StreamSplitter() = default;
510129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
520129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // Connect to the stream splitter by creating buffer queue and connecting it
530129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // with output surfaces.
540129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    status_t connect(const std::vector<sp<Surface> >& surfaces,
55050f5dcf7d1903926b165ebdd2dd30f7a2e83c02Emilian Peev            uint64_t consumerUsage, size_t halMaxBuffers,
56bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang            sp<Surface>* consumer);
570129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
580129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // addOutput adds an output BufferQueue to the splitter. The splitter
590129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // connects to outputQueue as a CPU producer, and any buffers queued
600129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // to the input will be queued to each output. It is assumed that all of the
610129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // outputs are added before any buffers are queued on the input. If any
620129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // output is abandoned by its consumer, the splitter will abandon its input
630129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // queue (see onAbandoned).
640129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    //
650129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // A return value other than NO_ERROR means that an error has occurred and
660129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // outputQueue has not been added to the splitter. BAD_VALUE is returned if
670129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // outputQueue is NULL. See IGraphicBufferProducer::connect for explanations
680129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // of other error codes.
69bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    status_t addOutput(const sp<Surface>& outputQueue);
70bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang
71bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // Notification that the graphic buffer has been released to the input
72bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // BufferQueue. The buffer should be reused by the camera device instead of
73bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // queuing to the outputs.
74bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    status_t notifyBufferReleased(const sp<GraphicBuffer>& buffer);
75bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang
76bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // Attach a buffer to the specified outputs. This call reserves a buffer
77bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // slot in the output queue.
78bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    status_t attachBufferToOutputs(ANativeWindowBuffer* anb,
79bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang            const std::vector<size_t>& surface_ids);
800129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
81bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // Get return value of onFrameAvailable to work around problem that
82bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // onFrameAvailable is void. This function should be called by the producer
83bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // right after calling queueBuffer().
84bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    status_t getOnFrameAvailableResult();
850129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
860129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // Disconnect the buffer queue from output surfaces.
870129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    void disconnect();
880129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
890129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wangprivate:
900129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // From IConsumerListener
910129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    //
920129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // During this callback, we store some tracking information, detach the
930129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // buffer from the input, and attach it to each of the outputs. This call
940129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // can block if there are too many outstanding buffers. If it blocks, it
950129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // will resume when onBufferReleasedByOutput releases a buffer back to the
960129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // input.
970129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    void onFrameAvailable(const BufferItem& item) override;
980129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
990129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // From IConsumerListener
1000129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // We don't care about released buffers because we detach each buffer as
1010129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // soon as we acquire it. See the comment for onBufferReleased below for
1020129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // some clarifying notes about the name.
1030129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    void onBuffersReleased() override {}
1040129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
1050129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // From IConsumerListener
1060129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // We don't care about sideband streams, since we won't be splitting them
1070129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    void onSidebandStreamChanged() override {}
1080129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
1090129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // This is the implementation of the onBufferReleased callback from
1100129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // IProducerListener. It gets called from an OutputListener (see below), and
1110129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // 'from' is which producer interface from which the callback was received.
1120129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    //
1130129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // During this callback, we detach the buffer from the output queue that
1140129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // generated the callback, update our state tracking to see if this is the
1150129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // last output releasing the buffer, and if so, release it to the input.
1160129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // If we release the buffer to the input, we allow a blocked
1170129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // onFrameAvailable call to proceed.
1180129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    void onBufferReleasedByOutput(const sp<IGraphicBufferProducer>& from);
1190129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
120a141c5f3cc2214a96f250999edacc3bd4d454601Shuzhen Wang    // This is the implementation of onBufferReleasedByOutput without the mutex locked.
121a141c5f3cc2214a96f250999edacc3bd4d454601Shuzhen Wang    // It could either be called from onBufferReleasedByOutput or from
122a141c5f3cc2214a96f250999edacc3bd4d454601Shuzhen Wang    // onFrameAvailable when a buffer in the async buffer queue is overwritten.
123a141c5f3cc2214a96f250999edacc3bd4d454601Shuzhen Wang    void onBufferReleasedByOutputLocked(const sp<IGraphicBufferProducer>& from);
124a141c5f3cc2214a96f250999edacc3bd4d454601Shuzhen Wang
1250129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // When this is called, the splitter disconnects from (i.e., abandons) its
1260129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // input queue and signals any waiting onFrameAvailable calls to wake up.
1270129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // It still processes callbacks from other outputs, but only detaches their
1280129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // buffers so they can continue operating until they run out of buffers to
1290129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // acquire. This must be called with mMutex locked.
1300129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    void onAbandonedLocked();
1310129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
132bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // Decrement the buffer's reference count. Once the reference count becomes
133bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // 0, return the buffer back to the input BufferQueue.
134bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    void decrementBufRefCountLocked(uint64_t id, const sp<IGraphicBufferProducer>& from);
135bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang
1360129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // This is a thin wrapper class that lets us determine which BufferQueue
1370129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // the IProducerListener::onBufferReleased callback is associated with. We
1380129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // create one of these per output BufferQueue, and then pass the producer
1390129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // into onBufferReleasedByOutput above.
1400129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    class OutputListener : public BnProducerListener,
1410129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang                           public IBinder::DeathRecipient {
1420129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    public:
1430129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        OutputListener(wp<Camera3StreamSplitter> splitter,
1440129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang                wp<IGraphicBufferProducer> output);
1450129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        virtual ~OutputListener() = default;
1460129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
1470129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        // From IProducerListener
1480129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        void onBufferReleased() override;
1490129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
1500129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        // From IBinder::DeathRecipient
1510129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        void binderDied(const wp<IBinder>& who) override;
1520129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
1530129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    private:
1540129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        wp<Camera3StreamSplitter> mSplitter;
1550129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        wp<IGraphicBufferProducer> mOutput;
1560129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    };
1570129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
1580129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    class BufferTracker {
1590129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    public:
160bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang        BufferTracker(const sp<GraphicBuffer>& buffer,
161bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang                const std::vector<size_t>& requestedSurfaces);
1620129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        ~BufferTracker() = default;
1630129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
1640129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        const sp<GraphicBuffer>& getBuffer() const { return mBuffer; }
1650129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        const sp<Fence>& getMergedFence() const { return mMergedFence; }
1660129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
1670129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        void mergeFence(const sp<Fence>& with);
1680129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
1690129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        // Returns the new value
1700129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        // Only called while mMutex is held
1710129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        size_t decrementReferenceCountLocked();
1720129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
173bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang        const std::vector<size_t> requestedSurfaces() const { return mRequestedSurfaces; }
174bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang
1750129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    private:
1760129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
1770129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        // Disallow copying
1780129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        BufferTracker(const BufferTracker& other);
1790129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        BufferTracker& operator=(const BufferTracker& other);
1800129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
1810129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        sp<GraphicBuffer> mBuffer; // One instance that holds this native handle
1820129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        sp<Fence> mMergedFence;
183bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang
184bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang        // Request surfaces for a particular buffer. And when the buffer becomes
185bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang        // available from the input queue, the registered surfaces are used to decide
186bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang        // which output is the buffer sent to.
187bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang        std::vector<size_t> mRequestedSurfaces;
1880129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang        size_t mReferenceCount;
1890129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    };
1900129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
1910129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // Must be accessed through RefBase
1920129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    virtual ~Camera3StreamSplitter();
1930129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
194bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    status_t addOutputLocked(const sp<Surface>& outputQueue);
195bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang
196bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // Send a buffer to particular output, and increment the reference count
197bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // of the buffer. If this output is abandoned, the buffer's reference count
198bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // won't be incremented.
199bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    status_t outputBufferLocked(const sp<IGraphicBufferProducer>& output,
200bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang            const BufferItem& bufferItem);
2010129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
2020129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // Get unique name for the buffer queue consumer
203bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    String8 getUniqueConsumerName();
2040129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
205bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // Helper function to get the BufferQueue slot where a particular buffer is attached to.
206bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    int getSlotForOutputLocked(const sp<IGraphicBufferProducer>& gbp,
207bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang            const sp<GraphicBuffer>& gb);
208bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // Helper function to remove the buffer from the BufferQueue slot
209bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    status_t removeSlotForOutputLocked(const sp<IGraphicBufferProducer>& gbp,
210bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang            const sp<GraphicBuffer>& gb);
2110129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
2120129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
213bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // Sum of max consumer buffers for all outputs
214bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    size_t mMaxConsumerBuffers = 0;
215bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    size_t mMaxHalBuffers = 0;
216bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang
217bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    static const nsecs_t kDequeueBufferTimeout   = s2ns(1); // 1 sec
2180129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
2190129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    Mutex mMutex;
2200129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
2210129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    sp<IGraphicBufferProducer> mProducer;
2220129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    sp<IGraphicBufferConsumer> mConsumer;
2230129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    sp<BufferItemConsumer> mBufferItemConsumer;
2240129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    sp<Surface> mSurface;
2250129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
2260129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    std::vector<sp<IGraphicBufferProducer> > mOutputs;
2270129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // Map of GraphicBuffer IDs (GraphicBuffer::getId()) to buffer tracking
2280129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // objects (which are mostly for counting how many outputs have released the
2290129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    // buffer, but also contain merged release fences).
2300129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang    std::unordered_map<uint64_t, std::unique_ptr<BufferTracker> > mBuffers;
231bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang
232bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    struct GBPHash {
233bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang        std::size_t operator()(const sp<IGraphicBufferProducer>& producer) const {
234bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang            return std::hash<IGraphicBufferProducer *>{}(producer.get());
235bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang        }
236bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    };
237bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang
238bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    std::unordered_map<sp<IGraphicBufferProducer>, sp<OutputListener>,
239bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang            GBPHash> mNotifiers;
240bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang
241bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    typedef std::vector<sp<GraphicBuffer>> OutputSlots;
242bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    std::unordered_map<sp<IGraphicBufferProducer>, std::unique_ptr<OutputSlots>,
243bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang            GBPHash> mOutputSlots;
244bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang
245bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    // Latest onFrameAvailable return value
246bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    std::atomic<status_t> mOnFrameAvailableRes{0};
247bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang
248bee0f0a5e7aa19aa7c59de03b508985b68bc6b5eShuzhen Wang    String8 mConsumerName;
2490129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang};
2500129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
2510129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang} // namespace android
2520129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang
2530129d52df9794d6fdf06be304722b5cb51a2eab5Shuzhen Wang#endif
254