blob: c6a4a232d18b2247a5de42068e97c84a6b3fb803 [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANDROID_BUFFER_HUB_BUFFER_H_
#define ANDROID_BUFFER_HUB_BUFFER_H_
#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 BufferHubBuffer {
public:
// 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);
// 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
// BufferHub share the same buffer id.
int id() const { return mId; }
// Returns the buffer description, which is guaranteed to be faithful values from BufferHub.
const AHardwareBuffer_Desc& desc() const { return mBufferDesc; }
// 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() {
return mMetadata.metadata_header()->buffer_state.load(std::memory_order_acquire);
}
// A state mask which is unique to a buffer hub client among all its siblings sharing the same
// concrete graphic buffer.
uint32_t client_state_mask() const { return mClientStateMask; }
size_t user_metadata_size() const { return mMetadata.user_metadata_size(); }
// Returns true if the BufferClient is still alive.
bool IsConnected() const { return mBufferClient->ping().isOk(); }
// 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.
// The buffer can be gained as long as there is no other client in acquired or gained state.
int Gain();
// Posts the gained buffer for other buffer clients to use the buffer.
// The buffer can be posted iff the buffer state for this client is gained.
// After posting the buffer, this client is put to released state and does not have access to
// the buffer for this cycle of the usage of the buffer.
int Post();
// Acquires the buffer for shared read permission.
// The buffer can be acquired iff the buffer state for this client is posted.
int Acquire();
// Releases the buffer.
// The buffer can be released from any buffer state.
// After releasing the buffer, this client no longer have any permissions to the buffer for the
// current cycle of the usage of the buffer.
int Release();
// 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(const native_handle_t* token);
int initWithBufferTraits(const frameworks::bufferhub::V1_0::BufferTraits& bufferTraits);
// Global id for the buffer that is consistent across processes.
int mId = 0;
// Client state mask of this BufferHubBuffer object. It is unique amoung all
// clients/users of the buffer.
uint32_t mClientStateMask = 0U;
// Stores ground truth of the buffer.
AHardwareBuffer_Desc mBufferDesc;
// 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.
BufferHubMetadata mMetadata;
// Shortcuts to the atomics inside the header of mMetadata.
std::atomic<uint32_t>* buffer_state_ = nullptr;
std::atomic<uint32_t>* fence_state_ = nullptr;
std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
// HwBinder backend
sp<frameworks::bufferhub::V1_0::IBufferClient> mBufferClient;
};
} // namespace android
#endif // ANDROID_BUFFER_HUB_BUFFER_H_