blob: e7ca459164496a62a0334552c39141fc0580317f [file] [log] [blame]
#ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
#define ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
#include "buffer_hub.h"
#include <functional>
#include <memory>
#include <vector>
#include <pdx/channel_handle.h>
#include <pdx/file_handle.h>
#include <pdx/rpc/buffer_wrapper.h>
#include <private/dvr/bufferhub_rpc.h>
#include <private/dvr/ion_buffer.h>
namespace android {
namespace dvr {
// The buffer changes ownership according to the following sequence:
// POST -> ACQUIRE/RELEASE (all consumers) -> GAIN (producer acquires) -> POST
// The producer channel is owned by a single app that writes into buffers and
// calls POST when drawing is complete. This channel has a set of consumer
// channels associated with it that are waiting for notifications.
class ProducerChannel : public BufferHubChannel {
public:
using Message = pdx::Message;
using BorrowedHandle = pdx::BorrowedHandle;
using RemoteChannelHandle = pdx::RemoteChannelHandle;
template <typename T>
using BufferWrapper = pdx::rpc::BufferWrapper<T>;
static std::shared_ptr<ProducerChannel> Create(
BufferHubService* service, int channel_id, int width, int height,
int format, int usage, size_t meta_size_bytes, size_t slice_count,
int* error);
~ProducerChannel() override;
bool HandleMessage(Message& message) override;
void HandleImpulse(Message& message) override;
BufferInfo GetBufferInfo() const override;
NativeBufferHandle<BorrowedHandle> OnGetBuffer(Message& message,
unsigned index);
std::vector<NativeBufferHandle<BorrowedHandle>> OnGetBuffers(
Message& message);
RemoteChannelHandle CreateConsumer(Message& message);
RemoteChannelHandle OnNewConsumer(Message& message);
std::pair<BorrowedFence, BufferWrapper<std::uint8_t*>> OnConsumerAcquire(
Message& message, std::size_t metadata_size);
int OnConsumerRelease(Message& message, LocalFence release_fence);
void OnConsumerIgnored();
void AddConsumer(ConsumerChannel* channel);
void RemoveConsumer(ConsumerChannel* channel);
bool CheckAccess(int euid, int egid);
bool CheckParameters(int width, int height, int format, int usage,
size_t meta_size_bytes, size_t slice_count);
int OnProducerMakePersistent(Message& message, const std::string& name,
int user_id, int group_id);
int OnRemovePersistence(Message& message);
private:
std::vector<ConsumerChannel*> consumer_channels_;
// This counts the number of consumers left to process this buffer. If this is
// zero then the producer can re-acquire ownership.
int pending_consumers_;
std::vector<IonBuffer> slices_;
bool producer_owns_;
LocalFence post_fence_;
LocalFence returned_fence_;
size_t meta_size_bytes_;
std::unique_ptr<uint8_t[]> meta_;
static constexpr int kNoCheckId = -1;
static constexpr int kUseCallerId = 0;
static constexpr int kRootId = 0;
// User and group id to check when obtaining a persistent buffer.
int owner_user_id_ = kNoCheckId;
int owner_group_id_ = kNoCheckId;
std::string name_;
ProducerChannel(BufferHubService* service, int channel, int width, int height,
int format, int usage, size_t meta_size_bytes,
size_t slice_count, int* error);
int OnProducerPost(Message& message, LocalFence acquire_fence,
BufferWrapper<std::vector<std::uint8_t>> metadata);
LocalFence OnProducerGain(Message& message);
ProducerChannel(const ProducerChannel&) = delete;
void operator=(const ProducerChannel&) = delete;
};
} // namespace dvr
} // namespace android
#endif // ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_