blob: 0af70324d78d873b0bea50003c85937849ae91f5 [file] [log] [blame]
/*
* Copyright (C) 2018-2019 ARM Limited. All rights reserved.
*
* Copyright 2016 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.
*/
#include <inttypes.h>
#include <log/log.h>
#include <sync/sync.h>
#include <mutex>
#include <unordered_set>
#include <system/window.h>
#include "GrallocMapper.h"
#include "GrallocBufferDescriptor.h"
#include "mali_gralloc_bufferallocation.h"
#include "mali_gralloc_bufferdescriptor.h"
#include "mali_gralloc_bufferaccess.h"
#include "mali_gralloc_reference.h"
#include "mali_gralloc_ion.h"
#include "mali_gralloc_buffer.h"
namespace android {
namespace hardware {
namespace graphics {
namespace mapper {
namespace HIDL_IMAPPER_NAMESPACE {
namespace implementation {
/* Default definitions for IMapper 2.x interface */
using V2_0::Error;
using V2_0::BufferDescriptor;
namespace {
/* An unordered set to internally store / retrieve imported buffer handles */
class RegisteredHandlePool
{
public:
/* Stores the buffer handle in the internal list */
bool add(buffer_handle_t bufferHandle)
{
std::lock_guard<std::mutex> lock(mutex);
return bufPool.insert(bufferHandle).second;
}
/* Retrieves and removes the buffer handle from internal list */
native_handle_t* remove(void* buffer)
{
auto bufferHandle = static_cast<native_handle_t*>(buffer);
std::lock_guard<std::mutex> lock(mutex);
return bufPool.erase(bufferHandle) == 1 ? bufferHandle : nullptr;
}
/* Retrieves the buffer handle from internal list */
buffer_handle_t get(const void* buffer)
{
auto bufferHandle = static_cast<buffer_handle_t>(buffer);
std::lock_guard<std::mutex> lock(mutex);
return bufPool.count(bufferHandle) == 1 ? bufferHandle : nullptr;
}
private:
std::mutex mutex;
std::unordered_set<buffer_handle_t> bufPool;
};
/* GraphicBufferMapper is expected to be valid (and leaked) during process
* termination. IMapper, and in turn, gRegisteredHandles must be valid as
* well. Create the registered handle pool on the heap, and let
* it leak for simplicity.
*
* However, there is no way to make sure gralloc0/gralloc1 are valid. Any use
* of static/global object in gralloc0/gralloc1 that may have been destructed
* is potentially broken.
*/
RegisteredHandlePool* gRegisteredHandles = new RegisteredHandlePool;
} /* anonymous namespace */
/**
* IMapper constructor. All the state information required for the Gralloc
* private module is populated in its default constructor. Gralloc 2.0 specific
* state information can be populated here.
*
* @return None
*/
GrallocMapper::GrallocMapper()
{
}
/*
* IMapper destructor. All the resources aquired for Gralloc private module
* (in the IMapper context) are released
*
* @return None
*/
GrallocMapper::~GrallocMapper()
{
mali_gralloc_ion_close();
}
/*
* Validates incoming IMapper descriptor attributes
*
* @param descriptor_attr [in] Specifies the attributes of the descriptor.
*
* @return false, for invalid buffer attributes
* true, otherwise
* Note: Latest IMapper version encapsulates all previous versions, hence all
* incoming descriptor information is mapped to the latest IMapper for validation
*/
bool GrallocMapper::validateDescriptorInfo(void *descriptor_attr) const
{
BufferDescriptorInfo * const descriptorInfo = (BufferDescriptorInfo *)descriptor_attr;
using android::hardware::graphics::common::HIDL_COMMON_NAMESPACE::BufferUsage;
using android::hardware::graphics::common::HIDL_COMMON_NAMESPACE::PixelFormat;
const uint64_t validUsageBits =
#if HIDL_MAPPER_VERSION_SCALED >= 210
BufferUsage::GPU_CUBE_MAP |
BufferUsage::GPU_MIPMAP_COMPLETE |
#endif
BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK |
BufferUsage::GPU_TEXTURE | BufferUsage::GPU_RENDER_TARGET |
BufferUsage::COMPOSER_OVERLAY | BufferUsage::COMPOSER_CLIENT_TARGET |
BufferUsage::CAMERA_INPUT | BufferUsage::CAMERA_OUTPUT |
BufferUsage::PROTECTED |
BufferUsage::COMPOSER_CURSOR |
BufferUsage::VIDEO_ENCODER |
BufferUsage::RENDERSCRIPT |
BufferUsage::VIDEO_DECODER |
BufferUsage::SENSOR_DIRECT_DATA |
BufferUsage::GPU_DATA_BUFFER |
BufferUsage::VENDOR_MASK;
if (!descriptorInfo->width || !descriptorInfo->height ||
!descriptorInfo->layerCount)
{
AERR("Invalid buffer descriptor (2.x mapper) attributes, width = %d height = %d layerCount = %d ",
descriptorInfo->width, descriptorInfo->height, descriptorInfo->layerCount);
return false;
}
if (descriptorInfo->format == static_cast<PixelFormat>(0))
{
return false;
}
if (descriptorInfo->usage & ~validUsageBits)
{
/* It is possible that application uses private usage bits. */
ALOGW("Buffer descriptor with invalid usage bits 0x%" PRIx64,
descriptorInfo->usage & ~validUsageBits);
}
return true;
}
/*
* Creates a buffer descriptor from incoming descriptor attributes
*
* @param descriptorInfo [in] Specifies the (2.0 IMapper) attributes of
* the descriptor.
* @param hidl_cb [in] HIDL callback function generating -
* error: NONE upon success. Otherwise,
* BAD_VALUE when any of the specified attributes are invalid
* descriptor: Newly created buffer descriptor.
*
* @return Void
*/
Return<void> GrallocMapper::createDescriptor(
const V2_0::IMapper::BufferDescriptorInfo& descriptorInfo,
createDescriptor_cb hidl_cb)
{
if (validateDescriptorInfo((void *)&descriptorInfo))
{
hidl_cb(Error::NONE, grallocEncodeBufferDescriptor(descriptorInfo));
}
else
{
AERR("Invalid attributes to create descriptor for Mapper 2.0");
hidl_cb(Error::BAD_VALUE, BufferDescriptor());
}
return Void();
}
/*
* Imports a raw buffer handle to create an imported buffer handle for use with
* the rest of the mapper or with other in-process libraries.
*
* @param rawHandle [in] Raw buffer handle to import.
* @param hidl_cb [in] HIDL Callback function to export output information
* @param hidl_cb [in] HIDL callback function generating -
* error : NONE upon success. Otherwise,
* BAD_BUFFER for an invalid buffer
* NO_RESOURCES when the raw handle cannot be imported
* BAD_VALUE when any of the specified attributes are invalid
* buffer : Imported buffer handle
*
* @return Void
*/
Return<void> GrallocMapper::importBuffer(const hidl_handle& rawHandle,
importBuffer_cb hidl_cb)
{
if (!rawHandle.getNativeHandle())
{
AERR("Invalid buffer handle to import");
hidl_cb(Error::BAD_BUFFER, nullptr);
return Void();
}
native_handle_t* bufferHandle = native_handle_clone(rawHandle.getNativeHandle());
if (!bufferHandle)
{
AERR("Failed to clone buffer handle");
hidl_cb(Error::NO_RESOURCES, nullptr);
return Void();
}
const Error error = registerBuffer(bufferHandle);
if (error != Error::NONE)
{
native_handle_close(bufferHandle);
native_handle_delete(bufferHandle);
hidl_cb(error, nullptr);
return Void();
}
if (gRegisteredHandles->add(bufferHandle) == false)
{
/* The newly cloned handle is already registered. This can only happen
* when a handle previously registered was native_handle_delete'd instead
* of freeBuffer'd.
*/
AERR("Handle %p has already been imported; potential fd leaking",
bufferHandle);
unregisterBuffer(bufferHandle);
native_handle_close(bufferHandle);
native_handle_delete(bufferHandle);
hidl_cb(Error::NO_RESOURCES, nullptr);
return Void();
}
hidl_cb(Error::NONE, bufferHandle);
return Void();
}
/*
* Frees a buffer handle and releases all the resources associated with it
*
* @param buffer [in] Imported buffer to free
*
* @return Error::BAD_BUFFER for an invalid buffer / when failed to free the buffer
* Error::NONE on successful free
*/
Return<Error> GrallocMapper::freeBuffer(void* buffer)
{
native_handle_t * const bufferHandle = gRegisteredHandles->remove(buffer);
if (!bufferHandle)
{
AERR("Invalid buffer handle %p to freeBuffer", buffer);
return Error::BAD_BUFFER;
}
const Error status = unregisterBuffer(bufferHandle);
if (status != Error::NONE)
{
return status;
}
native_handle_close(bufferHandle);
native_handle_delete(bufferHandle);
return Error::NONE;
}
/*
* Retrieves the file descriptor referring to a sync fence object
*
* @param fenceHandle [in] HIDL fence handle
* @param outFenceFd [out] Fence file descriptor. '-1' indicates no fence
*
* @return false, for an invalid HIDL fence handle
* true, otherwise
*/
bool GrallocMapper::getFenceFd(const hidl_handle& fenceHandle,
int* outFenceFd) const
{
auto const handle = fenceHandle.getNativeHandle();
if (handle && handle->numFds > 1)
{
AERR("Invalid fence handle with %d fds", handle->numFds);
return false;
}
*outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
return true;
}
/*
* Populates the HIDL fence handle for the given fence object
*
* @param fenceFd [in] Fence file descriptor
* @param handleStorage [in] HIDL handle storage for fence
*
* @return HIDL fence handle
*/
hidl_handle GrallocMapper::getFenceHandle(int fenceFd, char* handleStorage) const
{
native_handle_t* handle = nullptr;
if (fenceFd >= 0)
{
handle = native_handle_init(handleStorage, 1, 0);
handle->data[0] = fenceFd;
}
return hidl_handle(handle);
}
/*
* Locks the given buffer for the specified CPU usage.
*
* @param buffer [in] Buffer to lock
* @param cpuUsage [in] Specifies one or more CPU usage flags to request
* @param accessRegion [in] Portion of the buffer that the client intends to access
* @param acquireFence [in] Handle for aquire fence object
* @param hidl_cb [in] HIDL callback function generating -
* error: NONE upon success. Otherwise,
* BAD_BUFFER for an invalid buffer
* BAD_VALUE for an invalid input parameters
* data: CPU-accessible pointer to the buffer data
*
* @return Void
*/
Return<void> GrallocMapper::lock(void* buffer, uint64_t cpuUsage,
const IMapper::Rect& accessRegion,
const hidl_handle& acquireFence,
lock_cb hidl_cb)
{
buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
if (!bufferHandle)
{
AERR("Buffer to lock: %p has not been registered with Gralloc", buffer);
hidl_cb(Error::BAD_BUFFER, nullptr);
return Void();
}
int fenceFd;
if (!getFenceFd(acquireFence, &fenceFd))
{
hidl_cb(Error::BAD_VALUE, nullptr);
return Void();
}
void* data = nullptr;
const Error error = lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &data);
hidl_cb(error, data);
return Void();
}
/*
* Locks the given buffer for the specified CPU usage and exports cpu accessible
* data in YCbCr structure.
*
* @param buffer [in] Buffer to lock.
* @param cpuUsage [in] Specifies one or more CPU usage flags to request
* @param accessRegion [in] Portion of the buffer that the client intends to access.
* @param acquireFence [in] Handle for aquire fence object
* @param hidl_cb [in] HIDL callback function generating -
* error: NONE upon success. Otherwise,
* BAD_BUFFER for an invalid buffer
* BAD_VALUE for an invalid input parameters
* layout: Data layout of the buffer
*
* @return Void
*/
Return<void> GrallocMapper::lockYCbCr(void* buffer, uint64_t cpuUsage,
const IMapper::Rect& accessRegion,
const hidl_handle& acquireFence,
lockYCbCr_cb hidl_cb)
{
YCbCrLayout layout = {};
buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
if (!bufferHandle)
{
AERR("Buffer to lock(YCbCr): %p has not been registered with Gralloc", buffer);
hidl_cb(Error::BAD_BUFFER, layout);
return Void();
}
int fenceFd;
if (!getFenceFd(acquireFence, &fenceFd))
{
hidl_cb(Error::BAD_VALUE, layout);
return Void();
}
const Error error = lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &layout);
hidl_cb(error, layout);
return Void();
}
/*
* Unlocks a buffer to indicate all CPU accesses to the buffer have completed
*
* @param buffer [in] Buffer to lock.
* @param hidl_cb [in] HIDL callback function generating -
* error: NONE upon success. Otherwise,
* BAD_BUFFER for an invalid buffer
* releaseFence: Referrs to a sync fence object
*
* @return Void
*/
Return<void> GrallocMapper::unlock(void* buffer, unlock_cb hidl_cb)
{
buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
if (!bufferHandle)
{
AERR("Buffer to unlock: %p has not been registered with Gralloc", buffer);
hidl_cb(Error::BAD_BUFFER, nullptr);
return Void();
}
int fenceFd;
const Error error = unlockBuffer(bufferHandle, &fenceFd);
if (error == Error::NONE)
{
NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
hidl_cb(error, getFenceHandle(fenceFd, fenceStorage));
if (fenceFd >= 0)
{
close(fenceFd);
}
}
else
{
hidl_cb(error, nullptr);
}
return Void();
}
/*
* Translates the register buffer API into existing gralloc implementation
*
* @param bufferHandle [in] Private handle for the buffer to be imported
*
* @return Error::BAD_BUFFER for an invalid buffer
* Error::NO_RESOURCES when unable to import the given buffer
* Error::NONE on successful import
*/
Error GrallocMapper::registerBuffer(buffer_handle_t bufferHandle) const
{
if (private_handle_t::validate(bufferHandle) < 0)
{
AERR("Buffer: %p is corrupted", bufferHandle);
return Error::BAD_BUFFER;
}
if (mali_gralloc_reference_retain(&privateModule, bufferHandle) < 0)
{
return Error::NO_RESOURCES;
}
return Error::NONE;
}
/*
* Translates the unregister buffer API into existing gralloc implementation
*
* @param bufferHandle [in] Private handle for the buffer to be released
*
* @return Error::BAD_BUFFER for an invalid buffer / buffers which can't be released
* Error::NONE on successful release of the buffer
*/
Error GrallocMapper::unregisterBuffer(buffer_handle_t bufferHandle) const
{
if (private_handle_t::validate(bufferHandle) < 0)
{
AERR("Buffer: %p is corrupted", bufferHandle);
return Error::BAD_BUFFER;
}
const int status = mali_gralloc_reference_release(&privateModule, bufferHandle, true);
if (status != 0)
{
AERR("Unable to release buffer:%p", bufferHandle);
return Error::BAD_BUFFER;
}
return Error::NONE;
}
/*
* Locks the given buffer for the specified CPU usage.
*
* @param bufferHandle [in] Buffer to lock.
* @param cpuUsage [in] Specifies one or more CPU usage flags to request
* @param accessRegion [in] Portion of the buffer that the client intends to access.
* @param fenceFd [in] Fence file descriptor
* @param outData [out] CPU accessible buffer address
*
* @return Error::BAD_BUFFER for an invalid buffer
* Error::NO_RESOURCES when unable to duplicate fence
* Error::BAD_VALUE when locking fails
* Error::NONE on successful buffer lock
*/
Error GrallocMapper::lockBuffer(buffer_handle_t bufferHandle,
uint64_t cpuUsage,
const IMapper::Rect& accessRegion, int fenceFd,
void** outData) const
{
/* dup fenceFd as it is going to be owned by gralloc. Note that it is
* gralloc's responsibility to close it, even on locking errors.
*/
if (fenceFd >= 0)
{
fenceFd = dup(fenceFd);
if (fenceFd < 0)
{
AERR("Error encountered while duplicating fence file descriptor");
return Error::NO_RESOURCES;
}
}
if (private_handle_t::validate(bufferHandle) < 0)
{
AERR("Buffer: %p is corrupted", bufferHandle);
return Error::BAD_BUFFER;
}
void* data = nullptr;
if (mali_gralloc_lock_async(&privateModule, bufferHandle, cpuUsage,
accessRegion.left, accessRegion.top,
accessRegion.width, accessRegion.height,
&data, fenceFd) < 0)
{
return Error::BAD_VALUE;
}
*outData = data;
return Error::NONE;
}
/*
* Locks the given buffer for the specified CPU usage and exports cpu accessible
* data in YCbCr structure.
*
* @param bufferHandle [in] Buffer to lock.
* @param cpuUsage [in] Specifies one or more CPU usage flags to request
* @param accessRegion [in] Portion of the buffer that the client intends to access.
* @param fenceFd [in] Fence file descriptor
* @param outLayout [out] Describes CPU accessible information in YCbCr format
*
* @return Error::BAD_BUFFER for an invalid buffer
* Error::NO_RESOURCES when unable to duplicate fence
* Error::BAD_VALUE when locking fails
* Error::NONE on successful buffer lock
*/
Error GrallocMapper::lockBuffer(buffer_handle_t bufferHandle,
uint64_t cpuUsage,
const IMapper::Rect& accessRegion, int fenceFd,
YCbCrLayout* outLayout) const
{
int result;
android_ycbcr ycbcr = {};
if (private_handle_t::validate(bufferHandle) < 0)
{
AERR("Buffer: %p is corrupted", bufferHandle);
return Error::BAD_BUFFER;
}
if (fenceFd >= 0)
{
fenceFd = dup(fenceFd);
if (fenceFd < 0)
{
AERR("Error encountered while duplicating fence file descriptor");
return Error::NO_RESOURCES;
}
}
result = mali_gralloc_lock_ycbcr_async(&privateModule, bufferHandle, cpuUsage,
accessRegion.left, accessRegion.top,
accessRegion.width, accessRegion.height,
&ycbcr, fenceFd);
if (result)
{
AERR("Locking(YCbCr) failed with error: %d", result);
return Error::BAD_VALUE;
}
outLayout->y = ycbcr.y;
outLayout->cb = ycbcr.cb;
outLayout->cr = ycbcr.cr;
outLayout->yStride = ycbcr.ystride;
outLayout->cStride = ycbcr.cstride;
outLayout->chromaStep = ycbcr.chroma_step;
return Error::NONE;
}
/*
* Unlocks a buffer to indicate all CPU accesses to the buffer have completed
*
* @param bufferHandle [in] Buffer to lock.
* @param outFenceFd [out] Fence file descriptor
*
* @return Error::BAD_BUFFER for an invalid buffer
* Error::BAD_VALUE when unlocking failed
* Error::NONE on successful buffer unlock
*/
Error GrallocMapper::unlockBuffer(buffer_handle_t bufferHandle,
int* outFenceFd) const
{
if (private_handle_t::validate(bufferHandle) < 0)
{
AERR("Buffer: %p is corrupted", bufferHandle);
return Error::BAD_BUFFER;
}
int fenceFd = -1;
const int result = mali_gralloc_unlock_async(&privateModule, bufferHandle, &fenceFd);
if (result)
{
AERR("Unlocking failed with error: %d", result);
return Error::BAD_VALUE;
}
*outFenceFd = fenceFd;
return Error::NONE;
}
#if HIDL_MAPPER_VERSION_SCALED >= 210
/*
* Validates the buffer against specified descriptor attributes
*
* @param buffer [in] Buffer which needs to be validated.
* @param descriptorInfo [in] Required attributes of the buffer
* @param in_stride [in] Buffer stride returned by IAllocator::allocate
*
* @return Error::NONE upon success. Otherwise,
* Error::BAD_BUFFER upon bad buffer input
* Error::BAD_VALUE when any of the specified attributes are invalid
*/
Return<Error> GrallocMapper::validateBufferSize(void* buffer,
const V2_1::IMapper::BufferDescriptorInfo& descriptorInfo,
uint32_t in_stride)
{
/* The buffer must have been allocated by Gralloc */
buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
if (!bufferHandle)
{
AERR("Buffer: %p has not been registered with Gralloc", buffer);
return Error::BAD_BUFFER;
}
if (private_handle_t::validate(bufferHandle) < 0)
{
AERR("Buffer: %p is corrupted", bufferHandle);
return Error::BAD_BUFFER;
}
/* All Gralloc allocated buffers must be conform to local descriptor validation */
if (!validateDescriptorInfo((void *)&descriptorInfo))
{
AERR("Invalid descriptor attributes for validating buffer size");
return Error::BAD_VALUE;
}
buffer_descriptor_t grallocDescriptor;
grallocDescriptor.width = descriptorInfo.width;
grallocDescriptor.height = descriptorInfo.height;
grallocDescriptor.layer_count = descriptorInfo.layerCount;
grallocDescriptor.hal_format = static_cast<uint64_t>(descriptorInfo.format);
grallocDescriptor.producer_usage = static_cast<uint64_t>(descriptorInfo.usage);
grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage;
grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
/* Derive the buffer size for the given descriptor */
const int result = mali_gralloc_derive_format_and_size(&privateModule,
&grallocDescriptor);
if (result)
{
AERR("Unable to derive format and size for the given descriptor information. error: %d", result);
return Error::BAD_VALUE;
}
/* Validate the buffer parameters against descriptor info */
private_handle_t *gralloc_buffer = (private_handle_t *)bufferHandle;
/* The buffer size must be greater than (or equal to) what would have been allocated with descriptor */
if ((size_t)gralloc_buffer->size < grallocDescriptor.size)
{
ALOGW("Buf size mismatch. Buffer size = %u, Descriptor (derived) size = %zu",
gralloc_buffer->size, grallocDescriptor.size);
return Error::BAD_VALUE;
}
if ((uint32_t)gralloc_buffer->stride != in_stride)
{
AERR("Stride mismatch. Expected stride = %d, Buffer stride = %d",
in_stride, gralloc_buffer->stride);
return Error::BAD_VALUE;
}
if (gralloc_buffer->internal_format != grallocDescriptor.internal_format)
{
AERR("Buffer format :0x%" PRIx64" does not match descriptor (derived) format :0x%"
PRIx64, gralloc_buffer->internal_format, grallocDescriptor.internal_format);
return Error::BAD_VALUE;
}
if ((uint32_t)gralloc_buffer->width != grallocDescriptor.width)
{
AERR("Width mismatch. Buffer width = %u, Descriptor width = %u",
gralloc_buffer->width, grallocDescriptor.width);
return Error::BAD_VALUE;
}
if ((uint32_t)gralloc_buffer->height != grallocDescriptor.height)
{
AERR("Height mismatch. Buffer height = %u, Descriptor height = %u",
gralloc_buffer->height, grallocDescriptor.height);
return Error::BAD_VALUE;
}
if (gralloc_buffer->layer_count != grallocDescriptor.layer_count)
{
AERR("Layer Count mismatch. Buffer layer_count = %u, Descriptor layer_count width = %u",
gralloc_buffer->layer_count, grallocDescriptor.layer_count);
return Error::BAD_VALUE;
}
return Error::NONE;
}
/*
* Get the transport size of a buffer
*
* @param buffer [in] Buffer for computing transport size
* @param hidl_cb [in] HIDL callback function generating -
* error: NONE upon success. Otherwise,
* BAD_BUFFER for an invalid buffer
* numFds: Number of file descriptors needed for transport
* numInts: Number of integers needed for transport
*
* @return Void
*/
Return<void> GrallocMapper::getTransportSize(void* buffer, getTransportSize_cb hidl_cb)
{
/* The buffer must have been allocated by Gralloc */
buffer_handle_t bufferHandle = gRegisteredHandles->get(buffer);
if (!bufferHandle)
{
AERR("Buffer %p is not registered with Gralloc", bufferHandle);
hidl_cb(Error::BAD_BUFFER, -1, -1);
return Void();
}
if (private_handle_t::validate(bufferHandle) < 0)
{
AERR("Buffer %p is corrupted", buffer);
hidl_cb(Error::BAD_BUFFER, -1, -1);
return Void();
}
hidl_cb(Error::NONE, GRALLOC_ARM_NUM_FDS, NUM_INTS_IN_PRIVATE_HANDLE);
return Void();
}
/*
* Creates a buffer descriptor from incoming descriptor attributes
*
* @param descriptorInfo [in] Specifies the (2.1 IMapper) attributes of
* the descriptor.
* @param hidl_cb [in] HIDL callback function generating -
* error: NONE upon success. Otherwise,
* BAD_VALUE when any of the specified attributes are invalid
* descriptor: Newly created buffer descriptor.
*
* @return Void
*/
Return<void> GrallocMapper::createDescriptor_2_1(const V2_1::IMapper::BufferDescriptorInfo& descriptorInfo,
createDescriptor_2_1_cb hidl_cb)
{
if (validateDescriptorInfo((void *)&descriptorInfo))
{
hidl_cb(Error::NONE, grallocEncodeBufferDescriptor(descriptorInfo));
}
else
{
AERR("Invalid (IMapper 2.1) attributes to create descriptor");
hidl_cb(Error::BAD_VALUE, V2_0::BufferDescriptor());
}
return Void();
}
#endif /* HIDL_MAPPER_VERSION_SCALED >= 210 */
IMapper* HIDL_FETCH_IMapper(const char* /* name */)
{
ALOGV("Arm Module IMapper %d.%d , pid = %d ppid = %d ", GRALLOC_VERSION_MAJOR,
(HIDL_MAPPER_VERSION_SCALED - (GRALLOC_VERSION_MAJOR * 100)) / 10, getpid(), getppid());
return new GrallocMapper();
}
} // namespace implementation
} // namespace HIDL_IMAPPER_NAMESPACE
} // namespace mapper
} // namespace graphics
} // namespace hardware
} // namespace android