blob: f6a26ac80eb5c4d027924fb4a0528bc72769340b [file] [log] [blame]
/*
* Copyright (C) 2017 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 <VtsHalHidlTargetTestBase.h>
#include "VtsHalGraphicsMapperTestUtils.h"
namespace android {
namespace hardware {
namespace graphics {
namespace mapper {
namespace V2_0 {
namespace tests {
using android::hardware::graphics::allocator::V2_0::Buffer;
using android::hardware::graphics::allocator::V2_0::BufferDescriptor;
using android::hardware::graphics::allocator::V2_0::Error;
Mapper::Mapper() { init(); }
void Mapper::init() {
mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>();
ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
}
Mapper::~Mapper() {
for (auto it : mHandles) {
while (it.second) {
EXPECT_EQ(Error::NONE, mMapper->release(it.first))
<< "failed to release handle " << it.first;
it.second--;
}
}
mHandles.clear();
}
sp<IMapper> Mapper::getRaw() const { return mMapper; }
void Mapper::retain(const native_handle_t* handle) {
Error error = mMapper->retain(handle);
ASSERT_EQ(Error::NONE, error) << "failed to retain handle " << handle;
mHandles[handle]++;
}
void Mapper::release(const native_handle_t* handle) {
Error error = mMapper->release(handle);
ASSERT_EQ(Error::NONE, error) << "failed to release handle " << handle;
if (--mHandles[handle] == 0) {
mHandles.erase(handle);
}
}
Mapper::Dimensions Mapper::getDimensions(const native_handle_t* handle) {
Dimensions dimensions = {};
mMapper->getDimensions(handle, [&](const auto& tmpError, const auto& tmpWidth,
const auto& tmpHeight) {
ASSERT_EQ(Error::NONE, tmpError)
<< "failed to get dimensions for handle " << handle;
dimensions.width = tmpWidth;
dimensions.height = tmpHeight;
});
return dimensions;
}
PixelFormat Mapper::getFormat(const native_handle_t* handle) {
PixelFormat format = static_cast<PixelFormat>(0);
mMapper->getFormat(handle, [&](const auto& tmpError, const auto& tmpFormat) {
ASSERT_EQ(Error::NONE, tmpError)
<< "failed to get format for handle " << handle;
format = tmpFormat;
});
return format;
}
uint32_t Mapper::getLayerCount(const native_handle_t* handle) {
uint32_t count = 0;
mMapper->getLayerCount(
handle, [&](const auto& tmpError, const auto& tmpCount) {
ASSERT_EQ(Error::NONE, tmpError)
<< "failed to get layer count for handle " << handle;
count = tmpCount;
});
return count;
}
uint64_t Mapper::getProducerUsageMask(const native_handle_t* handle) {
uint64_t usageMask = 0;
mMapper->getProducerUsageMask(
handle, [&](const auto& tmpError, const auto& tmpUsageMask) {
ASSERT_EQ(Error::NONE, tmpError)
<< "failed to get producer usage mask for handle " << handle;
usageMask = tmpUsageMask;
});
return usageMask;
}
uint64_t Mapper::getConsumerUsageMask(const native_handle_t* handle) {
uint64_t usageMask = 0;
mMapper->getConsumerUsageMask(
handle, [&](const auto& tmpError, const auto& tmpUsageMask) {
ASSERT_EQ(Error::NONE, tmpError)
<< "failed to get consumer usage mask for handle " << handle;
usageMask = tmpUsageMask;
});
return usageMask;
}
BackingStore Mapper::getBackingStore(const native_handle_t* handle) {
BackingStore backingStore = 0;
mMapper->getBackingStore(
handle, [&](const auto& tmpError, const auto& tmpBackingStore) {
ASSERT_EQ(Error::NONE, tmpError)
<< "failed to get backing store for handle " << handle;
backingStore = tmpBackingStore;
});
return backingStore;
}
uint32_t Mapper::getStride(const native_handle_t* handle) {
uint32_t stride = 0;
mMapper->getStride(handle, [&](const auto& tmpError, const auto& tmpStride) {
ASSERT_EQ(Error::NONE, tmpError)
<< "failed to get stride for handle " << handle;
stride = tmpStride;
});
return stride;
}
void* Mapper::lock(const native_handle_t* handle, uint64_t producerUsageMask,
uint64_t consumerUsageMask,
const IMapper::Rect& accessRegion, int acquireFence) {
NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 0, 1);
native_handle_t* acquireFenceHandle = nullptr;
if (acquireFence >= 0) {
acquireFenceHandle = native_handle_init(acquireFenceStorage, 0, 1);
acquireFenceHandle->data[0] = acquireFence;
}
void* data = nullptr;
mMapper->lock(
handle, producerUsageMask, consumerUsageMask, accessRegion,
acquireFenceHandle, [&](const auto& tmpError, const auto& tmpData) {
ASSERT_EQ(Error::NONE, tmpError) << "failed to lock handle " << handle;
data = tmpData;
});
if (acquireFence >= 0) {
close(acquireFence);
}
return data;
}
FlexLayout Mapper::lockFlex(const native_handle_t* handle,
uint64_t producerUsageMask,
uint64_t consumerUsageMask,
const IMapper::Rect& accessRegion,
int acquireFence) {
NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 0, 1);
native_handle_t* acquireFenceHandle = nullptr;
if (acquireFence >= 0) {
acquireFenceHandle = native_handle_init(acquireFenceStorage, 0, 1);
acquireFenceHandle->data[0] = acquireFence;
}
FlexLayout layout = {};
mMapper->lockFlex(handle, producerUsageMask, consumerUsageMask, accessRegion,
acquireFenceHandle,
[&](const auto& tmpError, const auto& tmpLayout) {
ASSERT_EQ(Error::NONE, tmpError)
<< "failed to lockFlex handle " << handle;
layout = tmpLayout;
});
if (acquireFence >= 0) {
close(acquireFence);
}
return layout;
}
int Mapper::unlock(const native_handle_t* handle) {
int releaseFence = -1;
mMapper->unlock(handle, [&](const auto& tmpError,
const auto& tmpReleaseFence) {
ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock handle " << handle;
auto handle = tmpReleaseFence.getNativeHandle();
if (handle) {
ASSERT_EQ(0, handle->numInts) << "invalid fence handle " << handle;
if (handle->numFds == 1) {
releaseFence = dup(handle->data[0]);
ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
} else {
ASSERT_EQ(0, handle->numFds) << " invalid fence handle " << handle;
}
}
});
return releaseFence;
}
const native_handle_t* Mapper::allocate(
std::unique_ptr<AllocatorClient>& allocatorClient,
const IAllocatorClient::BufferDescriptorInfo& info) {
BufferDescriptor descriptor = allocatorClient->createDescriptor(info);
if (::testing::Test::HasFatalFailure()) {
return nullptr;
}
Buffer buffer = allocatorClient->allocate(descriptor);
if (::testing::Test::HasFatalFailure()) {
allocatorClient->destroyDescriptor(descriptor);
return nullptr;
}
const native_handle_t* handle =
allocatorClient->exportHandle(descriptor, buffer);
if (handle) {
retain(handle);
}
allocatorClient->free(buffer);
allocatorClient->destroyDescriptor(descriptor);
return handle;
}
} // namespace tests
} // namespace V2_0
} // namespace mapper
} // namespace graphics
} // namespace hardware
} // namespace android