1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#ifndef ANDROID_DVR_NATIVE_BUFFER_H_ 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define ANDROID_DVR_NATIVE_BUFFER_H_ 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <EGL/egl.h> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <EGL/eglext.h> 64fe60582f314e381098f8f3bc2e39c5880e9243aAlex Vakulenko#include <log/log.h> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <system/window.h> 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <ui/ANativeObjectBase.h> 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <utils/RefBase.h> 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <private/dvr/buffer_hub_client.h> 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace android { 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace dvr { 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// ANativeWindowBuffer is the abstraction Android HALs and frameworks use to 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// pass around hardware graphics buffers. The following classes implement this 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// abstraction with different DVR backing buffers, all of which provide 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// different semantics on top of ion/gralloc buffers. 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// An implementation of ANativeWindowBuffer backed by an IonBuffer. 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass NativeBuffer 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : public android::ANativeObjectBase<ANativeWindowBuffer, NativeBuffer, 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko android::LightRefBase<NativeBuffer>> { 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static constexpr int kEmptyFence = -1; 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit NativeBuffer(const std::shared_ptr<IonBuffer>& buffer) 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : BASE(), buffer_(buffer), fence_(kEmptyFence) { 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::width = buffer->width(); 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::height = buffer->height(); 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::stride = buffer->stride(); 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::format = buffer->format(); 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::usage = buffer->usage(); 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko handle = buffer_->handle(); 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko virtual ~NativeBuffer() {} 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::shared_ptr<IonBuffer> buffer() { return buffer_; } 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int fence() const { return fence_.Get(); } 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void SetFence(int fence) { fence_.Reset(fence); } 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend class android::LightRefBase<NativeBuffer>; 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::shared_ptr<IonBuffer> buffer_; 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pdx::LocalHandle fence_; 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko NativeBuffer(const NativeBuffer&) = delete; 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void operator=(NativeBuffer&) = delete; 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// NativeBufferProducer is an implementation of ANativeWindowBuffer backed by a 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// BufferProducer. 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass NativeBufferProducer : public android::ANativeObjectBase< 584d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar ANativeWindowBuffer, NativeBufferProducer, 594d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar android::LightRefBase<NativeBufferProducer>> { 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static constexpr int kEmptyFence = -1; 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko NativeBufferProducer(const std::shared_ptr<BufferProducer>& buffer, 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EGLDisplay display, uint32_t surface_buffer_index) 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : BASE(), 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko buffer_(buffer), 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko surface_buffer_index_(surface_buffer_index), 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko display_(display) { 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::width = buffer_->width(); 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::height = buffer_->height(); 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::stride = buffer_->stride(); 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::format = buffer_->format(); 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::usage = buffer_->usage(); 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko handle = buffer_->native_handle(); 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit NativeBufferProducer(const std::shared_ptr<BufferProducer>& buffer) 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : NativeBufferProducer(buffer, nullptr, 0) {} 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko virtual ~NativeBufferProducer() { 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (EGLImageKHR egl_image : egl_images_) { 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (egl_image != EGL_NO_IMAGE_KHR) 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko eglDestroyImageKHR(display_, egl_image); 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EGLImageKHR image_khr(int index) const { return egl_images_[index]; } 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::shared_ptr<BufferProducer> buffer() const { return buffer_; } 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int release_fence() const { return release_fence_.Get(); } 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint32_t surface_buffer_index() const { return surface_buffer_index_; } 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Return the release fence, passing ownership to the caller. 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pdx::LocalHandle ClaimReleaseFence() { return std::move(release_fence_); } 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Post the buffer consumer, closing the acquire and release fences. 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Post(int acquire_fence, uint64_t sequence) { 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko release_fence_.Close(); 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return buffer_->Post(pdx::LocalHandle(acquire_fence), sequence); 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Gain the buffer producer, closing the previous release fence if valid. 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Gain() { return buffer_->Gain(&release_fence_); } 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Asynchronously gain the buffer, closing the previous release fence. 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GainAsync() { 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko release_fence_.Close(); 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return buffer_->GainAsync(); 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend class android::LightRefBase<NativeBufferProducer>; 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::shared_ptr<BufferProducer> buffer_; 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pdx::LocalHandle release_fence_; 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<EGLImageKHR> egl_images_; 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint32_t surface_buffer_index_; 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EGLDisplay display_; 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko NativeBufferProducer(const NativeBufferProducer&) = delete; 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void operator=(NativeBufferProducer&) = delete; 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// NativeBufferConsumer is an implementation of ANativeWindowBuffer backed by a 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// BufferConsumer. 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass NativeBufferConsumer : public android::ANativeObjectBase< 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer, NativeBufferConsumer, 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko android::LightRefBase<NativeBufferConsumer>> { 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static constexpr int kEmptyFence = -1; 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 1314d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar explicit NativeBufferConsumer(const std::shared_ptr<BufferConsumer>& buffer) 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : BASE(), buffer_(buffer), acquire_fence_(kEmptyFence), sequence_(0) { 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::width = buffer_->width(); 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::height = buffer_->height(); 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::stride = buffer_->stride(); 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::format = buffer_->format(); 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ANativeWindowBuffer::usage = buffer_->usage(); 1384d3590f3fd0fd65f4e8758d3228de9f55cf135d0Hendrik Wagenaar handle = buffer_->native_handle(); 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko virtual ~NativeBufferConsumer() {} 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::shared_ptr<BufferConsumer> buffer() const { return buffer_; } 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int acquire_fence() const { return acquire_fence_.Get(); } 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint64_t sequence() const { return sequence_; } 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Return the acquire fence, passing ownership to the caller. 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pdx::LocalHandle ClaimAcquireFence() { return std::move(acquire_fence_); } 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Acquire the underlying buffer consumer, closing the previous acquire fence 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // if valid. 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Acquire() { return buffer_->Acquire(&acquire_fence_, &sequence_); } 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Release the buffer consumer, closing the acquire and release fences if 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // valid. 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int Release(int release_fence) { 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko acquire_fence_.Close(); 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sequence_ = 0; 159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return buffer_->Release(pdx::LocalHandle(release_fence)); 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend class android::LightRefBase<NativeBufferConsumer>; 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::shared_ptr<BufferConsumer> buffer_; 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pdx::LocalHandle acquire_fence_; 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uint64_t sequence_; 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko NativeBufferConsumer(const NativeBufferConsumer&) = delete; 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void operator=(NativeBufferConsumer&) = delete; 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace dvr 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // namespace android 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#endif // ANDROID_DVR_NATIVE_BUFFER_H_ 177