diff options
45 files changed, 1236 insertions, 927 deletions
diff --git a/common/end2end/Android.bp b/common/end2end/Android.bp index b802ad67..50ce8512 100644 --- a/common/end2end/Android.bp +++ b/common/end2end/Android.bp @@ -23,14 +23,18 @@ cc_test_host { "libGLESv2_emulation_with_host", "libEGL_emulation_with_host", "libgfxstream_guest_vulkan_with_host", + "libplatform_rutabaga_server", ], shared_libs: [ + "libandroidemu", + "libOpenglCodecCommon", + "libOpenglSystemCommonWithHost", "libbase", + "libcutils", "libdrm", "liblog", "libgfxstream_backend", - "libplatform_rutabaga", - "libOpenglSystemCommonWithHost", + "libplatform_rutabaga_server", ], static_libs: [ "gfxstream_base", @@ -38,8 +42,10 @@ cc_test_host { "gfxstream_snapshot", "gfxstream_vulkan_cereal_host", "libc++fs", + "libgfxstream_guest_android_with_host", "libgmock", "liblz4", + "libplatform_rutabaga", ], cflags: [ // TODO: remove diff --git a/common/end2end/GfxstreamEnd2EndGlTests.cpp b/common/end2end/GfxstreamEnd2EndGlTests.cpp index d3dedfc2..6b6934ff 100644 --- a/common/end2end/GfxstreamEnd2EndGlTests.cpp +++ b/common/end2end/GfxstreamEnd2EndGlTests.cpp @@ -88,10 +88,9 @@ TEST_P(GfxstreamEnd2EndGlTest, CreateWindowSurface) { constexpr const int width = 32; constexpr const int height = 32; - auto anw = CreateEmulatedANW(width, height); - auto anwEgl = anw->asEglNativeWindowType(); + auto anw = mAnwHelper->createNativeWindowForTesting(mGralloc.get(), width, height); - EGLSurface surface = mGl->eglCreateWindowSurface(display, config, anwEgl, nullptr); + EGLSurface surface = mGl->eglCreateWindowSurface(display, config, anw, nullptr); ASSERT_THAT(surface, Not(Eq(EGL_NO_SURFACE))); ASSERT_THAT(mGl->eglMakeCurrent(display, surface, surface, context), IsTrue()); @@ -108,7 +107,7 @@ TEST_P(GfxstreamEnd2EndGlTest, CreateWindowSurface) { ASSERT_THAT(mGl->eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT), IsTrue()); ASSERT_THAT(mGl->eglDestroyContext(display, context), IsTrue()); ASSERT_THAT(mGl->eglDestroySurface(display, surface), IsTrue()); - anw.reset(); + mAnwHelper->release(anw); TearDownGuest(); } diff --git a/common/end2end/GfxstreamEnd2EndTests.cpp b/common/end2end/GfxstreamEnd2EndTests.cpp index 5baa9da4..4c09ec90 100644 --- a/common/end2end/GfxstreamEnd2EndTests.cpp +++ b/common/end2end/GfxstreamEnd2EndTests.cpp @@ -22,7 +22,6 @@ #include <filesystem> -#include "Gralloc.h" #include "ProcessPipe.h" #include "aemu/base/files/StdioStream.h" #include "aemu/base/system/System.h" @@ -42,6 +41,7 @@ namespace tests { using testing::AnyOf; using testing::Eq; using testing::Gt; +using testing::IsFalse; using testing::IsTrue; using testing::Not; using testing::NotNull; @@ -177,13 +177,9 @@ void GfxstreamEnd2EndTest::SetUp() { ASSERT_THAT(mVk, NotNull()); } - mAnwHelper = std::make_unique<TestingVirtGpuANativeWindowHelper>(); - HostConnection::get()->setANativeWindowHelperForTesting(mAnwHelper.get()); - - mGralloc = std::make_unique<TestingVirtGpuGralloc>(); - HostConnection::get()->setGrallocHelperForTesting(mGralloc.get()); - - mSync = HostConnection::get()->syncHelper(); + mAnwHelper.reset(createPlatformANativeWindowHelper()); + mGralloc.reset(createPlatformGralloc()); + mSync.reset(createPlatformSyncHelper()); } void GfxstreamEnd2EndTest::TearDownGuest() { @@ -198,10 +194,10 @@ void GfxstreamEnd2EndTest::TearDownGuest() { } mVk.reset(); - mGralloc.reset(); mAnwHelper.reset(); + mGralloc.reset(); + mSync.reset(); - HostConnection::exit(); processPipeRestart(); // Figure out more reliable way for guest shutdown to complete... @@ -209,7 +205,15 @@ void GfxstreamEnd2EndTest::TearDownGuest() { } void GfxstreamEnd2EndTest::TearDownHost() { - ResetEmulatedVirtioGpu(); + const uint32_t users = GetNumActiveEmulatedVirtioGpuUsers(); + if (users != 0) { + ALOGE("The EmulationVirtioGpu was found to still be active by %" PRIu32 + " after the " + "end of the test. Please ensure you have fully destroyed all objects created " + "during the test (Gralloc allocations, ANW allocations, etc).", + users); + abort(); + } } void GfxstreamEnd2EndTest::TearDown() { @@ -217,16 +221,6 @@ void GfxstreamEnd2EndTest::TearDown() { TearDownHost(); } -std::unique_ptr<TestingANativeWindow> GfxstreamEnd2EndTest::CreateEmulatedANW( - uint32_t width, - uint32_t height) { - std::vector<std::unique_ptr<TestingAHardwareBuffer>> buffers; - for (int i = 0; i < 3; i++) { - buffers.push_back(mGralloc->allocate(width, height, DRM_FORMAT_ABGR8888)); - } - return std::make_unique<TestingANativeWindow>(width, height, DRM_FORMAT_ABGR8888, std::move(buffers)); -} - void GfxstreamEnd2EndTest::SetUpEglContextAndSurface( uint32_t contextVersion, uint32_t width, diff --git a/common/end2end/GfxstreamEnd2EndTests.h b/common/end2end/GfxstreamEnd2EndTests.h index 8e3151b9..34fd7285 100644 --- a/common/end2end/GfxstreamEnd2EndTests.h +++ b/common/end2end/GfxstreamEnd2EndTests.h @@ -12,16 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include <future> +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +#include <android-base/expected.h> #include <inttypes.h> + +#include <future> #include <memory> #include <string> #include <thread> #include <variant> -#include <gmock/gmock.h> -#include <gtest/gtest.h> - // clang-format off #include <EGL/egl.h> #include <EGL/eglext.h> @@ -37,13 +39,11 @@ #define VULKAN_HPP_NO_EXCEPTIONS #include <vulkan/vulkan.hpp> #include <vulkan/vk_android_native_buffer.h> - // clang-format on -#include <android-base/expected.h> - -#include "HostConnection.h" -#include "TestingAndroidWsi.h" +#include "gfxstream/guest/ANativeWindow.h" +#include "gfxstream/guest/Gralloc.h" +#include "Sync.h" namespace gfxstream { namespace tests { @@ -182,8 +182,6 @@ class GfxstreamEnd2EndTest : public ::testing::TestWithParam<TestParams> { void TearDownHost(); void TearDown() override; - std::unique_ptr<TestingANativeWindow> CreateEmulatedANW(uint32_t width, uint32_t height); - void SetUpEglContextAndSurface(uint32_t contextVersion, uint32_t width, uint32_t height, @@ -216,9 +214,9 @@ class GfxstreamEnd2EndTest : public ::testing::TestWithParam<TestParams> { void SnapshotSaveAndLoad(); - std::unique_ptr<TestingVirtGpuANativeWindowHelper> mAnwHelper; - std::unique_ptr<TestingVirtGpuGralloc> mGralloc; - SyncHelper* mSync; + std::unique_ptr<ANativeWindowHelper> mAnwHelper; + std::unique_ptr<Gralloc> mGralloc; + std::unique_ptr<SyncHelper> mSync; std::unique_ptr<GuestGlDispatchTable> mGl; std::unique_ptr<vkhpp::DynamicLoader> mVk; }; diff --git a/common/end2end/GfxstreamEnd2EndVkTests.cpp b/common/end2end/GfxstreamEnd2EndVkTests.cpp index 7110c5c9..087e829f 100644 --- a/common/end2end/GfxstreamEnd2EndVkTests.cpp +++ b/common/end2end/GfxstreamEnd2EndVkTests.cpp @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "GfxstreamEnd2EndTests.h" +#include <log/log.h> +#include "GfxstreamEnd2EndTests.h" #include "drm_fourcc.h" namespace gfxstream { @@ -46,11 +47,12 @@ TEST_P(GfxstreamEnd2EndVkTest, ImportAHB) { const uint32_t width = 32; const uint32_t height = 32; - auto ahb = mGralloc->allocate(width, height, DRM_FORMAT_ABGR8888); + AHardwareBuffer* ahb = nullptr; + ASSERT_THAT(mGralloc->allocate(width, height, DRM_FORMAT_ABGR8888, -1, &ahb), Eq(0)); const VkNativeBufferANDROID imageNativeBufferInfo = { .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID, - .handle = ahb->asBufferHandle(), + .handle = mGralloc->getNativeHandle(ahb), }; auto vkQueueSignalReleaseImageANDROID = PFN_vkQueueSignalReleaseImageANDROID( @@ -163,6 +165,8 @@ TEST_P(GfxstreamEnd2EndVkTest, ImportAHB) { ASSERT_THAT(fence, Not(Eq(-1))); ASSERT_THAT(mSync->wait(fence, 3000), Eq(0)); + + mGralloc->release(ahb); } TEST_P(GfxstreamEnd2EndVkTest, DeferredImportAHB) { @@ -171,7 +175,8 @@ TEST_P(GfxstreamEnd2EndVkTest, DeferredImportAHB) { const uint32_t width = 32; const uint32_t height = 32; - auto ahb = mGralloc->allocate(width, height, DRM_FORMAT_ABGR8888); + AHardwareBuffer* ahb = nullptr; + ASSERT_THAT(mGralloc->allocate(width, height, DRM_FORMAT_ABGR8888, -1, &ahb), Eq(0)); auto vkQueueSignalReleaseImageANDROID = PFN_vkQueueSignalReleaseImageANDROID( device->getProcAddr("vkQueueSignalReleaseImageANDROID")); @@ -199,7 +204,7 @@ TEST_P(GfxstreamEnd2EndVkTest, DeferredImportAHB) { // NOTE: Binding the VkImage to the AHB happens after the VkImage is created. const VkNativeBufferANDROID imageNativeBufferInfo = { .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID, - .handle = ahb->asBufferHandle(), + .handle = mGralloc->getNativeHandle(ahb), }; const vkhpp::BindImageMemoryInfo imageBindMemoryInfo = { @@ -218,6 +223,8 @@ TEST_P(GfxstreamEnd2EndVkTest, DeferredImportAHB) { ASSERT_THAT(fence, Not(Eq(-1))); ASSERT_THAT(mSync->wait(fence, 3000), Eq(0)); + + mGralloc->release(ahb); } TEST_P(GfxstreamEnd2EndVkTest, HostMemory) { diff --git a/guest/OpenglSystemCommon/Android.bp b/guest/OpenglSystemCommon/Android.bp index 0cf3aaa1..3cb00d66 100644 --- a/guest/OpenglSystemCommon/Android.bp +++ b/guest/OpenglSystemCommon/Android.bp @@ -19,55 +19,29 @@ package { default_applicable_licenses: ["hardware_google_gfxstream_license"], } -cc_library_static { - name: "libgfxstream_guest_gralloc", - vendor: true, - host_supported: true, - defaults: [ - "libgfxstream_guest_cc_defaults", - ], - header_libs: [ - "libdrm_headers", - "libgfxstream_guest_graphics_headers", - "libgfxstream_guest_iostream", - "libgralloc_cb.ranchu", - "minigbm_headers", - ], - export_header_lib_headers: [ - "libgfxstream_guest_graphics_headers", - "libgfxstream_guest_iostream", - "libgralloc_cb.ranchu", - ], - shared_libs: [ - "lib_renderControl_enc", - ], - export_shared_lib_headers: [ - "lib_renderControl_enc", - ], +cc_library_headers { + name: "libgfxstream_guest_sync", export_include_dirs: [ ".", ], - target: { - android: { - shared_libs: [ - "libnativewindow", - ], - export_shared_lib_headers: [ - "libnativewindow", - ], - srcs: [ - "GrallocGoldfish.cpp", - "GrallocMinigbm.cpp", - ], - }, - }, } cc_library_headers { - name: "libgfxstream_guest_sync", + name: "libOpenglSystemCommonHeaders", + host_supported: true, + vendor: true, + defaults: [ + "libgfxstream_guest_cc_defaults", + ], export_include_dirs: [ ".", ], + header_libs: [ + "libgfxstream_guest_rendercontrol_encoder_headers", + ], + export_header_lib_headers: [ + "libgfxstream_guest_rendercontrol_encoder_headers", + ], } cc_defaults { @@ -81,15 +55,12 @@ cc_defaults { "gfxstream_vulkan_headers", "libgfxstream_guest_graphics_headers", "libgfxstream_guest_iostream", - "libgralloc_cb.ranchu", "libhardware_headers", "libnativebase_headers", - "minigbm_headers", ], export_header_lib_headers: [ "libgfxstream_guest_graphics_headers", "libgfxstream_guest_iostream", - "libgralloc_cb.ranchu", "libhardware_headers", "libnativebase_headers", ], @@ -112,10 +83,6 @@ cc_defaults { "libGoldfishAddressSpace", "libringbuffer", "libqemupipe.ranchu", - "libgfxstream_guest_gralloc", - ], - export_static_lib_headers: [ - "libgfxstream_guest_gralloc", ], cflags: [ "-Wno-unused-variable", @@ -140,18 +107,6 @@ cc_defaults { export_header_lib_headers: [ "gfxstream_opengl_headers", ], - shared_libs: [ - "libnativewindow", - "libsync", - ], - srcs: [ - "ANativeWindowAndroid.cpp", - ], - }, - host: { - srcs: [ - "TestingAndroidWsi.cpp", - ], }, }, } @@ -165,12 +120,22 @@ cc_library_shared { "libandroidemu", ], static_libs: [ + "libgfxstream_guest_android", "libvulkan_enc", "libplatform", ], export_static_lib_headers: [ + "libgfxstream_guest_android", "libplatform", ], + target: { + android: { + shared_libs: [ + "libnativewindow", + "libsync", + ], + } + }, } cc_library_shared { @@ -179,14 +144,16 @@ cc_library_shared { "libOpenglSystemCommonDefaults", ], shared_libs: [ - "libgfxstream_backend", - "libplatform_rutabaga", "libandroidemu", + "libplatform_rutabaga_server", ], static_libs: [ + "libgfxstream_guest_android_with_host", "libgfxstream_guest_vulkan_encoder_with_host", + "libplatform_rutabaga", ], - export_shared_lib_headers: [ + export_static_lib_headers: [ + "libgfxstream_guest_android_with_host", "libplatform_rutabaga", ], target: { @@ -209,9 +176,11 @@ cc_library_static { ], static_libs: [ "libandroidemu_static", + "libgfxstream_guest_android", "libplatform", ], export_static_lib_headers: [ + "libgfxstream_guest_android", "libplatform", ], } @@ -225,13 +194,15 @@ cc_library_static { "vulkan_enc_headers", ], shared_libs: [ - "libgfxstream_backend", - "libplatform_rutabaga", + "libplatform_rutabaga_server", ], static_libs: [ "libandroidemu_static", + "libgfxstream_guest_android_with_host", + "libplatform_rutabaga", ], - export_shared_lib_headers: [ + export_static_lib_headers: [ + "libgfxstream_guest_android_with_host", "libplatform_rutabaga", ], target: { diff --git a/guest/OpenglSystemCommon/HostConnection.cpp b/guest/OpenglSystemCommon/HostConnection.cpp index 59b2385f..b82cab0b 100644 --- a/guest/OpenglSystemCommon/HostConnection.cpp +++ b/guest/OpenglSystemCommon/HostConnection.cpp @@ -15,12 +15,7 @@ */ #include "HostConnection.h" -#if defined(__ANDROID__) -#include "ANativeWindowAndroid.h" -#endif #include "GoldfishAddressSpaceStream.h" -#include "GrallocGoldfish.h" -#include "GrallocMinigbm.h" #include "VirtioGpuAddressSpaceStream.h" #include "aemu/base/AndroidHealthMonitor.h" #include "aemu/base/AndroidHealthMonitorConsumerBasic.h" @@ -45,8 +40,6 @@ using gfxstream::guest::CreateHealthMonitor; using gfxstream::guest::HealthMonitor; using gfxstream::guest::HealthMonitorConsumerBasic; using gfxstream::guest::IOStream; -using gfxstream::GoldfishGralloc; -using gfxstream::MinigbmGralloc; #ifdef GOLDFISH_NO_GL struct gl_client_context_t { @@ -178,29 +171,6 @@ static uint32_t getDrawCallFlushIntervalFromProperty() { return value; } -static GrallocType getGrallocTypeFromProperty() { - std::string value; - -#if defined(__ANDROID__) - value = android::base::GetProperty("ro.hardware.gralloc", ""); -#endif - - if (value.empty()) { - return GRALLOC_TYPE_RANCHU; - } - if (value == "minigbm") { - return GRALLOC_TYPE_MINIGBM; - } - if (value == "ranchu") { - return GRALLOC_TYPE_RANCHU; - } - return GRALLOC_TYPE_RANCHU; -} - -#if defined(__ANDROID__) -static GoldfishGralloc m_goldfishGralloc; -#endif - HostConnection::HostConnection() : exitUncleanly(false), m_checksumHelper(), @@ -216,10 +186,6 @@ HostConnection::~HostConnection() (void)m_rcEnc->rcGetRendererVersion(m_rcEnc.get()); } - if (m_grallocType == GRALLOC_TYPE_MINIGBM) { - delete m_grallocHelper; - } - if (m_vkEnc) { m_vkEnc->decRef(); } @@ -252,10 +218,7 @@ std::unique_ptr<HostConnection> HostConnection::connect(enum VirtGpuCapset capse ALOGE("Fatal: HOST_CONNECTION_ADDRESS_SPACE not supported on this host."); abort(); #endif - con->m_grallocType = GRALLOC_TYPE_RANCHU; -#if defined(__ANDROID__) - con->m_grallocHelper = &m_goldfishGralloc; -#endif + break; } #if !defined(__Fuchsia__) @@ -269,11 +232,7 @@ std::unique_ptr<HostConnection> HostConnection::connect(enum VirtGpuCapset capse ALOGE("Failed to connect to host (QemuPipeStream)\n"); return nullptr; } - con->m_grallocType = GRALLOC_TYPE_RANCHU; con->m_stream = stream; -#if defined(__ANDROID__) - con->m_grallocHelper = &m_goldfishGralloc; -#endif break; } #endif @@ -287,26 +246,9 @@ std::unique_ptr<HostConnection> HostConnection::connect(enum VirtGpuCapset capse ALOGE("Failed to connect to host (VirtioGpu)\n"); return nullptr; } - con->m_grallocType = getGrallocTypeFromProperty(); auto rendernodeFd = stream->getRendernodeFd(); con->m_stream = stream; con->m_rendernodeFd = rendernodeFd; -#if defined(__ANDROID__) - switch (con->m_grallocType) { - case GRALLOC_TYPE_RANCHU: - con->m_grallocHelper = &m_goldfishGralloc; - break; - case GRALLOC_TYPE_MINIGBM: { - MinigbmGralloc* m = new MinigbmGralloc; - m->setFd(rendernodeFd); - con->m_grallocHelper = m; - break; - } - default: - ALOGE("Fatal: Unknown gralloc type 0x%x\n", con->m_grallocType); - abort(); - } -#endif break; } case HOST_CONNECTION_VIRTIO_GPU_ADDRESS_SPACE: { @@ -320,36 +262,28 @@ std::unique_ptr<HostConnection> HostConnection::connect(enum VirtGpuCapset capse ALOGE("Failed to create virtgpu AddressSpaceStream\n"); return nullptr; } - con->m_grallocType = getGrallocTypeFromProperty(); con->m_stream = stream; con->m_rendernodeFd = deviceHandle; -#if defined(__ANDROID__) - switch (con->m_grallocType) { - case GRALLOC_TYPE_RANCHU: - con->m_grallocHelper = &m_goldfishGralloc; - break; - case GRALLOC_TYPE_MINIGBM: { - MinigbmGralloc* m = new gfxstream::MinigbmGralloc; - m->setFd(deviceHandle); - con->m_grallocHelper = m; - break; - } - default: - ALOGE("Fatal: Unknown gralloc type 0x%x\n", con->m_grallocType); - abort(); - } -#endif break; } default: break; } -#if defined(__ANDROID__) - con->m_anwHelper = new gfxstream::ANativeWindowHelperAndroid(); -#else - // Host builds are expected to set an ANW helper for testing. +#if defined(ANDROID) + con->m_grallocHelper.reset(gfxstream::createPlatformGralloc(con->m_rendernodeFd)); + if (!con->m_grallocHelper) { + ALOGE("Failed to create platform Gralloc!"); + abort(); + } + + con->m_anwHelper.reset(gfxstream::createPlatformANativeWindowHelper()); + if (!con->m_anwHelper) { + ALOGE("Failed to create platform ANativeWindowHelper!"); + abort(); + } #endif + con->m_syncHelper.reset(gfxstream::createPlatformSyncHelper()); // send zero 'clientFlags' to the host. diff --git a/guest/OpenglSystemCommon/HostConnection.h b/guest/OpenglSystemCommon/HostConnection.h index 740f2073..228df4e2 100644 --- a/guest/OpenglSystemCommon/HostConnection.h +++ b/guest/OpenglSystemCommon/HostConnection.h @@ -16,22 +16,24 @@ #ifndef __COMMON_HOST_CONNECTION_H #define __COMMON_HOST_CONNECTION_H -#include "ANativeWindow.h" +#if defined(ANDROID) +#include "gfxstream/guest/ANativeWindow.h" +#include "gfxstream/guest/Gralloc.h" +#endif + +#include <cstring> +#include <memory> +#include <mutex> +#include <optional> +#include <string> + #include "EmulatorFeatureInfo.h" -#include "Gralloc.h" #include "Sync.h" #include "VirtGpu.h" #include "gfxstream/guest/ChecksumCalculator.h" #include "gfxstream/guest/IOStream.h" #include "renderControl_enc.h" -#include <mutex> - -#include <memory> -#include <optional> -#include <cstring> -#include <string> - class GLEncoder; struct gl_client_context_t; class GL2Encoder; @@ -134,14 +136,11 @@ public: gfxstream::guest::ChecksumCalculator *checksumHelper() { return &m_checksumHelper; } - gfxstream::Gralloc* grallocHelper() { return m_grallocHelper; } - void setGrallocHelperForTesting(gfxstream::Gralloc* gralloc) { m_grallocHelper = gralloc; } - +#if defined(ANDROID) + gfxstream::ANativeWindowHelper* anwHelper() { return m_anwHelper.get(); } + gfxstream::Gralloc* grallocHelper() { return m_grallocHelper.get(); } +#endif gfxstream::SyncHelper* syncHelper() { return m_syncHelper.get(); } - void setSyncHelperForTesting(gfxstream::SyncHelper* sync) { m_syncHelper.reset(sync); } - - gfxstream::ANativeWindowHelper* anwHelper() { return m_anwHelper; } - void setANativeWindowHelperForTesting(gfxstream::ANativeWindowHelper* anw) { m_anwHelper = anw; } void flush() { if (m_stream) { @@ -205,27 +204,28 @@ private: GLint queryVersion(ExtendedRCEncoderContext* rcEnc); private: - HostConnectionType m_connectionType; - GrallocType m_grallocType; - - // intrusively refcounted - gfxstream::guest::IOStream* m_stream = nullptr; - - std::unique_ptr<GLEncoder> m_glEnc; - std::unique_ptr<GL2Encoder> m_gl2Enc; - - // intrusively refcounted - gfxstream::vk::VkEncoder* m_vkEnc = nullptr; - std::unique_ptr<ExtendedRCEncoderContext> m_rcEnc; - - gfxstream::guest::ChecksumCalculator m_checksumHelper; - gfxstream::ANativeWindowHelper* m_anwHelper = nullptr; - gfxstream::Gralloc* m_grallocHelper = nullptr; - std::unique_ptr<gfxstream::SyncHelper> m_syncHelper; - std::string m_hostExtensions; - bool m_noHostError; - mutable std::mutex m_lock; - int m_rendernodeFd; + HostConnectionType m_connectionType; + + // intrusively refcounted + gfxstream::guest::IOStream* m_stream = nullptr; + + std::unique_ptr<GLEncoder> m_glEnc; + std::unique_ptr<GL2Encoder> m_gl2Enc; + + // intrusively refcounted + gfxstream::vk::VkEncoder* m_vkEnc = nullptr; + std::unique_ptr<ExtendedRCEncoderContext> m_rcEnc; + + gfxstream::guest::ChecksumCalculator m_checksumHelper; +#if defined(ANDROID) + std::unique_ptr<gfxstream::ANativeWindowHelper> m_anwHelper; + std::unique_ptr<gfxstream::Gralloc> m_grallocHelper; +#endif + std::unique_ptr<gfxstream::SyncHelper> m_syncHelper; + std::string m_hostExtensions; + bool m_noHostError; + mutable std::mutex m_lock; + int m_rendernodeFd; }; #endif diff --git a/guest/OpenglSystemCommon/TestingAndroidWsi.cpp b/guest/OpenglSystemCommon/TestingAndroidWsi.cpp deleted file mode 100644 index b62ff184..00000000 --- a/guest/OpenglSystemCommon/TestingAndroidWsi.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -#include <iostream> -#include <cutils/log.h> - -#include "drm_fourcc.h" -#include "TestingAndroidWsi.h" - -namespace gfxstream { - -static constexpr int numFds = 0; -static constexpr int numInts = 1; - -std::optional<uint32_t> GlFormatToDrmFormat(uint32_t glFormat) { - switch (glFormat) { - case kGlRGB: - return DRM_FORMAT_BGR888; - case kGlRGB565: - return DRM_FORMAT_BGR565; - case kGlRGBA: - return DRM_FORMAT_ABGR8888; - } - return std::nullopt; -} - -std::optional<uint32_t> DrmToVirglFormat(uint32_t drmFormat) { - switch (drmFormat) { - case DRM_FORMAT_ABGR8888: - return VIRGL_FORMAT_B8G8R8A8_UNORM; - case DRM_FORMAT_BGR888: - return VIRGL_FORMAT_R8G8B8_UNORM; - case DRM_FORMAT_BGR565: - return VIRGL_FORMAT_B5G6R5_UNORM; - } - return std::nullopt; -} - -TestingAHardwareBuffer::TestingAHardwareBuffer( - uint32_t width, - uint32_t height, - VirtGpuBlobPtr resource) - : mWidth(width), - mHeight(height), - mResource(resource) { - mHandle = native_handle_create(numFds, numInts); - mHandle->data[0] = mResource->getResourceHandle(); -} - -TestingAHardwareBuffer::~TestingAHardwareBuffer() { - native_handle_close(mHandle); -} - -uint32_t TestingAHardwareBuffer::getResourceId() const { - return mResource->getResourceHandle(); -} - -uint32_t TestingAHardwareBuffer::getWidth() const { - return mWidth; -} - -uint32_t TestingAHardwareBuffer::getHeight() const { - return mHeight; -} - -int TestingAHardwareBuffer::getAndroidFormat() const { - return /*AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM=*/1; -} - -uint32_t TestingAHardwareBuffer::getDrmFormat() const { - return DRM_FORMAT_ABGR8888; -} - -AHardwareBuffer* TestingAHardwareBuffer::asAHardwareBuffer() { - return reinterpret_cast<AHardwareBuffer*>(this); -} - -buffer_handle_t TestingAHardwareBuffer::asBufferHandle() { - return reinterpret_cast<buffer_handle_t>(mHandle); -} - -EGLClientBuffer TestingAHardwareBuffer::asEglClientBuffer() { - return reinterpret_cast<EGLClientBuffer>(this); -} - -TestingVirtGpuGralloc::TestingVirtGpuGralloc() {} - -uint32_t TestingVirtGpuGralloc::createColorBuffer( - void*, - int width, - int height, - uint32_t glFormat) { - auto drmFormat = GlFormatToDrmFormat(glFormat); - if (!drmFormat) { - ALOGE("Unhandled format"); - } - - auto ahb = allocate(width, height, *drmFormat); - - uint32_t hostHandle = ahb->getResourceId(); - mAllocatedColorBuffers.emplace(hostHandle, std::move(ahb)); - return hostHandle; -} - -int TestingVirtGpuGralloc::allocate( - uint32_t width, - uint32_t height, - uint32_t format, - uint64_t usage, - AHardwareBuffer** outputAhb) { - (void)width; - (void)height; - (void)format; - (void)usage; - (void)outputAhb; - - // TODO: support export flow? - ALOGE("Unimplemented"); - - return 0; -} - -std::unique_ptr<TestingAHardwareBuffer> TestingVirtGpuGralloc::allocate( - uint32_t width, - uint32_t height, - uint32_t format) { - ALOGE("Allocating AHB w:%u, h:%u, format %u", width, height, format); - - auto device = VirtGpuDevice::getInstance(); - if (!device) { - ALOGE("Failed to allocate: no virtio gpu device."); - return nullptr; - } - - auto virglFormat = DrmToVirglFormat(format); - if (!virglFormat) { - std::cout << "Unhandled DRM format:" << format; - return nullptr; - } - - auto resource = device->createVirglBlob(width, height, *virglFormat); - if (!resource) { - ALOGE("Failed to allocate: failed to create virtio resource."); - return nullptr; - } - - resource->wait(); - - return std::make_unique<TestingAHardwareBuffer>(width, height, std::move(resource)); -} - -void TestingVirtGpuGralloc::acquire(AHardwareBuffer* ahb) { - // TODO -} - -void TestingVirtGpuGralloc::release(AHardwareBuffer* ahb) { - // TODO -} - -uint32_t TestingVirtGpuGralloc::getHostHandle(const native_handle_t* handle) { - const auto* ahb = reinterpret_cast<const TestingAHardwareBuffer*>(handle); - return ahb->getResourceId(); -} - -uint32_t TestingVirtGpuGralloc::getHostHandle(const AHardwareBuffer* handle) { - const auto* ahb = reinterpret_cast<const TestingAHardwareBuffer*>(handle); - return ahb->getResourceId(); -} - -int TestingVirtGpuGralloc::getFormat(const native_handle_t* handle) { - const auto* ahb = reinterpret_cast<const TestingAHardwareBuffer*>(handle); - return ahb->getAndroidFormat(); -} - -int TestingVirtGpuGralloc::getFormat(const AHardwareBuffer* handle) { - const auto* ahb = reinterpret_cast<const TestingAHardwareBuffer*>(handle); - return ahb->getAndroidFormat(); -} - -uint32_t TestingVirtGpuGralloc::getFormatDrmFourcc(const AHardwareBuffer* handle) { - const auto* ahb = reinterpret_cast<const TestingAHardwareBuffer*>(handle); - return ahb->getDrmFormat(); -} - -size_t TestingVirtGpuGralloc::getAllocatedSize(const native_handle_t*) { - ALOGE("Unimplemented."); - return 0; -} - -size_t TestingVirtGpuGralloc::getAllocatedSize(const AHardwareBuffer*) { - ALOGE("Unimplemented."); - return 0; -} - -TestingANativeWindow::TestingANativeWindow( - uint32_t width, - uint32_t height, - uint32_t format, - std::vector<std::unique_ptr<TestingAHardwareBuffer>> buffers) - : mWidth(width), - mHeight(height), - mFormat(format), - mBuffers(std::move(buffers)) { - for (auto& buffer : mBuffers) { - mBufferQueue.push_back(QueuedAHB{ - .ahb = buffer.get(), - .fence = -1, - }); - } -} - -EGLNativeWindowType TestingANativeWindow::asEglNativeWindowType() { - return reinterpret_cast<EGLNativeWindowType>(this); -} - -uint32_t TestingANativeWindow::getWidth() const { - return mWidth; -} - -uint32_t TestingANativeWindow::getHeight() const { - return mHeight; -} - -int TestingANativeWindow::getFormat() const { - return mFormat; -} - -int TestingANativeWindow::queueBuffer(EGLClientBuffer buffer, int fence) { - auto ahb = reinterpret_cast<TestingAHardwareBuffer*>(buffer); - - mBufferQueue.push_back(QueuedAHB{ - .ahb = ahb, - .fence = fence, - }); - - return 0; -} - -int TestingANativeWindow::dequeueBuffer(EGLClientBuffer* buffer, int* fence) { - auto queuedAhb = mBufferQueue.front(); - mBufferQueue.pop_front(); - - *buffer = queuedAhb.ahb->asEglClientBuffer(); - *fence = queuedAhb.fence; - return 0; -} - -int TestingANativeWindow::cancelBuffer(EGLClientBuffer buffer) { - auto ahb = reinterpret_cast<TestingAHardwareBuffer*>(buffer); - - mBufferQueue.push_back(QueuedAHB{ - .ahb = ahb, - .fence = -1, - }); - - return 0; -} - -bool TestingVirtGpuANativeWindowHelper::isValid(EGLNativeWindowType window) { - // TODO: maybe a registry of valid TestingANativeWindow-s? - return true; -} - -bool TestingVirtGpuANativeWindowHelper::isValid(EGLClientBuffer buffer) { - // TODO: maybe a registry of valid TestingAHardwareBuffer-s? - return true; -} - -void TestingVirtGpuANativeWindowHelper::acquire(EGLNativeWindowType window) { - // TODO: maybe a registry of valid TestingANativeWindow-s? -} - -void TestingVirtGpuANativeWindowHelper::release(EGLNativeWindowType window) { - // TODO: maybe a registry of valid TestingANativeWindow-s? -} - -void TestingVirtGpuANativeWindowHelper::acquire(EGLClientBuffer buffer) { - // TODO: maybe a registry of valid TestingAHardwareBuffer-s? -} - -void TestingVirtGpuANativeWindowHelper::release(EGLClientBuffer buffer) { - // TODO: maybe a registry of valid TestingAHardwareBuffer-s? -} - -int TestingVirtGpuANativeWindowHelper::getConsumerUsage(EGLNativeWindowType window, int* usage) { - (void)window; - (void)usage; - return 0; -} -void TestingVirtGpuANativeWindowHelper::setUsage(EGLNativeWindowType window, int usage) { - (void)window; - (void)usage; -} - -int TestingVirtGpuANativeWindowHelper::getWidth(EGLNativeWindowType window) { - auto anw = reinterpret_cast<TestingANativeWindow*>(window); - return anw->getWidth(); -} - -int TestingVirtGpuANativeWindowHelper::getHeight(EGLNativeWindowType window) { - auto anw = reinterpret_cast<TestingANativeWindow*>(window); - return anw->getHeight(); -} - -int TestingVirtGpuANativeWindowHelper::getWidth(EGLClientBuffer buffer) { - auto ahb = reinterpret_cast<TestingAHardwareBuffer*>(buffer); - return ahb->getWidth(); -} - -int TestingVirtGpuANativeWindowHelper::getHeight(EGLClientBuffer buffer) { - auto ahb = reinterpret_cast<TestingAHardwareBuffer*>(buffer); - return ahb->getHeight(); -} - -int TestingVirtGpuANativeWindowHelper::getFormat(EGLClientBuffer buffer, Gralloc* helper) { - auto ahb = reinterpret_cast<TestingAHardwareBuffer*>(buffer); - return ahb->getAndroidFormat(); -} - -void TestingVirtGpuANativeWindowHelper::setSwapInterval(EGLNativeWindowType window, int interval) { - ALOGE("Unimplemented"); -} - -int TestingVirtGpuANativeWindowHelper::queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, int fence) { - auto anw = reinterpret_cast<TestingANativeWindow*>(window); - return anw->queueBuffer(buffer, fence); -} - -int TestingVirtGpuANativeWindowHelper::dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, int* fence) { - auto anw = reinterpret_cast<TestingANativeWindow*>(window); - return anw->dequeueBuffer(buffer, fence); -} - -int TestingVirtGpuANativeWindowHelper::cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer) { - auto anw = reinterpret_cast<TestingANativeWindow*>(window); - return anw->cancelBuffer(buffer); -} - -int TestingVirtGpuANativeWindowHelper::getHostHandle(EGLClientBuffer buffer, Gralloc*) { - auto ahb = reinterpret_cast<TestingAHardwareBuffer*>(buffer); - return ahb->getResourceId(); -} - -} // namespace gfxstream diff --git a/guest/OpenglSystemCommon/TestingAndroidWsi.h b/guest/OpenglSystemCommon/TestingAndroidWsi.h deleted file mode 100644 index b18455e0..00000000 --- a/guest/OpenglSystemCommon/TestingAndroidWsi.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2023 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -#include <optional> -#include <queue> -#include <unordered_map> -#include <vector> - -#include "VirtGpu.h" -#include "ANativeWindow.h" - -namespace gfxstream { - -class TestingAHardwareBuffer { - public: - TestingAHardwareBuffer(uint32_t width, - uint32_t height, - VirtGpuBlobPtr resource); - - ~TestingAHardwareBuffer(); - - uint32_t getResourceId() const; - - uint32_t getWidth() const; - - uint32_t getHeight() const; - - int getAndroidFormat() const; - - uint32_t getDrmFormat() const; - - AHardwareBuffer* asAHardwareBuffer(); - - buffer_handle_t asBufferHandle(); - - EGLClientBuffer asEglClientBuffer(); - - private: - uint32_t mWidth; - uint32_t mHeight; - VirtGpuBlobPtr mResource; - native_handle_t *mHandle = nullptr; -}; - -class TestingVirtGpuGralloc : public Gralloc { - public: - TestingVirtGpuGralloc(); - - uint32_t createColorBuffer(void*, - int width, - int height, - uint32_t glFormat) override; - - int allocate(uint32_t width, - uint32_t height, - uint32_t format, - uint64_t usage, - AHardwareBuffer** outputAhb) override; - - std::unique_ptr<TestingAHardwareBuffer> allocate(uint32_t width, - uint32_t height, - uint32_t format); - - void acquire(AHardwareBuffer* ahb) override; - void release(AHardwareBuffer* ahb) override; - - uint32_t getHostHandle(const native_handle_t* handle) override; - uint32_t getHostHandle(const AHardwareBuffer* handle) override; - - int getFormat(const native_handle_t* handle) override; - int getFormat(const AHardwareBuffer* handle) override; - - uint32_t getFormatDrmFourcc(const AHardwareBuffer* handle) override; - - size_t getAllocatedSize(const native_handle_t*) override; - size_t getAllocatedSize(const AHardwareBuffer*) override; - - private: - std::unordered_map<uint32_t, std::unique_ptr<TestingAHardwareBuffer>> mAllocatedColorBuffers; -}; - -class TestingANativeWindow { - public: - TestingANativeWindow(uint32_t width, - uint32_t height, - uint32_t format, - std::vector<std::unique_ptr<TestingAHardwareBuffer>> buffers); - - EGLNativeWindowType asEglNativeWindowType(); - - uint32_t getWidth() const; - - uint32_t getHeight() const; - - int getFormat() const; - - int queueBuffer(EGLClientBuffer buffer, int fence); - int dequeueBuffer(EGLClientBuffer* buffer, int* fence); - int cancelBuffer(EGLClientBuffer buffer); - - private: - uint32_t mWidth; - uint32_t mHeight; - uint32_t mFormat; - std::vector<std::unique_ptr<TestingAHardwareBuffer>> mBuffers; - - struct QueuedAHB { - TestingAHardwareBuffer* ahb; - int fence = -1; - }; - std::deque<QueuedAHB> mBufferQueue; -}; - -class TestingVirtGpuANativeWindowHelper : public ANativeWindowHelper { - public: - bool isValid(EGLNativeWindowType window) override; - bool isValid(EGLClientBuffer buffer) override; - - void acquire(EGLNativeWindowType window) override; - void release(EGLNativeWindowType window) override; - - void acquire(EGLClientBuffer buffer) override; - void release(EGLClientBuffer buffer) override; - - int getConsumerUsage(EGLNativeWindowType window, int* usage) override; - void setUsage(EGLNativeWindowType window, int usage) override; - - int getWidth(EGLNativeWindowType window) override; - int getHeight(EGLNativeWindowType window) override; - - int getWidth(EGLClientBuffer buffer) override; - int getHeight(EGLClientBuffer buffer) override; - - int getFormat(EGLClientBuffer buffer, Gralloc* helper) override; - - void setSwapInterval(EGLNativeWindowType window, int interval) override; - - int queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, int fence) override; - int dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, int* fence) override; - int cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer) override; - - int getHostHandle(EGLClientBuffer buffer, Gralloc*) override; -}; - -} // namespace gfxstream diff --git a/guest/OpenglSystemCommon/ANativeWindowAndroid.cpp b/guest/android/ANativeWindowAndroid.cpp index 1edae701..6ab4fa6c 100644 --- a/guest/OpenglSystemCommon/ANativeWindowAndroid.cpp +++ b/guest/android/ANativeWindowAndroid.cpp @@ -68,7 +68,6 @@ void ANativeWindowHelperAndroid::release(EGLNativeWindowType window) { #endif // defined(__ANDROID__) } - void ANativeWindowHelperAndroid::acquire(EGLClientBuffer buffer) { #if defined(__ANDROID__) auto* anwb = reinterpret_cast<ANativeWindowBuffer*>(buffer); @@ -169,7 +168,8 @@ void ANativeWindowHelperAndroid::setSwapInterval(EGLNativeWindowType window, int #endif // defined(__ANDROID__) } -int ANativeWindowHelperAndroid::queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, int fence) { +int ANativeWindowHelperAndroid::queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, + int fence) { #if defined(__ANDROID__) auto* anw = reinterpret_cast<ANativeWindow*>(window); auto* anb = reinterpret_cast<ANativeWindowBuffer*>(buffer); @@ -182,7 +182,8 @@ int ANativeWindowHelperAndroid::queueBuffer(EGLNativeWindowType window, EGLClien #endif // defined(__ANDROID__) } -int ANativeWindowHelperAndroid::dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, int* fence) { +int ANativeWindowHelperAndroid::dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, + int* fence) { #if defined(__ANDROID__) auto* anw = reinterpret_cast<ANativeWindow*>(window); auto* anb = reinterpret_cast<ANativeWindowBuffer**>(buffer); @@ -218,4 +219,8 @@ int ANativeWindowHelperAndroid::getHostHandle(EGLClientBuffer buffer, Gralloc* g #endif // defined(__ANDROID__) } +ANativeWindowHelper* createPlatformANativeWindowHelper() { + return new ANativeWindowHelperAndroid(); +} + } // namespace gfxstream
\ No newline at end of file diff --git a/guest/OpenglSystemCommon/ANativeWindowAndroid.h b/guest/android/ANativeWindowAndroid.h index 97eba6a5..bac57c3f 100644 --- a/guest/OpenglSystemCommon/ANativeWindowAndroid.h +++ b/guest/android/ANativeWindowAndroid.h @@ -17,12 +17,12 @@ #include <EGL/egl.h> #include <EGL/eglext.h> -#include "ANativeWindow.h" +#include "gfxstream/guest/ANativeWindow.h" namespace gfxstream { class ANativeWindowHelperAndroid : public ANativeWindowHelper { - public: + public: ANativeWindowHelperAndroid() = default; bool isValid(EGLNativeWindowType window); diff --git a/guest/android/ANativeWindowEmulated.cpp b/guest/android/ANativeWindowEmulated.cpp new file mode 100644 index 00000000..d3e83c38 --- /dev/null +++ b/guest/android/ANativeWindowEmulated.cpp @@ -0,0 +1,199 @@ +// Copyright 2024 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 "ANativeWindowEmulated.h" + +#include <log/log.h> + +#include "drm_fourcc.h" + +namespace gfxstream { + +EmulatedANativeWindow::EmulatedANativeWindow( + uint32_t width, uint32_t height, uint32_t format, + std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> buffers) + : mRefCount(1), mWidth(width), mHeight(height), mFormat(format), mBuffers(std::move(buffers)) { + for (auto& buffer : mBuffers) { + mBufferQueue.push_back(QueuedAHB{ + .ahb = buffer.get(), + .fence = -1, + }); + } +} + +EGLNativeWindowType EmulatedANativeWindow::asEglNativeWindowType() { + return reinterpret_cast<EGLNativeWindowType>(this); +} + +uint32_t EmulatedANativeWindow::getWidth() const { return mWidth; } + +uint32_t EmulatedANativeWindow::getHeight() const { return mHeight; } + +int EmulatedANativeWindow::getFormat() const { return mFormat; } + +int EmulatedANativeWindow::queueBuffer(EGLClientBuffer buffer, int fence) { + auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer); + + mBufferQueue.push_back(QueuedAHB{ + .ahb = ahb, + .fence = fence, + }); + + return 0; +} + +int EmulatedANativeWindow::dequeueBuffer(EGLClientBuffer* buffer, int* fence) { + auto queuedAhb = mBufferQueue.front(); + mBufferQueue.pop_front(); + + *buffer = queuedAhb.ahb->asEglClientBuffer(); + *fence = queuedAhb.fence; + return 0; +} + +int EmulatedANativeWindow::cancelBuffer(EGLClientBuffer buffer) { + auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer); + + mBufferQueue.push_back(QueuedAHB{ + .ahb = ahb, + .fence = -1, + }); + + return 0; +} + +void EmulatedANativeWindow::acquire() { ++mRefCount; } + +void EmulatedANativeWindow::release() { + --mRefCount; + if (mRefCount == 0) { + delete this; + } +} + +bool EmulatedANativeWindowHelper::isValid(EGLNativeWindowType window) { + // TODO: maybe a registry of valid EmulatedANativeWindow-s? + (void)window; + return true; +} + +bool EmulatedANativeWindowHelper::isValid(EGLClientBuffer buffer) { + // TODO: maybe a registry of valid EmulatedAHardwareBuffer-s? + (void)buffer; + return true; +} + +void EmulatedANativeWindowHelper::acquire(EGLNativeWindowType window) { + auto* anw = reinterpret_cast<EmulatedANativeWindow*>(window); + anw->acquire(); +} + +void EmulatedANativeWindowHelper::release(EGLNativeWindowType window) { + auto* anw = reinterpret_cast<EmulatedANativeWindow*>(window); + anw->release(); +} + +void EmulatedANativeWindowHelper::acquire(EGLClientBuffer buffer) { + // TODO: maybe a registry of valid EmulatedAHardwareBuffer-s? + (void)buffer; +} + +void EmulatedANativeWindowHelper::release(EGLClientBuffer buffer) { (void)buffer; } + +int EmulatedANativeWindowHelper::getConsumerUsage(EGLNativeWindowType window, int* usage) { + (void)window; + (void)usage; + return 0; +} +void EmulatedANativeWindowHelper::setUsage(EGLNativeWindowType window, int usage) { + (void)window; + (void)usage; +} + +int EmulatedANativeWindowHelper::getWidth(EGLNativeWindowType window) { + auto anw = reinterpret_cast<EmulatedANativeWindow*>(window); + return anw->getWidth(); +} + +int EmulatedANativeWindowHelper::getHeight(EGLNativeWindowType window) { + auto anw = reinterpret_cast<EmulatedANativeWindow*>(window); + return anw->getHeight(); +} + +int EmulatedANativeWindowHelper::getWidth(EGLClientBuffer buffer) { + auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer); + return ahb->getWidth(); +} + +int EmulatedANativeWindowHelper::getHeight(EGLClientBuffer buffer) { + auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer); + return ahb->getHeight(); +} + +int EmulatedANativeWindowHelper::getFormat(EGLClientBuffer buffer, Gralloc* helper) { + (void)helper; + + auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer); + return ahb->getAndroidFormat(); +} + +void EmulatedANativeWindowHelper::setSwapInterval(EGLNativeWindowType window, int interval) { + ALOGE("Unimplemented"); + (void)window; + (void)interval; +} + +int EmulatedANativeWindowHelper::queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, + int fence) { + auto anw = reinterpret_cast<EmulatedANativeWindow*>(window); + return anw->queueBuffer(buffer, fence); +} + +int EmulatedANativeWindowHelper::dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, + int* fence) { + auto anw = reinterpret_cast<EmulatedANativeWindow*>(window); + return anw->dequeueBuffer(buffer, fence); +} + +int EmulatedANativeWindowHelper::cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer) { + auto anw = reinterpret_cast<EmulatedANativeWindow*>(window); + return anw->cancelBuffer(buffer); +} + +int EmulatedANativeWindowHelper::getHostHandle(EGLClientBuffer buffer, Gralloc*) { + auto ahb = reinterpret_cast<EmulatedAHardwareBuffer*>(buffer); + return ahb->getResourceId(); +} + +EGLNativeWindowType EmulatedANativeWindowHelper::createNativeWindowForTesting(Gralloc* gralloc, + uint32_t width, + uint32_t height) { + std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> buffers; + for (int i = 0; i < 3; i++) { + AHardwareBuffer* ahb = nullptr; + if (gralloc->allocate(width, height, DRM_FORMAT_ABGR8888, -1, &ahb) != 0) { + ALOGE("Failed to allocate gralloc buffer."); + return nullptr; + } + buffers.emplace_back(reinterpret_cast<EmulatedAHardwareBuffer*>(ahb)); + } + return reinterpret_cast<EGLNativeWindowType>( + new EmulatedANativeWindow(width, height, DRM_FORMAT_ABGR8888, std::move(buffers))); +} + +ANativeWindowHelper* createPlatformANativeWindowHelper() { + return new EmulatedANativeWindowHelper(); +} + +} // namespace gfxstream diff --git a/guest/android/ANativeWindowEmulated.h b/guest/android/ANativeWindowEmulated.h new file mode 100644 index 00000000..8794e517 --- /dev/null +++ b/guest/android/ANativeWindowEmulated.h @@ -0,0 +1,95 @@ +// Copyright 2024 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 <cstdint> +#include <memory> +#include <optional> +#include <queue> +#include <unordered_map> +#include <vector> + +#include "gfxstream/guest/ANativeWindow.h" +#include "GrallocEmulated.h" + +namespace gfxstream { + +class EmulatedANativeWindow { + public: + EmulatedANativeWindow(uint32_t width, uint32_t height, uint32_t format, + std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> buffers); + + EGLNativeWindowType asEglNativeWindowType(); + + uint32_t getWidth() const; + + uint32_t getHeight() const; + + int getFormat() const; + + int queueBuffer(EGLClientBuffer buffer, int fence); + int dequeueBuffer(EGLClientBuffer* buffer, int* fence); + int cancelBuffer(EGLClientBuffer buffer); + + void acquire(); + void release(); + + private: + uint32_t mRefCount; + uint32_t mWidth; + uint32_t mHeight; + uint32_t mFormat; + std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> mBuffers; + + struct QueuedAHB { + EmulatedAHardwareBuffer* ahb; + int fence = -1; + }; + std::deque<QueuedAHB> mBufferQueue; +}; + +class EmulatedANativeWindowHelper : public ANativeWindowHelper { + public: + bool isValid(EGLNativeWindowType window) override; + bool isValid(EGLClientBuffer buffer) override; + + void acquire(EGLNativeWindowType window) override; + void release(EGLNativeWindowType window) override; + + void acquire(EGLClientBuffer buffer) override; + void release(EGLClientBuffer buffer) override; + + int getConsumerUsage(EGLNativeWindowType window, int* usage) override; + void setUsage(EGLNativeWindowType window, int usage) override; + + int getWidth(EGLNativeWindowType window) override; + int getHeight(EGLNativeWindowType window) override; + + int getWidth(EGLClientBuffer buffer) override; + int getHeight(EGLClientBuffer buffer) override; + + int getFormat(EGLClientBuffer buffer, Gralloc* helper) override; + + void setSwapInterval(EGLNativeWindowType window, int interval) override; + + int queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, int fence) override; + int dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, int* fence) override; + int cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer) override; + + int getHostHandle(EGLClientBuffer buffer, Gralloc*) override; + + EGLNativeWindowType createNativeWindowForTesting(Gralloc* gralloc, uint32_t width, + uint32_t height) override; +}; + +} // namespace gfxstream diff --git a/guest/android/ANativeWindowStub.cpp b/guest/android/ANativeWindowStub.cpp new file mode 100644 index 00000000..4d613b9a --- /dev/null +++ b/guest/android/ANativeWindowStub.cpp @@ -0,0 +1,21 @@ +// Copyright 2024 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 expresso or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "gfxstream/guest/ANativeWindow.h" + +namespace gfxstream { + +ANativeWindowHelper* createPlatformANativeWindowHelper() { return nullptr; } + +} // namespace gfxstream
\ No newline at end of file diff --git a/guest/android/Android.bp b/guest/android/Android.bp new file mode 100644 index 00000000..48465972 --- /dev/null +++ b/guest/android/Android.bp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2024 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. + */ + +package { + // See: http://go/android-license-faq + default_applicable_licenses: ["hardware_google_gfxstream_license"], +} + +cc_defaults { + name: "libgfxstream_guest_android_defaults", + defaults: [ + "libgfxstream_guest_cc_defaults", + ], + host_supported: true, + vendor: true, + header_libs: [ + "gfxstream_opengl_headers", + ], + shared_libs: [ + "libcutils", + "libdrm", + "liblog", + "libutils", + ], + export_shared_lib_headers: [ + "libdrm", + ], + export_include_dirs: [ + "include" + ], + local_include_dirs: [ + ".", + "include", + ], +} + +cc_library_static { + name: "libgfxstream_guest_android", + defaults: [ + "libgfxstream_guest_android_defaults", + ], + static_libs: [ + "libplatform", + ], + target: { + android: { + header_libs: [ + "libnativebase_headers", + "libgralloc_cb.ranchu", + "minigbm_headers", + ], + shared_libs: [ + "lib_renderControl_enc", + "libnativewindow", + ], + srcs: [ + "ANativeWindowAndroid.cpp", + "Gralloc.cpp", + "GrallocGoldfish.cpp", + "GrallocMinigbm.cpp", + ], + }, + host: { + srcs: [ + "ANativeWindowStub.cpp", + "GrallocStub.cpp", + ], + }, + }, +} + +cc_library_static { + name: "libgfxstream_guest_android_with_host", + defaults: [ + "libgfxstream_guest_android_defaults", + ], + static_libs: [ + "libplatform_rutabaga", + ], + target: { + host: { + compile_multilib: "64", + }, + android: { + compile_multilib: "64", + }, + }, + srcs: [ + "ANativeWindowEmulated.cpp", + "GrallocEmulated.cpp", + ], +}
\ No newline at end of file diff --git a/guest/android/Gralloc.cpp b/guest/android/Gralloc.cpp new file mode 100644 index 00000000..500519db --- /dev/null +++ b/guest/android/Gralloc.cpp @@ -0,0 +1,39 @@ +// Copyright 2024 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 "gfxstream/guest/Gralloc.h" + +#if defined(__ANDROID__) + +#include <string> + +#include "GrallocGoldfish.h" +#include "GrallocMinigbm.h" +#include "android-base/properties.h" + +namespace gfxstream { + +Gralloc* createPlatformGralloc(int deviceFd) { + const std::string value = android::base::GetProperty("ro.hardware.gralloc", ""); + if (value == "minigbm") { + auto gralloc = new MinigbmGralloc(); + gralloc->setFd(deviceFd); + return gralloc; + } + return new GoldfishGralloc(); +} + +} // namespace gfxstream + +#endif
\ No newline at end of file diff --git a/guest/android/GrallocEmulated.cpp b/guest/android/GrallocEmulated.cpp new file mode 100644 index 00000000..e6031b16 --- /dev/null +++ b/guest/android/GrallocEmulated.cpp @@ -0,0 +1,204 @@ +// Copyright 2024 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 "GrallocEmulated.h" + +#include <cutils/log.h> + +#include <optional> + +#include "drm_fourcc.h" + +namespace gfxstream { +namespace { + +static constexpr int numFds = 0; +static constexpr int numInts = 1; + +std::optional<uint32_t> GlFormatToDrmFormat(uint32_t glFormat) { + switch (glFormat) { + case kGlRGB: + return DRM_FORMAT_BGR888; + case kGlRGB565: + return DRM_FORMAT_BGR565; + case kGlRGBA: + return DRM_FORMAT_ABGR8888; + } + return std::nullopt; +} + +std::optional<uint32_t> DrmToVirglFormat(uint32_t drmFormat) { + switch (drmFormat) { + case DRM_FORMAT_ABGR8888: + return VIRGL_FORMAT_B8G8R8A8_UNORM; + case DRM_FORMAT_BGR888: + return VIRGL_FORMAT_R8G8B8_UNORM; + case DRM_FORMAT_BGR565: + return VIRGL_FORMAT_B5G6R5_UNORM; + } + return std::nullopt; +} + +} // namespace + +EmulatedAHardwareBuffer::EmulatedAHardwareBuffer(uint32_t width, uint32_t height, + VirtGpuBlobPtr resource) + : mRefCount(1), mWidth(width), mHeight(height), mResource(resource) {} + +EmulatedAHardwareBuffer::~EmulatedAHardwareBuffer() {} + +uint32_t EmulatedAHardwareBuffer::getResourceId() const { return mResource->getResourceHandle(); } + +uint32_t EmulatedAHardwareBuffer::getWidth() const { return mWidth; } + +uint32_t EmulatedAHardwareBuffer::getHeight() const { return mHeight; } + +int EmulatedAHardwareBuffer::getAndroidFormat() const { + return /*AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM=*/1; +} + +uint32_t EmulatedAHardwareBuffer::getDrmFormat() const { return DRM_FORMAT_ABGR8888; } + +AHardwareBuffer* EmulatedAHardwareBuffer::asAHardwareBuffer() { + return reinterpret_cast<AHardwareBuffer*>(this); +} + +buffer_handle_t EmulatedAHardwareBuffer::asBufferHandle() { + return reinterpret_cast<buffer_handle_t>(this); +} + +EGLClientBuffer EmulatedAHardwareBuffer::asEglClientBuffer() { + return reinterpret_cast<EGLClientBuffer>(this); +} + +void EmulatedAHardwareBuffer::acquire() { ++mRefCount; } + +void EmulatedAHardwareBuffer::release() { + --mRefCount; + if (mRefCount == 0) { + delete this; + } +} + +EmulatedGralloc::EmulatedGralloc() {} + +uint32_t EmulatedGralloc::createColorBuffer(void*, int width, int height, uint32_t glFormat) { + auto drmFormat = GlFormatToDrmFormat(glFormat); + if (!drmFormat) { + ALOGE("Unhandled format"); + } + + auto ahb = allocate(width, height, *drmFormat); + + EmulatedAHardwareBuffer* rahb = reinterpret_cast<EmulatedAHardwareBuffer*>(ahb); + + mOwned.emplace_back(rahb); + + return rahb->getResourceId(); +} + +int EmulatedGralloc::allocate(uint32_t width, uint32_t height, uint32_t format, uint64_t usage, + AHardwareBuffer** outputAhb) { + (void)usage; + *outputAhb = allocate(width, height, format); + return 0; +} + +AHardwareBuffer* EmulatedGralloc::allocate(uint32_t width, uint32_t height, uint32_t format) { + ALOGE("Allocating AHB w:%u, h:%u, format %u", width, height, format); + + auto device = VirtGpuDevice::getInstance(); + if (!device) { + ALOGE("Failed to allocate: no virtio gpu device."); + return nullptr; + } + + auto virglFormat = DrmToVirglFormat(format); + if (!virglFormat) { + ALOGE("Unhandled DRM format:%u", format); + return nullptr; + } + + auto resource = device->createVirglBlob(width, height, *virglFormat); + if (!resource) { + ALOGE("Failed to allocate: failed to create virtio resource."); + return nullptr; + } + + resource->wait(); + + return reinterpret_cast<AHardwareBuffer*>( + new EmulatedAHardwareBuffer(width, height, std::move(resource))); +} + +void EmulatedGralloc::acquire(AHardwareBuffer* ahb) { + auto* rahb = reinterpret_cast<EmulatedAHardwareBuffer*>(ahb); + rahb->acquire(); +} + +void EmulatedGralloc::release(AHardwareBuffer* ahb) { + auto* rahb = reinterpret_cast<EmulatedAHardwareBuffer*>(ahb); + rahb->release(); +} + +uint32_t EmulatedGralloc::getHostHandle(const native_handle_t* handle) { + const auto* ahb = reinterpret_cast<const EmulatedAHardwareBuffer*>(handle); + return ahb->getResourceId(); +} + +uint32_t EmulatedGralloc::getHostHandle(const AHardwareBuffer* handle) { + const auto* ahb = reinterpret_cast<const EmulatedAHardwareBuffer*>(handle); + return ahb->getResourceId(); +} + +const native_handle_t* EmulatedGralloc::getNativeHandle(const AHardwareBuffer* ahb) { + return reinterpret_cast<const native_handle_t*>(ahb); +} + +int EmulatedGralloc::getFormat(const native_handle_t* handle) { + const auto* ahb = reinterpret_cast<const EmulatedAHardwareBuffer*>(handle); + return ahb->getAndroidFormat(); +} + +int EmulatedGralloc::getFormat(const AHardwareBuffer* handle) { + const auto* ahb = reinterpret_cast<const EmulatedAHardwareBuffer*>(handle); + return ahb->getAndroidFormat(); +} + +uint32_t EmulatedGralloc::getFormatDrmFourcc(const AHardwareBuffer* handle) { + const auto* ahb = reinterpret_cast<const EmulatedAHardwareBuffer*>(handle); + return ahb->getDrmFormat(); +} + +size_t EmulatedGralloc::getAllocatedSize(const native_handle_t*) { + ALOGE("Unimplemented."); + return 0; +} + +size_t EmulatedGralloc::getAllocatedSize(const AHardwareBuffer*) { + ALOGE("Unimplemented."); + return 0; +} + +int EmulatedGralloc::getId(const AHardwareBuffer* ahb, uint64_t* id) { + const auto* rahb = reinterpret_cast<const EmulatedAHardwareBuffer*>(ahb); + *id = rahb->getResourceId(); + return 0; +} + +Gralloc* createPlatformGralloc(int /*deviceFd*/) { + return new EmulatedGralloc(); +} + +} // namespace gfxstream diff --git a/guest/android/GrallocEmulated.h b/guest/android/GrallocEmulated.h new file mode 100644 index 00000000..8a48fef7 --- /dev/null +++ b/guest/android/GrallocEmulated.h @@ -0,0 +1,91 @@ +// Copyright 2024 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 <cstdint> +#include <memory> +#include <vector> + +#include "gfxstream/guest/Gralloc.h" +#include "VirtGpu.h" + +namespace gfxstream { + +using EGLClientBuffer = void*; + +class EmulatedAHardwareBuffer { + public: + EmulatedAHardwareBuffer(uint32_t width, uint32_t height, VirtGpuBlobPtr resource); + + ~EmulatedAHardwareBuffer(); + + uint32_t getResourceId() const; + + uint32_t getWidth() const; + + uint32_t getHeight() const; + + int getAndroidFormat() const; + + uint32_t getDrmFormat() const; + + AHardwareBuffer* asAHardwareBuffer(); + + buffer_handle_t asBufferHandle(); + + EGLClientBuffer asEglClientBuffer(); + + void acquire(); + void release(); + + private: + uint32_t mRefCount; + uint32_t mWidth; + uint32_t mHeight; + VirtGpuBlobPtr mResource; +}; + +class EmulatedGralloc : public Gralloc { + public: + EmulatedGralloc(); + + uint32_t createColorBuffer(void*, int width, int height, uint32_t glFormat) override; + + int allocate(uint32_t width, uint32_t height, uint32_t format, uint64_t usage, + AHardwareBuffer** outputAhb) override; + + AHardwareBuffer* allocate(uint32_t width, uint32_t height, uint32_t format); + + void acquire(AHardwareBuffer* ahb) override; + void release(AHardwareBuffer* ahb) override; + + uint32_t getHostHandle(const native_handle_t* handle) override; + uint32_t getHostHandle(const AHardwareBuffer* handle) override; + + const native_handle_t* getNativeHandle(const AHardwareBuffer* ahb) override; + + int getFormat(const native_handle_t* handle) override; + int getFormat(const AHardwareBuffer* handle) override; + + uint32_t getFormatDrmFourcc(const AHardwareBuffer* handle) override; + + size_t getAllocatedSize(const native_handle_t*) override; + size_t getAllocatedSize(const AHardwareBuffer*) override; + + int getId(const AHardwareBuffer* ahb, uint64_t* id) override; + + private: + std::vector<std::unique_ptr<EmulatedAHardwareBuffer>> mOwned; +}; + +} // namespace gfxstream diff --git a/guest/OpenglSystemCommon/GrallocGoldfish.cpp b/guest/android/GrallocGoldfish.cpp index b32562a6..f07abde9 100644 --- a/guest/OpenglSystemCommon/GrallocGoldfish.cpp +++ b/guest/android/GrallocGoldfish.cpp @@ -21,18 +21,13 @@ namespace gfxstream { -uint32_t GoldfishGralloc::createColorBuffer(void* rcEnc, int width, - int height, uint32_t glformat) { +uint32_t GoldfishGralloc::createColorBuffer(void* rcEnc, int width, int height, uint32_t glformat) { auto* rc = reinterpret_cast<renderControl_client_context_t*>(rcEnc); return rc->rcCreateColorBuffer(rc, width, height, glformat); } -int GoldfishGralloc::allocate(uint32_t width, - uint32_t height, - uint32_t format, - uint64_t usage, - AHardwareBuffer** outputAhb) { - +int GoldfishGralloc::allocate(uint32_t width, uint32_t height, uint32_t format, uint64_t usage, + AHardwareBuffer** outputAhb) { struct AHardwareBuffer_Desc desc = { .width = width, .height = height, @@ -44,13 +39,9 @@ int GoldfishGralloc::allocate(uint32_t width, return AHardwareBuffer_allocate(&desc, outputAhb); } -void GoldfishGralloc::acquire(AHardwareBuffer* ahb) { - AHardwareBuffer_acquire(ahb); -} +void GoldfishGralloc::acquire(AHardwareBuffer* ahb) { AHardwareBuffer_acquire(ahb); } -void GoldfishGralloc::release(AHardwareBuffer* ahb) { - AHardwareBuffer_release(ahb); -} +void GoldfishGralloc::release(AHardwareBuffer* ahb) { AHardwareBuffer_release(ahb); } uint32_t GoldfishGralloc::getHostHandle(native_handle_t const* handle) { return cb_handle_t::from(handle)->hostHandle; @@ -61,6 +52,10 @@ uint32_t GoldfishGralloc::getHostHandle(const AHardwareBuffer* ahb) { return getHostHandle(handle); } +const native_handle_t* GoldfishGralloc::getNativeHandle(const AHardwareBuffer* ahb) { + return AHardwareBuffer_getNativeHandle(ahb); +} + int GoldfishGralloc::getFormat(const native_handle_t* handle) { return cb_handle_t::from(handle)->format; } @@ -79,6 +74,16 @@ size_t GoldfishGralloc::getAllocatedSize(const AHardwareBuffer* ahb) { return getAllocatedSize(handle); } +int GoldfishGralloc::getId(const AHardwareBuffer* ahb, uint64_t* id) { +#if ANDROID_API_LEVEL >= 31 + return AHardwareBuffer_getId(ahb, id); +#else + (void)ahb; + *id = 0; + return 0; +#endif +} + bool GoldfishGralloc::treatBlobAsImage() { return true; } } // namespace gfxstream diff --git a/guest/OpenglSystemCommon/GrallocGoldfish.h b/guest/android/GrallocGoldfish.h index 2d7b9faf..560550ff 100644 --- a/guest/OpenglSystemCommon/GrallocGoldfish.h +++ b/guest/android/GrallocGoldfish.h @@ -14,19 +14,15 @@ #pragma once -#include "Gralloc.h" +#include "gfxstream/guest/Gralloc.h" namespace gfxstream { class GoldfishGralloc : public Gralloc { public: - uint32_t createColorBuffer(void* rcEnc, int width, int height, - uint32_t glformat) override; + uint32_t createColorBuffer(void* rcEnc, int width, int height, uint32_t glformat) override; - int allocate(uint32_t width, - uint32_t height, - uint32_t format, - uint64_t usage, + int allocate(uint32_t width, uint32_t height, uint32_t format, uint64_t usage, AHardwareBuffer** outputAhb) override; void acquire(AHardwareBuffer* ahb) override; @@ -35,14 +31,17 @@ class GoldfishGralloc : public Gralloc { uint32_t getHostHandle(native_handle_t const* handle) override; uint32_t getHostHandle(const AHardwareBuffer* handle) override; + const native_handle_t* getNativeHandle(const AHardwareBuffer* ahb) override; + int getFormat(const native_handle_t* handle) override; int getFormat(const AHardwareBuffer* handle) override; size_t getAllocatedSize(const native_handle_t* handle) override; size_t getAllocatedSize(const AHardwareBuffer* handle) override; + int getId(const AHardwareBuffer* ahb, uint64_t* id) override; + bool treatBlobAsImage() override; }; - } // namespace gfxstream diff --git a/guest/OpenglSystemCommon/GrallocMinigbm.cpp b/guest/android/GrallocMinigbm.cpp index a4057c89..a3daf433 100644 --- a/guest/OpenglSystemCommon/GrallocMinigbm.cpp +++ b/guest/android/GrallocMinigbm.cpp @@ -14,16 +14,16 @@ #include "GrallocMinigbm.h" -#include <cinttypes> -#include <cstring> -#include <stdlib.h> - #include <cros_gralloc/cros_gralloc_handle.h> #include <errno.h> #include <log/log.h> +#include <stdlib.h> #include <sys/user.h> -#include <xf86drm.h> #include <vndk/hardware_buffer.h> +#include <xf86drm.h> + +#include <cinttypes> +#include <cstring> #include "virtgpu_drm.h" @@ -34,7 +34,6 @@ constexpr size_t kPageSize = PAGE_SIZE; static const size_t kPageSize = getpagesize(); #endif - namespace gfxstream { namespace { @@ -61,8 +60,7 @@ bool getVirtioGpuResourceInfo(int fd, native_handle_t const* handle, return false; } struct ManagedDrmGem { - ManagedDrmGem(int fd, uint32_t handle) - : m_fd(fd), m_prime_handle(handle) {} + ManagedDrmGem(int fd, uint32_t handle) : m_fd(fd), m_prime_handle(handle) {} ManagedDrmGem(const ManagedDrmGem&) = delete; ~ManagedDrmGem() { struct drm_gem_close gem_close { @@ -114,8 +112,7 @@ bool getVirtioGpuResourceInfo(int fd, native_handle_t const* handle, } // namespace -uint32_t MinigbmGralloc::createColorBuffer(void*, int width, int height, - uint32_t glformat) { +uint32_t MinigbmGralloc::createColorBuffer(void*, int width, int height, uint32_t glformat) { // Only supported format for pbuffers in gfxstream should be RGBA8 const uint32_t kVirglFormatRGBA = 67; // VIRGL_FORMAT_R8G8B8A8_UNORM; uint32_t virtgpu_format = 0; @@ -162,12 +159,8 @@ uint32_t MinigbmGralloc::createColorBuffer(void*, int width, int height, return res_create.res_handle; } -int MinigbmGralloc::allocate(uint32_t width, - uint32_t height, - uint32_t format, - uint64_t usage, +int MinigbmGralloc::allocate(uint32_t width, uint32_t height, uint32_t format, uint64_t usage, AHardwareBuffer** outputAhb) { - struct AHardwareBuffer_Desc desc = { .width = width, .height = height, @@ -179,13 +172,9 @@ int MinigbmGralloc::allocate(uint32_t width, return AHardwareBuffer_allocate(&desc, outputAhb); } -void MinigbmGralloc::acquire(AHardwareBuffer* ahb) { - AHardwareBuffer_acquire(ahb); -} +void MinigbmGralloc::acquire(AHardwareBuffer* ahb) { AHardwareBuffer_acquire(ahb); } -void MinigbmGralloc::release(AHardwareBuffer* ahb) { - AHardwareBuffer_release(ahb); -} +void MinigbmGralloc::release(AHardwareBuffer* ahb) { AHardwareBuffer_release(ahb); } uint32_t MinigbmGralloc::getHostHandle(const native_handle_t* handle) { struct drm_virtgpu_resource_info info; @@ -202,6 +191,10 @@ uint32_t MinigbmGralloc::getHostHandle(const AHardwareBuffer* ahb) { return getHostHandle(handle); } +const native_handle_t* MinigbmGralloc::getNativeHandle(const AHardwareBuffer* ahb) { + return AHardwareBuffer_getNativeHandle(ahb); +} + int MinigbmGralloc::getFormat(const native_handle_t* handle) { return ((cros_gralloc_handle*)handle)->droid_format; } @@ -235,4 +228,14 @@ size_t MinigbmGralloc::getAllocatedSize(const AHardwareBuffer* ahb) { return getAllocatedSize(handle); } +int MinigbmGralloc::getId(const AHardwareBuffer* ahb, uint64_t* id) { +#if ANDROID_API_LEVEL >= 31 + return AHardwareBuffer_getId(ahb, id); +#else + (void)ahb; + *id = 0; + return 0; +#endif +} + } // namespace gfxstream diff --git a/guest/OpenglSystemCommon/GrallocMinigbm.h b/guest/android/GrallocMinigbm.h index d165a033..c02aaebd 100644 --- a/guest/OpenglSystemCommon/GrallocMinigbm.h +++ b/guest/android/GrallocMinigbm.h @@ -14,19 +14,15 @@ #pragma once -#include "Gralloc.h" +#include "gfxstream/guest/Gralloc.h" namespace gfxstream { class MinigbmGralloc : public Gralloc { public: - uint32_t createColorBuffer(void* rcEnc, int width, int height, - uint32_t glformat) override; + uint32_t createColorBuffer(void* rcEnc, int width, int height, uint32_t glformat) override; - int allocate(uint32_t width, - uint32_t height, - uint32_t format, - uint64_t usage, + int allocate(uint32_t width, uint32_t height, uint32_t format, uint64_t usage, AHardwareBuffer** outputAhb) override; void acquire(AHardwareBuffer* ahb) override; @@ -35,6 +31,8 @@ class MinigbmGralloc : public Gralloc { uint32_t getHostHandle(native_handle_t const* handle) override; uint32_t getHostHandle(const AHardwareBuffer* handle) override; + const native_handle_t* getNativeHandle(const AHardwareBuffer* ahb) override; + int getFormat(const native_handle_t* handle) override; int getFormat(const AHardwareBuffer* handle) override; @@ -44,6 +42,8 @@ class MinigbmGralloc : public Gralloc { size_t getAllocatedSize(const native_handle_t* handle) override; size_t getAllocatedSize(const AHardwareBuffer* handle) override; + int getId(const AHardwareBuffer* ahb, uint64_t* id) override; + void setFd(int fd) { m_fd = fd; } private: diff --git a/guest/android/GrallocStub.cpp b/guest/android/GrallocStub.cpp new file mode 100644 index 00000000..e92faff5 --- /dev/null +++ b/guest/android/GrallocStub.cpp @@ -0,0 +1,21 @@ +// Copyright 2024 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 expresso or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "gfxstream/guest/Gralloc.h" + +namespace gfxstream { + +Gralloc* createPlatformGralloc(int) { return nullptr; } + +} // namespace gfxstream
\ No newline at end of file diff --git a/guest/OpenglSystemCommon/ANativeWindow.h b/guest/android/include/gfxstream/guest/ANativeWindow.h index a50d9c29..0c59d192 100644 --- a/guest/OpenglSystemCommon/ANativeWindow.h +++ b/guest/android/include/gfxstream/guest/ANativeWindow.h @@ -14,23 +14,27 @@ #pragma once +#if defined(ANDROID) + #include <EGL/egl.h> #include <EGL/eglext.h> #include "Gralloc.h" +using EGLClientBuffer = void*; + namespace gfxstream { // Abstraction around libnativewindow to support testing. class ANativeWindowHelper { - public: + public: virtual ~ANativeWindowHelper() {} virtual bool isValid(EGLNativeWindowType window) = 0; virtual bool isValid(EGLClientBuffer buffer) = 0; virtual void acquire(EGLNativeWindowType window) = 0; - virtual void release(EGLNativeWindowType window)= 0; + virtual void release(EGLNativeWindowType window) = 0; virtual void acquire(EGLClientBuffer buffer) = 0; virtual void release(EGLClientBuffer buffer) = 0; @@ -51,6 +55,16 @@ class ANativeWindowHelper { virtual int queueBuffer(EGLNativeWindowType window, EGLClientBuffer buffer, int fence) = 0; virtual int dequeueBuffer(EGLNativeWindowType window, EGLClientBuffer* buffer, int* fence) = 0; virtual int cancelBuffer(EGLNativeWindowType window, EGLClientBuffer buffer) = 0; + + virtual EGLNativeWindowType createNativeWindowForTesting(Gralloc* /*gralloc*/, + uint32_t /*width*/, + uint32_t /*height*/) { + return (EGLNativeWindowType)0; + } }; +ANativeWindowHelper* createPlatformANativeWindowHelper(); + } // namespace gfxstream + +#endif // defined(ANDROID)
\ No newline at end of file diff --git a/guest/OpenglSystemCommon/Gralloc.h b/guest/android/include/gfxstream/guest/Gralloc.h index 1758c000..5eb91390 100644 --- a/guest/OpenglSystemCommon/Gralloc.h +++ b/guest/android/include/gfxstream/guest/Gralloc.h @@ -14,10 +14,11 @@ #pragma once -#include <stddef.h> -#include <stdint.h> +#if defined(ANDROID) #include <cutils/native_handle.h> +#include <stddef.h> +#include <stdint.h> typedef struct AHardwareBuffer AHardwareBuffer; @@ -32,18 +33,16 @@ class Gralloc { public: virtual ~Gralloc() {} - virtual uint32_t createColorBuffer(void* rcEnc, int width, int height, - uint32_t glformat) = 0; + virtual uint32_t createColorBuffer(void* rcEnc, int width, int height, uint32_t glformat) = 0; virtual void acquire(AHardwareBuffer* ahb) = 0; virtual void release(AHardwareBuffer* ahb) = 0; - virtual int allocate(uint32_t width, - uint32_t height, - uint32_t format, - uint64_t usage, + virtual int allocate(uint32_t width, uint32_t height, uint32_t format, uint64_t usage, AHardwareBuffer** outputAhb) = 0; + virtual const native_handle_t* getNativeHandle(const AHardwareBuffer* ahb) = 0; + virtual uint32_t getHostHandle(const native_handle_t* handle) = 0; virtual uint32_t getHostHandle(const AHardwareBuffer* handle) = 0; @@ -62,7 +61,13 @@ class Gralloc { virtual size_t getAllocatedSize(const native_handle_t* handle) = 0; virtual size_t getAllocatedSize(const AHardwareBuffer* handle) = 0; + virtual int getId(const AHardwareBuffer* ahb, uint64_t* id) = 0; + virtual bool treatBlobAsImage() { return false; } }; +Gralloc* createPlatformGralloc(int deviceFd = -1); + } // namespace gfxstream + +#endif // defined(ANDROID)
\ No newline at end of file diff --git a/guest/egl/Android.bp b/guest/egl/Android.bp index 7a1819b3..3b071224 100644 --- a/guest/egl/Android.bp +++ b/guest/egl/Android.bp @@ -89,8 +89,6 @@ cc_library_shared { ], shared_libs: [ "libOpenglSystemCommonWithHost", - "libplatform_rutabaga", - "libgfxstream_backend", ], target: { host: { diff --git a/guest/platform/Android.bp b/guest/platform/Android.bp index 9ecc24e0..e3561243 100644 --- a/guest/platform/Android.bp +++ b/guest/platform/Android.bp @@ -19,10 +19,19 @@ package { default_applicable_licenses: ["hardware_google_gfxstream_license"], } +cc_library_headers { + name: "libplatform_headers", + host_supported: true, + vendor_available: true, + export_include_dirs: [ + "include" + ], +} + cc_library_static { name: "libplatform", host_supported: true, - vendor_available: true, + vendor: true, srcs: [ "VirtGpu.cpp", "linux/LinuxVirtGpuBlob.cpp", @@ -56,17 +65,46 @@ cc_library_static { shared_libs: [ "libsync", ], - } - } + }, + }, } cc_library_shared { + name: "libplatform_rutabaga_server", + host_supported: true, + vendor_available: true, + srcs: [ + "rutabaga/RutabagaLayer.cpp", + ], + header_libs: [ + "libplatform_headers", + ], + shared_libs: [ + "libcutils", + "libgfxstream_backend", + "liblog", + "libutils", + ], + export_include_dirs: [ + // TODO: restrict to just RutabagaLayer.h + "rutabaga/include", + ], + target: { + host: { + compile_multilib: "64", + }, + android: { + compile_multilib: "64", + }, + }, +} + +cc_library_static { name: "libplatform_rutabaga", host_supported: true, vendor_available: true, srcs: [ "VirtGpu.cpp", - "rutabaga/RutabagaLayer.cpp", "rutabaga/RutabagaVirtGpuBlob.cpp", "rutabaga/RutabagaVirtGpuBlobMapping.cpp", "rutabaga/RutabagaVirtGpuDevice.cpp", @@ -75,7 +113,7 @@ cc_library_shared { shared_libs: [ "libcutils", "libdrm", - "libgfxstream_backend", + "libplatform_rutabaga_server", "liblog", "libutils", ], diff --git a/guest/platform/rutabaga/RutabagaLayer.cpp b/guest/platform/rutabaga/RutabagaLayer.cpp index 5017a9a0..fb225f9b 100644 --- a/guest/platform/rutabaga/RutabagaLayer.cpp +++ b/guest/platform/rutabaga/RutabagaLayer.cpp @@ -929,55 +929,62 @@ void EmulatedVirtioGpu::EmulatedVirtioGpuImpl::RunVirtioGpuTaskProcessingLoop() } } +EmulatedVirtioGpu::EmulatedVirtioGpu() + : mImpl{std::make_unique<EmulatedVirtioGpu::EmulatedVirtioGpuImpl>()} {} + namespace { -EmulatedVirtioGpu* sInstance = nullptr; +static std::mutex sInstanceMutex; +static std::weak_ptr<EmulatedVirtioGpu> sInstance; } // namespace -EmulatedVirtioGpu::EmulatedVirtioGpu() - : mImpl{std::make_unique<EmulatedVirtioGpu::EmulatedVirtioGpuImpl>()} {} - /*static*/ -EmulatedVirtioGpu& EmulatedVirtioGpu::Get() { - if (sInstance == nullptr) { - sInstance = new EmulatedVirtioGpu(); +std::shared_ptr<EmulatedVirtioGpu> EmulatedVirtioGpu::Get() { + std::lock_guard<std::mutex> lock(sInstanceMutex); - bool withGl = false; - bool withVk = true; - bool withVkSnapshots = false; + std::shared_ptr<EmulatedVirtioGpu> instance = sInstance.lock(); + if (instance != nullptr) { + return instance; + } - struct Option { - std::string env; - bool* val; - }; - const std::vector<Option> options = { - {"GFXSTREAM_EMULATED_VIRTIO_GPU_WITH_GL", &withGl}, - {"GFXSTREAM_EMULATED_VIRTIO_GPU_WITH_VK", &withVk}, - {"GFXSTREAM_EMULATED_VIRTIO_GPU_WITH_VK_SNAPSHOTS", &withVkSnapshots}, - }; - for (const Option option : options) { - const char* val = std::getenv(option.env.c_str()); - if (val != nullptr && (val[0] == 'Y' || val[0] == 'y')) { - *option.val = true; - } - } + instance = std::shared_ptr<EmulatedVirtioGpu>(new EmulatedVirtioGpu()); + + bool withGl = false; + bool withVk = true; + bool withVkSnapshots = false; - ALOGE("Initializing withGl:%d withVk:%d withVkSnapshots:%d", withGl, withVk, - withVkSnapshots); - if (!sInstance->Init(withGl, withVk, withVkSnapshots)) { - ALOGE("Failed to initialize EmulatedVirtioGpu."); + struct Option { + std::string env; + bool* val; + }; + const std::vector<Option> options = { + {"GFXSTREAM_EMULATED_VIRTIO_GPU_WITH_GL", &withGl}, + {"GFXSTREAM_EMULATED_VIRTIO_GPU_WITH_VK", &withVk}, + {"GFXSTREAM_EMULATED_VIRTIO_GPU_WITH_VK_SNAPSHOTS", &withVkSnapshots}, + }; + for (const Option option : options) { + const char* val = std::getenv(option.env.c_str()); + if (val != nullptr && (val[0] == 'Y' || val[0] == 'y')) { + *option.val = true; } } - return *sInstance; + + ALOGE("Initializing withGl:%d withVk:%d withVkSnapshots:%d", withGl, withVk, withVkSnapshots); + if (!instance->Init(withGl, withVk, withVkSnapshots)) { + ALOGE("Failed to initialize EmulatedVirtioGpu."); + return nullptr; + } + ALOGE("Successfully initialized EmulatedVirtioGpu."); + sInstance = instance; + return instance; } /*static*/ -void EmulatedVirtioGpu::Reset() { - if (sInstance != nullptr) { - delete sInstance; - sInstance = nullptr; - } +uint32_t EmulatedVirtioGpu::GetNumActiveUsers() { + std::lock_guard<std::mutex> lock(sInstanceMutex); + std::shared_ptr<EmulatedVirtioGpu> instance = sInstance.lock(); + return instance.use_count(); } bool EmulatedVirtioGpu::Init(bool withGl, bool withVk, bool withVkSnapshots) { @@ -1031,6 +1038,6 @@ int EmulatedVirtioGpu::WaitOnEmulatedFence(int fenceAsFileDescriptor, int timeou void EmulatedVirtioGpu::SignalEmulatedFence(int fenceId) { mImpl->SignalEmulatedFence(fenceId); } -void ResetEmulatedVirtioGpu() { EmulatedVirtioGpu::Reset(); } +bool GetNumActiveEmulatedVirtioGpuUsers() { return EmulatedVirtioGpu::GetNumActiveUsers(); } } // namespace gfxstream diff --git a/guest/platform/rutabaga/RutabagaLayer.h b/guest/platform/rutabaga/RutabagaLayer.h index 057b2f75..7c6443b7 100644 --- a/guest/platform/rutabaga/RutabagaLayer.h +++ b/guest/platform/rutabaga/RutabagaLayer.h @@ -19,6 +19,8 @@ #include <memory> #include <optional> +// TODO: switch to virtgpu_drm.h to avoid circular dep between +// libplatform_rutabaga and libplatform_rutabaga_server. #include "VirtGpu.h" namespace gfxstream { @@ -28,47 +30,38 @@ namespace gfxstream { // host server via rutabaga. class EmulatedVirtioGpu { public: - static EmulatedVirtioGpu& Get(); - static void Reset(); + static std::shared_ptr<EmulatedVirtioGpu> Get(); + static uint32_t GetNumActiveUsers(); - bool Init(bool withGl, bool withVk, bool withVkSnapshots); + bool Init(bool withGl, bool withVk, bool withVkSnapshots); - VirtGpuCaps GetCaps(VirtGpuCapset capset); + VirtGpuCaps GetCaps(VirtGpuCapset capset); - std::optional<uint32_t> CreateContext(); - void DestroyContext(uint32_t contextId); + std::optional<uint32_t> CreateContext(); + void DestroyContext(uint32_t contextId); - std::optional<uint32_t> CreateBlob(uint32_t contextId, - const struct VirtGpuCreateBlob& params); - std::optional<uint32_t> CreateVirglBlob(uint32_t contextId, - uint32_t width, - uint32_t height, - uint32_t virglFormat); + std::optional<uint32_t> CreateBlob(uint32_t contextId, const struct VirtGpuCreateBlob& params); + std::optional<uint32_t> CreateVirglBlob(uint32_t contextId, uint32_t width, uint32_t height, + uint32_t virglFormat); - void DestroyResource(uint32_t contextId, - uint32_t resourceId); + void DestroyResource(uint32_t contextId, uint32_t resourceId); - uint8_t* Map(uint32_t resourceId); - void Unmap(uint32_t resourceId); + uint8_t* Map(uint32_t resourceId); + void Unmap(uint32_t resourceId); - int ExecBuffer(uint32_t contextId, - struct VirtGpuExecBuffer& execbuffer, - std::optional<uint32_t> blobResourceId); + int ExecBuffer(uint32_t contextId, struct VirtGpuExecBuffer& execbuffer, + std::optional<uint32_t> blobResourceId); - int Wait(uint32_t resourceId); + int Wait(uint32_t resourceId); - int TransferFromHost(uint32_t contextId, - uint32_t resourceId, - uint32_t transferOffset, - uint32_t transferSize); - int TransferToHost(uint32_t contextId, - uint32_t resourceId, - uint32_t transferOffset, - uint32_t transferSize); + int TransferFromHost(uint32_t contextId, uint32_t resourceId, uint32_t transferOffset, + uint32_t transferSize); + int TransferToHost(uint32_t contextId, uint32_t resourceId, uint32_t transferOffset, + uint32_t transferSize); - void SignalEmulatedFence(int fenceId); + void SignalEmulatedFence(int fenceId); - int WaitOnEmulatedFence(int fenceAsFileDescriptor, int timeoutMilliseconds); + int WaitOnEmulatedFence(int fenceAsFileDescriptor, int timeoutMilliseconds); private: EmulatedVirtioGpu(); diff --git a/guest/platform/rutabaga/RutabagaVirtGpu.h b/guest/platform/rutabaga/RutabagaVirtGpu.h index 8cf07f5f..64568ab5 100644 --- a/guest/platform/rutabaga/RutabagaVirtGpu.h +++ b/guest/platform/rutabaga/RutabagaVirtGpu.h @@ -28,14 +28,16 @@ class RutabagaVirtGpuDevice; class RutabagaVirtGpuBlobMapping : public VirtGpuBlobMapping { public: - RutabagaVirtGpuBlobMapping(VirtGpuBlobPtr blob, uint8_t* mapped); - ~RutabagaVirtGpuBlobMapping(); + RutabagaVirtGpuBlobMapping(std::shared_ptr<EmulatedVirtioGpu> emulation, VirtGpuBlobPtr blob, + uint8_t* mapped); + ~RutabagaVirtGpuBlobMapping(); - uint8_t* asRawPtr(void) override; + uint8_t* asRawPtr(void) override; private: - VirtGpuBlobPtr mBlob; - uint8_t* mMapped = nullptr; + const std::shared_ptr<EmulatedVirtioGpu> mEmulation; + const VirtGpuBlobPtr mBlob; + uint8_t* mMapped = nullptr; }; class RutabagaVirtGpuResource : public std::enable_shared_from_this<RutabagaVirtGpuResource>, public VirtGpuBlob { @@ -61,11 +63,10 @@ class RutabagaVirtGpuResource : public std::enable_shared_from_this<RutabagaVirt kPipe, }; - RutabagaVirtGpuResource(uint32_t resourceId, - ResourceType resourceType, - uint32_t contextId); - + RutabagaVirtGpuResource(std::shared_ptr<EmulatedVirtioGpu> emulation, uint32_t resourceId, + ResourceType resourceType, uint32_t contextId); + const std::shared_ptr<EmulatedVirtioGpu> mEmulation; const uint32_t mContextId; const uint32_t mResourceId; const ResourceType mResourceType; @@ -73,27 +74,29 @@ class RutabagaVirtGpuResource : public std::enable_shared_from_this<RutabagaVirt class RutabagaVirtGpuDevice : public std::enable_shared_from_this<RutabagaVirtGpuDevice>, public VirtGpuDevice { public: - RutabagaVirtGpuDevice(uint32_t contextId, VirtGpuCapset capset); - ~RutabagaVirtGpuDevice(); + RutabagaVirtGpuDevice(std::shared_ptr<EmulatedVirtioGpu> emulation, uint32_t contextId, + VirtGpuCapset capset); + ~RutabagaVirtGpuDevice(); - int64_t getDeviceHandle() override; + int64_t getDeviceHandle() override; - VirtGpuCaps getCaps() override; + VirtGpuCaps getCaps() override; - VirtGpuBlobPtr createBlob(const struct VirtGpuCreateBlob& blobCreate) override; + VirtGpuBlobPtr createBlob(const struct VirtGpuCreateBlob& blobCreate) override; - VirtGpuBlobPtr createVirglBlob(uint32_t width, uint32_t height, uint32_t virglFormat) override; + VirtGpuBlobPtr createVirglBlob(uint32_t width, uint32_t height, uint32_t virglFormat) override; - VirtGpuBlobPtr importBlob(const struct VirtGpuExternalHandle& handle) override; + VirtGpuBlobPtr importBlob(const struct VirtGpuExternalHandle& handle) override; - int execBuffer(struct VirtGpuExecBuffer& execbuffer, const VirtGpuBlob* blob) override; + int execBuffer(struct VirtGpuExecBuffer& execbuffer, const VirtGpuBlob* blob) override; - private: - const uint32_t mContextId; - const VirtGpuCapset mCapset; + private: + const std::shared_ptr<EmulatedVirtioGpu> mEmulation; + const uint32_t mContextId; + const VirtGpuCapset mCapset; - friend class RutabagaVirtGpuResource; - uint32_t GetContextId() const { return mContextId; } + friend class RutabagaVirtGpuResource; + uint32_t GetContextId() const { return mContextId; } }; } // namespace gfxstream diff --git a/guest/platform/rutabaga/RutabagaVirtGpuBlob.cpp b/guest/platform/rutabaga/RutabagaVirtGpuBlob.cpp index 0b7db44d..6f97ffb7 100644 --- a/guest/platform/rutabaga/RutabagaVirtGpuBlob.cpp +++ b/guest/platform/rutabaga/RutabagaVirtGpuBlob.cpp @@ -21,17 +21,21 @@ namespace gfxstream { -RutabagaVirtGpuResource::RutabagaVirtGpuResource(uint32_t resourceId, ResourceType resourceType, +RutabagaVirtGpuResource::RutabagaVirtGpuResource(std::shared_ptr<EmulatedVirtioGpu> emulation, + uint32_t resourceId, ResourceType resourceType, uint32_t contextId) - : mContextId(contextId), mResourceId(resourceId), mResourceType(resourceType) {} + : mEmulation(emulation), + mContextId(contextId), + mResourceId(resourceId), + mResourceType(resourceType) {} RutabagaVirtGpuResource::~RutabagaVirtGpuResource() { - EmulatedVirtioGpu::Get().DestroyResource(mContextId, mResourceId); + mEmulation->DestroyResource(mContextId, mResourceId); } VirtGpuBlobMappingPtr RutabagaVirtGpuResource::createMapping(void) { - uint8_t* mapped = EmulatedVirtioGpu::Get().Map(mResourceId); - return std::make_shared<RutabagaVirtGpuBlobMapping>(shared_from_this(), mapped); + uint8_t* mapped = mEmulation->Map(mResourceId); + return std::make_shared<RutabagaVirtGpuBlobMapping>(mEmulation, shared_from_this(), mapped); } uint32_t RutabagaVirtGpuResource::getResourceHandle() const { return mResourceId; } @@ -56,7 +60,7 @@ int RutabagaVirtGpuResource::exportBlob(VirtGpuExternalHandle&) { return -1; } -int RutabagaVirtGpuResource::wait() { return EmulatedVirtioGpu::Get().Wait(mResourceId); } +int RutabagaVirtGpuResource::wait() { return mEmulation->Wait(mResourceId); } int RutabagaVirtGpuResource::transferFromHost(uint32_t offset, uint32_t size) { if (mResourceType != ResourceType::kPipe) { @@ -64,7 +68,7 @@ int RutabagaVirtGpuResource::transferFromHost(uint32_t offset, uint32_t size) { return -1; } - return EmulatedVirtioGpu::Get().TransferFromHost(mContextId, mResourceId, offset, size); + return mEmulation->TransferFromHost(mContextId, mResourceId, offset, size); } int RutabagaVirtGpuResource::transferToHost(uint32_t offset, uint32_t size) { @@ -73,7 +77,7 @@ int RutabagaVirtGpuResource::transferToHost(uint32_t offset, uint32_t size) { return -1; } - return EmulatedVirtioGpu::Get().TransferToHost(mContextId, mResourceId, offset, size); + return mEmulation->TransferToHost(mContextId, mResourceId, offset, size); } } // namespace gfxstream diff --git a/guest/platform/rutabaga/RutabagaVirtGpuBlobMapping.cpp b/guest/platform/rutabaga/RutabagaVirtGpuBlobMapping.cpp index 4f82f7c4..750ddeed 100644 --- a/guest/platform/rutabaga/RutabagaVirtGpuBlobMapping.cpp +++ b/guest/platform/rutabaga/RutabagaVirtGpuBlobMapping.cpp @@ -19,11 +19,12 @@ namespace gfxstream { -RutabagaVirtGpuBlobMapping::RutabagaVirtGpuBlobMapping(VirtGpuBlobPtr blob, uint8_t* mapped) - : mBlob(blob), mMapped(mapped) {} +RutabagaVirtGpuBlobMapping::RutabagaVirtGpuBlobMapping(std::shared_ptr<EmulatedVirtioGpu> emulation, + VirtGpuBlobPtr blob, uint8_t* mapped) + : mEmulation(emulation), mBlob(blob), mMapped(mapped) {} RutabagaVirtGpuBlobMapping::~RutabagaVirtGpuBlobMapping(void) { - EmulatedVirtioGpu::Get().Unmap(mBlob->getResourceHandle()); + mEmulation->Unmap(mBlob->getResourceHandle()); } uint8_t* RutabagaVirtGpuBlobMapping::asRawPtr(void) { return mMapped; } diff --git a/guest/platform/rutabaga/RutabagaVirtGpuDevice.cpp b/guest/platform/rutabaga/RutabagaVirtGpuDevice.cpp index 999ac2ff..615e81ef 100644 --- a/guest/platform/rutabaga/RutabagaVirtGpuDevice.cpp +++ b/guest/platform/rutabaga/RutabagaVirtGpuDevice.cpp @@ -21,38 +21,35 @@ namespace gfxstream { -RutabagaVirtGpuDevice::RutabagaVirtGpuDevice(uint32_t contextId, VirtGpuCapset capset) - : VirtGpuDevice(capset), mContextId(contextId), mCapset(capset) {} +RutabagaVirtGpuDevice::RutabagaVirtGpuDevice(std::shared_ptr<EmulatedVirtioGpu> emulation, + uint32_t contextId, VirtGpuCapset capset) + : VirtGpuDevice(capset), mEmulation(emulation), mContextId(contextId), mCapset(capset) {} -RutabagaVirtGpuDevice::~RutabagaVirtGpuDevice() { - EmulatedVirtioGpu::Get().DestroyContext(mContextId); - EmulatedVirtioGpu::Reset(); -} +RutabagaVirtGpuDevice::~RutabagaVirtGpuDevice() { mEmulation->DestroyContext(mContextId); } int64_t RutabagaVirtGpuDevice::getDeviceHandle() { return -1; } -VirtGpuCaps RutabagaVirtGpuDevice::getCaps() { return EmulatedVirtioGpu::Get().GetCaps(mCapset); } +VirtGpuCaps RutabagaVirtGpuDevice::getCaps() { return mEmulation->GetCaps(mCapset); } VirtGpuBlobPtr RutabagaVirtGpuDevice::createBlob(const struct VirtGpuCreateBlob& blobCreate) { - const auto resourceIdOpt = EmulatedVirtioGpu::Get().CreateBlob(mContextId, blobCreate); + const auto resourceIdOpt = mEmulation->CreateBlob(mContextId, blobCreate); if (!resourceIdOpt) { return nullptr; } return VirtGpuBlobPtr(new RutabagaVirtGpuResource( - *resourceIdOpt, RutabagaVirtGpuResource::ResourceType::kBlob, mContextId)); + mEmulation, *resourceIdOpt, RutabagaVirtGpuResource::ResourceType::kBlob, mContextId)); } VirtGpuBlobPtr RutabagaVirtGpuDevice::createVirglBlob(uint32_t width, uint32_t height, uint32_t virglFormat) { - const auto resourceIdOpt = - EmulatedVirtioGpu::Get().CreateVirglBlob(mContextId, width, height, virglFormat); + const auto resourceIdOpt = mEmulation->CreateVirglBlob(mContextId, width, height, virglFormat); if (!resourceIdOpt) { return nullptr; } return VirtGpuBlobPtr(new RutabagaVirtGpuResource( - *resourceIdOpt, RutabagaVirtGpuResource::ResourceType::kPipe, mContextId)); + mEmulation, *resourceIdOpt, RutabagaVirtGpuResource::ResourceType::kPipe, mContextId)); } int RutabagaVirtGpuDevice::execBuffer(struct VirtGpuExecBuffer& execbuffer, @@ -61,7 +58,7 @@ int RutabagaVirtGpuDevice::execBuffer(struct VirtGpuExecBuffer& execbuffer, if (blob) { blobResourceId = blob->getResourceHandle(); } - return EmulatedVirtioGpu::Get().ExecBuffer(mContextId, execbuffer, blobResourceId); + return mEmulation->ExecBuffer(mContextId, execbuffer, blobResourceId); } VirtGpuBlobPtr RutabagaVirtGpuDevice::importBlob(const struct VirtGpuExternalHandle&) { @@ -72,10 +69,16 @@ VirtGpuBlobPtr RutabagaVirtGpuDevice::importBlob(const struct VirtGpuExternalHan } // namespace gfxstream VirtGpuDevice* createPlatformVirtGpuDevice(enum VirtGpuCapset capset, int) { - const auto contextIdOp = gfxstream::EmulatedVirtioGpu::Get().CreateContext(); + std::shared_ptr<gfxstream::EmulatedVirtioGpu> emulation = gfxstream::EmulatedVirtioGpu::Get(); + if (!emulation) { + ALOGE("Failed to create RutabagaVirtGpuDevice: failed to get emulation layer."); + return nullptr; + } + + const auto contextIdOp = emulation->CreateContext(); if (!contextIdOp) { ALOGE("Failed to create RutabagaVirtGpuDevice: failed to create context."); return nullptr; } - return new gfxstream::RutabagaVirtGpuDevice(*contextIdOp, capset); + return new gfxstream::RutabagaVirtGpuDevice(emulation, *contextIdOp, capset); } diff --git a/guest/platform/rutabaga/RutabagaVirtGpuSyncHelper.cpp b/guest/platform/rutabaga/RutabagaVirtGpuSyncHelper.cpp index 4ddaee23..2f97ea84 100644 --- a/guest/platform/rutabaga/RutabagaVirtGpuSyncHelper.cpp +++ b/guest/platform/rutabaga/RutabagaVirtGpuSyncHelper.cpp @@ -16,14 +16,21 @@ #include "RutabagaVirtGpuSyncHelper.h" +#include <log/log.h> + #include "RutabagaLayer.h" namespace gfxstream { RutabagaVirtGpuSyncHelper::RutabagaVirtGpuSyncHelper() {} +bool RutabagaVirtGpuSyncHelper::Init() { + mEmulation = EmulatedVirtioGpu::Get(); + return mEmulation != nullptr; +} + int RutabagaVirtGpuSyncHelper::wait(int syncFd, int timeoutMilliseconds) { - return EmulatedVirtioGpu::Get().WaitOnEmulatedFence(syncFd, timeoutMilliseconds); + return mEmulation->WaitOnEmulatedFence(syncFd, timeoutMilliseconds); } int RutabagaVirtGpuSyncHelper::dup(int syncFd) { @@ -33,6 +40,13 @@ int RutabagaVirtGpuSyncHelper::dup(int syncFd) { int RutabagaVirtGpuSyncHelper::close(int) { return 0; } -SyncHelper* createPlatformSyncHelper() { return new RutabagaVirtGpuSyncHelper(); } +SyncHelper* createPlatformSyncHelper() { + RutabagaVirtGpuSyncHelper* sync = new RutabagaVirtGpuSyncHelper(); + if (!sync->Init()) { + ALOGE("Failed to initialize RutabagaVirtGpuSyncHelper: Failed to get emulation layer."); + return nullptr; + } + return sync; +} } // namespace gfxstream diff --git a/guest/platform/rutabaga/RutabagaVirtGpuSyncHelper.h b/guest/platform/rutabaga/RutabagaVirtGpuSyncHelper.h index c163eb39..6b50e719 100644 --- a/guest/platform/rutabaga/RutabagaVirtGpuSyncHelper.h +++ b/guest/platform/rutabaga/RutabagaVirtGpuSyncHelper.h @@ -14,6 +14,9 @@ * limitations under the License. */ +#include <memory> + +#include "RutabagaLayer.h" #include "Sync.h" namespace gfxstream { @@ -22,11 +25,16 @@ class RutabagaVirtGpuSyncHelper : public SyncHelper { public: RutabagaVirtGpuSyncHelper(); + bool Init(); + int wait(int syncFd, int timeoutMilliseconds) override; int dup(int syncFd) override; int close(int) override; + + private: + std::shared_ptr<EmulatedVirtioGpu> mEmulation; }; SyncHelper* createPlatformSyncHelper(); diff --git a/guest/platform/rutabaga/include/gfxstream/RutabagaLayerTestUtils.h b/guest/platform/rutabaga/include/gfxstream/RutabagaLayerTestUtils.h index 4817a9c2..8f4536d3 100644 --- a/guest/platform/rutabaga/include/gfxstream/RutabagaLayerTestUtils.h +++ b/guest/platform/rutabaga/include/gfxstream/RutabagaLayerTestUtils.h @@ -18,6 +18,6 @@ namespace gfxstream { -void ResetEmulatedVirtioGpu(); +uint32_t GetNumActiveEmulatedVirtioGpuUsers(); } // namespace gfxstream diff --git a/guest/renderControl_enc/Android.bp b/guest/renderControl_enc/Android.bp index 2ffb2b41..5f346a35 100644 --- a/guest/renderControl_enc/Android.bp +++ b/guest/renderControl_enc/Android.bp @@ -19,6 +19,18 @@ package { default_applicable_licenses: ["hardware_google_gfxstream_license"], } +cc_library_headers { + name: "libgfxstream_guest_rendercontrol_encoder_headers", + host_supported: true, + vendor_available: true, + defaults: [ + "libgfxstream_guest_cc_defaults", + ], + export_include_dirs: [ + ".", + ], +} + cc_library_shared { name: "lib_renderControl_enc", host_supported: true, @@ -32,6 +44,7 @@ cc_library_shared { ], export_header_lib_headers: [ "libgfxstream_guest_graphics_headers", + "libgfxstream_guest_iostream", ], shared_libs: [ "libandroidemu", diff --git a/guest/vulkan/Android.bp b/guest/vulkan/Android.bp index 4db968fe..03b4e961 100644 --- a/guest/vulkan/Android.bp +++ b/guest/vulkan/Android.bp @@ -47,7 +47,6 @@ cc_defaults { "libmesa_util_gfxstream", "libmesa_util_format_gfxstream", "libGoldfishAddressSpace", - "libgfxstream_guest_gralloc", "libringbuffer", "libqemupipe.ranchu", "libarect", @@ -114,6 +113,7 @@ cc_library_shared { ], static_libs: [ "libplatform", + "libgfxstream_guest_android", "libgfxstream_guest_system_common", ], } @@ -124,11 +124,12 @@ cc_library_shared { "libgfxstream_guest_vulkan_defaults", ], shared_libs: [ - "libplatform_rutabaga", - "libgfxstream_backend", + "libplatform_rutabaga_server", ], static_libs: [ + "libgfxstream_guest_android_with_host", "libgfxstream_guest_system_common_with_host", + "libplatform_rutabaga", ], cflags: [ "-DEND2END_TESTS", diff --git a/guest/vulkan_enc/Android.bp b/guest/vulkan_enc/Android.bp index f129878a..a672423d 100644 --- a/guest/vulkan_enc/Android.bp +++ b/guest/vulkan_enc/Android.bp @@ -113,6 +113,7 @@ cc_defaults { ], header_libs: [ "gfxstream_vulkan_headers", + "libOpenglSystemCommonHeaders", "libgfxstream_guest_iostream", "libnativewindow_headers", "mesa_common_headers_gfxstream", @@ -133,9 +134,9 @@ cc_defaults { "libdrm", "libandroidemu_static", "libGoldfishAddressSpace", - "libgfxstream_guest_gralloc", "libmesa_vulkan_util_gfxstream", "libmesa_vulkan_runtime_gfxstream", + "libgfxstream_guest_android", "libgfxstream_guest_vulkan_entrypoints", "libmesa_util_gfxstream", "libmesa_util_format_gfxstream", @@ -196,9 +197,11 @@ cc_library_static { defaults: [ "libgfxstream_guest_vulkan_encoder_defaults", ], - shared_libs: [ + static_libs: [ + "libplatform_rutabaga", + ], + export_static_lib_headers: [ "libplatform_rutabaga", - "libgfxstream_backend", ], target: { host: { diff --git a/guest/vulkan_enc/AndroidHardwareBuffer.cpp b/guest/vulkan_enc/AndroidHardwareBuffer.cpp index 0cb77949..c5984b35 100644 --- a/guest/vulkan_enc/AndroidHardwareBuffer.cpp +++ b/guest/vulkan_enc/AndroidHardwareBuffer.cpp @@ -20,8 +20,9 @@ #endif #include <assert.h> +#include <log/log.h> -#include "../OpenglSystemCommon/HostConnection.h" +#include "gfxstream/guest/Gralloc.h" #include "vk_format_info.h" #include "vk_util.h" diff --git a/guest/vulkan_enc/AndroidHardwareBuffer.h b/guest/vulkan_enc/AndroidHardwareBuffer.h index 0389f096..5b2bef52 100644 --- a/guest/vulkan_enc/AndroidHardwareBuffer.h +++ b/guest/vulkan_enc/AndroidHardwareBuffer.h @@ -16,7 +16,7 @@ #include <vulkan/vulkan.h> -#include "../OpenglSystemCommon/Gralloc.h" +#include "gfxstream/guest/Gralloc.h" #include "HostVisibleMemoryVirtualization.h" // Structure similar to diff --git a/guest/vulkan_enc/ResourceTracker.cpp b/guest/vulkan_enc/ResourceTracker.cpp index be6fb36f..7a568fdf 100644 --- a/guest/vulkan_enc/ResourceTracker.cpp +++ b/guest/vulkan_enc/ResourceTracker.cpp @@ -702,8 +702,9 @@ SetBufferCollectionBufferConstraintsResult setBufferCollectionBufferConstraintsI uint64_t getAHardwareBufferId(AHardwareBuffer* ahw) { uint64_t id = 0; -#if defined(__ANDROID__) && ANDROID_API_LEVEL >= 31 - AHardwareBuffer_getId(ahw, &id); +#if defined(ANDROID) + auto* gralloc = ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->grallocHelper(); + gralloc->getId(ahw, &id); #else (void)ahw; #endif @@ -5938,13 +5939,7 @@ void ResourceTracker::unwrap_VkNativeBufferANDROID(const VkNativeBufferANDROID* auto* gralloc = ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->grallocHelper(); const native_handle_t* nativeHandle = (const native_handle_t*)inputNativeInfo->handle; - -#if defined(END2END_TESTS) - // This is valid since the testing backend creates the handle and we know the layout. - *(uint32_t*)(outputNativeInfo->handle) = (uint32_t)nativeHandle->data[0]; -#else *(uint32_t*)(outputNativeInfo->handle) = gralloc->getHostHandle(nativeHandle); -#endif } void ResourceTracker::unwrap_VkBindImageMemorySwapchainInfoKHR( @@ -6499,6 +6494,7 @@ void ResourceTracker::on_vkGetPhysicalDeviceExternalBufferProperties_common( VkExternalBufferProperties* pExternalBufferProperties) { VkEncoder* enc = (VkEncoder*)context; +#if defined(ANDROID) // Older versions of Goldfish's Gralloc did not support allocating AHARDWAREBUFFER_FORMAT_BLOB // with GPU usage (b/299520213). if (ResourceTracker::threadingCallbacks.hostConnectionGetFunc() @@ -6511,6 +6507,7 @@ void ResourceTracker::on_vkGetPhysicalDeviceExternalBufferProperties_common( pExternalBufferProperties->externalMemoryProperties.compatibleHandleTypes = 0; return; } +#endif uint32_t supportedHandleType = 0; #ifdef VK_USE_PLATFORM_FUCHSIA diff --git a/guest/vulkan_enc/func_table.cpp b/guest/vulkan_enc/func_table.cpp index f3632cab..4dcfcc4a 100644 --- a/guest/vulkan_enc/func_table.cpp +++ b/guest/vulkan_enc/func_table.cpp @@ -34,7 +34,6 @@ #include <cstring> -#include "../OpenglSystemCommon/HostConnection.h" #include "ResourceTracker.h" #include "VkEncoder.h" #include "gfxstream_vk_entrypoints.h" diff --git a/guest/vulkan_enc/vk_format_info.h b/guest/vulkan_enc/vk_format_info.h index 2d5d84eb..9c5422c0 100644 --- a/guest/vulkan_enc/vk_format_info.h +++ b/guest/vulkan_enc/vk_format_info.h @@ -35,6 +35,10 @@ enum { HAL_PIXEL_FORMAT_YV12 = 842094169, }; #endif + +#if !defined(__INTRODUCED_IN) +#define __INTRODUCED_IN(__api_level) /* nothing */ +#endif #include <vndk/hardware_buffer.h> #include <vulkan/vulkan.h> |