blob: 140ffc5a5a028dbd62e15d23b6a207023736276b [file] [log] [blame]
#ifndef ANDROID_DVR_NATIVE_BUFFER_H_
#define ANDROID_DVR_NATIVE_BUFFER_H_
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <log/log.h>
#include <ui/ANativeObjectBase.h>
#include <utils/RefBase.h>
#include <nativebase/nativebase.h>
#include <private/dvr/buffer_hub_client.h>
namespace android {
namespace dvr {
// ANativeWindowBuffer is the abstraction Android HALs and frameworks use to
// pass around hardware graphics buffers. The following classes implement this
// abstraction with different DVR backing buffers, all of which provide
// different semantics on top of ion/gralloc buffers.
// An implementation of ANativeWindowBuffer backed by an IonBuffer.
class NativeBuffer
: public android::ANativeObjectBase<ANativeWindowBuffer, NativeBuffer,
android::LightRefBase<NativeBuffer>> {
public:
static constexpr int kEmptyFence = -1;
explicit NativeBuffer(const std::shared_ptr<IonBuffer>& buffer)
: BASE(), buffer_(buffer), fence_(kEmptyFence) {
ANativeWindowBuffer::width = buffer->width();
ANativeWindowBuffer::height = buffer->height();
ANativeWindowBuffer::stride = buffer->stride();
ANativeWindowBuffer::format = buffer->format();
ANativeWindowBuffer::usage = buffer->usage();
handle = buffer_->handle();
}
virtual ~NativeBuffer() {}
std::shared_ptr<IonBuffer> buffer() { return buffer_; }
int fence() const { return fence_.Get(); }
void SetFence(int fence) { fence_.Reset(fence); }
private:
friend class android::LightRefBase<NativeBuffer>;
std::shared_ptr<IonBuffer> buffer_;
pdx::LocalHandle fence_;
NativeBuffer(const NativeBuffer&) = delete;
void operator=(NativeBuffer&) = delete;
};
class NativeBufferProducer : public android::ANativeObjectBase<
ANativeWindowBuffer, NativeBufferProducer,
android::LightRefBase<NativeBufferProducer>> {
public:
static constexpr int kEmptyFence = -1;
NativeBufferProducer(const std::shared_ptr<BufferProducer>& buffer,
EGLDisplay display, uint32_t surface_buffer_index)
: BASE(),
buffer_(buffer),
surface_buffer_index_(surface_buffer_index),
display_(display) {
ANativeWindowBuffer::width = buffer_->width();
ANativeWindowBuffer::height = buffer_->height();
ANativeWindowBuffer::stride = buffer_->stride();
ANativeWindowBuffer::format = buffer_->format();
ANativeWindowBuffer::usage = buffer_->usage();
ANativeWindowBuffer::handle = buffer_->native_handle();
if (display_) {
image_khr_ =
eglCreateImageKHR(display_, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
static_cast<ANativeWindowBuffer*>(this), nullptr);
} else {
image_khr_ = EGL_NO_IMAGE_KHR;
}
}
explicit NativeBufferProducer(const std::shared_ptr<BufferProducer>& buffer)
: NativeBufferProducer(buffer, nullptr, 0) {}
virtual ~NativeBufferProducer() {
if (image_khr_ != EGL_NO_IMAGE_KHR)
eglDestroyImageKHR(display_, image_khr_);
}
EGLImageKHR image_khr() const { return image_khr_; }
std::shared_ptr<BufferProducer> buffer() const { return buffer_; }
int release_fence() const { return release_fence_.Get(); }
uint32_t surface_buffer_index() const { return surface_buffer_index_; }
// Return the release fence, passing ownership to the caller.
pdx::LocalHandle ClaimReleaseFence() { return std::move(release_fence_); }
// Post the buffer consumer, closing the acquire and release fences.
int Post(int acquire_fence, uint64_t sequence) {
release_fence_.Close();
return buffer_->Post(pdx::LocalHandle(acquire_fence), sequence);
}
// Gain the buffer producer, closing the previous release fence if valid.
int Gain() { return buffer_->Gain(&release_fence_); }
// Asynchronously gain the buffer, closing the previous release fence.
int GainAsync() {
release_fence_.Close();
return buffer_->GainAsync();
}
private:
friend class android::LightRefBase<NativeBufferProducer>;
std::shared_ptr<BufferProducer> buffer_;
pdx::LocalHandle release_fence_;
EGLImageKHR image_khr_;
uint32_t surface_buffer_index_;
EGLDisplay display_;
NativeBufferProducer(const NativeBufferProducer&) = delete;
void operator=(NativeBufferProducer&) = delete;
};
// NativeBufferConsumer is an implementation of ANativeWindowBuffer backed by a
// BufferConsumer.
class NativeBufferConsumer : public android::ANativeObjectBase<
ANativeWindowBuffer, NativeBufferConsumer,
android::LightRefBase<NativeBufferConsumer>> {
public:
static constexpr int kEmptyFence = -1;
explicit NativeBufferConsumer(const std::shared_ptr<BufferConsumer>& buffer)
: BASE(), buffer_(buffer), acquire_fence_(kEmptyFence), sequence_(0) {
ANativeWindowBuffer::width = buffer_->width();
ANativeWindowBuffer::height = buffer_->height();
ANativeWindowBuffer::stride = buffer_->stride();
ANativeWindowBuffer::format = buffer_->format();
ANativeWindowBuffer::usage = buffer_->usage();
handle = buffer_->native_handle();
}
virtual ~NativeBufferConsumer() {}
std::shared_ptr<BufferConsumer> buffer() const { return buffer_; }
int acquire_fence() const { return acquire_fence_.Get(); }
uint64_t sequence() const { return sequence_; }
// Return the acquire fence, passing ownership to the caller.
pdx::LocalHandle ClaimAcquireFence() { return std::move(acquire_fence_); }
// Acquire the underlying buffer consumer, closing the previous acquire fence
// if valid.
int Acquire() { return buffer_->Acquire(&acquire_fence_, &sequence_); }
// Release the buffer consumer, closing the acquire and release fences if
// valid.
int Release(int release_fence) {
acquire_fence_.Close();
sequence_ = 0;
return buffer_->Release(pdx::LocalHandle(release_fence));
}
private:
friend class android::LightRefBase<NativeBufferConsumer>;
std::shared_ptr<BufferConsumer> buffer_;
pdx::LocalHandle acquire_fence_;
uint64_t sequence_;
NativeBufferConsumer(const NativeBufferConsumer&) = delete;
void operator=(NativeBufferConsumer&) = delete;
};
} // namespace dvr
} // namespace android
#endif // ANDROID_DVR_NATIVE_BUFFER_H_