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

Commit b0ae9c12 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refactor IonBuffer to use GraphicBuffer"

parents 570e6ec1 8a71b131
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