native_buffer.h revision a9347647eca3101c014be902b713772de3977d87
1#ifndef ANDROID_DVR_NATIVE_BUFFER_H_
2#define ANDROID_DVR_NATIVE_BUFFER_H_
3
4#include <EGL/egl.h>
5#include <EGL/eglext.h>
6#include <log/log.h>
7#include <system/window.h>
8#include <ui/ANativeObjectBase.h>
9#include <utils/RefBase.h>
10
11#include <private/dvr/buffer_hub_client.h>
12
13namespace android {
14namespace dvr {
15
16// ANativeWindowBuffer is the abstraction Android HALs and frameworks use to
17// pass around hardware graphics buffers. The following classes implement this
18// abstraction with different DVR backing buffers, all of which provide
19// different semantics on top of ion/gralloc buffers.
20
21// An implementation of ANativeWindowBuffer backed by an IonBuffer.
22class NativeBuffer
23    : public android::ANativeObjectBase<ANativeWindowBuffer, NativeBuffer,
24                                        android::LightRefBase<NativeBuffer>> {
25 public:
26  static constexpr int kEmptyFence = -1;
27
28  explicit NativeBuffer(const std::shared_ptr<IonBuffer>& buffer)
29      : BASE(), buffer_(buffer), fence_(kEmptyFence) {
30    ANativeWindowBuffer::width = buffer->width();
31    ANativeWindowBuffer::height = buffer->height();
32    ANativeWindowBuffer::stride = buffer->stride();
33    ANativeWindowBuffer::format = buffer->format();
34    ANativeWindowBuffer::usage = buffer->usage();
35    handle = buffer_->handle();
36  }
37
38  virtual ~NativeBuffer() {}
39
40  std::shared_ptr<IonBuffer> buffer() { return buffer_; }
41  int fence() const { return fence_.Get(); }
42
43  void SetFence(int fence) { fence_.Reset(fence); }
44
45 private:
46  friend class android::LightRefBase<NativeBuffer>;
47
48  std::shared_ptr<IonBuffer> buffer_;
49  pdx::LocalHandle fence_;
50
51  NativeBuffer(const NativeBuffer&) = delete;
52  void operator=(NativeBuffer&) = delete;
53};
54
55// NativeBufferProducerSlice is an implementation of ANativeWindowBuffer backed
56// by a buffer slice of a BufferProducer.
57class NativeBufferProducerSlice
58    : public android::ANativeObjectBase<
59          ANativeWindowBuffer, NativeBufferProducerSlice,
60          android::LightRefBase<NativeBufferProducerSlice>> {
61 public:
62  NativeBufferProducerSlice(const std::shared_ptr<BufferProducer>& buffer,
63                            int buffer_index)
64      : BASE(), buffer_(buffer) {
65    ANativeWindowBuffer::width = buffer_->width();
66    ANativeWindowBuffer::height = buffer_->height();
67    ANativeWindowBuffer::stride = buffer_->stride();
68    ANativeWindowBuffer::format = buffer_->format();
69    ANativeWindowBuffer::usage = buffer_->usage();
70    handle = buffer_->native_handle(buffer_index);
71  }
72
73  virtual ~NativeBufferProducerSlice() {}
74
75 private:
76  friend class android::LightRefBase<NativeBufferProducerSlice>;
77
78  std::shared_ptr<BufferProducer> buffer_;
79
80  NativeBufferProducerSlice(const NativeBufferProducerSlice&) = delete;
81  void operator=(NativeBufferProducerSlice&) = delete;
82};
83
84// NativeBufferProducer is an implementation of ANativeWindowBuffer backed by a
85// BufferProducer.
86class NativeBufferProducer : public android::ANativeObjectBase<
87  ANativeWindowBuffer, NativeBufferProducer,
88  android::LightRefBase<NativeBufferProducer>> {
89 public:
90  static constexpr int kEmptyFence = -1;
91
92  NativeBufferProducer(const std::shared_ptr<BufferProducer>& buffer,
93                       EGLDisplay display, uint32_t surface_buffer_index)
94      : BASE(),
95        buffer_(buffer),
96        surface_buffer_index_(surface_buffer_index),
97        display_(display) {
98    ANativeWindowBuffer::width = buffer_->width();
99    ANativeWindowBuffer::height = buffer_->height();
100    ANativeWindowBuffer::stride = buffer_->stride();
101    ANativeWindowBuffer::format = buffer_->format();
102    ANativeWindowBuffer::usage = buffer_->usage();
103    handle = buffer_->native_handle();
104    for (int i = 0; i < buffer->slice_count(); ++i) {
105      // display == null means don't create an EGL image. This is used by our
106      // Vulkan code.
107      slices_.push_back(new NativeBufferProducerSlice(buffer, i));
108      if (display_ != nullptr) {
109        egl_images_.push_back(eglCreateImageKHR(
110            display_, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
111            static_cast<ANativeWindowBuffer*>(slices_.back().get()), nullptr));
112        if (egl_images_.back() == EGL_NO_IMAGE_KHR) {
113          ALOGE("NativeBufferProducer: eglCreateImageKHR failed");
114        }
115      }
116    }
117  }
118
119  explicit NativeBufferProducer(const std::shared_ptr<BufferProducer>& buffer)
120      : NativeBufferProducer(buffer, nullptr, 0) {}
121
122  virtual ~NativeBufferProducer() {
123    for (EGLImageKHR egl_image : egl_images_) {
124      if (egl_image != EGL_NO_IMAGE_KHR)
125        eglDestroyImageKHR(display_, egl_image);
126    }
127  }
128
129  EGLImageKHR image_khr(int index) const { return egl_images_[index]; }
130  std::shared_ptr<BufferProducer> buffer() const { return buffer_; }
131  int release_fence() const { return release_fence_.Get(); }
132  uint32_t surface_buffer_index() const { return surface_buffer_index_; }
133
134  // Return the release fence, passing ownership to the caller.
135  pdx::LocalHandle ClaimReleaseFence() { return std::move(release_fence_); }
136
137  // Post the buffer consumer, closing the acquire and release fences.
138  int Post(int acquire_fence, uint64_t sequence) {
139    release_fence_.Close();
140    return buffer_->Post(pdx::LocalHandle(acquire_fence), sequence);
141  }
142
143  // Gain the buffer producer, closing the previous release fence if valid.
144  int Gain() { return buffer_->Gain(&release_fence_); }
145
146  // Asynchronously gain the buffer, closing the previous release fence.
147  int GainAsync() {
148    release_fence_.Close();
149    return buffer_->GainAsync();
150  }
151
152 private:
153  friend class android::LightRefBase<NativeBufferProducer>;
154
155  std::shared_ptr<BufferProducer> buffer_;
156  pdx::LocalHandle release_fence_;
157  std::vector<android::sp<NativeBufferProducerSlice>> slices_;
158  std::vector<EGLImageKHR> egl_images_;
159  uint32_t surface_buffer_index_;
160  EGLDisplay display_;
161
162  NativeBufferProducer(const NativeBufferProducer&) = delete;
163  void operator=(NativeBufferProducer&) = delete;
164};
165
166// NativeBufferConsumer is an implementation of ANativeWindowBuffer backed by a
167// BufferConsumer.
168class NativeBufferConsumer : public android::ANativeObjectBase<
169                                 ANativeWindowBuffer, NativeBufferConsumer,
170                                 android::LightRefBase<NativeBufferConsumer>> {
171 public:
172  static constexpr int kEmptyFence = -1;
173
174  explicit NativeBufferConsumer(const std::shared_ptr<BufferConsumer>& buffer,
175                                int index)
176      : BASE(), buffer_(buffer), acquire_fence_(kEmptyFence), sequence_(0) {
177    ANativeWindowBuffer::width = buffer_->width();
178    ANativeWindowBuffer::height = buffer_->height();
179    ANativeWindowBuffer::stride = buffer_->stride();
180    ANativeWindowBuffer::format = buffer_->format();
181    ANativeWindowBuffer::usage = buffer_->usage();
182    LOG_ALWAYS_FATAL_IF(buffer_->slice_count() <= index);
183    handle = buffer_->slice(index)->handle();
184  }
185
186  explicit NativeBufferConsumer(const std::shared_ptr<BufferConsumer>& buffer)
187      : NativeBufferConsumer(buffer, 0) {}
188
189  virtual ~NativeBufferConsumer() {}
190
191  std::shared_ptr<BufferConsumer> buffer() const { return buffer_; }
192  int acquire_fence() const { return acquire_fence_.Get(); }
193  uint64_t sequence() const { return sequence_; }
194
195  // Return the acquire fence, passing ownership to the caller.
196  pdx::LocalHandle ClaimAcquireFence() { return std::move(acquire_fence_); }
197
198  // Acquire the underlying buffer consumer, closing the previous acquire fence
199  // if valid.
200  int Acquire() { return buffer_->Acquire(&acquire_fence_, &sequence_); }
201
202  // Release the buffer consumer, closing the acquire and release fences if
203  // valid.
204  int Release(int release_fence) {
205    acquire_fence_.Close();
206    sequence_ = 0;
207    return buffer_->Release(pdx::LocalHandle(release_fence));
208  }
209
210 private:
211  friend class android::LightRefBase<NativeBufferConsumer>;
212
213  std::shared_ptr<BufferConsumer> buffer_;
214  pdx::LocalHandle acquire_fence_;
215  uint64_t sequence_;
216
217  NativeBufferConsumer(const NativeBufferConsumer&) = delete;
218  void operator=(NativeBufferConsumer&) = delete;
219};
220
221}  // namespace dvr
222}  // namespace android
223
224#endif  // ANDROID_DVR_NATIVE_BUFFER_H_
225