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

Commit 021776e2 authored by Fan Xu's avatar Fan Xu Committed by Tianyu Jiang
Browse files

Refactor BufferHubBuffer to use hwbinder

Entirely move BufferHubBuffer off pdx dependency and using hwbinder
backend and rewrite test cases to fit in current behavior.

Remove duplicated test cases in buffer_hub-test. Commented out
BufferHubBuffer related parts and remove related include and using
statement.

Add hidl interface dependency to libs/gui build file to avoid compile
errors.

Test: BufferHub_test, GraphicBuffer_test, buffer_hub-test
Bug: 116681016
Change-Id: I9d8f734f681e04d3d50b7a02c27b17df8c66cbad
parent 6b4b1e5b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ cc_library_shared {
    ],

    shared_libs: [
        "android.frameworks.bufferhub@1.0",
        "android.hardware.graphics.common@1.1",
        "libbase",
        "libsync",
@@ -153,6 +154,7 @@ cc_library_shared {
                "BufferHubProducer.cpp",
            ],
            exclude_shared_libs: [
                "android.frameworks.bufferhub@1.0",
                "libbufferhub",
                "libbufferhubqueue",
                "libpdx_default_transport",
+2 −4
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ cc_library_shared {
    ],

    shared_libs: [
        "android.frameworks.bufferhub@1.0",
        "android.hardware.graphics.allocator@2.0",
        "android.hardware.graphics.common@1.2",
        "android.hardware.graphics.mapper@2.0",
@@ -93,7 +94,6 @@ cc_library_shared {
        "libutils",
        "libutilscallstack",
        "liblog",
        "libpdx_default_transport",  // TODO(b/112338294): Remove this once BufferHub moved to use Binder.
    ],

    export_shared_lib_headers: [
@@ -121,6 +121,7 @@ cc_library_shared {
                "libnativewindow_headers",
            ],
            exclude_shared_libs: [
                "android.frameworks.bufferhub@1.0",
                "libpdx_default_transport",
            ],
        },
@@ -148,9 +149,6 @@ cc_library_shared {
        "libhardware_headers",
        "libui_headers",
    ],

    // TODO(b/117568153): Temporarily opt out using libcrt.
    no_libcrt: true,
}

cc_library_headers {
+182 −134
Original line number Diff line number Diff line
@@ -14,150 +14,190 @@
 * limitations under the License.
 */

// We would eliminate the clang warnings introduced by libdpx.
// TODO(b/112338294): Remove those once BufferHub moved to use Binder
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wdouble-promotion"
#pragma clang diagnostic ignored "-Wgnu-case-range"
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override"
#pragma clang diagnostic ignored "-Wnested-anon-types"
#pragma clang diagnostic ignored "-Wpacked"
#pragma clang diagnostic ignored "-Wshadow"
#pragma clang diagnostic ignored "-Wsign-conversion"
#pragma clang diagnostic ignored "-Wswitch-enum"
#pragma clang diagnostic ignored "-Wundefined-func-template"
#pragma clang diagnostic ignored "-Wunused-template"
#pragma clang diagnostic ignored "-Wweak-vtables"
#include <pdx/default_transport/client_channel.h>
#include <pdx/default_transport/client_channel_factory.h>
#include <pdx/file_handle.h>
#include <private/dvr/bufferhub_rpc.h>
#pragma clang diagnostic pop

#include <poll.h>

#include <android-base/unique_fd.h>
#include <android/frameworks/bufferhub/1.0/IBufferHub.h>
#include <log/log.h>
#include <ui/BufferHubBuffer.h>
#include <ui/BufferHubDefs.h>

using android::base::unique_fd;
using android::dvr::BufferTraits;
using android::dvr::DetachedBufferRPC;
using android::dvr::NativeHandleWrapper;

// TODO(b/112338294): Remove PDX dependencies from libui.
using android::pdx::LocalChannelHandle;
using android::pdx::LocalHandle;
using android::pdx::Status;
using android::pdx::default_transport::ClientChannel;
using android::pdx::default_transport::ClientChannelFactory;
#include <utils/Trace.h>

using ::android::base::unique_fd;
using ::android::BufferHubDefs::AnyClientAcquired;
using ::android::BufferHubDefs::AnyClientGained;
using ::android::BufferHubDefs::IsClientAcquired;
using ::android::BufferHubDefs::IsClientGained;
using ::android::BufferHubDefs::IsClientPosted;
using ::android::BufferHubDefs::IsClientReleased;
using ::android::frameworks::bufferhub::V1_0::BufferHubStatus;
using ::android::frameworks::bufferhub::V1_0::BufferTraits;
using ::android::frameworks::bufferhub::V1_0::IBufferClient;
using ::android::frameworks::bufferhub::V1_0::IBufferHub;
using ::android::hardware::hidl_handle;
using ::android::hardware::graphics::common::V1_2::HardwareBufferDescription;

namespace android {

namespace {

// TODO(b/112338294): Remove this string literal after refactoring BufferHub
// to use Binder.
static constexpr char kBufferHubClientPath[] = "system/buffer_hub/client";

using BufferHubDefs::AnyClientAcquired;
using BufferHubDefs::AnyClientGained;
using BufferHubDefs::IsClientAcquired;
using BufferHubDefs::IsClientGained;
using BufferHubDefs::IsClientPosted;
using BufferHubDefs::IsClientReleased;
using BufferHubDefs::kHighBitsMask;

} // namespace
std::unique_ptr<BufferHubBuffer> BufferHubBuffer::Create(uint32_t width, uint32_t height,
                                                         uint32_t layerCount, uint32_t format,
                                                         uint64_t usage, size_t userMetadataSize) {
    auto buffer = std::unique_ptr<BufferHubBuffer>(
            new BufferHubBuffer(width, height, layerCount, format, usage, userMetadataSize));
    return buffer->IsValid() ? std::move(buffer) : nullptr;
}

BufferHubClient::BufferHubClient() : Client(ClientChannelFactory::Create(kBufferHubClientPath)) {}
std::unique_ptr<BufferHubBuffer> BufferHubBuffer::Import(const native_handle_t* token) {
    if (token == nullptr) {
        ALOGE("%s: token cannot be nullptr!", __FUNCTION__);
        return nullptr;
    }

BufferHubClient::BufferHubClient(LocalChannelHandle mChannelHandle)
      : Client(ClientChannel::Create(std::move(mChannelHandle))) {}
    auto buffer = std::unique_ptr<BufferHubBuffer>(new BufferHubBuffer(token));
    return buffer->IsValid() ? std::move(buffer) : nullptr;
}

BufferHubClient::~BufferHubClient() {}
BufferHubBuffer::BufferHubBuffer(uint32_t width, uint32_t height, uint32_t layerCount,
                                 uint32_t format, uint64_t usage, size_t userMetadataSize) {
    ATRACE_CALL();
    ALOGD("%s: width=%u height=%u layerCount=%u, format=%u "
          "usage=%" PRIx64 " mUserMetadataSize=%zu",
          __FUNCTION__, width, height, layerCount, format, usage, userMetadataSize);

    sp<IBufferHub> bufferhub = IBufferHub::getService();
    if (bufferhub.get() == nullptr) {
        ALOGE("%s: BufferHub service not found!", __FUNCTION__);
        return;
    }

bool BufferHubClient::IsValid() const {
    return IsConnected() && GetChannelHandle().valid();
    AHardwareBuffer_Desc aDesc = {width, height,         layerCount,   format,
                                  usage, /*stride=*/0UL, /*rfu0=*/0UL, /*rfu1=*/0ULL};
    HardwareBufferDescription desc;
    memcpy(&desc, &aDesc, sizeof(HardwareBufferDescription));

    BufferHubStatus ret;
    sp<IBufferClient> client;
    BufferTraits bufferTraits;
    IBufferHub::allocateBuffer_cb alloc_cb = [&](const auto& status, const auto& outClient,
                                                 const auto& traits) {
        ret = status;
        client = std::move(outClient);
        bufferTraits = std::move(traits);
    };

    if (!bufferhub->allocateBuffer(desc, static_cast<uint32_t>(userMetadataSize), alloc_cb)
                 .isOk()) {
        ALOGE("%s: allocateBuffer transaction failed!", __FUNCTION__);
        return;
    } else if (ret != BufferHubStatus::NO_ERROR) {
        ALOGE("%s: allocateBuffer failed with error %u.", __FUNCTION__, ret);
        return;
    } else if (client == nullptr) {
        ALOGE("%s: allocateBuffer got null BufferClient.", __FUNCTION__);
        return;
    }

LocalChannelHandle BufferHubClient::TakeChannelHandle() {
    if (IsConnected()) {
        return std::move(GetChannelHandle());
    } else {
        return {};
    const int importRet = initWithBufferTraits(bufferTraits);
    if (importRet < 0) {
        ALOGE("%s: Failed to import buffer: %s", __FUNCTION__, strerror(-importRet));
        client->close();
    }
    mBufferClient = std::move(client);
}

BufferHubBuffer::BufferHubBuffer(uint32_t width, uint32_t height, uint32_t layerCount,
                                 uint32_t format, uint64_t usage, size_t mUserMetadataSize) {
    ATRACE_CALL();
    ALOGD("%s: width=%u height=%u layerCount=%u, format=%u usage=%" PRIx64 " mUserMetadataSize=%zu",
          __FUNCTION__, width, height, layerCount, format, usage, mUserMetadataSize);
BufferHubBuffer::BufferHubBuffer(const native_handle_t* token) {
    sp<IBufferHub> bufferhub = IBufferHub::getService();
    if (bufferhub.get() == nullptr) {
        ALOGE("%s: BufferHub service not found!", __FUNCTION__);
        return;
    }

    auto status =
            mClient.InvokeRemoteMethod<DetachedBufferRPC::Create>(width, height, layerCount, format,
                                                                  usage, mUserMetadataSize);
    if (!status) {
        ALOGE("%s: Failed to create detached buffer: %s", __FUNCTION__,
              status.GetErrorMessage().c_str());
        mClient.Close(-status.error());
    BufferHubStatus ret;
    sp<IBufferClient> client;
    BufferTraits bufferTraits;
    IBufferHub::importBuffer_cb import_cb = [&](const auto& status, const auto& outClient,
                                                const auto& traits) {
        ret = status;
        client = std::move(outClient);
        bufferTraits = std::move(traits);
    };

    // hidl_handle(native_handle_t*) simply creates a raw pointer reference withouth ownership
    // transfer.
    if (!bufferhub->importBuffer(hidl_handle(token), import_cb).isOk()) {
        ALOGE("%s: importBuffer transaction failed!", __FUNCTION__);
        return;
    } else if (ret != BufferHubStatus::NO_ERROR) {
        ALOGE("%s: importBuffer failed with error %u.", __FUNCTION__, ret);
        return;
    } else if (client == nullptr) {
        ALOGE("%s: importBuffer got null BufferClient.", __FUNCTION__);
        return;
    }

    const int ret = ImportGraphicBuffer();
    if (ret < 0) {
        ALOGE("%s: Failed to import buffer: %s", __FUNCTION__, strerror(-ret));
        mClient.Close(ret);
    const int importRet = initWithBufferTraits(bufferTraits);
    if (importRet < 0) {
        ALOGE("%s: Failed to import buffer: %s", __FUNCTION__, strerror(-importRet));
        client->close();
    }
    mBufferClient = std::move(client);
}

BufferHubBuffer::BufferHubBuffer(LocalChannelHandle mChannelHandle)
      : mClient(std::move(mChannelHandle)) {
    const int ret = ImportGraphicBuffer();
    if (ret < 0) {
        ALOGE("%s: Failed to import buffer: %s", __FUNCTION__, strerror(-ret));
        mClient.Close(ret);
BufferHubBuffer::~BufferHubBuffer() {
    // Close buffer client to avoid possible race condition: user could first duplicate and hold
    // token with the original buffer gone, and then try to import the token. The close function
    // will explicitly invalidate the token to avoid this.
    if (mBufferClient != nullptr) {
        if (!mBufferClient->close().isOk()) {
            ALOGE("%s: close BufferClient transaction failed!", __FUNCTION__);
        }
    }
}

int BufferHubBuffer::ImportGraphicBuffer() {
int BufferHubBuffer::initWithBufferTraits(const BufferTraits& bufferTraits) {
    ATRACE_CALL();

    auto status = mClient.InvokeRemoteMethod<DetachedBufferRPC::Import>();
    if (!status) {
        ALOGE("%s: Failed to import GraphicBuffer: %s", __FUNCTION__,
              status.GetErrorMessage().c_str());
        return -status.error();
    if (bufferTraits.bufferInfo.getNativeHandle() == nullptr) {
        ALOGE("%s: missing buffer info handle.", __FUNCTION__);
        return -EINVAL;
    }

    if (bufferTraits.bufferHandle.getNativeHandle() == nullptr) {
        ALOGE("%s: missing gralloc handle.", __FUNCTION__);
        return -EINVAL;
    }

    BufferTraits<LocalHandle> bufferTraits = status.take();
    if (bufferTraits.id() < 0) {
        ALOGE("%s: Received an invalid id!", __FUNCTION__);
        return -EIO;
    int bufferId = bufferTraits.bufferInfo->data[1];
    if (bufferId < 0) {
        ALOGE("%s: Received an invalid (negative) id!", __FUNCTION__);
        return -EINVAL;
    }

    // Stash the buffer id to replace the value in mId.
    const int bufferId = bufferTraits.id();
    uint32_t clientBitMask;
    memcpy(&clientBitMask, &bufferTraits.bufferInfo->data[2], sizeof(clientBitMask));
    if (clientBitMask == 0U) {
        ALOGE("%s: Received a invalid client state mask!", __FUNCTION__);
        return -EINVAL;
    }

    // Import the metadata.
    LocalHandle metadataHandle = bufferTraits.take_metadata_handle();
    unique_fd metadataFd(metadataHandle.Release());
    mMetadata = BufferHubMetadata::Import(std::move(metadataFd));
    // Import the metadata. Dup since hidl_handle owns the fd
    unique_fd ashmemFd(dup(bufferTraits.bufferInfo->data[0]));
    mMetadata = BufferHubMetadata::Import(std::move(ashmemFd));

    if (!mMetadata.IsValid()) {
        ALOGE("%s: invalid metadata.", __FUNCTION__);
        return -ENOMEM;
        return -EINVAL;
    }

    if (mMetadata.metadata_size() != bufferTraits.metadata_size()) {
        ALOGE("%s: metadata buffer too small: %zu, expected: %" PRIu64 ".", __FUNCTION__,
              mMetadata.metadata_size(), bufferTraits.metadata_size());
        return -ENOMEM;
    uint32_t userMetadataSize;
    memcpy(&userMetadataSize, &bufferTraits.bufferInfo->data[3], sizeof(userMetadataSize));
    if (mMetadata.user_metadata_size() != userMetadataSize) {
        ALOGE("%s: user metadata size not match: expected %u, actual %zu.", __FUNCTION__,
              userMetadataSize, mMetadata.user_metadata_size());
        return -EINVAL;
    }

    size_t metadataSize = static_cast<size_t>(bufferTraits.metadata_size());
    size_t metadataSize = static_cast<size_t>(mMetadata.metadata_size());
    if (metadataSize < BufferHubDefs::kMetadataHeaderSize) {
        ALOGE("%s: metadata too small: %zu", __FUNCTION__, metadataSize);
        return -EINVAL;
@@ -178,24 +218,14 @@ int BufferHubBuffer::ImportGraphicBuffer() {

    // Import the buffer: We only need to hold on the native_handle_t here so that
    // GraphicBuffer instance can be created in future.
    mBufferHandle = bufferTraits.take_buffer_handle();

    // Populate buffer desc based on buffer traits.
    mBufferDesc.width = bufferTraits.width();
    mBufferDesc.height = bufferTraits.height();
    mBufferDesc.layers = bufferTraits.layer_count();
    mBufferDesc.format = bufferTraits.format();
    mBufferDesc.usage = bufferTraits.usage();
    mBufferDesc.stride = bufferTraits.stride();
    mBufferDesc.rfu0 = 0U;
    mBufferDesc.rfu1 = 0U;

    // If all imports succeed, replace the previous buffer and id.
    mBufferHandle = std::move(bufferTraits.bufferHandle);
    memcpy(&mBufferDesc, &bufferTraits.bufferDesc, sizeof(AHardwareBuffer_Desc));

    mId = bufferId;
    mClientStateMask = bufferTraits.client_state_mask();
    mClientStateMask = clientBitMask;

    // TODO(b/112012161) Set up shared fences.
    ALOGD("%s: id=%d, buffer_state=%" PRIx32 ".", __FUNCTION__, id(),
    ALOGD("%s: id=%d, buffer_state=%" PRIx32 ".", __FUNCTION__, mId,
          buffer_state_->load(std::memory_order_acquire));
    return 0;
}
@@ -225,7 +255,7 @@ int BufferHubBuffer::Gain() {

int BufferHubBuffer::Post() {
    uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
    uint32_t updated_buffer_state = (~mClientStateMask) & kHighBitsMask;
    uint32_t updated_buffer_state = (~mClientStateMask) & BufferHubDefs::kHighBitsMask;
    do {
        if (!IsClientGained(current_buffer_state, mClientStateMask)) {
            ALOGE("%s: Cannot post a buffer that is not gained by this client. buffer_id=%d "
@@ -283,24 +313,42 @@ int BufferHubBuffer::Release() {
    return 0;
}

int BufferHubBuffer::Poll(int timeoutMs) {
    ATRACE_CALL();

    pollfd p = {mClient.event_fd(), POLLIN, 0};
    return poll(&p, 1, timeoutMs);
bool BufferHubBuffer::IsValid() const {
    // TODO(b/68770788): check eventFd once implemented
    return mBufferHandle.getNativeHandle() != nullptr && mId >= 0 && mClientStateMask != 0U &&
            mMetadata.IsValid() && mBufferClient != nullptr;
}

Status<LocalChannelHandle> BufferHubBuffer::Duplicate() {
    ATRACE_CALL();
    ALOGD("%s: id=%d.", __FUNCTION__, mId);
// TODO(b/68770788): implement Poll() once we have event fd
int BufferHubBuffer::Poll(int /* timeoutMs */) {
    return -ENOSYS;
}

    auto statusOrHandle = mClient.InvokeRemoteMethod<DetachedBufferRPC::Duplicate>();
native_handle_t* BufferHubBuffer::Duplicate() {
    if (mBufferClient == nullptr) {
        ALOGE("%s: missing BufferClient!", __FUNCTION__);
        return nullptr;
    }

    if (!statusOrHandle.ok()) {
        ALOGE("%s: Failed to duplicate buffer (id=%d): %s.", __FUNCTION__, mId,
              statusOrHandle.GetErrorMessage().c_str());
    hidl_handle token;
    BufferHubStatus ret;
    IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
        token = std::move(outToken);
        ret = status;
    };

    if (!mBufferClient->duplicate(dup_cb).isOk()) {
        ALOGE("%s: duplicate transaction failed!", __FUNCTION__);
        return nullptr;
    } else if (ret != BufferHubStatus::NO_ERROR) {
        ALOGE("%s: duplicate failed with error %u.", __FUNCTION__, ret);
        return nullptr;
    } else if (token.getNativeHandle() == nullptr) {
        ALOGE("%s: duplicate got null token.", __FUNCTION__);
        return nullptr;
    }
    return statusOrHandle;

    return native_handle_clone(token.getNativeHandle());
}

} // namespace android
+36 −72
Original line number Diff line number Diff line
@@ -17,73 +17,43 @@
#ifndef ANDROID_BUFFER_HUB_BUFFER_H_
#define ANDROID_BUFFER_HUB_BUFFER_H_

// We would eliminate the clang warnings introduced by libdpx.
// TODO(b/112338294): Remove those once BufferHub moved to use Binder
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wdouble-promotion"
#pragma clang diagnostic ignored "-Wgnu-case-range"
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override"
#pragma clang diagnostic ignored "-Wnested-anon-types"
#pragma clang diagnostic ignored "-Wpacked"
#pragma clang diagnostic ignored "-Wshadow"
#pragma clang diagnostic ignored "-Wsign-conversion"
#pragma clang diagnostic ignored "-Wswitch-enum"
#pragma clang diagnostic ignored "-Wundefined-func-template"
#pragma clang diagnostic ignored "-Wunused-template"
#pragma clang diagnostic ignored "-Wweak-vtables"
#include <pdx/client.h>
#include <private/dvr/native_handle_wrapper.h>
#pragma clang diagnostic pop

#include <android/frameworks/bufferhub/1.0/IBufferClient.h>
#include <android/hardware_buffer.h>
#include <cutils/native_handle.h>
#include <ui/BufferHubDefs.h>
#include <ui/BufferHubMetadata.h>

namespace android {

class BufferHubClient : public pdx::Client {
public:
    BufferHubClient();
    virtual ~BufferHubClient();
    explicit BufferHubClient(pdx::LocalChannelHandle mChannelHandle);

    bool IsValid() const;
    pdx::LocalChannelHandle TakeChannelHandle();

    using pdx::Client::Close;
    using pdx::Client::event_fd;
    using pdx::Client::GetChannel;
    using pdx::Client::InvokeRemoteMethod;
};

class BufferHubBuffer {
public:
    // Allocates a standalone BufferHubBuffer not associated with any producer consumer set.
    // Allocates a standalone BufferHubBuffer.
    static std::unique_ptr<BufferHubBuffer> Create(uint32_t width, uint32_t height,
                                                   uint32_t layerCount, uint32_t format,
                                                   uint64_t usage, size_t userMetadataSize) {
        return std::unique_ptr<BufferHubBuffer>(
                new BufferHubBuffer(width, height, layerCount, format, usage, userMetadataSize));
    }
                                                   uint64_t usage, size_t userMetadataSize);

    // Imports the given channel handle to a BufferHubBuffer, taking ownership.
    static std::unique_ptr<BufferHubBuffer> Import(pdx::LocalChannelHandle mChannelHandle) {
        return std::unique_ptr<BufferHubBuffer>(new BufferHubBuffer(std::move(mChannelHandle)));
    }
    // Imports the given token to a BufferHubBuffer. Not taking ownership of the token. Caller
    // should close and destroy the token after calling this function regardless of output.
    // TODO(b/122543147): use a movable wrapper for token
    static std::unique_ptr<BufferHubBuffer> Import(const native_handle_t* token);

    BufferHubBuffer(const BufferHubBuffer&) = delete;
    void operator=(const BufferHubBuffer&) = delete;

    virtual ~BufferHubBuffer();

    // Gets ID of the buffer client. All BufferHubBuffer clients derived from the same buffer in
    // bufferhubd share the same buffer id.
    // BufferHub share the same buffer id.
    int id() const { return mId; }

    // Returns the buffer description, which is guaranteed to be faithful values from bufferhubd.
    // Returns the buffer description, which is guaranteed to be faithful values from BufferHub.
    const AHardwareBuffer_Desc& desc() const { return mBufferDesc; }

    const native_handle_t* DuplicateHandle() { return mBufferHandle.DuplicateHandle(); }
    // Duplicate the underlying Gralloc buffer handle. Caller is responsible to free the handle
    // after use.
    native_handle_t* DuplicateHandle() {
        return native_handle_clone(mBufferHandle.getNativeHandle());
    }

    // Returns the current value of MetadataHeader::buffer_state.
    uint32_t buffer_state() {
@@ -96,12 +66,12 @@ public:

    size_t user_metadata_size() const { return mMetadata.user_metadata_size(); }

    // Returns true if the buffer holds an open PDX channels towards bufferhubd.
    bool IsConnected() const { return mClient.IsValid(); }
    // Returns true if the BufferClient is still alive.
    bool IsConnected() const { return mBufferClient->ping().isOk(); }

    // Returns true if the buffer holds an valid native buffer handle that's availble for the client
    // to read from and/or write into.
    bool IsValid() const { return mBufferHandle.IsValid(); }
    // Returns true if the buffer is valid: non-null buffer handle, valid id, valid client bit mask,
    // valid metadata and valid buffer client
    bool IsValid() const;

    // Gains the buffer for exclusive write permission. Read permission is implied once a buffer is
    // gained.
@@ -124,33 +94,27 @@ public:
    // current cycle of the usage of the buffer.
    int Release();

    // Returns the event mask for all the events that are pending on this buffer (see sys/poll.h for
    // all possible bits).
    pdx::Status<int> GetEventMask(int events) {
        if (auto* channel = mClient.GetChannel()) {
            return channel->GetEventMask(events);
        } else {
            return pdx::ErrorStatus(EINVAL);
        }
    }

    // Polls the fd for |timeoutMs| milliseconds (-1 for infinity).
    int Poll(int timeoutMs);

    // Creates a BufferHubBuffer client from an existing one. The new client will
    // share the same underlying gralloc buffer and ashmem region for metadata.
    pdx::Status<pdx::LocalChannelHandle> Duplicate();
    // Creates a token that stands for this BufferHubBuffer client and could be used for Import to
    // create another BufferHubBuffer. The new BufferHubBuffer will share the same underlying
    // gralloc buffer and ashmem region for metadata. Note that the caller owns the token and
    // should free it after use.
    // Returns a valid token on success, nullptr on failure.
    // TODO(b/122543147): use a movable wrapper for token
    native_handle_t* Duplicate();

private:
    BufferHubBuffer(uint32_t width, uint32_t height, uint32_t layerCount, uint32_t format,
                    uint64_t usage, size_t userMetadataSize);

    BufferHubBuffer(pdx::LocalChannelHandle mChannelHandle);
    BufferHubBuffer(const native_handle_t* token);

    int ImportGraphicBuffer();
    int initWithBufferTraits(const frameworks::bufferhub::V1_0::BufferTraits& bufferTraits);

    // Global id for the buffer that is consistent across processes.
    int mId = -1;
    int mId = 0;

    // Client state mask of this BufferHubBuffer object. It is unique amoung all
    // clients/users of the buffer.
@@ -159,8 +123,8 @@ private:
    // Stores ground truth of the buffer.
    AHardwareBuffer_Desc mBufferDesc;

    // Wrapps the gralloc buffer handle of this buffer.
    dvr::NativeHandleWrapper<pdx::LocalHandle> mBufferHandle;
    // Wraps the gralloc buffer handle of this buffer.
    hardware::hidl_handle mBufferHandle;

    // An ashmem-based metadata object. The same shared memory are mapped to the
    // bufferhubd daemon and all buffer clients.
@@ -170,8 +134,8 @@ private:
    std::atomic<uint32_t>* fence_state_ = nullptr;
    std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;

    // PDX backend.
    BufferHubClient mClient;
    // HwBinder backend
    sp<frameworks::bufferhub::V1_0::IBufferClient> mBufferClient;
};

} // namespace android
+4 −4

File changed.

Preview size limit exceeded, changes collapsed.

Loading