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

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

Merge "Move core data structure of DetachedBuffer into BufferNode"

parents fe5966b0 2e06c1cb
Loading
Loading
Loading
Loading
+32 −0
Original line number Original line Diff line number Diff line
@@ -945,3 +945,35 @@ TEST_F(LibBufferHubTest, TestDetachThenPromote) {
  EXPECT_EQ(b1_id, p2_id);
  EXPECT_EQ(b1_id, p2_id);
  EXPECT_TRUE(IsBufferGained(p2->buffer_state()));
  EXPECT_TRUE(IsBufferGained(p2->buffer_state()));
}
}

TEST_F(LibBufferHubTest, TestDuplicateDetachedBuffer) {
  auto b1 = DetachedBuffer::Create(kWidth, kHeight, kLayerCount, kFormat,
                                   kUsage, kUserMetadataSize);
  int b1_id = b1->id();
  EXPECT_TRUE(b1->IsValid());

  auto status_or_handle = b1->Duplicate();
  EXPECT_TRUE(status_or_handle);

  // The detached buffer should still be valid.
  EXPECT_TRUE(b1->IsConnected());
  EXPECT_TRUE(b1->IsValid());

  // Gets the channel handle for the duplicated buffer.
  LocalChannelHandle h2 = status_or_handle.take();
  EXPECT_TRUE(h2.valid());

  std::unique_ptr<DetachedBuffer> b2 = DetachedBuffer::Import(std::move(h2));
  EXPECT_FALSE(h2.valid());
  ASSERT_TRUE(b2 != nullptr);
  int b2_id = b2->id();

  // The duplicated buffer should inherit the same buffer id.
  EXPECT_EQ(b1_id, b2_id);

  // Promote the detached buffer should fail as b1 is no longer the exclusive
  // owner of the buffer..
  status_or_handle = b1->Promote();
  EXPECT_FALSE(status_or_handle.ok());
  EXPECT_EQ(status_or_handle.error(), EINVAL);
}
+14 −0
Original line number Original line Diff line number Diff line
@@ -104,6 +104,20 @@ Status<LocalChannelHandle> DetachedBuffer::Promote() {
  return status_or_handle;
  return status_or_handle;
}
}


Status<LocalChannelHandle> DetachedBuffer::Duplicate() {
  ATRACE_NAME("DetachedBuffer::Duplicate");
  ALOGD_IF(TRACE, "DetachedBuffer::Duplicate: id=%d.", id_);

  auto status_or_handle =
      client_.InvokeRemoteMethod<DetachedBufferRPC::Duplicate>();

  if (!status_or_handle.ok()) {
    ALOGE("DetachedBuffer::Duplicate: Failed to duplicate buffer (id=%d): %s.",
          id_, status_or_handle.GetErrorMessage().c_str());
  }
  return status_or_handle;
}

sp<GraphicBuffer> DetachedBuffer::TakeGraphicBuffer() {
sp<GraphicBuffer> DetachedBuffer::TakeGraphicBuffer() {
  if (!client_.IsValid() || !buffer_.buffer()) {
  if (!client_.IsValid() || !buffer_.buffer()) {
    ALOGE("DetachedBuffer::TakeGraphicBuffer: Invalid buffer.");
    ALOGE("DetachedBuffer::TakeGraphicBuffer: Invalid buffer.");
+89 −0
Original line number Original line Diff line number Diff line
#ifndef ANDROID_DVR_BUFFER_HUB_DEFS_H_
#define ANDROID_DVR_BUFFER_HUB_DEFS_H_

#include <dvr/dvr_api.h>
#include <hardware/gralloc.h>

#include <atomic>

namespace android {
namespace dvr {

namespace BufferHubDefs {

static constexpr uint32_t kMetadataFormat = HAL_PIXEL_FORMAT_BLOB;
static constexpr uint32_t kMetadataUsage =
    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;

// Single producuer multiple (up to 63) consumers ownership signal.
// 64-bit atomic unsigned int.
//
// MSB           LSB
//  |             |
//  v             v
// [P|C62|...|C1|C0]
// Gain'ed state:     [0|..|0|0] -> Exclusively Writable.
// Post'ed state:     [1|..|0|0]
// Acquired'ed state: [1|..|X|X] -> At least one bit is set in lower 63 bits
// Released'ed state: [0|..|X|X] -> At least one bit is set in lower 63 bits
static constexpr uint64_t kProducerStateBit = 1ULL << 63;
static constexpr uint64_t kConsumerStateMask = (1ULL << 63) - 1;

static inline void ModifyBufferState(std::atomic<uint64_t>* buffer_state,
                                     uint64_t clear_mask, uint64_t set_mask) {
  uint64_t old_state;
  uint64_t new_state;
  do {
    old_state = buffer_state->load();
    new_state = (old_state & ~clear_mask) | set_mask;
  } while (!buffer_state->compare_exchange_weak(old_state, new_state));
}

static inline bool IsBufferGained(uint64_t state) { return state == 0; }

static inline bool IsBufferPosted(uint64_t state,
                                  uint64_t consumer_bit = kConsumerStateMask) {
  return (state & kProducerStateBit) && !(state & consumer_bit);
}

static inline bool IsBufferAcquired(uint64_t state) {
  return (state & kProducerStateBit) && (state & kConsumerStateMask);
}

static inline bool IsBufferReleased(uint64_t state) {
  return !(state & kProducerStateBit) && (state & kConsumerStateMask);
}

static inline uint64_t FindNextClearedBit(uint64_t bits) {
  return ~bits - (~bits & (~bits - 1));
}

static inline uint64_t FindFirstClearedBit() {
  return FindNextClearedBit(kProducerStateBit);
}

struct __attribute__((packed, aligned(8))) MetadataHeader {
  // Internal data format, which can be updated as long as the size, padding and
  // field alignment of the struct is consistent within the same ABI. As this
  // part is subject for future updates, it's not stable cross Android version,
  // so don't have it visible from outside of the Android platform (include Apps
  // and vendor HAL).
  std::atomic<uint64_t> buffer_state;
  std::atomic<uint64_t> fence_state;
  uint64_t queue_index;

  // Public data format, which should be updated with caution. See more details
  // in dvr_api.h
  DvrNativeBufferMetadata metadata;
};

static_assert(sizeof(MetadataHeader) == 128, "Unexpected MetadataHeader size");
static constexpr size_t kMetadataHeaderSize = sizeof(MetadataHeader);

}  // namespace BufferHubDefs

}  // namespace dvr
}  // namespace android


#endif  // ANDROID_DVR_BUFFER_HUB_DEFS_H_
+5 −68
Original line number Original line Diff line number Diff line
#ifndef ANDROID_DVR_BUFFERHUB_RPC_H_
#ifndef ANDROID_DVR_BUFFERHUB_RPC_H_
#define ANDROID_DVR_BUFFERHUB_RPC_H_
#define ANDROID_DVR_BUFFERHUB_RPC_H_


#include "buffer_hub_defs.h"

#include <cutils/native_handle.h>
#include <cutils/native_handle.h>
#include <sys/types.h>
#include <ui/BufferQueueDefs.h>
#include <ui/BufferQueueDefs.h>


#include <dvr/dvr_api.h>
#include <pdx/channel_handle.h>
#include <pdx/channel_handle.h>
#include <pdx/file_handle.h>
#include <pdx/file_handle.h>
#include <pdx/rpc/remote_method.h>
#include <pdx/rpc/remote_method.h>
@@ -15,71 +15,6 @@
namespace android {
namespace android {
namespace dvr {
namespace dvr {


namespace BufferHubDefs {

static constexpr uint32_t kMetadataFormat = HAL_PIXEL_FORMAT_BLOB;
static constexpr uint32_t kMetadataUsage =
    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;

// Single producuer multiple (up to 63) consumers ownership signal.
// 64-bit atomic unsigned int.
//
// MSB           LSB
//  |             |
//  v             v
// [P|C62|...|C1|C0]
// Gain'ed state:     [0|..|0|0] -> Exclusively Writable.
// Post'ed state:     [1|..|0|0]
// Acquired'ed state: [1|..|X|X] -> At least one bit is set in lower 63 bits
// Released'ed state: [0|..|X|X] -> At least one bit is set in lower 63 bits
static constexpr uint64_t kProducerStateBit = 1ULL << 63;
static constexpr uint64_t kConsumerStateMask = (1ULL << 63) - 1;

static inline void ModifyBufferState(std::atomic<uint64_t>* buffer_state,
                                     uint64_t clear_mask, uint64_t set_mask) {
  uint64_t old_state;
  uint64_t new_state;
  do {
    old_state = buffer_state->load();
    new_state = (old_state & ~clear_mask) | set_mask;
  } while (!buffer_state->compare_exchange_weak(old_state, new_state));
}

static inline bool IsBufferGained(uint64_t state) { return state == 0; }

static inline bool IsBufferPosted(uint64_t state,
                                  uint64_t consumer_bit = kConsumerStateMask) {
  return (state & kProducerStateBit) && !(state & consumer_bit);
}

static inline bool IsBufferAcquired(uint64_t state) {
  return (state & kProducerStateBit) && (state & kConsumerStateMask);
}

static inline bool IsBufferReleased(uint64_t state) {
  return !(state & kProducerStateBit) && (state & kConsumerStateMask);
}

struct __attribute__((packed, aligned(8))) MetadataHeader {
  // Internal data format, which can be updated as long as the size, padding and
  // field alignment of the struct is consistent within the same ABI. As this
  // part is subject for future updates, it's not stable cross Android version,
  // so don't have it visible from outside of the Android platform (include Apps
  // and vendor HAL).
  std::atomic<uint64_t> buffer_state;
  std::atomic<uint64_t> fence_state;
  uint64_t queue_index;

  // Public data format, which should be updated with caution. See more details
  // in dvr_api.h
  DvrNativeBufferMetadata metadata;
};

static_assert(sizeof(MetadataHeader) == 128, "Unexpected MetadataHeader size");
static constexpr size_t kMetadataHeaderSize = sizeof(MetadataHeader);

}  // namespace BufferHubDefs

template <typename FileHandleType>
template <typename FileHandleType>
class NativeBufferHandle {
class NativeBufferHandle {
 public:
 public:
@@ -450,6 +385,7 @@ struct DetachedBufferRPC final : public BufferHubRPC {
    kOpCreate = kOpDetachedBufferBase,
    kOpCreate = kOpDetachedBufferBase,
    kOpImport,
    kOpImport,
    kOpPromote,
    kOpPromote,
    kOpDuplicate,
  };
  };


 public:
 public:
@@ -459,8 +395,9 @@ struct DetachedBufferRPC final : public BufferHubRPC {
                         size_t user_metadata_size));
                         size_t user_metadata_size));
  PDX_REMOTE_METHOD(Import, kOpImport, BufferDescription<LocalHandle>(Void));
  PDX_REMOTE_METHOD(Import, kOpImport, BufferDescription<LocalHandle>(Void));
  PDX_REMOTE_METHOD(Promote, kOpPromote, LocalChannelHandle(Void));
  PDX_REMOTE_METHOD(Promote, kOpPromote, LocalChannelHandle(Void));
  PDX_REMOTE_METHOD(Duplicate, kOpDuplicate, LocalChannelHandle(Void));


  PDX_REMOTE_API(API, Create, Promote);
  PDX_REMOTE_API(API, Create, Import, Promote, Duplicate);
};
};


}  // namespace dvr
}  // namespace dvr
+3 −0
Original line number Original line Diff line number Diff line
@@ -57,6 +57,9 @@ class DetachedBuffer {
  // return. Further IPCs towards this channel will return error.
  // return. Further IPCs towards this channel will return error.
  pdx::Status<pdx::LocalChannelHandle> Promote();
  pdx::Status<pdx::LocalChannelHandle> Promote();


  // Creates a DetachedBuffer from an existing one.
  pdx::Status<pdx::LocalChannelHandle> Duplicate();

  // Takes the underlying graphic buffer out of this DetachedBuffer. This call
  // Takes the underlying graphic buffer out of this DetachedBuffer. This call
  // immediately invalidates this DetachedBuffer object and transfers the
  // immediately invalidates this DetachedBuffer object and transfers the
  // underlying pdx::LocalChannelHandle into the GraphicBuffer.
  // underlying pdx::LocalChannelHandle into the GraphicBuffer.
Loading