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