Commit 1de497cc by Jason Macnak

Support Gralloc3 in SwiftShader

Also moves the -DHAVE_GRALLOC cflags away from the host build as hosts do not have gralloc and mapper 3 does not have a header only library available. Bug: b/157902551 Test: launch_cvd w/ Cuttlefish ashmem Gralloc0 Test: launch_cvd w/ Cuttlefish minigbm Gralloc3 Change-Id: I99da611a2b72f9d39df32ab9883dc52f2c081217 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/46408 Presubmit-Ready: Jason Macnak <natsu@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Tested-by: 's avatarJason Macnak <natsu@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 100707a3
......@@ -26,7 +26,6 @@ cc_defaults {
"-D__STDC_LIMIT_MACROS",
"-D__STDC_CONSTANT_MACROS",
"-D__STDC_FORMAT_MACROS",
"-DHAVE_GRALLOC1",
"-DNO_SANITIZE_FUNCTION=",
// FIXME: Use <android/api-level.h> instead?
"-DANDROID_PLATFORM_SDK_VERSION=10000",
......@@ -44,17 +43,24 @@ cc_defaults {
target: {
android: {
cflags: [
"-DHAVE_GRALLOC1",
"-DHAVE_GRALLOC3",
],
relative_install_path: "egl",
header_libs: [
"swiftshader_platform_headers",
"libnativebase_headers",
],
shared_libs: [
"android.hardware.graphics.mapper@3.0",
"libnativewindow",
"libhardware",
"libhidlbase",
"libcutils",
"libsync",
"liblog",
"libutils",
],
static_libs: [
"libarect",
......@@ -539,6 +545,7 @@ cc_defaults {
"-D__STDC_CONSTANT_MACROS",
"-D__STDC_FORMAT_MACROS",
"-DHAVE_GRALLOC1",
"-DHAVE_GRALLOC3",
"-DNO_SANITIZE_FUNCTION=",
// FIXME: Use <android/api-level.h> instead?
"-DANDROID_PLATFORM_SDK_VERSION=10000",
......@@ -576,11 +583,14 @@ cc_defaults {
"hwvulkan_headers",
],
shared_libs: [
"android.hardware.graphics.mapper@3.0",
"libnativewindow",
"libhardware",
"libhidlbase",
"libcutils",
"libsync",
"liblog",
"libutils",
],
static_libs: [
"libarect",
......
......@@ -16,7 +16,12 @@
#include "Debug.hpp"
#ifdef HAVE_GRALLOC1
#include <sync/sync.h>
# include <sync/sync.h>
#endif
#ifdef HAVE_GRALLOC3
using V3Error = android::hardware::graphics::mapper::V3_0::Error;
using V3Mapper = android::hardware::graphics::mapper::V3_0::IMapper;
using android::hardware::hidl_handle;
#endif
GrallocModule *GrallocModule::getInstance()
......@@ -27,37 +32,109 @@ GrallocModule *GrallocModule::getInstance()
GrallocModule::GrallocModule()
{
#ifdef HAVE_GRALLOC3
m_gralloc3_mapper = V3Mapper::getService();
if(m_gralloc3_mapper != nullptr)
{
return;
}
#endif
const hw_module_t *module = nullptr;
hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
m_major_version = (module->module_api_version >> 8) & 0xff;
switch(m_major_version)
{
case 0:
m_module = reinterpret_cast<const gralloc_module_t*>(module);
break;
case 1:
case 0:
m_module = reinterpret_cast<const gralloc_module_t *>(module);
break;
case 1:
#ifdef HAVE_GRALLOC1
gralloc1_open(module, &m_gralloc1_device);
m_gralloc1_lock = (GRALLOC1_PFN_LOCK) m_gralloc1_device->getFunction(m_gralloc1_device, GRALLOC1_FUNCTION_LOCK);
m_gralloc1_unlock = (GRALLOC1_PFN_UNLOCK)m_gralloc1_device->getFunction(m_gralloc1_device, GRALLOC1_FUNCTION_UNLOCK);
break;
gralloc1_open(module, &m_gralloc1_device);
m_gralloc1_lock = (GRALLOC1_PFN_LOCK)m_gralloc1_device->getFunction(m_gralloc1_device, GRALLOC1_FUNCTION_LOCK);
m_gralloc1_unlock = (GRALLOC1_PFN_UNLOCK)m_gralloc1_device->getFunction(m_gralloc1_device, GRALLOC1_FUNCTION_UNLOCK);
break;
#endif
default:
TRACE("unknown gralloc major version (%d)", m_major_version);
break;
default:
TRACE("unknown gralloc major version (%d)", m_major_version);
break;
}
}
int GrallocModule::import(buffer_handle_t handle, buffer_handle_t *imported_handle)
{
#ifdef HAVE_GRALLOC3
if(m_gralloc3_mapper != nullptr)
{
V3Error error;
auto ret = m_gralloc3_mapper->importBuffer(handle,
[&](const auto &tmp_err, const auto &tmp_buf) {
error = tmp_err;
if(error == V3Error::NONE)
{
*imported_handle = static_cast<buffer_handle_t>(tmp_buf);
}
});
return ret.isOk() && error == V3Error::NONE ? 0 : -1;
}
#endif
*imported_handle = handle;
return 0;
}
int GrallocModule::release(buffer_handle_t handle)
{
#ifdef HAVE_GRALLOC3
if(m_gralloc3_mapper != nullptr)
{
native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
return m_gralloc3_mapper->freeBuffer(native_handle).isOk() ? 0 : 1;
}
#endif
return 0;
}
int GrallocModule::lock(buffer_handle_t handle, int usage, int left, int top, int width, int height, void **vaddr)
{
#ifdef HAVE_GRALLOC3
if(m_gralloc3_mapper != nullptr)
{
native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
V3Mapper::Rect rect;
rect.left = left;
rect.top = top;
rect.width = width;
rect.height = height;
hidl_handle empty_fence_handle;
V3Error error;
auto ret = m_gralloc3_mapper->lock(native_handle, usage, rect, empty_fence_handle,
[&](const auto &tmp_err,
const auto &tmp_vaddr,
const auto & /*bytes_per_pixel*/,
const auto & /*bytes_per_stride*/) {
error = tmp_err;
if(tmp_err == V3Error::NONE)
{
*vaddr = tmp_vaddr;
}
});
return ret.isOk() && error == V3Error::NONE ? 0 : -1;
}
#endif
switch(m_major_version)
{
case 0:
case 0:
{
return m_module->lock(m_module, handle, usage, left, top, width, height, vaddr);
}
case 1:
case 1:
#ifdef HAVE_GRALLOC1
{
gralloc1_rect_t outRect{};
......@@ -68,7 +145,7 @@ int GrallocModule::lock(buffer_handle_t handle, int usage, int left, int top, in
return m_gralloc1_lock(m_gralloc1_device, handle, usage, usage, &outRect, vaddr, -1);
}
#endif
default:
default:
{
TRACE("no gralloc module to lock");
return -1;
......@@ -78,18 +155,32 @@ int GrallocModule::lock(buffer_handle_t handle, int usage, int left, int top, in
int GrallocModule::unlock(buffer_handle_t handle)
{
#ifdef HAVE_GRALLOC3
if(m_gralloc3_mapper != nullptr)
{
native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
V3Error error;
auto ret = m_gralloc3_mapper->unlock(native_handle,
[&](const auto &tmp_err, const auto &) {
error = tmp_err;
});
return ret.isOk() && error == V3Error::NONE ? 0 : -1;
}
#endif
switch(m_major_version)
{
case 0:
case 0:
{
return m_module->unlock(m_module, handle);
}
case 1:
case 1:
#ifdef HAVE_GRALLOC1
{
int32_t fenceFd = -1;
int error = m_gralloc1_unlock(m_gralloc1_device, handle, &fenceFd);
if (!error)
if(!error)
{
sync_wait(fenceFd, -1);
close(fenceFd);
......@@ -97,7 +188,7 @@ int GrallocModule::unlock(buffer_handle_t handle)
return error;
}
#endif
default:
default:
{
TRACE("no gralloc module to unlock");
return -1;
......
......@@ -16,17 +16,22 @@
#define GRALLOC_ANDROID
#include <hardware/gralloc.h>
#ifdef HAVE_GRALLOC1
#include <hardware/gralloc1.h>
#ifdef HAVE_GRALLOC3
# include <android/hardware/graphics/mapper/3.0/IMapper.h>
# include <utils/StrongPointer.h>
#endif
#include <unistd.h> // for close()
#include <unistd.h> // for close()
class GrallocModule
{
public:
static GrallocModule *getInstance();
int import(buffer_handle_t handle, buffer_handle_t *imported_handle);
int release(buffer_handle_t handle);
int lock(buffer_handle_t handle, int usage, int left, int top, int width, int height, void **vaddr);
int unlock(buffer_handle_t handle);
......@@ -39,6 +44,9 @@ private:
GRALLOC1_PFN_LOCK m_gralloc1_lock = nullptr;
GRALLOC1_PFN_UNLOCK m_gralloc1_unlock = nullptr;
#endif
#ifdef HAVE_GRALLOC3
android::sp<android::hardware::graphics::mapper::V3_0::IMapper> m_gralloc3_mapper;
#endif
};
#endif // GRALLOC_ANDROID
......@@ -54,7 +54,7 @@ namespace sw
FrameBufferAndroid::FrameBufferAndroid(ANativeWindow* window, int width, int height)
: FrameBuffer(width, height, false, false),
nativeWindow(window), buffer(nullptr)
nativeWindow(window), buffer(nullptr)
{
#ifndef ANDROID_NDK_BUILD
nativeWindow->common.incRef(&nativeWindow->common);
......@@ -101,7 +101,7 @@ namespace sw
if((surfaceBuffer.width < width) || (surfaceBuffer.height < height))
{
TRACE("lock failed: buffer of %dx%d too small for window of %dx%d",
surfaceBuffer.width, surfaceBuffer.height, width, height);
surfaceBuffer.width, surfaceBuffer.height, width, height);
return nullptr;
}
......@@ -126,9 +126,14 @@ namespace sw
{
return nullptr;
}
if(GrallocModule::getInstance()->lock(buffer->handle,
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
0, 0, buffer->width, buffer->height, &framebuffer) != 0)
if(GrallocModule::getInstance()->import(buffer->handle, &bufferImportedHandle) != 0) {
TRACE("%s failed to import buffer %p", __FUNCTION__, buffer);
return nullptr;
}
if(GrallocModule::getInstance()->lock(bufferImportedHandle,
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
0, 0, buffer->width, buffer->height, &framebuffer) != 0)
{
TRACE("%s failed to lock buffer %p", __FUNCTION__, buffer);
return nullptr;
......@@ -137,7 +142,7 @@ namespace sw
if((buffer->width < width) || (buffer->height < height))
{
TRACE("lock failed: buffer of %dx%d too small for window of %dx%d",
buffer->width, buffer->height, width, height);
buffer->width, buffer->height, width, height);
return nullptr;
}
......@@ -179,10 +184,13 @@ namespace sw
#ifdef ANDROID_NDK_BUILD
ANativeWindow_unlockAndPost(nativeWindow);
#else
if(GrallocModule::getInstance()->unlock(buffer->handle) != 0)
if(GrallocModule::getInstance()->unlock(bufferImportedHandle) != 0)
{
TRACE("%s: badness unlock failed", __FUNCTION__);
}
if(GrallocModule::getInstance()->release(bufferImportedHandle) != 0) {
TRACE("%s: badness release failed", __FUNCTION__);
}
#endif
}
}
......
......@@ -15,6 +15,8 @@
#ifndef sw_FrameBufferAndroid_hpp
#define sw_FrameBufferAndroid_hpp
#include <cutils/native_handle.h>
#include "Main/FrameBuffer.hpp"
#include "Common/Debug.hpp"
......@@ -41,6 +43,7 @@ namespace sw
private:
ANativeWindow *nativeWindow;
ANativeWindowBuffer *buffer;
buffer_handle_t bufferImportedHandle;
};
}
......
......@@ -273,15 +273,20 @@ public:
nativeBuffer(nativeBuffer)
{
nativeBuffer->common.incRef(&nativeBuffer->common);
GrallocModule::getInstance()->import(nativeBuffer->handle, &nativeBufferImportedHandle);
}
private:
ANativeWindowBuffer *nativeBuffer;
buffer_handle_t nativeBufferImportedHandle;
~AndroidNativeImage() override
{
sync(); // Wait for any threads that use this image to finish.
GrallocModule::getInstance()->release(nativeBufferImportedHandle);
nativeBuffer->common.decRef(&nativeBuffer->common);
}
......@@ -340,14 +345,14 @@ private:
void *lockNativeBuffer(int usage)
{
void *buffer = nullptr;
GrallocModule::getInstance()->lock(nativeBuffer->handle, usage, 0, 0, nativeBuffer->width, nativeBuffer->height, &buffer);
GrallocModule::getInstance()->lock(nativeBufferImportedHandle, usage, 0, 0, nativeBuffer->width, nativeBuffer->height, &buffer);
return buffer;
}
void unlockNativeBuffer()
{
GrallocModule::getInstance()->unlock(nativeBuffer->handle);
GrallocModule::getInstance()->unlock(nativeBufferImportedHandle);
}
void release() override
......
......@@ -18,6 +18,11 @@
#ifdef HAVE_GRALLOC1
# include <sync/sync.h>
#endif
#ifdef HAVE_GRALLOC3
using V3Error = android::hardware::graphics::mapper::V3_0::Error;
using V3Mapper = android::hardware::graphics::mapper::V3_0::IMapper;
using android::hardware::hidl_handle;
#endif
GrallocModule *GrallocModule::getInstance()
{
......@@ -27,6 +32,14 @@ GrallocModule *GrallocModule::getInstance()
GrallocModule::GrallocModule()
{
#ifdef HAVE_GRALLOC3
m_gralloc3_mapper = V3Mapper::getService();
if(m_gralloc3_mapper != nullptr)
{
return;
}
#endif
const hw_module_t *module = nullptr;
hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
......@@ -49,8 +62,72 @@ GrallocModule::GrallocModule()
}
}
int GrallocModule::import(buffer_handle_t handle, buffer_handle_t *imported_handle)
{
#ifdef HAVE_GRALLOC3
if(m_gralloc3_mapper != nullptr)
{
V3Error error;
auto ret = m_gralloc3_mapper->importBuffer(handle,
[&](const auto &tmp_err, const auto &tmp_buf) {
error = tmp_err;
if(error == V3Error::NONE)
{
*imported_handle = static_cast<buffer_handle_t>(tmp_buf);
}
});
return ret.isOk() && error == V3Error::NONE ? 0 : -1;
}
#endif
*imported_handle = handle;
return 0;
}
int GrallocModule::release(buffer_handle_t handle)
{
#ifdef HAVE_GRALLOC3
if(m_gralloc3_mapper != nullptr)
{
native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
return m_gralloc3_mapper->freeBuffer(native_handle).isOk() ? 0 : 1;
}
#endif
return 0;
}
int GrallocModule::lock(buffer_handle_t handle, int usage, int left, int top, int width, int height, void **vaddr)
{
#ifdef HAVE_GRALLOC3
if(m_gralloc3_mapper != nullptr)
{
native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
V3Mapper::Rect rect;
rect.left = left;
rect.top = top;
rect.width = width;
rect.height = height;
hidl_handle empty_fence_handle;
V3Error error;
auto ret = m_gralloc3_mapper->lock(native_handle, usage, rect, empty_fence_handle,
[&](const auto &tmp_err,
const auto &tmp_vaddr,
const auto & /*bytes_per_pixel*/,
const auto & /*bytes_per_stride*/) {
error = tmp_err;
if(tmp_err == V3Error::NONE)
{
*vaddr = tmp_vaddr;
}
});
return ret.isOk() && error == V3Error::NONE ? 0 : -1;
}
#endif
switch(m_major_version)
{
case 0:
......@@ -78,6 +155,20 @@ int GrallocModule::lock(buffer_handle_t handle, int usage, int left, int top, in
int GrallocModule::unlock(buffer_handle_t handle)
{
#ifdef HAVE_GRALLOC3
if(m_gralloc3_mapper != nullptr)
{
native_handle_t *native_handle = const_cast<native_handle_t *>(handle);
V3Error error;
auto ret = m_gralloc3_mapper->unlock(native_handle,
[&](const auto &tmp_err, const auto &) {
error = tmp_err;
});
return ret.isOk() && error == V3Error::NONE ? 0 : -1;
}
#endif
switch(m_major_version)
{
case 0:
......
......@@ -16,9 +16,10 @@
#define GRALLOC_ANDROID
#include <hardware/gralloc.h>
#ifdef HAVE_GRALLOC1
# include <hardware/gralloc1.h>
#include <hardware/gralloc1.h>
#ifdef HAVE_GRALLOC3
# include <android/hardware/graphics/mapper/3.0/IMapper.h>
# include <utils/StrongPointer.h>
#endif
#include <unistd.h> // for close()
......@@ -27,6 +28,10 @@ class GrallocModule
{
public:
static GrallocModule *getInstance();
int import(buffer_handle_t handle, buffer_handle_t *imported_handle);
int release(buffer_handle_t handle);
int lock(buffer_handle_t handle, int usage, int left, int top, int width, int height, void **vaddr);
int unlock(buffer_handle_t handle);
......@@ -39,6 +44,9 @@ private:
GRALLOC1_PFN_LOCK m_gralloc1_lock = nullptr;
GRALLOC1_PFN_UNLOCK m_gralloc1_unlock = nullptr;
#endif
#ifdef HAVE_GRALLOC3
android::sp<android::hardware::graphics::mapper::V3_0::IMapper> m_gralloc3_mapper;
#endif
};
#endif // GRALLOC_ANDROID
......@@ -236,7 +236,17 @@ VkResult Image::prepareForExternalUseANDROID() const
void *nativeBuffer = nullptr;
VkExtent3D extent = getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
if(GrallocModule::getInstance()->lock(backingMemory.nativeHandle, GRALLOC_USAGE_SW_WRITE_OFTEN, 0, 0, extent.width, extent.height, &nativeBuffer) != 0)
buffer_handle_t importedBufferHandle = nullptr;
if(GrallocModule::getInstance()->import(backingMemory.nativeHandle, &importedBufferHandle) != 0)
{
return VK_ERROR_OUT_OF_DATE_KHR;
}
if(!importedBufferHandle)
{
return VK_ERROR_OUT_OF_DATE_KHR;
}
if(GrallocModule::getInstance()->lock(importedBufferHandle, GRALLOC_USAGE_SW_WRITE_OFTEN, 0, 0, extent.width, extent.height, &nativeBuffer) != 0)
{
return VK_ERROR_OUT_OF_DATE_KHR;
}
......@@ -257,7 +267,12 @@ VkResult Image::prepareForExternalUseANDROID() const
memcpy(dstBuffer + (i * bufferRowBytes), srcBuffer + (i * imageRowBytes), imageRowBytes);
}
if(GrallocModule::getInstance()->unlock(backingMemory.nativeHandle) != 0)
if(GrallocModule::getInstance()->unlock(importedBufferHandle) != 0)
{
return VK_ERROR_OUT_OF_DATE_KHR;
}
if(GrallocModule::getInstance()->release(importedBufferHandle) != 0)
{
return VK_ERROR_OUT_OF_DATE_KHR;
}
......
......@@ -64,6 +64,7 @@
# include "commit.h"
# include "System/GrallocAndroid.hpp"
# include <android/log.h>
# include <hardware/gralloc1.h>
# include <sync/sync.h>
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment