Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a71b131 authored by Mark Urbanus's avatar Mark Urbanus
Browse files

Refactor IonBuffer to use GraphicBuffer

- Replace gralloc0 based implementation with GraphicBuffer implementation.
- Removed incompatible ion-buffer unit-tests.
- Added libui dependencies to dependants.

Bug: 34879523
Test: Tested on Lucid, validated graphics and poses are working
Change-Id: I49a129f269d54c81bda93b44d879d4b8dee2006a
parent 8348fa35
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -51,8 +51,6 @@ Status<LocalChannelHandle> BufferHubBuffer::CreateConsumer() {

int BufferHubBuffer::ImportBuffer() {
  ATRACE_NAME("BufferHubBuffer::ImportBuffer");
  if (!IonBuffer::GetGrallocModule())
    return -EIO;

  Status<std::vector<NativeBufferHandle<LocalHandle>>> status =
      InvokeRemoteMethod<BufferHubRPC::GetBuffers>();
+18 −37
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@
#define ANDROID_DVR_ION_BUFFER_H_

#include <hardware/gralloc.h>
#include <log/log.h>
#include <ui/GraphicBuffer.h>

namespace android {
namespace dvr {
@@ -58,45 +60,24 @@ class IonBuffer {
  int LockYUV(int usage, int x, int y, int width, int height,
              struct android_ycbcr* yuv);
  int Unlock();

  buffer_handle_t handle() const { return handle_; }
  int width() const { return width_; }
  int height() const { return height_; }
  int layer_count() const { return layer_count_; }
  int stride() const { return stride_; }
  int layer_stride() const { return layer_stride_; }
  int format() const { return format_; }
  int usage() const { return usage_; }

  static gralloc_module_t const* GetGrallocModule() {
    GrallocInit();
    return gralloc_module_;
  }

  static alloc_device_t* GetGrallocDevice() {
    GrallocInit();
    return gralloc_device_;
  }
  buffer_handle_t handle() const { if (buffer_.get()) return buffer_->handle;
                                   else return nullptr; }
  int width() const { if (buffer_.get()) return buffer_->getWidth();
                      else return 0; }
  int height() const { if (buffer_.get()) return buffer_->getHeight();
                       else return 0; }
  int layer_count() const { if (buffer_.get()) return buffer_->getLayerCount();
                            else return 0; }
  int stride() const { if (buffer_.get()) return buffer_->getStride();
                       else return 0; }
  int layer_stride() const { return 0; }
  int format() const { if (buffer_.get()) return buffer_->getPixelFormat();
                       else return 0; }
  int usage() const { if (buffer_.get()) return buffer_->getUsage();
                      else return 0; }

 private:
  buffer_handle_t handle_;
  int width_;
  int height_;
  int layer_count_;
  int stride_;
  int layer_stride_;
  int format_;
  int usage_;
  bool locked_;
  bool needs_unregister_;

  void Replace(buffer_handle_t handle, int width, int height, int layer_count,
               int stride, int layer_stride, int format, int usage,
               bool needs_unregister);

  static void GrallocInit();
  static gralloc_module_t const* gralloc_module_;
  static alloc_device_t* gralloc_device_;
  sp<GraphicBuffer> buffer_;

  IonBuffer(const IonBuffer&) = delete;
  void operator=(const IonBuffer&) = delete;
+51 −150
Original line number Diff line number Diff line
#include <private/dvr/ion_buffer.h>
#include <ui/GraphicBufferMapper.h>

#include <log/log.h>
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
@@ -9,9 +10,6 @@
namespace android {
namespace dvr {

gralloc_module_t const* IonBuffer::gralloc_module_ = nullptr;
alloc_device_t* IonBuffer::gralloc_device_ = nullptr;

IonBuffer::IonBuffer() : IonBuffer(nullptr, 0, 0, 0, 0, 0, 0, 0) {}

IonBuffer::IonBuffer(int width, int height, int format, int usage)
@@ -23,33 +21,26 @@ IonBuffer::IonBuffer(buffer_handle_t handle, int width, int height, int stride,
                     int format, int usage)
    : IonBuffer(handle, width, height, 1, stride, 0, format, usage) {}


IonBuffer::IonBuffer(buffer_handle_t handle, int width, int height,
                     int layer_count, int stride, int layer_stride, int format,
                     int usage)
    : handle_(handle),
      width_(width),
      height_(height),
      layer_count_(layer_count),
      stride_(stride),
      layer_stride_(layer_stride),
      format_(format),
      usage_(usage),
      locked_(false),
      needs_unregister_(false) {
    : buffer_(nullptr) {
  ALOGD_IF(TRACE,
         "IonBuffer::IonBuffer: handle=%p width=%d height=%d layer_count=%d "
         "stride=%d layer stride=%d format=%d usage=%d",
           handle_, width_, height_, layer_count_, stride_, layer_stride_,
           format_, usage_);
  GrallocInit();
         handle, width, height, layer_count, stride, layer_stride,
         format, usage);
  if (handle != 0) {
    Import(handle, width, height, stride, format, usage);
  }
}

IonBuffer::~IonBuffer() {
  ALOGD_IF(TRACE,
           "IonBuffer::~IonBuffer: handle=%p width=%d height=%d stride=%d "
           "format=%d usage=%d",
           handle_, width_, height_, stride_, format_, usage_);

           handle() , width(), height(), stride(), format(), usage());
  FreeHandle();
}

@@ -58,111 +49,42 @@ IonBuffer::IonBuffer(IonBuffer&& other) : IonBuffer() {
}

IonBuffer& IonBuffer::operator=(IonBuffer&& other) {
  ALOGD_IF(TRACE, "IonBuffer::operator=: handle_=%p other.handle_=%p", handle_,
           other.handle_);
  ALOGD_IF(TRACE, "IonBuffer::operator=: handle_=%p other.handle_=%p", handle(),
           other.handle());

  if (this != &other) {
    Replace(other.handle_, other.width_, other.height_, other.layer_count_,
            other.stride_, other.layer_stride_, other.format_, other.usage_,
            other.needs_unregister_);
    locked_ = other.locked_;
    other.handle_ = nullptr;
    buffer_ = other.buffer_;
    other.FreeHandle();
  }

  return *this;
}

void IonBuffer::FreeHandle() {
  if (handle_) {
    // Lock/Unlock don't need to be balanced, but one Unlock is needed to
    // clean/unmap the buffer. Warn if this didn't happen before freeing the
    // native handle.
    ALOGW_IF(locked_,
             "IonBuffer::FreeHandle: freeing a locked handle!!! handle=%p",
             handle_);

    if (needs_unregister_) {
      int ret = gralloc_module_->unregisterBuffer(gralloc_module_, handle_);
      ALOGE_IF(ret < 0,
               "IonBuffer::FreeHandle: Failed to unregister handle: %s",
               strerror(-ret));

      native_handle_close(const_cast<native_handle_t*>(handle_));
      native_handle_delete(const_cast<native_handle_t*>(handle_));
    } else {
      int ret = gralloc_device_->free(gralloc_device_, handle_);
      if (ret < 0) {
        ALOGE("IonBuffer::FreeHandle: failed to free buffer: %s",
              strerror(-ret));

        // Not sure if this is the right thing to do. Attempting to prevent a
        // memory leak of the native handle.
        native_handle_close(const_cast<native_handle_t*>(handle_));
        native_handle_delete(const_cast<native_handle_t*>(handle_));
      }
  if (buffer_.get()) {
    // GraphicBuffer unregisters and cleans up the handle if needed
    buffer_ = nullptr;
  }
}

  // Always re-initialize these members, even if handle_ was nullptr, in case
  // someone was dumb enough to pass a nullptr handle to the constructor or
  // Reset.
  handle_ = nullptr;
  width_ = 0;
  height_ = 0;
  layer_count_ = 0;
  stride_ = 0;
  layer_stride_ = 0;
  format_ = 0;
  usage_ = 0;
  locked_ = false;
  needs_unregister_ = false;
}

int IonBuffer::Alloc(int width, int height, int format, int usage) {
  ATRACE_NAME("IonBuffer::Alloc");
  ALOGD_IF(TRACE, "IonBuffer::Alloc: width=%d height=%d format=%d usage=%d",
           width, height, format, usage);

  int stride;
  buffer_handle_t handle;

  int ret = gralloc_device_->alloc(gralloc_device_, width, height, format,
                                   usage, &handle, &stride);
  if (ret < 0) {
    ALOGE("IonBuffer::Alloc: failed to allocate gralloc buffer: %s",
          strerror(-ret));
    return ret;
  GraphicBufferMapper& mapper = GraphicBufferMapper::get();
  buffer_ = new GraphicBuffer(width, height, format, usage);
  if (mapper.registerBuffer(buffer_.get()) != OK) {
    ALOGE("IonBuffer::Aloc: Failed to register buffer");
  }

  Replace(handle, width, height, 1, stride, 0, format, usage, false);
  return 0;
}

void IonBuffer::Replace(buffer_handle_t handle, int width, int height,
                        int layer_count, int stride, int layer_stride,
                        int format, int usage, bool needs_unregister) {
  FreeHandle();

  handle_ = handle;
  width_ = width;
  height_ = height;
  layer_count_ = layer_count;
  stride_ = stride;
  layer_stride_ = layer_stride;
  format_ = format;
  usage_ = usage;
  needs_unregister_ = needs_unregister;
}

void IonBuffer::Reset(buffer_handle_t handle, int width, int height, int stride,
                      int format, int usage) {
  ALOGD_IF(TRACE,
           "IonBuffer::Reset: handle=%p width=%d height=%d stride=%d format=%d "
           "usage=%d",
           handle, width, height, stride, format, usage);

  Replace(handle, width, height, 1, stride, 0, format, usage, false);
  Import(handle, width, height, stride, format, usage);
}

int IonBuffer::Import(buffer_handle_t handle, int width, int height, int stride,
@@ -173,14 +95,14 @@ int IonBuffer::Import(buffer_handle_t handle, int width, int height, int stride,
      "IonBuffer::Import: handle=%p width=%d height=%d stride=%d format=%d "
      "usage=%d",
      handle, width, height, stride, format, usage);

  int ret = gralloc_module_->registerBuffer(gralloc_module_, handle);
  if (ret < 0) {
    ALOGE("IonBuffer::Import: failed to import handle: %s", strerror(-ret));
    return ret;
  FreeHandle();
  GraphicBufferMapper& mapper = GraphicBufferMapper::get();
  buffer_ = new GraphicBuffer(width, height, format, 1, usage,
                              stride, (native_handle_t*)handle, true);
  if (mapper.registerBuffer(buffer_.get()) != OK) {
    ALOGE("IonBuffer::Import: Failed to register cloned buffer");
    return -EINVAL;
  }

  Replace(handle, width, height, 1, stride, 0, format, usage, true);
  return 0;
}

@@ -262,15 +184,14 @@ int IonBuffer::Lock(int usage, int x, int y, int width, int height,
  ALOGD_IF(TRACE,
           "IonBuffer::Lock: handle=%p usage=%d x=%d y=%d width=%d height=%d "
           "address=%p",
           handle_, usage, x, y, width, height, address);

  // Lock may be called multiple times; but only one Unlock is required.
  const int err = gralloc_module_->lock(gralloc_module_, handle_, usage, x, y,
                                        width, height, address);
  if (!err)
    locked_ = true;
           handle(), usage, x, y, width, height, address);

  return err;
  status_t err = buffer_->lock(usage, Rect(x, y, x + width, y + height),
                               address);
  if (err != NO_ERROR)
    return -EINVAL;
  else
    return 0;
}

int IonBuffer::LockYUV(int usage, int x, int y, int width, int height,
@@ -278,45 +199,25 @@ int IonBuffer::LockYUV(int usage, int x, int y, int width, int height,
  ATRACE_NAME("IonBuffer::LockYUV");
  ALOGD_IF(TRACE,
           "IonBuffer::Lock: handle=%p usage=%d x=%d y=%d width=%d height=%d",
           handle_, usage, x, y, width, height);
  const int err = gralloc_module_->lock_ycbcr(gralloc_module_, handle_, usage,
                                              x, y, width, height, yuv);
  if (!err)
    locked_ = true;
           handle(), usage, x, y, width, height);

  return err;
  status_t err = buffer_->lockYCbCr(usage, Rect(x, y, x + width, y + height),
                                    yuv);
  if (err != NO_ERROR)
    return -EINVAL;
  else
    return 0;
}

int IonBuffer::Unlock() {
  ATRACE_NAME("IonBuffer::Unlock");
  ALOGD_IF(TRACE, "IonBuffer::Unlock: handle=%p", handle_);

  // Lock may be called multiple times; but only one Unlock is required.
  const int err = gralloc_module_->unlock(gralloc_module_, handle_);
  if (!err)
    locked_ = false;

  return err;
}

void IonBuffer::GrallocInit() {
  static std::once_flag gralloc_flag;
  std::call_once(gralloc_flag, []() {
    hw_module_t const* module = nullptr;
    alloc_device_t* device = nullptr;
  ALOGD_IF(TRACE, "IonBuffer::Unlock: handle=%p", handle());

    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
    ALOGE_IF(err, "IonBuffer::GrallocInit: failed to find the %s module: %s",
             GRALLOC_HARDWARE_MODULE_ID, strerror(-err));

    err = gralloc_open(module, &device);
    ALOGE_IF(err, "IonBuffer::GrallocInit: failed to open gralloc device: %s",
             strerror(-err));

    gralloc_module_ = reinterpret_cast<gralloc_module_t const*>(module);
    gralloc_device_ = device;
  });
  status_t err = buffer_->unlock();
  if (err != NO_ERROR)
    return -EINVAL;
  else
    return 0;
}

} // namespace dvr
} // namespace android
+0 −1
Original line number Diff line number Diff line
include $(call all-subdir-makefiles)
+0 −74
Original line number Diff line number Diff line
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

COMPONENT_TOP := ${LOCAL_PATH}/../..

LOCAL_SRC_FILES := \
        ion_buffer-test.cpp \
        ../../ion_buffer.cpp \
        ../../mocks/gralloc/gralloc.cpp

LOCAL_SHARED_LIBRARIES := \
        libc \
        libcutils \
        libutils \
        liblog

LOCAL_STATIC_LIBRARIES := \
        libgmock

LOCAL_C_INCLUDES := \
        ${COMPONENT_TOP}/mocks/gralloc \
        ${COMPONENT_TOP}/include \
        $(TOP)/system/core/base/include

LOCAL_EXPORT_C_INCLUDE_DIRS := ${LOCAL_C_INCLUDES}

LOCAL_NATIVE_COVERAGE := true

LOCAL_CFLAGS := -DTRACE=0 -g

LOCAL_MODULE := ion_buffer-test
LOCAL_MODULE_TAGS := tests

include $(BUILD_NATIVE_TEST)

include $(CLEAR_VARS)

LOCAL_SRC_FILES := \
        ion_buffer-test.cpp \
        ../../ion_buffer.cpp \
        ../../mocks/gralloc/gralloc.cpp

LOCAL_SHARED_LIBRARIES := \
        liblog

LOCAL_STATIC_LIBRARIES := \
        libgmock_host

LOCAL_C_INCLUDES := \
        ${COMPONENT_TOP}/mocks/gralloc \
        ${COMPONENT_TOP}/include \
        $(TOP)/system/core/base/include

LOCAL_EXPORT_C_INCLUDE_DIRS := ${LOCAL_C_INCLUDES}

LOCAL_NATIVE_COVERAGE := true

LOCAL_CFLAGS := -DTRACE=0

LOCAL_MODULE := ion_buffer-host_test
LOCAL_MODULE_TAGS := tests
include $(BUILD_HOST_NATIVE_TEST)

.PHONY: dvr_host_native_unit_tests
dvr_host_native_unit_tests: ion_buffer-host_test
ifeq (true,$(NATIVE_COVERAGE))
  ion_buffer-host_test: llvm-cov
  ion_buffer-test: llvm-cov
  # This shouldn't be necessary, but the default build with
  # NATIVE_COVERAGE=true manages to ion_buffer-test without
  # building llvm-cov (droid is the default target).
  droid: llvm-cov
endif
Loading