blob: e3531877018732da29bc4cc3486bff6329e088ca [file] [log] [blame]
#ifndef ANDROID_DVR_BUFFER_HUB_QUEUE_CORE_H_
#define ANDROID_DVR_BUFFER_HUB_QUEUE_CORE_H_
#include <private/dvr/buffer_hub_queue_client.h>
#include <gui/BufferSlot.h>
#include <utils/Atomic.h>
#include <utils/String8.h>
#include <mutex>
namespace android {
namespace dvr {
class BufferHubQueueCore {
private:
friend class BufferHubQueueProducer;
public:
static constexpr int kNoConnectedApi = -1;
// Create a BufferHubQueueCore instance by creating a new producer queue.
static std::shared_ptr<BufferHubQueueCore> Create();
// Create a BufferHubQueueCore instance by importing an existing prodcuer queue.
static std::shared_ptr<BufferHubQueueCore> Create(
const std::shared_ptr<ProducerQueue>& producer);
struct BufferMetadata {
// Timestamp of the frame.
int64_t timestamp;
};
class NativeBuffer
: public ANativeObjectBase<ANativeWindowBuffer, NativeBuffer, RefBase> {
public:
explicit NativeBuffer(const std::shared_ptr<BufferHubBuffer>& buffer)
: buffer_(buffer) {
ANativeWindowBuffer::width = buffer_->width();
ANativeWindowBuffer::height = buffer_->height();
ANativeWindowBuffer::stride = buffer_->stride();
ANativeWindowBuffer::format = buffer_->format();
ANativeWindowBuffer::usage = buffer_->usage();
ANativeWindowBuffer::handle = buffer_->buffer()->handle();
}
std::shared_ptr<BufferHubBuffer> buffer() { return buffer_; }
private:
std::shared_ptr<BufferHubBuffer> buffer_;
};
// Get the unique buffer producer queue backing this BufferHubQueue.
std::shared_ptr<ProducerQueue> GetProducerQueue() { return producer_; }
private:
using LocalHandle = pdx::LocalHandle;
struct BufferHubSlot : public BufferSlot {
BufferHubSlot() : mBufferProducer(nullptr), mIsReallocating(false) {}
// BufferSlot comes from android framework, using m prefix to comply with
// the name convention with the reset of data fields from BufferSlot.
std::shared_ptr<BufferProducer> mBufferProducer;
bool mIsReallocating;
};
static String8 getUniqueName() {
static volatile int32_t counter = 0;
return String8::format("unnamed-%d-%d", getpid(),
android_atomic_inc(&counter));
}
static uint64_t getUniqueId() {
static std::atomic<uint32_t> counter{0};
static uint64_t id = static_cast<uint64_t>(getpid()) << 32;
return id | counter++;
}
// Private constructor to force use of |Create|.
BufferHubQueueCore();
// Allocate a new buffer producer through BufferHub.
int AllocateBuffer(uint32_t width, uint32_t height, PixelFormat format,
uint32_t usage, size_t slice_count);
// Detach a buffer producer through BufferHub.
int DetachBuffer(size_t slot);
// Mutex for thread safety.
std::mutex mutex_;
// Connect client API, should be one of the NATIVE_WINDOW_API_* flags.
int connected_api_{kNoConnectedApi};
// |buffers_| stores the buffers that have been dequeued from
// |dvr::BufferHubQueue|, It is initialized to invalid buffers, and gets
// filled in with the result of |Dequeue|.
// TODO(jwcai) The buffer allocated to a slot will also be replaced if the
// requested buffer usage or geometry differs from that of the buffer
// allocated to a slot.
BufferHubSlot buffers_[BufferHubQueue::kMaxQueueCapacity];
// Concreate implementation backed by BufferHubBuffer.
std::shared_ptr<ProducerQueue> producer_;
// |generation_number_| stores the current generation number of the attached
// producer. Any attempt to attach a buffer with a different generation
// number will fail.
uint32_t generation_number_;
// Sets how long dequeueBuffer or attachBuffer will block if a buffer or
// slot is not yet available. The timeout is stored in milliseconds.
int dequeue_timeout_ms_;
const uint64_t unique_id_;
};
} // namespace dvr
} // namespace android
#endif // ANDROID_DVR_BUFFER_HUB_QUEUE_CORE_H_