Snap for 6198741 from e202d55d5a0d85ca81dbfd33721252ba68d2ef40 to sdk-release
Change-Id: Ic1de502a3e479b2bd3b41902c827b238b5df3fda
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 2f333a0..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,112 +0,0 @@
-cc_library_shared {
- name: "libvulkan_goldfish",
-
- srcs: [
- "android-emu/android/base/AlignedBuf.cpp",
- "android-emu/android/base/Pool.cpp",
- "android-emu/android/base/SubAllocator.cpp",
- "android-emu/android/base/files/MemStream.cpp",
- "android-emu/android/base/files/Stream.cpp",
- "android-emu/android/base/files/StreamSerializing.cpp",
- "android-emu/android/base/Tracing.cpp",
- "shared/OpenglCodecCommon/ChecksumCalculator.cpp",
- "shared/OpenglCodecCommon/glUtils.cpp",
- "shared/OpenglCodecCommon/goldfish_address_space.cpp",
- "shared/OpenglCodecCommon/goldfish_dma.cpp",
- "system/OpenglSystemCommon/HostConnection.cpp",
- "system/OpenglSystemCommon/ProcessPipe.cpp",
- "system/OpenglSystemCommon/ThreadInfo.cpp",
- "system/renderControl_enc/renderControl_enc.cpp",
- "system/vulkan/func_table.cpp",
- "system/vulkan/goldfish_vulkan.cpp",
- "system/vulkan_enc/HostVisibleMemoryVirtualization.cpp",
- "system/vulkan_enc/ResourceTracker.cpp",
- "system/vulkan_enc/Resources.cpp",
- "system/vulkan_enc/Validation.cpp",
- "system/vulkan_enc/VkEncoder.cpp",
- "system/vulkan_enc/VulkanHandleMapping.cpp",
- "system/vulkan_enc/VulkanStreamGuest.cpp",
- "system/vulkan_enc/goldfish_vk_deepcopy_guest.cpp",
- "system/vulkan_enc/goldfish_vk_extension_structs_guest.cpp",
- "system/vulkan_enc/goldfish_vk_marshaling_guest.cpp",
- "system/vulkan_enc/goldfish_vk_transform_guest.cpp",
- ],
-
- cflags: [
- "-DLOG_TAG=\"goldfish_vulkan\"",
- "-DGOLDFISH_VULKAN",
- "-DGOLDFISH_NO_GL",
- "-DPAGE_SIZE=4096",
- "-Wno-unused-parameter",
- "-Wno-missing-field-initializers",
- "-Wno-newline-eof",
- "-Wno-unused-function",
- "-Wno-unused-value",
- "-Wno-unused-variable",
- ],
-
- include_dirs: [
- "external/vulkan-headers/include",
- ],
-
- local_include_dirs: [
- "android-emu",
- "host/include/libOpenglRender",
- "shared/OpenglCodecCommon",
- "system/OpenglSystemCommon",
- "system/renderControl_enc",
- "system/vulkan_enc",
- "system/include",
- ],
-
- // Only enable on fuchsia.
- enabled: false,
- target: {
- fuchsia: {
- // TODO(reveman): Enable when not breaking the build.
- //enabled: true,
-
- srcs: [
- "fuchsia/port.cc",
- "system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp",
- ],
-
- cflags: [
- "-DVK_USE_PLATFORM_FUCHSIA",
- "-DPLATFORM_SDK_VERSION=1",
- "-DFUCHSIA_NO_TRACE",
- "-DQEMU_PIPE_PATH=\"/dev/class/goldfish-pipe/000\"",
- "-DGOLDFISH_ADDRESS_SPACE_DEVICE_NAME=\"/dev/class/goldfish-address-space/000\"",
- ],
-
- stl: "libc++_static",
-
- local_include_dirs: [
- "fuchsia/include",
- ],
-
- static_libs: [
- "libasync",
- "libfidl",
- "libfidl_base",
- "libfidl_cpp",
- "libfidl_cpp_base",
- "libfidl_cpp_sync",
- "libfuchsia.hardware.goldfish.address.space",
- "libfuchsia.hardware.goldfish.control",
- "libfuchsia.hardware.goldfish.pipe",
- "libfuchsia.sysmem",
- "libzx",
- ],
-
- shared_libs: [
- "libasync-default",
- "libfdio",
- ],
-
- required: [
- "libzircon",
- ],
- },
- },
-}
diff --git a/Android.mk b/Android.mk
index 6cf4651..7afa40a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -150,6 +150,12 @@
include $(GOLDFISH_OPENGL_PATH)/system/gralloc/Android.mk
+ifneq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST))
+include $(GOLDFISH_OPENGL_PATH)/system/hals/Android.mk
+endif
+
+include $(GOLDFISH_OPENGL_PATH)/system/cbmanager/Android.mk
+
include $(GOLDFISH_OPENGL_PATH)/system/egl/Android.mk
ifeq (true,$(BUILD_EMULATOR_VULKAN)) # Vulkan libs
@@ -159,6 +165,11 @@
ifeq ($(shell test $(PLATFORM_SDK_VERSION) -gt 28 -o $(IS_AT_LEAST_QPR1) = true && echo isApi29OrHigher),isApi29OrHigher)
# HWC2 enabled after P
include $(GOLDFISH_OPENGL_PATH)/system/hwc2/Android.mk
+ # hardware codecs enabled after P
+ include $(GOLDFISH_OPENGL_PATH)/system/codecs/omx/common/Android.mk
+ include $(GOLDFISH_OPENGL_PATH)/system/codecs/omx/plugin/Android.mk
+ include $(GOLDFISH_OPENGL_PATH)/system/codecs/omx/avcdec/Android.mk
+ include $(GOLDFISH_OPENGL_PATH)/system/codecs/omx/vpxdec/Android.mk
endif
endif
diff --git a/BUILD.gn b/BUILD.gn
index c6e0201..0e2fea1 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -5,8 +5,8 @@
"android-emu/android/base/Pool.cpp",
"android-emu/android/base/Pool.h",
"android-emu/android/base/ring_buffer.c",
- "android-emu/android/base/SubAllocator.cpp",
- "android-emu/android/base/SubAllocator.h",
+ "android-emu/android/base/AndroidSubAllocator.cpp",
+ "android-emu/android/base/AndroidSubAllocator.h",
"android-emu/android/base/files/MemStream.cpp",
"android-emu/android/base/files/MemStream.h",
"android-emu/android/base/files/Stream.cpp",
@@ -36,6 +36,7 @@
"shared/OpenglCodecCommon/goldfish_address_space.h",
"shared/OpenglCodecCommon/goldfish_dma.cpp",
"shared/OpenglCodecCommon/goldfish_dma.h",
+ "system/OpenglSystemCommon/AddressSpaceStream.cpp",
"system/OpenglSystemCommon/HostConnection.cpp",
"system/OpenglSystemCommon/HostConnection.h",
"system/OpenglSystemCommon/ProcessPipe.cpp",
@@ -113,7 +114,9 @@
if (target_os == "fuchsia") {
sources -= [ "system/OpenglSystemCommon/QemuPipeStream.cpp" ]
sources += [
+ "fuchsia/fuchsia_stdio.cc",
"fuchsia/port.cc",
+ "fuchsia/service_connector.cc",
"system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp",
]
@@ -127,12 +130,13 @@
]
deps = [
- "//zircon/system/fidl/fuchsia-hardware-goldfish-address-space",
- "//zircon/system/fidl/fuchsia-hardware-goldfish-control",
- "//zircon/system/fidl/fuchsia-hardware-goldfish-pipe",
+ "//sdk/fidl/fuchsia.hardware.goldfish",
"//zircon/system/fidl/fuchsia-sysmem",
- "//zircon/public/lib/fdio",
- "//zircon/public/lib/trace",
+ "//zircon/public/lib/trace-with-static-engine",
+ "//zircon/public/lib/syslog-static",
+ "//zircon/public/lib/zx",
+ "//zircon/public/lib/zxio",
+ "//zircon/system/fidl/fuchsia-logger:llcpp",
]
defines += [
diff --git a/CMakeLists.txt b/CMakeLists.txt
index add8779..9c58ad1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@
# instead run make from .../device/generic/goldfish-opengl
# which will re-generate this file.
set(GOLDFISH_DEVICE_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/./Android.mk" "cfc211dbbd3c755fb04aef9a811289d617130f92147e411e8099550e284b095a")
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/./Android.mk" "c8e5536771d09cd120c3e396beac994a1e2d2880f37b4e3bd1844be4cfc31555")
add_subdirectory(shared/OpenglCodecCommon)
add_subdirectory(system/GLESv1_enc)
add_subdirectory(system/GLESv2_enc)
diff --git a/android-emu/Android.mk b/android-emu/Android.mk
index 6de495e..4be199b 100644
--- a/android-emu/Android.mk
+++ b/android-emu/Android.mk
@@ -18,7 +18,7 @@
android/base/Pool.cpp \
android/base/ring_buffer.c \
android/base/StringFormat.cpp \
- android/base/SubAllocator.cpp \
+ android/base/AndroidSubAllocator.cpp \
android/base/synchronization/AndroidMessageChannel.cpp \
android/base/threads/AndroidFunctorThread.cpp \
android/base/threads/AndroidThreadStore.cpp \
diff --git a/android-emu/CMakeLists.txt b/android-emu/CMakeLists.txt
index e6482d8..f490697 100644
--- a/android-emu/CMakeLists.txt
+++ b/android-emu/CMakeLists.txt
@@ -1,9 +1,9 @@
# This is an autogenerated file! Do not edit!
# instead run make from .../device/generic/goldfish-opengl
# which will re-generate this file.
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/android-emu/Android.mk" "3654f06acfa661c75b91fe271337a63a77326a69b4247026996c40bff8138bde")
-set(androidemu_src android/base/AlignedBuf.cpp android/base/files/MemStream.cpp android/base/files/Stream.cpp android/base/files/StreamSerializing.cpp android/base/Pool.cpp android/base/ring_buffer.c android/base/StringFormat.cpp android/base/SubAllocator.cpp android/base/synchronization/AndroidMessageChannel.cpp android/base/threads/AndroidFunctorThread.cpp android/base/threads/AndroidThreadStore.cpp android/base/threads/AndroidThread_pthread.cpp android/base/threads/AndroidWorkPool.cpp android/base/Tracing.cpp android/utils/debug.c)
-android_add_shared_library(androidemu)
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/android-emu/Android.mk" "e7c9acc2277e7c651d6e722f96705a1fd445441b5ab6bb5b6d5b4c46dddfc702")
+set(androidemu_src android/base/AlignedBuf.cpp android/base/files/MemStream.cpp android/base/files/Stream.cpp android/base/files/StreamSerializing.cpp android/base/Pool.cpp android/base/ring_buffer.c android/base/StringFormat.cpp android/base/AndroidSubAllocator.cpp android/base/synchronization/AndroidMessageChannel.cpp android/base/threads/AndroidFunctorThread.cpp android/base/threads/AndroidThreadStore.cpp android/base/threads/AndroidThread_pthread.cpp android/base/threads/AndroidWorkPool.cpp android/base/Tracing.cpp android/utils/debug.c)
+android_add_library(TARGET androidemu SHARED LICENSE Apache-2.0 SRC android/base/AlignedBuf.cpp android/base/files/MemStream.cpp android/base/files/Stream.cpp android/base/files/StreamSerializing.cpp android/base/Pool.cpp android/base/ring_buffer.c android/base/StringFormat.cpp android/base/AndroidSubAllocator.cpp android/base/synchronization/AndroidMessageChannel.cpp android/base/threads/AndroidFunctorThread.cpp android/base/threads/AndroidThreadStore.cpp android/base/threads/AndroidThread_pthread.cpp android/base/threads/AndroidWorkPool.cpp android/base/Tracing.cpp android/utils/debug.c)
target_include_directories(androidemu PRIVATE ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
target_compile_definitions(androidemu PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"androidemu\"")
target_compile_options(androidemu PRIVATE "-fvisibility=default" "-Wno-unused-parameter" "-Wno-missing-field-initializers" "-fstrict-aliasing")
diff --git a/android-emu/android/base/AndroidSubAllocator.cpp b/android-emu/android/base/AndroidSubAllocator.cpp
new file mode 100644
index 0000000..0b17a8a
--- /dev/null
+++ b/android-emu/android/base/AndroidSubAllocator.cpp
@@ -0,0 +1,240 @@
+// Copyright 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include "android/base/AndroidSubAllocator.h"
+
+#include "android/base/address_space.h"
+#include "android/base/files/Stream.h"
+
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+#include <log/log.h>
+
+namespace android {
+namespace base {
+namespace guest {
+
+class SubAllocator::Impl {
+public:
+ Impl(
+ void* _buffer,
+ uint64_t _totalSize,
+ uint64_t _pageSize) :
+ buffer(_buffer),
+ totalSize(_totalSize),
+ pageSize(_pageSize),
+ startAddr((uintptr_t)buffer),
+ endAddr(startAddr + totalSize) {
+
+ address_space_allocator_init(
+ &addr_alloc,
+ totalSize,
+ 32);
+ }
+
+ ~Impl() {
+ address_space_allocator_destroy_nocleanup(&addr_alloc);
+ }
+
+ void clear() {
+ address_space_allocator_destroy_nocleanup(&addr_alloc);
+ address_space_allocator_init(
+ &addr_alloc,
+ totalSize,
+ 32);
+ }
+
+ bool save(Stream* stream) {
+ address_space_allocator_iter_func_t allocatorSaver =
+ [](void* context, struct address_space_allocator* allocator) {
+ Stream* stream = reinterpret_cast<Stream*>(context);
+ stream->putBe32(allocator->size);
+ stream->putBe32(allocator->capacity);
+ stream->putBe64(allocator->total_bytes);
+ };
+ address_block_iter_func_t allocatorBlockSaver =
+ [](void* context, struct address_block* block) {
+ Stream* stream = reinterpret_cast<Stream*>(context);
+ stream->putBe64(block->offset);
+ stream->putBe64(block->size_available);
+ };
+ address_space_allocator_run(
+ &addr_alloc,
+ (void*)stream,
+ allocatorSaver,
+ allocatorBlockSaver);
+
+ stream->putBe64(pageSize);
+ stream->putBe64(totalSize);
+ stream->putBe32(allocCount);
+
+ return true;
+ }
+
+ bool load(Stream* stream) {
+ clear();
+ address_space_allocator_iter_func_t allocatorLoader =
+ [](void* context, struct address_space_allocator* allocator) {
+ Stream* stream = reinterpret_cast<Stream*>(context);
+ allocator->size = stream->getBe32();
+ allocator->capacity = stream->getBe32();
+ allocator->total_bytes = stream->getBe64();
+ };
+ address_block_iter_func_t allocatorBlockLoader =
+ [](void* context, struct address_block* block) {
+ Stream* stream = reinterpret_cast<Stream*>(context);
+ block->offset = stream->getBe64();
+ block->size_available = stream->getBe64();
+ };
+ address_space_allocator_run(
+ &addr_alloc,
+ (void*)stream,
+ allocatorLoader,
+ allocatorBlockLoader);
+
+ pageSize = stream->getBe64();
+ totalSize = stream->getBe64();
+ allocCount = stream->getBe32();
+
+ return true;
+ }
+
+ bool postLoad(void* postLoadBuffer) {
+ buffer = postLoadBuffer;
+ startAddr =
+ (uint64_t)(uintptr_t)postLoadBuffer;
+ return true;
+ }
+
+ void rangeCheck(const char* task, void* ptr) {
+ uint64_t addr = (uintptr_t)ptr;
+ if (addr < startAddr ||
+ addr > endAddr) {
+ std::stringstream ss;
+ ss << "SubAllocator " << task << ": ";
+ ss << "Out of range: " << std::hex << addr << " ";
+ ss << "Range: " <<
+ std::hex << startAddr << " " <<
+ std::hex << endAddr;
+ std::string msg = ss.str();
+ ALOGE("Fatal: %s\n", msg.c_str());
+ }
+ }
+
+ uint64_t getOffset(void* checkedPtr) {
+ uint64_t addr = (uintptr_t)checkedPtr;
+ return addr - startAddr;
+ }
+
+ bool free(void* ptr) {
+ if (!ptr) return false;
+
+ rangeCheck("free", ptr);
+ if (EINVAL == address_space_allocator_deallocate(
+ &addr_alloc, getOffset(ptr))) {
+ return false;
+ }
+
+ --allocCount;
+ return true;
+ }
+
+ void freeAll() {
+ address_space_allocator_reset(&addr_alloc);
+ allocCount = 0;
+ }
+
+ void* alloc(size_t wantedSize) {
+ if (wantedSize == 0) return nullptr;
+
+ uint64_t wantedSize64 =
+ (uint64_t)wantedSize;
+
+ size_t toPageSize =
+ pageSize *
+ ((wantedSize + pageSize - 1) / pageSize);
+
+ uint64_t offset =
+ address_space_allocator_allocate(
+ &addr_alloc, toPageSize);
+
+ if (offset == ANDROID_EMU_ADDRESS_SPACE_BAD_OFFSET) {
+ return nullptr;
+ }
+
+ ++allocCount;
+ return (void*)(uintptr_t)(startAddr + offset);
+ }
+
+ bool empty() const {
+ return allocCount == 0;
+ }
+
+ void* buffer;
+ uint64_t totalSize;
+ uint64_t pageSize;
+ uint64_t startAddr;
+ uint64_t endAddr;
+ struct address_space_allocator addr_alloc;
+ uint32_t allocCount = 0;
+};
+
+SubAllocator::SubAllocator(
+ void* buffer,
+ uint64_t totalSize,
+ uint64_t pageSize) :
+ mImpl(
+ new SubAllocator::Impl(buffer, totalSize, pageSize)) { }
+
+SubAllocator::~SubAllocator() {
+ delete mImpl;
+}
+
+// Snapshotting
+bool SubAllocator::save(Stream* stream) {
+ return mImpl->save(stream);
+}
+
+bool SubAllocator::load(Stream* stream) {
+ return mImpl->load(stream);
+}
+
+bool SubAllocator::postLoad(void* postLoadBuffer) {
+ return mImpl->postLoad(postLoadBuffer);
+}
+
+void* SubAllocator::alloc(size_t wantedSize) {
+ return mImpl->alloc(wantedSize);
+}
+
+bool SubAllocator::free(void* ptr) {
+ return mImpl->free(ptr);
+}
+
+void SubAllocator::freeAll() {
+ mImpl->freeAll();
+}
+
+uint64_t SubAllocator::getOffset(void* ptr) {
+ return mImpl->getOffset(ptr);
+}
+
+bool SubAllocator::empty() const {
+ return mImpl->empty();
+}
+
+} // namespace guest
+} // namespace base
+} // namespace android
diff --git a/android-emu/android/base/SubAllocator.h b/android-emu/android/base/AndroidSubAllocator.h
similarity index 86%
rename from android-emu/android/base/SubAllocator.h
rename to android-emu/android/base/AndroidSubAllocator.h
index b2363bd..8442137 100644
--- a/android-emu/android/base/SubAllocator.h
+++ b/android-emu/android/base/AndroidSubAllocator.h
@@ -20,6 +20,16 @@
namespace android {
namespace base {
+class Stream;
+
+} // namespace base
+} // namespace android
+
+namespace android {
+namespace base {
+namespace guest {
+
+
// Class to create sub-allocations in an existing buffer. Similar interface to
// Pool, but underlying mechanism is different as it's difficult to combine
// same-size heaps in Pool with a preallocated buffer.
@@ -36,12 +46,20 @@
// SubAllocator, but the prealloced buffer is not freed.
~SubAllocator();
+ // Snapshotting
+ bool save(Stream* stream);
+ bool load(Stream* stream);
+ bool postLoad(void* postLoadBuffer);
+
// returns null if the allocation cannot be satisfied.
void* alloc(size_t wantedSize);
- void free(void* ptr);
+ // returns true if |ptr| came from alloc(), false otherwise
+ bool free(void* ptr);
void freeAll();
uint64_t getOffset(void* ptr);
+ bool empty() const;
+
// Convenience function to allocate an array
// of objects of type T.
template <class T>
@@ -80,5 +98,6 @@
Impl* mImpl = nullptr;
};
+} // namespace guest
} // namespace base
} // namespace android
diff --git a/android-emu/android/base/SubAllocator.cpp b/android-emu/android/base/SubAllocator.cpp
deleted file mode 100644
index 99d7b78..0000000
--- a/android-emu/android/base/SubAllocator.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2018 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-#include "android/base/SubAllocator.h"
-
-#include "android/base/address_space.h"
-
-#include <log/log.h>
-
-#include <iomanip>
-#include <sstream>
-#include <string>
-
-namespace android {
-namespace base {
-
-class SubAllocator::Impl {
-public:
- Impl(
- void* _buffer,
- uint64_t _totalSize,
- uint64_t _pageSize) :
- buffer(_buffer),
- totalSize(_totalSize),
- pageSize(_pageSize),
- startAddr((uintptr_t)buffer),
- endAddr(startAddr + totalSize) {
-
- address_space_allocator_init(
- &addr_alloc,
- totalSize,
- 32);
- }
-
- ~Impl() {
- address_space_allocator_destroy(&addr_alloc);
- }
-
- void rangeCheck(const char* task, void* ptr) {
- uint64_t addr = (uintptr_t)ptr;
- if (addr < startAddr ||
- addr > endAddr) {
- std::stringstream ss;
- ss << "SubAllocator " << task << ": ";
- ss << "Out of range: " << std::hex << addr << " ";
- ss << "Range: " <<
- std::hex << startAddr << " " <<
- std::hex << endAddr;
- std::string msg = ss.str();
- ALOGE("%s", msg.c_str());
- abort();
- }
- }
-
- uint64_t getOffset(void* checkedPtr) {
- uint64_t addr = (uintptr_t)checkedPtr;
- return addr - startAddr;
- }
-
- void free(void* ptr) {
- if (!ptr) return;
-
- rangeCheck("free", ptr);
- address_space_allocator_deallocate(
- &addr_alloc, getOffset(ptr));
- }
-
- void freeAll() {
- address_space_allocator_reset(&addr_alloc);
- }
-
- void* alloc(size_t wantedSize) {
- if (wantedSize == 0) return nullptr;
-
- size_t toPageSize =
- pageSize *
- ((wantedSize + pageSize - 1) / pageSize);
-
- uint64_t offset =
- address_space_allocator_allocate(
- &addr_alloc, toPageSize);
-
- if (offset == ANDROID_EMU_ADDRESS_SPACE_BAD_OFFSET) {
- return nullptr;
- }
-
- return (void*)(uintptr_t)(startAddr + offset);
- }
-
- void* buffer;
- uint64_t totalSize;
- uint64_t pageSize;
- uint64_t startAddr;
- uint64_t endAddr;
- struct address_space_allocator addr_alloc;
-};
-
-SubAllocator::SubAllocator(
- void* buffer,
- uint64_t totalSize,
- uint64_t pageSize) :
- mImpl(
- new SubAllocator::Impl(buffer, totalSize, pageSize)) { }
-
-SubAllocator::~SubAllocator() {
- delete mImpl;
-}
-
-void* SubAllocator::alloc(size_t wantedSize) {
- return mImpl->alloc(wantedSize);
-}
-
-void SubAllocator::free(void* ptr) {
- mImpl->free(ptr);
-}
-
-void SubAllocator::freeAll() {
- mImpl->freeAll();
-}
-
-uint64_t SubAllocator::getOffset(void* ptr) {
- return mImpl->getOffset(ptr);
-}
-
-} // namespace base
-} // namespace android
diff --git a/android-emu/android/base/address_space.h b/android-emu/android/base/address_space.h
index 50c9bbd..e7b43fd 100644
--- a/android-emu/android/base/address_space.h
+++ b/android-emu/android/base/address_space.h
@@ -18,10 +18,15 @@
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
ANDROID_BEGIN_HEADER
+#ifdef ADDRESS_SPACE_NAMESPACE
+namespace ADDRESS_SPACE_NAMESPACE {
+#endif
+
// This is ported from goldfish_address_space, allowing it to be used for
// general sub-allocations of any buffer range.
// It is also a pure header library, so there are no compiler tricks needed
@@ -33,8 +38,13 @@
*/
struct address_block {
uint64_t offset;
- uint64_t size : 63;
- uint64_t available : 1;
+ union {
+ uint64_t size_available; /* VMSTATE_x does not support bit fields */
+ struct {
+ uint64_t size : 63;
+ uint64_t available : 1;
+ };
+ };
};
/* A dynamic array of address blocks, with the following invariant:
@@ -53,7 +63,6 @@
/* The assert function to abort if something goes wrong. */
static void address_space_assert(bool condition) {
- (void)condition;
#ifdef ANDROID_EMU_ADDRESS_SPACE_ASSERT_FUNC
ANDROID_EMU_ADDRESS_SPACE_ASSERT_FUNC(condition);
#else
@@ -61,7 +70,7 @@
#endif
}
-void* address_space_malloc0(size_t size) {
+static void* address_space_malloc0(size_t size) {
#ifdef ANDROID_EMU_ADDRESS_SPACE_MALLOC0_FUNC
return ANDROID_EMU_ADDRESS_SPACE_MALLOC0_FUNC(size);
#else
@@ -71,7 +80,7 @@
#endif
}
-void* address_space_realloc(void* ptr, size_t size) {
+static void* address_space_realloc(void* ptr, size_t size) {
#ifdef ANDROID_EMU_ADDRESS_SPACE_REALLOC_FUNC
return ANDROID_EMU_ADDRESS_SPACE_REALLOC_FUNC(ptr, size);
#else
@@ -80,7 +89,7 @@
#endif
}
-void address_space_free(void* ptr) {
+static void address_space_free(void* ptr) {
#ifdef ANDROID_EMU_ADDRESS_SPACE_FREE_FUNC
return ANDROID_EMU_ADDRESS_SPACE_FREE_FUNC(ptr);
#else
@@ -302,7 +311,8 @@
allocator->blocks =
(struct address_block*)
- address_space_malloc0(sizeof(struct address_block) * initial_capacity);
+ malloc(sizeof(struct address_block) * initial_capacity);
+ memset(allocator->blocks, 0, sizeof(struct address_block) * initial_capacity);
address_space_assert(allocator->blocks);
struct address_block *block = allocator->blocks;
@@ -328,6 +338,15 @@
address_space_free(allocator->blocks);
}
+/* Destroy function if we don't care what was previoulsy allocated.
+ * have been merged into one block.
+ */
+static void address_space_allocator_destroy_nocleanup(
+ struct address_space_allocator *allocator)
+{
+ address_space_free(allocator->blocks);
+}
+
/* Resets the state of the allocator to the initial state without
* performing any dynamic memory management. */
static void address_space_allocator_reset(
@@ -343,4 +362,33 @@
block->available = 1;
}
+typedef void (*address_block_iter_func_t)(void* context, struct address_block*);
+typedef void (*address_space_allocator_iter_func_t)(void* context, struct address_space_allocator*);
+
+static void address_space_allocator_run(
+ struct address_space_allocator *allocator,
+ void* context,
+ address_space_allocator_iter_func_t allocator_func,
+ address_block_iter_func_t block_func)
+{
+ struct address_block *block = 0;
+ int size;
+ int i;
+
+ allocator_func(context, allocator);
+
+ block = allocator->blocks;
+ size = allocator->size;
+
+ address_space_assert(size >= 1);
+
+ for (i = 0; i < size; ++i, ++block) {
+ block_func(context, block);
+ }
+}
+
+#ifdef ADDRESS_SPACE_NAMESPACE
+}
+#endif
+
ANDROID_END_HEADER
diff --git a/android-emu/android/base/ring_buffer.c b/android-emu/android/base/ring_buffer.c
index ef26d1d..f6b3b78 100644
--- a/android-emu/android/base/ring_buffer.c
+++ b/android-emu/android/base/ring_buffer.c
@@ -156,6 +156,40 @@
return (long)steps;
}
+long ring_buffer_advance_write(
+ struct ring_buffer* r, uint32_t step_size, uint32_t steps) {
+ uint32_t i;
+
+ for (i = 0; i < steps; ++i) {
+ if (!ring_buffer_can_write(r, step_size)) {
+ errno = -EAGAIN;
+ return (long)i;
+ }
+
+ __atomic_add_fetch(&r->write_pos, step_size, __ATOMIC_SEQ_CST);
+ }
+
+ errno = 0;
+ return (long)steps;
+}
+
+long ring_buffer_advance_read(
+ struct ring_buffer* r, uint32_t step_size, uint32_t steps) {
+ uint32_t i;
+
+ for (i = 0; i < steps; ++i) {
+ if (!ring_buffer_can_read(r, step_size)) {
+ errno = -EAGAIN;
+ return (long)i;
+ }
+
+ __atomic_add_fetch(&r->read_pos, step_size, __ATOMIC_SEQ_CST);
+ }
+
+ errno = 0;
+ return (long)steps;
+}
+
uint32_t ring_buffer_calc_shift(uint32_t size) {
uint32_t shift = 0;
while ((1 << shift) < size) {
@@ -196,7 +230,7 @@
v->mask = (1 << shift) - 1;
}
-static uint32_t ring_buffer_view_get_ring_pos(
+uint32_t ring_buffer_view_get_ring_pos(
const struct ring_buffer_view* v,
uint32_t index) {
return index & v->mask;
@@ -235,6 +269,60 @@
}
}
+int ring_buffer_copy_contents(
+ const struct ring_buffer* r,
+ const struct ring_buffer_view* v,
+ uint32_t wanted_bytes,
+ uint8_t* res) {
+
+ uint32_t total_available =
+ ring_buffer_available_read(r, v);
+ uint32_t available_at_end = 0;
+
+ if (v) {
+ available_at_end =
+ v->size - ring_buffer_view_get_ring_pos(v, r->read_pos);
+ } else {
+ available_at_end =
+ RING_BUFFER_SIZE - get_ring_pos(r->write_pos);
+ }
+
+ if (total_available < wanted_bytes) {
+ return -1;
+ }
+
+ if (v) {
+ if (wanted_bytes > available_at_end) {
+ uint32_t remaining = wanted_bytes - available_at_end;
+ memcpy(res,
+ &v->buf[ring_buffer_view_get_ring_pos(v, r->read_pos)],
+ available_at_end);
+ memcpy(res + available_at_end,
+ &v->buf[ring_buffer_view_get_ring_pos(v, r->read_pos + available_at_end)],
+ remaining);
+ } else {
+ memcpy(res,
+ &v->buf[ring_buffer_view_get_ring_pos(v, r->read_pos)],
+ wanted_bytes);
+ }
+ } else {
+ if (wanted_bytes > available_at_end) {
+ uint32_t remaining = wanted_bytes - available_at_end;
+ memcpy(res,
+ &r->buf[get_ring_pos(r->read_pos)],
+ available_at_end);
+ memcpy(res + available_at_end,
+ &r->buf[get_ring_pos(r->read_pos + available_at_end)],
+ remaining);
+ } else {
+ memcpy(res,
+ &r->buf[get_ring_pos(r->read_pos)],
+ wanted_bytes);
+ }
+ }
+ return 0;
+}
+
long ring_buffer_view_write(
struct ring_buffer* r,
struct ring_buffer_view* v,
@@ -319,9 +407,7 @@
void ring_buffer_yield() {
#ifdef _WIN32
- if (!SwitchToThread()) {
- Sleep(0);
- }
+ ring_buffer_pause();
#else
sched_yield();
#endif
@@ -352,6 +438,9 @@
uint32_t bytes,
uint64_t timeout_us) {
+ uint64_t start_us = ring_buffer_curr_us();
+ uint64_t curr_wait_us;
+
bool can_write =
v ? ring_buffer_view_can_write(r, v, bytes) :
ring_buffer_can_write(r, bytes);
@@ -404,6 +493,24 @@
struct ring_buffer_view* v,
const void* data,
uint32_t bytes) {
+ ring_buffer_write_fully_with_abort(r, v, data, bytes, 0, 0);
+}
+
+void ring_buffer_read_fully(
+ struct ring_buffer* r,
+ struct ring_buffer_view* v,
+ void* data,
+ uint32_t bytes) {
+ ring_buffer_read_fully_with_abort(r, v, data, bytes, 0, 0);
+}
+
+uint32_t ring_buffer_write_fully_with_abort(
+ struct ring_buffer* r,
+ struct ring_buffer_view* v,
+ const void* data,
+ uint32_t bytes,
+ uint32_t abort_value,
+ const volatile uint32_t* abort_ptr) {
uint32_t candidate_step = get_step_size(r, v, bytes);
uint32_t processed = 0;
@@ -425,14 +532,22 @@
}
processed += processed_here ? candidate_step : 0;
+
+ if (abort_ptr && (abort_value == *abort_ptr)) {
+ return processed;
+ }
}
+
+ return processed;
}
-void ring_buffer_read_fully(
+uint32_t ring_buffer_read_fully_with_abort(
struct ring_buffer* r,
struct ring_buffer_view* v,
void* data,
- uint32_t bytes) {
+ uint32_t bytes,
+ uint32_t abort_value,
+ const volatile uint32_t* abort_ptr) {
uint32_t candidate_step = get_step_size(r, v, bytes);
uint32_t processed = 0;
@@ -455,7 +570,13 @@
}
processed += processed_here ? candidate_step : 0;
+
+ if (abort_ptr && (abort_value == *abort_ptr)) {
+ return processed;
+ }
}
+
+ return processed;
}
void ring_buffer_sync_init(struct ring_buffer* r) {
diff --git a/android-emu/android/base/ring_buffer.h b/android-emu/android/base/ring_buffer.h
index 34c0666..390a758 100644
--- a/android-emu/android/base/ring_buffer.h
+++ b/android-emu/android/base/ring_buffer.h
@@ -52,6 +52,13 @@
struct ring_buffer* r, const void* data, uint32_t step_size, uint32_t steps);
long ring_buffer_read(
struct ring_buffer* r, void* data, uint32_t step_size, uint32_t steps);
+// Like ring_buffer_write / ring_buffer_read, but merely advances the counters
+// without reading or writing anything. Returns the number of step_size steps
+// advanced.
+long ring_buffer_advance_write(
+ struct ring_buffer* r, uint32_t step_size, uint32_t steps);
+long ring_buffer_advance_read(
+ struct ring_buffer* r, uint32_t step_size, uint32_t steps);
// If we want to work with dynamically allocated buffers, a separate struct is
// needed; the host and guest are in different address spaces and thus have
@@ -63,6 +70,13 @@
uint32_t mask;
};
+// Convenience struct that holds a pointer to a ring along with a view. It's a
+// common pattern for the ring and the buffer of the view to be shared between
+// two entities (in this case, usually guest and host).
+struct ring_buffer_with_view {
+ struct ring_buffer* ring;
+ struct ring_buffer_view view;
+};
// Calculates the highest power of 2 so that
// (1 << shift) <= size.
@@ -122,6 +136,29 @@
void* data,
uint32_t bytes);
+// Like read/write fully, but with an abort value. The value is read from
+// |abortPtr| each time. If |abortPtr| is null, then behaves the same
+// as ring_buffer_(read|write)_fully.
+// Returns the actual number of bytes sent or received.
+uint32_t ring_buffer_write_fully_with_abort(
+ struct ring_buffer* r,
+ struct ring_buffer_view* v,
+ const void* data,
+ uint32_t bytes,
+ uint32_t abort_value,
+ const volatile uint32_t* abort_ptr);
+uint32_t ring_buffer_read_fully_with_abort(
+ struct ring_buffer* r,
+ struct ring_buffer_view* v,
+ void* data,
+ uint32_t bytes,
+ uint32_t abort_value,
+ const volatile uint32_t* abort_ptr);
+
+uint32_t ring_buffer_view_get_ring_pos(
+ const struct ring_buffer_view* v,
+ uint32_t index);
+
bool ring_buffer_can_write(
const struct ring_buffer* r, uint32_t bytes);
bool ring_buffer_can_read(
@@ -137,6 +174,16 @@
uint32_t ring_buffer_available_read(
const struct ring_buffer* r,
const struct ring_buffer_view* v);
+// Copies out contents from the consumer side of
+// ring buffer/view |r,v|.
+// If there is less available read than |wanted_bytes|,
+// returns -1.
+// On success, returns 0.
+int ring_buffer_copy_contents(
+ const struct ring_buffer* r,
+ const struct ring_buffer_view* v,
+ uint32_t wanted_bytes,
+ uint8_t* res);
// Lockless synchronization where the consumer is allowed to hang up and go to
// sleep. This can be considered a sort of asymmetric lock for two threads,
diff --git a/cmake_transform.py b/cmake_transform.py
index 3e8d9c5..3583ec8 100644
--- a/cmake_transform.py
+++ b/cmake_transform.py
@@ -88,9 +88,9 @@
'android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/%s" "%s")' % (mkfile, sha256))
make.append('set(%s_src %s)' % (name, ' '.join(module['src'])))
if module['type'] == 'SHARED_LIBRARY':
- make.append('android_add_shared_library(%s)' % name)
+ make.append('android_add_library(TARGET {} SHARED LICENSE Apache-2.0 SRC {})'.format(name, ' '.join(module['src'])))
elif module['type'] == 'STATIC_LIBRARY':
- make.append('android_add_library(%s)' % name)
+ make.append('android_add_library(TARGET {} LICENSE Apache-2.0 SRC {})'.format(name, ' '.join(module['src'])))
else:
raise ValueError('Unexpected module type: %s' % module['type'])
diff --git a/fuchsia/fuchsia_stdio.cc b/fuchsia/fuchsia_stdio.cc
new file mode 100644
index 0000000..9f33454
--- /dev/null
+++ b/fuchsia/fuchsia_stdio.cc
@@ -0,0 +1,89 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <assert.h>
+#include <lib/syslog/global.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void __assert_fail(const char *expr, const char *file, int line, const char *func)
+{
+ FX_LOGF(ERROR, "goldfish", "Assertion failed: %s (%s: %s: %d)", expr, file, func, line);
+ abort();
+}
+
+int puts(const char *s)
+{
+ return fputs(s, stdout);
+}
+
+int printf(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ vfprintf(stdout, format, args);
+ va_end(args);
+ return 0;
+}
+
+int vprintf(const char *format, va_list ap)
+{
+ return vfprintf(stdout, format, ap);
+}
+
+int fprintf(FILE *stream, const char *format, ...)
+{
+ assert(stream == stdout || stream == stderr);
+ if (stream == stdout || stream == stderr)
+ {
+ va_list args;
+ va_start(args, format);
+ vfprintf(stream, format, args);
+ va_end(args);
+ }
+ return 0;
+}
+
+static inline fx_log_severity_t severity(FILE *stream)
+{
+ return stream == stdout ? FX_LOG_INFO : FX_LOG_ERROR;
+}
+
+int fputs(const char *s, FILE *stream)
+{
+ assert(stream == stdout || stream == stderr);
+ if (stream == stdout || stream == stderr)
+ {
+ _FX_LOG(severity(stream), "goldfish", s);
+ }
+ return 0;
+}
+
+int vfprintf(FILE *stream, const char *format, va_list ap)
+{
+ assert(stream == stdout || stream == stderr);
+ if (stream == stdout || stream == stderr)
+ {
+ _FX_LOGVF(severity(stream), "goldfish", format, ap);
+ }
+ return 0;
+}
+
+size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream)
+{
+ assert(stream == stdout || stream == stderr);
+ char buffer[512];
+ size_t offset = 0;
+ size_t count = 0;
+ for (; count < nitems; count++)
+ {
+ snprintf(buffer + offset, sizeof(buffer) - offset, reinterpret_cast<const char *>(ptr) + offset, size);
+ offset += size;
+ if (offset > sizeof(buffer))
+ break;
+ }
+ buffer[sizeof(buffer) - 1] = 0;
+ fputs(buffer, stream);
+ return count;
+}
diff --git a/fuchsia/include/cutils/log.h b/fuchsia/include/cutils/log.h
index 19ef6ca..a2ddde8 100644
--- a/fuchsia/include/cutils/log.h
+++ b/fuchsia/include/cutils/log.h
@@ -17,18 +17,17 @@
ANDROID_LOG_SILENT,
};
-#define android_printLog(prio, tag, ...) \
- __android_log_print(prio, tag, __VA_ARGS__)
+#define android_printLog(prio, tag, format, ...) \
+ __android_log_print(prio, tag, "[prio %d] " format, prio, ##__VA_ARGS__)
#define LOG_PRI(priority, tag, ...) android_printLog(priority, tag, __VA_ARGS__)
#define ALOG(priority, tag, ...) LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
#define __android_second(dummy, second, ...) second
#define __android_rest(first, ...) , ##__VA_ARGS__
-#define android_printAssert(condition, tag, ...) \
- __android_log_assert(condition, tag, \
- __android_second(0, ##__VA_ARGS__, NULL) \
- __android_rest(__VA_ARGS__))
+
+#define android_printAssert(condition, tag, format, ...) \
+ __android_log_assert(condition, tag, "assert: condition: %s " format, condition, ##__VA_ARGS__)
#define LOG_ALWAYS_FATAL_IF(condition, ...) \
((condition) \
diff --git a/fuchsia/include/services/service_connector.h b/fuchsia/include/services/service_connector.h
new file mode 100644
index 0000000..1320401
--- /dev/null
+++ b/fuchsia/include/services/service_connector.h
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 The Android Open Source Project
+// Copyright (C) 2019 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef FUCHSIA_INCLUDE_SERVICES_SERVICE_CONNECTOR_H_
+#define FUCHSIA_INCLUDE_SERVICES_SERVICE_CONNECTOR_H_
+
+#include <cstdint>
+#include <zircon/types.h>
+
+// Takes the name of a service (e.g. /svc/fuchsia.sysmem.Allocator) and returns
+// a handle to a connection to it.
+typedef zx_handle_t (*PFN_ConnectToServiceAddr)(const char *pName);
+
+void SetConnectToServiceFunction(PFN_ConnectToServiceAddr func);
+PFN_ConnectToServiceAddr GetConnectToServiceFunction();
+
+#endif // FUCHSIA_INCLUDE_SERVICES_SERVICE_CONNECTOR_H_
diff --git a/fuchsia/port.cc b/fuchsia/port.cc
index dd00eb6..37c7694 100644
--- a/fuchsia/port.cc
+++ b/fuchsia/port.cc
@@ -11,6 +11,8 @@
#include <cstdio>
#include <thread>
+#include <lib/syslog/global.h>
+
#include "cutils/log.h"
#include "cutils/properties.h"
#include "cutils/threads.h"
@@ -30,12 +32,21 @@
if (!local_tag) {
local_tag = "<NO_TAG>";
}
- printf("%d %s ", priority, local_tag);
va_list ap;
va_start(ap, format);
- vprintf(format, ap);
- va_end(ap);
- printf("\n");
+ switch (priority) {
+ case ANDROID_LOG_WARN:
+ FX_LOGVF(WARNING, local_tag, format, ap);
+ break;
+ case ANDROID_LOG_ERROR:
+ case ANDROID_LOG_FATAL:
+ FX_LOGVF(ERROR, local_tag, format, ap);
+ break;
+ case ANDROID_LOG_INFO:
+ default:
+ FX_LOGVF(INFO, local_tag, format, ap);
+ break;
+ }
return 1;
}
@@ -45,17 +56,12 @@
if (!local_tag) {
local_tag = "<NO_TAG>";
}
- printf("__android_log_assert: condition: %s tag: %s ", condition, local_tag);
- if (format) {
- va_list ap;
- va_start(ap, format);
- vprintf(format, ap);
- va_end(ap);
- }
- printf("\n");
+ va_list ap;
+ va_start(ap, format);
+ FX_LOGVF(ERROR, local_tag, format, ap);
+ va_end(ap);
- assert(0);
- exit(-1);
+ abort();
}
int sync_wait(int fd, int timeout) {
diff --git a/fuchsia/releasepackage.py b/fuchsia/releasepackage.py
index 2d4df50..dda9432 100644
--- a/fuchsia/releasepackage.py
+++ b/fuchsia/releasepackage.py
@@ -25,6 +25,7 @@
os.chdir(dir_path)
fuchsia_root = os.path.abspath(os.path.join(dir_path, "../../../"))
+fx_path = os.path.join(fuchsia_root, "scripts/fx")
if args.release_dir:
release_dir = os.path.abspath(args.release_dir)
@@ -40,11 +41,12 @@
else:
arch = "x64"
-target_name = "%s-shared/libvulkan_goldfish.so" % arch
+target_name = "%s-shared/lib.unstripped/libvulkan_goldfish.so" % arch
git_repo_location = "%s/third_party/goldfish-opengl" % fuchsia_root
package_dir = "libvulkan_goldfish/%s" % arch
package_name = "fuchsia/lib/libvulkan/%s" % package_dir
+repo_name = "goldfish-opengl"
git_branch = subprocess.check_output([
"git", "-C", git_repo_location, "rev-parse", "--abbrev-ref", "HEAD"
]).strip()
@@ -59,9 +61,7 @@
# Force ninja dry-run
ninja_output = subprocess.check_output([
- os.path.join(fuchsia_root, "buildtools/ninja"), "-C", release_dir, "-v",
- "-n",
- target_name
+ fx_path, "ninja", "-C", release_dir, "-v", "-n", target_name
])
if "ninja: no work to do." not in ninja_output:
@@ -73,8 +73,7 @@
sys.exit(1)
gn_output = subprocess.check_output([
- os.path.join(fuchsia_root, "buildtools/gn"), "args", release_dir,
- "--list=is_debug", "--short"
+ fx_path, "gn", "args", release_dir, "--list=is_debug", "--short"
]).strip()
if gn_output != "is_debug = false":
print("GN argument \"%s\" unexpected" % gn_output)
@@ -92,14 +91,18 @@
os.remove(full_name)
except:
pass
+try:
+ os.makedirs(package_dir)
+except:
+ pass
shutil.copyfile(source_file_name, full_name)
-cipd_path = os.path.join(fuchsia_root, "buildtools/cipd")
git_rev = subprocess.check_output(
["git", "-C", git_repo_location, "rev-parse", "HEAD"]).strip()
-cipd_command = "%s create -in %s -name %s -ref latest -install-mode copy -tag git_revision:%s" % (
- cipd_path, package_dir, package_name, git_rev)
+cipd_command = ("%s cipd create -in %s -name %s -ref latest"
+ " -install-mode copy -tag git_revision:%s") % (
+ fx_path, package_dir, package_name, git_rev)
print cipd_command
if not args.dry_run:
subprocess.check_call(cipd_command.split(" "))
diff --git a/fuchsia/service_connector.cc b/fuchsia/service_connector.cc
new file mode 100644
index 0000000..409ef63
--- /dev/null
+++ b/fuchsia/service_connector.cc
@@ -0,0 +1,28 @@
+// Copyright (C) 2019 The Android Open Source Project
+// Copyright (C) 2019 Google Inc.
+//
+// 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 "services/service_connector.h"
+
+namespace {
+PFN_ConnectToServiceAddr g_connection_function;
+}
+
+void SetConnectToServiceFunction(PFN_ConnectToServiceAddr func) {
+ g_connection_function = func;
+}
+
+PFN_ConnectToServiceAddr GetConnectToServiceFunction() {
+ return g_connection_function;
+}
diff --git a/shared/OpenglCodecCommon/Android.bp b/shared/OpenglCodecCommon/Android.bp
new file mode 100644
index 0000000..e56dfcd
--- /dev/null
+++ b/shared/OpenglCodecCommon/Android.bp
@@ -0,0 +1,5 @@
+cc_library_headers {
+ name: "goldfish_pipe_headers",
+ vendor_available: true,
+ export_include_dirs: ["."],
+}
diff --git a/shared/OpenglCodecCommon/CMakeLists.txt b/shared/OpenglCodecCommon/CMakeLists.txt
index ade4cc2..4528e13 100644
--- a/shared/OpenglCodecCommon/CMakeLists.txt
+++ b/shared/OpenglCodecCommon/CMakeLists.txt
@@ -3,7 +3,7 @@
# which will re-generate this file.
android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon/Android.mk" "b93e7098601bba92b0e1b4d4a94cee25d2181a9842c7902d5f339c405c862cea")
set(OpenglCodecCommon_host_src GLClientState.cpp GLESTextureUtils.cpp ChecksumCalculator.cpp GLSharedGroup.cpp glUtils.cpp IndexRangeCache.cpp SocketStream.cpp TcpStream.cpp auto_goldfish_dma_context.cpp goldfish_address_space.cpp goldfish_dma_host.cpp qemu_pipe_host.cpp)
-android_add_shared_library(OpenglCodecCommon_host)
+android_add_library(TARGET OpenglCodecCommon_host SHARED LICENSE Apache-2.0 SRC GLClientState.cpp GLESTextureUtils.cpp ChecksumCalculator.cpp GLSharedGroup.cpp glUtils.cpp IndexRangeCache.cpp SocketStream.cpp TcpStream.cpp auto_goldfish_dma_context.cpp goldfish_address_space.cpp goldfish_dma_host.cpp qemu_pipe_host.cpp)
target_include_directories(OpenglCodecCommon_host PRIVATE ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
target_compile_definitions(OpenglCodecCommon_host PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"eglCodecCommon\"")
target_compile_options(OpenglCodecCommon_host PRIVATE "-fvisibility=default" "-Wno-unused-parameter" "-Wno-unused-private-field")
diff --git a/shared/OpenglCodecCommon/GLClientState.cpp b/shared/OpenglCodecCommon/GLClientState.cpp
index f2bc0f5..c6140db 100644
--- a/shared/OpenglCodecCommon/GLClientState.cpp
+++ b/shared/OpenglCodecCommon/GLClientState.cpp
@@ -41,6 +41,13 @@
m_arrayBuffer = 0;
m_arrayBuffer_lastEncode = 0;
+
+ m_attribEnableCache = 0;
+ m_vaoAttribBindingCacheInvalid = 0xffff;
+ m_vaoAttribBindingHasClientArrayCache = 0;
+ m_vaoAttribBindingHasVboCache = 0;
+ m_noClientArraysCache = 0;
+
m_max_vertex_attrib_bindings = m_nLocations;
addVertexArrayObject(0);
setVertexArrayObject(0);
@@ -130,6 +137,12 @@
{
m_currVaoState[location].enableDirty |= (state != m_currVaoState[location].enabled);
m_currVaoState[location].enabled = state;
+ if (state) {
+ m_attribEnableCache |= (1 << location);
+ m_noClientArraysCache = 0;
+ } else {
+ m_attribEnableCache &= ~(1 << location);
+ }
}
void GLClientState::setVertexAttribState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data, bool isInt)
@@ -163,6 +176,9 @@
void GLClientState::setVertexAttribBinding(int attribindex, int bindingindex) {
m_currVaoState[attribindex].bindingindex = bindingindex;
+ m_currVaoState.bufferBinding(bindingindex).vertexAttribLoc = attribindex;
+ m_vaoAttribBindingCacheInvalid |= (1 << attribindex);
+ m_noClientArraysCache = 0;
}
void GLClientState::setVertexAttribFormat(int location, int size, GLenum type, GLboolean normalized, GLuint reloffset, bool isInt) {
@@ -267,8 +283,68 @@
return m_vaoMap.find(vao) != m_vaoMap.end();
}
-const GLClientState::VertexAttribState& GLClientState::getState(int location)
-{
+void GLClientState::getVBOUsage(bool* hasClientArrays, bool* hasVBOs) {
+ uint8_t todo_count = 0;
+ uint8_t todo[CODEC_MAX_VERTEX_ATTRIBUTES];
+
+ if (m_noClientArraysCache) {
+ *hasClientArrays = false;
+ *hasVBOs = true;
+ return;
+ }
+
+ for (int i = 0; i < CODEC_MAX_VERTEX_ATTRIBUTES; i++) {
+ if ((1 << i) & (m_attribEnableCache)) {
+ if (!((1 << i) & m_vaoAttribBindingCacheInvalid)) {
+ if ((1 << i) & m_vaoAttribBindingHasClientArrayCache) {
+ *hasClientArrays = true;
+ }
+ if ((1 << i) & m_vaoAttribBindingHasVboCache) {
+ *hasVBOs = true;
+ }
+ if (*hasClientArrays && *hasVBOs) return;
+ } else {
+ todo[todo_count] = i;
+ ++todo_count;
+ }
+ }
+ }
+
+ if (todo_count == 0 &&
+ !(*hasClientArrays) &&
+ *hasVBOs) {
+ m_noClientArraysCache = 1;
+ }
+
+ for (int k = 0; k < todo_count; ++k) {
+ int i = todo[k];
+ const GLClientState::BufferBinding& curr_binding =
+ m_currVaoState.bufferBindings_const()[
+ m_currVaoState[i].bindingindex];
+ GLuint bufferObject = curr_binding.buffer;
+ if (bufferObject == 0 && curr_binding.offset && hasClientArrays) {
+ *hasClientArrays = true;
+ m_vaoAttribBindingHasClientArrayCache |= (1 << i);
+ } else {
+ m_vaoAttribBindingHasClientArrayCache &= ~(1 << i);
+ }
+ if (bufferObject != 0 && hasVBOs) {
+ *hasVBOs = true;
+ m_vaoAttribBindingHasVboCache |= (1 << i);
+ } else {
+ m_vaoAttribBindingHasVboCache &= ~(1 << i);
+ }
+ m_vaoAttribBindingCacheInvalid &= ~(1 << i);
+ if (*hasClientArrays && *hasVBOs) return;
+ }
+
+ if (!(*hasClientArrays) &&
+ *hasVBOs) {
+ m_noClientArraysCache = 1;
+ }
+}
+
+const GLClientState::VertexAttribState& GLClientState::getState(int location) {
return m_currVaoState[location];
}
@@ -394,6 +470,8 @@
sClearIndexedBufferBinding(id, m_indexedAtomicCounterBuffers);
sClearIndexedBufferBinding(id, m_indexedShaderStorageBuffers);
sClearIndexedBufferBinding(id, m_currVaoState.bufferBindings());
+ m_vaoAttribBindingCacheInvalid = 0xffff;
+ m_noClientArraysCache = 0;
}
int GLClientState::bindBuffer(GLenum target, GLuint id)
@@ -474,6 +552,7 @@
m_currVaoState.bufferBinding(index).size = size;
m_currVaoState.bufferBinding(index).stride = stride;
m_currVaoState.bufferBinding(index).effectiveStride = effectiveStride;
+ m_vaoAttribBindingCacheInvalid |= (1 << m_currVaoState.bufferBinding(index).vertexAttribLoc);
return;
}
}
@@ -654,7 +733,7 @@
}
}
if (which_state != -1)
- *params = getState(which_state).data;
+ *params = m_currVaoState[which_state].data;
}
int GLClientState::setPixelStore(GLenum param, GLint value)
diff --git a/shared/OpenglCodecCommon/GLClientState.h b/shared/OpenglCodecCommon/GLClientState.h
index 49a63b6..5180338 100644
--- a/shared/OpenglCodecCommon/GLClientState.h
+++ b/shared/OpenglCodecCommon/GLClientState.h
@@ -139,6 +139,7 @@
GLsizeiptr size;
GLuint buffer;
GLuint divisor;
+ GLint vertexAttribLoc;
};
typedef std::vector<VertexAttribState> VertexAttribStateVector;
@@ -221,6 +222,7 @@
const BufferBinding& getCurrAttributeBindingInfo(int attribindex);
void setVertexAttribBinding(int attribindex, int bindingindex);
void setVertexAttribFormat(int location, int size, GLenum type, GLboolean normalized, GLuint reloffset, bool isInt = false);
+ void getVBOUsage(bool* hasClientArrays, bool* hasVBOs);
const VertexAttribState& getState(int location);
const VertexAttribState& getStateAndEnableDirty(int location, bool *enableChanged);
void updateEnableDirtyArrayForDraw();
@@ -450,6 +452,12 @@
VAOStateMap m_vaoMap;
VAOStateRef m_currVaoState;
+ uint16_t m_attribEnableCache;
+ uint16_t m_vaoAttribBindingCacheInvalid;
+ uint16_t m_vaoAttribBindingHasClientArrayCache;
+ uint16_t m_vaoAttribBindingHasVboCache;
+ uint8_t m_noClientArraysCache;
+
// Other buffer id's, other targets
GLuint m_copyReadBuffer;
GLuint m_copyWriteBuffer;
diff --git a/shared/OpenglCodecCommon/GLSharedGroup.cpp b/shared/OpenglCodecCommon/GLSharedGroup.cpp
index e4bc889..46d94a9 100755
--- a/shared/OpenglCodecCommon/GLSharedGroup.cpp
+++ b/shared/OpenglCodecCommon/GLSharedGroup.cpp
@@ -34,8 +34,7 @@
/**** ProgramData ****/
ProgramData::ProgramData() : m_numIndexes(0),
- m_initialized(false),
- m_locShiftWAR(false) {
+ m_initialized(false) {
m_Indexes = NULL;
}
@@ -46,7 +45,6 @@
delete [] m_Indexes;
m_Indexes = new IndexInfo[numIndexes];
- m_locShiftWAR = false;
}
bool ProgramData::isInitialized() {
@@ -68,14 +66,6 @@
m_Indexes[index].base = base;
m_Indexes[index].size = size;
m_Indexes[index].type = type;
-
- if (index > 0) {
- m_Indexes[index].appBase = m_Indexes[index-1].appBase +
- m_Indexes[index-1].size;
- } else {
- m_Indexes[index].appBase = 0;
- }
-
m_Indexes[index].hostLocsPerElement = 1;
m_Indexes[index].flags = 0;
m_Indexes[index].samplerValue = 0;
@@ -112,52 +102,6 @@
return 0;
}
-void ProgramData::setupLocationShiftWAR() {
- m_locShiftWAR = false;
- for (GLuint i= 0; i < m_numIndexes; i++) {
- if (0 != (m_Indexes[i].base & 0xffff)) {
- return;
- }
- }
-
- // if we have one uniform at location 0, we do not need the WAR.
- if (m_numIndexes > 1) m_locShiftWAR = true;
-}
-
-GLint ProgramData::locationWARHostToApp(GLint hostLoc, GLint arrIndex) {
-
- if (!m_locShiftWAR) return hostLoc;
-
- GLuint index = getIndexForLocation(hostLoc);
-
- if (index < m_numIndexes) {
- if (arrIndex > 0) {
- m_Indexes[index].hostLocsPerElement =
- (hostLoc - m_Indexes[index].base) / arrIndex;
- }
- return m_Indexes[index].appBase + arrIndex;
- }
-
- return -1;
-}
-
-GLint ProgramData::locationWARAppToHost(GLint appLoc) {
-
- if (!m_locShiftWAR) return appLoc;
-
- for (GLuint i = 0; i < m_numIndexes; i++) {
- GLint elemIndex =
- appLoc - m_Indexes[i].appBase;
-
- if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
- return m_Indexes[i].base +
- elemIndex * m_Indexes[i].hostLocsPerElement;
- }
- }
-
- return -1;
-}
-
GLint ProgramData::getNextSamplerUniform(
GLint index, GLint* val, GLenum* target) {
@@ -187,7 +131,7 @@
for (GLuint i = 0; i < m_numIndexes; i++) {
- GLint elemIndex = appLoc - m_Indexes[i].appBase;
+ GLint elemIndex = appLoc - m_Indexes[i].base;
if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
if (m_Indexes[i].type == GL_SAMPLER_2D) {
@@ -520,77 +464,6 @@
return false;
}
-void GLSharedGroup::setupLocationShiftWAR(GLuint program) {
-
- android::AutoMutex _lock(m_lock);
-
- ProgramData* pData =
- findObjectOrDefault(m_programs, program);
-
- if (pData) pData->setupLocationShiftWAR();
-}
-
-GLint GLSharedGroup::locationWARHostToApp(
- GLuint program, GLint hostLoc, GLint arrIndex) {
-
- android::AutoMutex _lock(m_lock);
-
- ProgramData* pData = findObjectOrDefault(m_programs, program);
-
- if (pData) return pData->locationWARHostToApp(hostLoc, arrIndex);
-
- if (m_shaderProgramIdMap.find(program) ==
- m_shaderProgramIdMap.end()) return hostLoc;
-
- ShaderProgramData* spData =
- findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[program]);
-
- if (spData) return spData->programData.locationWARHostToApp(hostLoc, arrIndex);
-
- return hostLoc;
-}
-
-GLint GLSharedGroup::locationWARAppToHost(GLuint program, GLint appLoc) {
-
- android::AutoMutex _lock(m_lock);
-
- ProgramData* pData =
- findObjectOrDefault(m_programs, program);
-
- if (pData) return pData->locationWARAppToHost(appLoc);
-
- if (m_shaderProgramIdMap.find(program) ==
- m_shaderProgramIdMap.end()) return appLoc;
-
- ShaderProgramData* spData =
- findObjectOrDefault(
- m_shaderPrograms, m_shaderProgramIdMap[program]);
-
- if (spData) return spData->programData.locationWARAppToHost(appLoc);
-
- return appLoc;
-}
-
-bool GLSharedGroup::needUniformLocationWAR(GLuint program) {
-
- android::AutoMutex _lock(m_lock);
-
- ProgramData* pData =
- findObjectOrDefault(m_programs, program);
-
- if (pData) return pData->needUniformLocationWAR();
-
- if (m_shaderProgramIdMap.find(program) ==
- m_shaderProgramIdMap.end()) return false;
-
- ShaderProgramData* spData =
- findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[program]);
-
- if (spData) return spData->programData.needUniformLocationWAR();
-
- return false;
-}
-
GLint GLSharedGroup::getNextSamplerUniform(
GLuint program, GLint index, GLint* val, GLenum* target) const {
@@ -787,8 +660,3 @@
}
}
}
-
-void GLSharedGroup::setupShaderProgramLocationShiftWAR(GLuint shaderProgram) {
- ShaderProgramData* spData = getShaderProgramData(shaderProgram);
- spData->programData.setupLocationShiftWAR();
-}
diff --git a/shared/OpenglCodecCommon/GLSharedGroup.h b/shared/OpenglCodecCommon/GLSharedGroup.h
index 9ef92ea..d471795 100755
--- a/shared/OpenglCodecCommon/GLSharedGroup.h
+++ b/shared/OpenglCodecCommon/GLSharedGroup.h
@@ -71,7 +71,6 @@
GLint base;
GLint size;
GLenum type;
- GLint appBase;
GLint hostLocsPerElement;
GLuint flags;
GLint samplerValue; // only set for sampler uniforms
@@ -80,7 +79,6 @@
GLuint m_numIndexes;
IndexInfo* m_Indexes;
bool m_initialized;
- bool m_locShiftWAR;
std::vector<GLuint> m_shaders;
@@ -98,11 +96,6 @@
GLuint getIndexForLocation(GLint location);
GLenum getTypeForLocation(GLint location);
- bool needUniformLocationWAR() const { return m_locShiftWAR; }
- void setupLocationShiftWAR();
- GLint locationWARHostToApp(GLint hostLoc, GLint arrIndex);
- GLint locationWARAppToHost(GLint appLoc);
-
GLint getNextSamplerUniform(GLint index, GLint* val, GLenum* target);
bool setSamplerUniform(GLint appLoc, GLint val, GLenum* target);
@@ -165,10 +158,6 @@
void deleteProgramData(GLuint program);
void setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type, const char* name);
GLenum getProgramUniformType(GLuint program, GLint location);
- void setupLocationShiftWAR(GLuint program);
- GLint locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex);
- GLint locationWARAppToHost(GLuint program, GLint appLoc);
- bool needUniformLocationWAR(GLuint program);
GLint getNextSamplerUniform(GLuint program, GLint index, GLint* val, GLenum* target) const;
bool setSamplerUniform(GLuint program, GLint appLoc, GLint val, GLenum* target);
@@ -187,7 +176,6 @@
void deleteShaderProgramData(GLuint shaderProgramName);
void initShaderProgramData(GLuint shaderProgram, GLuint numIndices);
void setShaderProgramIndexInfo(GLuint shaderProgram, GLuint index, GLint base, GLint size, GLenum type, const char* name);
- void setupShaderProgramLocationShiftWAR(GLuint shaderProgram);
};
typedef SmartPtr<GLSharedGroup> GLSharedGroupPtr;
diff --git a/shared/OpenglCodecCommon/goldfish_address_space.h b/shared/OpenglCodecCommon/goldfish_address_space.h
index f02fa2e..064f601 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space.h
+++ b/shared/OpenglCodecCommon/goldfish_address_space.h
@@ -19,7 +19,7 @@
#include <stddef.h>
#ifdef __Fuchsia__
-#include <fuchsia/hardware/goldfish/address/space/cpp/fidl.h>
+#include <fuchsia/hardware/goldfish/cpp/fidl.h>
#endif
class GoldfishAddressSpaceBlock;
@@ -43,11 +43,16 @@
typedef int address_space_handle_t;
#endif
+enum GoldfishAddressSpaceSubdeviceType {
+ NoSubdevice = -1,
+ Graphics = 0,
+ Media = 1,
+ HostMemoryAllocator = 5,
+};
+
class GoldfishAddressSpaceBlockProvider {
public:
- static const uint64_t SUBDEVICE_TYPE_NO_SUBDEVICE_ID = -1;
- static const uint64_t SUBDEVICE_TYPE_HOST_MEMORY_ALLOCATOR_ID = 5;
- GoldfishAddressSpaceBlockProvider(uint64_t subdevice);
+ GoldfishAddressSpaceBlockProvider(GoldfishAddressSpaceSubdeviceType subdevice);
~GoldfishAddressSpaceBlockProvider();
private:
@@ -60,7 +65,8 @@
static void closeHandle(address_space_handle_t handle);
#ifdef __Fuchsia__
- fuchsia::hardware::goldfish::address::space::DeviceSyncPtr m_device;
+ fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr m_device;
+ fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr m_child_driver;
#else // __Fuchsia__
address_space_handle_t m_handle;
#endif // !__Fuchsia__
@@ -75,6 +81,7 @@
~GoldfishAddressSpaceBlock();
bool allocate(GoldfishAddressSpaceBlockProvider *provider, size_t size);
+ bool claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size);
uint64_t physAddr() const;
uint64_t hostAddr() const;
uint64_t offset() const { return m_offset; }
@@ -91,7 +98,7 @@
GoldfishAddressSpaceBlock &operator=(const GoldfishAddressSpaceBlock &);
#ifdef __Fuchsia__
- fuchsia::hardware::goldfish::address::space::DeviceSyncPtr* m_device;
+ fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* m_driver;
uint32_t m_vmo;
#else // __Fuchsia__
address_space_handle_t m_handle;
@@ -102,6 +109,7 @@
uint64_t m_host_addr;
uint64_t m_offset;
uint64_t m_size;
+ bool m_is_shared_mapping;
};
class GoldfishAddressSpaceHostMemoryAllocator {
@@ -119,4 +127,41 @@
GoldfishAddressSpaceBlockProvider m_provider;
};
+// Convenience functions that run address space driver api without wrapping in
+// a class. Useful for when a client wants to manage the driver handle directly
+// (e.g., mmaping() more than one region associated with a single handle will
+// require different lifetime expectations versus GoldfishAddressSpaceBlock).
+
+// We also expose the ping info struct that is shared between host and guest.
+struct goldfish_address_space_ping {
+ uint64_t offset;
+ uint64_t size;
+ uint64_t metadata;
+ uint32_t version;
+ uint32_t wait_fd;
+ uint32_t wait_flags;
+ uint32_t direction;
+};
+
+address_space_handle_t goldfish_address_space_open();
+void goldfish_address_space_close(address_space_handle_t);
+
+bool goldfish_address_space_allocate(
+ address_space_handle_t, size_t size, uint64_t* phys_addr, uint64_t* offset);
+bool goldfish_address_space_free(
+ address_space_handle_t, uint64_t offset);
+
+bool goldfish_address_space_claim_shared(
+ address_space_handle_t, uint64_t offset, uint64_t size);
+bool goldfish_address_space_unclaim_shared(
+ address_space_handle_t, uint64_t offset);
+
+// pgoff is the offset into the page to return in the result
+void* goldfish_address_space_map(
+ address_space_handle_t, uint64_t offset, uint64_t size, uint64_t pgoff = 0);
+void goldfish_address_space_unmap(void* ptr, uint64_t size);
+
+bool goldfish_address_space_set_subdevice_type(address_space_handle_t, GoldfishAddressSpaceSubdeviceType type, address_space_handle_t*);
+bool goldfish_address_space_ping(address_space_handle_t, struct goldfish_address_space_ping*);
+
#endif // #ifndef ANDROID_INCLUDE_HARDWARE_GOLDFISH_ADDRESS_SPACE_H
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_android.impl b/shared/OpenglCodecCommon/goldfish_address_space_android.impl
index 90fc097..646695f 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_android.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_android.impl
@@ -41,14 +41,9 @@
__u64 phys_addr;
};
-struct goldfish_address_space_ping {
+struct goldfish_address_space_claim_shared {
__u64 offset;
__u64 size;
- __u64 metadata;
- __u32 version;
- __u32 wait_fd;
- __u32 wait_flags;
- __u32 direction;
};
#define GOLDFISH_ADDRESS_SPACE_IOCTL_MAGIC 'G'
@@ -56,6 +51,8 @@
#define GOLDFISH_ADDRESS_SPACE_IOCTL_ALLOCATE_BLOCK GOLDFISH_ADDRESS_SPACE_IOCTL_OP(10, struct goldfish_address_space_allocate_block)
#define GOLDFISH_ADDRESS_SPACE_IOCTL_DEALLOCATE_BLOCK GOLDFISH_ADDRESS_SPACE_IOCTL_OP(11, __u64)
#define GOLDFISH_ADDRESS_SPACE_IOCTL_PING GOLDFISH_ADDRESS_SPACE_IOCTL_OP(12, struct goldfish_address_space_ping)
+#define GOLDFISH_ADDRESS_SPACE_IOCTL_CLAIM_SHARED GOLDFISH_ADDRESS_SPACE_IOCTL_OP(13, struct goldfish_address_space_claim_shared)
+#define GOLDFISH_ADDRESS_SPACE_IOCTL_UNCLAIM_SHARED GOLDFISH_ADDRESS_SPACE_IOCTL_OP(14, __u64)
const char GOLDFISH_ADDRESS_SPACE_DEVICE_NAME[] = "/dev/goldfish_address_space";
@@ -92,12 +89,22 @@
return ioctl_ping(fd, &request);
}
+long ioctl_claim_shared(int fd, struct goldfish_address_space_claim_shared *request)
+{
+ return ::ioctl(fd, GOLDFISH_ADDRESS_SPACE_IOCTL_CLAIM_SHARED, request);
+}
+
+long ioctl_unclaim_shared(int fd, uint64_t offset)
+{
+ return ::ioctl(fd, GOLDFISH_ADDRESS_SPACE_IOCTL_UNCLAIM_SHARED, &offset);
+}
+
} // namespace
-GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider(uint64_t subdevice)
+GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider(GoldfishAddressSpaceSubdeviceType subdevice)
: m_handle(create_address_space_fd())
{
- if ((subdevice != SUBDEVICE_TYPE_NO_SUBDEVICE_ID) && is_opened()) {
+ if ((subdevice != GoldfishAddressSpaceSubdeviceType::NoSubdevice) && is_opened()) {
const long ret = set_address_space_subdevice_type(m_handle, subdevice);
if (ret) {
ALOGE("%s: set_address_space_subdevice_type failed for device_type=%lu, ret=%ld",
@@ -187,6 +194,7 @@
m_offset = request.offset;
m_size = request.size;
m_handle = provider->m_handle;
+ m_is_shared_mapping = false;
ALOGD("%s: ioctl allocate returned offset 0x%llx size 0x%llx\n", __func__,
(unsigned long long)m_offset,
@@ -196,6 +204,35 @@
}
}
+bool GoldfishAddressSpaceBlock::claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size)
+{
+ ALOGD("%s: Ask to claim region [0x%llx 0x%llx]\n", __func__,
+ (unsigned long long)offset,
+ (unsigned long long)offset + size);
+
+ destroy();
+
+ if (!provider->is_opened()) {
+ return false;
+ }
+
+ struct goldfish_address_space_claim_shared request;
+ request.offset = offset;
+ request.size = size;
+ long res = ioctl_claim_shared(provider->m_handle, &request);
+
+ if (res) {
+ return false;
+ }
+
+ m_offset = offset;
+ m_size = size;
+ m_handle = provider->m_handle;
+ m_is_shared_mapping = true;
+
+ return true;
+}
+
uint64_t GoldfishAddressSpaceBlock::physAddr() const
{
return m_phys_addr;
@@ -246,12 +283,24 @@
}
if (m_size) {
- const long res = ioctl_deallocate(m_handle, m_offset);
- if (res) {
- ALOGE("ioctl_deallocate failed, res=%ld", res);
- ::abort();
+ long res = -EINVAL;
+
+ if (m_is_shared_mapping) {
+ res = ioctl_unclaim_shared(m_handle, m_offset);
+ if (res) {
+ ALOGE("ioctl_unclaim_shared failed, res=%ld", res);
+ ::abort();
+ }
+ } else {
+ res = ioctl_deallocate(m_handle, m_offset);
+ if (res) {
+ ALOGE("ioctl_deallocate failed, res=%ld", res);
+ ::abort();
+ }
}
+ m_is_shared_mapping = false;
+
m_phys_addr = 0;
m_host_addr = 0;
m_offset = 0;
@@ -289,7 +338,7 @@
}
GoldfishAddressSpaceHostMemoryAllocator::GoldfishAddressSpaceHostMemoryAllocator()
- : m_provider(GoldfishAddressSpaceBlockProvider::SUBDEVICE_TYPE_HOST_MEMORY_ALLOCATOR_ID) {}
+ : m_provider(GoldfishAddressSpaceSubdeviceType::HostMemoryAllocator) {}
bool GoldfishAddressSpaceHostMemoryAllocator::is_opened() const { return m_provider.is_opened(); }
@@ -355,3 +404,108 @@
block->replace(NULL);
}
+
+address_space_handle_t goldfish_address_space_open() {
+ return ::open(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME, O_RDWR);
+}
+
+void goldfish_address_space_close(address_space_handle_t handle) {
+ ::close(handle);
+}
+
+bool goldfish_address_space_allocate(
+ address_space_handle_t handle,
+ size_t size, uint64_t* phys_addr, uint64_t* offset) {
+
+ struct goldfish_address_space_allocate_block request;
+ ::memset(&request, 0, sizeof(request));
+ request.size = size;
+
+ long res = ioctl_allocate(handle, &request);
+
+ if (res) return false;
+
+ *phys_addr = request.phys_addr;
+ *offset = request.offset;
+ return true;
+}
+
+bool goldfish_address_space_free(
+ address_space_handle_t handle, uint64_t offset) {
+
+ long res = ioctl_deallocate(handle, offset);
+
+ if (res) {
+ ALOGE("ioctl_deallocate failed, res=%ld", res);
+ ::abort();
+ }
+
+ return true;
+}
+
+bool goldfish_address_space_claim_shared(
+ address_space_handle_t handle, uint64_t offset, uint64_t size) {
+
+ struct goldfish_address_space_claim_shared request;
+ request.offset = offset;
+ request.size = size;
+ long res = ioctl_claim_shared(handle, &request);
+
+ if (res) return false;
+
+ return true;
+}
+
+bool goldfish_address_space_unclaim_shared(
+ address_space_handle_t handle, uint64_t offset) {
+ long res = ioctl_unclaim_shared(handle, offset);
+ if (res) {
+ ALOGE("ioctl_unclaim_shared failed, res=%ld", res);
+ ::abort();
+ }
+
+ return true;
+}
+
+// pgoff is the offset into the page to return in the result
+void* goldfish_address_space_map(
+ address_space_handle_t handle,
+ uint64_t offset, uint64_t size,
+ uint64_t pgoff) {
+
+ void* res = ::mmap64(0, size, PROT_WRITE, MAP_SHARED, handle, offset);
+
+ if (res == MAP_FAILED) {
+ ALOGE("%s: failed to map. errno: %d\n", __func__, errno);
+ return 0;
+ }
+
+ return (void*)(((char*)res) + (uintptr_t)(pgoff & (PAGE_SIZE - 1)));
+}
+
+void goldfish_address_space_unmap(void* ptr, uint64_t size) {
+ void* pagePtr = (void*)(((uintptr_t)ptr) & ~(PAGE_SIZE - 1));
+ ::munmap(pagePtr, size);
+}
+
+bool goldfish_address_space_set_subdevice_type(
+ address_space_handle_t handle, GoldfishAddressSpaceSubdeviceType type,
+ address_space_handle_t* handle_out) {
+ struct goldfish_address_space_ping request;
+ request.metadata = (uint64_t)type;
+ *handle_out = handle;
+ return goldfish_address_space_ping(handle, &request);
+}
+
+bool goldfish_address_space_ping(
+ address_space_handle_t handle,
+ struct goldfish_address_space_ping* ping) {
+ long res = ioctl_ping(handle, ping);
+
+ if (res) {
+ ALOGE("%s: ping failed: errno: %d\n", __func__, errno);
+ return false;
+ }
+
+ return true;
+}
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl b/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl
index d11fcd1..4d54eed 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_fuchsia.impl
@@ -15,7 +15,6 @@
#include <memory>
#include <fcntl.h>
-#include <lib/fdio/fdio.h>
#include <lib/zx/channel.h>
#include <lib/zx/vmo.h>
#include <log/log.h>
@@ -28,24 +27,43 @@
#include <zircon/syscalls/object.h>
#include "goldfish_address_space.h"
+#include "android/base/synchronization/AndroidLock.h"
+#include "services/service_connector.h"
-GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider(uint64_t subdevice) {
+#include <unordered_map>
- if (subdevice != SUBDEVICE_TYPE_NO_SUBDEVICE_ID) {
+using android::base::guest::AutoLock;
+using android::base::guest::Lock;
+
+using fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr;
+using fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr;
+using fuchsia::hardware::goldfish::AddressSpaceChildDriverType;
+using fuchsia::hardware::goldfish::AddressSpaceChildDriverPingMessage;
+
+GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider(GoldfishAddressSpaceSubdeviceType subdevice) {
+
+ if (subdevice != GoldfishAddressSpaceSubdeviceType::NoSubdevice) {
ALOGE("%s: Tried to use a nontrivial subdevice when support has not been added\n", __func__);
abort();
}
- zx::channel channel;
- zx_status_t status =
- fdio_get_service_handle(::open(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME, O_RDWR),
- channel.reset_and_get_address());
- if (status != ZX_OK) {
- ALOGE("%s: failed to get service handle for " GOLDFISH_ADDRESS_SPACE_DEVICE_NAME ": %d",
- __FUNCTION__, status);
+ zx::channel channel(GetConnectToServiceFunction()(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME));
+ if (!channel) {
+ ALOGE("%s: failed to get service handle for " GOLDFISH_ADDRESS_SPACE_DEVICE_NAME,
+ __FUNCTION__);
return;
}
m_device.Bind(std::move(channel));
+
+ zx_status_t status = (*m_device).OpenChildDriver(
+ static_cast<fuchsia::hardware::goldfish::AddressSpaceChildDriverType>(0 /* graphics */),
+ m_child_driver.NewRequest());
+
+ if (status != ZX_OK) {
+ ALOGE("%s: failed to open child driver: %d",
+ __FUNCTION__, status);
+ return;
+ }
}
GoldfishAddressSpaceBlockProvider::~GoldfishAddressSpaceBlockProvider()
@@ -61,7 +79,7 @@
// address_space_handle_t GoldfishAddressSpaceBlockProvider::release() - not imeplemented
GoldfishAddressSpaceBlock::GoldfishAddressSpaceBlock()
- : m_device(NULL)
+ : m_driver(NULL)
, m_vmo(ZX_HANDLE_INVALID)
, m_mmaped_ptr(NULL)
, m_phys_addr(0)
@@ -82,7 +100,7 @@
m_host_addr = rhs.m_host_addr;
m_offset = rhs.m_offset;
m_size = rhs.m_size;
- m_device = rhs.m_device;
+ m_driver = rhs.m_driver;
return *this;
}
@@ -98,28 +116,35 @@
return false;
}
- fuchsia::hardware::goldfish::address::space::DeviceSyncPtr* device = &provider->m_device;
+ fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* driver = &provider->m_child_driver;
int32_t res = ZX_OK;
zx::vmo vmo;
- zx_status_t status = (*device)->AllocateBlock(size, &res, &m_phys_addr, &vmo);
+ zx_status_t status = (*driver)->AllocateBlock(size, &res, &m_phys_addr, &vmo);
if (status != ZX_OK || res != ZX_OK) {
ALOGE("%s: allocate block failed: %d:%d", __func__, status, res);
return false;
}
- m_offset = 0;
m_size = size;
m_vmo = vmo.release();
+ m_offset = 0;
+ m_is_shared_mapping = false;
ALOGD("%s: allocate returned offset 0x%llx size 0x%llx\n", __func__,
(unsigned long long)m_offset,
(unsigned long long)m_size);
- m_device = device;
+ m_driver = driver;
return true;
}
+bool GoldfishAddressSpaceBlock::claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size)
+{
+ ALOGE("%s: FATAL: not supported\n", __func__);
+ abort();
+}
+
uint64_t GoldfishAddressSpaceBlock::physAddr() const
{
return m_phys_addr;
@@ -179,12 +204,23 @@
if (m_size) {
zx_handle_close(m_vmo);
m_vmo = ZX_HANDLE_INVALID;
- int32_t res = ZX_OK;
- zx_status_t status = (*m_device)->DeallocateBlock(m_phys_addr, &res);
- if (status != ZX_OK || res != ZX_OK) {
- ALOGE("%s: deallocate block failed: %d:%d", __func__, status, res);
+ if (m_is_shared_mapping) {
+ // TODO
+ ALOGE("%s: unsupported: GoldfishAddressSpaceBlock destroy() for shared regions\n", __func__);
+ abort();
+ // int32_t res = ZX_OK;
+ // zx_status_t status = (*m_driver)->UnclaimShared(m_offset, &res);
+ // if (status != ZX_OK || res != ZX_OK) {
+ // ALOGE("%s: unclaim shared block failed: %d:%d", __func__, status, res);
+ // }
+ } else {
+ int32_t res = ZX_OK;
+ zx_status_t status = (*m_driver)->DeallocateBlock(m_phys_addr, &res);
+ if (status != ZX_OK || res != ZX_OK) {
+ ALOGE("%s: deallocate block failed: %d:%d", __func__, status, res);
+ }
}
- m_device = NULL;
+ m_driver = NULL;
m_phys_addr = 0;
m_host_addr = 0;
m_offset = 0;
@@ -193,9 +229,7 @@
}
GoldfishAddressSpaceHostMemoryAllocator::GoldfishAddressSpaceHostMemoryAllocator()
- : m_provider(GoldfishAddressSpaceBlockProvider::SUBDEVICE_TYPE_HOST_MEMORY_ALLOCATOR_ID)
-{
-}
+ : m_provider(GoldfishAddressSpaceSubdeviceType::HostMemoryAllocator) { }
long GoldfishAddressSpaceHostMemoryAllocator::hostMalloc(GoldfishAddressSpaceBlock *block, size_t size)
{
@@ -205,3 +239,221 @@
void GoldfishAddressSpaceHostMemoryAllocator::hostFree(GoldfishAddressSpaceBlock *block)
{
}
+
+class VmoStore {
+public:
+ struct Info {
+ zx_handle_t vmo = ZX_HANDLE_INVALID;
+ uint64_t phys_addr = 0;
+ };
+
+ void add(uint64_t offset, const Info& info) {
+ AutoLock lock(mLock);
+ mInfo[offset] = info;
+ }
+
+ void remove(uint64_t offset) {
+ AutoLock lock(mLock);
+ mInfo.erase(offset);
+ }
+
+ Info get(uint64_t offset) {
+ Info res;
+ AutoLock lock(mLock);
+ auto it = mInfo.find(offset);
+ if (it == mInfo.end()) {
+ ALOGE("VmoStore::%s cannot find info on offset 0x%llx\n", __func__,
+ (unsigned long long)offset);
+ return res;
+ }
+ res = it->second;
+ return res;
+ }
+
+private:
+ Lock mLock;
+ std::unordered_map<uint64_t, Info> mInfo;
+};
+
+static Lock sVmoStoreInitLock;
+static VmoStore* sVmoStore = nullptr;
+
+static VmoStore* getVmoStore() {
+ AutoLock lock(sVmoStoreInitLock);
+ if (!sVmoStore) sVmoStore = new VmoStore;
+ return sVmoStore;
+}
+
+address_space_handle_t goldfish_address_space_open() {
+ zx::channel channel(GetConnectToServiceFunction()(GOLDFISH_ADDRESS_SPACE_DEVICE_NAME));
+ if (!channel) {
+ ALOGE("%s: failed to get service handle for " GOLDFISH_ADDRESS_SPACE_DEVICE_NAME,
+ __FUNCTION__);
+ return 0;
+ }
+ fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr*
+ deviceSync = new fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr;
+ deviceSync->Bind(std::move(channel));
+ return (address_space_handle_t)deviceSync;
+}
+
+void goldfish_address_space_close(address_space_handle_t handle) {
+ fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr* deviceSync =
+ reinterpret_cast<
+ fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr*>(handle);
+ delete deviceSync;
+}
+
+bool goldfish_address_space_set_subdevice_type(
+ address_space_handle_t handle, GoldfishAddressSpaceSubdeviceType type,
+ address_space_handle_t* handle_out) {
+
+ fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr* deviceSync =
+ reinterpret_cast<
+ fuchsia::hardware::goldfish::AddressSpaceDeviceSyncPtr*>(handle);
+
+ fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr*
+ childSync = new fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr;
+
+ zx_status_t res = (*(*deviceSync)).OpenChildDriver(
+ static_cast<fuchsia::hardware::goldfish::AddressSpaceChildDriverType>(type),
+ (*childSync).NewRequest());
+
+ // On creating a subdevice, in our use cases we wont be needing the
+ // original device sync anymore, so get rid of it.
+ delete deviceSync;
+
+ *handle_out = (void*)childSync;
+
+ return true;
+}
+
+bool goldfish_address_space_allocate(
+ address_space_handle_t handle,
+ size_t size, uint64_t* phys_addr, uint64_t* offset) {
+ fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* deviceSync =
+ reinterpret_cast<
+ fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr*>(handle);
+
+ int32_t res = ZX_OK;
+ zx::vmo vmo;
+ zx_status_t status = (*(*deviceSync)).AllocateBlock(size, &res, phys_addr, &vmo);
+ if (status != ZX_OK || res != ZX_OK) {
+ ALOGE("%s: allocate block failed: %d:%d", __func__, status, res);
+ return false;
+ }
+
+ *offset = 0;
+
+ VmoStore::Info info = {
+ vmo.release(),
+ *phys_addr,
+ };
+
+ getVmoStore()->add(*offset, info);
+ return true;
+}
+
+bool goldfish_address_space_free(
+ address_space_handle_t handle, uint64_t offset) {
+ auto info = getVmoStore()->get(offset);
+ if (info.vmo == ZX_HANDLE_INVALID) return false;
+ zx_handle_close(info.vmo);
+
+ fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* deviceSync =
+ reinterpret_cast<
+ fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr*>(handle);
+
+ int32_t res = ZX_OK;
+ zx_status_t status = (*(*deviceSync)).DeallocateBlock(info.phys_addr, &res);
+ if (status != ZX_OK || res != ZX_OK) {
+ ALOGE("%s: deallocate block failed: %d:%d", __func__, status, res);
+ return false;
+ }
+
+ return true;
+}
+
+bool goldfish_address_space_claim_shared(
+ address_space_handle_t handle, uint64_t offset, uint64_t size) {
+
+ fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* deviceSync =
+ reinterpret_cast<
+ fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr*>(handle);
+ zx::vmo vmo;
+ zx_status_t res;
+ zx_status_t status = (*(*deviceSync)).ClaimSharedBlock(offset, size, &res, &vmo);
+
+ VmoStore::Info info = {
+ vmo.release(),
+ };
+
+ getVmoStore()->add(offset, info);
+
+ if (status != ZX_OK) return false;
+
+ return true;
+}
+
+bool goldfish_address_space_unclaim_shared(
+ address_space_handle_t handle, uint64_t offset) {
+ fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr* deviceSync =
+ reinterpret_cast<
+ fuchsia::hardware::goldfish::AddressSpaceChildDriverSyncPtr*>(handle);
+ zx::vmo vmo;
+ zx_status_t res;
+ zx_status_t status = (*(*deviceSync)).UnclaimSharedBlock(offset, &res);
+
+ if (status != ZX_OK) return false;
+
+ getVmoStore()->remove(offset);
+ return true;
+}
+
+// pgoff is the offset into the page to return in the result
+void* goldfish_address_space_map(
+ address_space_handle_t handle,
+ uint64_t offset, uint64_t size,
+ uint64_t pgoff) {
+
+ auto info = getVmoStore()->get(offset);
+ if (info.vmo == ZX_HANDLE_INVALID) return nullptr;
+
+ zx_vaddr_t ptr = 0;
+ zx_status_t status =
+ zx_vmar_map(zx_vmar_root_self(),
+ ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
+ 0, info.vmo,
+ 0, size,
+ &ptr);
+ return (void*)(((char*)ptr) + (uintptr_t)(pgoff & (PAGE_SIZE - 1)));
+}
+
+void goldfish_address_space_unmap(void* ptr, uint64_t size) {
+ zx_vmar_unmap(zx_vmar_root_self(),
+ (zx_vaddr_t)(((uintptr_t)ptr) & (uintptr_t)(~(PAGE_SIZE - 1))),
+ size);
+}
+
+bool goldfish_address_space_ping(
+ address_space_handle_t handle,
+ struct goldfish_address_space_ping* ping) {
+
+ AddressSpaceChildDriverPingMessage fuchsiaPing =
+ *(AddressSpaceChildDriverPingMessage*)ping;
+
+ AddressSpaceChildDriverSyncPtr* deviceSync =
+ reinterpret_cast<
+ AddressSpaceChildDriverSyncPtr*>(handle);
+
+ AddressSpaceChildDriverPingMessage res;
+ zx_status_t pingStatus;
+ zx_status_t status = (*(*deviceSync)).Ping(fuchsiaPing, &pingStatus, &res);
+
+ if (pingStatus != ZX_OK) {
+ return false;
+ }
+
+ *ping = *(struct goldfish_address_space_ping*)(&res);
+ return true;
+}
diff --git a/shared/OpenglCodecCommon/goldfish_address_space_host.impl b/shared/OpenglCodecCommon/goldfish_address_space_host.impl
index 7d07d8b..6630ed7 100644
--- a/shared/OpenglCodecCommon/goldfish_address_space_host.impl
+++ b/shared/OpenglCodecCommon/goldfish_address_space_host.impl
@@ -13,15 +13,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include <memory>
#include "android/emulation/hostdevices/HostAddressSpace.h"
+#include <memory>
+
#if PLATFORM_SDK_VERSION < 26
#include <cutils/log.h>
#else
#include <log/log.h>
#endif
+#include <errno.h>
#include "goldfish_address_space.h"
namespace {
@@ -34,10 +36,10 @@
using android::HostAddressSpaceDevice;
using android::emulation::AddressSpaceDevicePingInfo;
-GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider(uint64_t subdevice)
+GoldfishAddressSpaceBlockProvider::GoldfishAddressSpaceBlockProvider(GoldfishAddressSpaceSubdeviceType subdevice)
: m_handle(HostAddressSpaceDevice::get()->open())
{
- if ((subdevice != SUBDEVICE_TYPE_NO_SUBDEVICE_ID) && is_opened()) {
+ if ((subdevice != GoldfishAddressSpaceSubdeviceType::NoSubdevice) && is_opened()) {
AddressSpaceDevicePingInfo request;
::memset(&request, 0, sizeof(request));
request.metadata = subdevice;
@@ -84,7 +86,8 @@
, m_phys_addr(0)
, m_host_addr(0)
, m_offset(0)
- , m_size(0) {}
+ , m_size(0)
+ , m_is_shared_mapping(false) {}
GoldfishAddressSpaceBlock::~GoldfishAddressSpaceBlock()
{
@@ -98,6 +101,7 @@
m_host_addr = rhs.m_host_addr;
m_offset = rhs.m_offset;
m_size = rhs.m_size;
+ m_is_shared_mapping = rhs.m_is_shared_mapping;
m_handle = rhs.m_handle;
return *this;
}
@@ -118,6 +122,36 @@
HostAddressSpaceDevice::get()->allocBlock(
provider->m_handle, size, &m_phys_addr);
m_handle = provider->m_handle;
+ m_is_shared_mapping = false;
+
+ return true;
+}
+
+bool GoldfishAddressSpaceBlock::claimShared(GoldfishAddressSpaceBlockProvider *provider, uint64_t offset, uint64_t size)
+{
+ ALOGD("%s: Ask to claim region [0x%llx 0x%llx]\n", __func__,
+ (unsigned long long)offset,
+ (unsigned long long)offset + size);
+
+ destroy();
+
+ if (!provider->is_opened()) {
+ return false;
+ }
+
+ int claimRes = HostAddressSpaceDevice::get()->claimShared(
+ provider->m_handle, offset, size);
+
+ if (claimRes) {
+ ALOGE("%s: failed to claim shared region. Error: %d\n", __func__, claimRes);
+ return false;
+ }
+
+ m_size = size;
+ m_offset = offset;
+ m_handle = provider->m_handle;
+ m_is_shared_mapping = true;
+ m_phys_addr = HostAddressSpaceDevice::get()->offsetToPhysAddr(m_offset);
return true;
}
@@ -132,6 +166,8 @@
return m_host_addr;
}
+// In the host implementation:
+// mmap: is done by interpreting |host_addr| as the actual host address.
void *GoldfishAddressSpaceBlock::mmap(uint64_t host_addr)
{
if (m_size == 0) {
@@ -162,7 +198,11 @@
}
if (m_size) {
- HostAddressSpaceDevice::get()->freeBlock(m_handle, m_offset);
+ if (m_is_shared_mapping) {
+ HostAddressSpaceDevice::get()->unclaimShared(m_handle, m_offset);
+ } else {
+ HostAddressSpaceDevice::get()->freeBlock(m_handle, m_offset);
+ }
m_phys_addr = 0;
m_host_addr = 0;
m_offset = 0;
@@ -192,7 +232,7 @@
void GoldfishAddressSpaceBlock::memoryUnmap(void *ptr, size_t size) {}
GoldfishAddressSpaceHostMemoryAllocator::GoldfishAddressSpaceHostMemoryAllocator()
- : m_provider(GoldfishAddressSpaceBlockProvider::SUBDEVICE_TYPE_HOST_MEMORY_ALLOCATOR_ID) {}
+ : m_provider(GoldfishAddressSpaceSubdeviceType::HostMemoryAllocator) {}
bool GoldfishAddressSpaceHostMemoryAllocator::is_opened() const { return m_provider.is_opened(); }
@@ -248,3 +288,91 @@
block->replace(NULL);
}
+address_space_handle_t goldfish_address_space_open() {
+ return HostAddressSpaceDevice::get()->open();
+}
+
+void goldfish_address_space_close(address_space_handle_t handle) {
+ HostAddressSpaceDevice::get()->close(handle);
+}
+
+bool goldfish_address_space_allocate(
+ address_space_handle_t handle,
+ size_t size, uint64_t* phys_addr, uint64_t* offset) {
+
+ *offset =
+ HostAddressSpaceDevice::get()->allocBlock(
+ handle, size, phys_addr);
+
+ return true;
+}
+
+bool goldfish_address_space_free(
+ address_space_handle_t handle, uint64_t offset) {
+ HostAddressSpaceDevice::get()->freeBlock(handle, offset);
+ return true;
+}
+
+bool goldfish_address_space_claim_shared(
+ address_space_handle_t handle, uint64_t offset, uint64_t size) {
+
+ int claimRes = HostAddressSpaceDevice::get()->claimShared(
+ handle, offset, size);
+
+ if (claimRes) {
+ ALOGE("%s: failed to claim shared region. Error: %d\n", __func__, claimRes);
+ return false;
+ }
+
+ return true;
+}
+
+bool goldfish_address_space_unclaim_shared(
+ address_space_handle_t handle, uint64_t offset) {
+ HostAddressSpaceDevice::get()->unclaimShared(handle, offset);
+ return true;
+}
+
+// pgoff is the offset into the page to return in the result
+void* goldfish_address_space_map(
+ address_space_handle_t handle,
+ uint64_t offset, uint64_t size,
+ uint64_t pgoff) {
+
+ (void)size;
+
+ void* res = HostAddressSpaceDevice::get()->
+ getHostAddr(
+ HostAddressSpaceDevice::get()->offsetToPhysAddr(offset));
+
+ if (!res) {
+ ALOGE("%s: failed to map. errno: %d\n", __func__, errno);
+ return nullptr;
+ }
+
+ return (void*)(((char*)res) + (uintptr_t)(pgoff & (PAGE_SIZE - 1)));
+}
+
+// same address space
+void goldfish_address_space_unmap(void*, uint64_t) { }
+
+bool goldfish_address_space_set_subdevice_type(
+ address_space_handle_t handle, GoldfishAddressSpaceSubdeviceType type,
+ address_space_handle_t* handle_out) {
+ struct goldfish_address_space_ping request;
+ request.metadata = (uint64_t)type;
+ *handle_out = handle;
+ return goldfish_address_space_ping(handle, &request);
+}
+
+bool goldfish_address_space_ping(
+ address_space_handle_t handle,
+ struct goldfish_address_space_ping* ping) {
+
+ AddressSpaceDevicePingInfo* asHostPingInfo =
+ reinterpret_cast<AddressSpaceDevicePingInfo*>(ping);
+
+ HostAddressSpaceDevice::get()->ping(handle, asHostPingInfo);
+
+ return true;
+}
diff --git a/shared/OpenglCodecCommon/gralloc_cb.h b/shared/OpenglCodecCommon/gralloc_cb.h
index 3167ca0..26d6026 100644
--- a/shared/OpenglCodecCommon/gralloc_cb.h
+++ b/shared/OpenglCodecCommon/gralloc_cb.h
@@ -38,7 +38,8 @@
int32_t p_glFormat,
int32_t p_glType,
uint32_t p_bufSize,
- void* p_bufPtr)
+ void* p_bufPtr,
+ uint64_t p_mmapedOffset)
: bufferFd(p_bufferFd),
hostHandleRefCountFd(p_hostHandleRefCountFd),
magic(p_magic),
@@ -50,6 +51,8 @@
glFormat(p_glFormat),
glType(p_glType),
bufferSize(p_bufSize),
+ mmapedOffsetLo(static_cast<uint32_t>(p_mmapedOffset)),
+ mmapedOffsetHi(static_cast<uint32_t>(p_mmapedOffset >> 32)),
lockedLeft(0),
lockedTop(0),
lockedWidth(0),
@@ -71,6 +74,10 @@
bufferPtrHi = uint32_t(addr >> 32);
}
+ uint64_t getMmapedOffset() const {
+ return (uint64_t(mmapedOffsetHi) << 32) | mmapedOffsetLo;
+ }
+
uint32_t allocatedSize() const {
return getBufferPtr() ? bufferSize : 0;
}
@@ -81,9 +88,9 @@
}
static cb_handle_t* from(void* p) {
- if (!p) { return nullptr; }
+ if (!p) { return NULL; }
cb_handle_t* cb = static_cast<cb_handle_t*>(p);
- return cb->isValid() ? cb : nullptr;
+ return cb->isValid() ? cb : NULL;
}
static const cb_handle_t* from(const void* p) {
@@ -110,6 +117,8 @@
uint32_t bufferSize; // buffer size and location
uint32_t bufferPtrLo;
uint32_t bufferPtrHi;
+ uint32_t mmapedOffsetLo;
+ uint32_t mmapedOffsetHi;
int32_t lockedLeft; // region of buffer locked for s/w write
int32_t lockedTop;
int32_t lockedWidth;
diff --git a/shared/OpenglCodecCommon/qemu_pipe.h b/shared/OpenglCodecCommon/qemu_pipe.h
index 82c4a94..55ebb74 100644
--- a/shared/OpenglCodecCommon/qemu_pipe.h
+++ b/shared/OpenglCodecCommon/qemu_pipe.h
@@ -16,9 +16,15 @@
#ifndef ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H
#define ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H
+#include <sys/types.h>
+#include <stdint.h>
+#include <errno.h>
+
#ifdef HOST_BUILD
-#include <sys/types.h>
+#ifndef QEMU_PIPE_RETRY
+#define QEMU_PIPE_RETRY TEMP_FAILURE_RETRY
+#endif
typedef void* QEMU_PIPE_HANDLE;
@@ -55,16 +61,6 @@
#define QEMU_PIPE_PATH "/dev/qemu_pipe"
#endif
-#ifndef TEMP_FAILURE_RETRY
-#define TEMP_FAILURE_RETRY(exp) ({ \
- __typeof__(exp) _rc; \
- do { \
- _rc = (exp); \
- } while (_rc == -1 && errno == EINTR); \
- _rc; })
-#include <stdint.h>
-#endif
-
#if PLATFORM_SDK_VERSION < 26
#include <cutils/log.h>
#else
@@ -80,24 +76,11 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <errno.h>
#ifndef D
# define D(...) do{}while(0)
#endif
-static bool WriteFully(QEMU_PIPE_HANDLE fd, const void* data, size_t byte_count) {
- const uint8_t* p = (const uint8_t*)(data);
- size_t remaining = byte_count;
- while (remaining > 0) {
- ssize_t n = QEMU_PIPE_RETRY(write(fd, p, remaining));
- if (n == -1) return false;
- p += n;
- remaining -= n;
- }
- return true;
-}
-
/* Try to open a new Qemu fast-pipe. This function returns a file descriptor
* that can be used to communicate with a named service managed by the
* emulator.
@@ -120,8 +103,12 @@
* except for a few special cases (e.g. GSM modem), where EBUSY will be
* returned if more than one client tries to connect to it.
*/
+
+static __inline__ ssize_t
+qemu_pipe_write_fully(QEMU_PIPE_HANDLE pipe, const void* buffer, ssize_t len);
+
static __inline__ QEMU_PIPE_HANDLE
-qemu_pipe_open(const char* pipeName) {
+qemu_pipe_open_ns(const char* ns, const char* pipeName, int flags) {
char buff[256];
int buffLen;
QEMU_PIPE_HANDLE fd;
@@ -131,11 +118,15 @@
return -1;
}
- snprintf(buff, sizeof buff, "pipe:%s", pipeName);
+ if (ns) {
+ buffLen = snprintf(buff, sizeof(buff), "pipe:%s:%s", ns, pipeName);
+ } else {
+ buffLen = snprintf(buff, sizeof(buff), "pipe:%s", pipeName);
+ }
- fd = QEMU_PIPE_RETRY(open(QEMU_PIPE_PATH, O_RDWR | O_NONBLOCK));
+ fd = QEMU_PIPE_RETRY(open(QEMU_PIPE_PATH, flags));
if (fd < 0 && errno == ENOENT) {
- fd = QEMU_PIPE_RETRY(open("/dev/goldfish_pipe", O_RDWR | O_NONBLOCK));
+ fd = QEMU_PIPE_RETRY(open("/dev/goldfish_pipe", flags));
}
if (fd < 0) {
D("%s: Could not open " QEMU_PIPE_PATH ": %s", __FUNCTION__, strerror(errno));
@@ -143,9 +134,7 @@
return -1;
}
- buffLen = strlen(buff);
-
- if (!WriteFully(fd, buff, buffLen + 1)) {
+ if (qemu_pipe_write_fully(fd, buff, buffLen + 1)) {
D("%s: Could not connect to %s pipe service: %s", __FUNCTION__, pipeName, strerror(errno));
return -1;
}
@@ -153,6 +142,11 @@
return fd;
}
+static __inline__ QEMU_PIPE_HANDLE
+qemu_pipe_open(const char* pipeName) {
+ return qemu_pipe_open_ns(NULL, pipeName, O_RDWR | O_NONBLOCK);
+}
+
static __inline__ void
qemu_pipe_close(QEMU_PIPE_HANDLE pipe) {
close(pipe);
@@ -183,6 +177,46 @@
ALOGE("pipe error: fd %d errno %d", pipe, errno);
}
+
#endif // !HOST_BUILD
+#ifndef TEMP_FAILURE_RETRY
+#define TEMP_FAILURE_RETRY(exp) ({ \
+ __typeof__(exp) _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1 && errno == EINTR); \
+ _rc; })
+#endif
+
+static __inline__ ssize_t
+qemu_pipe_read_fully(QEMU_PIPE_HANDLE pipe, void* buffer, ssize_t len) {
+ char* p = (char*)buffer;
+
+ while (len > 0) {
+ ssize_t n = QEMU_PIPE_RETRY(qemu_pipe_read(pipe, p, len));
+ if (n < 0) return n;
+
+ p += n;
+ len -= n;
+ }
+
+ return 0;
+}
+
+static __inline__ ssize_t
+qemu_pipe_write_fully(QEMU_PIPE_HANDLE pipe, const void* buffer, ssize_t len) {
+ const char* p = (const char*)buffer;
+
+ while (len > 0) {
+ ssize_t n = QEMU_PIPE_RETRY(qemu_pipe_write(pipe, p, len));
+ if (n < 0) return n;
+
+ p += n;
+ len -= n;
+ }
+
+ return 0;
+}
+
#endif /* ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H */
diff --git a/shared/OpenglCodecCommon/qemu_pipe_host.cpp b/shared/OpenglCodecCommon/qemu_pipe_host.cpp
index 1249eb1..c53a8eb 100644
--- a/shared/OpenglCodecCommon/qemu_pipe_host.cpp
+++ b/shared/OpenglCodecCommon/qemu_pipe_host.cpp
@@ -21,6 +21,8 @@
#include <log/log.h>
#endif
+#include <errno.h>
+
using android::HostGoldfishPipeDevice;
QEMU_PIPE_HANDLE qemu_pipe_open(const char* pipeName) {
diff --git a/system/GLESv1/CMakeLists.txt b/system/GLESv1/CMakeLists.txt
index 5685013..a8dc669 100644
--- a/system/GLESv1/CMakeLists.txt
+++ b/system/GLESv1/CMakeLists.txt
@@ -3,7 +3,7 @@
# which will re-generate this file.
android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/GLESv1/Android.mk" "e095cb082e3791719749cfc80b90560afd7348eb0d7895449d2509aa129bea75")
set(GLESv1_CM_emulation_src gl.cpp)
-android_add_shared_library(GLESv1_CM_emulation)
+android_add_library(TARGET GLESv1_CM_emulation SHARED LICENSE Apache-2.0 SRC gl.cpp)
target_include_directories(GLESv1_CM_emulation PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/bionic-include ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon ${GOLDFISH_DEVICE_ROOT}/bionic/libc/private ${GOLDFISH_DEVICE_ROOT}/bionic/libc/platform ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
target_compile_definitions(GLESv1_CM_emulation PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"GLES_emulation\"")
target_compile_options(GLESv1_CM_emulation PRIVATE "-fvisibility=default" "-Wno-unused-parameter")
diff --git a/system/GLESv1_enc/CMakeLists.txt b/system/GLESv1_enc/CMakeLists.txt
index 2849dcc..8acc4ff 100644
--- a/system/GLESv1_enc/CMakeLists.txt
+++ b/system/GLESv1_enc/CMakeLists.txt
@@ -3,7 +3,7 @@
# which will re-generate this file.
android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc/Android.mk" "953e6b7371d10eed63a4be555f8f1fb6f347338484a78102fa8f55dff96f5d3b")
set(GLESv1_enc_src GLEncoder.cpp GLEncoderUtils.cpp gl_client_context.cpp gl_enc.cpp gl_entry.cpp)
-android_add_shared_library(GLESv1_enc)
+android_add_library(TARGET GLESv1_enc SHARED LICENSE Apache-2.0 SRC GLEncoder.cpp GLEncoderUtils.cpp gl_client_context.cpp gl_enc.cpp gl_entry.cpp)
target_include_directories(GLESv1_enc PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
target_compile_definitions(GLESv1_enc PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"emuglGLESv1_enc\"")
target_compile_options(GLESv1_enc PRIVATE "-fvisibility=default" "-Wno-unused-parameter")
diff --git a/system/GLESv2/CMakeLists.txt b/system/GLESv2/CMakeLists.txt
index 0b28934..e2f5f4e 100644
--- a/system/GLESv2/CMakeLists.txt
+++ b/system/GLESv2/CMakeLists.txt
@@ -3,7 +3,7 @@
# which will re-generate this file.
android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/GLESv2/Android.mk" "d8f9dda69ec57ad8b7a65f02c3335b16a4724f612dec1d1a2cd793c28c0a10f9")
set(GLESv2_emulation_src gl2.cpp)
-android_add_shared_library(GLESv2_emulation)
+android_add_library(TARGET GLESv2_emulation SHARED LICENSE Apache-2.0 SRC gl2.cpp)
target_include_directories(GLESv2_emulation PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/bionic-include ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon ${GOLDFISH_DEVICE_ROOT}/bionic/libc/private ${GOLDFISH_DEVICE_ROOT}/bionic/libc/platform ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
target_compile_definitions(GLESv2_emulation PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"GLESv2_emulation\"")
target_compile_options(GLESv2_emulation PRIVATE "-fvisibility=default" "-Wno-unused-parameter")
diff --git a/system/GLESv2_enc/CMakeLists.txt b/system/GLESv2_enc/CMakeLists.txt
index 747a356..72afa76 100644
--- a/system/GLESv2_enc/CMakeLists.txt
+++ b/system/GLESv2_enc/CMakeLists.txt
@@ -3,7 +3,7 @@
# which will re-generate this file.
android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc/Android.mk" "d4fc971ccdbafbf971253b27bbc2168682b2994476079f4f81fb7a33c27070e0")
set(GLESv2_enc_src GL2EncoderUtils.cpp GL2Encoder.cpp GLESv2Validation.cpp gl2_client_context.cpp gl2_enc.cpp gl2_entry.cpp ../enc_common/IOStream_common.cpp)
-android_add_shared_library(GLESv2_enc)
+android_add_library(TARGET GLESv2_enc SHARED LICENSE Apache-2.0 SRC GL2EncoderUtils.cpp GL2Encoder.cpp GLESv2Validation.cpp gl2_client_context.cpp gl2_enc.cpp gl2_entry.cpp ../enc_common/IOStream_common.cpp)
target_include_directories(GLESv2_enc PRIVATE ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
target_compile_definitions(GLESv2_enc PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"emuglGLESv2_enc\"")
target_compile_options(GLESv2_enc PRIVATE "-fvisibility=default" "-Wno-unused-parameter" "-Wno-unused-private-field")
diff --git a/system/GLESv2_enc/GL2Encoder.cpp b/system/GLESv2_enc/GL2Encoder.cpp
index 2f20516..cc009a9 100755
--- a/system/GLESv2_enc/GL2Encoder.cpp
+++ b/system/GLESv2_enc/GL2Encoder.cpp
@@ -1186,19 +1186,7 @@
if (hasClientArrays) *hasClientArrays = false;
if (hasVBOs) *hasVBOs = false;
- for (int i = 0; i < m_state->nLocations(); i++) {
- const GLClientState::VertexAttribState& state = m_state->getState(i);
- if (state.enabled) {
- const GLClientState::BufferBinding& curr_binding = m_state->getCurrAttributeBindingInfo(i);
- GLuint bufferObject = curr_binding.buffer;
- if (bufferObject == 0 && curr_binding.offset && hasClientArrays) {
- *hasClientArrays = true;
- }
- if (bufferObject != 0 && hasVBOs) {
- *hasVBOs = true;
- }
- }
- }
+ m_state->getVBOUsage(hasClientArrays, hasVBOs);
}
void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count, bool hasClientArrays, GLsizei primcount)
@@ -1344,7 +1332,6 @@
ctx->sendVertexAttributes(first, count, true);
ctx->m_glDrawArrays_enc(ctx, mode, 0, count);
} else {
- ctx->sendVertexAttributes(0, count, false);
ctx->m_glDrawArrays_enc(ctx, mode, first, count);
}
}
@@ -1408,7 +1395,6 @@
bool adjustIndices = true;
if (ctx->m_state->currentIndexVbo() != 0) {
if (!has_client_vertex_arrays) {
- ctx->sendVertexAttributes(0, maxIndex + 1, false);
ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
ctx->glDrawElementsOffset(ctx, mode, count, type, offset);
ctx->flushDrawCall();
@@ -1458,7 +1444,6 @@
ctx->sendVertexAttributes(first, count, true);
ctx->m_glDrawArraysNullAEMU_enc(ctx, mode, 0, count);
} else {
- ctx->sendVertexAttributes(0, count, false);
ctx->m_glDrawArraysNullAEMU_enc(ctx, mode, first, count);
}
ctx->flushDrawCall();
@@ -1476,7 +1461,7 @@
bool has_client_vertex_arrays = false;
bool has_indirect_arrays = false;
- GLintptr offset = 0;
+ GLintptr offset = (GLintptr)indices;
ctx->getVBOUsage(&has_client_vertex_arrays, &has_indirect_arrays);
@@ -1496,15 +1481,19 @@
// can more quickly get min/max vertex index by
// caching previous results.
if (ctx->m_state->currentIndexVbo() != 0) {
- buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
- offset = (GLintptr)indices;
- indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
- ctx->getBufferIndexRange(buf,
- indices,
- type,
- (size_t)count,
- (size_t)offset,
- &minIndex, &maxIndex);
+ if (!has_client_vertex_arrays && has_indirect_arrays) {
+ // Don't do anything
+ } else {
+ buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo());
+ offset = (GLintptr)indices;
+ indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices);
+ ctx->getBufferIndexRange(buf,
+ indices,
+ type,
+ (size_t)count,
+ (size_t)offset,
+ &minIndex, &maxIndex);
+ }
} else {
// In this case, the |indices| field holds a real
// array, so calculate the indices now. They will
@@ -1522,8 +1511,7 @@
bool adjustIndices = true;
if (ctx->m_state->currentIndexVbo() != 0) {
if (!has_client_vertex_arrays) {
- ctx->sendVertexAttributes(0, maxIndex + 1, false);
- ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
+ ctx->doBindBufferEncodeCached(GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo());
ctx->glDrawElementsOffsetNullAEMU(ctx, mode, count, type, offset);
ctx->flushDrawCall();
adjustIndices = false;
@@ -1755,8 +1743,22 @@
// Track original sources---they may be translated in the backend
std::vector<std::string> orig_sources;
- for (int i = 0; i < count; i++) {
- orig_sources.push_back(std::string((const char*)(string[i])));
+ if (length) {
+ for (int i = 0; i < count; i++) {
+ // Each element in the length array may contain the length of the corresponding
+ // string (the null character is not counted as part of the string length) or a
+ // value less than 0 to indicate that the string is null terminated.
+ if (length[i] >= 0) {
+ orig_sources.push_back(std::string((const char*)(string[i]),
+ (const char*)(string[i]) + length[i]));
+ } else {
+ orig_sources.push_back(std::string((const char*)(string[i])));
+ }
+ }
+ } else {
+ for (int i = 0; i < count; i++) {
+ orig_sources.push_back(std::string((const char*)(string[i])));
+ }
}
shaderData->sources = orig_sources;
@@ -1817,7 +1819,6 @@
location = ctx->m_glGetUniformLocation_enc(self, program, name);
ctx->m_shared->setProgramIndexInfo(program, i, location, size, type, name);
}
- ctx->m_shared->setupLocationShiftWAR(program);
delete[] name;
}
@@ -1836,7 +1837,7 @@
SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
ctx->m_glGetUniformiv_enc(self, program, hostLoc, params);
}
@@ -1846,7 +1847,7 @@
SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program,location);
+ GLint hostLoc = location;
SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
ctx->m_glGetUniformfv_enc(self, program, hostLoc, params);
}
@@ -1957,24 +1958,8 @@
int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name)
{
if (!name) return -1;
-
GL2Encoder *ctx = (GL2Encoder*)self;
-
- // if we need the uniform location WAR
- // parse array index from the end of the name string
- int arrIndex = 0;
- bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
- if (needLocationWAR) {
- int err;
- arrIndex = sArrIndexOfUniformExpr(name, &err);
- if (err) return -1;
- }
-
- int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name);
- if (hostLoc >= 0 && needLocationWAR) {
- return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex);
- }
- return hostLoc;
+ return ctx->m_glGetUniformLocation_enc(self, program, name);
}
bool GL2Encoder::updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget)
@@ -2045,14 +2030,14 @@
void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform1f_enc(self, hostLoc, x);
}
void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform1fv_enc(self, hostLoc, count, v);
}
@@ -2062,7 +2047,7 @@
GLClientState* state = ctx->m_state;
GLSharedGroupPtr shared = ctx->m_shared;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform1i_enc(self, hostLoc, x);
GLenum target;
@@ -2078,112 +2063,112 @@
void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform1iv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform2f_enc(self, hostLoc, x, y);
}
void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform2fv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform2i_enc(self, hostLoc, x, y);
}
void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform2iv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform3f_enc(self, hostLoc, x, y, z);
}
void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform3fv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform3i_enc(self, hostLoc, x, y, z);
}
void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform3iv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w);
}
void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform4fv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w);
}
void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform4iv_enc(self, hostLoc, count, v);
}
void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value);
}
@@ -3536,7 +3521,6 @@
std::string packed = packVarNames(uniformCount, (const char**)uniformNames, &err);
SET_ERROR_IF(err != GL_NO_ERROR, GL_INVALID_OPERATION);
- bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program);
std::vector<int> arrIndices;
for (size_t i = 0; i < uniformCount; i++) {
int err;
@@ -3548,13 +3532,6 @@
}
ctx->glGetUniformIndicesAEMU(ctx, program, uniformCount, (const GLchar*)&packed[0], packed.size() + 1, uniformIndices);
-
- for (int i = 0; i < uniformCount; i++) {
- if (uniformIndices[i] >= 0 && needLocationWAR) {
- uniformIndices[i] =
- ctx->m_shared->locationWARHostToApp(program, uniformIndices[i], arrIndices[i]);
- }
- }
}
void GL2Encoder::s_glUniform1ui(void* self, GLint location, GLuint v0) {
@@ -3562,7 +3539,7 @@
GLClientState* state = ctx->m_state;
GLSharedGroupPtr shared = ctx->m_shared;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform1ui_enc(self, hostLoc, v0);
GLenum target;
@@ -3577,79 +3554,79 @@
void GL2Encoder::s_glUniform2ui(void* self, GLint location, GLuint v0, GLuint v1) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform2ui_enc(self, hostLoc, v0, v1);
}
void GL2Encoder::s_glUniform3ui(void* self, GLint location, GLuint v0, GLuint v1, GLuint v2) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform3ui_enc(self, hostLoc, v0, v1, v2);
}
void GL2Encoder::s_glUniform4ui(void* self, GLint location, GLint v0, GLuint v1, GLuint v2, GLuint v3) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform4ui_enc(self, hostLoc, v0, v1, v2, v3);
}
void GL2Encoder::s_glUniform1uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform1uiv_enc(self, hostLoc, count, value);
}
void GL2Encoder::s_glUniform2uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform2uiv_enc(self, hostLoc, count, value);
}
void GL2Encoder::s_glUniform3uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform3uiv_enc(self, hostLoc, count, value);
}
void GL2Encoder::s_glUniform4uiv(void* self, GLint location, GLsizei count, const GLuint *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniform4uiv_enc(self, hostLoc, count, value);
}
void GL2Encoder::s_glUniformMatrix2x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniformMatrix2x3fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix3x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniformMatrix3x2fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix2x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniformMatrix2x4fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix4x2fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniformMatrix4x2fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix3x4fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniformMatrix3x4fv_enc(self, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glUniformMatrix4x3fv(void* self, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentShaderProgram(),location);
+ GLint hostLoc = location;
ctx->m_glUniformMatrix4x3fv_enc(self, hostLoc, count, transpose, value);
}
@@ -3658,7 +3635,7 @@
SET_ERROR_IF(!ctx->m_shared->isShaderOrProgramObject(program), GL_INVALID_VALUE);
SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_OPERATION);
SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION);
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION);
ctx->m_glGetUniformuiv_enc(self, program, hostLoc, params);
}
@@ -3957,12 +3934,12 @@
SET_ERROR_IF(level > ilog2(max_3d_texture_size), GL_INVALID_VALUE);
SET_ERROR_IF(width < 0 || height < 0 || depth < 0, GL_INVALID_VALUE);
- SET_ERROR_IF(width > GL_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
- SET_ERROR_IF(height > GL_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
- SET_ERROR_IF(depth > GL_MAX_TEXTURE_SIZE, GL_INVALID_VALUE);
- SET_ERROR_IF(width > GL_MAX_3D_TEXTURE_SIZE, GL_INVALID_VALUE);
- SET_ERROR_IF(height > GL_MAX_3D_TEXTURE_SIZE, GL_INVALID_VALUE);
- SET_ERROR_IF(depth > GL_MAX_3D_TEXTURE_SIZE, GL_INVALID_VALUE);
+ SET_ERROR_IF(width > max_texture_size, GL_INVALID_VALUE);
+ SET_ERROR_IF(height > max_texture_size, GL_INVALID_VALUE);
+ SET_ERROR_IF(depth > max_texture_size, GL_INVALID_VALUE);
+ SET_ERROR_IF(width > max_3d_texture_size, GL_INVALID_VALUE);
+ SET_ERROR_IF(height > max_3d_texture_size, GL_INVALID_VALUE);
+ SET_ERROR_IF(depth > max_3d_texture_size, GL_INVALID_VALUE);
SET_ERROR_IF(border != 0, GL_INVALID_VALUE);
// If unpack buffer is nonzero, verify buffer data fits and is evenly divisible by the type.
SET_ERROR_IF(ctx->boundBuffer(GL_PIXEL_UNPACK_BUFFER) &&
@@ -4911,8 +4888,6 @@
ctx->m_shared->setShaderProgramIndexInfo(res, i, location, size, uniformType, name);
}
- ctx->m_shared->setupShaderProgramLocationShiftWAR(res);
-
delete [] name;
return res;
@@ -4921,21 +4896,21 @@
void GL2Encoder::s_glProgramUniform1f(void* self, GLuint program, GLint location, GLfloat v0)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform1f_enc(self, program, hostLoc, v0);
}
void GL2Encoder::s_glProgramUniform1fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform1fv_enc(self, program, hostLoc, count, value);
}
void GL2Encoder::s_glProgramUniform1i(void* self, GLuint program, GLint location, GLint v0)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform1i_enc(self, program, hostLoc, v0);
GLClientState* state = ctx->m_state;
@@ -4954,14 +4929,14 @@
void GL2Encoder::s_glProgramUniform1iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform1iv_enc(self, program, hostLoc, count, value);
}
void GL2Encoder::s_glProgramUniform1ui(void* self, GLuint program, GLint location, GLuint v0)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform1ui_enc(self, program, hostLoc, v0);
GLClientState* state = ctx->m_state;
@@ -4980,196 +4955,196 @@
void GL2Encoder::s_glProgramUniform1uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform1uiv_enc(self, program, hostLoc, count, value);
}
void GL2Encoder::s_glProgramUniform2f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform2f_enc(self, program, hostLoc, v0, v1);
}
void GL2Encoder::s_glProgramUniform2fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform2fv_enc(self, program, hostLoc, count, value);
}
void GL2Encoder::s_glProgramUniform2i(void* self, GLuint program, GLint location, GLint v0, GLint v1)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform2i_enc(self, program, hostLoc, v0, v1);
}
void GL2Encoder::s_glProgramUniform2iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform2iv_enc(self, program, hostLoc, count, value);
}
void GL2Encoder::s_glProgramUniform2ui(void* self, GLuint program, GLint location, GLint v0, GLuint v1)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform2ui_enc(self, program, hostLoc, v0, v1);
}
void GL2Encoder::s_glProgramUniform2uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform2uiv_enc(self, program, hostLoc, count, value);
}
void GL2Encoder::s_glProgramUniform3f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform3f_enc(self, program, hostLoc, v0, v1, v2);
}
void GL2Encoder::s_glProgramUniform3fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform3fv_enc(self, program, hostLoc, count, value);
}
void GL2Encoder::s_glProgramUniform3i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform3i_enc(self, program, hostLoc, v0, v1, v2);
}
void GL2Encoder::s_glProgramUniform3iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform3iv_enc(self, program, hostLoc, count, value);
}
void GL2Encoder::s_glProgramUniform3ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLuint v2)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform3ui_enc(self, program, hostLoc, v0, v1, v2);
}
void GL2Encoder::s_glProgramUniform3uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform3uiv_enc(self, program, hostLoc, count, value);
}
void GL2Encoder::s_glProgramUniform4f(void* self, GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform4f_enc(self, program, hostLoc, v0, v1, v2, v3);
}
void GL2Encoder::s_glProgramUniform4fv(void* self, GLuint program, GLint location, GLsizei count, const GLfloat *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform4fv_enc(self, program, hostLoc, count, value);
}
void GL2Encoder::s_glProgramUniform4i(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform4i_enc(self, program, hostLoc, v0, v1, v2, v3);
}
void GL2Encoder::s_glProgramUniform4iv(void* self, GLuint program, GLint location, GLsizei count, const GLint *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform4iv_enc(self, program, hostLoc, count, value);
}
void GL2Encoder::s_glProgramUniform4ui(void* self, GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLuint v3)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform4ui_enc(self, program, hostLoc, v0, v1, v2, v3);
}
void GL2Encoder::s_glProgramUniform4uiv(void* self, GLuint program, GLint location, GLsizei count, const GLuint *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniform4uiv_enc(self, program, hostLoc, count, value);
}
void GL2Encoder::s_glProgramUniformMatrix2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniformMatrix2fv_enc(self, program, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glProgramUniformMatrix2x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniformMatrix2x3fv_enc(self, program, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glProgramUniformMatrix2x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniformMatrix2x4fv_enc(self, program, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glProgramUniformMatrix3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniformMatrix3fv_enc(self, program, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glProgramUniformMatrix3x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniformMatrix3x2fv_enc(self, program, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glProgramUniformMatrix3x4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniformMatrix3x4fv_enc(self, program, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glProgramUniformMatrix4fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniformMatrix4fv_enc(self, program, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glProgramUniformMatrix4x2fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniformMatrix4x2fv_enc(self, program, hostLoc, count, transpose, value);
}
void GL2Encoder::s_glProgramUniformMatrix4x3fv(void* self, GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
GL2Encoder *ctx = (GL2Encoder*)self;
- GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location);
+ GLint hostLoc = location;
ctx->m_glProgramUniformMatrix4x3fv_enc(self, program, hostLoc, count, transpose, value);
}
@@ -5359,7 +5334,8 @@
GLClientState* state = ctx->m_state;
bool hasClientArrays = false;
- ctx->getVBOUsage(&hasClientArrays, NULL);
+ bool hasVBOs = false;
+ ctx->getVBOUsage(&hasClientArrays, &hasVBOs);
SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
@@ -5385,7 +5361,8 @@
GLClientState* state = ctx->m_state;
bool hasClientArrays = false;
- ctx->getVBOUsage(&hasClientArrays, NULL);
+ bool hasVBOs = false;
+ ctx->getVBOUsage(&hasClientArrays, &hasVBOs);
SET_ERROR_IF(hasClientArrays, GL_INVALID_OPERATION);
SET_ERROR_IF(!state->currentVertexArrayObject(), GL_INVALID_OPERATION);
diff --git a/system/OpenglSystemCommon/AddressSpaceStream.cpp b/system/OpenglSystemCommon/AddressSpaceStream.cpp
new file mode 100644
index 0000000..ce7c720
--- /dev/null
+++ b/system/OpenglSystemCommon/AddressSpaceStream.cpp
@@ -0,0 +1,550 @@
+/*
+* Copyright (C) 2011 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 "AddressSpaceStream.h"
+
+#if PLATFORM_SDK_VERSION < 26
+#include <cutils/log.h>
+#else
+#include <log/log.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+static const size_t kReadSize = 512 * 1024;
+static const size_t kWriteOffset = kReadSize;
+
+AddressSpaceStream* createAddressSpaceStream(size_t ignored_bufSize) {
+ // Ignore incoming ignored_bufSize
+ (void)ignored_bufSize;
+
+ auto handle = goldfish_address_space_open();
+ address_space_handle_t child_device_handle;
+
+ if (!goldfish_address_space_set_subdevice_type(handle, GoldfishAddressSpaceSubdeviceType::Graphics, &child_device_handle)) {
+ ALOGE("AddressSpaceStream::create failed (initial device create)\n");
+ goldfish_address_space_close(handle);
+ return nullptr;
+ }
+
+ struct goldfish_address_space_ping request;
+ request.metadata = ASG_GET_RING;
+ if (!goldfish_address_space_ping(child_device_handle, &request)) {
+ ALOGE("AddressSpaceStream::create failed (get ring)\n");
+ goldfish_address_space_close(child_device_handle);
+ return nullptr;
+ }
+
+ uint64_t ringOffset = request.metadata;
+
+ request.metadata = ASG_GET_BUFFER;
+ if (!goldfish_address_space_ping(child_device_handle, &request)) {
+ ALOGE("AddressSpaceStream::create failed (get buffer)\n");
+ goldfish_address_space_close(child_device_handle);
+ return nullptr;
+ }
+
+ uint64_t bufferOffset = request.metadata;
+ uint64_t bufferSize = request.size;
+
+ if (!goldfish_address_space_claim_shared(
+ child_device_handle, ringOffset, sizeof(asg_ring_storage))) {
+ ALOGE("AddressSpaceStream::create failed (claim ring storage)\n");
+ goldfish_address_space_close(child_device_handle);
+ return nullptr;
+ }
+
+ if (!goldfish_address_space_claim_shared(
+ child_device_handle, bufferOffset, bufferSize)) {
+ ALOGE("AddressSpaceStream::create failed (claim buffer storage)\n");
+ goldfish_address_space_unclaim_shared(child_device_handle, ringOffset);
+ goldfish_address_space_close(child_device_handle);
+ return nullptr;
+ }
+
+ char* ringPtr = (char*)goldfish_address_space_map(
+ child_device_handle, ringOffset, sizeof(struct asg_ring_storage));
+
+ if (!ringPtr) {
+ ALOGE("AddressSpaceStream::create failed (map ring storage)\n");
+ goldfish_address_space_unclaim_shared(child_device_handle, bufferOffset);
+ goldfish_address_space_unclaim_shared(child_device_handle, ringOffset);
+ goldfish_address_space_close(child_device_handle);
+ return nullptr;
+ }
+
+ char* bufferPtr = (char*)goldfish_address_space_map(
+ child_device_handle, bufferOffset, bufferSize);
+
+ if (!bufferPtr) {
+ ALOGE("AddressSpaceStream::create failed (map buffer storage)\n");
+ goldfish_address_space_unmap(ringPtr, sizeof(struct asg_ring_storage));
+ goldfish_address_space_unclaim_shared(child_device_handle, bufferOffset);
+ goldfish_address_space_unclaim_shared(child_device_handle, ringOffset);
+ goldfish_address_space_close(child_device_handle);
+ return nullptr;
+ }
+
+ struct asg_context context =
+ asg_context_create(
+ ringPtr, bufferPtr, bufferSize);
+
+ request.metadata = ASG_SET_VERSION;
+ request.size = 1; // version 1
+
+ if (!goldfish_address_space_ping(child_device_handle, &request)) {
+ ALOGE("AddressSpaceStream::create failed (get buffer)\n");
+ goldfish_address_space_unmap(bufferPtr, bufferSize);
+ goldfish_address_space_unmap(ringPtr, sizeof(struct asg_ring_storage));
+ goldfish_address_space_unclaim_shared(child_device_handle, bufferOffset);
+ goldfish_address_space_unclaim_shared(child_device_handle, ringOffset);
+ goldfish_address_space_close(child_device_handle);
+ return nullptr;
+ }
+
+ uint32_t version = request.size;
+
+ context.ring_config->transfer_mode = 1;
+ context.ring_config->host_consumed_pos = 0;
+ context.ring_config->guest_write_pos = 0;
+
+ AddressSpaceStream* res =
+ new AddressSpaceStream(
+ child_device_handle, version, context,
+ ringOffset, bufferOffset);
+
+ return res;
+}
+
+AddressSpaceStream::AddressSpaceStream(
+ address_space_handle_t handle,
+ uint32_t version,
+ struct asg_context context,
+ uint64_t ringOffset,
+ uint64_t writeBufferOffset) :
+ IOStream(context.ring_config->flush_interval),
+ m_tmpBuf(0),
+ m_tmpBufSize(0),
+ m_tmpBufXferSize(0),
+ m_usingTmpBuf(0),
+ m_readBuf(0),
+ m_read(0),
+ m_readLeft(0),
+ m_handle(handle),
+ m_version(version),
+ m_context(context),
+ m_ringOffset(ringOffset),
+ m_writeBufferOffset(writeBufferOffset),
+ m_writeBufferSize(context.ring_config->buffer_size),
+ m_writeBufferMask(m_writeBufferSize - 1),
+ m_buf((unsigned char*)context.buffer),
+ m_writeStart(m_buf),
+ m_writeStep(context.ring_config->flush_interval),
+ m_notifs(0),
+ m_written(0) {
+ // We'll use this in the future, but at the moment,
+ // it's a potential compile Werror.
+ (void)m_version;
+}
+
+AddressSpaceStream::~AddressSpaceStream() {
+ goldfish_address_space_unmap(m_context.to_host, sizeof(struct asg_ring_storage));
+ goldfish_address_space_unmap(m_context.buffer, m_writeBufferSize);
+ goldfish_address_space_unclaim_shared(m_handle, m_ringOffset);
+ goldfish_address_space_unclaim_shared(m_handle, m_writeBufferOffset);
+ goldfish_address_space_close(m_handle);
+ if (m_readBuf) free(m_readBuf);
+ if (m_tmpBuf) free(m_tmpBuf);
+}
+
+size_t AddressSpaceStream::idealAllocSize(size_t len) {
+ if (len > m_writeStep) return len;
+ return m_writeStep;
+}
+
+void *AddressSpaceStream::allocBuffer(size_t minSize) {
+ if (!m_readBuf) {
+ m_readBuf = (unsigned char*)malloc(kReadSize);
+ }
+
+ size_t allocSize =
+ (m_writeStep < minSize ? minSize : m_writeStep);
+
+ if (m_writeStep < allocSize) {
+ if (!m_tmpBuf) {
+ m_tmpBufSize = allocSize * 2;
+ m_tmpBuf = (unsigned char*)malloc(m_tmpBufSize);
+ }
+
+ if (m_tmpBufSize < allocSize) {
+ m_tmpBufSize = allocSize * 2;
+ m_tmpBuf = (unsigned char*)realloc(m_tmpBuf, m_tmpBufSize);
+ }
+
+ if (!m_usingTmpBuf) {
+ flush();
+ }
+
+ m_usingTmpBuf = true;
+ m_tmpBufXferSize = allocSize;
+ return m_tmpBuf;
+ } else {
+ if (m_usingTmpBuf) {
+ writeFully(m_tmpBuf, m_tmpBufXferSize);
+ m_usingTmpBuf = false;
+ m_tmpBufXferSize = 0;
+ }
+
+ return m_writeStart;
+ }
+};
+
+int AddressSpaceStream::commitBuffer(size_t size)
+{
+ if (size == 0) return 0;
+
+ if (m_usingTmpBuf) {
+ writeFully(m_tmpBuf, size);
+ m_tmpBufXferSize = 0;
+ m_usingTmpBuf = false;
+ return 0;
+ } else {
+ int res = type1Write(m_writeStart - m_buf, size);
+ advanceWrite();
+ return res;
+ }
+}
+
+const unsigned char *AddressSpaceStream::readFully(void *ptr, size_t totalReadSize)
+{
+
+ unsigned char* userReadBuf = static_cast<unsigned char*>(ptr);
+
+ if (!userReadBuf) {
+ if (totalReadSize > 0) {
+ ALOGE("AddressSpaceStream::commitBufferAndReadFully failed, userReadBuf=NULL, totalReadSize %zu, lethal"
+ " error, exiting.", totalReadSize);
+ abort();
+ }
+ return nullptr;
+ }
+
+ // Advance buffered read if not yet consumed.
+ size_t remaining = totalReadSize;
+ size_t bufferedReadSize =
+ m_readLeft < remaining ? m_readLeft : remaining;
+
+ if (bufferedReadSize) {
+ memcpy(userReadBuf,
+ m_readBuf + (m_read - m_readLeft),
+ bufferedReadSize);
+ remaining -= bufferedReadSize;
+ m_readLeft -= bufferedReadSize;
+ }
+
+ if (!remaining) return userReadBuf;
+
+ // Read up to kReadSize bytes if all buffered read has been consumed.
+ size_t maxRead = m_readLeft ? 0 : kReadSize;
+ ssize_t actual = 0;
+
+ if (maxRead) {
+ actual = speculativeRead(m_readBuf, maxRead);
+
+ // Updated buffered read size.
+ if (actual > 0) {
+ m_read = m_readLeft = actual;
+ }
+
+ if (actual == 0) {
+ ALOGD("%s: end of pipe", __FUNCTION__);
+ return NULL;
+ }
+ }
+
+ // Consume buffered read and read more if necessary.
+ while (remaining) {
+ bufferedReadSize = m_readLeft < remaining ? m_readLeft : remaining;
+ if (bufferedReadSize) {
+ memcpy(userReadBuf + (totalReadSize - remaining),
+ m_readBuf + (m_read - m_readLeft),
+ bufferedReadSize);
+ remaining -= bufferedReadSize;
+ m_readLeft -= bufferedReadSize;
+ continue;
+ }
+
+ actual = speculativeRead(m_readBuf, kReadSize);
+
+ if (actual == 0) {
+ ALOGD("%s: Failed reading from pipe: %d", __FUNCTION__, errno);
+ return NULL;
+ }
+
+ if (actual > 0) {
+ m_read = m_readLeft = actual;
+ continue;
+ }
+ }
+
+ return userReadBuf;
+}
+
+const unsigned char *AddressSpaceStream::read(void *buf, size_t *inout_len) {
+ unsigned char* dst = (unsigned char*)buf;
+ size_t wanted = *inout_len;
+ ssize_t actual = speculativeRead(dst, wanted);
+
+ if (actual >= 0) {
+ *inout_len = actual;
+ } else {
+ return nullptr;
+ }
+
+ return (const unsigned char*)dst;
+}
+
+int AddressSpaceStream::writeFully(const void *buf, size_t size)
+{
+ ensureConsumerFinishing();
+ ensureType3Finished();
+ ensureType1Finished();
+
+ m_context.ring_config->transfer_size = size;
+ m_context.ring_config->transfer_mode = 3;
+
+ size_t sent = 0;
+ size_t quarterRingSize = m_writeBufferSize / 4;
+ size_t chunkSize = size < quarterRingSize ? size : quarterRingSize;
+ const uint8_t* bufferBytes = (const uint8_t*)buf;
+
+ while (sent < size) {
+ size_t remaining = size - sent;
+ size_t sendThisTime = remaining < chunkSize ? remaining : chunkSize;
+
+ long sentChunks =
+ ring_buffer_view_write(
+ m_context.to_host_large_xfer.ring,
+ &m_context.to_host_large_xfer.view,
+ bufferBytes + sent, sendThisTime, 1);
+
+ if (*(m_context.host_state) != ASG_HOST_STATE_CAN_CONSUME) {
+ notifyAvailable();
+ }
+
+ if (sentChunks == 0) {
+ ring_buffer_yield();
+ }
+
+ sent += sentChunks * sendThisTime;
+
+ if (isInError()) {
+ return -1;
+ }
+ }
+
+ ensureType3Finished();
+ m_context.ring_config->transfer_mode = 1;
+ m_written += size;
+ return 0;
+}
+
+const unsigned char *AddressSpaceStream::commitBufferAndReadFully(
+ size_t writeSize, void *userReadBufPtr, size_t totalReadSize) {
+
+ if (m_usingTmpBuf) {
+ writeFully(m_tmpBuf, writeSize);
+ m_usingTmpBuf = false;
+ m_tmpBufXferSize = 0;
+ return readFully(userReadBufPtr, totalReadSize);
+ } else {
+ commitBuffer(writeSize);
+ return readFully(userReadBufPtr, totalReadSize);
+ }
+}
+
+bool AddressSpaceStream::isInError() const {
+ return 1 == m_context.ring_config->in_error;
+}
+
+ssize_t AddressSpaceStream::speculativeRead(unsigned char* readBuffer, size_t trySize) {
+ ensureConsumerFinishing();
+ ensureType3Finished();
+ ensureType1Finished();
+
+ size_t actuallyRead = 0;
+ while (!actuallyRead) {
+ uint32_t readAvail =
+ ring_buffer_available_read(
+ m_context.from_host_large_xfer.ring,
+ &m_context.from_host_large_xfer.view);
+
+ if (!readAvail) {
+ ring_buffer_yield();
+ continue;
+ }
+
+ uint32_t toRead = readAvail > trySize ? trySize : readAvail;
+
+ long stepsRead = ring_buffer_view_read(
+ m_context.from_host_large_xfer.ring,
+ &m_context.from_host_large_xfer.view,
+ readBuffer, toRead, 1);
+
+ actuallyRead += stepsRead * toRead;
+
+ if (isInError()) {
+ return -1;
+ }
+ }
+
+ return actuallyRead;
+}
+
+void AddressSpaceStream::notifyAvailable() {
+ struct goldfish_address_space_ping request;
+ request.metadata = ASG_NOTIFY_AVAILABLE;
+ goldfish_address_space_ping(m_handle, &request);
+ ++m_notifs;
+}
+
+uint32_t AddressSpaceStream::getRelativeBufferPos(uint32_t pos) {
+ return pos & m_writeBufferMask;
+}
+
+void AddressSpaceStream::advanceWrite() {
+ m_writeStart += m_context.ring_config->flush_interval;
+
+ if (m_writeStart == m_buf + m_context.ring_config->buffer_size) {
+ m_writeStart = m_buf;
+ }
+}
+
+void AddressSpaceStream::ensureConsumerFinishing() {
+ uint32_t currAvailRead = ring_buffer_available_read(m_context.to_host, 0);
+
+ while (currAvailRead) {
+ ring_buffer_yield();
+ uint32_t nextAvailRead = ring_buffer_available_read(m_context.to_host, 0);
+
+ if (nextAvailRead != currAvailRead) {
+ break;
+ }
+
+ if (*(m_context.host_state) != ASG_HOST_STATE_CAN_CONSUME) {
+ notifyAvailable();
+ break;
+ }
+ }
+}
+
+void AddressSpaceStream::ensureType1Finished() {
+ ensureConsumerFinishing();
+
+ uint32_t currAvailRead =
+ ring_buffer_available_read(m_context.to_host, 0);
+
+ while (currAvailRead) {
+ ring_buffer_yield();
+ currAvailRead = ring_buffer_available_read(m_context.to_host, 0);
+ if (isInError()) {
+ return;
+ }
+ }
+}
+
+void AddressSpaceStream::ensureType3Finished() {
+ uint32_t availReadLarge =
+ ring_buffer_available_read(
+ m_context.to_host_large_xfer.ring,
+ &m_context.to_host_large_xfer.view);
+ while (availReadLarge) {
+ ring_buffer_yield();
+ availReadLarge =
+ ring_buffer_available_read(
+ m_context.to_host_large_xfer.ring,
+ &m_context.to_host_large_xfer.view);
+ if (*(m_context.host_state) != ASG_HOST_STATE_CAN_CONSUME) {
+ notifyAvailable();
+ }
+ if (isInError()) {
+ return;
+ }
+ }
+}
+
+int AddressSpaceStream::type1Write(uint32_t bufferOffset, size_t size) {
+ size_t sent = 0;
+ size_t sizeForRing = sizeof(struct asg_type1_xfer);
+
+ struct asg_type1_xfer xfer = {
+ bufferOffset,
+ (uint32_t)size,
+ };
+
+ uint8_t* writeBufferBytes = (uint8_t*)(&xfer);
+
+ uint32_t maxOutstanding = 1;
+ uint32_t maxSteps = m_context.ring_config->buffer_size /
+ m_context.ring_config->flush_interval;
+
+ if (maxSteps > 1) maxOutstanding = maxSteps >> 1;
+
+ uint32_t ringAvailReadNow = ring_buffer_available_read(m_context.to_host, 0);
+
+ while (ringAvailReadNow >= maxOutstanding) {
+ ensureConsumerFinishing();
+ ring_buffer_yield();
+ ringAvailReadNow = ring_buffer_available_read(m_context.to_host, 0);
+ }
+
+ while (sent < sizeForRing) {
+
+ long sentChunks = ring_buffer_write(
+ m_context.to_host,
+ writeBufferBytes + sent,
+ sizeForRing - sent, 1);
+
+ if (*(m_context.host_state) != ASG_HOST_STATE_CAN_CONSUME) {
+ notifyAvailable();
+ }
+
+ if (sentChunks == 0) {
+ ring_buffer_yield();
+ }
+
+ sent += sentChunks * (sizeForRing - sent);
+
+ if (isInError()) {
+ return -1;
+ }
+ }
+
+ ensureConsumerFinishing();
+ m_written += size;
+
+ float mb = (float)m_written / 1048576.0f;
+ if (mb > 100.0f) {
+ ALOGD("%s: %f mb in %d notifs. %f mb/notif\n", __func__,
+ mb, m_notifs, m_notifs ? mb / (float)m_notifs : 0.0f);
+ m_notifs = 0;
+ m_written = 0;
+ }
+
+ return 0;
+}
diff --git a/system/OpenglSystemCommon/AddressSpaceStream.h b/system/OpenglSystemCommon/AddressSpaceStream.h
new file mode 100644
index 0000000..a4db5aa
--- /dev/null
+++ b/system/OpenglSystemCommon/AddressSpaceStream.h
@@ -0,0 +1,83 @@
+/*
+* Copyright (C) 2011 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#ifndef __ADDRESS_SPACE_STREAM_H
+#define __ADDRESS_SPACE_STREAM_H
+
+#include "IOStream.h"
+
+#include "address_space_graphics_types.h"
+#include "goldfish_address_space.h"
+
+class AddressSpaceStream;
+
+AddressSpaceStream* createAddressSpaceStream(size_t bufSize);
+
+class AddressSpaceStream : public IOStream {
+public:
+ explicit AddressSpaceStream(
+ address_space_handle_t handle,
+ uint32_t version,
+ struct asg_context context,
+ uint64_t ringOffset,
+ uint64_t writeBufferOffset);
+ ~AddressSpaceStream();
+
+ virtual size_t idealAllocSize(size_t len);
+ virtual void *allocBuffer(size_t minSize);
+ virtual int commitBuffer(size_t size);
+ virtual const unsigned char *readFully( void *buf, size_t len);
+ virtual const unsigned char *read( void *buf, size_t *inout_len);
+ virtual int writeFully(const void *buf, size_t len);
+ virtual const unsigned char *commitBufferAndReadFully(size_t size, void *buf, size_t len);
+
+private:
+ bool isInError() const;
+ ssize_t speculativeRead(unsigned char* readBuffer, size_t trySize);
+ void notifyAvailable();
+ uint32_t getRelativeBufferPos(uint32_t pos);
+ void advanceWrite();
+ void ensureConsumerFinishing();
+ void ensureType1Finished();
+ void ensureType3Finished();
+ int type1Write(uint32_t offset, size_t size);
+
+ unsigned char* m_tmpBuf;
+ size_t m_tmpBufSize;
+ size_t m_tmpBufXferSize;
+ bool m_usingTmpBuf;
+
+ unsigned char* m_readBuf;
+ size_t m_read;
+ size_t m_readLeft;
+
+ address_space_handle_t m_handle;
+ uint32_t m_version;
+ struct asg_context m_context;
+
+ uint64_t m_ringOffset;
+ uint64_t m_writeBufferOffset;
+
+ uint32_t m_writeBufferSize;
+ uint32_t m_writeBufferMask;
+ unsigned char* m_buf;
+ unsigned char* m_writeStart;
+ uint32_t m_writeStep;
+
+ uint32_t m_notifs;
+ uint32_t m_written;
+};
+
+#endif
diff --git a/system/OpenglSystemCommon/Android.mk b/system/OpenglSystemCommon/Android.mk
index e8af35b..bb9e14f 100644
--- a/system/OpenglSystemCommon/Android.mk
+++ b/system/OpenglSystemCommon/Android.mk
@@ -3,16 +3,19 @@
$(call emugl-begin-shared-library,libOpenglSystemCommon)
$(call emugl-import,libGLESv1_enc libGLESv2_enc lib_renderControl_enc)
-ifeq (true,$(BUILD_EMULATOR_VULKAN))
-$(call emugl-import,libvulkan_enc)
-endif
-
LOCAL_SRC_FILES := \
FormatConversions.cpp \
HostConnection.cpp \
QemuPipeStream.cpp \
ProcessPipe.cpp \
+ifeq (true,$(BUILD_EMULATOR_VULKAN))
+$(call emugl-import,libvulkan_enc)
+
+LOCAL_SRC_FILES += AddressSpaceStream.cpp
+
+endif
+
LOCAL_CFLAGS += -Wno-unused-variable -Wno-unused-parameter
ifeq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST))
@@ -26,6 +29,14 @@
LOCAL_HEADER_LIBRARIES += vulkan_headers
+LOCAL_CFLAGS += -DVIRTIO_GPU
+LOCAL_SRC_FILES += \
+ VirtioGpuStream.cpp \
+ VirtioGpuPipeStream.cpp \
+
+LOCAL_C_INCLUDES += external/libdrm external/minigbm/cros_gralloc
+LOCAL_SHARED_LIBRARIES += libdrm
+
endif
LOCAL_SRC_FILES += \
@@ -33,13 +44,6 @@
endif
-ifneq ($(filter virgl, $(BOARD_GPU_DRIVERS)),)
-LOCAL_CFLAGS += -DVIRTIO_GPU
-LOCAL_SRC_FILES += VirtioGpuStream.cpp
-LOCAL_C_INCLUDES += external/libdrm external/minigbm/cros_gralloc
-LOCAL_SHARED_LIBRARIES += libdrm
-endif
-
ifdef IS_AT_LEAST_OPD1
LOCAL_HEADER_LIBRARIES += libnativebase_headers
diff --git a/system/OpenglSystemCommon/CMakeLists.txt b/system/OpenglSystemCommon/CMakeLists.txt
index 25d2b6c..7feb903 100644
--- a/system/OpenglSystemCommon/CMakeLists.txt
+++ b/system/OpenglSystemCommon/CMakeLists.txt
@@ -1,9 +1,9 @@
# This is an autogenerated file! Do not edit!
# instead run make from .../device/generic/goldfish-opengl
# which will re-generate this file.
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/Android.mk" "e8484748e692aa93eff0414a8e15ca19c75c3e333427c74a392d774872e56050")
-set(OpenglSystemCommon_src FormatConversions.cpp HostConnection.cpp QemuPipeStream.cpp ProcessPipe.cpp ThreadInfo_host.cpp)
-android_add_shared_library(OpenglSystemCommon)
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/Android.mk" "6fedb15afaabb2c4e6cd24123f711639d6574b47356b2fa626a668bb497b8977")
+set(OpenglSystemCommon_src FormatConversions.cpp HostConnection.cpp QemuPipeStream.cpp ProcessPipe.cpp AddressSpaceStream.cpp ThreadInfo_host.cpp)
+android_add_library(TARGET OpenglSystemCommon SHARED LICENSE Apache-2.0 SRC FormatConversions.cpp HostConnection.cpp QemuPipeStream.cpp ProcessPipe.cpp AddressSpaceStream.cpp ThreadInfo_host.cpp)
target_include_directories(OpenglSystemCommon PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon ${GOLDFISH_DEVICE_ROOT}/bionic/libc/platform ${GOLDFISH_DEVICE_ROOT}/bionic/libc/private ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/bionic-include ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
target_compile_definitions(OpenglSystemCommon PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN")
target_compile_options(OpenglSystemCommon PRIVATE "-fvisibility=default" "-Wno-unused-parameter" "-Wno-unused-variable")
diff --git a/system/OpenglSystemCommon/EmulatorFeatureInfo.h b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
index 9df134f..e20c129 100644
--- a/system/OpenglSystemCommon/EmulatorFeatureInfo.h
+++ b/system/OpenglSystemCommon/EmulatorFeatureInfo.h
@@ -26,15 +26,16 @@
// capability, and we will use a fence fd to synchronize buffer swaps.
enum SyncImpl {
SYNC_IMPL_NONE = 0,
- SYNC_IMPL_NATIVE_SYNC_V2 = 1,
- SYNC_IMPL_NATIVE_SYNC_V3 = 2,
+ SYNC_IMPL_NATIVE_SYNC_V2 = 1, // ANDROID_native_fence_sync
+ SYNC_IMPL_NATIVE_SYNC_V3 = 2, // KHR_wait_sync
+ SYNC_IMPL_NATIVE_SYNC_V4 = 3, // Correct eglGetSyncAttribKHR
};
-// Interface:
-// Use the highest of v2 or v3 that show up, making us
-// SYNC_IMPL_NATIVE_SYNC_V2 or SYNC_IMPL_NATIVE_SYNC_V3.
+// Interface for native sync:
+// Use the highest that shows up
static const char kRCNativeSyncV2[] = "ANDROID_EMU_native_sync_v2";
static const char kRCNativeSyncV3[] = "ANDROID_EMU_native_sync_v3";
+static const char kRCNativeSyncV4[] = "ANDROID_EMU_native_sync_v4";
// DMA for OpenGL
enum DmaImpl {
@@ -87,6 +88,9 @@
// Vulkan create resources with requirements
static const char kVulkanCreateResourcesWithRequirements[] = "ANDROID_EMU_vulkan_create_resources_with_requirements";
+// Vulkan ignored handles
+static const char kVulkanIgnoredHandles[] = "ANDROID_EMU_vulkan_ignored_handles";
+
// YUV host cache
static const char kYUVCache[] = "ANDROID_EMU_YUV_Cache";
@@ -106,6 +110,7 @@
hasDeferredVulkanCommands(false),
hasVulkanNullOptionalStrings(false),
hasVulkanCreateResourcesWithRequirements(false),
+ hasVulkanIgnoredHandles(false),
hasYUVCache (false),
hasAsyncUnmapBuffer (false) { }
@@ -118,8 +123,23 @@
bool hasDeferredVulkanCommands;
bool hasVulkanNullOptionalStrings;
bool hasVulkanCreateResourcesWithRequirements;
+ bool hasVulkanIgnoredHandles;
bool hasYUVCache;
bool hasAsyncUnmapBuffer;
};
+enum HostConnectionType {
+ HOST_CONNECTION_TCP = 0,
+ HOST_CONNECTION_QEMU_PIPE = 1,
+ HOST_CONNECTION_VIRTIO_GPU = 2,
+ HOST_CONNECTION_ADDRESS_SPACE = 3,
+ HOST_CONNECTION_VIRTIO_GPU_PIPE = 4,
+};
+
+enum GrallocType {
+ GRALLOC_TYPE_RANCHU = 0,
+ GRALLOC_TYPE_MINIGBM = 1,
+ GRALLOC_TYPE_DYN_ALLOC_MINIGBM = 2,
+};
+
#endif // __COMMON_EMULATOR_FEATURE_INFO_H
diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp
index 2cd1d38..f69b1d5 100644
--- a/system/OpenglSystemCommon/HostConnection.cpp
+++ b/system/OpenglSystemCommon/HostConnection.cpp
@@ -44,6 +44,7 @@
#ifdef GOLDFISH_VULKAN
#include "VkEncoder.h"
+#include "AddressSpaceStream.h"
#else
namespace goldfish_vk {
struct VkEncoder {
@@ -51,6 +52,12 @@
int placeholder;
};
} // namespace goldfish_vk
+class QemuPipeStream;
+typedef QemuPipeStream AddressSpaceStream;
+AddressSpaceStream* createAddressSpaceStream(size_t bufSize) {
+ ALOGE("%s: FATAL: Trying to create ASG stream in unsupported build\n", __func__);
+ abort();
+}
#endif
using goldfish_vk::VkEncoder;
@@ -63,7 +70,14 @@
#include "gralloc_cb.h"
#ifdef VIRTIO_GPU
+
#include "VirtioGpuStream.h"
+#include "VirtioGpuPipeStream.h"
+
+#include <cros_gralloc_handle.h>
+#include <drm/virtgpu_drm.h>
+#include <xf86drm.h>
+
#endif
#undef LOG_TAG
@@ -78,18 +92,29 @@
#define STREAM_PORT_NUM 22468
static HostConnectionType getConnectionTypeFromProperty() {
+#ifdef __Fuchsia__
+ return HOST_CONNECTION_ADDRESS_SPACE;
+#else
char transportValue[PROPERTY_VALUE_MAX] = "";
property_get("ro.kernel.qemu.gltransport", transportValue, "");
bool isValid = transportValue[0] != '\0';
+
+ if (!isValid) {
+ property_get("ro.boot.hardware.gltransport", transportValue, "");
+ isValid = transportValue[0] != '\0';
+ }
+
if (!isValid) return HOST_CONNECTION_QEMU_PIPE;
if (!strcmp("tcp", transportValue)) return HOST_CONNECTION_TCP;
if (!strcmp("pipe", transportValue)) return HOST_CONNECTION_QEMU_PIPE;
if (!strcmp("virtio-gpu", transportValue)) return HOST_CONNECTION_VIRTIO_GPU;
if (!strcmp("asg", transportValue)) return HOST_CONNECTION_ADDRESS_SPACE;
+ if (!strcmp("virtio-gpu-pipe", transportValue)) return HOST_CONNECTION_VIRTIO_GPU_PIPE;
return HOST_CONNECTION_QEMU_PIPE;
+#endif
}
static uint32_t getDrawCallFlushIntervalFromProperty() {
@@ -106,27 +131,215 @@
return (uint32_t)interval;
}
+static GrallocType getGrallocTypeFromProperty() {
+ char prop[PROPERTY_VALUE_MAX] = "";
+ property_get("ro.hardware.gralloc", prop, "");
+
+ bool isValid = prop[0] != '\0';
+
+ if (!isValid) return GRALLOC_TYPE_RANCHU;
+
+ if (!strcmp("ranchu", prop)) return GRALLOC_TYPE_RANCHU;
+ if (!strcmp("minigbm", prop)) return GRALLOC_TYPE_MINIGBM;
+ return GRALLOC_TYPE_RANCHU;
+}
class GoldfishGralloc : public Gralloc
{
public:
- uint32_t getHostHandle(native_handle_t const* handle)
+ virtual uint32_t createColorBuffer(
+ ExtendedRCEncoderContext* rcEnc,
+ int width, int height, uint32_t glformat) {
+ return rcEnc->rcCreateColorBuffer(
+ rcEnc, width, height, glformat);
+ }
+
+ virtual uint32_t getHostHandle(native_handle_t const* handle)
{
return cb_handle_t::from(handle)->hostHandle;
}
- int getFormat(native_handle_t const* handle)
+ virtual int getFormat(native_handle_t const* handle)
{
return cb_handle_t::from(handle)->format;
}
+
+ virtual size_t getAllocatedSize(native_handle_t const* handle)
+ {
+ return static_cast<size_t>(cb_handle_t::from(handle)->allocatedSize());
+ }
};
+static inline uint32_t align_up(uint32_t n, uint32_t a) {
+ return ((n + a - 1) / a) * a;
+}
+
+#ifdef VIRTIO_GPU
+
+class MinigbmGralloc : public Gralloc {
+public:
+ virtual uint32_t createColorBuffer(
+ ExtendedRCEncoderContext*,
+ int width, int height, uint32_t glformat) {
+
+ // Only supported format for pbuffers in gfxstream
+ // should be RGBA8
+ const uint32_t kGlRGB = 0x1907;
+ const uint32_t kGlRGBA = 0x1908;
+ const uint32_t kVirglFormatRGBA = 67; // VIRGL_FORMAT_R8G8B8A8_UNORM;
+ uint32_t virtgpu_format = 0;
+ uint32_t bpp = 0;
+ switch (glformat) {
+ case kGlRGB:
+ ALOGD("Note: egl wanted GL_RGB, still using RGBA");
+ virtgpu_format = kVirglFormatRGBA;
+ bpp = 4;
+ break;
+ case kGlRGBA:
+ virtgpu_format = kVirglFormatRGBA;
+ bpp = 4;
+ break;
+ default:
+ ALOGD("Note: egl wanted 0x%x, still using RGBA", glformat);
+ virtgpu_format = kVirglFormatRGBA;
+ bpp = 4;
+ break;
+ }
+ const uint32_t kPipeTexture2D = 2; // PIPE_TEXTURE_2D
+ const uint32_t kBindRenderTarget = 1 << 1; // VIRGL_BIND_RENDER_TARGET
+ struct drm_virtgpu_resource_create res_create;
+ memset(&res_create, 0, sizeof(res_create));
+ res_create.target = kPipeTexture2D;
+ res_create.format = virtgpu_format;
+ res_create.bind = kBindRenderTarget;
+ res_create.width = width;
+ res_create.height = height;
+ res_create.depth = 1;
+ res_create.array_size = 1;
+ res_create.last_level = 0;
+ res_create.nr_samples = 0;
+ res_create.stride = bpp * width;
+ res_create.size = align_up(bpp * width * height, PAGE_SIZE);
+
+ int ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE, &res_create);
+ if (ret) {
+ ALOGE("%s: DRM_IOCTL_VIRTGPU_RESOURCE_CREATE failed with %s (%d)\n", __func__,
+ strerror(errno), errno);
+ abort();
+ }
+
+ return res_create.res_handle;
+ }
+
+ virtual uint32_t getHostHandle(native_handle_t const* handle) {
+ struct drm_virtgpu_resource_info info;
+ if (!getResInfo(handle, &info)) {
+ ALOGE("%s: failed to get resource info\n", __func__);
+ return 0;
+ }
+
+ return info.res_handle;
+ }
+
+ virtual int getFormat(native_handle_t const* handle) {
+ return ((cros_gralloc_handle *)handle)->droid_format;
+ }
+
+ virtual size_t getAllocatedSize(native_handle_t const* handle) {
+ struct drm_virtgpu_resource_info info;
+ if (!getResInfo(handle, &info)) {
+ ALOGE("%s: failed to get resource info\n", __func__);
+ return 0;
+ }
+
+ return info.size;
+ }
+
+ void setFd(int fd) { m_fd = fd; }
+
+private:
+
+ bool getResInfo(native_handle_t const* handle,
+ struct drm_virtgpu_resource_info* info) {
+ memset(info, 0x0, sizeof(*info));
+ if (m_fd < 0) {
+ ALOGE("%s: Error, rendernode fd missing\n", __func__);
+ return false;
+ }
+
+ struct drm_gem_close gem_close;
+ memset(&gem_close, 0x0, sizeof(gem_close));
+
+ cros_gralloc_handle const* cros_handle =
+ reinterpret_cast<cros_gralloc_handle const*>(handle);
+
+ uint32_t prime_handle;
+ int ret = drmPrimeFDToHandle(m_fd, cros_handle->fds[0], &prime_handle);
+ if (ret) {
+ ALOGE("%s: DRM_IOCTL_PRIME_FD_TO_HANDLE failed: %s (errno %d)\n",
+ __func__, strerror(errno), errno);
+ return false;
+ }
+
+ info->bo_handle = prime_handle;
+ gem_close.handle = prime_handle;
+
+ ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_RESOURCE_INFO, info);
+ if (ret) {
+ ALOGE("%s: DRM_IOCTL_VIRTGPU_RESOURCE_INFO failed: %s (errno %d)\n",
+ __func__, strerror(errno), errno);
+ drmIoctl(m_fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
+ return false;
+ }
+
+ drmIoctl(m_fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
+ return true;
+ }
+
+ int m_fd = -1;
+};
+
+#else
+
+class MinigbmGralloc : public Gralloc {
+public:
+ virtual uint32_t createColorBuffer(
+ ExtendedRCEncoderContext*,
+ int width, int height, uint32_t glformat) {
+ ALOGE("%s: Error: using minigbm without -DVIRTIO_GPU\n", __func__);
+ return 0;
+ }
+
+ virtual uint32_t getHostHandle(native_handle_t const* handle) {
+ ALOGE("%s: Error: using minigbm without -DVIRTIO_GPU\n", __func__);
+ return 0;
+ }
+
+ virtual int getFormat(native_handle_t const* handle) {
+ ALOGE("%s: Error: using minigbm without -DVIRTIO_GPU\n", __func__);
+ return 0;
+ }
+
+ virtual size_t getAllocatedSize(native_handle_t const* handle) {
+ ALOGE("%s: Error: using minigbm without -DVIRTIO_GPU\n", __func__);
+ return 0;
+ }
+
+ void setFd(int fd) { m_fd = fd; }
+
+private:
+
+ int m_fd = -1;
+};
+
+#endif
+
class GoldfishProcessPipe : public ProcessPipe
{
public:
- bool processPipeInit(renderControl_encoder_context_t *rcEnc)
+ bool processPipeInit(HostConnectionType connType, renderControl_encoder_context_t *rcEnc)
{
- return ::processPipeInit(rcEnc);
+ return ::processPipeInit(connType, rcEnc);
}
};
@@ -151,6 +364,9 @@
if (m_rcEnc) {
(void) m_rcEnc->rcGetRendererVersion(m_rcEnc);
}
+ if (m_grallocType == GRALLOC_TYPE_MINIGBM) {
+ delete m_grallocHelper;
+ }
delete m_stream;
delete m_glEnc;
delete m_gl2Enc;
@@ -162,11 +378,23 @@
if (!con) return con;
const enum HostConnectionType connType = getConnectionTypeFromProperty();
+ // const enum HostConnectionType connType = HOST_CONNECTION_VIRTIO_GPU;
switch (connType) {
- default:
- case HOST_CONNECTION_ADDRESS_SPACE: // Not implemented yet
- ALOGE("Trying to use address space graphics device, not implemented yet\n");
+ case HOST_CONNECTION_ADDRESS_SPACE: {
+ AddressSpaceStream *stream = createAddressSpaceStream(STREAM_BUFFER_SIZE);
+ if (!stream) {
+ ALOGE("Failed to create AddressSpaceStream for host connection!!!\n");
+ delete con;
+ return NULL;
+ }
+ con->m_connectionType = HOST_CONNECTION_ADDRESS_SPACE;
+ con->m_grallocType = GRALLOC_TYPE_RANCHU;
+ con->m_stream = stream;
+ con->m_grallocHelper = &m_goldfishGralloc;
+ con->m_processPipe = &m_goldfishProcessPipe;
+ break;
+ }
case HOST_CONNECTION_QEMU_PIPE: {
QemuPipeStream *stream = new QemuPipeStream(STREAM_BUFFER_SIZE);
if (!stream) {
@@ -181,6 +409,7 @@
return NULL;
}
con->m_connectionType = HOST_CONNECTION_QEMU_PIPE;
+ con->m_grallocType = GRALLOC_TYPE_RANCHU;
con->m_stream = stream;
con->m_grallocHelper = &m_goldfishGralloc;
con->m_processPipe = &m_goldfishProcessPipe;
@@ -207,6 +436,7 @@
return NULL;
}
con->m_connectionType = HOST_CONNECTION_TCP;
+ con->m_grallocType = GRALLOC_TYPE_RANCHU;
con->m_stream = stream;
con->m_grallocHelper = &m_goldfishGralloc;
con->m_processPipe = &m_goldfishProcessPipe;
@@ -228,11 +458,50 @@
return NULL;
}
con->m_connectionType = HOST_CONNECTION_VIRTIO_GPU;
+ con->m_grallocType = GRALLOC_TYPE_MINIGBM;
con->m_stream = stream;
- con->m_grallocHelper = stream->getGralloc();
+ MinigbmGralloc* m = new MinigbmGralloc;
+ m->setFd(stream->getRendernodeFd());
+ con->m_grallocHelper = m;
con->m_processPipe = stream->getProcessPipe();
break;
}
+ case HOST_CONNECTION_VIRTIO_GPU_PIPE: {
+ VirtioGpuPipeStream *stream = new VirtioGpuPipeStream(STREAM_BUFFER_SIZE);
+ if (!stream) {
+ ALOGE("Failed to create VirtioGpu for host connection!!!\n");
+ delete con;
+ return NULL;
+ }
+ if (stream->connect() < 0) {
+ ALOGE("Failed to connect to host (VirtioGpu)!!!\n");
+ delete stream;
+ delete con;
+ return NULL;
+ }
+ con->m_connectionType = HOST_CONNECTION_VIRTIO_GPU_PIPE;
+ con->m_grallocType = getGrallocTypeFromProperty();
+ con->m_stream = stream;
+ switch (con->m_grallocType) {
+ case GRALLOC_TYPE_RANCHU:
+ con->m_grallocHelper = &m_goldfishGralloc;
+ break;
+ case GRALLOC_TYPE_MINIGBM: {
+ MinigbmGralloc* m = new MinigbmGralloc;
+ m->setFd(stream->getRendernodeFd());
+ con->m_grallocHelper = m;
+ break;
+ }
+ default:
+ ALOGE("Fatal: Unknown gralloc type 0x%x\n", con->m_grallocType);
+ abort();
+ }
+ con->m_processPipe = &m_goldfishProcessPipe;
+ break;
+ }
+#else
+ default:
+ break;
#endif
}
@@ -244,6 +513,8 @@
ALOGD("HostConnection::get() New Host Connection established %p, tid %d\n",
con, getCurrentThreadId());
+
+ // ALOGD("Address space echo latency check done\n");
return con;
}
@@ -279,7 +550,7 @@
}
}
-// static
+// static
HostConnection *HostConnection::createUnique() {
ALOGD("%s: call\n", __func__);
return connect(new HostConnection());
@@ -339,10 +610,11 @@
queryAndSetDeferredVulkanCommandsSupport(m_rcEnc);
queryAndSetVulkanNullOptionalStringsSupport(m_rcEnc);
queryAndSetVulkanCreateResourcesWithRequirementsSupport(m_rcEnc);
+ queryAndSetVulkanIgnoredHandles(m_rcEnc);
queryAndSetYUVCache(m_rcEnc);
queryAndSetAsyncUnmapBuffer(m_rcEnc);
if (m_processPipe) {
- m_processPipe->processPipeInit(m_rcEnc);
+ m_processPipe->processPipeInit(m_connectionType, m_rcEnc);
}
}
return m_rcEnc;
@@ -433,7 +705,9 @@
#if PLATFORM_SDK_VERSION <= 16 || (!defined(__i386__) && !defined(__x86_64__))
rcEnc->setSyncImpl(SYNC_IMPL_NONE);
#else
- if (glExtensions.find(kRCNativeSyncV3) != std::string::npos) {
+ if (glExtensions.find(kRCNativeSyncV4) != std::string::npos) {
+ rcEnc->setSyncImpl(SYNC_IMPL_NATIVE_SYNC_V4);
+ } else if (glExtensions.find(kRCNativeSyncV3) != std::string::npos) {
rcEnc->setSyncImpl(SYNC_IMPL_NATIVE_SYNC_V3);
} else if (glExtensions.find(kRCNativeSyncV2) != std::string::npos) {
rcEnc->setSyncImpl(SYNC_IMPL_NATIVE_SYNC_V2);
@@ -515,6 +789,13 @@
}
}
+void HostConnection::queryAndSetVulkanIgnoredHandles(ExtendedRCEncoderContext* rcEnc) {
+ std::string glExtensions = queryGLExtensions(rcEnc);
+ if (glExtensions.find(kVulkanIgnoredHandles) != std::string::npos) {
+ rcEnc->featureInfo()->hasVulkanIgnoredHandles = true;
+ }
+}
+
void HostConnection::queryAndSetYUVCache(ExtendedRCEncoderContext* rcEnc) {
std::string glExtensions = queryGLExtensions(rcEnc);
if (glExtensions.find(kYUVCache) != std::string::npos) {
diff --git a/system/OpenglSystemCommon/HostConnection.h b/system/OpenglSystemCommon/HostConnection.h
index c7547ca..0f262a3 100644
--- a/system/OpenglSystemCommon/HostConnection.h
+++ b/system/OpenglSystemCommon/HostConnection.h
@@ -54,6 +54,7 @@
m_featureInfo.hostComposition = hostComposition; }
bool hasNativeSync() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V2; }
bool hasNativeSyncV3() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V3; }
+ bool hasNativeSyncV4() const { return m_featureInfo.syncImpl >= SYNC_IMPL_NATIVE_SYNC_V4; }
bool hasHostCompositionV1() const {
return m_featureInfo.hostComposition == HOST_COMPOSITION_V1; }
bool hasHostCompositionV2() const {
@@ -113,26 +114,23 @@
// Abstraction for gralloc handle conversion
class Gralloc {
public:
+ virtual uint32_t createColorBuffer(
+ ExtendedRCEncoderContext* rcEnc, int width, int height, uint32_t glformat);
virtual uint32_t getHostHandle(native_handle_t const* handle) = 0;
virtual int getFormat(native_handle_t const* handle) = 0;
+ virtual size_t getAllocatedSize(native_handle_t const* handle) = 0;
virtual ~Gralloc() {}
};
// Abstraction for process pipe helper
class ProcessPipe {
public:
- virtual bool processPipeInit(renderControl_encoder_context_t *rcEnc) = 0;
+ virtual bool processPipeInit(HostConnectionType connType, renderControl_encoder_context_t *rcEnc) = 0;
virtual ~ProcessPipe() {}
};
struct EGLThreadInfo;
-enum HostConnectionType {
- HOST_CONNECTION_TCP = 0,
- HOST_CONNECTION_QEMU_PIPE = 1,
- HOST_CONNECTION_VIRTIO_GPU = 2,
- HOST_CONNECTION_ADDRESS_SPACE = 3,
-};
class HostConnection
{
@@ -202,11 +200,13 @@
void queryAndSetDeferredVulkanCommandsSupport(ExtendedRCEncoderContext *rcEnc);
void queryAndSetVulkanNullOptionalStringsSupport(ExtendedRCEncoderContext *rcEnc);
void queryAndSetVulkanCreateResourcesWithRequirementsSupport(ExtendedRCEncoderContext *rcEnc);
+ void queryAndSetVulkanIgnoredHandles(ExtendedRCEncoderContext *rcEnc);
void queryAndSetYUVCache(ExtendedRCEncoderContext *mrcEnc);
void queryAndSetAsyncUnmapBuffer(ExtendedRCEncoderContext *rcEnc);
private:
HostConnectionType m_connectionType;
+ GrallocType m_grallocType;
IOStream *m_stream;
GLEncoder *m_glEnc;
GL2Encoder *m_gl2Enc;
diff --git a/system/OpenglSystemCommon/ProcessPipe.cpp b/system/OpenglSystemCommon/ProcessPipe.cpp
index e04d153..40cb298 100644
--- a/system/OpenglSystemCommon/ProcessPipe.cpp
+++ b/system/OpenglSystemCommon/ProcessPipe.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "ProcessPipe.h"
#include "renderControl_enc.h"
#include "qemu_pipe.h"
@@ -26,17 +27,25 @@
#include <errno.h>
#ifdef __Fuchsia__
-#include <fuchsia/hardware/goldfish/pipe/cpp/fidl.h>
-#include <lib/fdio/fdio.h>
+#include <fuchsia/hardware/goldfish/cpp/fidl.h>
#include <lib/zx/vmo.h>
+
+#include "services/service_connector.h"
+
static QEMU_PIPE_HANDLE sProcDevice = 0;
-#endif
+#else // __Fuchsia__
+
+#include "VirtioGpuPipeStream.h"
+static VirtioGpuPipeStream* sVirtioGpuPipeStream = 0;
+
+#endif // !__Fuchsia__
static QEMU_PIPE_HANDLE sProcPipe = 0;
static pthread_once_t sProcPipeOnce = PTHREAD_ONCE_INIT;
// sProcUID is a unique ID per process assigned by the host.
// It is different from getpid().
static uint64_t sProcUID = 0;
+static volatile HostConnectionType sConnType = HOST_CONNECTION_VIRTIO_GPU_PIPE;
// processPipeInitOnce is used to generate a process unique ID (puid).
// processPipeInitOnce will only be called at most once per process.
@@ -47,30 +56,20 @@
// host.
#ifdef __Fuchsia__
static void processPipeInitOnce() {
- int fd = ::open(QEMU_PIPE_PATH, O_RDWR);
- if (fd < 0) {
- ALOGE("%s: failed to open " QEMU_PIPE_PATH ": %s",
- __FUNCTION__, strerror(errno));
+ zx::channel channel(GetConnectToServiceFunction()(QEMU_PIPE_PATH));
+ if (!channel) {
+ ALOGE("%s: failed to open " QEMU_PIPE_PATH,
+ __FUNCTION__);
return;
}
- zx::channel channel;
- zx_status_t status = fdio_get_service_handle(
- fd, channel.reset_and_get_address());
- if (status != ZX_OK) {
- ALOGE("%s: failed to get service handle for " QEMU_PIPE_PATH ": %d",
- __FUNCTION__, status);
- close(fd);
- return;
- }
-
- fuchsia::hardware::goldfish::pipe::DeviceSyncPtr device;
+ fuchsia::hardware::goldfish::PipeDeviceSyncPtr device;
device.Bind(std::move(channel));
- fuchsia::hardware::goldfish::pipe::PipeSyncPtr pipe;
+ fuchsia::hardware::goldfish::PipeSyncPtr pipe;
device->OpenPipe(pipe.NewRequest());
- zx_status_t status2 = ZX_OK;
+ zx_status_t status, status2 = ZX_OK;
zx::vmo vmo;
status = pipe->GetBuffer(&status2, &vmo);
if (status != ZX_OK || status2 != ZX_OK) {
@@ -113,8 +112,9 @@
sProcDevice = device.Unbind().TakeChannel().release();
sProcPipe = pipe.Unbind().TakeChannel().release();
}
-#else
-static void processPipeInitOnce() {
+#else // __Fuchsia__
+
+static void sQemuPipeInit() {
sProcPipe = qemu_pipe_open("GLProcessPipe");
if (!qemu_pipe_valid(sProcPipe)) {
sProcPipe = 0;
@@ -152,11 +152,37 @@
return;
}
}
-#endif
-bool processPipeInit(renderControl_encoder_context_t *rcEnc) {
+static void processPipeInitOnce() {
+#if defined(HOST_BUILD) || !defined(GOLDFISH_VULKAN)
+ sQemuPipeInit();
+#else // HOST_BUILD
+ switch (sConnType) {
+ // TODO: Move those over too
+ case HOST_CONNECTION_QEMU_PIPE:
+ case HOST_CONNECTION_ADDRESS_SPACE:
+ case HOST_CONNECTION_TCP:
+ case HOST_CONNECTION_VIRTIO_GPU:
+ sQemuPipeInit();
+ break;
+ case HOST_CONNECTION_VIRTIO_GPU_PIPE: {
+ sVirtioGpuPipeStream = new VirtioGpuPipeStream(4096);
+ sProcUID = sVirtioGpuPipeStream->initProcessPipe();
+ break;
+ }
+ }
+#endif // !HOST_BUILD
+}
+#endif // !__Fuchsia__
+
+bool processPipeInit(HostConnectionType connType, renderControl_encoder_context_t *rcEnc) {
+ sConnType = connType;
pthread_once(&sProcPipeOnce, processPipeInitOnce);
- if (!sProcPipe) return false;
+ bool pipeHandleInvalid = !sProcPipe;
+#ifndef __Fuchsia__
+ pipeHandleInvalid = pipeHandleInvalid && !sVirtioGpuPipeStream;
+#endif // !__Fuchsia__
+ if (pipeHandleInvalid) return false;
rcEnc->rcSetPuid(rcEnc, sProcUID);
return true;
}
diff --git a/system/OpenglSystemCommon/ProcessPipe.h b/system/OpenglSystemCommon/ProcessPipe.h
index 66744b1..dea2a3f 100644
--- a/system/OpenglSystemCommon/ProcessPipe.h
+++ b/system/OpenglSystemCommon/ProcessPipe.h
@@ -13,9 +13,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-
#pragma once
+#include "EmulatorFeatureInfo.h"
+
#include <stdint.h>
// The process pipe is used to notify the host about process exits,
@@ -30,6 +31,6 @@
//
// This is called when creating rcEncoder.
-struct renderControl_client_context_t;
+struct renderControl_encoder_context_t;
-extern bool processPipeInit(renderControl_encoder_context_t *rcEnc);
+extern bool processPipeInit(HostConnectionType connType, renderControl_encoder_context_t *rcEnc);
diff --git a/system/OpenglSystemCommon/QemuPipeStream.h b/system/OpenglSystemCommon/QemuPipeStream.h
index 65755da..87638af 100644
--- a/system/OpenglSystemCommon/QemuPipeStream.h
+++ b/system/OpenglSystemCommon/QemuPipeStream.h
@@ -26,7 +26,7 @@
#include "qemu_pipe.h"
#ifdef __Fuchsia__
-#include <fuchsia/hardware/goldfish/pipe/cpp/fidl.h>
+#include <fuchsia/hardware/goldfish/cpp/fidl.h>
#include <lib/zx/event.h>
#include <lib/zx/vmo.h>
#endif
@@ -58,8 +58,8 @@
size_t m_read;
size_t m_readLeft;
#ifdef __Fuchsia__
- fuchsia::hardware::goldfish::pipe::DeviceSyncPtr m_device;
- fuchsia::hardware::goldfish::pipe::PipeSyncPtr m_pipe;
+ fuchsia::hardware::goldfish::PipeDeviceSyncPtr m_device;
+ fuchsia::hardware::goldfish::PipeSyncPtr m_pipe;
zx::event m_event;
zx::vmo m_vmo;
#endif
diff --git a/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp b/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp
index 8b22719..66dec13 100644
--- a/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp
+++ b/system/OpenglSystemCommon/QemuPipeStreamFuchsia.cpp
@@ -17,7 +17,6 @@
#include <cutils/log.h>
#include <errno.h>
-#include <lib/fdio/fdio.h>
#include <lib/zx/channel.h>
#include <stdio.h>
#include <stdlib.h>
@@ -27,6 +26,8 @@
#include <utility>
+#include "services/service_connector.h"
+
constexpr size_t kReadSize = 512 * 1024;
constexpr size_t kWriteOffset = kReadSize;
@@ -68,27 +69,18 @@
int QemuPipeStream::connect(void)
{
- int fd = TEMP_FAILURE_RETRY(open(QEMU_PIPE_PATH, O_RDWR));
- if (fd < 0) {
- ALOGE("%s: failed to open " QEMU_PIPE_PATH ": %s",
- __FUNCTION__, strerror(errno));
+ zx::channel channel(GetConnectToServiceFunction()(QEMU_PIPE_PATH));
+ if (!channel) {
+ ALOGE("%s: failed to get service handle for " QEMU_PIPE_PATH,
+ __FUNCTION__);
return -1;
}
- zx::channel channel;
- zx_status_t status = fdio_get_service_handle(
- fd, channel.reset_and_get_address());
- if (status != ZX_OK) {
- ALOGE("%s: failed to get service handle for " QEMU_PIPE_PATH ": %d",
- __FUNCTION__, status);
- close(fd);
- return -1;
- }
m_device.Bind(std::move(channel));
m_device->OpenPipe(m_pipe.NewRequest());
zx::event event;
- status = zx::event::create(0, &event);
+ zx_status_t status = zx::event::create(0, &event);
if (status != ZX_OK) {
ALOGE("%s: failed to create event: %d", __FUNCTION__, status);
return -1;
@@ -286,14 +278,14 @@
}
zx_signals_t observed = ZX_SIGNAL_NONE;
status = m_event.wait_one(
- fuchsia::hardware::goldfish::pipe::SIGNAL_READABLE |
- fuchsia::hardware::goldfish::pipe::SIGNAL_HANGUP,
+ fuchsia::hardware::goldfish::SIGNAL_READABLE |
+ fuchsia::hardware::goldfish::SIGNAL_HANGUP,
zx::time::infinite(), &observed);
if (status != ZX_OK) {
ALOGD("%s: wait_one failed: %d", __FUNCTION__, status);
return nullptr;
}
- if (observed & fuchsia::hardware::goldfish::pipe::SIGNAL_HANGUP) {
+ if (observed & fuchsia::hardware::goldfish::SIGNAL_HANGUP) {
ALOGD("%s: Remote end hungup", __FUNCTION__);
return nullptr;
}
diff --git a/system/OpenglSystemCommon/VirtioGpuPipeStream.cpp b/system/OpenglSystemCommon/VirtioGpuPipeStream.cpp
new file mode 100644
index 0000000..d3618f3
--- /dev/null
+++ b/system/OpenglSystemCommon/VirtioGpuPipeStream.cpp
@@ -0,0 +1,420 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "VirtioGpuPipeStream.h"
+
+#include <drm/virtgpu_drm.h>
+#include <xf86drm.h>
+
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <errno.h>
+#include <unistd.h>
+
+// In a virtual machine, there should only be one GPU
+#define RENDERNODE_MINOR 128
+
+// Attributes use to allocate our response buffer
+// Similar to virgl's fence objects
+#define PIPE_BUFFER 0
+#define VIRGL_FORMAT_R8_UNORM 64
+#define VIRGL_BIND_CUSTOM (1 << 17)
+
+static const size_t kTransferBufferSize = (1048576);
+
+static const size_t kReadSize = 512 * 1024;
+static const size_t kWriteOffset = kReadSize;
+
+VirtioGpuPipeStream::VirtioGpuPipeStream(size_t bufSize) :
+ IOStream(bufSize),
+ m_fd(-1),
+ m_virtio_rh(~0U),
+ m_virtio_bo(0),
+ m_virtio_mapped(nullptr),
+ m_bufsize(bufSize),
+ m_buf(nullptr),
+ m_read(0),
+ m_readLeft(0),
+ m_writtenPos(0) { }
+
+VirtioGpuPipeStream::~VirtioGpuPipeStream()
+{
+ if (m_virtio_mapped) {
+ munmap(m_virtio_mapped, kTransferBufferSize);
+ }
+
+ if (m_virtio_bo > 0U) {
+ drm_gem_close gem_close = {
+ .handle = m_virtio_bo,
+ };
+ drmIoctl(m_fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
+ }
+
+ if (m_fd >= 0) {
+ close(m_fd);
+ }
+
+ free(m_buf);
+}
+
+int VirtioGpuPipeStream::connect(const char* serviceName)
+{
+ if (m_fd < 0) {
+ m_fd = drmOpenRender(RENDERNODE_MINOR);
+ if (m_fd < 0) {
+ ERR("%s: failed with fd %d (%s)", __func__, m_fd, strerror(errno));
+ return -1;
+ }
+ }
+
+ if (!m_virtio_bo) {
+ drm_virtgpu_resource_create create = {
+ .target = PIPE_BUFFER,
+ .format = VIRGL_FORMAT_R8_UNORM,
+ .bind = VIRGL_BIND_CUSTOM,
+ .width = kTransferBufferSize,
+ .height = 1U,
+ .depth = 1U,
+ .array_size = 0U,
+ .size = kTransferBufferSize,
+ .stride = kTransferBufferSize,
+ };
+
+ int ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE, &create);
+ if (ret) {
+ ERR("%s: failed with %d allocating command buffer (%s)",
+ __func__, ret, strerror(errno));
+ return -1;
+ }
+
+ m_virtio_bo = create.bo_handle;
+ if (!m_virtio_bo) {
+ ERR("%s: no handle when allocating command buffer",
+ __func__);
+ return -1;
+ }
+
+ m_virtio_rh = create.res_handle;
+
+ if (create.size != kTransferBufferSize) {
+ ERR("%s: command buffer wrongly sized, create.size=%zu "
+ "!= %zu", __func__,
+ static_cast<size_t>(create.size),
+ static_cast<size_t>(kTransferBufferSize));
+ abort();
+ }
+ }
+
+ if (!m_virtio_mapped) {
+ drm_virtgpu_map map = {
+ .handle = m_virtio_bo,
+ };
+
+ int ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_MAP, &map);
+ if (ret) {
+ ERR("%s: failed with %d mapping command response buffer (%s)",
+ __func__, ret, strerror(errno));
+ return -1;
+ }
+
+ m_virtio_mapped = static_cast<unsigned char*>(
+ mmap64(nullptr, kTransferBufferSize, PROT_WRITE,
+ MAP_SHARED, m_fd, map.offset));
+
+ if (m_virtio_mapped == MAP_FAILED) {
+ ERR("%s: failed with %d mmap'ing command response buffer (%s)",
+ __func__, ret, strerror(errno));
+ return -1;
+ }
+ }
+
+ wait();
+
+ if (serviceName) {
+ writeFully(serviceName, strlen(serviceName) + 1);
+ } else {
+ static const char kPipeString[] = "pipe:opengles";
+ std::string pipeStr(kPipeString);
+ writeFully(kPipeString, sizeof(kPipeString));
+ }
+ return 0;
+}
+
+uint64_t VirtioGpuPipeStream::initProcessPipe() {
+ connect("pipe:GLProcessPipe");
+ int32_t confirmInt = 100;
+ writeFully(&confirmInt, sizeof(confirmInt));
+ uint64_t res;
+ readFully(&res, sizeof(res));
+ return res;
+}
+
+void *VirtioGpuPipeStream::allocBuffer(size_t minSize) {
+ size_t allocSize = (m_bufsize < minSize ? minSize : m_bufsize);
+ if (!m_buf) {
+ m_buf = (unsigned char *)malloc(allocSize);
+ }
+ else if (m_bufsize < allocSize) {
+ unsigned char *p = (unsigned char *)realloc(m_buf, allocSize);
+ if (p != NULL) {
+ m_buf = p;
+ m_bufsize = allocSize;
+ } else {
+ ERR("realloc (%zu) failed\n", allocSize);
+ free(m_buf);
+ m_buf = NULL;
+ m_bufsize = 0;
+ }
+ }
+
+ return m_buf;
+}
+
+int VirtioGpuPipeStream::commitBuffer(size_t size) {
+ if (size == 0) return 0;
+ return writeFully(m_buf, size);
+}
+
+int VirtioGpuPipeStream::writeFully(const void *buf, size_t len)
+{
+ //DBG(">> VirtioGpuPipeStream::writeFully %d\n", len);
+ if (!valid()) return -1;
+ if (!buf) {
+ if (len>0) {
+ // If len is non-zero, buf must not be NULL. Otherwise the pipe would be
+ // in a corrupted state, which is lethal for the emulator.
+ ERR("VirtioGpuPipeStream::writeFully failed, buf=NULL, len %zu,"
+ " lethal error, exiting", len);
+ abort();
+ }
+ return 0;
+ }
+
+ size_t res = len;
+ int retval = 0;
+
+ while (res > 0) {
+ ssize_t stat = transferToHost((const char *)(buf) + (len - res), res);
+ if (stat > 0) {
+ res -= stat;
+ continue;
+ }
+ if (stat == 0) { /* EOF */
+ ERR("VirtioGpuPipeStream::writeFully failed: premature EOF\n");
+ retval = -1;
+ break;
+ }
+ if (errno == EAGAIN) {
+ continue;
+ }
+ retval = stat;
+ ERR("VirtioGpuPipeStream::writeFully failed: %s, lethal error, exiting.\n",
+ strerror(errno));
+ abort();
+ }
+ //DBG("<< VirtioGpuPipeStream::writeFully %d\n", len );
+ return retval;
+}
+
+const unsigned char *VirtioGpuPipeStream::readFully(void *buf, size_t len)
+{
+ flush();
+
+ if (!valid()) return NULL;
+ if (!buf) {
+ if (len > 0) {
+ // If len is non-zero, buf must not be NULL. Otherwise the pipe would be
+ // in a corrupted state, which is lethal for the emulator.
+ ERR("VirtioGpuPipeStream::readFully failed, buf=NULL, len %zu, lethal"
+ " error, exiting.", len);
+ abort();
+ }
+ }
+
+ size_t res = len;
+ while (res > 0) {
+ ssize_t stat = transferFromHost((char *)(buf) + len - res, res);
+ if (stat == 0) {
+ // client shutdown;
+ return NULL;
+ } else if (stat < 0) {
+ if (errno == EAGAIN) {
+ continue;
+ } else {
+ ERR("VirtioGpuPipeStream::readFully failed (buf %p, len %zu"
+ ", res %zu): %s, lethal error, exiting.", buf, len, res,
+ strerror(errno));
+ abort();
+ }
+ } else {
+ res -= stat;
+ }
+ }
+ //DBG("<< VirtioGpuPipeStream::readFully %d\n", len);
+ return (const unsigned char *)buf;
+}
+
+const unsigned char *VirtioGpuPipeStream::commitBufferAndReadFully(
+ size_t writeSize, void *userReadBufPtr, size_t totalReadSize)
+{
+ return commitBuffer(writeSize) ? nullptr : readFully(userReadBufPtr, totalReadSize);
+}
+
+const unsigned char *VirtioGpuPipeStream::read( void *buf, size_t *inout_len)
+{
+ //DBG(">> VirtioGpuPipeStream::read %d\n", *inout_len);
+ if (!valid()) return NULL;
+ if (!buf) {
+ ERR("VirtioGpuPipeStream::read failed, buf=NULL");
+ return NULL; // do not allow NULL buf in that implementation
+ }
+
+ int n = recv(buf, *inout_len);
+
+ if (n > 0) {
+ *inout_len = n;
+ return (const unsigned char *)buf;
+ }
+
+ //DBG("<< VirtioGpuPipeStream::read %d\n", *inout_len);
+ return NULL;
+}
+
+int VirtioGpuPipeStream::recv(void *buf, size_t len)
+{
+ if (!valid()) return int(ERR_INVALID_SOCKET);
+ char* p = (char *)buf;
+ int ret = 0;
+ while(len > 0) {
+ int res = transferFromHost(p, len);
+ if (res > 0) {
+ p += res;
+ ret += res;
+ len -= res;
+ continue;
+ }
+ if (res == 0) { /* EOF */
+ break;
+ }
+ if (errno != EAGAIN) {
+ continue;
+ }
+
+ /* A real error */
+ if (ret == 0)
+ ret = -1;
+ break;
+ }
+ return ret;
+}
+
+void VirtioGpuPipeStream::wait() {
+ struct drm_virtgpu_3d_wait waitcmd;
+ memset(&waitcmd, 0, sizeof(waitcmd));
+ waitcmd.handle = m_virtio_bo;
+ int ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_WAIT, &waitcmd);
+ if (ret) {
+ ERR("VirtioGpuPipeStream: DRM_IOCTL_VIRTGPU_WAIT failed with %d (%s)\n", errno, strerror(errno));
+ }
+ m_writtenPos = 0;
+}
+
+ssize_t VirtioGpuPipeStream::transferToHost(const void* buffer, size_t len) {
+ size_t todo = len;
+ size_t done = 0;
+ int ret = EAGAIN;
+ struct drm_virtgpu_3d_transfer_to_host xfer;
+
+ unsigned char* virtioPtr = m_virtio_mapped;
+
+ const unsigned char* readPtr = reinterpret_cast<const unsigned char*>(buffer);
+
+ while (done < len) {
+ size_t toXfer = todo > kTransferBufferSize ? kTransferBufferSize : todo;
+
+ if (toXfer > (kTransferBufferSize - m_writtenPos)) {
+ wait();
+ }
+
+ memcpy(virtioPtr + m_writtenPos, readPtr, toXfer);
+
+ memset(&xfer, 0, sizeof(xfer));
+ xfer.bo_handle = m_virtio_bo;
+ xfer.box.x = m_writtenPos;
+ xfer.box.y = 0;
+ xfer.box.w = toXfer;
+ xfer.box.h = 1;
+ xfer.box.d = 1;
+
+ ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_TRANSFER_TO_HOST, &xfer);
+
+ if (ret) {
+ ERR("VirtioGpuPipeStream: failed with errno %d (%s)\n", errno, strerror(errno));
+ return (ssize_t)ret;
+ }
+
+ done += toXfer;
+ readPtr += toXfer;
+ todo -= toXfer;
+ m_writtenPos += toXfer;
+ }
+
+ return len;
+}
+
+ssize_t VirtioGpuPipeStream::transferFromHost(void* buffer, size_t len) {
+ size_t todo = len;
+ size_t done = 0;
+ int ret = EAGAIN;
+ struct drm_virtgpu_3d_transfer_from_host xfer;
+
+ const unsigned char* virtioPtr = m_virtio_mapped;
+ unsigned char* readPtr = reinterpret_cast<unsigned char*>(buffer);
+
+ if (m_writtenPos) {
+ wait();
+ }
+
+ while (done < len) {
+ size_t toXfer = todo > kTransferBufferSize ? kTransferBufferSize : todo;
+
+ memset(&xfer, 0, sizeof(xfer));
+ xfer.bo_handle = m_virtio_bo;
+ xfer.box.x = 0;
+ xfer.box.y = 0;
+ xfer.box.w = toXfer;
+ xfer.box.h = 1;
+ xfer.box.d = 1;
+
+ ret = drmIoctl(m_fd, DRM_IOCTL_VIRTGPU_TRANSFER_FROM_HOST, &xfer);
+
+ if (ret) {
+ ERR("VirtioGpuPipeStream: failed with errno %d (%s)\n", errno, strerror(errno));
+ return (ssize_t)ret;
+ }
+
+ wait();
+
+ memcpy(readPtr, virtioPtr, toXfer);
+
+ done += toXfer;
+ readPtr += toXfer;
+ todo -= toXfer;
+ }
+
+ return len;
+}
diff --git a/system/OpenglSystemCommon/VirtioGpuPipeStream.h b/system/OpenglSystemCommon/VirtioGpuPipeStream.h
new file mode 100644
index 0000000..3f3c537
--- /dev/null
+++ b/system/OpenglSystemCommon/VirtioGpuPipeStream.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "HostConnection.h"
+#include "IOStream.h"
+
+#include <stdlib.h>
+
+/* This file implements an IOStream that uses VIRTGPU TRANSFER* ioctls on a
+ * virtio-gpu DRM rendernode device to communicate with a goldfish-pipe
+ * service on the host side.
+ */
+
+class VirtioGpuPipeStream : public IOStream {
+public:
+ typedef enum { ERR_INVALID_SOCKET = -1000 } QemuPipeStreamError;
+
+ explicit VirtioGpuPipeStream(size_t bufsize = 10000);
+ ~VirtioGpuPipeStream();
+ int connect(const char* serviceName = 0);
+ uint64_t initProcessPipe();
+
+ virtual void *allocBuffer(size_t minSize);
+ virtual int commitBuffer(size_t size);
+ virtual const unsigned char *readFully( void *buf, size_t len);
+ virtual const unsigned char *commitBufferAndReadFully(
+ size_t size, void *buf, size_t len);
+ virtual const unsigned char *read( void *buf, size_t *inout_len);
+
+ bool valid() { return m_fd >= 0; }
+ int getRendernodeFd() { return m_fd; }
+ int recv(void *buf, size_t len);
+
+ virtual int writeFully(const void *buf, size_t len);
+
+ int getSocket() const;
+private:
+ // sync. Also resets the write position.
+ void wait();
+
+ // transfer to/from host ops
+ ssize_t transferToHost(const void* buffer, size_t len);
+ ssize_t transferFromHost(void* buffer, size_t len);
+
+ int m_fd; // rendernode fd
+
+ uint32_t m_virtio_rh; // transfer buffer res handle
+ uint32_t m_virtio_bo; // transfer bo handle
+ unsigned char* m_virtio_mapped; // user mapping of bo
+
+ // intermediate buffer
+ size_t m_bufsize;
+ unsigned char *m_buf;
+ size_t m_read;
+ size_t m_readLeft;
+
+ size_t m_writtenPos;
+
+ VirtioGpuPipeStream(int sock, size_t bufSize);
+};
diff --git a/system/OpenglSystemCommon/VirtioGpuStream.cpp b/system/OpenglSystemCommon/VirtioGpuStream.cpp
index f6d04d8..a0876dc 100644
--- a/system/OpenglSystemCommon/VirtioGpuStream.cpp
+++ b/system/OpenglSystemCommon/VirtioGpuStream.cpp
@@ -52,25 +52,7 @@
unsigned char buf[0];
} __attribute__((packed));
-uint32_t CrosGralloc::getHostHandle(native_handle_t const* handle_)
-{
- uint32_t id = 0;
-
- if (m_fd >= 0) {
- cros_gralloc_handle const* handle =
- reinterpret_cast<cros_gralloc_handle const*>(handle_);
- drmPrimeFDToHandle(m_fd, handle->fds[0], &id);
- }
-
- return id;
-}
-
-int CrosGralloc::getFormat(native_handle_t const* handle)
-{
- return ((cros_gralloc_handle *)handle)->droid_format;
-}
-
-bool VirtioGpuProcessPipe::processPipeInit(renderControl_encoder_context_t *rcEnc)
+bool VirtioGpuProcessPipe::processPipeInit(HostConnectionType, renderControl_encoder_context_t *rcEnc)
{
union {
uint64_t proto;
@@ -187,7 +169,6 @@
}
}
- m_gralloc.setFd(m_fd);
return 0;
}
diff --git a/system/OpenglSystemCommon/VirtioGpuStream.h b/system/OpenglSystemCommon/VirtioGpuStream.h
index 0be50e6..1c7a496 100644
--- a/system/OpenglSystemCommon/VirtioGpuStream.h
+++ b/system/OpenglSystemCommon/VirtioGpuStream.h
@@ -27,23 +27,10 @@
struct VirtioGpuCmd;
-class CrosGralloc : public Gralloc
-{
- friend class VirtioGpuStream;
-
-public:
- virtual uint32_t getHostHandle(native_handle_t const* handle);
- virtual int getFormat(native_handle_t const* handle);
-
-private:
- inline void setFd(int fd) { m_fd = fd; }
- int m_fd = -1;
-};
-
class VirtioGpuProcessPipe : public ProcessPipe
{
public:
- virtual bool processPipeInit(renderControl_encoder_context_t *rcEnc);
+ virtual bool processPipeInit(HostConnectionType connType, renderControl_encoder_context_t *rcEnc);
};
class VirtioGpuStream : public IOStream
@@ -53,7 +40,6 @@
~VirtioGpuStream();
int connect();
- Gralloc *getGralloc() { return &m_gralloc; }
ProcessPipe *getProcessPipe() { return &m_processPipe; }
// override IOStream so we can see non-rounded allocation sizes
@@ -83,6 +69,8 @@
return m_fd >= 0 && m_cmdResp_bo > 0 && m_cmdResp;
}
+ int getRendernodeFd() { return m_fd; }
+
private:
// rendernode fd
int m_fd;
@@ -115,9 +103,6 @@
// bytes of an alloc flushed through flush() API
size_t m_allocFlushSize;
- // CrOS gralloc interface
- CrosGralloc m_gralloc;
-
// Fake process pipe implementation
VirtioGpuProcessPipe m_processPipe;
diff --git a/system/OpenglSystemCommon/address_space_graphics_types.h b/system/OpenglSystemCommon/address_space_graphics_types.h
new file mode 100644
index 0000000..1ebad34
--- /dev/null
+++ b/system/OpenglSystemCommon/address_space_graphics_types.h
@@ -0,0 +1,354 @@
+// Copyright 2019 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.
+#pragma once
+
+#include "android/base/ring_buffer.h"
+
+#include <functional>
+
+// This file defines common types for address space graphics and provides
+// documentation.
+
+// Address space graphics======================================================
+//
+// Basic idea
+//
+// Address space graphics (ASG) is a subdevice of the address space device that
+// provides a way to run graphics commands and data with fewer VM exits by
+// leveraging shared memory ring buffers.
+//
+// Each GL/Vk thread in the guest is associated with a context (asg_context).
+// asg_context consists of pointers into the shared memory that view it as a
+// collection of ring buffers and a common write buffer.
+//
+// Consumer concept
+//
+// ASG does not assume a particular rendering backend (though we will use
+// RenderThread's). This is for ease of coding/testing and flexibility; the
+// implementation is not coupled to emugl/libOpenglRender.
+//
+// Instead, there is the concept of a "Consumer" of ASG that will do something
+// with the data arriving from the shared memory region, and possibly reply
+// back to the guest. We register functions to construct and deconstruct
+// Consumers as part of emulator init (setConsumer).
+//
+// Guest workflow
+//
+// 1. Open address space device
+//
+// 2. Create the graphics context as the subdevice
+//
+// 3. ping(ASG_GET_RING) to get the offset/size of the ring buffer admin. info
+//
+// 4. ping(ASG_GET_BUFFER) to get the offset/size of the shared transfer buffer.
+//
+// 5. ioctl(CLAIM_SHARED) and mmap on those two offset/size pairs to get a
+// guest-side mapping.
+//
+// 6. call asg_context_create on the ring and buffer pointers to create the asg_context.
+//
+// 7. Now the guest and host share asg_context pts and can communicate.
+//
+// 8. But usually the guest will sometimes need to ping(ASG_NOTIFY_AVAILABLE)
+// so that the host side (which is usually a separate thread that we don't want
+// to spin too much) wakes up and processes data.
+
+namespace android {
+namespace base {
+
+class Stream;
+
+} // namespace base
+} // namespace android
+
+#define ADDRESS_SPACE_GRAPHICS_DEVICE_ID 0
+#define ADDRESS_SPACE_GRAPHICS_PAGE_SIZE 4096
+#define ADDRESS_SPACE_GRAPHICS_BLOCK_SIZE (16ULL * 1048576ULL)
+
+// AddressSpaceGraphicsContext shares memory with
+// the guest via the following layout:
+extern "C" {
+
+struct asg_ring_storage { // directly shared with guest
+ char to_host[ADDRESS_SPACE_GRAPHICS_PAGE_SIZE];
+ char to_host_large_xfer[ADDRESS_SPACE_GRAPHICS_PAGE_SIZE];
+ char from_host_large_xfer[ADDRESS_SPACE_GRAPHICS_PAGE_SIZE];
+};
+
+// Set by the address space graphics device to notify the guest that the host
+// has slept or is able to consume something, or we are exiting, or there is an
+// error.
+enum asg_host_state {
+ // The host renderthread is asleep and needs to be woken up.
+ ASG_HOST_STATE_NEED_NOTIFY = 0,
+
+ // The host renderthread is active and can consume new data
+ // without notification.
+ ASG_HOST_STATE_CAN_CONSUME = 1,
+
+ // Normal exit
+ ASG_HOST_STATE_EXIT = 2,
+
+ // Error: Something weird happened and we need to exit.
+ ASG_HOST_STATE_ERROR = 3,
+};
+
+struct asg_ring_config;
+
+// Each context has a pair of ring buffers for communication
+// to and from the host. There is another ring buffer for large xfers
+// to the host (all xfers from the host are already considered "large").
+//
+// Each context also comes with _one_ auxiliary buffer to hold both its own
+// commands and to perform private DMA transfers.
+struct asg_context { // ptrs into RingStorage
+ struct ring_buffer* to_host;
+ char* buffer;
+ asg_host_state* host_state;
+ asg_ring_config* ring_config;
+ struct ring_buffer_with_view to_host_large_xfer;
+ struct ring_buffer_with_view from_host_large_xfer;
+};
+
+// Helper function that will be common between guest and host:
+// Given ring storage and a write buffer, returns asg_context that
+// is the correct view into it.
+static struct asg_context asg_context_create(
+ char* ring_storage,
+ char* buffer,
+ uint32_t buffer_size) {
+
+ struct asg_context res;
+
+ res.to_host =
+ reinterpret_cast<struct ring_buffer*>(
+ ring_storage +
+ offsetof(struct asg_ring_storage, to_host));
+ res.to_host_large_xfer.ring =
+ reinterpret_cast<struct ring_buffer*>(
+ ring_storage +
+ offsetof(struct asg_ring_storage, to_host_large_xfer));
+ res.from_host_large_xfer.ring =
+ reinterpret_cast<struct ring_buffer*>(
+ ring_storage +
+ offsetof(struct asg_ring_storage, from_host_large_xfer));
+
+ ring_buffer_init(res.to_host);
+
+ res.buffer = buffer;
+ res.host_state =
+ reinterpret_cast<asg_host_state*>(
+ &res.to_host->state);
+ res.ring_config =
+ reinterpret_cast<asg_ring_config*>(
+ res.to_host->config);
+
+ ring_buffer_view_init(
+ res.to_host_large_xfer.ring,
+ &res.to_host_large_xfer.view,
+ (uint8_t*)res.buffer, buffer_size);
+
+ ring_buffer_view_init(
+ res.from_host_large_xfer.ring,
+ &res.from_host_large_xfer.view,
+ (uint8_t*)res.buffer, buffer_size);
+
+ return res;
+}
+
+// During operation, the guest sends commands and data over the auxiliary
+// buffer while using the |to_host| ring to communicate what parts of the auxiliary
+// buffer is outstanding traffic needing to be consumed by the host.
+// After a transfer completes to the host, the host may write back data.
+// The guest then reads the results on the same auxiliary buffer
+// while being notified of which parts to read via the |from_host| ring.
+//
+// The size of the auxiliary buffer and flush interval is defined by
+// the following config.ini android_hw setting:
+//
+// 1) android_hw->hw_gltransport_asg_writeBufferSize
+// 2) android_hw->hw_gltransport_asg_writeStepSize
+//
+// 1) the size for the auxiliary buffer
+// 2) the step size over which commands are flushed to the host
+//
+// When transferring commands, command data is built up in writeStepSize
+// chunks and flushed to the host when either writeStepSize is reached or
+// the guest flushes explicitly.
+//
+// Command vs. Data Modes
+//
+// For command data larger than writeStepSize or when transferring data, we
+// fall back to using a different mode where the entire auxiliary buffer is
+// used to perform the transfer, |asg_writeBufferSize| steps at a time. The
+// host is also notified of the total transport size.
+//
+// When writing back to the guest, it is assumed that the write buffer will
+// be completely empty as the guest has already flushed and the host has
+// already consumed all commands/data, and is writing back. In this case,
+// the full auxiliary buffer is used at the same time for writing back to
+// the guest.
+//
+// Larger / Shared transfers
+//
+// Each of |to_host| and |from_host| can contain elements of type 1, 2, or 3:
+// Type 1: 8 bytes: 4 bytes offset, 4 bytes size. Relative to write buffer.
+struct __attribute__((__packed__)) asg_type1_xfer {
+ uint32_t offset;
+ uint32_t size;
+};
+// Type 2: 16 bytes: 16 bytes offset into address space PCI space, 8 bytes
+// size.
+struct __attribute__((__packed__)) asg_type2_xfer {
+ uint64_t physAddr;
+ uint64_t size;
+};
+// Type 3: There is a large transfer of known size and the entire write buffer
+// will be used to send it over.
+//
+// For type 1 transfers, we get the corresponding host virtual address by
+// adding the offset to the beginning of the write buffer. For type 2
+// transfers, we need to calculate the guest physical address and then call
+// addressspacecontrolops.gethostptr, which is slower since it goes through
+// a data structure map of existing mappings.
+//
+// The rings never contain a mix of type 1 and 2 elements. For to_host,
+// the guest initiates changes between type 1 and 2.
+//
+// The config fields:
+//
+struct asg_ring_config {
+ // config[0]: size of the auxiliary buffer
+ uint32_t buffer_size;
+
+ // config[1]: flush interval for the auxiliary buffer
+ uint32_t flush_interval;
+
+ // the position of the interval in the auxiliary buffer
+ // that the host has read so far
+ uint32_t host_consumed_pos;
+
+ // the start of the places the guest might write to next
+ uint32_t guest_write_pos;
+
+ // 1 if transfers are of type 1, 2 if transfers of type 2,
+ // 3 if the overall transfer size is known and we are sending something large.
+ uint32_t transfer_mode;
+
+ // the size of the transfer, used if transfer size is known.
+ // Set before setting config[2] to 3.
+ uint32_t transfer_size;
+
+ // error state
+ uint32_t in_error;
+};
+
+// State/config changes may only occur if the ring is empty, or the state
+// is transitioning to Error. That way, the host and guest have a chance to
+// synchronize on the same state.
+//
+// Thus far we've established how commands and data are transferred
+// to and from the host. Next, let's discuss how AddressSpaceGraphicsContext
+// talks to the code that actually does something with the commands
+// and sends data back.
+
+} // extern "C"
+
+namespace android {
+namespace emulation {
+namespace asg {
+
+// Consumer Concept
+//
+// AddressSpaceGraphicsContext's are each associated with a consumer that
+// takes data off the auxiliary buffer and to_host, while sending back data
+// over the auxiliary buffer / from_host.
+//
+// will read the commands and write back data.
+//
+// The consumer type is fixed at startup. The interface is as follows:
+
+// Called by the consumer, implemented in AddressSpaceGraphicsContext:
+//
+// Called when the consumer doesn't find anything to
+// read in to_host. Will make the consumer sleep
+// until another Ping(NotifyAvailable).
+using OnUnavailableReadCallback =
+ std::function<int()>;
+
+// Unpacks a type 2 transfer into host pointer and size.
+using GetPtrCallback =
+ std::function<char*(uint64_t)>;
+
+struct ConsumerCallbacks {
+ OnUnavailableReadCallback onUnavailableRead;
+ GetPtrCallback getPtr;
+};
+
+using ConsumerCreateCallback =
+ std::function<void* (struct asg_context, ConsumerCallbacks)>;
+using ConsumerDestroyCallback =
+ std::function<void(void*)>;
+using ConsumerSaveCallback =
+ std::function<void(void*, base::Stream*)>;
+using ConsumerLoadCallback =
+ std::function<void(void*, base::Stream*)>;
+
+struct ConsumerInterface {
+ ConsumerCreateCallback create;
+ ConsumerDestroyCallback destroy;
+ ConsumerSaveCallback save;
+ ConsumerLoadCallback load;
+};
+
+} // namespace asg
+} // namespace emulation
+} // namespace android
+
+// The interface for the guest:
+
+extern "C" {
+// Handled outside in address_space_device.cpp:
+//
+// Ping(device id): Create the device. On the host, the two rings and
+// auxiliary buffer are allocated. The two rings are allocated up front.
+// Both the auxiliary buffers and the rings are allocated from blocks of
+// rings and auxiliary buffers. New blocks are created if we run out either
+// way.
+enum asg_command {
+ // Ping(get_ring): Returns, in the fields:
+ // metadata: offset to give to claimShared and mmap() in the guest
+ // size: size to give to claimShared and mmap() in the guest
+ ASG_GET_RING = 0,
+
+ // Ping(get_buffer): Returns, in the fields:
+ // metadata: offset to give to claimShared and mmap() in the guest
+ // size: size to give to claimShared and mmap() in the guest
+ ASG_GET_BUFFER = 1,
+
+ // Ping(set_version): Run after the guest reads and negotiates its
+ // version of the device with the host. The host now knows the guest's
+ // version and can proceed with a protocol that works for both.
+ // size (in): the version of the guest
+ // size (out): the version of the host
+ // After this command runs, the consumer is
+ // implicitly created.
+ ASG_SET_VERSION = 2,
+
+ // Ping(notiy_available): Wakes up the consumer from sleep so it
+ // can read data via toHost
+ ASG_NOTIFY_AVAILABLE = 3,
+};
+
+} // extern "C"
diff --git a/system/cbmanager/Android.mk b/system/cbmanager/Android.mk
new file mode 100644
index 0000000..753f00a
--- /dev/null
+++ b/system/cbmanager/Android.mk
@@ -0,0 +1,53 @@
+#
+# Copyright 2015 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_CFLAGS += \
+ -DLOG_TAG=\"cbmanager\" \
+ -Werror \
+
+ifeq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST))
+LOCAL_CFLAGS += \
+ -DHOST_BUILD \
+
+LOCAL_SRC_FILES := host.cpp
+else
+LOCAL_SHARED_LIBRARIES += \
+ liblog \
+ libcutils \
+ libutils \
+ libhidlbase \
+ android.hardware.graphics.mapper@2.0 \
+ android.hardware.graphics.mapper@3.0 \
+ android.hardware.graphics.allocator@2.0 \
+ android.hardware.graphics.allocator@3.0 \
+
+LOCAL_CFLAGS += \
+ -DPLATFORM_SDK_VERSION=$(PLATFORM_SDK_VERSION) \
+
+LOCAL_SRC_FILES := hidl.cpp
+
+endif
+
+LOCAL_C_INCLUDES += \
+ device/generic/goldfish-opengl/system/include \
+ device/generic/goldfish-opengl/shared/OpenglCodecCommon \
+
+LOCAL_MODULE := libcbmanager
+LOCAL_VENDOR_MODULE := true
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/system/cbmanager/debug.h b/system/cbmanager/debug.h
new file mode 100644
index 0000000..23899bd
--- /dev/null
+++ b/system/cbmanager/debug.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_GOLDFISH_OPENGL_SYSTEM_CBMANAGER_DEBUG_H
+#define ANDROID_GOLDFISH_OPENGL_SYSTEM_CBMANAGER_DEBUG_H
+
+#include <log/log.h>
+
+#define CRASH(MSG) \
+ do { \
+ ALOGE("%s:%d crashed with '%s'", __func__, __LINE__, MSG); \
+ ::abort(); \
+ } while (false)
+
+#define CRASH_IF(COND, MSG) \
+ do { \
+ if ((COND)) { \
+ ALOGE("%s:%d crashed on '%s' with '%s'", __func__, __LINE__, #COND, MSG); \
+ ::abort(); \
+ } \
+ } while (false)
+
+#define RETURN_ERROR_CODE(X) \
+ do { \
+ ALOGE("%s:%d failed with '%s' (%d)", \
+ __func__, __LINE__, strerror(-(X)), -(X)); \
+ return (X); \
+ } while (false)
+
+#define RETURN_ERROR(X) \
+ do { \
+ ALOGE("%s:%d failed with '%s'", __func__, __LINE__, #X); \
+ return (X); \
+ } while (false)
+
+#define RETURN(X) return (X)
+
+#endif // ANDROID_GOLDFISH_OPENGL_SYSTEM_CBMANAGER_DEBUG_H
diff --git a/system/cbmanager/hidl.cpp b/system/cbmanager/hidl.cpp
new file mode 100644
index 0000000..46b6b1b
--- /dev/null
+++ b/system/cbmanager/hidl.cpp
@@ -0,0 +1,387 @@
+/*
+ * Copyright 2019 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 <cutils/native_handle.h>
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <log/log.h>
+
+#include "cbmanager.h"
+#include "debug.h"
+
+namespace android {
+namespace {
+using hardware::hidl_handle;
+using hardware::hidl_vec;
+
+namespace IMapper2ns = hardware::graphics::mapper::V2_0;
+namespace IMapper3ns = hardware::graphics::mapper::V3_0;
+namespace IAllocator2ns = hardware::graphics::allocator::V2_0;
+namespace IAllocator3ns = hardware::graphics::allocator::V3_0;
+
+class CbManagerHidlV3Impl : public CbManager::CbManagerImpl {
+public:
+ typedef CbManager::BufferUsage BufferUsage;
+ typedef CbManager::PixelFormat PixelFormat;
+ typedef CbManager::YCbCrLayout YCbCrLayout;
+ typedef hardware::hidl_bitfield<BufferUsage> BufferUsageBits;
+
+ CbManagerHidlV3Impl(sp<IMapper3ns::IMapper> mapper,
+ sp<IAllocator3ns::IAllocator> allocator)
+ : mMapper(mapper), mAllocator(allocator) {}
+
+ native_handle_t* allocateBuffer(int width, int height,
+ PixelFormat format, BufferUsageBits usage) {
+ using IMapper3ns::Error;
+ using IMapper3ns::BufferDescriptor;
+
+ IMapper3ns::IMapper::BufferDescriptorInfo descriptor_info;
+ descriptor_info.width = width;
+ descriptor_info.height = height;
+ descriptor_info.layerCount = 1;
+ descriptor_info.format =
+ static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
+ descriptor_info.usage = usage;
+ Error hidl_err = Error::NONE;
+
+ BufferDescriptor descriptor;
+ mMapper->createDescriptor(descriptor_info,
+ [&](const Error &_error,
+ const BufferDescriptor &_descriptor) {
+ hidl_err = _error;
+ descriptor = _descriptor;
+ });
+ if (hidl_err != Error::NONE) {
+ RETURN_ERROR(nullptr);
+ }
+
+ hidl_handle raw_handle = nullptr;
+ mAllocator->allocate(descriptor, 1,
+ [&](const Error &_error,
+ uint32_t _stride,
+ const hidl_vec<hidl_handle> &_buffers) {
+ hidl_err = _error;
+ (void)_stride;
+ raw_handle = _buffers[0];
+ });
+ if (hidl_err != Error::NONE) {
+ RETURN_ERROR(nullptr);
+ }
+
+ native_handle_t *buf = nullptr;
+ mMapper->importBuffer(raw_handle, [&](const Error &_error,
+ void *_buf) {
+ hidl_err = _error;
+ buf = static_cast<native_handle_t*>(_buf);
+ });
+ if (hidl_err != Error::NONE) {
+ RETURN_ERROR(nullptr);
+ }
+
+ RETURN(buf);
+ }
+
+ void freeBuffer(const native_handle_t* _h) {
+ using IMapper2ns::Error;
+
+ native_handle_t* h = const_cast<native_handle_t*>(_h);
+
+ mMapper->freeBuffer(h);
+ native_handle_close(h);
+ native_handle_delete(h);
+ }
+
+ int lockBuffer(native_handle_t& handle,
+ BufferUsageBits usage,
+ int left, int top, int width, int height,
+ void** vaddr) {
+ using IMapper3ns::Error;
+
+ Error hidl_err = Error::NONE;
+ mMapper->lock(
+ &handle,
+ usage,
+ { left, top, width, height }, // rect
+ hidl_handle(), // fence
+ [&hidl_err, vaddr](const Error &_error,
+ void* _ptr,
+ int32_t /*bytesPerPixel*/,
+ int32_t /*bytesPerStride*/) {
+ hidl_err = _error;
+ if (_error == Error::NONE) {
+ *vaddr = _ptr;
+ }
+ });
+
+ if (hidl_err == Error::NONE) {
+ RETURN(0);
+ } else {
+ RETURN_ERROR(-1);
+ }
+ }
+
+ int lockYCbCrBuffer(native_handle_t& handle,
+ BufferUsageBits usage,
+ int left, int top, int width, int height,
+ YCbCrLayout* ycbcr) {
+ using IMapper3ns::Error;
+ typedef IMapper3ns::YCbCrLayout YCbCrLayout3;
+
+ Error hidl_err = Error::NONE;
+ mMapper->lockYCbCr(
+ &handle,
+ usage,
+ { left, top, width, height }, // rect
+ hidl_handle(), // fence
+ [&hidl_err, ycbcr](const Error &_error,
+ const YCbCrLayout3 &_ycbcr) {
+ hidl_err = _error;
+ if (_error == Error::NONE) {
+ ycbcr->y = _ycbcr.y;
+ ycbcr->cb = _ycbcr.cb;
+ ycbcr->cr = _ycbcr.cr;
+ ycbcr->yStride = _ycbcr.yStride;
+ ycbcr->cStride = _ycbcr.cStride;
+ ycbcr->chromaStep = _ycbcr.chromaStep;
+ }
+ });
+
+ if (hidl_err == Error::NONE) {
+ RETURN(0);
+ } else {
+ RETURN_ERROR(-1);
+ }
+ }
+
+ int unlockBuffer(native_handle_t& handle) {
+ using IMapper3ns::Error;
+
+ Error hidl_err = Error::NONE;
+ int fence = -1;
+ mMapper->unlock(
+ &handle,
+ [&hidl_err, &fence](const Error &_error,
+ const hidl_handle &_fence) {
+ hidl_err = _error;
+ (void)_fence;
+ });
+
+ if (hidl_err == Error::NONE) {
+ RETURN(0);
+ } else {
+ RETURN_ERROR(-1);
+ }
+ }
+
+private:
+ const sp<IMapper3ns::IMapper> mMapper;
+ const sp<IAllocator3ns::IAllocator> mAllocator;
+};
+
+class CbManagerHidlV2Impl : public CbManager::CbManagerImpl {
+public:
+ typedef CbManager::BufferUsage BufferUsage;
+ typedef CbManager::PixelFormat PixelFormat;
+ typedef CbManager::YCbCrLayout YCbCrLayout;
+ typedef hardware::hidl_bitfield<BufferUsage> BufferUsageBits;
+
+ CbManagerHidlV2Impl(sp<IMapper2ns::IMapper> mapper,
+ sp<IAllocator2ns::IAllocator> allocator)
+ : mMapper(mapper), mAllocator(allocator) {}
+
+ native_handle_t* allocateBuffer(int width, int height,
+ PixelFormat format, BufferUsageBits usage) {
+ using IMapper2ns::Error;
+ using IMapper2ns::BufferDescriptor;
+
+ IMapper2ns::IMapper::BufferDescriptorInfo descriptor_info;
+ descriptor_info.width = width;
+ descriptor_info.height = height;
+ descriptor_info.layerCount = 1;
+ descriptor_info.format = format;
+ descriptor_info.usage = usage;
+ Error hidl_err = Error::NONE;
+
+ BufferDescriptor descriptor;
+ mMapper->createDescriptor(descriptor_info,
+ [&](const Error &_error,
+ const BufferDescriptor &_descriptor) {
+ hidl_err = _error;
+ descriptor = _descriptor;
+ });
+ if (hidl_err != Error::NONE) {
+ RETURN_ERROR(nullptr);
+ }
+
+ hidl_handle raw_handle = nullptr;
+ mAllocator->allocate(descriptor, 1,
+ [&](const Error &_error,
+ uint32_t _stride,
+ const hidl_vec<hidl_handle> &_buffers) {
+ hidl_err = _error;
+ (void)_stride;
+ raw_handle = _buffers[0];
+ });
+ if (hidl_err != Error::NONE) {
+ RETURN_ERROR(nullptr);
+ }
+
+ native_handle_t *buf = nullptr;
+ mMapper->importBuffer(raw_handle, [&](const Error &_error,
+ void *_buf) {
+ hidl_err = _error;
+ buf = static_cast<native_handle_t*>(_buf);
+ });
+ if (hidl_err != Error::NONE) {
+ RETURN_ERROR(nullptr);
+ }
+
+ RETURN(buf);
+ }
+
+ void freeBuffer(const native_handle_t* _h) {
+ using IMapper2ns::Error;
+
+ native_handle_t* h = const_cast<native_handle_t*>(_h);
+
+ mMapper->freeBuffer(h);
+ native_handle_close(h);
+ native_handle_delete(h);
+ }
+
+ int lockBuffer(native_handle_t& handle,
+ BufferUsageBits usage,
+ int left, int top, int width, int height,
+ void** vaddr) {
+ using IMapper2ns::Error;
+
+ Error hidl_err = Error::NONE;
+ mMapper->lock(
+ &handle,
+ usage,
+ { left, top, width, height }, // rect
+ hidl_handle(), // fence
+ [&hidl_err, vaddr](const Error &_error,
+ void* _ptr) {
+ hidl_err = _error;
+ if (_error == Error::NONE) {
+ *vaddr = _ptr;
+ }
+ });
+
+ if (hidl_err == Error::NONE) {
+ RETURN(0);
+ } else {
+ RETURN_ERROR(-1);
+ }
+ }
+
+ int lockYCbCrBuffer(native_handle_t& handle,
+ BufferUsageBits usage,
+ int left, int top, int width, int height,
+ YCbCrLayout* ycbcr) {
+ using IMapper2ns::Error;
+
+ Error hidl_err = Error::NONE;
+ mMapper->lockYCbCr(
+ &handle,
+ usage,
+ { left, top, width, height }, // rect
+ hidl_handle(), // fence
+ [&hidl_err, ycbcr](const Error &_error,
+ const YCbCrLayout &_ycbcr) {
+ hidl_err = _error;
+ if (_error == Error::NONE) {
+ *ycbcr = _ycbcr;
+ }
+ });
+
+ if (hidl_err == Error::NONE) {
+ RETURN(0);
+ } else {
+ RETURN_ERROR(-1);
+ }
+ }
+
+ int unlockBuffer(native_handle_t& handle) {
+ using IMapper2ns::Error;
+
+ Error hidl_err = Error::NONE;
+ int fence = -1;
+ mMapper->unlock(
+ &handle,
+ [&hidl_err, &fence](const Error &_error,
+ const hidl_handle &_fence) {
+ hidl_err = _error;
+ (void)_fence;
+ });
+
+ if (hidl_err == Error::NONE) {
+ RETURN(0);
+ } else {
+ RETURN_ERROR(-1);
+ }
+ }
+
+private:
+ const sp<IMapper2ns::IMapper> mMapper;
+ const sp<IAllocator2ns::IAllocator> mAllocator;
+};
+
+std::unique_ptr<CbManager::CbManagerImpl> buildHidlImpl() {
+ {
+ sp<IMapper3ns::IMapper> mapper =
+ IMapper3ns::IMapper::getService();
+ if (!mapper) {
+ ALOGW("%s:%d: no IMapper@3.0 implementation found", __func__, __LINE__);
+ }
+
+ sp<IAllocator3ns::IAllocator> allocator =
+ IAllocator3ns::IAllocator::getService();
+ if (!allocator) {
+ ALOGW("%s:%d: no IAllocator@3.0 implementation found", __func__, __LINE__);
+ }
+
+ if (mapper && allocator) {
+ return std::make_unique<CbManagerHidlV3Impl>(mapper, allocator);
+ }
+ }
+ {
+ sp<IMapper2ns::IMapper> mapper =
+ IMapper2ns::IMapper::getService();
+ if (!mapper) {
+ ALOGW("%s:%d: no IMapper@2.0 implementation found", __func__, __LINE__);
+ }
+
+ sp<IAllocator2ns::IAllocator> allocator =
+ IAllocator2ns::IAllocator::getService();
+ if (!allocator) {
+ ALOGW("%s:%d: no IAllocator@2.0 implementation found", __func__, __LINE__);
+ }
+
+ return std::make_unique<CbManagerHidlV2Impl>(mapper, allocator);
+ }
+
+ return nullptr;
+}
+
+} // namespace
+
+CbManager::CbManager() : mImpl(buildHidlImpl()) {}
+
+} // namespace android
diff --git a/system/cbmanager/host.cpp b/system/cbmanager/host.cpp
new file mode 100644
index 0000000..c1a46af
--- /dev/null
+++ b/system/cbmanager/host.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019 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 <hardware/gralloc.h>
+#include "cbmanager.h"
+
+namespace android {
+namespace {
+
+class CbManagerHostImpl : public CbManager::CbManagerImpl {
+public:
+ CbManagerHostImpl() {}
+
+ ~CbManagerHostImpl() {}
+
+ const cb_handle_t* allocateBuffer(int width, int height, int format) {
+ return nullptr;
+ }
+
+ void freeBuffer(const cb_handle_t* h) {
+ }
+
+private:
+};
+
+std::unique_ptr<CbManager::CbManagerImpl> buildHostImpl() {
+ return std::make_unique<CbManagerHostImpl>();
+}
+} // namespace
+
+CbManager::CbManager() : mImpl(buildHostImpl()) {}
+
+} // namespace android
diff --git a/system/codecs/Android.mk b/system/codecs/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/system/codecs/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/system/codecs/omx/Android.mk b/system/codecs/omx/Android.mk
new file mode 100644
index 0000000..c307f8e
--- /dev/null
+++ b/system/codecs/omx/Android.mk
@@ -0,0 +1,16 @@
+#
+# Copyright 2018 The Android Open-Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+include $(call all-subdir-makefiles)
diff --git a/system/codecs/omx/avcdec/Android.mk b/system/codecs/omx/avcdec/Android.mk
new file mode 100644
index 0000000..798255f
--- /dev/null
+++ b/system/codecs/omx/avcdec/Android.mk
@@ -0,0 +1,55 @@
+#
+# Copyright 2019 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+commonSources := \
+ GoldfishAVCDec.cpp \
+ MediaH264Decoder.cpp
+
+$(call emugl-begin-shared-library,libstagefright_goldfish_avcdec$(GOLDFISH_OPENGL_LIB_SUFFIX))
+
+LOCAL_SRC_FILES := $(commonSources)
+
+LOCAL_CFLAGS += -DLOG_TAG=\"goldfish_avcdec\"
+LOCAL_CFLAGS += -Wno-unused-private-field
+
+$(call emugl-export,SHARED_LIBRARIES,libcutils libutils liblog)
+
+LOCAL_HEADER_LIBRARIES := media_plugin_headers \
+ libmedia_headers \
+ libbinder_headers \
+ libhidlbase_impl_internal \
+ libbase
+LOCAL_HEADER_LIBRARIES += libui_headers \
+ libnativewindow_headers \
+ libhardware_headers \
+ libarect_headers \
+ libarect_headers_for_ndk
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libutils \
+ liblog \
+ libcutils \
+ libui \
+ android.hardware.media.omx@1.0 \
+ android.hardware.graphics.allocator@3.0 \
+ android.hardware.graphics.mapper@3.0 \
+ libstagefright_foundation
+
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+$(call emugl-import,libgoldfish_codecs_common)
+$(call emugl-import,libstagefrighthw)
+$(call emugl-end-module)
diff --git a/system/codecs/omx/avcdec/GoldfishAVCDec.cpp b/system/codecs/omx/avcdec/GoldfishAVCDec.cpp
new file mode 100644
index 0000000..662fe4e
--- /dev/null
+++ b/system/codecs/omx/avcdec/GoldfishAVCDec.cpp
@@ -0,0 +1,618 @@
+/*
+ * Copyright 2015 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.
+ */
+
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include "GoldfishAVCDec.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <OMX_VideoExt.h>
+#include <inttypes.h>
+
+#include <nativebase/nativebase.h>
+
+#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <hidl/LegacySupport.h>
+
+using ::android::hardware::graphics::common::V1_2::PixelFormat;
+using ::android::hardware::graphics::common::V1_0::BufferUsage;
+
+namespace android {
+
+#define componentName "video_decoder.avc"
+#define codingType OMX_VIDEO_CodingAVC
+#define CODEC_MIME_TYPE MEDIA_MIMETYPE_VIDEO_AVC
+
+/** Function and structure definitions to keep code similar for each codec */
+#define ivdec_api_function ih264d_api_function
+#define ivdext_create_ip_t ih264d_create_ip_t
+#define ivdext_create_op_t ih264d_create_op_t
+#define ivdext_delete_ip_t ih264d_delete_ip_t
+#define ivdext_delete_op_t ih264d_delete_op_t
+#define ivdext_ctl_set_num_cores_ip_t ih264d_ctl_set_num_cores_ip_t
+#define ivdext_ctl_set_num_cores_op_t ih264d_ctl_set_num_cores_op_t
+
+#define IVDEXT_CMD_CTL_SET_NUM_CORES \
+ (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES
+
+static const CodecProfileLevel kProfileLevels[] = {
+ { OMX_VIDEO_AVCProfileConstrainedBaseline, OMX_VIDEO_AVCLevel52 },
+
+ { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel52 },
+
+ { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel52 },
+
+ { OMX_VIDEO_AVCProfileConstrainedHigh, OMX_VIDEO_AVCLevel52 },
+
+ { OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel52 },
+};
+
+GoldfishAVCDec::GoldfishAVCDec(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component, RenderMode renderMode)
+ : GoldfishVideoDecoderOMXComponent(
+ name, componentName, codingType,
+ kProfileLevels, ARRAY_SIZE(kProfileLevels),
+ 320 /* width */, 240 /* height */, callbacks,
+ appData, component),
+ mOmxColorFormat(OMX_COLOR_FormatYUV420Planar),
+ mChangingResolution(false),
+ mSignalledError(false),
+ mInputOffset(0), mRenderMode(renderMode){
+ if (renderMode == RenderMode::RENDER_BY_HOST_GPU) {
+ mOutputFormat = (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_YCBCR_420_888;
+ }
+ initPorts(
+ 1 /* numMinInputBuffers */, kNumBuffers, INPUT_BUF_SIZE,
+ 1 /* numMinOutputBuffers */, kNumBuffers, CODEC_MIME_TYPE);
+
+ mTimeStart = mTimeEnd = systemTime();
+
+ // If input dump is enabled, then open create an empty file
+ GENERATE_FILE_NAMES();
+ CREATE_DUMP_FILE(mInFile);
+}
+
+GoldfishAVCDec::~GoldfishAVCDec() {
+ CHECK_EQ(deInitDecoder(), (status_t)OK);
+}
+
+void GoldfishAVCDec::logVersion() {
+ // TODO: get emulation decoder implementation version from the host.
+ ALOGV("GoldfishAVC decoder version 1.0");
+}
+
+status_t GoldfishAVCDec::resetPlugin() {
+ mIsInFlush = false;
+ mReceivedEOS = false;
+
+ /* Initialize both start and end times */
+ mTimeStart = mTimeEnd = systemTime();
+
+ return OK;
+}
+
+status_t GoldfishAVCDec::resetDecoder() {
+ // The resolution may have changed, so our safest bet is to just destroy the
+ // current context and recreate another one, with the new width and height.
+ mContext->destroyH264Context();
+ mContext.reset(nullptr);
+
+ return OK;
+}
+
+status_t GoldfishAVCDec::setFlushMode() {
+ /* Set the decoder in Flush mode, subsequent decode() calls will flush */
+ mIsInFlush = true;
+ mContext->flush();
+ return OK;
+}
+
+status_t GoldfishAVCDec::initDecoder() {
+ /* Initialize the decoder */
+ mContext.reset(new MediaH264Decoder(mRenderMode));
+ mContext->initH264Context(mWidth,
+ mHeight,
+ mWidth,
+ mHeight,
+ MediaH264Decoder::PixelFormat::YUV420P);
+
+ /* Reset the plugin state */
+ resetPlugin();
+
+ /* Get codec version */
+ logVersion();
+
+ return OK;
+}
+
+status_t GoldfishAVCDec::deInitDecoder() {
+ if (mContext) {
+ mContext->destroyH264Context();
+ mContext.reset();
+ }
+
+ mChangingResolution = false;
+
+ return OK;
+}
+
+void GoldfishAVCDec::onReset() {
+ GoldfishVideoDecoderOMXComponent::onReset();
+
+ mSignalledError = false;
+ mInputOffset = 0;
+ resetDecoder();
+ resetPlugin();
+}
+
+bool GoldfishAVCDec::getVUIParams(h264_image_t& img) {
+ int32_t primaries = img.color_primaries;
+ bool fullRange = img.color_range == 2 ? true : false;
+ int32_t transfer = img.color_trc;
+ int32_t coeffs = img.colorspace;
+
+ ColorAspects colorAspects;
+ ColorUtils::convertIsoColorAspectsToCodecAspects(
+ primaries, transfer, coeffs, fullRange, colorAspects);
+
+ ALOGD("img pts %lld, primaries %d, range %d transfer %d colorspace %d", (long long)img.pts,
+ (int)img.color_primaries, (int)img.color_range, (int)img.color_trc, (int)img.colorspace);
+
+ // Update color aspects if necessary.
+ if (colorAspectsDiffer(colorAspects, mBitstreamColorAspects)) {
+ mBitstreamColorAspects = colorAspects;
+ status_t err = handleColorAspectsChange();
+ CHECK(err == OK);
+ }
+ return true;
+}
+
+bool GoldfishAVCDec::setDecodeArgs(
+ OMX_BUFFERHEADERTYPE *inHeader,
+ OMX_BUFFERHEADERTYPE *outHeader) {
+ size_t sizeY = outputBufferWidth() * outputBufferHeight();
+ size_t sizeUV = sizeY / 4;
+
+ /* When in flush and after EOS with zero byte input,
+ * inHeader is set to zero. Hence check for non-null */
+ if (inHeader) {
+ mConsumedBytes = inHeader->nFilledLen - mInputOffset;
+ mInPBuffer = inHeader->pBuffer + inHeader->nOffset + mInputOffset;
+ ALOGD("got input timestamp %lld in-addr-base %p real-data-offset %d inputoffset %d", (long long)(inHeader->nTimeStamp),
+ inHeader->pBuffer, (int)(inHeader->nOffset + mInputOffset), (int)mInputOffset);
+ } else {
+ mConsumedBytes = 0;
+ mInPBuffer = nullptr;
+ }
+
+ if (outHeader) {
+ if (outHeader->nAllocLen < sizeY + (sizeUV * 2)) {
+ ALOGE("outHeader->nAllocLen %d < needed size %d", outHeader->nAllocLen, (int)(sizeY + sizeUV * 2));
+ android_errorWriteLog(0x534e4554, "27833616");
+ return false;
+ }
+ mOutHeaderBuf = outHeader->pBuffer;
+ } else {
+ // We flush out on the host side
+ mOutHeaderBuf = nullptr;
+ }
+
+ return true;
+}
+
+void GoldfishAVCDec::readAndDiscardAllHostBuffers() {
+ while (mContext) {
+ h264_image_t img = mContext->getImage();
+ if (img.data != nullptr) {
+ ALOGD("img pts %lld is discarded", (long long)img.pts);
+ } else {
+ return;
+ }
+ }
+}
+
+void GoldfishAVCDec::onPortFlushCompleted(OMX_U32 portIndex) {
+ /* Once the output buffers are flushed, ignore any buffers that are held in decoder */
+ if (kOutputPortIndex == portIndex) {
+ setFlushMode();
+ ALOGD("%s %d", __func__, __LINE__);
+ readAndDiscardAllHostBuffers();
+ mContext->resetH264Context(mWidth, mHeight, mWidth, mHeight, MediaH264Decoder::PixelFormat::YUV420P);
+ if (!mCsd0.empty() && !mCsd1.empty()) {
+ mContext->decodeFrame(&(mCsd0[0]), mCsd0.size(), 0);
+ mContext->getImage();
+ mContext->decodeFrame(&(mCsd1[0]), mCsd1.size(), 0);
+ mContext->getImage();
+ }
+ resetPlugin();
+ } else {
+ mInputOffset = 0;
+ }
+}
+
+void GoldfishAVCDec::copyImageData( OMX_BUFFERHEADERTYPE *outHeader, h264_image_t & img) {
+ int myStride = outputBufferWidth();
+ for (int i=0; i < mHeight; ++i) {
+ memcpy(outHeader->pBuffer + i * myStride, img.data + i * mWidth, mWidth);
+ }
+ int Y = myStride * outputBufferHeight();
+ for (int i=0; i < mHeight/2; ++i) {
+ memcpy(outHeader->pBuffer + Y + i * myStride / 2 , img.data + mWidth * mHeight + i * mWidth/2, mWidth/2);
+ }
+ int UV = Y/4;
+ for (int i=0; i < mHeight/2; ++i) {
+ memcpy(outHeader->pBuffer + Y + UV + i * myStride / 2 , img.data + mWidth * mHeight * 5/4 + i * mWidth/2, mWidth/2);
+ }
+}
+
+int GoldfishAVCDec::getHostColorBufferId(void* header) {
+ if (mNWBuffers.find(header) == mNWBuffers.end()) {
+ return -1;
+ }
+ sp<ANativeWindowBuffer> nBuf = mNWBuffers[header];
+ cb_handle_t *handle = (cb_handle_t*)nBuf->handle;
+ return handle->hostHandle;
+}
+
+void GoldfishAVCDec::onQueueFilled(OMX_U32 portIndex) {
+ static int count1=0;
+ ALOGD("calling %s count %d", __func__, ++count1);
+ UNUSED(portIndex);
+ OMX_BUFFERHEADERTYPE *inHeader = NULL;
+ BufferInfo *inInfo = NULL;
+
+ if (mSignalledError) {
+ return;
+ }
+ if (mOutputPortSettingsChange != NONE) {
+ return;
+ }
+
+ if (mContext == nullptr) {
+ if (OK != initDecoder()) {
+ ALOGE("Failed to initialize decoder");
+ notify(OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
+ }
+
+ List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex);
+ List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
+
+ int count2=0;
+ while (!outQueue.empty()) {
+ ALOGD("calling %s in while loop count %d", __func__, ++count2);
+ BufferInfo *outInfo;
+ OMX_BUFFERHEADERTYPE *outHeader;
+
+ if (!mIsInFlush && (NULL == inHeader)) {
+ if (!inQueue.empty()) {
+ inInfo = *inQueue.begin();
+ inHeader = inInfo->mHeader;
+ if (inHeader == NULL) {
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ continue;
+ }
+ } else {
+ break;
+ }
+ }
+
+ outInfo = *outQueue.begin();
+ outHeader = outInfo->mHeader;
+ outHeader->nFlags = 0;
+ outHeader->nTimeStamp = 0;
+ outHeader->nOffset = 0;
+
+ if (inHeader != NULL) {
+ if (inHeader->nFilledLen == 0) {
+ // An empty buffer can be end of stream (EOS) buffer, so
+ // we'll set the decoder in flush mode if so. If it's not EOS,
+ // then just release the buffer.
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+
+ if (!(inHeader->nFlags & OMX_BUFFERFLAG_EOS)) {
+ return;
+ }
+
+ mReceivedEOS = true;
+ inHeader = NULL;
+ setFlushMode();
+ } else if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ mReceivedEOS = true;
+ }
+ }
+
+ {
+ nsecs_t timeDelay, timeTaken;
+
+ if (!setDecodeArgs(inHeader, outHeader)) {
+ ALOGE("Decoder arg setup failed");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
+
+ mTimeStart = systemTime();
+ /* Compute time elapsed between end of previous decode()
+ * to start of current decode() */
+ timeDelay = mTimeStart - mTimeEnd;
+
+ // TODO: We also need to send the timestamp
+ h264_result_t h264Res = {(int)MediaH264Decoder::Err::NoErr, 0};
+ if (inHeader != nullptr) {
+ if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ unsigned long mysize = (inHeader->nFilledLen - mInputOffset);
+ uint8_t* mydata = mInPBuffer;
+ if (mCsd0.empty()) {
+ mCsd0.assign(mydata, mydata + mysize);
+ } else if (mCsd1.empty()) {
+ mCsd1.assign(mydata, mydata + mysize);
+ }
+ }
+ ALOGD("Decoding frame(sz=%lu)", (unsigned long)(inHeader->nFilledLen - mInputOffset));
+ h264Res = mContext->decodeFrame(mInPBuffer,
+ inHeader->nFilledLen - mInputOffset,
+ inHeader->nTimeStamp);
+ mConsumedBytes = h264Res.bytesProcessed;
+ if (h264Res.ret == (int)MediaH264Decoder::Err::DecoderRestarted) {
+ mChangingResolution = true;
+ }
+ } else {
+ ALOGD("No more input data. Attempting to get a decoded frame, if any.");
+ }
+ h264_image_t img = {};
+
+ if (mRenderMode == RenderMode::RENDER_BY_GUEST_CPU) {
+ img = mContext->getImage();
+ } else {
+ img = mContext->renderOnHostAndReturnImageMetadata(getHostColorBufferId(outHeader));
+ }
+
+
+ if (img.data != nullptr) {
+ getVUIParams(img);
+ }
+
+ mTimeEnd = systemTime();
+ /* Compute time taken for decode() */
+ timeTaken = mTimeEnd - mTimeStart;
+
+
+ if (inHeader) {
+ ALOGD("input time stamp %lld flag %d", inHeader->nTimeStamp, (int)(inHeader->nFlags));
+ }
+
+ // If the decoder is in the changing resolution mode and there is no output present,
+ // that means the switching is done and it's ready to reset the decoder and the plugin.
+ if (mChangingResolution && img.data == nullptr) {
+ mChangingResolution = false;
+ ALOGD("re-create decoder because resolution changed");
+ bool portWillReset = false;
+ handlePortSettingsChange(&portWillReset, img.width, img.height);
+ {
+ ALOGD("handling port reset");
+ ALOGD("port resetting (img.width=%u, img.height=%u, mWidth=%u, mHeight=%u)",
+ img.width, img.height, mWidth, mHeight);
+ //resetDecoder();
+ resetPlugin();
+
+ //mContext->destroyH264Context();
+ //mContext.reset(new MediaH264Decoder());
+ mContext->resetH264Context(mWidth,
+ mHeight,
+ mWidth,
+ mHeight,
+ MediaH264Decoder::PixelFormat::YUV420P);
+ //mInputOffset += mConsumedBytes;
+ return;
+ }
+ }
+
+ if (img.data != nullptr) {
+ int myWidth = img.width;
+ int myHeight = img.height;
+ if (myWidth != mWidth || myHeight != mHeight) {
+ bool portWillReset = false;
+ handlePortSettingsChange(&portWillReset, myWidth, myHeight);
+ resetPlugin();
+ mWidth = myWidth;
+ mHeight = myHeight;
+ if (portWillReset) {
+ return;
+ }
+ }
+ outHeader->nFilledLen = (outputBufferWidth() * outputBufferHeight() * 3) / 2;
+ if (mRenderMode == RenderMode::RENDER_BY_GUEST_CPU) {
+ if (outputBufferWidth() == mWidth && outputBufferHeight() == mHeight) {
+ memcpy(outHeader->pBuffer, img.data, outHeader->nFilledLen);
+ } else {
+ copyImageData(outHeader, img);
+ }
+ }
+
+ outHeader->nTimeStamp = img.pts;
+ ALOGD("got output timestamp %lld", (long long)(img.pts));
+
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(outQueue.begin());
+ outInfo = NULL;
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+ } else if (mIsInFlush) {
+ ALOGD("not img.data and it is in flush mode");
+ /* If in flush mode and no output is returned by the codec,
+ * then come out of flush mode */
+ mIsInFlush = false;
+
+ /* If EOS was recieved on input port and there is no output
+ * from the codec, then signal EOS on output port */
+ if (mReceivedEOS) {
+ ALOGD("recived EOS, re-create host context");
+ outHeader->nFilledLen = 0;
+ outHeader->nFlags |= OMX_BUFFERFLAG_EOS;
+
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(outQueue.begin());
+ outInfo = NULL;
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+ resetPlugin();
+
+ //mContext->destroyH264Context();
+ //mContext.reset(new MediaH264Decoder());
+ mContext->resetH264Context(mWidth,
+ mHeight,
+ mWidth,
+ mHeight,
+ MediaH264Decoder::PixelFormat::YUV420P);
+
+ }
+ }
+ mInputOffset += mConsumedBytes;
+ }
+
+ // If more than 4 bytes are remaining in input, then do not release it
+ if (inHeader != NULL && ((inHeader->nFilledLen - mInputOffset) <= 4)) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ mInputOffset = 0;
+
+ /* If input EOS is seen and decoder is not in flush mode,
+ * set the decoder in flush mode.
+ * There can be a case where EOS is sent along with last picture data
+ * In that case, only after decoding that input data, decoder has to be
+ * put in flush. This case is handled here */
+
+ if (mReceivedEOS && !mIsInFlush) {
+ setFlushMode();
+ }
+ }
+ }
+}
+
+OMX_ERRORTYPE GoldfishAVCDec::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ const int32_t indexFull = index;
+ switch (indexFull) {
+ case kGetAndroidNativeBufferUsageIndex:
+ {
+ ALOGD("calling kGetAndroidNativeBufferUsageIndex");
+ GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) params;
+ nativeBuffersUsage->nUsage = (unsigned int)(BufferUsage::GPU_DATA_BUFFER);
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return GoldfishVideoDecoderOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE GoldfishAVCDec::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ // Include extension index OMX_INDEXEXTTYPE.
+ const int32_t indexFull = index;
+
+ switch (indexFull) {
+ case kEnableAndroidNativeBuffersIndex:
+ {
+ ALOGD("calling kEnableAndroidNativeBuffersIndex");
+ EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) params;
+ if (enableNativeBuffers) {
+ mEnableAndroidNativeBuffers = enableNativeBuffers->enable;
+ if (mEnableAndroidNativeBuffers == false) {
+ mNWBuffers.clear();
+ ALOGD("disabled kEnableAndroidNativeBuffersIndex");
+ } else {
+ ALOGD("enabled kEnableAndroidNativeBuffersIndex");
+ }
+ }
+ return OMX_ErrorNone;
+ }
+
+ case kUseAndroidNativeBufferIndex:
+ {
+ if (mEnableAndroidNativeBuffers == false) {
+ ALOGE("Error: not enabled Android Native Buffers");
+ return OMX_ErrorBadParameter;
+ }
+ UseAndroidNativeBufferParams *use_buffer_params = (UseAndroidNativeBufferParams *)params;
+ if (use_buffer_params) {
+ sp<ANativeWindowBuffer> nBuf = use_buffer_params->nativeBuffer;
+ cb_handle_t *handle = (cb_handle_t*)nBuf->handle;
+ void* dst = NULL;
+ ALOGD("kUseAndroidNativeBufferIndex with handle %p host color handle %d calling usebuffer", handle,
+ handle->hostHandle);
+ useBufferCallerLockedAlready(use_buffer_params->bufferHeader,use_buffer_params->nPortIndex,
+ use_buffer_params->pAppPrivate,handle->allocatedSize(), (OMX_U8*)dst);
+ mNWBuffers[*(use_buffer_params->bufferHeader)] = use_buffer_params->nativeBuffer;;
+ }
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return GoldfishVideoDecoderOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE GoldfishAVCDec::getExtensionIndex(
+ const char *name, OMX_INDEXTYPE *index) {
+
+ if (mRenderMode == RenderMode::RENDER_BY_HOST_GPU) {
+ if (!strcmp(name, "OMX.google.android.index.enableAndroidNativeBuffers")) {
+ ALOGD("calling getExtensionIndex for enable ANB");
+ *(int32_t*)index = kEnableAndroidNativeBuffersIndex;
+ return OMX_ErrorNone;
+ } else if (!strcmp(name, "OMX.google.android.index.useAndroidNativeBuffer")) {
+ *(int32_t*)index = kUseAndroidNativeBufferIndex;
+ return OMX_ErrorNone;
+ } else if (!strcmp(name, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
+ *(int32_t*)index = kGetAndroidNativeBufferUsageIndex;
+ return OMX_ErrorNone;
+ }
+ }
+ return GoldfishVideoDecoderOMXComponent::getExtensionIndex(name, index);
+}
+
+int GoldfishAVCDec::getColorAspectPreference() {
+ return kPreferBitstream;
+}
+
+} // namespace android
+
+android::GoldfishOMXComponent *createGoldfishOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData,
+ OMX_COMPONENTTYPE **component) {
+ if (!strncmp("OMX.android.goldfish", name, 20)) {
+ return new android::GoldfishAVCDec(name, callbacks, appData, component, RenderMode::RENDER_BY_HOST_GPU);
+ } else {
+ return new android::GoldfishAVCDec(name, callbacks, appData, component, RenderMode::RENDER_BY_GUEST_CPU);
+ }
+}
+
diff --git a/system/codecs/omx/avcdec/GoldfishAVCDec.h b/system/codecs/omx/avcdec/GoldfishAVCDec.h
new file mode 100644
index 0000000..dc9dc96
--- /dev/null
+++ b/system/codecs/omx/avcdec/GoldfishAVCDec.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GOLDFISH_H264_DEC_H_
+
+#define GOLDFISH_H264_DEC_H_
+
+#include "GoldfishVideoDecoderOMXComponent.h"
+#include "MediaH264Decoder.h"
+#include <sys/time.h>
+
+#include <vector>
+#include <map>
+
+#include "gralloc_cb.h"
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <utils/Vector.h>
+#include <utils/List.h>
+#include <ui/GraphicBuffer.h>
+
+
+namespace android {
+
+/** Number of entries in the time-stamp array */
+#define MAX_TIME_STAMPS 64
+
+/** Maximum number of cores supported by the codec */
+#define CODEC_MAX_NUM_CORES 4
+
+#define CODEC_MAX_WIDTH 1920
+
+#define CODEC_MAX_HEIGHT 1088
+
+/** Input buffer size */
+#define INPUT_BUF_SIZE (1024 * 1024)
+
+#define MIN(a, b) ((a) < (b)) ? (a) : (b)
+
+/** Used to remove warnings about unused parameters */
+#define UNUSED(x) ((void)(x))
+
+struct GoldfishAVCDec : public GoldfishVideoDecoderOMXComponent {
+ GoldfishAVCDec(const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component, RenderMode renderMode);
+
+protected:
+ virtual ~GoldfishAVCDec();
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+ virtual void onPortFlushCompleted(OMX_U32 portIndex);
+ virtual void onReset();
+ virtual int getColorAspectPreference();
+
+ virtual OMX_ERRORTYPE internalGetParameter(OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE getExtensionIndex(const char *name, OMX_INDEXTYPE *index);
+
+private:
+ // Number of input and output buffers
+ enum {
+ kNumBuffers = 8
+ };
+
+ RenderMode mRenderMode = RenderMode::RENDER_BY_GUEST_CPU;
+ bool mEnableAndroidNativeBuffers = false;
+ std::map<void*, sp<ANativeWindowBuffer>> mNWBuffers;
+
+ int getHostColorBufferId(void* header);
+
+ size_t mNumCores; // Number of cores to be uesd by the codec
+
+ nsecs_t mTimeStart; // Time at the start of decode()
+ nsecs_t mTimeEnd; // Time at the end of decode()
+
+#ifdef FILE_DUMP_ENABLE
+ char mInFile[200];
+#endif /* FILE_DUMP_ENABLE */
+
+ OMX_COLOR_FORMATTYPE mOmxColorFormat; // OMX Color format
+
+ bool mIsInFlush; // codec is flush mode
+ bool mReceivedEOS; // EOS is receieved on input port
+
+ // The input stream has changed to a different resolution, which is still supported by the
+ // codec. So the codec is switching to decode the new resolution.
+ bool mChangingResolution;
+ bool mSignalledError;
+ size_t mInputOffset;
+
+ status_t initDecoder();
+ status_t deInitDecoder();
+ status_t setFlushMode();
+ status_t setParams(size_t stride);
+ void logVersion();
+ status_t setNumCores();
+ status_t resetDecoder();
+ status_t resetPlugin();
+
+
+ void readAndDiscardAllHostBuffers();
+
+ bool setDecodeArgs(
+ OMX_BUFFERHEADERTYPE *inHeader,
+ OMX_BUFFERHEADERTYPE *outHeader);
+
+ bool getVUIParams(h264_image_t& img);
+
+ void copyImageData( OMX_BUFFERHEADERTYPE *outHeader, h264_image_t & img);
+
+ std::unique_ptr<MediaH264Decoder> mContext;
+ std::vector<uint8_t> mCsd0;
+ std::vector<uint8_t> mCsd1;
+ uint64_t mConsumedBytes = 0;
+ uint8_t* mInPBuffer = nullptr;
+ uint8_t* mOutHeaderBuf = nullptr;
+ DISALLOW_EVIL_CONSTRUCTORS(GoldfishAVCDec);
+};
+#ifdef FILE_DUMP_ENABLE
+
+#define INPUT_DUMP_PATH "/sdcard/media/avcd_input"
+#define INPUT_DUMP_EXT "h264"
+
+#define GENERATE_FILE_NAMES() { \
+ strcpy(mInFile, ""); \
+ sprintf(mInFile, "%s_%lld.%s", INPUT_DUMP_PATH, \
+ (long long) mTimeStart, \
+ INPUT_DUMP_EXT); \
+}
+
+#define CREATE_DUMP_FILE(m_filename) { \
+ FILE *fp = fopen(m_filename, "wb"); \
+ if (fp != NULL) { \
+ fclose(fp); \
+ } else { \
+ ALOGD("Could not open file %s", m_filename); \
+ } \
+}
+#define DUMP_TO_FILE(m_filename, m_buf, m_size, m_offset)\
+{ \
+ FILE *fp = fopen(m_filename, "ab"); \
+ if (fp != NULL && m_buf != NULL && m_offset == 0) { \
+ int i; \
+ i = fwrite(m_buf, 1, m_size, fp); \
+ ALOGD("fwrite ret %d to write %d", i, m_size); \
+ if (i != (int) m_size) { \
+ ALOGD("Error in fwrite, returned %d", i); \
+ perror("Error in write to file"); \
+ } \
+ } else if (fp == NULL) { \
+ ALOGD("Could not write to file %s", m_filename);\
+ } \
+ if (fp) { \
+ fclose(fp); \
+ } \
+}
+#else /* FILE_DUMP_ENABLE */
+#define INPUT_DUMP_PATH
+#define INPUT_DUMP_EXT
+#define OUTPUT_DUMP_PATH
+#define OUTPUT_DUMP_EXT
+#define GENERATE_FILE_NAMES()
+#define CREATE_DUMP_FILE(m_filename)
+#define DUMP_TO_FILE(m_filename, m_buf, m_size, m_offset)
+#endif /* FILE_DUMP_ENABLE */
+
+} // namespace android
+
+#endif // GOLDFISH_H264_DEC_H_
diff --git a/system/codecs/omx/avcdec/MediaH264Decoder.cpp b/system/codecs/omx/avcdec/MediaH264Decoder.cpp
new file mode 100644
index 0000000..e7aaf75
--- /dev/null
+++ b/system/codecs/omx/avcdec/MediaH264Decoder.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2015 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 <utils/Log.h>
+
+#include "MediaH264Decoder.h"
+#include "goldfish_media_utils.h"
+#include <string.h>
+
+MediaH264Decoder::MediaH264Decoder(RenderMode renderMode) :mRenderMode(renderMode) {
+ if (renderMode == RenderMode::RENDER_BY_HOST_GPU) {
+ mVersion = 200;
+ } else if (renderMode == RenderMode::RENDER_BY_GUEST_CPU) {
+ mVersion = 100;
+ }
+}
+
+void MediaH264Decoder::initH264Context(unsigned int width,
+ unsigned int height,
+ unsigned int outWidth,
+ unsigned int outHeight,
+ PixelFormat pixFmt) {
+ auto transport = GoldfishMediaTransport::getInstance();
+ if (!mHasAddressSpaceMemory) {
+ int slot = transport->getMemorySlot();
+ if (slot < 0) {
+ ALOGE("ERROR: Failed to initH264Context: cannot get memory slot");
+ return;
+ }
+ mAddressOffSet = static_cast<unsigned int>(slot) * 8 * (1 << 20);
+ ALOGD("got memory lot %d addrr %x", slot, mAddressOffSet);
+ mHasAddressSpaceMemory = true;
+ }
+ transport->writeParam(mVersion, 0, mAddressOffSet);
+ transport->writeParam(width, 1, mAddressOffSet);
+ transport->writeParam(height, 2, mAddressOffSet);
+ transport->writeParam(outWidth, 3, mAddressOffSet);
+ transport->writeParam(outHeight, 4, mAddressOffSet);
+ transport->writeParam(static_cast<uint64_t>(pixFmt), 5, mAddressOffSet);
+ transport->sendOperation(MediaCodecType::H264Codec,
+ MediaOperation::InitContext, mAddressOffSet);
+ auto* retptr = transport->getReturnAddr(mAddressOffSet);
+ mHostHandle = *(uint64_t*)(retptr);
+ ALOGD("initH264Context: got handle to host %lld", mHostHandle);
+}
+
+
+void MediaH264Decoder::resetH264Context(unsigned int width,
+ unsigned int height,
+ unsigned int outWidth,
+ unsigned int outHeight,
+ PixelFormat pixFmt) {
+ auto transport = GoldfishMediaTransport::getInstance();
+ if (!mHasAddressSpaceMemory) {
+ ALOGE("%s no address space memory", __func__);
+ return;
+ }
+ transport->writeParam((uint64_t)mHostHandle, 0, mAddressOffSet);
+ transport->writeParam(width, 1, mAddressOffSet);
+ transport->writeParam(height, 2, mAddressOffSet);
+ transport->writeParam(outWidth, 3, mAddressOffSet);
+ transport->writeParam(outHeight, 4, mAddressOffSet);
+ transport->writeParam(static_cast<uint64_t>(pixFmt), 5, mAddressOffSet);
+ transport->sendOperation(MediaCodecType::H264Codec,
+ MediaOperation::Reset, mAddressOffSet);
+ ALOGD("resetH264Context: done");
+}
+
+
+void MediaH264Decoder::destroyH264Context() {
+
+ ALOGD("return memory lot %d addrr %x", (int)(mAddressOffSet >> 23), mAddressOffSet);
+ auto transport = GoldfishMediaTransport::getInstance();
+ transport->writeParam((uint64_t)mHostHandle, 0, mAddressOffSet);
+ transport->sendOperation(MediaCodecType::H264Codec,
+ MediaOperation::DestroyContext, mAddressOffSet);
+ transport->returnMemorySlot(mAddressOffSet >> 23);
+ mHasAddressSpaceMemory = false;
+}
+
+h264_result_t MediaH264Decoder::decodeFrame(uint8_t* img, size_t szBytes, uint64_t pts) {
+ ALOGD("decode frame: use handle to host %lld", mHostHandle);
+ h264_result_t res = {0, 0};
+ if (!mHasAddressSpaceMemory) {
+ ALOGE("%s no address space memory", __func__);
+ return res;
+ }
+ auto transport = GoldfishMediaTransport::getInstance();
+ uint8_t* hostSrc = transport->getInputAddr(mAddressOffSet);
+ if (img != nullptr && szBytes > 0) {
+ memcpy(hostSrc, img, szBytes);
+ }
+ transport->writeParam((uint64_t)mHostHandle, 0, mAddressOffSet);
+ transport->writeParam(transport->offsetOf((uint64_t)(hostSrc)) - mAddressOffSet, 1, mAddressOffSet);
+ transport->writeParam((uint64_t)szBytes, 2, mAddressOffSet);
+ transport->writeParam((uint64_t)pts, 3, mAddressOffSet);
+ transport->sendOperation(MediaCodecType::H264Codec,
+ MediaOperation::DecodeImage, mAddressOffSet);
+
+
+ auto* retptr = transport->getReturnAddr(mAddressOffSet);
+ res.bytesProcessed = *(uint64_t*)(retptr);
+ res.ret = *(int*)(retptr + 8);
+
+ return res;
+}
+
+void MediaH264Decoder::flush() {
+ if (!mHasAddressSpaceMemory) {
+ ALOGE("%s no address space memory", __func__);
+ return;
+ }
+ ALOGD("flush: use handle to host %lld", mHostHandle);
+ auto transport = GoldfishMediaTransport::getInstance();
+ transport->writeParam((uint64_t)mHostHandle, 0, mAddressOffSet);
+ transport->sendOperation(MediaCodecType::H264Codec,
+ MediaOperation::Flush, mAddressOffSet);
+}
+
+h264_image_t MediaH264Decoder::getImage() {
+ ALOGD("getImage: use handle to host %lld", mHostHandle);
+ h264_image_t res { };
+ if (!mHasAddressSpaceMemory) {
+ ALOGE("%s no address space memory", __func__);
+ return res;
+ }
+ auto transport = GoldfishMediaTransport::getInstance();
+ uint8_t* dst = transport->getInputAddr(mAddressOffSet); // Note: reuse the same addr for input and output
+ transport->writeParam((uint64_t)mHostHandle, 0, mAddressOffSet);
+ transport->writeParam(transport->offsetOf((uint64_t)(dst)) - mAddressOffSet, 1, mAddressOffSet);
+ transport->sendOperation(MediaCodecType::H264Codec,
+ MediaOperation::GetImage, mAddressOffSet);
+ auto* retptr = transport->getReturnAddr(mAddressOffSet);
+ res.ret = *(int*)(retptr);
+ if (res.ret >= 0) {
+ res.data = dst;
+ res.width = *(uint32_t*)(retptr + 8);
+ res.height = *(uint32_t*)(retptr + 16);
+ res.pts = *(uint32_t*)(retptr + 24);
+ res.color_primaries = *(uint32_t*)(retptr + 32);
+ res.color_range = *(uint32_t*)(retptr + 40);
+ res.color_trc = *(uint32_t*)(retptr + 48);
+ res.colorspace = *(uint32_t*)(retptr + 56);
+ } else if (res.ret == (int)(Err::DecoderRestarted)) {
+ res.width = *(uint32_t*)(retptr + 8);
+ res.height = *(uint32_t*)(retptr + 16);
+ }
+ return res;
+}
+
+
+h264_image_t MediaH264Decoder::renderOnHostAndReturnImageMetadata(int hostColorBufferId) {
+ ALOGD("%s: use handle to host %lld", __func__, mHostHandle);
+ h264_image_t res { };
+ if (hostColorBufferId < 0) {
+ ALOGE("%s negative color buffer id %d", __func__, hostColorBufferId);
+ return res;
+ }
+ ALOGD("%s send color buffer id %d", __func__, hostColorBufferId);
+ if (!mHasAddressSpaceMemory) {
+ ALOGE("%s no address space memory", __func__);
+ return res;
+ }
+ auto transport = GoldfishMediaTransport::getInstance();
+ uint8_t* dst = transport->getInputAddr(mAddressOffSet); // Note: reuse the same addr for input and output
+ transport->writeParam((uint64_t)mHostHandle, 0, mAddressOffSet);
+ transport->writeParam(transport->offsetOf((uint64_t)(dst)) - mAddressOffSet, 1, mAddressOffSet);
+ transport->writeParam((uint64_t)hostColorBufferId, 2, mAddressOffSet);
+ transport->sendOperation(MediaCodecType::H264Codec,
+ MediaOperation::GetImage, mAddressOffSet);
+ auto* retptr = transport->getReturnAddr(mAddressOffSet);
+ res.ret = *(int*)(retptr);
+ if (res.ret >= 0) {
+ res.data = dst; // note: the data could be junk
+ res.width = *(uint32_t*)(retptr + 8);
+ res.height = *(uint32_t*)(retptr + 16);
+ res.pts = *(uint32_t*)(retptr + 24);
+ res.color_primaries = *(uint32_t*)(retptr + 32);
+ res.color_range = *(uint32_t*)(retptr + 40);
+ res.color_trc = *(uint32_t*)(retptr + 48);
+ res.colorspace = *(uint32_t*)(retptr + 56);
+ } else if (res.ret == (int)(Err::DecoderRestarted)) {
+ res.width = *(uint32_t*)(retptr + 8);
+ res.height = *(uint32_t*)(retptr + 16);
+ }
+ return res;
+}
diff --git a/system/codecs/omx/avcdec/MediaH264Decoder.h b/system/codecs/omx/avcdec/MediaH264Decoder.h
new file mode 100644
index 0000000..8264d3c
--- /dev/null
+++ b/system/codecs/omx/avcdec/MediaH264Decoder.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GOLDFISH_MEDIA_H264_DEC_H_
+#define GOLDFISH_MEDIA_H264_DEC_H_
+
+struct h264_init_result_t {
+ uint64_t host_handle;
+ int ret;
+};
+
+struct h264_result_t {
+ int ret;
+ uint64_t bytesProcessed;
+};
+
+struct h264_image_t {
+ const uint8_t* data;
+ uint32_t width;
+ uint32_t height;
+ uint64_t pts; // presentation time stamp
+ uint64_t color_primaries;
+ uint64_t color_range;
+ uint64_t color_trc;
+ uint64_t colorspace;
+ // on success, |ret| will indicate the size of |data|.
+ // If failed, |ret| will contain some negative error code.
+ int ret;
+};
+
+enum class RenderMode {
+ RENDER_BY_HOST_GPU = 1,
+ RENDER_BY_GUEST_CPU = 2,
+};
+
+class MediaH264Decoder {
+ uint64_t mHostHandle = 0;
+ uint32_t mVersion = 100;
+ RenderMode mRenderMode = RenderMode::RENDER_BY_GUEST_CPU;
+
+ bool mHasAddressSpaceMemory = false;
+ uint64_t mAddressOffSet = 0;
+
+public:
+ MediaH264Decoder(RenderMode renderMode);
+ virtual ~MediaH264Decoder() = default;
+
+ enum class PixelFormat : uint8_t {
+ YUV420P = 0,
+ UYVY422 = 1,
+ BGRA8888 = 2,
+ };
+
+ enum class Err : int {
+ NoErr = 0,
+ NoDecodedFrame = -1,
+ InitContextFailed = -2,
+ DecoderRestarted = -3,
+ NALUIgnored = -4,
+ };
+
+ bool getAddressSpaceMemory();
+ void initH264Context(unsigned int width,
+ unsigned int height,
+ unsigned int outWidth,
+ unsigned int outHeight,
+ PixelFormat pixFmt);
+ void resetH264Context(unsigned int width,
+ unsigned int height,
+ unsigned int outWidth,
+ unsigned int outHeight,
+ PixelFormat pixFmt);
+ void destroyH264Context();
+ h264_result_t decodeFrame(uint8_t* img, size_t szBytes, uint64_t pts);
+ void flush();
+ // ask host to copy image data back to guest, with image metadata
+ // to guest as well
+ h264_image_t getImage();
+ // ask host to render to hostColorBufferId, return only image metadata back to
+ // guest
+ h264_image_t renderOnHostAndReturnImageMetadata(int hostColorBufferId);
+};
+#endif
diff --git a/system/codecs/omx/avcdec/exports.lds b/system/codecs/omx/avcdec/exports.lds
new file mode 100644
index 0000000..e6674f2
--- /dev/null
+++ b/system/codecs/omx/avcdec/exports.lds
@@ -0,0 +1,5 @@
+{
+ global:
+ _Z26createGoldfishOMXComponentPKcPK16OMX_CALLBACKTYPEPvPP17OMX_COMPONENTTYPE;
+ local: *;
+};
diff --git a/system/codecs/omx/common/Android.mk b/system/codecs/omx/common/Android.mk
new file mode 100644
index 0000000..50ce286
--- /dev/null
+++ b/system/codecs/omx/common/Android.mk
@@ -0,0 +1,32 @@
+#
+# Copyright 2019 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+commonSources := \
+ goldfish_media_utils.cpp
+
+$(call emugl-begin-shared-library,libgoldfish_codecs_common$(GOLDFISH_OPENGL_LIB_SUFFIX))
+
+LOCAL_SRC_FILES := $(commonSources)
+
+LOCAL_CFLAGS += -DLOG_TAG=\"goldfish_codecs_common\"
+LOCAL_CFLAGS += -Wno-unused-private-field
+
+$(call emugl-export,SHARED_LIBRARIES,libcutils libutils liblog)
+
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+$(call emugl-import,libOpenglSystemCommon)
+$(call emugl-end-module)
diff --git a/system/codecs/omx/common/goldfish_media_utils.cpp b/system/codecs/omx/common/goldfish_media_utils.cpp
new file mode 100644
index 0000000..36883c2
--- /dev/null
+++ b/system/codecs/omx/common/goldfish_media_utils.cpp
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2018 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "goldfish_media_utils.h"
+
+#include "goldfish_address_space.h"
+
+#include <log/log.h>
+#include <memory>
+#include <vector>
+#include <mutex>
+
+
+
+std::mutex sSingletonMutex;
+std::unique_ptr<GoldfishMediaTransport> sTransport;
+
+class GoldfishMediaTransportImpl : public GoldfishMediaTransport {
+public:
+ GoldfishMediaTransportImpl();
+ ~GoldfishMediaTransportImpl();
+
+ virtual void writeParam(__u64 val, unsigned int num, unsigned int offSetToStartAddr = 0) override;
+ virtual bool sendOperation(MediaCodecType type, MediaOperation op, unsigned int offSetToStartAddr = 0) override;
+ virtual uint8_t* getBaseAddr() const override;
+ virtual uint8_t* getInputAddr(unsigned int offSet = 0) const override;
+ virtual uint8_t* getOutputAddr() const override;
+ virtual uint8_t* getReturnAddr(unsigned int offSet = 0) const override;
+ virtual __u64 offsetOf(uint64_t addr) const override;
+
+public:
+ // each lot has 8 M
+ virtual int getMemorySlot() override {
+ std::lock_guard<std::mutex> g{mMemoryMutex};
+ for (int i = mMemoryLotsAvailable.size() - 1; i >=0 ; --i) {
+ if (mMemoryLotsAvailable[i]) {
+ mMemoryLotsAvailable[i] = false;
+ return i;
+ }
+ }
+ return -1;
+ }
+ virtual void returnMemorySlot(int lot) override {
+ if (lot < 0 || lot >= mMemoryLotsAvailable.size()) {
+ return;
+ }
+ std::lock_guard<std::mutex> g{mMemoryMutex};
+ if (mMemoryLotsAvailable[lot] == false) {
+ mMemoryLotsAvailable[lot] = true;
+ } else {
+ ALOGE("Error, cannot twice");
+ }
+ }
+private:
+ std::mutex mMemoryMutex;
+ std::vector<bool> mMemoryLotsAvailable = {true, true, true, true};
+
+ address_space_handle_t mHandle;
+ uint64_t mOffset;
+ uint64_t mPhysAddr;
+ uint64_t mSize;
+ void* mStartPtr = nullptr;
+
+ // MediaCodecType will be or'd together with the metadata, so the highest 8-bits
+ // will have the type.
+ static __u64 makeMetadata(MediaCodecType type,
+ MediaOperation op, uint64_t offset);
+
+ // Chunk size for parameters/return data
+ static constexpr size_t kParamSizeBytes = 4096; // 4K
+ // Chunk size for input
+ static constexpr size_t kInputSizeBytes = 4096 * 4096; // 16M
+ // Chunk size for output
+ static constexpr size_t kOutputSizeBytes = 4096 * 4096; // 16M
+ // Maximum number of parameters that can be passed
+ static constexpr size_t kMaxParams = 32;
+ // Offset from the memory region for return data (8 is size of
+ // a parameter in bytes)
+ static constexpr size_t kReturnOffset = 8 * kMaxParams;
+};
+
+GoldfishMediaTransportImpl::~GoldfishMediaTransportImpl() {
+ if(mHandle >= 0) {
+ goldfish_address_space_close(mHandle);
+ mHandle = -1;
+ }
+}
+
+GoldfishMediaTransportImpl::GoldfishMediaTransportImpl() {
+ // Allocate host memory; the contiguous memory region will be laid out as
+ // follows:
+ // ========================================================
+ // | kParamSizeBytes | kInputSizeBytes | kOutputSizeBytes |
+ // ========================================================
+ mHandle = goldfish_address_space_open();
+ if (mHandle < 0) {
+ ALOGE("Failed to ping host to allocate memory");
+ abort();
+ }
+ mSize = kParamSizeBytes + kInputSizeBytes + kOutputSizeBytes;
+ bool success = goldfish_address_space_allocate(mHandle, mSize, &mPhysAddr, &mOffset);
+ if (success) {
+ ALOGD("successfully allocated %d bytes in goldfish_address_block", (int)mSize);
+ mStartPtr = goldfish_address_space_map(mHandle, mOffset, mSize);
+ ALOGD("guest address is %p", mStartPtr);
+
+ struct goldfish_address_space_ping pingInfo;
+ pingInfo.metadata = GoldfishAddressSpaceSubdeviceType::Media;
+ pingInfo.offset = mOffset;
+ if (goldfish_address_space_ping(mHandle, &pingInfo) == false) {
+ ALOGE("Failed to ping host to allocate memory");
+ abort();
+ return;
+ } else {
+ ALOGD("successfully pinged host to allocate memory");
+ }
+ } else {
+ ALOGE("failed to allocate %d bytes in goldfish_address_block", (int)mSize);
+ abort();
+ }
+}
+
+// static
+GoldfishMediaTransport* GoldfishMediaTransport::getInstance() {
+ std::lock_guard<std::mutex> g{sSingletonMutex};
+ if (sTransport == nullptr) {
+ sTransport.reset(new GoldfishMediaTransportImpl());
+ }
+ return sTransport.get();
+}
+
+// static
+__u64 GoldfishMediaTransportImpl::makeMetadata(MediaCodecType type,
+ MediaOperation op, uint64_t offset) {
+ // Shift |type| into the highest 8-bits, leaving the lower bits for other
+ // metadata.
+ offset = offset >> 20;
+ return ((__u64)type << (64 - 8)) | (offset << 8) | static_cast<uint8_t>(op);
+}
+
+uint8_t* GoldfishMediaTransportImpl::getInputAddr(unsigned int offSet) const {
+ return (uint8_t*)mStartPtr + kParamSizeBytes + offSet;
+}
+
+uint8_t* GoldfishMediaTransportImpl::getOutputAddr() const {
+ return getInputAddr() + kInputSizeBytes;
+}
+
+uint8_t* GoldfishMediaTransportImpl::getBaseAddr() const {
+ return (uint8_t*)mStartPtr;
+}
+
+uint8_t* GoldfishMediaTransportImpl::getReturnAddr(unsigned int offSet) const {
+ return (uint8_t*)mStartPtr + kReturnOffset + offSet;
+}
+
+__u64 GoldfishMediaTransportImpl::offsetOf(uint64_t addr) const {
+ return addr - (uint64_t)mStartPtr;
+}
+
+void GoldfishMediaTransportImpl::writeParam(__u64 val, unsigned int num, unsigned int offSetToStartAddr) {
+ uint8_t* p = (uint8_t*)mStartPtr + (offSetToStartAddr);
+ uint64_t* pint = (uint64_t*)(p + 8 * num);
+ *pint = val;
+}
+
+bool GoldfishMediaTransportImpl::sendOperation(MediaCodecType type,
+ MediaOperation op, unsigned int offSetToStartAddr) {
+ struct goldfish_address_space_ping pingInfo;
+ pingInfo.metadata = makeMetadata(type, op, offSetToStartAddr);
+ pingInfo.offset = mOffset; // + (offSetToStartAddr);
+ if (goldfish_address_space_ping(mHandle, &pingInfo) == false) {
+ ALOGE("failed to ping host");
+ abort();
+ return false;
+ } else {
+ ALOGD("successfully pinged host for operation type=%d, op=%d", (int)type, (int)op);
+ }
+
+ return true;
+}
diff --git a/system/codecs/omx/common/goldfish_media_utils.h b/system/codecs/omx/common/goldfish_media_utils.h
new file mode 100644
index 0000000..da57689
--- /dev/null
+++ b/system/codecs/omx/common/goldfish_media_utils.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2018 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/types.h>
+#include <stdint.h>
+
+#ifndef GOLDFISH_COMMON_GOLDFISH_DEFS_H
+#define GOLDFISH_COMMON_GOLDFISH_DEFS_H
+
+enum class MediaCodecType : __u8 {
+ VP8Codec = 0,
+ VP9Codec = 1,
+ H264Codec = 2,
+ Max = 3,
+};
+
+enum class MediaOperation : __u8 {
+ InitContext = 0,
+ DestroyContext = 1,
+ DecodeImage = 2,
+ GetImage = 3,
+ Flush = 4,
+ Reset = 5,
+ Max = 6,
+};
+
+// This class will abstract away the knowledge required to send media codec data
+// to the host. The implementation should only need the following information to
+// properly send the data:
+// 1) Which codec to use (MediaCodecType)
+// 2) What operation to perform (MediaOperation)
+//
+// Example:
+// auto transport = GoldfishMediaTransport::getInstance();
+//
+class GoldfishMediaTransport {
+protected:
+ GoldfishMediaTransport() {}
+
+public:
+ virtual ~GoldfishMediaTransport() {}
+
+ // Writes a parameter to send to the host. Each parameter will take up
+ // 64-bits. |val| is the value of the parameter, and |num| is the parameter
+ // number, starting from 0. If |val| is an address, wrap it around
+ // offsetOf(), e.g., writeParam(offsetOf((uint64_t)ptr), 2);
+ virtual void writeParam(__u64 val, unsigned int num, unsigned int offSetToStartAddr = 0) = 0;
+ // Send the operation to perform to the host. At the time of this call, any
+ // parameters that the host needs should have already been passed using
+ // writeParam().
+ virtual bool sendOperation(MediaCodecType codec, MediaOperation op, unsigned int offSetToStartAddr = 0) = 0;
+ // Get the address for input. This is usually given the the codec context to
+ // write data into for the host to process.
+ virtual uint8_t* getInputAddr(unsigned int offSet = 0) const = 0;
+ // Get the address for base pointer
+ virtual uint8_t* getBaseAddr() const = 0;
+ // Get the address for output. This is usually given to the codec context to
+ // read data written there by the host.
+ virtual uint8_t* getOutputAddr() const = 0;
+ // Get the address for return data from the host. The guest codec
+ // implementation will have knowledge of how the return data is laid out.
+ virtual uint8_t* getReturnAddr(unsigned int offSet = 0) const = 0;
+ // Get the offset of an address relative to the starting address of the
+ // allocated memory region. Use this for passing pointers from the guest to
+ // the host, as the guest address will be translated, thus the offset is the
+ // only value of significance.
+ virtual __u64 offsetOf(uint64_t addr) const = 0;
+
+ // Get a slot of memory (8 M per slot) for use by a decoder instance.
+ // returns -1 for failure; or a slot >=0 on success.
+ // as of now, there are only 4 slots for use, each has 8 M, it is up
+ // to client on how to use it.
+ // 0th slot: [base, base+8M)
+ // ...
+ // ith slot: [base+8M*i, base+8M*(i+1))
+ virtual int getMemorySlot() = 0;
+
+ // Return a slot back to pool. the slot should be valid >=0 and less
+ // than the total size of slots. If nobody returns slot timely, the
+ // new client could get -1 from getMemorySlot()
+ virtual void returnMemorySlot(int slot) = 0;
+
+ static GoldfishMediaTransport* getInstance();
+};
+
+__u64 goldfish_create_media_metadata(MediaCodecType codecType,
+ __u64 metadata);
+
+#endif
diff --git a/system/codecs/omx/plugin/Android.mk b/system/codecs/omx/plugin/Android.mk
new file mode 100644
index 0000000..77a2091
--- /dev/null
+++ b/system/codecs/omx/plugin/Android.mk
@@ -0,0 +1,56 @@
+#
+# Copyright 2018 The Android Open-Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+commonSources := \
+ GoldfishOMXComponent.cpp \
+ GoldfishOMXPlugin.cpp \
+ GoldfishVideoDecoderOMXComponent.cpp \
+ SimpleGoldfishOMXComponent.cpp \
+
+$(call emugl-begin-shared-library,libstagefrighthw$(GOLDFISH_OPENGL_LIB_SUFFIX))
+
+LOCAL_SRC_FILES := $(commonSources)
+
+LOCAL_CFLAGS += $(PV_CFLAGS_MINUS_VISIBILITY) -Werror
+LOCAL_CFLAGS += -Wno-unused-private-field
+
+LOCAL_C_INCLUDES += \
+ $(call include-path-for, frameworks-native)/media/hardware \
+ $(call include-path-for, frameworks-native)/media/openmax \
+
+$(call emugl-export,SHARED_LIBRARIES,libcutils libutils liblog)
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+
+
+
+LOCAL_HEADER_LIBRARIES := media_plugin_headers \
+ libmedia_headers \
+ libbinder_headers \
+ libhidlbase_impl_internal \
+ libbase
+
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libutils \
+ liblog \
+ libcutils \
+ android.hardware.media.omx@1.0 \
+ libstagefright_foundation
+
+LOCAL_VENDOR_MODULE := true
+
+$(call emugl-end-module)
diff --git a/system/codecs/omx/plugin/GoldfishOMXComponent.cpp b/system/codecs/omx/plugin/GoldfishOMXComponent.cpp
new file mode 100644
index 0000000..021a99b
--- /dev/null
+++ b/system/codecs/omx/plugin/GoldfishOMXComponent.cpp
@@ -0,0 +1,330 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "GoldfishOMXComponent"
+#include "GoldfishOMXComponent.h"
+
+#include <log/log.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+GoldfishOMXComponent::GoldfishOMXComponent(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : mName(name),
+ mCallbacks(callbacks),
+ mComponent(new OMX_COMPONENTTYPE),
+ mLibHandle(NULL) {
+ mComponent->nSize = sizeof(*mComponent);
+ mComponent->nVersion.s.nVersionMajor = 1;
+ mComponent->nVersion.s.nVersionMinor = 0;
+ mComponent->nVersion.s.nRevision = 0;
+ mComponent->nVersion.s.nStep = 0;
+ mComponent->pComponentPrivate = this;
+ mComponent->pApplicationPrivate = appData;
+
+ mComponent->GetComponentVersion = NULL;
+ mComponent->SendCommand = SendCommandWrapper;
+ mComponent->GetParameter = GetParameterWrapper;
+ mComponent->SetParameter = SetParameterWrapper;
+ mComponent->GetConfig = GetConfigWrapper;
+ mComponent->SetConfig = SetConfigWrapper;
+ mComponent->GetExtensionIndex = GetExtensionIndexWrapper;
+ mComponent->GetState = GetStateWrapper;
+ mComponent->ComponentTunnelRequest = NULL;
+ mComponent->UseBuffer = UseBufferWrapper;
+ mComponent->AllocateBuffer = AllocateBufferWrapper;
+ mComponent->FreeBuffer = FreeBufferWrapper;
+ mComponent->EmptyThisBuffer = EmptyThisBufferWrapper;
+ mComponent->FillThisBuffer = FillThisBufferWrapper;
+ mComponent->SetCallbacks = NULL;
+ mComponent->ComponentDeInit = NULL;
+ mComponent->UseEGLImage = NULL;
+ mComponent->ComponentRoleEnum = NULL;
+
+ *component = mComponent;
+}
+
+GoldfishOMXComponent::~GoldfishOMXComponent() {
+ delete mComponent;
+ mComponent = NULL;
+}
+
+void GoldfishOMXComponent::setLibHandle(void *libHandle) {
+ CHECK(libHandle != NULL);
+ mLibHandle = libHandle;
+}
+
+void *GoldfishOMXComponent::libHandle() const {
+ return mLibHandle;
+}
+
+OMX_ERRORTYPE GoldfishOMXComponent::initCheck() {
+ return OMX_ErrorNone;
+}
+
+void
+GoldfishOMXComponent::prepareForDestruction() {
+}
+
+const char *GoldfishOMXComponent::name() const {
+ return mName.c_str();
+}
+
+void GoldfishOMXComponent::notify(
+ OMX_EVENTTYPE event,
+ OMX_U32 data1, OMX_U32 data2, OMX_PTR data) {
+ (*mCallbacks->EventHandler)(
+ mComponent,
+ mComponent->pApplicationPrivate,
+ event,
+ data1,
+ data2,
+ data);
+}
+
+void GoldfishOMXComponent::notifyEmptyBufferDone(OMX_BUFFERHEADERTYPE *header) {
+ (*mCallbacks->EmptyBufferDone)(
+ mComponent, mComponent->pApplicationPrivate, header);
+}
+
+void GoldfishOMXComponent::notifyFillBufferDone(OMX_BUFFERHEADERTYPE *header) {
+ (*mCallbacks->FillBufferDone)(
+ mComponent, mComponent->pApplicationPrivate, header);
+}
+
+// static
+OMX_ERRORTYPE GoldfishOMXComponent::SendCommandWrapper(
+ OMX_HANDLETYPE component,
+ OMX_COMMANDTYPE cmd,
+ OMX_U32 param,
+ OMX_PTR data) {
+ GoldfishOMXComponent *me =
+ (GoldfishOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->sendCommand(cmd, param, data);
+}
+
+// static
+OMX_ERRORTYPE GoldfishOMXComponent::GetParameterWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params) {
+ GoldfishOMXComponent *me =
+ (GoldfishOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->getParameter(index, params);
+}
+
+// static
+OMX_ERRORTYPE GoldfishOMXComponent::SetParameterWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params) {
+ GoldfishOMXComponent *me =
+ (GoldfishOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->setParameter(index, params);
+}
+
+// static
+OMX_ERRORTYPE GoldfishOMXComponent::GetConfigWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params) {
+ GoldfishOMXComponent *me =
+ (GoldfishOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->getConfig(index, params);
+}
+
+// static
+OMX_ERRORTYPE GoldfishOMXComponent::SetConfigWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params) {
+ GoldfishOMXComponent *me =
+ (GoldfishOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->setConfig(index, params);
+}
+
+// static
+OMX_ERRORTYPE GoldfishOMXComponent::GetExtensionIndexWrapper(
+ OMX_HANDLETYPE component,
+ OMX_STRING name,
+ OMX_INDEXTYPE *index) {
+ GoldfishOMXComponent *me =
+ (GoldfishOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->getExtensionIndex(name, index);
+}
+
+// static
+OMX_ERRORTYPE GoldfishOMXComponent::UseBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *ptr) {
+ GoldfishOMXComponent *me =
+ (GoldfishOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->useBuffer(buffer, portIndex, appPrivate, size, ptr);
+}
+
+// static
+OMX_ERRORTYPE GoldfishOMXComponent::AllocateBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size) {
+ GoldfishOMXComponent *me =
+ (GoldfishOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->allocateBuffer(buffer, portIndex, appPrivate, size);
+}
+
+// static
+OMX_ERRORTYPE GoldfishOMXComponent::FreeBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *buffer) {
+ GoldfishOMXComponent *me =
+ (GoldfishOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->freeBuffer(portIndex, buffer);
+}
+
+// static
+OMX_ERRORTYPE GoldfishOMXComponent::EmptyThisBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE *buffer) {
+ GoldfishOMXComponent *me =
+ (GoldfishOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->emptyThisBuffer(buffer);
+}
+
+// static
+OMX_ERRORTYPE GoldfishOMXComponent::FillThisBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE *buffer) {
+ GoldfishOMXComponent *me =
+ (GoldfishOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->fillThisBuffer(buffer);
+}
+
+// static
+OMX_ERRORTYPE GoldfishOMXComponent::GetStateWrapper(
+ OMX_HANDLETYPE component,
+ OMX_STATETYPE *state) {
+ GoldfishOMXComponent *me =
+ (GoldfishOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ return me->getState(state);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+OMX_ERRORTYPE GoldfishOMXComponent::sendCommand(
+ OMX_COMMANDTYPE /* cmd */, OMX_U32 /* param */, OMX_PTR /* data */) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE GoldfishOMXComponent::getParameter(
+ OMX_INDEXTYPE /* index */, OMX_PTR /* params */) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE GoldfishOMXComponent::setParameter(
+ OMX_INDEXTYPE /* index */, const OMX_PTR /* params */) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE GoldfishOMXComponent::getConfig(
+ OMX_INDEXTYPE /* index */, OMX_PTR /* params */) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE GoldfishOMXComponent::setConfig(
+ OMX_INDEXTYPE /* index */, const OMX_PTR /* params */) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE GoldfishOMXComponent::getExtensionIndex(
+ const char * /* name */, OMX_INDEXTYPE * /* index */) {
+ return OMX_ErrorUnsupportedIndex;
+}
+
+OMX_ERRORTYPE GoldfishOMXComponent::useBuffer(
+ OMX_BUFFERHEADERTYPE ** /* buffer */,
+ OMX_U32 /* portIndex */,
+ OMX_PTR /* appPrivate */,
+ OMX_U32 /* size */,
+ OMX_U8 * /* ptr */) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE GoldfishOMXComponent::allocateBuffer(
+ OMX_BUFFERHEADERTYPE ** /* buffer */,
+ OMX_U32 /* portIndex */,
+ OMX_PTR /* appPrivate */,
+ OMX_U32 /* size */) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE GoldfishOMXComponent::freeBuffer(
+ OMX_U32 /* portIndex */,
+ OMX_BUFFERHEADERTYPE * /* buffer */) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE GoldfishOMXComponent::emptyThisBuffer(
+ OMX_BUFFERHEADERTYPE * /* buffer */) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE GoldfishOMXComponent::fillThisBuffer(
+ OMX_BUFFERHEADERTYPE * /* buffer */) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE GoldfishOMXComponent::getState(OMX_STATETYPE * /* state */) {
+ return OMX_ErrorUndefined;
+}
+
+} // namespace android
diff --git a/system/codecs/omx/plugin/GoldfishOMXComponent.h b/system/codecs/omx/plugin/GoldfishOMXComponent.h
new file mode 100644
index 0000000..87a65ae
--- /dev/null
+++ b/system/codecs/omx/plugin/GoldfishOMXComponent.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GOLDFISH_OMX_COMPONENT_H_
+
+#define GOLDFISH_OMX_COMPONENT_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AString.h>
+#include <utils/RefBase.h>
+
+#include <OMX_Component.h>
+
+namespace android {
+
+struct GoldfishOMXComponent : public RefBase {
+ GoldfishOMXComponent(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+ virtual OMX_ERRORTYPE initCheck();
+
+ void setLibHandle(void *libHandle);
+ void *libHandle() const;
+
+ virtual void prepareForDestruction();
+
+protected:
+ virtual ~GoldfishOMXComponent();
+
+ const char *name() const;
+
+ void notify(
+ OMX_EVENTTYPE event,
+ OMX_U32 data1, OMX_U32 data2, OMX_PTR data);
+
+ void notifyEmptyBufferDone(OMX_BUFFERHEADERTYPE *header);
+ void notifyFillBufferDone(OMX_BUFFERHEADERTYPE *header);
+
+ virtual OMX_ERRORTYPE sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data);
+
+ virtual OMX_ERRORTYPE getParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE setParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE getConfig(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE setConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE getExtensionIndex(
+ const char *name, OMX_INDEXTYPE *index);
+
+ virtual OMX_ERRORTYPE useBuffer(
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *ptr);
+
+ virtual OMX_ERRORTYPE allocateBuffer(
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size);
+
+ virtual OMX_ERRORTYPE freeBuffer(
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE emptyThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE fillThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE getState(OMX_STATETYPE *state);
+
+private:
+ AString mName;
+ const OMX_CALLBACKTYPE *mCallbacks;
+ OMX_COMPONENTTYPE *mComponent;
+
+ void *mLibHandle;
+
+ static OMX_ERRORTYPE SendCommandWrapper(
+ OMX_HANDLETYPE component,
+ OMX_COMMANDTYPE cmd,
+ OMX_U32 param,
+ OMX_PTR data);
+
+ static OMX_ERRORTYPE GetParameterWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params);
+
+ static OMX_ERRORTYPE SetParameterWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params);
+
+ static OMX_ERRORTYPE GetConfigWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params);
+
+ static OMX_ERRORTYPE SetConfigWrapper(
+ OMX_HANDLETYPE component,
+ OMX_INDEXTYPE index,
+ OMX_PTR params);
+
+ static OMX_ERRORTYPE GetExtensionIndexWrapper(
+ OMX_HANDLETYPE component,
+ OMX_STRING name,
+ OMX_INDEXTYPE *index);
+
+ static OMX_ERRORTYPE UseBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *ptr);
+
+ static OMX_ERRORTYPE AllocateBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size);
+
+ static OMX_ERRORTYPE FreeBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ static OMX_ERRORTYPE EmptyThisBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ static OMX_ERRORTYPE FillThisBufferWrapper(
+ OMX_HANDLETYPE component,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ static OMX_ERRORTYPE GetStateWrapper(
+ OMX_HANDLETYPE component,
+ OMX_STATETYPE *state);
+
+ DISALLOW_EVIL_CONSTRUCTORS(GoldfishOMXComponent);
+};
+
+template<typename T>
+bool isValidOMXParam(T *a) {
+ static_assert(offsetof(typeof(*a), nSize) == 0, "nSize not at offset 0");
+ static_assert(std::is_same< decltype(a->nSize), OMX_U32>::value, "nSize has wrong type");
+ static_assert(offsetof(typeof(*a), nVersion) == 4, "nVersion not at offset 4");
+ static_assert(std::is_same< decltype(a->nVersion), OMX_VERSIONTYPE>::value,
+ "nVersion has wrong type");
+
+ if (a->nSize < sizeof(*a)) {
+ ALOGE("b/27207275: need %zu, got %u", sizeof(*a), a->nSize);
+ //android_errorWriteLog(0x534e4554, "27207275");
+ return false;
+ }
+ return true;
+}
+
+} // namespace android
+
+#endif // GOLDFISH_OMX_COMPONENT_H_
diff --git a/system/codecs/omx/plugin/GoldfishOMXPlugin.cpp b/system/codecs/omx/plugin/GoldfishOMXPlugin.cpp
new file mode 100644
index 0000000..47c22a3
--- /dev/null
+++ b/system/codecs/omx/plugin/GoldfishOMXPlugin.cpp
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GoldfishOMXPlugin"
+#include "GoldfishOMXPlugin.h"
+
+//#define LOG_NDEBUG 0
+#include <vector>
+
+#include <cutils/properties.h>
+#include <log/log.h>
+
+#include "GoldfishOMXComponent.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AString.h>
+
+#include <dlfcn.h>
+
+namespace android {
+
+OMXPluginBase *createOMXPlugin() {
+ ALOGD("called createOMXPlugin for Goldfish");
+ return new GoldfishOMXPlugin;
+}
+
+// Each component's name should have it's own feature flag in order to toggle
+// individual codecs
+struct GoldfishComponent {
+ const char *mName;
+ const char *mLibNameSuffix;
+ const char *mRole;
+};
+
+static bool useGoogleGoldfishComponentInstance(const char* libname) {
+ // We have a property set indicating whether to use the host side codec
+ // or not (ro.kernel.qemu.hwcodec.<mLibNameSuffix>).
+ char propValue[PROP_VALUE_MAX];
+ AString prop = "ro.kernel.qemu.hwcodec.";
+ prop.append(libname);
+
+ bool myret = property_get(prop.c_str(), propValue, "") > 0 &&
+ strcmp("1", propValue) == 0;
+ if (myret) {
+ ALOGD("%s %d found prop %s val %s", __func__, __LINE__, prop.c_str(), propValue);
+ }
+ return myret;
+}
+
+static bool useAndroidGoldfishComponentInstance(const char* libname) {
+ // We have a property set indicating whether to use the host side codec
+ // or not (ro.kernel.qemu.hwcodec.<mLibNameSuffix>).
+ char propValue[PROP_VALUE_MAX];
+ AString prop = "ro.kernel.qemu.hwcodec.";
+ prop.append(libname);
+
+ bool myret = property_get(prop.c_str(), propValue, "") > 0 &&
+ strcmp("2", propValue) == 0;
+ if (myret) {
+ ALOGD("%s %d found prop %s val %s", __func__, __LINE__, prop.c_str(), propValue);
+ }
+ return myret;
+}
+
+static const GoldfishComponent kComponents[] = {
+ { "OMX.google.goldfish.vp8.decoder", "vpxdec", "video_decoder.vp8" },
+ { "OMX.google.goldfish.vp9.decoder", "vpxdec", "video_decoder.vp9" },
+ { "OMX.google.goldfish.h264.decoder", "avcdec", "video_decoder.avc" },
+ { "OMX.android.goldfish.h264.decoder", "avcdec", "video_decoder.avc" },
+};
+
+static std::vector<GoldfishComponent> kActiveComponents;
+
+static const size_t kNumComponents =
+ sizeof(kComponents) / sizeof(kComponents[0]);
+
+GoldfishOMXPlugin::GoldfishOMXPlugin() {
+ for (int i = 0; i < kNumComponents; ++i) {
+ if ( !strncmp("OMX.google", kComponents[i].mName, 10) &&
+ useGoogleGoldfishComponentInstance(kComponents[i].mLibNameSuffix)) {
+ ALOGD("found and use kComponents[i].name %s", kComponents[i].mName);
+ kActiveComponents.push_back(kComponents[i]);
+ } else if (!strncmp("OMX.android", kComponents[i].mName, 11) &&
+ useAndroidGoldfishComponentInstance(kComponents[i].mLibNameSuffix)) {
+ ALOGD("found and use kComponents[i].name %s", kComponents[i].mName);
+ kActiveComponents.push_back(kComponents[i]);
+ }
+ }
+}
+
+OMX_ERRORTYPE GoldfishOMXPlugin::makeComponentInstance(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component) {
+ ALOGI("makeComponentInstance '%s'", name);
+
+ for (size_t i = 0; i < kActiveComponents.size(); ++i) {
+ if (strcmp(name, kActiveComponents[i].mName)) {
+ continue;
+ }
+
+ AString libName;
+ AString ldsExport;
+ libName = "libstagefright_goldfish_";
+ ldsExport = "_Z26createGoldfishOMXComponentPKcPK16OMX_CALLBACKTYPEPvPP17OMX_COMPONENTTYPE";
+ ALOGI("Using goldfish codec for '%s'", kActiveComponents[i].mLibNameSuffix);
+
+ libName.append(kActiveComponents[i].mLibNameSuffix);
+ libName.append(".so");
+
+ void *libHandle = dlopen(libName.c_str(), RTLD_NOW|RTLD_NODELETE);
+
+ if (libHandle == NULL) {
+ ALOGE("unable to dlopen %s: %s", libName.c_str(), dlerror());
+
+ return OMX_ErrorComponentNotFound;
+ }
+
+ typedef GoldfishOMXComponent *(*CreateGoldfishOMXComponentFunc)(
+ const char *, const OMX_CALLBACKTYPE *,
+ OMX_PTR, OMX_COMPONENTTYPE **);
+
+ CreateGoldfishOMXComponentFunc createGoldfishOMXComponent =
+ (CreateGoldfishOMXComponentFunc)dlsym(
+ libHandle,
+ ldsExport.c_str()
+ );
+
+ if (createGoldfishOMXComponent == NULL) {
+ ALOGE("unable to create component for %s", libName.c_str());
+ dlclose(libHandle);
+ libHandle = NULL;
+
+ return OMX_ErrorComponentNotFound;
+ }
+
+ sp<GoldfishOMXComponent> codec =
+ (*createGoldfishOMXComponent)(name, callbacks, appData, component);
+
+ if (codec == NULL) {
+ dlclose(libHandle);
+ libHandle = NULL;
+
+ return OMX_ErrorInsufficientResources;
+ }
+
+ OMX_ERRORTYPE err = codec->initCheck();
+ if (err != OMX_ErrorNone) {
+ dlclose(libHandle);
+ libHandle = NULL;
+
+ return err;
+ }
+
+ codec->incStrong(this);
+ codec->setLibHandle(libHandle);
+
+ return OMX_ErrorNone;
+ }
+
+ return OMX_ErrorInvalidComponentName;
+}
+
+OMX_ERRORTYPE GoldfishOMXPlugin::destroyComponentInstance(
+ OMX_COMPONENTTYPE *component) {
+ GoldfishOMXComponent *me =
+ (GoldfishOMXComponent *)
+ ((OMX_COMPONENTTYPE *)component)->pComponentPrivate;
+
+ me->prepareForDestruction();
+
+ CHECK_EQ(me->getStrongCount(), 1);
+ me->decStrong(this);
+ me = NULL;
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE GoldfishOMXPlugin::enumerateComponents(
+ OMX_STRING name,
+ size_t /* size */,
+ OMX_U32 index) {
+ if (index >= kActiveComponents.size()) {
+ return OMX_ErrorNoMore;
+ }
+
+ ALOGD("enumerate %s component", kActiveComponents[index].mName);
+ strcpy(name, kActiveComponents[index].mName);
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE GoldfishOMXPlugin::getRolesOfComponent(
+ const char *name,
+ Vector<String8> *roles) {
+ for (size_t i = 0; i < kActiveComponents.size(); ++i) {
+ if (strcmp(name, kActiveComponents[i].mName)) {
+ continue;
+ }
+
+ roles->clear();
+ roles->push(String8(kActiveComponents[i].mRole));
+
+ return OMX_ErrorNone;
+ }
+
+ return OMX_ErrorInvalidComponentName;
+}
+
+} // namespace android
diff --git a/system/codecs/omx/plugin/GoldfishOMXPlugin.h b/system/codecs/omx/plugin/GoldfishOMXPlugin.h
new file mode 100644
index 0000000..26cee76
--- /dev/null
+++ b/system/codecs/omx/plugin/GoldfishOMXPlugin.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GOLDFISH_OMX_PLUGIN_H_
+
+#define GOLDFISH_OMX_PLUGIN_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/hardware/OMXPluginBase.h>
+
+namespace android {
+
+struct GoldfishOMXPlugin : public OMXPluginBase {
+ GoldfishOMXPlugin();
+
+ virtual OMX_ERRORTYPE makeComponentInstance(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+ virtual OMX_ERRORTYPE destroyComponentInstance(
+ OMX_COMPONENTTYPE *component);
+
+ virtual OMX_ERRORTYPE enumerateComponents(
+ OMX_STRING name,
+ size_t size,
+ OMX_U32 index);
+
+ virtual OMX_ERRORTYPE getRolesOfComponent(
+ const char *name,
+ Vector<String8> *roles);
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(GoldfishOMXPlugin);
+};
+
+} // namespace android
+
+#endif // GOLDFISH_OMX_PLUGIN_H_
diff --git a/system/codecs/omx/plugin/GoldfishVideoDecoderOMXComponent.cpp b/system/codecs/omx/plugin/GoldfishVideoDecoderOMXComponent.cpp
new file mode 100644
index 0000000..f98adab
--- /dev/null
+++ b/system/codecs/omx/plugin/GoldfishVideoDecoderOMXComponent.cpp
@@ -0,0 +1,806 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <inttypes.h>
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "GoldfishVideoDecoderOMXComponent"
+#include <utils/Log.h>
+
+#include "GoldfishVideoDecoderOMXComponent.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/foundation/AUtils.h>
+#include <media/stagefright/foundation/MediaDefs.h>
+#include <media/hardware/HardwareAPI.h>
+
+namespace android {
+
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
+GoldfishVideoDecoderOMXComponent::GoldfishVideoDecoderOMXComponent(
+ const char *name,
+ const char *componentRole,
+ OMX_VIDEO_CODINGTYPE codingType,
+ const CodecProfileLevel *profileLevels,
+ size_t numProfileLevels,
+ int32_t width,
+ int32_t height,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : SimpleGoldfishOMXComponent(name, callbacks, appData, component),
+ mIsAdaptive(false),
+ mAdaptiveMaxWidth(0),
+ mAdaptiveMaxHeight(0),
+ mWidth(width),
+ mHeight(height),
+ mCropLeft(0),
+ mCropTop(0),
+ mCropWidth(width),
+ mCropHeight(height),
+ mOutputFormat(OMX_COLOR_FormatYUV420Planar),
+ mOutputPortSettingsChange(NONE),
+ mUpdateColorAspects(false),
+ mMinInputBufferSize(384), // arbitrary, using one uncompressed macroblock
+ mMinCompressionRatio(1), // max input size is normally the output size
+ mComponentRole(componentRole),
+ mCodingType(codingType),
+ mProfileLevels(profileLevels),
+ mNumProfileLevels(numProfileLevels) {
+
+ // init all the color aspects to be Unspecified.
+ memset(&mDefaultColorAspects, 0, sizeof(ColorAspects));
+ memset(&mBitstreamColorAspects, 0, sizeof(ColorAspects));
+ memset(&mFinalColorAspects, 0, sizeof(ColorAspects));
+ memset(&mHdrStaticInfo, 0, sizeof(HDRStaticInfo));
+}
+
+void GoldfishVideoDecoderOMXComponent::initPorts(
+ OMX_U32 numInputBuffers,
+ OMX_U32 inputBufferSize,
+ OMX_U32 numOutputBuffers,
+ const char *mimeType,
+ OMX_U32 minCompressionRatio) {
+ initPorts(numInputBuffers, numInputBuffers, inputBufferSize,
+ numOutputBuffers, numOutputBuffers, mimeType, minCompressionRatio);
+}
+
+void GoldfishVideoDecoderOMXComponent::initPorts(
+ OMX_U32 numMinInputBuffers,
+ OMX_U32 numInputBuffers,
+ OMX_U32 inputBufferSize,
+ OMX_U32 numMinOutputBuffers,
+ OMX_U32 numOutputBuffers,
+ const char *mimeType,
+ OMX_U32 minCompressionRatio) {
+ mMinInputBufferSize = inputBufferSize;
+ mMinCompressionRatio = minCompressionRatio;
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+
+ def.nPortIndex = kInputPortIndex;
+ def.eDir = OMX_DirInput;
+ def.nBufferCountMin = numMinInputBuffers;
+ def.nBufferCountActual = numInputBuffers;
+ def.nBufferSize = inputBufferSize;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainVideo;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 1;
+
+ def.format.video.cMIMEType = const_cast<char *>(mimeType);
+ def.format.video.pNativeRender = NULL;
+ /* size is initialized in updatePortDefinitions() */
+ def.format.video.nBitrate = 0;
+ def.format.video.xFramerate = 0;
+ def.format.video.bFlagErrorConcealment = OMX_FALSE;
+ def.format.video.eCompressionFormat = mCodingType;
+ def.format.video.eColorFormat = OMX_COLOR_FormatUnused;
+ def.format.video.pNativeWindow = NULL;
+
+ addPort(def);
+
+ def.nPortIndex = kOutputPortIndex;
+ def.eDir = OMX_DirOutput;
+ def.nBufferCountMin = numMinOutputBuffers;
+ def.nBufferCountActual = numOutputBuffers;
+ def.bEnabled = OMX_TRUE;
+ def.bPopulated = OMX_FALSE;
+ def.eDomain = OMX_PortDomainVideo;
+ def.bBuffersContiguous = OMX_FALSE;
+ def.nBufferAlignment = 2;
+
+ def.format.video.cMIMEType = const_cast<char *>("video/raw");
+ def.format.video.pNativeRender = NULL;
+ /* size is initialized in updatePortDefinitions() */
+ def.format.video.nBitrate = 0;
+ def.format.video.xFramerate = 0;
+ def.format.video.bFlagErrorConcealment = OMX_FALSE;
+ def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+ def.format.video.pNativeWindow = NULL;
+
+ addPort(def);
+
+ updatePortDefinitions(true /* updateCrop */, true /* updateInputSize */);
+}
+
+void GoldfishVideoDecoderOMXComponent::updatePortDefinitions(bool updateCrop, bool updateInputSize) {
+ OMX_PARAM_PORTDEFINITIONTYPE *outDef = &editPortInfo(kOutputPortIndex)->mDef;
+ outDef->format.video.nFrameWidth = outputBufferWidth();
+ outDef->format.video.nFrameHeight = outputBufferHeight();
+ outDef->format.video.eColorFormat = mOutputFormat;
+ outDef->format.video.nSliceHeight = outDef->format.video.nFrameHeight;
+
+ int32_t bpp = (mOutputFormat == OMX_COLOR_FormatYUV420Planar16) ? 2 : 1;
+ outDef->format.video.nStride = outDef->format.video.nFrameWidth * bpp;
+ outDef->nBufferSize =
+ (outDef->format.video.nStride * outDef->format.video.nSliceHeight * 3) / 2;
+
+ OMX_PARAM_PORTDEFINITIONTYPE *inDef = &editPortInfo(kInputPortIndex)->mDef;
+ inDef->format.video.nFrameWidth = mWidth;
+ inDef->format.video.nFrameHeight = mHeight;
+ // input port is compressed, hence it has no stride
+ inDef->format.video.nStride = 0;
+ inDef->format.video.nSliceHeight = 0;
+
+ // when output format changes, input buffer size does not actually change
+ if (updateInputSize) {
+ inDef->nBufferSize = max(
+ outDef->nBufferSize / mMinCompressionRatio,
+ max(mMinInputBufferSize, inDef->nBufferSize));
+ }
+
+ if (updateCrop) {
+ mCropLeft = 0;
+ mCropTop = 0;
+ mCropWidth = mWidth;
+ mCropHeight = mHeight;
+ }
+}
+
+
+uint32_t GoldfishVideoDecoderOMXComponent::outputBufferWidth() {
+ return max(mIsAdaptive ? mAdaptiveMaxWidth : 0, mWidth);
+}
+
+uint32_t GoldfishVideoDecoderOMXComponent::outputBufferHeight() {
+ return max(mIsAdaptive ? mAdaptiveMaxHeight : 0, mHeight);
+}
+
+void GoldfishVideoDecoderOMXComponent::handlePortSettingsChange(
+ bool *portWillReset, uint32_t width, uint32_t height,
+ OMX_COLOR_FORMATTYPE outputFormat,
+ CropSettingsMode cropSettingsMode, bool fakeStride) {
+ *portWillReset = false;
+ bool sizeChanged = (width != mWidth || height != mHeight);
+ bool formatChanged = (outputFormat != mOutputFormat);
+ bool updateCrop = (cropSettingsMode == kCropUnSet);
+ bool cropChanged = (cropSettingsMode == kCropChanged);
+ bool strideChanged = false;
+ if (fakeStride) {
+ OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kOutputPortIndex)->mDef;
+ if (def->format.video.nStride != (OMX_S32)width
+ || def->format.video.nSliceHeight != (OMX_U32)height) {
+ strideChanged = true;
+ }
+ }
+
+ if (formatChanged || sizeChanged || cropChanged || strideChanged) {
+ if (formatChanged) {
+ ALOGD("formatChanged: 0x%08x -> 0x%08x", mOutputFormat, outputFormat);
+ }
+ mOutputFormat = outputFormat;
+ mWidth = width;
+ mHeight = height;
+
+ if ((sizeChanged && !mIsAdaptive)
+ || width > mAdaptiveMaxWidth
+ || height > mAdaptiveMaxHeight
+ || formatChanged) {
+ if (mIsAdaptive) {
+ if (width > mAdaptiveMaxWidth) {
+ mAdaptiveMaxWidth = width;
+ }
+ if (height > mAdaptiveMaxHeight) {
+ mAdaptiveMaxHeight = height;
+ }
+ }
+ updatePortDefinitions(updateCrop);
+ notify(OMX_EventPortSettingsChanged, kOutputPortIndex, 0, NULL);
+ mOutputPortSettingsChange = AWAITING_DISABLED;
+ *portWillReset = true;
+ } else {
+ updatePortDefinitions(updateCrop);
+
+ if (fakeStride) {
+ // MAJOR HACK that is not pretty, it's just to fool the renderer to read the correct
+ // data.
+ // Some software decoders (e.g. SoftMPEG4) fill decoded frame directly to output
+ // buffer without considering the output buffer stride and slice height. So this is
+ // used to signal how the buffer is arranged. The alternative is to re-arrange the
+ // output buffer in SoftMPEG4, but that results in memcopies.
+ OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kOutputPortIndex)->mDef;
+ def->format.video.nStride = mWidth;
+ def->format.video.nSliceHeight = mHeight;
+ }
+
+ notify(OMX_EventPortSettingsChanged, kOutputPortIndex,
+ OMX_IndexConfigCommonOutputCrop, NULL);
+ }
+ } else if (mUpdateColorAspects) {
+ notify(OMX_EventPortSettingsChanged, kOutputPortIndex,
+ kDescribeColorAspectsIndex, NULL);
+ mUpdateColorAspects = false;
+ }
+}
+
+void GoldfishVideoDecoderOMXComponent::dumpColorAspects(const ColorAspects &colorAspects) {
+ ALOGD("dumpColorAspects: (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) ",
+ colorAspects.mRange, asString(colorAspects.mRange),
+ colorAspects.mPrimaries, asString(colorAspects.mPrimaries),
+ colorAspects.mMatrixCoeffs, asString(colorAspects.mMatrixCoeffs),
+ colorAspects.mTransfer, asString(colorAspects.mTransfer));
+}
+
+bool GoldfishVideoDecoderOMXComponent::colorAspectsDiffer(
+ const ColorAspects &a, const ColorAspects &b) {
+ if (a.mRange != b.mRange
+ || a.mPrimaries != b.mPrimaries
+ || a.mTransfer != b.mTransfer
+ || a.mMatrixCoeffs != b.mMatrixCoeffs) {
+ return true;
+ }
+ return false;
+}
+
+void GoldfishVideoDecoderOMXComponent::updateFinalColorAspects(
+ const ColorAspects &otherAspects, const ColorAspects &preferredAspects) {
+ Mutex::Autolock autoLock(mColorAspectsLock);
+ ColorAspects newAspects;
+ newAspects.mRange = preferredAspects.mRange != ColorAspects::RangeUnspecified ?
+ preferredAspects.mRange : otherAspects.mRange;
+ newAspects.mPrimaries = preferredAspects.mPrimaries != ColorAspects::PrimariesUnspecified ?
+ preferredAspects.mPrimaries : otherAspects.mPrimaries;
+ newAspects.mTransfer = preferredAspects.mTransfer != ColorAspects::TransferUnspecified ?
+ preferredAspects.mTransfer : otherAspects.mTransfer;
+ newAspects.mMatrixCoeffs = preferredAspects.mMatrixCoeffs != ColorAspects::MatrixUnspecified ?
+ preferredAspects.mMatrixCoeffs : otherAspects.mMatrixCoeffs;
+
+ // Check to see if need update mFinalColorAspects.
+ if (colorAspectsDiffer(mFinalColorAspects, newAspects)) {
+ mFinalColorAspects = newAspects;
+ mUpdateColorAspects = true;
+ }
+}
+
+status_t GoldfishVideoDecoderOMXComponent::handleColorAspectsChange() {
+ int perference = getColorAspectPreference();
+ ALOGD("Color Aspects preference: %d ", perference);
+
+ if (perference == kPreferBitstream) {
+ updateFinalColorAspects(mDefaultColorAspects, mBitstreamColorAspects);
+ } else if (perference == kPreferContainer) {
+ updateFinalColorAspects(mBitstreamColorAspects, mDefaultColorAspects);
+ } else {
+ return OMX_ErrorUnsupportedSetting;
+ }
+ return OK;
+}
+
+void GoldfishVideoDecoderOMXComponent::copyYV12FrameToOutputBuffer(
+ uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
+ size_t srcYStride, size_t srcUStride, size_t srcVStride) {
+ OMX_PARAM_PORTDEFINITIONTYPE *outDef = &editPortInfo(kOutputPortIndex)->mDef;
+ int32_t bpp = (outDef->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar16) ? 2 : 1;
+
+ size_t dstYStride = outputBufferWidth() * bpp;
+ size_t dstUVStride = dstYStride / 2;
+ size_t dstHeight = outputBufferHeight();
+ uint8_t *dstStart = dst;
+
+ for (size_t i = 0; i < mHeight; ++i) {
+ memcpy(dst, srcY, mWidth * bpp);
+ srcY += srcYStride;
+ dst += dstYStride;
+ }
+
+ dst = dstStart + dstYStride * dstHeight;
+ for (size_t i = 0; i < mHeight / 2; ++i) {
+ memcpy(dst, srcU, mWidth / 2 * bpp);
+ srcU += srcUStride;
+ dst += dstUVStride;
+ }
+
+ dst = dstStart + (5 * dstYStride * dstHeight) / 4;
+ for (size_t i = 0; i < mHeight / 2; ++i) {
+ memcpy(dst, srcV, mWidth / 2 * bpp);
+ srcV += srcVStride;
+ dst += dstUVStride;
+ }
+}
+
+OMX_ERRORTYPE GoldfishVideoDecoderOMXComponent::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > kMaxPortIndex) {
+ return OMX_ErrorBadPortIndex;
+ }
+
+ if (formatParams->nIndex != 0) {
+ return OMX_ErrorNoMore;
+ }
+
+ if (formatParams->nPortIndex == kInputPortIndex) {
+ formatParams->eCompressionFormat = mCodingType;
+ formatParams->eColorFormat = OMX_COLOR_FormatUnused;
+ formatParams->xFramerate = 0;
+ } else {
+ CHECK_EQ(formatParams->nPortIndex, 1u);
+
+ formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused;
+ formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar;
+ formatParams->xFramerate = 0;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamVideoProfileLevelQuerySupported:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel =
+ (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) params;
+
+ if (!isValidOMXParam(profileLevel)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (profileLevel->nPortIndex != kInputPortIndex) {
+ ALOGE("Invalid port index: %" PRIu32, profileLevel->nPortIndex);
+ return OMX_ErrorUnsupportedIndex;
+ }
+
+ if (profileLevel->nProfileIndex >= mNumProfileLevels) {
+ return OMX_ErrorNoMore;
+ }
+
+ profileLevel->eProfile = mProfileLevels[profileLevel->nProfileIndex].mProfile;
+ profileLevel->eLevel = mProfileLevels[profileLevel->nProfileIndex].mLevel;
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return SimpleGoldfishOMXComponent::internalGetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE GoldfishVideoDecoderOMXComponent::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ // Include extension index OMX_INDEXEXTTYPE.
+ const int32_t indexFull = index;
+
+ switch (indexFull) {
+ case OMX_IndexParamStandardComponentRole:
+ {
+ const OMX_PARAM_COMPONENTROLETYPE *roleParams =
+ (const OMX_PARAM_COMPONENTROLETYPE *)params;
+
+ if (!isValidOMXParam(roleParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (strncmp((const char *)roleParams->cRole,
+ mComponentRole,
+ OMX_MAX_STRINGNAME_SIZE - 1)) {
+ return OMX_ErrorUndefined;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params;
+
+ if (!isValidOMXParam(formatParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (formatParams->nPortIndex > kMaxPortIndex) {
+ return OMX_ErrorBadPortIndex;
+ }
+
+ if (formatParams->nPortIndex == kInputPortIndex) {
+ if (formatParams->eCompressionFormat != mCodingType
+ || formatParams->eColorFormat != OMX_COLOR_FormatUnused) {
+ return OMX_ErrorUnsupportedSetting;
+ }
+ } else {
+ if (formatParams->eCompressionFormat != OMX_VIDEO_CodingUnused
+ || formatParams->eColorFormat != OMX_COLOR_FormatYUV420Planar) {
+ return OMX_ErrorUnsupportedSetting;
+ }
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case kPrepareForAdaptivePlaybackIndex:
+ {
+ const PrepareForAdaptivePlaybackParams* adaptivePlaybackParams =
+ (const PrepareForAdaptivePlaybackParams *)params;
+
+ if (!isValidOMXParam(adaptivePlaybackParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ mIsAdaptive = adaptivePlaybackParams->bEnable;
+ if (mIsAdaptive) {
+ mAdaptiveMaxWidth = adaptivePlaybackParams->nMaxFrameWidth;
+ mAdaptiveMaxHeight = adaptivePlaybackParams->nMaxFrameHeight;
+ mWidth = mAdaptiveMaxWidth;
+ mHeight = mAdaptiveMaxHeight;
+ } else {
+ mAdaptiveMaxWidth = 0;
+ mAdaptiveMaxHeight = 0;
+ }
+ updatePortDefinitions(true /* updateCrop */, true /* updateInputSize */);
+ return OMX_ErrorNone;
+ }
+
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *newParams =
+ (OMX_PARAM_PORTDEFINITIONTYPE *)params;
+
+ if (!isValidOMXParam(newParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &newParams->format.video;
+ OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(newParams->nPortIndex)->mDef;
+
+ uint32_t oldWidth = def->format.video.nFrameWidth;
+ uint32_t oldHeight = def->format.video.nFrameHeight;
+ uint32_t newWidth = video_def->nFrameWidth;
+ uint32_t newHeight = video_def->nFrameHeight;
+ // We need width, height, stride and slice-height to be non-zero and sensible.
+ // These values were chosen to prevent integer overflows further down the line, and do
+ // not indicate support for 32kx32k video.
+ if (newWidth > 32768 || newHeight > 32768
+ || video_def->nStride > 32768 || video_def->nStride < -32768
+ || video_def->nSliceHeight > 32768) {
+ ALOGE("b/22885421");
+ return OMX_ErrorBadParameter;
+ }
+ if (newWidth != oldWidth || newHeight != oldHeight) {
+ bool outputPort = (newParams->nPortIndex == kOutputPortIndex);
+ if (outputPort) {
+ // only update (essentially crop) if size changes
+ mWidth = newWidth;
+ mHeight = newHeight;
+
+ updatePortDefinitions(true /* updateCrop */, true /* updateInputSize */);
+ // reset buffer size based on frame size
+ newParams->nBufferSize = def->nBufferSize;
+ } else {
+ // For input port, we only set nFrameWidth and nFrameHeight. Buffer size
+ // is updated when configuring the output port using the max-frame-size,
+ // though client can still request a larger size.
+ def->format.video.nFrameWidth = newWidth;
+ def->format.video.nFrameHeight = newHeight;
+ }
+ }
+ return SimpleGoldfishOMXComponent::internalSetParameter(index, params);
+ }
+
+ default:
+ return SimpleGoldfishOMXComponent::internalSetParameter(index, params);
+ }
+}
+
+OMX_ERRORTYPE GoldfishVideoDecoderOMXComponent::getConfig(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch ((int)index) {
+ case OMX_IndexConfigCommonOutputCrop:
+ {
+ OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)params;
+
+ if (!isValidOMXParam(rectParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (rectParams->nPortIndex != kOutputPortIndex) {
+ return OMX_ErrorUndefined;
+ }
+
+ rectParams->nLeft = mCropLeft;
+ rectParams->nTop = mCropTop;
+ rectParams->nWidth = mCropWidth;
+ rectParams->nHeight = mCropHeight;
+
+ return OMX_ErrorNone;
+ }
+ case kDescribeColorAspectsIndex:
+ {
+ if (!supportsDescribeColorAspects()) {
+ return OMX_ErrorUnsupportedIndex;
+ }
+
+ DescribeColorAspectsParams* colorAspectsParams =
+ (DescribeColorAspectsParams *)params;
+
+ if (!isValidOMXParam(colorAspectsParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (colorAspectsParams->nPortIndex != kOutputPortIndex) {
+ return OMX_ErrorBadParameter;
+ }
+
+ colorAspectsParams->sAspects = mFinalColorAspects;
+ if (colorAspectsParams->bRequestingDataSpace || colorAspectsParams->bDataSpaceChanged) {
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ return OMX_ErrorNone;
+ }
+
+ case kDescribeHdrStaticInfoIndex:
+ {
+ if (!supportDescribeHdrStaticInfo()) {
+ return OMX_ErrorUnsupportedIndex;
+ }
+
+ DescribeHDRStaticInfoParams* hdrStaticInfoParams =
+ (DescribeHDRStaticInfoParams *)params;
+
+ if (!isValidOMXParam(hdrStaticInfoParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (hdrStaticInfoParams->nPortIndex != kOutputPortIndex) {
+ return OMX_ErrorBadPortIndex;
+ }
+
+ hdrStaticInfoParams->sInfo = mHdrStaticInfo;
+
+ return OMX_ErrorNone;
+ }
+
+ case kDescribeHdr10PlusInfoIndex:
+ {
+ if (!supportDescribeHdr10PlusInfo()) {
+ return OMX_ErrorUnsupportedIndex;
+ }
+
+ if (mHdr10PlusOutputs.size() > 0) {
+ auto it = mHdr10PlusOutputs.begin();
+
+ auto info = (*it).get();
+
+ DescribeHDR10PlusInfoParams* outParams =
+ (DescribeHDR10PlusInfoParams *)params;
+
+ outParams->nParamSizeUsed = info->size();
+
+ // If the buffer provided by the client does not have enough
+ // storage, return the size only and do not remove the param yet.
+ if (outParams->nParamSize >= info->size()) {
+ memcpy(outParams->nValue, info->data(), info->size());
+ mHdr10PlusOutputs.erase(it);
+ }
+ return OMX_ErrorNone;
+ }
+ return OMX_ErrorUnderflow;
+ }
+
+ default:
+ return OMX_ErrorUnsupportedIndex;
+ }
+}
+
+OMX_ERRORTYPE GoldfishVideoDecoderOMXComponent::internalSetConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig){
+ switch ((int)index) {
+ case kDescribeColorAspectsIndex:
+ {
+ if (!supportsDescribeColorAspects()) {
+ return OMX_ErrorUnsupportedIndex;
+ }
+ const DescribeColorAspectsParams* colorAspectsParams =
+ (const DescribeColorAspectsParams *)params;
+
+ if (!isValidOMXParam(colorAspectsParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (colorAspectsParams->nPortIndex != kOutputPortIndex) {
+ return OMX_ErrorBadParameter;
+ }
+
+ // Update color aspects if necessary.
+ if (colorAspectsDiffer(colorAspectsParams->sAspects, mDefaultColorAspects)) {
+ mDefaultColorAspects = colorAspectsParams->sAspects;
+ status_t err = handleColorAspectsChange();
+ CHECK(err == OK);
+ }
+ return OMX_ErrorNone;
+ }
+
+ case kDescribeHdrStaticInfoIndex:
+ {
+ if (!supportDescribeHdrStaticInfo()) {
+ return OMX_ErrorUnsupportedIndex;
+ }
+
+ const DescribeHDRStaticInfoParams* hdrStaticInfoParams =
+ (DescribeHDRStaticInfoParams *)params;
+
+ if (!isValidOMXParam(hdrStaticInfoParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (hdrStaticInfoParams->nPortIndex != kOutputPortIndex) {
+ return OMX_ErrorBadPortIndex;
+ }
+
+ mHdrStaticInfo = hdrStaticInfoParams->sInfo;
+ updatePortDefinitions(false);
+
+ return OMX_ErrorNone;
+ }
+
+ case kDescribeHdr10PlusInfoIndex:
+ {
+ if (!supportDescribeHdr10PlusInfo()) {
+ return OMX_ErrorUnsupportedIndex;
+ }
+
+ const DescribeHDR10PlusInfoParams* inParams =
+ (DescribeHDR10PlusInfoParams *)params;
+
+ if (*frameConfig) {
+ // This is a request to append to the current frame config set.
+ // For now, we only support kDescribeHdr10PlusInfoIndex, which
+ // we simply replace with the last set value.
+ if (mHdr10PlusInputs.size() > 0) {
+ *(--mHdr10PlusInputs.end()) = ABuffer::CreateAsCopy(
+ inParams->nValue, inParams->nParamSizeUsed);
+ } else {
+ ALOGW("Ignoring kDescribeHdr10PlusInfoIndex: append to "
+ "frame config while no frame config is present");
+ }
+ } else {
+ // This is a frame config, setting *frameConfig to true so that
+ // the client marks the next queued input frame to apply it.
+ *frameConfig = true;
+ mHdr10PlusInputs.push_back(ABuffer::CreateAsCopy(
+ inParams->nValue, inParams->nParamSizeUsed));
+ }
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return OMX_ErrorUnsupportedIndex;
+ }
+}
+
+sp<ABuffer> GoldfishVideoDecoderOMXComponent::dequeueInputFrameConfig() {
+ auto it = mHdr10PlusInputs.begin();
+ sp<ABuffer> info = *it;
+ mHdr10PlusInputs.erase(it);
+ return info;
+}
+
+void GoldfishVideoDecoderOMXComponent::queueOutputFrameConfig(const sp<ABuffer> &info) {
+ mHdr10PlusOutputs.push_back(info);
+ notify(OMX_EventConfigUpdate,
+ kOutputPortIndex,
+ kDescribeHdr10PlusInfoIndex,
+ NULL);
+}
+
+OMX_ERRORTYPE GoldfishVideoDecoderOMXComponent::getExtensionIndex(
+ const char *name, OMX_INDEXTYPE *index) {
+ if (!strcmp(name, "OMX.google.android.index.prepareForAdaptivePlayback")) {
+ *(int32_t*)index = kPrepareForAdaptivePlaybackIndex;
+ return OMX_ErrorNone;
+ } else if (!strcmp(name, "OMX.google.android.index.describeColorAspects")
+ && supportsDescribeColorAspects()) {
+ *(int32_t*)index = kDescribeColorAspectsIndex;
+ return OMX_ErrorNone;
+ } else if (!strcmp(name, "OMX.google.android.index.describeHDRStaticInfo")
+ && supportDescribeHdrStaticInfo()) {
+ *(int32_t*)index = kDescribeHdrStaticInfoIndex;
+ return OMX_ErrorNone;
+ } else if (!strcmp(name, "OMX.google.android.index.describeHDR10PlusInfo")
+ && supportDescribeHdr10PlusInfo()) {
+ *(int32_t*)index = kDescribeHdr10PlusInfoIndex;
+ return OMX_ErrorNone;
+ }
+
+ return SimpleGoldfishOMXComponent::getExtensionIndex(name, index);
+}
+
+bool GoldfishVideoDecoderOMXComponent::supportsDescribeColorAspects() {
+ return getColorAspectPreference() != kNotSupported;
+}
+
+int GoldfishVideoDecoderOMXComponent::getColorAspectPreference() {
+ return kNotSupported;
+}
+
+bool GoldfishVideoDecoderOMXComponent::supportDescribeHdrStaticInfo() {
+ return false;
+}
+
+bool GoldfishVideoDecoderOMXComponent::supportDescribeHdr10PlusInfo() {
+ return false;
+}
+
+void GoldfishVideoDecoderOMXComponent::onReset() {
+ mOutputPortSettingsChange = NONE;
+}
+
+void GoldfishVideoDecoderOMXComponent::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
+ if (portIndex != kOutputPortIndex) {
+ return;
+ }
+
+ switch (mOutputPortSettingsChange) {
+ case NONE:
+ break;
+
+ case AWAITING_DISABLED:
+ {
+ CHECK(!enabled);
+ mOutputPortSettingsChange = AWAITING_ENABLED;
+ break;
+ }
+
+ default:
+ {
+ CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED);
+ CHECK(enabled);
+ mOutputPortSettingsChange = NONE;
+ break;
+ }
+ }
+}
+
+} // namespace android
diff --git a/system/codecs/omx/plugin/GoldfishVideoDecoderOMXComponent.h b/system/codecs/omx/plugin/GoldfishVideoDecoderOMXComponent.h
new file mode 100644
index 0000000..bf60f61
--- /dev/null
+++ b/system/codecs/omx/plugin/GoldfishVideoDecoderOMXComponent.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GOLDFISH_VIDEO_DECODER_OMX_COMPONENT_H_
+
+#define GOLDFISH_VIDEO_DECODER_OMX_COMPONENT_H_
+
+#include "SimpleGoldfishOMXComponent.h"
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/AHandlerReflector.h>
+#include <media/stagefright/foundation/ColorUtils.h>
+#include <media/IOMX.h>
+#include <media/hardware/HardwareAPI.h>
+
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <utils/Vector.h>
+#include <utils/List.h>
+
+namespace android {
+
+struct GoldfishVideoDecoderOMXComponent : public SimpleGoldfishOMXComponent {
+ GoldfishVideoDecoderOMXComponent(
+ const char *name,
+ const char *componentRole,
+ OMX_VIDEO_CODINGTYPE codingType,
+ const CodecProfileLevel *profileLevels,
+ size_t numProfileLevels,
+ int32_t width,
+ int32_t height,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ enum {
+ kDescribeColorAspectsIndex = kPrepareForAdaptivePlaybackIndex + 1,
+ kDescribeHdrStaticInfoIndex = kPrepareForAdaptivePlaybackIndex + 2,
+ kDescribeHdr10PlusInfoIndex = kPrepareForAdaptivePlaybackIndex + 3,
+ kEnableAndroidNativeBuffersIndex = kPrepareForAdaptivePlaybackIndex + 4,
+ kUseAndroidNativeBufferIndex = kPrepareForAdaptivePlaybackIndex + 5,
+ kGetAndroidNativeBufferUsageIndex = kPrepareForAdaptivePlaybackIndex + 6,
+ };
+
+ enum {
+ kNotSupported,
+ kPreferBitstream,
+ kPreferContainer,
+ };
+
+ virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+ virtual void onReset();
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE getConfig(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig);
+
+ virtual OMX_ERRORTYPE getExtensionIndex(
+ const char *name, OMX_INDEXTYPE *index);
+
+ virtual bool supportsDescribeColorAspects();
+
+ virtual int getColorAspectPreference();
+
+ virtual bool supportDescribeHdrStaticInfo();
+
+ virtual bool supportDescribeHdr10PlusInfo();
+
+ // This function sets both minimum buffer count and actual buffer count of
+ // input port to be |numInputBuffers|. It will also set both minimum buffer
+ // count and actual buffer count of output port to be |numOutputBuffers|.
+ void initPorts(OMX_U32 numInputBuffers,
+ OMX_U32 inputBufferSize,
+ OMX_U32 numOutputBuffers,
+ const char *mimeType,
+ OMX_U32 minCompressionRatio = 1u);
+
+ // This function sets input port's minimum buffer count to |numMinInputBuffers|,
+ // sets input port's actual buffer count to |numInputBuffers|, sets output port's
+ // minimum buffer count to |numMinOutputBuffers| and sets output port's actual buffer
+ // count to be |numOutputBuffers|.
+ void initPorts(OMX_U32 numMinInputBuffers,
+ OMX_U32 numInputBuffers,
+ OMX_U32 inputBufferSize,
+ OMX_U32 numMinOutputBuffers,
+ OMX_U32 numOutputBuffers,
+ const char *mimeType,
+ OMX_U32 minCompressionRatio = 1u);
+
+ virtual void updatePortDefinitions(bool updateCrop = true, bool updateInputSize = false);
+
+ uint32_t outputBufferWidth();
+ uint32_t outputBufferHeight();
+
+ enum CropSettingsMode {
+ kCropUnSet = 0,
+ kCropSet,
+ kCropChanged,
+ };
+
+ // This function will handle several port change events which include
+ // size changed, crop changed, stride changed and coloraspects changed.
+ // It will trigger OMX_EventPortSettingsChanged event if necessary.
+ void handlePortSettingsChange(
+ bool *portWillReset, uint32_t width, uint32_t height,
+ OMX_COLOR_FORMATTYPE outputFormat = OMX_COLOR_FormatYUV420Planar,
+ CropSettingsMode cropSettingsMode = kCropUnSet,
+ bool fakeStride = false);
+
+ void copyYV12FrameToOutputBuffer(
+ uint8_t *dst, const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV,
+ size_t srcYStride, size_t srcUStride, size_t srcVStride);
+
+ enum {
+ kInputPortIndex = 0,
+ kOutputPortIndex = 1,
+ kMaxPortIndex = 1,
+ };
+
+ bool mIsAdaptive;
+ uint32_t mAdaptiveMaxWidth, mAdaptiveMaxHeight;
+ uint32_t mWidth, mHeight;
+ uint32_t mCropLeft, mCropTop, mCropWidth, mCropHeight;
+ OMX_COLOR_FORMATTYPE mOutputFormat;
+ HDRStaticInfo mHdrStaticInfo;
+ enum {
+ NONE,
+ AWAITING_DISABLED,
+ AWAITING_ENABLED
+ } mOutputPortSettingsChange;
+
+ bool mUpdateColorAspects;
+
+ Mutex mColorAspectsLock;
+ // color aspects passed from the framework.
+ ColorAspects mDefaultColorAspects;
+ // color aspects parsed from the bitstream.
+ ColorAspects mBitstreamColorAspects;
+ // final color aspects after combining the above two aspects.
+ ColorAspects mFinalColorAspects;
+
+ bool colorAspectsDiffer(const ColorAspects &a, const ColorAspects &b);
+
+ // This functions takes two color aspects and updates the mFinalColorAspects
+ // based on |preferredAspects|.
+ void updateFinalColorAspects(
+ const ColorAspects &otherAspects, const ColorAspects &preferredAspects);
+
+ // This function will update the mFinalColorAspects based on codec preference.
+ status_t handleColorAspectsChange();
+
+ // Helper function to dump the ColorAspects.
+ void dumpColorAspects(const ColorAspects &colorAspects);
+
+ sp<ABuffer> dequeueInputFrameConfig();
+ void queueOutputFrameConfig(const sp<ABuffer> &info);
+
+private:
+ uint32_t mMinInputBufferSize;
+ uint32_t mMinCompressionRatio;
+
+ const char *mComponentRole;
+ OMX_VIDEO_CODINGTYPE mCodingType;
+ const CodecProfileLevel *mProfileLevels;
+ size_t mNumProfileLevels;
+ typedef List<sp<ABuffer> > Hdr10PlusInfoList;
+ Hdr10PlusInfoList mHdr10PlusInputs;
+ Hdr10PlusInfoList mHdr10PlusOutputs;
+
+ DISALLOW_EVIL_CONSTRUCTORS(GoldfishVideoDecoderOMXComponent);
+};
+
+} // namespace android
+
+#endif // GOLDFISH_VIDEO_DECODER_OMX_COMPONENT_H_
diff --git a/system/codecs/omx/plugin/SimpleGoldfishOMXComponent.cpp b/system/codecs/omx/plugin/SimpleGoldfishOMXComponent.cpp
new file mode 100644
index 0000000..8c8e694
--- /dev/null
+++ b/system/codecs/omx/plugin/SimpleGoldfishOMXComponent.cpp
@@ -0,0 +1,750 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "SimpleGoldfishOMXComponent"
+#include <utils/Log.h>
+
+#include "SimpleGoldfishOMXComponent.h"
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AMessage.h>
+
+namespace android {
+
+SimpleGoldfishOMXComponent::SimpleGoldfishOMXComponent(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : GoldfishOMXComponent(name, callbacks, appData, component),
+ mLooper(new ALooper),
+ mHandler(new AHandlerReflector<SimpleGoldfishOMXComponent>(this)),
+ mState(OMX_StateLoaded),
+ mTargetState(OMX_StateLoaded),
+ mFrameConfig(false) {
+ mLooper->setName(name);
+ mLooper->registerHandler(mHandler);
+
+ mLooper->start(
+ false, // runOnCallingThread
+ false, // canCallJava
+ ANDROID_PRIORITY_VIDEO);
+}
+
+void SimpleGoldfishOMXComponent::prepareForDestruction() {
+ // The looper's queue may still contain messages referencing this
+ // object. Make sure those are flushed before returning so that
+ // a subsequent dlunload() does not pull out the rug from under us.
+
+ mLooper->unregisterHandler(mHandler->id());
+ mLooper->stop();
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data) {
+ CHECK(data == NULL);
+
+ sp<AMessage> msg = new AMessage(kWhatSendCommand, mHandler);
+ msg->setInt32("cmd", cmd);
+ msg->setInt32("param", param);
+ msg->post();
+
+ return OMX_ErrorNone;
+}
+
+bool SimpleGoldfishOMXComponent::isSetParameterAllowed(
+ OMX_INDEXTYPE index, const OMX_PTR params) const {
+ if (mState == OMX_StateLoaded) {
+ return true;
+ }
+
+ OMX_U32 portIndex;
+
+ switch (index) {
+ case OMX_IndexParamPortDefinition:
+ {
+ const OMX_PARAM_PORTDEFINITIONTYPE *portDefs =
+ (const OMX_PARAM_PORTDEFINITIONTYPE *) params;
+ if (!isValidOMXParam(portDefs)) {
+ return false;
+ }
+ portIndex = portDefs->nPortIndex;
+ break;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ const OMX_AUDIO_PARAM_PCMMODETYPE *pcmMode =
+ (const OMX_AUDIO_PARAM_PCMMODETYPE *) params;
+ if (!isValidOMXParam(pcmMode)) {
+ return false;
+ }
+ portIndex = pcmMode->nPortIndex;
+ break;
+ }
+
+ case OMX_IndexParamAudioAac:
+ {
+ const OMX_AUDIO_PARAM_AACPROFILETYPE *aacMode =
+ (const OMX_AUDIO_PARAM_AACPROFILETYPE *) params;
+ if (!isValidOMXParam(aacMode)) {
+ return false;
+ }
+ portIndex = aacMode->nPortIndex;
+ break;
+ }
+
+ default:
+ return false;
+ }
+
+ CHECK(portIndex < mPorts.size());
+
+ return !mPorts.itemAt(portIndex).mDef.bEnabled;
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::getParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ Mutex::Autolock autoLock(mLock);
+ return internalGetParameter(index, params);
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::setParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ Mutex::Autolock autoLock(mLock);
+
+ CHECK(isSetParameterAllowed(index, params));
+
+ return internalSetParameter(index, params);
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *defParams =
+ (OMX_PARAM_PORTDEFINITIONTYPE *)params;
+
+ if (!isValidOMXParam(defParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (defParams->nPortIndex >= mPorts.size()
+ || defParams->nSize
+ != sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) {
+ return OMX_ErrorUndefined;
+ }
+
+ const PortInfo *port =
+ &mPorts.itemAt(defParams->nPortIndex);
+
+ memcpy(defParams, &port->mDef, sizeof(port->mDef));
+
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return OMX_ErrorUnsupportedIndex;
+ }
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ switch (index) {
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *defParams =
+ (OMX_PARAM_PORTDEFINITIONTYPE *)params;
+
+ if (!isValidOMXParam(defParams)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (defParams->nPortIndex >= mPorts.size()) {
+ return OMX_ErrorBadPortIndex;
+ }
+ if (defParams->nSize != sizeof(OMX_PARAM_PORTDEFINITIONTYPE)) {
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ PortInfo *port =
+ &mPorts.editItemAt(defParams->nPortIndex);
+
+ // default behavior is that we only allow buffer size to increase
+ if (defParams->nBufferSize > port->mDef.nBufferSize) {
+ port->mDef.nBufferSize = defParams->nBufferSize;
+ }
+
+ if (defParams->nBufferCountActual < port->mDef.nBufferCountMin) {
+ ALOGW("component requires at least %u buffers (%u requested)",
+ port->mDef.nBufferCountMin, defParams->nBufferCountActual);
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ port->mDef.nBufferCountActual = defParams->nBufferCountActual;
+ return OMX_ErrorNone;
+ }
+
+ default:
+ return OMX_ErrorUnsupportedIndex;
+ }
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::internalSetConfig(
+ OMX_INDEXTYPE index __unused, const OMX_PTR params __unused, bool *frameConfig __unused) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::setConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ bool frameConfig = mFrameConfig;
+ OMX_ERRORTYPE err = internalSetConfig(index, params, &frameConfig);
+ if (err == OMX_ErrorNone) {
+ mFrameConfig = frameConfig;
+ }
+ return err;
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::useBuffer(
+ OMX_BUFFERHEADERTYPE **header,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *ptr) {
+ Mutex::Autolock autoLock(mLock);
+ return useBufferCallerLockedAlready(header, portIndex, appPrivate, size, ptr);
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::useBufferCallerLockedAlready(
+ OMX_BUFFERHEADERTYPE **header,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *ptr) {
+ CHECK_LT(portIndex, mPorts.size());
+ CHECK_LT(portIndex, mPorts.size());
+
+ PortInfo *port = &mPorts.editItemAt(portIndex);
+ if (size < port->mDef.nBufferSize) {
+ ALOGE("b/63522430, Buffer size is too small.");
+ android_errorWriteLog(0x534e4554, "63522430");
+ return OMX_ErrorBadParameter;
+ }
+
+ *header = new OMX_BUFFERHEADERTYPE;
+ (*header)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+ (*header)->nVersion.s.nVersionMajor = 1;
+ (*header)->nVersion.s.nVersionMinor = 0;
+ (*header)->nVersion.s.nRevision = 0;
+ (*header)->nVersion.s.nStep = 0;
+ (*header)->pBuffer = ptr;
+ (*header)->nAllocLen = size;
+ (*header)->nFilledLen = 0;
+ (*header)->nOffset = 0;
+ (*header)->pAppPrivate = appPrivate;
+ (*header)->pPlatformPrivate = NULL;
+ (*header)->pInputPortPrivate = NULL;
+ (*header)->pOutputPortPrivate = NULL;
+ (*header)->hMarkTargetComponent = NULL;
+ (*header)->pMarkData = NULL;
+ (*header)->nTickCount = 0;
+ (*header)->nTimeStamp = 0;
+ (*header)->nFlags = 0;
+ (*header)->nOutputPortIndex = portIndex;
+ (*header)->nInputPortIndex = portIndex;
+
+ CHECK(mState == OMX_StateLoaded || port->mDef.bEnabled == OMX_FALSE);
+
+ CHECK_LT(port->mBuffers.size(), port->mDef.nBufferCountActual);
+
+ port->mBuffers.push();
+
+ BufferInfo *buffer =
+ &port->mBuffers.editItemAt(port->mBuffers.size() - 1);
+
+ buffer->mHeader = *header;
+ buffer->mOwnedByUs = false;
+
+ if (port->mBuffers.size() == port->mDef.nBufferCountActual) {
+ port->mDef.bPopulated = OMX_TRUE;
+ checkTransitions();
+ }
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::allocateBuffer(
+ OMX_BUFFERHEADERTYPE **header,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size) {
+ OMX_U8 *ptr = new OMX_U8[size];
+
+ OMX_ERRORTYPE err =
+ useBuffer(header, portIndex, appPrivate, size, ptr);
+
+ if (err != OMX_ErrorNone) {
+ delete[] ptr;
+ ptr = NULL;
+
+ return err;
+ }
+
+ CHECK((*header)->pPlatformPrivate == NULL);
+ (*header)->pPlatformPrivate = ptr;
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::freeBuffer(
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *header) {
+ Mutex::Autolock autoLock(mLock);
+
+ CHECK_LT(portIndex, mPorts.size());
+
+ PortInfo *port = &mPorts.editItemAt(portIndex);
+
+#if 0 // XXX
+ CHECK((mState == OMX_StateIdle && mTargetState == OMX_StateLoaded)
+ || port->mDef.bEnabled == OMX_FALSE);
+#endif
+
+ bool found = false;
+ for (size_t i = 0; i < port->mBuffers.size(); ++i) {
+ BufferInfo *buffer = &port->mBuffers.editItemAt(i);
+
+ if (buffer->mHeader == header) {
+ CHECK(!buffer->mOwnedByUs);
+
+ if (header->pPlatformPrivate != NULL) {
+ // This buffer's data was allocated by us.
+ CHECK(header->pPlatformPrivate == header->pBuffer);
+
+ delete[] header->pBuffer;
+ header->pBuffer = NULL;
+ }
+
+ delete header;
+ header = NULL;
+
+ port->mBuffers.removeAt(i);
+ port->mDef.bPopulated = OMX_FALSE;
+
+ checkTransitions();
+
+ found = true;
+ break;
+ }
+ }
+
+ CHECK(found);
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::emptyThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer) {
+ sp<AMessage> msg = new AMessage(kWhatEmptyThisBuffer, mHandler);
+ msg->setPointer("header", buffer);
+ if (mFrameConfig) {
+ msg->setInt32("frame-config", mFrameConfig);
+ mFrameConfig = false;
+ }
+ msg->post();
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::fillThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer) {
+ sp<AMessage> msg = new AMessage(kWhatFillThisBuffer, mHandler);
+ msg->setPointer("header", buffer);
+ msg->post();
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE SimpleGoldfishOMXComponent::getState(OMX_STATETYPE *state) {
+ Mutex::Autolock autoLock(mLock);
+
+ *state = mState;
+
+ return OMX_ErrorNone;
+}
+
+void SimpleGoldfishOMXComponent::onMessageReceived(const sp<AMessage> &msg) {
+ Mutex::Autolock autoLock(mLock);
+ uint32_t msgType = msg->what();
+ ALOGV("msgType = %d", msgType);
+ switch (msgType) {
+ case kWhatSendCommand:
+ {
+ int32_t cmd, param;
+ CHECK(msg->findInt32("cmd", &cmd));
+ CHECK(msg->findInt32("param", ¶m));
+
+ onSendCommand((OMX_COMMANDTYPE)cmd, (OMX_U32)param);
+ break;
+ }
+
+ case kWhatEmptyThisBuffer:
+ case kWhatFillThisBuffer:
+ {
+ OMX_BUFFERHEADERTYPE *header;
+ CHECK(msg->findPointer("header", (void **)&header));
+ int32_t frameConfig;
+ if (!msg->findInt32("frame-config", &frameConfig)) {
+ frameConfig = 0;
+ }
+
+ CHECK(mState == OMX_StateExecuting && mTargetState == mState);
+
+ bool found = false;
+ size_t portIndex = (kWhatEmptyThisBuffer == msgType)?
+ header->nInputPortIndex: header->nOutputPortIndex;
+ PortInfo *port = &mPorts.editItemAt(portIndex);
+
+ for (size_t j = 0; j < port->mBuffers.size(); ++j) {
+ BufferInfo *buffer = &port->mBuffers.editItemAt(j);
+
+ if (buffer->mHeader == header) {
+ CHECK(!buffer->mOwnedByUs);
+
+ buffer->mOwnedByUs = true;
+ buffer->mFrameConfig = (bool)frameConfig;
+
+ CHECK((msgType == kWhatEmptyThisBuffer
+ && port->mDef.eDir == OMX_DirInput)
+ || (port->mDef.eDir == OMX_DirOutput));
+
+ port->mQueue.push_back(buffer);
+ onQueueFilled(portIndex);
+
+ found = true;
+ break;
+ }
+ }
+
+ CHECK(found);
+ break;
+ }
+
+ default:
+ TRESPASS();
+ break;
+ }
+}
+
+void SimpleGoldfishOMXComponent::onSendCommand(
+ OMX_COMMANDTYPE cmd, OMX_U32 param) {
+ switch (cmd) {
+ case OMX_CommandStateSet:
+ {
+ onChangeState((OMX_STATETYPE)param);
+ break;
+ }
+
+ case OMX_CommandPortEnable:
+ case OMX_CommandPortDisable:
+ {
+ onPortEnable(param, cmd == OMX_CommandPortEnable);
+ break;
+ }
+
+ case OMX_CommandFlush:
+ {
+ onPortFlush(param, true /* sendFlushComplete */);
+ break;
+ }
+
+ default:
+ TRESPASS();
+ break;
+ }
+}
+
+void SimpleGoldfishOMXComponent::onChangeState(OMX_STATETYPE state) {
+ ALOGV("%p requesting change from %d to %d", this, mState, state);
+ // We shouldn't be in a state transition already.
+
+ if (mState == OMX_StateLoaded
+ && mTargetState == OMX_StateIdle
+ && state == OMX_StateLoaded) {
+ // OMX specifically allows "canceling" a state transition from loaded
+ // to idle. Pretend we made it to idle, and go back to loaded
+ ALOGV("load->idle canceled");
+ mState = mTargetState = OMX_StateIdle;
+ state = OMX_StateLoaded;
+ }
+
+ if (mState != mTargetState) {
+ ALOGE("State change to state %d requested while still transitioning from state %d to %d",
+ state, mState, mTargetState);
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ return;
+ }
+
+ switch (mState) {
+ case OMX_StateLoaded:
+ CHECK_EQ((int)state, (int)OMX_StateIdle);
+ break;
+ case OMX_StateIdle:
+ CHECK(state == OMX_StateLoaded || state == OMX_StateExecuting);
+ break;
+ case OMX_StateExecuting:
+ {
+ CHECK_EQ((int)state, (int)OMX_StateIdle);
+
+ for (size_t i = 0; i < mPorts.size(); ++i) {
+ onPortFlush(i, false /* sendFlushComplete */);
+ }
+
+ mState = OMX_StateIdle;
+ notify(OMX_EventCmdComplete, OMX_CommandStateSet, state, NULL);
+ break;
+ }
+
+ default:
+ TRESPASS();
+ }
+
+ mTargetState = state;
+
+ checkTransitions();
+}
+
+void SimpleGoldfishOMXComponent::onReset() {
+ // no-op
+}
+
+void SimpleGoldfishOMXComponent::onPortEnable(OMX_U32 portIndex, bool enable) {
+ CHECK_LT(portIndex, mPorts.size());
+
+ PortInfo *port = &mPorts.editItemAt(portIndex);
+ CHECK_EQ((int)port->mTransition, (int)PortInfo::NONE);
+ CHECK(port->mDef.bEnabled == !enable);
+
+ if (port->mDef.eDir != OMX_DirOutput) {
+ ALOGE("Port enable/disable allowed only on output ports.");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ android_errorWriteLog(0x534e4554, "29421804");
+ return;
+ }
+
+ if (!enable) {
+ port->mDef.bEnabled = OMX_FALSE;
+ port->mTransition = PortInfo::DISABLING;
+
+ for (size_t i = 0; i < port->mBuffers.size(); ++i) {
+ BufferInfo *buffer = &port->mBuffers.editItemAt(i);
+
+ if (buffer->mOwnedByUs) {
+ buffer->mOwnedByUs = false;
+
+ if (port->mDef.eDir == OMX_DirInput) {
+ notifyEmptyBufferDone(buffer->mHeader);
+ } else {
+ CHECK_EQ(port->mDef.eDir, OMX_DirOutput);
+ notifyFillBufferDone(buffer->mHeader);
+ }
+ }
+ }
+
+ port->mQueue.clear();
+ } else {
+ port->mTransition = PortInfo::ENABLING;
+ }
+
+ checkTransitions();
+}
+
+void SimpleGoldfishOMXComponent::onPortFlush(
+ OMX_U32 portIndex, bool sendFlushComplete) {
+ if (portIndex == OMX_ALL) {
+ for (size_t i = 0; i < mPorts.size(); ++i) {
+ onPortFlush(i, sendFlushComplete);
+ }
+
+ if (sendFlushComplete) {
+ notify(OMX_EventCmdComplete, OMX_CommandFlush, OMX_ALL, NULL);
+ }
+
+ return;
+ }
+
+ CHECK_LT(portIndex, mPorts.size());
+
+ PortInfo *port = &mPorts.editItemAt(portIndex);
+ // Ideally, the port should not in transitioning state when flushing.
+ // However, in error handling case, e.g., the client can't allocate buffers
+ // when it tries to re-enable the port, the port will be stuck in ENABLING.
+ // The client will then transition the component from Executing to Idle,
+ // which leads to flushing ports. At this time, it should be ok to notify
+ // the client of the error and still clear all buffers on the port.
+ if (port->mTransition != PortInfo::NONE) {
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
+ }
+
+ for (size_t i = 0; i < port->mBuffers.size(); ++i) {
+ BufferInfo *buffer = &port->mBuffers.editItemAt(i);
+
+ if (!buffer->mOwnedByUs) {
+ continue;
+ }
+
+ buffer->mHeader->nFilledLen = 0;
+ buffer->mHeader->nOffset = 0;
+ buffer->mHeader->nFlags = 0;
+
+ buffer->mOwnedByUs = false;
+
+ if (port->mDef.eDir == OMX_DirInput) {
+ notifyEmptyBufferDone(buffer->mHeader);
+ } else {
+ CHECK_EQ(port->mDef.eDir, OMX_DirOutput);
+
+ notifyFillBufferDone(buffer->mHeader);
+ }
+ }
+
+ port->mQueue.clear();
+
+ if (sendFlushComplete) {
+ notify(OMX_EventCmdComplete, OMX_CommandFlush, portIndex, NULL);
+
+ onPortFlushCompleted(portIndex);
+ }
+}
+
+void SimpleGoldfishOMXComponent::checkTransitions() {
+ if (mState != mTargetState) {
+ bool transitionComplete = true;
+
+ if (mState == OMX_StateLoaded) {
+ CHECK_EQ((int)mTargetState, (int)OMX_StateIdle);
+
+ for (size_t i = 0; i < mPorts.size(); ++i) {
+ const PortInfo &port = mPorts.itemAt(i);
+ if (port.mDef.bEnabled == OMX_FALSE) {
+ continue;
+ }
+
+ if (port.mDef.bPopulated == OMX_FALSE) {
+ transitionComplete = false;
+ break;
+ }
+ }
+ } else if (mTargetState == OMX_StateLoaded) {
+ CHECK_EQ((int)mState, (int)OMX_StateIdle);
+
+ for (size_t i = 0; i < mPorts.size(); ++i) {
+ const PortInfo &port = mPorts.itemAt(i);
+ if (port.mDef.bEnabled == OMX_FALSE) {
+ continue;
+ }
+
+ size_t n = port.mBuffers.size();
+
+ if (n > 0) {
+ CHECK_LE(n, port.mDef.nBufferCountActual);
+
+ if (n == port.mDef.nBufferCountActual) {
+ CHECK_EQ((int)port.mDef.bPopulated, (int)OMX_TRUE);
+ } else {
+ CHECK_EQ((int)port.mDef.bPopulated, (int)OMX_FALSE);
+ }
+
+ transitionComplete = false;
+ break;
+ }
+ }
+ }
+
+ if (transitionComplete) {
+ ALOGV("state transition from %d to %d complete", mState, mTargetState);
+ mState = mTargetState;
+
+ if (mState == OMX_StateLoaded) {
+ onReset();
+ }
+
+ notify(OMX_EventCmdComplete, OMX_CommandStateSet, mState, NULL);
+ } else {
+ ALOGV("state transition from %d to %d not yet complete", mState, mTargetState);
+ }
+ }
+
+ for (size_t i = 0; i < mPorts.size(); ++i) {
+ PortInfo *port = &mPorts.editItemAt(i);
+
+ if (port->mTransition == PortInfo::DISABLING) {
+ if (port->mBuffers.empty()) {
+ ALOGV("Port %zu now disabled.", i);
+
+ port->mTransition = PortInfo::NONE;
+ notify(OMX_EventCmdComplete, OMX_CommandPortDisable, i, NULL);
+
+ onPortEnableCompleted(i, false /* enabled */);
+ }
+ } else if (port->mTransition == PortInfo::ENABLING) {
+ if (port->mDef.bPopulated == OMX_TRUE) {
+ ALOGV("Port %zu now enabled.", i);
+
+ port->mTransition = PortInfo::NONE;
+ port->mDef.bEnabled = OMX_TRUE;
+ notify(OMX_EventCmdComplete, OMX_CommandPortEnable, i, NULL);
+
+ onPortEnableCompleted(i, true /* enabled */);
+ }
+ }
+ }
+}
+
+void SimpleGoldfishOMXComponent::addPort(const OMX_PARAM_PORTDEFINITIONTYPE &def) {
+ CHECK_EQ(def.nPortIndex, mPorts.size());
+
+ mPorts.push();
+ PortInfo *info = &mPorts.editItemAt(mPorts.size() - 1);
+ info->mDef = def;
+ info->mTransition = PortInfo::NONE;
+}
+
+void SimpleGoldfishOMXComponent::onQueueFilled(OMX_U32 portIndex __unused) {
+}
+
+void SimpleGoldfishOMXComponent::onPortFlushCompleted(OMX_U32 portIndex __unused) {
+}
+
+void SimpleGoldfishOMXComponent::onPortEnableCompleted(
+ OMX_U32 portIndex __unused, bool enabled __unused) {
+}
+
+List<SimpleGoldfishOMXComponent::BufferInfo *> &
+SimpleGoldfishOMXComponent::getPortQueue(OMX_U32 portIndex) {
+ CHECK_LT(portIndex, mPorts.size());
+ return mPorts.editItemAt(portIndex).mQueue;
+}
+
+SimpleGoldfishOMXComponent::PortInfo *SimpleGoldfishOMXComponent::editPortInfo(
+ OMX_U32 portIndex) {
+ CHECK_LT(portIndex, mPorts.size());
+ return &mPorts.editItemAt(portIndex);
+}
+
+} // namespace android
diff --git a/system/codecs/omx/plugin/SimpleGoldfishOMXComponent.h b/system/codecs/omx/plugin/SimpleGoldfishOMXComponent.h
new file mode 100644
index 0000000..d2a3bf5
--- /dev/null
+++ b/system/codecs/omx/plugin/SimpleGoldfishOMXComponent.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SIMPLE_GOLDFISH_OMX_COMPONENT_H_
+
+#define SIMPLE_GOLDFISH_OMX_COMPONENT_H_
+
+#include "GoldfishOMXComponent.h"
+
+#include <atomic>
+#include <media/stagefright/foundation/AHandlerReflector.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+struct ALooper;
+struct ABuffer;
+
+struct CodecProfileLevel {
+ OMX_U32 mProfile;
+ OMX_U32 mLevel;
+};
+
+struct SimpleGoldfishOMXComponent : public GoldfishOMXComponent {
+ SimpleGoldfishOMXComponent(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+ virtual void prepareForDestruction();
+
+ void onMessageReceived(const sp<AMessage> &msg);
+
+protected:
+ struct BufferInfo {
+ OMX_BUFFERHEADERTYPE *mHeader;
+ bool mOwnedByUs;
+ bool mFrameConfig;
+ };
+
+ struct PortInfo {
+ OMX_PARAM_PORTDEFINITIONTYPE mDef;
+ Vector<BufferInfo> mBuffers;
+ List<BufferInfo *> mQueue;
+
+ enum {
+ NONE,
+ DISABLING,
+ ENABLING,
+ } mTransition;
+ };
+
+ enum {
+ kStoreMetaDataExtensionIndex = OMX_IndexVendorStartUnused + 1,
+ kPrepareForAdaptivePlaybackIndex,
+ };
+
+ void addPort(const OMX_PARAM_PORTDEFINITIONTYPE &def);
+
+ virtual OMX_ERRORTYPE internalGetParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE internalSetConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig);
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+ List<BufferInfo *> &getPortQueue(OMX_U32 portIndex);
+
+ virtual void onPortFlushCompleted(OMX_U32 portIndex);
+ virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled);
+ virtual void onReset();
+
+ PortInfo *editPortInfo(OMX_U32 portIndex);
+
+protected:
+ enum {
+ kWhatSendCommand,
+ kWhatEmptyThisBuffer,
+ kWhatFillThisBuffer,
+ };
+
+ Mutex mLock;
+
+ sp<ALooper> mLooper;
+ sp<AHandlerReflector<SimpleGoldfishOMXComponent> > mHandler;
+
+ OMX_STATETYPE mState;
+ OMX_STATETYPE mTargetState;
+
+ Vector<PortInfo> mPorts;
+ std::atomic_bool mFrameConfig;
+
+ bool isSetParameterAllowed(
+ OMX_INDEXTYPE index, const OMX_PTR params) const;
+
+ virtual OMX_ERRORTYPE sendCommand(
+ OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data);
+
+ virtual OMX_ERRORTYPE getParameter(
+ OMX_INDEXTYPE index, OMX_PTR params);
+
+ virtual OMX_ERRORTYPE setParameter(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE setConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
+ virtual OMX_ERRORTYPE useBuffer(
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *ptr);
+
+ OMX_ERRORTYPE useBufferCallerLockedAlready(
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size,
+ OMX_U8 *ptr);
+
+ virtual OMX_ERRORTYPE allocateBuffer(
+ OMX_BUFFERHEADERTYPE **buffer,
+ OMX_U32 portIndex,
+ OMX_PTR appPrivate,
+ OMX_U32 size);
+
+ virtual OMX_ERRORTYPE freeBuffer(
+ OMX_U32 portIndex,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE emptyThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE fillThisBuffer(
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ virtual OMX_ERRORTYPE getState(OMX_STATETYPE *state);
+
+ void onSendCommand(OMX_COMMANDTYPE cmd, OMX_U32 param);
+ void onChangeState(OMX_STATETYPE state);
+ void onPortEnable(OMX_U32 portIndex, bool enable);
+ void onPortFlush(OMX_U32 portIndex, bool sendFlushComplete);
+
+ void checkTransitions();
+
+ DISALLOW_EVIL_CONSTRUCTORS(SimpleGoldfishOMXComponent);
+};
+
+} // namespace android
+
+#endif // SIMPLE_GOLDFISH_OMX_COMPONENT_H_
diff --git a/system/codecs/omx/vpxdec/Android.mk b/system/codecs/omx/vpxdec/Android.mk
new file mode 100644
index 0000000..6374ac3
--- /dev/null
+++ b/system/codecs/omx/vpxdec/Android.mk
@@ -0,0 +1,48 @@
+#
+# Copyright 2019 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.
+#
+LOCAL_PATH := $(call my-dir)
+
+commonSources := \
+ GoldfishVPX.cpp \
+ goldfish_vpx_impl.cpp
+
+$(call emugl-begin-shared-library,libstagefright_goldfish_vpxdec$(GOLDFISH_OPENGL_LIB_SUFFIX))
+
+LOCAL_SRC_FILES := $(commonSources)
+
+LOCAL_CFLAGS += -DLOG_TAG=\"goldfish_vpxdec\"
+LOCAL_CFLAGS += -Wno-unused-private-field
+
+$(call emugl-export,SHARED_LIBRARIES,libcutils libutils liblog)
+
+LOCAL_HEADER_LIBRARIES := media_plugin_headers \
+ libmedia_headers \
+ libbinder_headers \
+ libhidlbase_impl_internal \
+ libbase
+
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libutils \
+ liblog \
+ libcutils \
+ android.hardware.media.omx@1.0 \
+ libstagefright_foundation
+
+$(call emugl-export,C_INCLUDES,$(LOCAL_PATH))
+$(call emugl-import,libgoldfish_codecs_common)
+$(call emugl-import,libstagefrighthw)
+$(call emugl-end-module)
diff --git a/system/codecs/omx/vpxdec/GoldfishVPX.cpp b/system/codecs/omx/vpxdec/GoldfishVPX.cpp
new file mode 100644
index 0000000..e10dec2
--- /dev/null
+++ b/system/codecs/omx/vpxdec/GoldfishVPX.cpp
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+#include <utils/misc.h>
+//#include "OMX_VideoExt.h"
+
+#include "GoldfishVPX.h"
+
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaDefs.h>
+
+
+namespace android {
+
+// Only need to declare the highest supported profile and level here.
+static const CodecProfileLevel kVP9ProfileLevels[] = {
+ { OMX_VIDEO_VP9Profile0, OMX_VIDEO_VP9Level5 },
+ { OMX_VIDEO_VP9Profile2, OMX_VIDEO_VP9Level5 },
+ { OMX_VIDEO_VP9Profile2HDR, OMX_VIDEO_VP9Level5 },
+ { OMX_VIDEO_VP9Profile2HDR10Plus, OMX_VIDEO_VP9Level5 },
+};
+
+GoldfishVPX::GoldfishVPX(
+ const char *name,
+ const char *componentRole,
+ OMX_VIDEO_CODINGTYPE codingType,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component)
+ : GoldfishVideoDecoderOMXComponent(
+ name, componentRole, codingType,
+ codingType == OMX_VIDEO_CodingVP8 ? NULL : kVP9ProfileLevels,
+ codingType == OMX_VIDEO_CodingVP8 ? 0 : NELEM(kVP9ProfileLevels),
+ 320 /* width */, 240 /* height */, callbacks, appData, component),
+ mMode(codingType == OMX_VIDEO_CodingVP8 ? MODE_VP8 : MODE_VP9),
+ mEOSStatus(INPUT_DATA_AVAILABLE),
+ mCtx(NULL),
+ mFrameParallelMode(false),
+ mTimeStampIdx(0),
+ mImg(NULL) {
+ // arbitrary from avc/hevc as vpx does not specify a min compression ratio
+ const size_t kMinCompressionRatio = mMode == MODE_VP8 ? 2 : 4;
+ const char *mime = mMode == MODE_VP8 ? MEDIA_MIMETYPE_VIDEO_VP8 : MEDIA_MIMETYPE_VIDEO_VP9;
+ const size_t kMaxOutputBufferSize = 2048 * 2048 * 3 / 2;
+ initPorts(
+ kNumBuffers, kMaxOutputBufferSize / kMinCompressionRatio /* inputBufferSize */,
+ kNumBuffers, mime, kMinCompressionRatio);
+ ALOGE("calling constructor of GoldfishVPX");
+ CHECK_EQ(initDecoder(), (status_t)OK);
+}
+
+GoldfishVPX::~GoldfishVPX() {
+ ALOGE("calling destructor of GoldfishVPX");
+ destroyDecoder();
+}
+
+bool GoldfishVPX::supportDescribeHdrStaticInfo() {
+ return true;
+}
+
+bool GoldfishVPX::supportDescribeHdr10PlusInfo() {
+ return true;
+}
+
+status_t GoldfishVPX::initDecoder() {
+ mCtx = new vpx_codec_ctx_t;
+ mCtx->vpversion = mMode == MODE_VP8 ? 8 : 9;
+
+ int vpx_err = 0;
+ if ((vpx_err = vpx_codec_dec_init(mCtx))) {
+ ALOGE("vpx decoder failed to initialize. (%d)", vpx_err);
+ return UNKNOWN_ERROR;
+ }
+
+ return OK;
+}
+
+status_t GoldfishVPX::destroyDecoder() {
+ vpx_codec_destroy(mCtx);
+ delete mCtx;
+ mCtx = NULL;
+ return OK;
+}
+
+void GoldfishVPX::setup_ctx_parameters(vpx_codec_ctx_t* ctx) {
+ ctx->width = mWidth;
+ ctx->height = mHeight;
+ ctx->outputBufferWidth = outputBufferWidth();
+ ctx->outputBufferHeight = outputBufferHeight();
+ OMX_PARAM_PORTDEFINITIONTYPE *outDef = &editPortInfo(kOutputPortIndex)->mDef;
+ int32_t bpp = (outDef->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar16) ? 2 : 1;
+ ctx->bpp = bpp;
+}
+
+bool GoldfishVPX::outputBuffers(bool flushDecoder, bool display, bool eos, bool *portWillReset) {
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+ BufferInfo *outInfo = NULL;
+ OMX_BUFFERHEADERTYPE *outHeader = NULL;
+
+ if (flushDecoder && mFrameParallelMode) {
+ // Flush decoder by passing NULL data ptr and 0 size.
+ // Ideally, this should never fail.
+ if (vpx_codec_flush(mCtx)) {
+ ALOGE("Failed to flush on2 decoder.");
+ return false;
+ }
+ }
+
+ if (!display) {
+ if (!flushDecoder) {
+ ALOGE("Invalid operation.");
+ return false;
+ }
+ // Drop all the decoded frames in decoder.
+ // TODO: move this to host, with something like
+ // vpx_codec_drop_all_frames(mCtx);
+ setup_ctx_parameters(mCtx);
+ while ((mImg = vpx_codec_get_frame(mCtx))) {
+ }
+ return true;
+ }
+
+ while (!outQueue.empty()) {
+ if (mImg == NULL) {
+ setup_ctx_parameters(mCtx);
+ mImg = vpx_codec_get_frame(mCtx);
+ if (mImg == NULL) {
+ break;
+ }
+ }
+ uint32_t width = mImg->d_w;
+ uint32_t height = mImg->d_h;
+ outInfo = *outQueue.begin();
+ outHeader = outInfo->mHeader;
+ CHECK(mImg->fmt == VPX_IMG_FMT_I420 || mImg->fmt == VPX_IMG_FMT_I42016);
+ OMX_COLOR_FORMATTYPE outputColorFormat = OMX_COLOR_FormatYUV420Planar;
+ int32_t bpp = 1;
+ if (mImg->fmt == VPX_IMG_FMT_I42016) {
+ outputColorFormat = OMX_COLOR_FormatYUV420Planar16;
+ bpp = 2;
+ }
+ handlePortSettingsChange(portWillReset, width, height, outputColorFormat);
+ if (*portWillReset) {
+ return true;
+ }
+
+ outHeader->nOffset = 0;
+ outHeader->nFlags = 0;
+ outHeader->nFilledLen = (outputBufferWidth() * outputBufferHeight() * bpp * 3) / 2;
+ PrivInfo *privInfo = (PrivInfo *)mImg->user_priv;
+ outHeader->nTimeStamp = privInfo->mTimeStamp;
+ if (privInfo->mHdr10PlusInfo != nullptr) {
+ queueOutputFrameConfig(privInfo->mHdr10PlusInfo);
+ }
+
+ if (outputBufferSafe(outHeader)) {
+ uint8_t *dst = outHeader->pBuffer;
+ memcpy(dst, mCtx->dst, outHeader->nFilledLen);
+ } else {
+ outHeader->nFilledLen = 0;
+ }
+
+ mImg = NULL;
+ outInfo->mOwnedByUs = false;
+ outQueue.erase(outQueue.begin());
+ outInfo = NULL;
+ notifyFillBufferDone(outHeader);
+ outHeader = NULL;
+ }
+
+ if (!eos) {
+ return true;
+ }
+
+ if (!outQueue.empty()) {
+ outInfo = *outQueue.begin();
+ outQueue.erase(outQueue.begin());
+ outHeader = outInfo->mHeader;
+ outHeader->nTimeStamp = 0;
+ outHeader->nFilledLen = 0;
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ outInfo->mOwnedByUs = false;
+ notifyFillBufferDone(outHeader);
+ mEOSStatus = OUTPUT_FRAMES_FLUSHED;
+ }
+ return true;
+}
+
+bool GoldfishVPX::outputBufferSafe(OMX_BUFFERHEADERTYPE *outHeader) {
+ uint32_t width = outputBufferWidth();
+ uint32_t height = outputBufferHeight();
+ uint64_t nFilledLen = width;
+ nFilledLen *= height;
+ if (nFilledLen > UINT32_MAX / 3) {
+ ALOGE("b/29421675, nFilledLen overflow %llu w %u h %u",
+ (unsigned long long)nFilledLen, width, height);
+ android_errorWriteLog(0x534e4554, "29421675");
+ return false;
+ } else if (outHeader->nAllocLen < outHeader->nFilledLen) {
+ ALOGE("b/27597103, buffer too small");
+ android_errorWriteLog(0x534e4554, "27597103");
+ return false;
+ }
+
+ return true;
+}
+
+void GoldfishVPX::onQueueFilled(OMX_U32 /* portIndex */) {
+ if (mOutputPortSettingsChange != NONE || mEOSStatus == OUTPUT_FRAMES_FLUSHED) {
+ return;
+ }
+
+ List<BufferInfo *> &inQueue = getPortQueue(0);
+ List<BufferInfo *> &outQueue = getPortQueue(1);
+ bool EOSseen = false;
+ bool portWillReset = false;
+
+ while ((mEOSStatus == INPUT_EOS_SEEN || !inQueue.empty())
+ && !outQueue.empty()) {
+ // Output the pending frames that left from last port reset or decoder flush.
+ if (mEOSStatus == INPUT_EOS_SEEN || mImg != NULL) {
+ if (!outputBuffers(
+ mEOSStatus == INPUT_EOS_SEEN, true /* display */,
+ mEOSStatus == INPUT_EOS_SEEN, &portWillReset)) {
+ ALOGE("on2 decoder failed to output frame.");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ return;
+ }
+ if (portWillReset || mEOSStatus == OUTPUT_FRAMES_FLUSHED ||
+ mEOSStatus == INPUT_EOS_SEEN) {
+ return;
+ }
+ // Continue as outQueue may be empty now.
+ continue;
+ }
+
+ BufferInfo *inInfo = *inQueue.begin();
+ OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+ // Software VP9 Decoder does not need the Codec Specific Data (CSD)
+ // (specified in http://www.webmproject.org/vp9/profiles/). Ignore it if
+ // it was passed.
+ if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ // Only ignore CSD buffer for VP9.
+ if (mMode == MODE_VP9) {
+ inQueue.erase(inQueue.begin());
+ inInfo->mOwnedByUs = false;
+ notifyEmptyBufferDone(inHeader);
+ continue;
+ } else {
+ // Tolerate the CSD buffer for VP8. This is a workaround
+ // for b/28689536.
+ ALOGW("WARNING: Got CSD buffer for VP8.");
+ }
+ }
+
+ mPrivInfo[mTimeStampIdx].mTimeStamp = inHeader->nTimeStamp;
+
+ if (inInfo->mFrameConfig) {
+ mPrivInfo[mTimeStampIdx].mHdr10PlusInfo = dequeueInputFrameConfig();
+ } else {
+ mPrivInfo[mTimeStampIdx].mHdr10PlusInfo.clear();
+ }
+
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ mEOSStatus = INPUT_EOS_SEEN;
+ EOSseen = true;
+ }
+
+ if (inHeader->nFilledLen > 0) {
+ int err = vpx_codec_decode(mCtx, inHeader->pBuffer + inHeader->nOffset,
+ inHeader->nFilledLen, &mPrivInfo[mTimeStampIdx], 0);
+ if (err == VPX_CODEC_OK) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ } else {
+ ALOGE("on2 decoder failed to decode frame. err: %d", err);
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ return;
+ }
+ }
+
+ mTimeStampIdx = (mTimeStampIdx + 1) % kNumBuffers;
+
+ if (!outputBuffers(
+ EOSseen /* flushDecoder */, true /* display */, EOSseen, &portWillReset)) {
+ ALOGE("on2 decoder failed to output frame.");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ return;
+ }
+ if (portWillReset) {
+ return;
+ }
+ }
+}
+
+void GoldfishVPX::onPortFlushCompleted(OMX_U32 portIndex) {
+ if (portIndex == kInputPortIndex) {
+ bool portWillReset = false;
+ if (!outputBuffers(
+ true /* flushDecoder */, false /* display */, false /* eos */, &portWillReset)) {
+ ALOGE("Failed to flush decoder.");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ return;
+ }
+ mEOSStatus = INPUT_DATA_AVAILABLE;
+ }
+}
+
+void GoldfishVPX::onReset() {
+ bool portWillReset = false;
+ if (!outputBuffers(
+ true /* flushDecoder */, false /* display */, false /* eos */, &portWillReset)) {
+ ALOGW("Failed to flush decoder. Try to hard reset decoder");
+ destroyDecoder();
+ initDecoder();
+ }
+ mEOSStatus = INPUT_DATA_AVAILABLE;
+}
+
+} // namespace android
+
+android::GoldfishOMXComponent *createGoldfishOMXComponent(
+ const char *name, const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData, OMX_COMPONENTTYPE **component) {
+ if (!strcmp(name, "OMX.google.goldfish.vp8.decoder")) {
+ return new android::GoldfishVPX(
+ name, "video_decoder.vp8", OMX_VIDEO_CodingVP8,
+ callbacks, appData, component);
+ } else if (!strcmp(name, "OMX.google.goldfish.vp9.decoder")) {
+ return new android::GoldfishVPX(
+ name, "video_decoder.vp9", OMX_VIDEO_CodingVP9,
+ callbacks, appData, component);
+ } else {
+ CHECK(!"Unknown component");
+ }
+ return NULL;
+}
diff --git a/system/codecs/omx/vpxdec/GoldfishVPX.h b/system/codecs/omx/vpxdec/GoldfishVPX.h
new file mode 100644
index 0000000..2ba8beb
--- /dev/null
+++ b/system/codecs/omx/vpxdec/GoldfishVPX.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GOLDFISH_VPX_H_
+
+#define GOLDFISH_VPX_H_
+
+#include "GoldfishVideoDecoderOMXComponent.h"
+#include "goldfish_vpx_defs.h"
+
+namespace android {
+
+struct ABuffer;
+
+struct GoldfishVPX : public GoldfishVideoDecoderOMXComponent {
+ GoldfishVPX(const char *name,
+ const char *componentRole,
+ OMX_VIDEO_CODINGTYPE codingType,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+protected:
+ virtual ~GoldfishVPX();
+
+ virtual void onQueueFilled(OMX_U32 portIndex);
+ virtual void onPortFlushCompleted(OMX_U32 portIndex);
+ virtual void onReset();
+ virtual bool supportDescribeHdrStaticInfo();
+ virtual bool supportDescribeHdr10PlusInfo();
+
+private:
+ enum {
+ kNumBuffers = 10
+ };
+
+ enum {
+ MODE_VP8,
+ MODE_VP9
+ } mMode;
+
+ enum {
+ INPUT_DATA_AVAILABLE, // VPX component is ready to decode data.
+ INPUT_EOS_SEEN, // VPX component saw EOS and is flushing On2 decoder.
+ OUTPUT_FRAMES_FLUSHED // VPX component finished flushing On2 decoder.
+ } mEOSStatus;
+
+ vpx_codec_ctx_t *mCtx;
+ bool mFrameParallelMode; // Frame parallel is only supported by VP9 decoder.
+ struct PrivInfo {
+ OMX_TICKS mTimeStamp;
+ sp<ABuffer> mHdr10PlusInfo;
+ };
+ PrivInfo mPrivInfo[kNumBuffers];
+ uint8_t mTimeStampIdx;
+ vpx_image_t *mImg;
+
+ status_t initDecoder();
+ status_t destroyDecoder();
+ bool outputBuffers(bool flushDecoder, bool display, bool eos, bool *portWillReset);
+ bool outputBufferSafe(OMX_BUFFERHEADERTYPE *outHeader);
+
+ void setup_ctx_parameters(vpx_codec_ctx_t*);
+
+ DISALLOW_EVIL_CONSTRUCTORS(GoldfishVPX);
+};
+
+} // namespace android
+
+#endif // GOLDFISH_VPX_H_
diff --git a/system/codecs/omx/vpxdec/exports.lds b/system/codecs/omx/vpxdec/exports.lds
new file mode 100644
index 0000000..e6674f2
--- /dev/null
+++ b/system/codecs/omx/vpxdec/exports.lds
@@ -0,0 +1,5 @@
+{
+ global:
+ _Z26createGoldfishOMXComponentPKcPK16OMX_CALLBACKTYPEPvPP17OMX_COMPONENTTYPE;
+ local: *;
+};
diff --git a/system/codecs/omx/vpxdec/goldfish_vpx_defs.h b/system/codecs/omx/vpxdec/goldfish_vpx_defs.h
new file mode 100644
index 0000000..1b1358c
--- /dev/null
+++ b/system/codecs/omx/vpxdec/goldfish_vpx_defs.h
@@ -0,0 +1,54 @@
+#ifndef MY_VPX_DEFS_H_
+#define MY_VPX_DEFS_H_
+
+
+#define VPX_IMG_FMT_PLANAR 0x100 /**< Image is a planar format. */
+#define VPX_IMG_FMT_UV_FLIP 0x200 /**< V plane precedes U in memory. */
+#define VPX_IMG_FMT_HAS_ALPHA 0x400 /**< Image has an alpha channel. */
+#define VPX_IMG_FMT_HIGHBITDEPTH 0x800 /**< Image uses 16bit framebuffer. */
+
+typedef unsigned char uint8_t;
+
+enum vpx_img_fmt_t {
+ VPX_IMG_FMT_NONE,
+ VPX_IMG_FMT_YV12 =
+ VPX_IMG_FMT_PLANAR | VPX_IMG_FMT_UV_FLIP | 1, /**< planar YVU */
+ VPX_IMG_FMT_I420 = VPX_IMG_FMT_PLANAR | 2,
+ VPX_IMG_FMT_I422 = VPX_IMG_FMT_PLANAR | 5,
+ VPX_IMG_FMT_I444 = VPX_IMG_FMT_PLANAR | 6,
+ VPX_IMG_FMT_I440 = VPX_IMG_FMT_PLANAR | 7,
+ VPX_IMG_FMT_I42016 = VPX_IMG_FMT_I420 | VPX_IMG_FMT_HIGHBITDEPTH,
+ VPX_IMG_FMT_I42216 = VPX_IMG_FMT_I422 | VPX_IMG_FMT_HIGHBITDEPTH,
+ VPX_IMG_FMT_I44416 = VPX_IMG_FMT_I444 | VPX_IMG_FMT_HIGHBITDEPTH,
+ VPX_IMG_FMT_I44016 = VPX_IMG_FMT_I440 | VPX_IMG_FMT_HIGHBITDEPTH
+};
+
+struct vpx_image_t {
+ vpx_img_fmt_t fmt; /**< Image Format */
+ unsigned int d_w; /**< Displayed image width */
+ unsigned int d_h; /**< Displayed image height */
+ void *user_priv;
+};
+
+#define VPX_CODEC_OK 0
+
+struct vpx_codec_ctx_t {
+ int vpversion; //8: vp8 or 9: vp9
+ size_t outputBufferWidth;
+ size_t outputBufferHeight;
+ size_t width;
+ size_t height;
+ size_t bpp;
+ uint8_t *data;
+ uint8_t *dst;
+};
+
+int vpx_codec_destroy(vpx_codec_ctx_t*);
+int vpx_codec_dec_init(vpx_codec_ctx_t*);
+vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t*);
+int vpx_codec_flush(vpx_codec_ctx_t *ctx);
+int vpx_codec_decode(vpx_codec_ctx_t *ctx, const uint8_t *data,
+ unsigned int data_sz, void *user_priv,
+ long deadline);
+
+#endif // MY_VPX_DEFS_H_
diff --git a/system/codecs/omx/vpxdec/goldfish_vpx_impl.cpp b/system/codecs/omx/vpxdec/goldfish_vpx_impl.cpp
new file mode 100644
index 0000000..0771176
--- /dev/null
+++ b/system/codecs/omx/vpxdec/goldfish_vpx_impl.cpp
@@ -0,0 +1,98 @@
+#include <log/log.h>
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <cstdlib>
+#include <string>
+#include <errno.h>
+#include "goldfish_vpx_defs.h"
+#include "goldfish_media_utils.h"
+
+static vpx_image_t myImg;
+
+static void sendVpxOperation(vpx_codec_ctx_t* ctx, MediaOperation op) {
+ auto transport = GoldfishMediaTransport::getInstance();
+ transport->sendOperation(
+ ctx->vpversion == 8 ?
+ MediaCodecType::VP8Codec :
+ MediaCodecType::VP9Codec,
+ op);
+}
+
+int vpx_codec_destroy(vpx_codec_ctx_t* ctx) {
+ sendVpxOperation(ctx, MediaOperation::DestroyContext);
+ return 0;
+}
+
+int vpx_codec_dec_init(vpx_codec_ctx_t* ctx) {
+ auto transport = GoldfishMediaTransport::getInstance();
+ // data and dst are on the host side actually
+ ctx->data = transport->getInputAddr();
+ ctx->dst = transport->getOutputAddr();
+ sendVpxOperation(ctx, MediaOperation::InitContext);
+ return 0;
+}
+
+static int getReturnCode(uint8_t* ptr) {
+ int* pint = (int*)(ptr);
+ return *pint;
+}
+
+static void getVpxFrame(uint8_t* ptr) {
+ uint8_t* imgptr = (ptr + 8);
+ myImg.fmt = *(vpx_img_fmt_t*)imgptr;
+ imgptr += 8;
+ myImg.d_w = *(unsigned int *)imgptr;
+ imgptr += 8;
+ myImg.d_h = *(unsigned int *)imgptr;
+ imgptr += 8;
+ myImg.user_priv = (void*)(*(uint64_t*)imgptr);
+}
+
+//TODO: we might not need to do the putting all the time
+vpx_image_t* vpx_codec_get_frame(vpx_codec_ctx_t* ctx) {
+ auto transport = GoldfishMediaTransport::getInstance();
+
+ transport->writeParam(ctx->outputBufferWidth, 0);
+ transport->writeParam(ctx->outputBufferHeight, 1);
+ transport->writeParam(ctx->width, 2);
+ transport->writeParam(ctx->height, 3);
+ transport->writeParam(ctx->bpp, 4);
+ transport->writeParam(transport->offsetOf((uint64_t)(ctx->dst)), 5);
+
+ sendVpxOperation(ctx, MediaOperation::GetImage);
+
+ auto* retptr = transport->getReturnAddr();
+ int ret = getReturnCode(retptr);
+ if (ret) {
+ return nullptr;
+ }
+ getVpxFrame(retptr);
+ return &myImg;
+}
+
+int vpx_codec_flush(vpx_codec_ctx_t* ctx) {
+ sendVpxOperation(ctx, MediaOperation::Flush);
+ return 0;
+}
+
+int vpx_codec_decode(vpx_codec_ctx_t *ctx,
+ const uint8_t* data,
+ unsigned int data_sz,
+ void* user_priv,
+ long deadline) {
+ auto transport = GoldfishMediaTransport::getInstance();
+ memcpy(ctx->data, data, data_sz);
+
+ transport->writeParam(transport->offsetOf((uint64_t)(ctx->data)), 0);
+ transport->writeParam((__u64)data_sz, 1);
+ transport->writeParam((__u64)user_priv, 2);
+ sendVpxOperation(ctx, MediaOperation::DecodeImage);
+ return 0;
+}
diff --git a/system/egl/CMakeLists.txt b/system/egl/CMakeLists.txt
index d3d4b57..25b4cdd 100644
--- a/system/egl/CMakeLists.txt
+++ b/system/egl/CMakeLists.txt
@@ -3,7 +3,7 @@
# which will re-generate this file.
android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/egl/Android.mk" "53f944775eac93c4fff6cb2b10ec932462422eb0e4ae0fb616f2f16bb0baf4af")
set(EGL_emulation_src eglDisplay.cpp egl.cpp ClientAPIExts.cpp)
-android_add_shared_library(EGL_emulation)
+android_add_library(TARGET EGL_emulation SHARED LICENSE Apache-2.0 SRC eglDisplay.cpp egl.cpp ClientAPIExts.cpp)
target_include_directories(EGL_emulation PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/bionic-include ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon ${GOLDFISH_DEVICE_ROOT}/bionic/libc/private ${GOLDFISH_DEVICE_ROOT}/bionic/libc/platform ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
target_compile_definitions(EGL_emulation PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"EGL_emulation\"" "-DEGL_EGLEXT_PROTOTYPES")
target_compile_options(EGL_emulation PRIVATE "-fvisibility=default" "-Wno-unused-parameter" "-Wno-gnu-designator")
diff --git a/system/egl/egl.cpp b/system/egl/egl.cpp
index 60d17e5..5940b79 100644
--- a/system/egl/egl.cpp
+++ b/system/egl/egl.cpp
@@ -675,7 +675,7 @@
return EGL_FALSE;
}
- rcColorBuffer = rcEnc->rcCreateColorBuffer(rcEnc, getWidth(), getHeight(), pixelFormat);
+ rcColorBuffer = grallocHelper->createColorBuffer(rcEnc, getWidth(), getHeight(), pixelFormat);
if (!rcColorBuffer) {
ALOGE("rcCreateColorBuffer returned 0");
return EGL_FALSE;
@@ -2258,9 +2258,22 @@
case EGL_SYNC_TYPE_KHR:
*value = sync->type;
return EGL_TRUE;
- case EGL_SYNC_STATUS_KHR:
- *value = sync->status;
- return EGL_TRUE;
+ case EGL_SYNC_STATUS_KHR: {
+ if (sync->status == EGL_SIGNALED_KHR) {
+ *value = sync->status;
+ return EGL_TRUE;
+ } else {
+ // ask the host again
+ DEFINE_HOST_CONNECTION;
+ if (rcEnc->hasNativeSyncV4()) {
+ if (rcEnc->rcIsSyncSignaled(rcEnc, sync->handle)) {
+ sync->status = EGL_SIGNALED_KHR;
+ }
+ }
+ *value = sync->status;
+ return EGL_TRUE;
+ }
+ }
case EGL_SYNC_CONDITION_KHR:
*value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
return EGL_TRUE;
diff --git a/system/gralloc/Android.mk b/system/gralloc/Android.mk
index 3fb4d97..8a12378 100644
--- a/system/gralloc/Android.mk
+++ b/system/gralloc/Android.mk
@@ -11,7 +11,11 @@
LOCAL_CFLAGS += -Wno-missing-field-initializers
LOCAL_CFLAGS += -Wno-gnu-designator
+ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 30; echo $$?), 0)
+LOCAL_SRC_FILES := gralloc_30.cpp
+else
LOCAL_SRC_FILES := gralloc_old.cpp
+endif
ifneq (true,$(GOLDFISH_OPENGL_BUILD_FOR_HOST))
LOCAL_SHARED_LIBRARIES += libdl
diff --git a/system/gralloc/CMakeLists.txt b/system/gralloc/CMakeLists.txt
index b696caa..cf65352 100644
--- a/system/gralloc/CMakeLists.txt
+++ b/system/gralloc/CMakeLists.txt
@@ -1,9 +1,9 @@
# This is an autogenerated file! Do not edit!
# instead run make from .../device/generic/goldfish-opengl
# which will re-generate this file.
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/gralloc/Android.mk" "2233defde8a8ff38eb1c7a8878204f3f8aa410fe64f7122bdececd1c5737de3f")
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/gralloc/Android.mk" "09618d9293855148fb310e67065028da8c7f6dcf936b02b5695292c82ed4724e")
set(gralloc.goldfish_src gralloc_old.cpp)
-android_add_shared_library(gralloc.goldfish)
+android_add_library(TARGET gralloc.goldfish SHARED LICENSE Apache-2.0 SRC gralloc_old.cpp)
target_include_directories(gralloc.goldfish PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/bionic-include ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon ${GOLDFISH_DEVICE_ROOT}/bionic/libc/private ${GOLDFISH_DEVICE_ROOT}/bionic/libc/platform ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
target_compile_definitions(gralloc.goldfish PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"gralloc_goldfish\"")
target_compile_options(gralloc.goldfish PRIVATE "-fvisibility=default" "-Wno-unused-parameter" "-Wno-missing-field-initializers" "-Wno-gnu-designator")
@@ -11,9 +11,9 @@
# This is an autogenerated file! Do not edit!
# instead run make from .../device/generic/goldfish-opengl
# which will re-generate this file.
-android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/gralloc/Android.mk" "2233defde8a8ff38eb1c7a8878204f3f8aa410fe64f7122bdececd1c5737de3f")
+android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/gralloc/Android.mk" "09618d9293855148fb310e67065028da8c7f6dcf936b02b5695292c82ed4724e")
set(gralloc.ranchu_src gralloc_old.cpp)
-android_add_shared_library(gralloc.ranchu)
+android_add_library(TARGET gralloc.ranchu SHARED LICENSE Apache-2.0 SRC gralloc_old.cpp)
target_include_directories(gralloc.ranchu PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/bionic-include ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon ${GOLDFISH_DEVICE_ROOT}/bionic/libc/private ${GOLDFISH_DEVICE_ROOT}/bionic/libc/platform ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
target_compile_definitions(gralloc.ranchu PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"gralloc_ranchu\"")
target_compile_options(gralloc.ranchu PRIVATE "-fvisibility=default" "-Wno-unused-parameter" "-Wno-missing-field-initializers" "-Wno-gnu-designator")
diff --git a/system/gralloc/gralloc_30.cpp b/system/gralloc/gralloc_30.cpp
new file mode 100644
index 0000000..6597405
--- /dev/null
+++ b/system/gralloc/gralloc_30.cpp
@@ -0,0 +1,1077 @@
+/*
+* Copyright (C) 2019 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 <string.h>
+#include <pthread.h>
+#include <limits.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <set>
+#include <map>
+#include <vector>
+#include <string>
+#include <algorithm>
+
+#include <log/log.h>
+#include <sys/mman.h>
+
+#include <hardware/hardware.h>
+#include <hardware/gralloc.h>
+
+#include "../../shared/OpenglCodecCommon/gralloc_cb.h"
+#include "gralloc_common.h"
+#include "goldfish_address_space.h"
+#include "HostConnection.h"
+#include "FormatConversions.h"
+#include "qemu_pipe.h"
+
+#define CRASH(MSG) \
+ do { \
+ ALOGE("%s:%d crashed with '%s'", __func__, __LINE__, MSG); \
+ ::abort(); \
+ } while (false)
+
+#define CRASH_IF(COND, MSG) \
+ do { \
+ if ((COND)) { \
+ ALOGE("%s:%d crashed on '%s' with '%s'", __func__, __LINE__, #COND, MSG); \
+ ::abort(); \
+ } \
+ } while (false)
+
+#define RETURN_ERROR_CODE(X) \
+ do { \
+ ALOGE("%s:%d failed with '%s' (%d)", \
+ __func__, __LINE__, strerror(-(X)), -(X)); \
+ return (X); \
+ } while (false)
+
+#define RETURN_ERROR(X) \
+ do { \
+ ALOGE("%s:%d failed with '%s'", __func__, __LINE__, #X); \
+ return (X); \
+ } while (false)
+
+namespace {
+
+const char GOLDFISH_GRALLOC_MODULE_NAME[] = "Graphics Memory Allocator Module";
+
+hw_device_t make_hw_device(hw_module_t* module, int (*close)(hw_device_t*)) {
+ hw_device_t result = {};
+
+ result.tag = HARDWARE_DEVICE_TAG;
+ result.version = 0;
+ result.module = module;
+ result.close = close;
+
+ return result;
+}
+
+size_t align(const size_t v, const size_t a) { return (v + a - 1) & ~(a - 1); }
+
+class HostConnectionSession {
+public:
+ explicit HostConnectionSession(HostConnection* hc) : conn(hc) {
+ hc->lock();
+ }
+
+ ~HostConnectionSession() {
+ if (conn) {
+ conn->unlock();
+ }
+ }
+
+ HostConnectionSession(HostConnectionSession&& rhs) : conn(rhs.conn) {
+ rhs.conn = nullptr;
+ }
+
+ HostConnectionSession& operator=(HostConnectionSession&& rhs) {
+ if (this != &rhs) {
+ std::swap(conn, rhs.conn);
+ }
+ return *this;
+ }
+
+ HostConnectionSession(const HostConnectionSession&) = delete;
+ HostConnectionSession& operator=(const HostConnectionSession&) = delete;
+
+ ExtendedRCEncoderContext* getRcEncoder() const {
+ return conn->rcEncoder();
+ }
+
+private:
+ HostConnection* conn;
+};
+
+class goldfish_gralloc30_module_t;
+class goldfish_gralloc30_device_t;
+class goldfish_fb30_device_t;
+
+class buffer_manager_t {
+public:
+ buffer_manager_t() = default;
+ buffer_manager_t(const buffer_manager_t&) = delete;
+ buffer_manager_t& operator=(const buffer_manager_t&) = delete;
+ buffer_manager_t(buffer_manager_t&&) = delete;
+ buffer_manager_t& operator=(buffer_manager_t&&) = delete;
+ virtual ~buffer_manager_t() {}
+
+ virtual uint64_t getMmapedPhysAddr(uint64_t offset) const = 0;
+
+ virtual int alloc_buffer(int usage,
+ int width, int height, int format,
+ EmulatorFrameworkFormat emulatorFrameworkFormat,
+ int glFormat, int glType,
+ size_t bufferSize,
+ buffer_handle_t* pHandle) = 0;
+ virtual int free_buffer(buffer_handle_t h) = 0;
+ virtual int register_buffer(buffer_handle_t h) = 0;
+ virtual int unregister_buffer(buffer_handle_t h) = 0;
+};
+
+std::unique_ptr<buffer_manager_t> create_buffer_manager(goldfish_gralloc30_module_t*);
+
+class goldfish_gralloc30_module_t {
+public:
+ goldfish_gralloc30_module_t(): m_hostConn(HostConnection::createUnique()) {
+ CRASH_IF(!m_hostConn, "m_hostConn cannot be nullptr");
+ m_bufferManager = create_buffer_manager(this);
+ CRASH_IF(!m_bufferManager, "m_bufferManager cannot be nullptr");
+ }
+
+ HostConnectionSession getHostConnectionSession() const {
+ return HostConnectionSession(m_hostConn /*.get()*/);
+ }
+
+ int alloc_buffer(int usage,
+ int width, int height, int format,
+ EmulatorFrameworkFormat emulatorFrameworkFormat,
+ int glFormat, int glType,
+ size_t bufferSize,
+ buffer_handle_t* pHandle) {
+ return m_bufferManager->alloc_buffer(usage,
+ width, height, format,
+ emulatorFrameworkFormat,
+ glFormat, glType,
+ bufferSize,
+ pHandle);
+ }
+
+ int free_buffer(buffer_handle_t h) {
+ return m_bufferManager->free_buffer(h);
+ }
+
+ int register_buffer(buffer_handle_t h) {
+ return m_bufferManager->register_buffer(h);
+ }
+
+ int unregister_buffer(buffer_handle_t h) {
+ return m_bufferManager->unregister_buffer(h);
+ }
+
+ int lock(cb_handle_t& handle,
+ const int usage,
+ const int left, const int top, const int width, const int height,
+ void** vaddr) {
+ if (!handle.bufferSize) { RETURN_ERROR_CODE(-EINVAL); }
+ char* const bufferBits = static_cast<char*>(handle.getBufferPtr());
+ if (!bufferBits) { RETURN_ERROR_CODE(-EINVAL); }
+
+ if (handle.hostHandle) {
+ const int res = lock_impl(handle,
+ usage,
+ left, top, width, height,
+ bufferBits);
+ if (res) { return res; }
+ }
+
+ *vaddr = bufferBits;
+ return 0;
+ }
+
+ int unlock(cb_handle_t& handle) {
+ if (!handle.bufferSize) { RETURN_ERROR_CODE(-EINVAL); }
+
+ char* const bufferBits = static_cast<char*>(handle.getBufferPtr());
+ if (!bufferBits) { RETURN_ERROR_CODE(-EINVAL); }
+
+ if (handle.hostHandle) {
+ unlock_impl(handle, bufferBits);
+ }
+
+ return 0;
+ }
+
+ int lock_ycbcr(cb_handle_t& handle,
+ const int usage,
+ const int left, const int top, const int width, const int height,
+ android_ycbcr* ycbcr) {
+ if (!ycbcr) { RETURN_ERROR_CODE(-EINVAL); }
+ if (!handle.bufferSize) { RETURN_ERROR_CODE(-EINVAL); }
+ char* const bufferBits = static_cast<char*>(handle.getBufferPtr());
+ if (!bufferBits) { RETURN_ERROR_CODE(-EINVAL); }
+
+ size_t uOffset;
+ size_t vOffset;
+ size_t yStride;
+ size_t cStride;
+ size_t cStep;
+
+ switch (handle.format) {
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ yStride = handle.width;
+ cStride = yStride;
+ vOffset = yStride * handle.height;
+ uOffset = vOffset + 1;
+ cStep = 2;
+ break;
+
+ case HAL_PIXEL_FORMAT_YV12:
+ // https://developer.android.com/reference/android/graphics/ImageFormat.html#YV12
+ yStride = align(handle.width, 16);
+ cStride = align(yStride / 2, 16);
+ vOffset = yStride * handle.height;
+ uOffset = vOffset + (cStride * handle.height / 2);
+ cStep = 1;
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_420_888:
+ yStride = handle.width;
+ cStride = yStride / 2;
+ uOffset = handle.height * yStride;
+ vOffset = uOffset + cStride * handle.height / 2;
+ cStep = 1;
+ break;
+
+ default:
+ ALOGE("%s:%d unexpected format (%d)", __func__, __LINE__, handle.format);
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ if (handle.hostHandle) {
+ const int res = lock_impl(handle,
+ usage,
+ left, top, width, height,
+ bufferBits);
+ if (res) { return res; }
+ }
+
+ memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
+ char* const vaddr1 = static_cast<char*>(bufferBits);
+ ycbcr->y = vaddr1;
+ ycbcr->cb = vaddr1 + uOffset;
+ ycbcr->cr = vaddr1 + vOffset;
+ ycbcr->ystride = yStride;
+ ycbcr->cstride = cStride;
+ ycbcr->chroma_step = cStep;
+ return 0;
+ }
+
+private:
+ int lock_impl(cb_handle_t& handle,
+ const int usage,
+ const int left, const int top, const int width, const int height,
+ char* const bufferBits) {
+ const bool usageSwRead = usage & GRALLOC_USAGE_SW_READ_MASK;
+ const bool usageSwWrite = usage & GRALLOC_USAGE_SW_WRITE_MASK;
+ const bool usageHwCamera = usage & GRALLOC_USAGE_HW_CAMERA_MASK;
+ const bool usageHwCameraWrite = usage & GRALLOC_USAGE_HW_CAMERA_WRITE;
+
+ const HostConnectionSession conn = getHostConnectionSession();
+ ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
+
+ const int res = rcEnc->rcColorBufferCacheFlush(
+ rcEnc, handle.hostHandle, 0, usageSwRead);
+ if (res < 0) {
+ RETURN_ERROR_CODE(-EBUSY);
+ }
+
+ // camera delivers bits to the buffer directly and does not require
+ // an explicit read.
+ if (usageSwRead && !usageHwCamera) {
+ if (gralloc_is_yuv_format(handle.format)) {
+ if (rcEnc->hasYUVCache()) {
+ uint32_t bufferSize;
+
+ switch (handle.format) {
+ case HAL_PIXEL_FORMAT_YV12:
+ get_yv12_offsets(handle.width, handle.height,
+ nullptr, nullptr, &bufferSize);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_888:
+ get_yuv420p_offsets(handle.width, handle.height,
+ nullptr, nullptr, &bufferSize);
+ break;
+ default:
+ CRASH("Unexpected format, switch is out of sync with gralloc_is_yuv_format");
+ break;
+ }
+
+ rcEnc->rcReadColorBufferYUV(rcEnc, handle.hostHandle,
+ 0, 0, handle.width, handle.height,
+ bufferBits, bufferSize);
+ } else {
+ // We are using RGB888
+ std::vector<char> tmpBuf(handle.width * handle.height * 3);
+ rcEnc->rcReadColorBuffer(rcEnc, handle.hostHandle,
+ 0, 0, handle.width, handle.height,
+ handle.glFormat, handle.glType,
+ tmpBuf.data());
+
+ switch (handle.format) {
+ case HAL_PIXEL_FORMAT_YV12:
+ rgb888_to_yv12(bufferBits, tmpBuf.data(),
+ handle.width, handle.height,
+ left, top,
+ left + width - 1, top + height - 1);
+ break;
+ case HAL_PIXEL_FORMAT_YCbCr_420_888:
+ rgb888_to_yuv420p(bufferBits, tmpBuf.data(),
+ handle.width, handle.height,
+ left, top,
+ left + width - 1, top + height - 1);
+ break;
+ default:
+ CRASH("Unexpected format, switch is out of sync with gralloc_is_yuv_format");
+ break;
+ }
+ }
+ } else {
+ rcEnc->rcReadColorBuffer(rcEnc,
+ handle.hostHandle,
+ 0, 0, handle.width, handle.height,
+ handle.glFormat, handle.glType,
+ bufferBits);
+ }
+ }
+
+ if (usageSwWrite || usageHwCameraWrite) {
+ handle.lockedLeft = left;
+ handle.lockedTop = top;
+ handle.lockedWidth = width;
+ handle.lockedHeight = height;
+ } else {
+ handle.lockedLeft = 0;
+ handle.lockedTop = 0;
+ handle.lockedWidth = handle.width;
+ handle.lockedHeight = handle.height;
+ }
+
+ return 0;
+ }
+
+ void unlock_impl(cb_handle_t& handle, char* const bufferBits) {
+ const int bpp = glUtilsPixelBitSize(handle.glFormat, handle.glType) >> 3;
+ const int left = handle.lockedLeft;
+ const int top = handle.lockedTop;
+ const int width = handle.lockedWidth;
+ const int height = handle.lockedHeight;
+ const uint32_t rgbSize = width * height * bpp;
+
+ std::vector<char> convertedBuf;
+ const char* bitsToSend;
+ uint32_t sizeToSend;
+ if (gralloc_is_yuv_format(handle.format)) {
+ bitsToSend = bufferBits;
+ switch (handle.format) {
+ case HAL_PIXEL_FORMAT_YV12:
+ get_yv12_offsets(width, height, nullptr, nullptr, &sizeToSend);
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_420_888:
+ get_yuv420p_offsets(width, height, nullptr, nullptr, &sizeToSend);
+ break;
+
+ default:
+ CRASH("Unexpected format, switch is out of sync with gralloc_is_yuv_format");
+ break;
+ }
+ } else {
+ convertedBuf.resize(rgbSize);
+ copy_rgb_buffer_from_unlocked(
+ convertedBuf.data(), bufferBits,
+ handle.width,
+ width, height, top, left, bpp);
+ bitsToSend = convertedBuf.data();
+ sizeToSend = rgbSize;
+ }
+
+ {
+ const HostConnectionSession conn = getHostConnectionSession();
+ ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
+
+ rcEnc->bindDmaDirectly(bufferBits,
+ m_bufferManager->getMmapedPhysAddr(handle.getMmapedOffset()));
+ rcEnc->rcUpdateColorBufferDMA(rcEnc, handle.hostHandle,
+ left, top, width, height,
+ handle.glFormat, handle.glType,
+ const_cast<char*>(bitsToSend), sizeToSend);
+ }
+
+ handle.lockedLeft = 0;
+ handle.lockedTop = 0;
+ handle.lockedWidth = 0;
+ handle.lockedHeight = 0;
+ }
+
+ //std::unique_ptr<HostConnection> m_hostConn; // b/142677230
+ HostConnection* m_hostConn;
+ std::unique_ptr<buffer_manager_t> m_bufferManager;
+};
+
+// no ctor/dctor here
+struct private_module_t {
+ goldfish_gralloc30_module_t* impl() {
+ return &gralloc30;
+ }
+
+ hw_module_t* to_hw_module() { return &base.common; }
+
+ static private_module_t* from_hw_module(const hw_module_t* m) {
+ if (!m) {
+ RETURN_ERROR(nullptr);
+ }
+
+ if ((m->id == GRALLOC_HARDWARE_MODULE_ID) && (m->name == GOLDFISH_GRALLOC_MODULE_NAME)) {
+ return reinterpret_cast<private_module_t*>(const_cast<hw_module_t*>(m));
+ } else {
+ RETURN_ERROR(nullptr);
+ }
+ }
+
+ static private_module_t* from_gralloc_module(const gralloc_module_t* m) {
+ if (!m) {
+ RETURN_ERROR(nullptr);
+ }
+
+ return from_hw_module(&m->common);
+ }
+
+ gralloc_module_t base;
+ goldfish_gralloc30_module_t gralloc30;
+};
+
+class goldfish_gralloc30_device_t {
+ alloc_device_t device;
+ goldfish_gralloc30_module_t* gralloc_module;
+
+public:
+ goldfish_gralloc30_device_t(private_module_t* module)
+ : gralloc_module(module->impl()) {
+ memset(&device, 0, sizeof(device));
+ device.common = make_hw_device(module->to_hw_module(),
+ &s_goldfish_gralloc30_device_close);
+ device.alloc = &s_gralloc_alloc;
+ device.free = &s_gralloc_free;
+ }
+
+ hw_device_t* get_hw_device_ptr() { return &device.common; }
+
+private:
+ static int get_buffer_format(const int frameworkFormat, const int usage) {
+ if (frameworkFormat == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+ if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
+ if (usage & GRALLOC_USAGE_HW_TEXTURE) {
+ // Camera-to-display is RGBA
+ return HAL_PIXEL_FORMAT_RGBA_8888;
+ } else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
+ // Camera-to-encoder is NV21
+ return HAL_PIXEL_FORMAT_YCrCb_420_SP;
+ }
+ }
+
+ RETURN_ERROR_CODE(-EINVAL);
+ } else {
+ return frameworkFormat;
+ }
+ }
+
+ int gralloc_alloc(const int width, const int height,
+ const int frameworkFormat,
+ const int usage,
+ buffer_handle_t* pHandle,
+ int* pStride) {
+ const bool usageSwWrite = usage & GRALLOC_USAGE_SW_WRITE_MASK;
+ const bool usageSwRead = usage & GRALLOC_USAGE_SW_READ_MASK;
+ const bool usageHwTexture = usage & GRALLOC_USAGE_HW_TEXTURE;
+ const bool usageHwRender = usage & GRALLOC_USAGE_HW_RENDER;
+ const bool usageHw2d = usage & GRALLOC_USAGE_HW_2D;
+ const bool usageHwComposer = usage & GRALLOC_USAGE_HW_COMPOSER;
+ const bool usageHwFb = usage & GRALLOC_USAGE_HW_FB;
+ const bool usageHwCamWrite = usage & GRALLOC_USAGE_HW_CAMERA_WRITE;
+ const bool usageHwCamRead = usage & GRALLOC_USAGE_HW_CAMERA_READ;
+ const bool usageRGB888Unsupported = usageHwTexture
+ || usageHwRender ||usageHw2d || usageHwComposer || usageHwFb;
+
+ int bpp = 1;
+ int glFormat = 0;
+ int glType = 0;
+ int align = 1;
+ bool yuv_format = false;
+ EmulatorFrameworkFormat emulatorFrameworkFormat = FRAMEWORK_FORMAT_GL_COMPATIBLE;
+
+ const int format = get_buffer_format(frameworkFormat, usage);
+ if (format < 0) {
+ ALOGE("%s:%d Unsupported format: frameworkFormat=%d, usage=%x",
+ __func__, __LINE__, frameworkFormat, usage);
+ return format;
+ }
+
+ switch (format) {
+ case HAL_PIXEL_FORMAT_RGBA_8888:
+ case HAL_PIXEL_FORMAT_RGBX_8888:
+ case HAL_PIXEL_FORMAT_BGRA_8888:
+ bpp = 4;
+ glFormat = GL_RGBA;
+ glType = GL_UNSIGNED_BYTE;
+ break;
+
+ case HAL_PIXEL_FORMAT_RGB_888:
+ if (usageRGB888Unsupported) {
+ RETURN_ERROR_CODE(-EINVAL); // we dont support RGB_888 for HW usage
+ } else {
+ bpp = 3;
+ glFormat = GL_RGB;
+ glType = GL_UNSIGNED_BYTE;
+ }
+ break;
+
+ case HAL_PIXEL_FORMAT_RGB_565:
+ bpp = 2;
+ glFormat = GL_RGB565;
+ glType = GL_UNSIGNED_SHORT_5_6_5;
+ break;
+
+ case HAL_PIXEL_FORMAT_RGBA_FP16:
+ bpp = 8;
+ glFormat = GL_RGBA16F;
+ glType = GL_HALF_FLOAT;
+ break;
+
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
+ bpp = 4;
+ glFormat = GL_RGB10_A2;
+ glType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ break;
+
+ case HAL_PIXEL_FORMAT_RAW16:
+ case HAL_PIXEL_FORMAT_Y16:
+ bpp = 2;
+ align = 16 * bpp;
+ if (!((usageSwRead || usageHwCamRead) && (usageSwWrite || usageHwCamWrite))) {
+ // Raw sensor data or Y16 only goes between camera and CPU
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+ // Not expecting to actually create any GL surfaces for this
+ glFormat = GL_LUMINANCE;
+ glType = GL_UNSIGNED_SHORT;
+ break;
+
+ case HAL_PIXEL_FORMAT_BLOB:
+ if (!usageSwRead) {
+ // Blob data cannot be used by HW other than camera emulator
+ // But there is a CTS test trying to have access to it
+ // BUG: https://buganizer.corp.google.com/issues/37719518
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+ // Not expecting to actually create any GL surfaces for this
+ glFormat = GL_LUMINANCE;
+ glType = GL_UNSIGNED_BYTE;
+ break;
+
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ yuv_format = true;
+ // Not expecting to actually create any GL surfaces for this
+ break;
+
+ case HAL_PIXEL_FORMAT_YV12:
+ align = 16;
+ yuv_format = true;
+ // We are going to use RGB8888 on the host for Vulkan
+ glFormat = GL_RGBA;
+ glType = GL_UNSIGNED_BYTE;
+ emulatorFrameworkFormat = FRAMEWORK_FORMAT_YV12;
+ break;
+
+ case HAL_PIXEL_FORMAT_YCbCr_420_888:
+ yuv_format = true;
+ // We are going to use RGB888 on the host
+ glFormat = GL_RGB;
+ glType = GL_UNSIGNED_BYTE;
+ emulatorFrameworkFormat = FRAMEWORK_FORMAT_YUV_420_888;
+ break;
+
+ default:
+ ALOGE("%s:%d Unsupported format: format=%d, frameworkFormat=%d, usage=%x",
+ __func__, __LINE__, format, frameworkFormat, usage);
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ const size_t align1 = align - 1;
+ int stride;
+ size_t bufferSize;
+
+ if (yuv_format) {
+ const size_t yStride = (width * bpp + align1) & ~align1;
+ const size_t uvStride = (yStride / 2 + align1) & ~align1;
+ const size_t uvHeight = height / 2;
+ bufferSize = yStride * height + 2 * (uvHeight * uvStride);
+ stride = yStride / bpp;
+ } else {
+ const size_t bpr = (width * bpp + align1) & ~align1;
+ bufferSize = bpr * height;
+ stride = bpr / bpp;
+ }
+
+ const int res = gralloc_module->alloc_buffer(
+ usage,
+ width, height, format,
+ emulatorFrameworkFormat,
+ glFormat, glType,
+ bufferSize,
+ pHandle);
+ if (res) {
+ return res;
+ }
+
+ *pStride = stride;
+ return 0;
+ }
+
+ int gralloc_free(buffer_handle_t h) {
+ return gralloc_module->free_buffer(h);
+ }
+
+ static int s_goldfish_gralloc30_device_close(hw_device_t* d) {
+ goldfish_gralloc30_device_t* gd = from_hw_device(d);
+ if (!gd) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ std::unique_ptr<goldfish_gralloc30_device_t> deleter(gd);
+ return 0;
+ }
+
+ static int s_gralloc_alloc(alloc_device_t* ad,
+ int w, int h, int format, int usage,
+ buffer_handle_t* pHandle, int* pStride) {
+ goldfish_gralloc30_device_t* gd = from_alloc_device(ad);
+ if (!gd) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ return gd->gralloc_alloc(w, h, format, usage, pHandle, pStride);
+ }
+
+ static int s_gralloc_free(alloc_device_t* ad, buffer_handle_t h) {
+ goldfish_gralloc30_device_t* gd = from_alloc_device(ad);
+ if (!gd) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ return gd->gralloc_free(h);
+ }
+
+ static goldfish_gralloc30_device_t* from_hw_device(hw_device_t* d) {
+ if (!d) {
+ RETURN_ERROR(nullptr);
+ }
+
+ if (d->close == &s_goldfish_gralloc30_device_close) {
+ return reinterpret_cast<goldfish_gralloc30_device_t*>(d);
+ } else {
+ RETURN_ERROR(nullptr);
+ }
+ }
+
+ static goldfish_gralloc30_device_t* from_alloc_device(alloc_device_t* d) {
+ if (!d) {
+ RETURN_ERROR(nullptr);
+ }
+
+ return from_hw_device(&d->common);
+ }
+};
+
+template <class T> T& unconst(const T& x) { return const_cast<T&>(x); }
+
+const uint32_t CB_HANDLE_MAGIC_30 = CB_HANDLE_MAGIC_BASE | 0x2;
+
+struct cb_handle_30_t : public cb_handle_t {
+ cb_handle_30_t(address_space_handle_t p_bufferFd,
+ QEMU_PIPE_HANDLE p_hostHandleRefCountFd,
+ uint32_t p_hostHandle,
+ int32_t p_usage,
+ int32_t p_width,
+ int32_t p_height,
+ int32_t p_format,
+ int32_t p_glFormat,
+ int32_t p_glType,
+ uint32_t p_bufSize,
+ void* p_bufPtr,
+ int32_t p_bufferPtrPid,
+ uint32_t p_mmapedSize,
+ uint64_t p_mmapedOffset)
+ : cb_handle_t(p_bufferFd,
+ p_hostHandleRefCountFd,
+ CB_HANDLE_MAGIC_30,
+ p_hostHandle,
+ p_usage,
+ p_width,
+ p_height,
+ p_format,
+ p_glFormat,
+ p_glType,
+ p_bufSize,
+ p_bufPtr,
+ p_mmapedOffset),
+ bufferFdAsInt(p_bufferFd),
+ bufferPtrPid(p_bufferPtrPid),
+ mmapedSize(p_mmapedSize) {
+ numInts = CB_HANDLE_NUM_INTS(numFds);
+ }
+
+ bool isValid() const { return (version == sizeof(native_handle_t)) && (magic == CB_HANDLE_MAGIC_30); }
+
+ static cb_handle_30_t* from(void* p) {
+ if (!p) { return nullptr; }
+ cb_handle_30_t* cb = static_cast<cb_handle_30_t*>(p);
+ return cb->isValid() ? cb : nullptr;
+ }
+
+ static const cb_handle_30_t* from(const void* p) {
+ return from(const_cast<void*>(p));
+ }
+
+ static cb_handle_30_t* from_unconst(const void* p) {
+ return from(const_cast<void*>(p));
+ }
+
+ int32_t bufferFdAsInt; // int copy of bufferFd, to check if fd was duped
+ int32_t bufferPtrPid; // pid where bufferPtr belongs to
+ uint32_t mmapedSize; // real allocation side
+};
+
+// goldfish_address_space_host_malloc_handle_manager_t uses
+// GoldfishAddressSpaceHostMemoryAllocator and GoldfishAddressSpaceBlock
+// to allocate buffers on the host.
+// It keeps track of usage of host handles allocated by rcCreateColorBufferDMA
+// on the guest by qemu_pipe_open("refcount").
+class goldfish_address_space_host_malloc_buffer_manager_t : public buffer_manager_t {
+public:
+ goldfish_address_space_host_malloc_buffer_manager_t(goldfish_gralloc30_module_t* gr): m_gr(gr) {
+ GoldfishAddressSpaceHostMemoryAllocator host_memory_allocator;
+ CRASH_IF(!host_memory_allocator.is_opened(),
+ "GoldfishAddressSpaceHostMemoryAllocator failed to open");
+
+ GoldfishAddressSpaceBlock bufferBits;
+ CRASH_IF(host_memory_allocator.hostMalloc(&bufferBits, 256),
+ "hostMalloc failed");
+
+ m_physAddrToOffset = bufferBits.physAddr() - bufferBits.offset();
+ }
+
+ uint64_t getMmapedPhysAddr(uint64_t offset) const override {
+ return m_physAddrToOffset + offset;
+ }
+
+ int alloc_buffer(int usage,
+ int width, int height, int format,
+ EmulatorFrameworkFormat emulatorFrameworkFormat,
+ int glFormat, int glType,
+ size_t bufferSize,
+ buffer_handle_t* pHandle) override {
+ GoldfishAddressSpaceHostMemoryAllocator host_memory_allocator;
+ if (!host_memory_allocator.is_opened()) { RETURN_ERROR_CODE(-EIO); }
+
+ GoldfishAddressSpaceBlock bufferBits;
+ if (host_memory_allocator.hostMalloc(&bufferBits, bufferSize)) { RETURN_ERROR_CODE(-EIO); }
+
+ uint32_t hostHandle = 0;
+ QEMU_PIPE_HANDLE hostHandleRefCountFd = QEMU_PIPE_INVALID_HANDLE;
+ if (need_host_cb(usage, format)) {
+ hostHandleRefCountFd = qemu_pipe_open("refcount");
+ if (!qemu_pipe_valid(hostHandleRefCountFd)) { RETURN_ERROR_CODE(-EIO); }
+
+ const GLenum allocFormat =
+ (HAL_PIXEL_FORMAT_RGBX_8888 == format) ? GL_RGB : glFormat;
+
+ const HostConnectionSession conn = m_gr->getHostConnectionSession();
+ ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
+
+ hostHandle = rcEnc->rcCreateColorBufferDMA(
+ rcEnc,
+ width, height,
+ allocFormat, emulatorFrameworkFormat);
+ if (!hostHandle) {
+ qemu_pipe_close(hostHandleRefCountFd);
+ RETURN_ERROR_CODE(-EIO);
+ }
+ if (qemu_pipe_write(hostHandleRefCountFd, &hostHandle, sizeof(hostHandle)) != sizeof(hostHandle)) {
+ rcEnc->rcCloseColorBuffer(rcEnc, hostHandle);
+ qemu_pipe_close(hostHandleRefCountFd);
+ RETURN_ERROR_CODE(-EIO);
+ }
+ }
+
+ std::unique_ptr<cb_handle_30_t> handle =
+ std::make_unique<cb_handle_30_t>(
+ host_memory_allocator.release(), hostHandleRefCountFd,
+ hostHandle,
+ usage, width, height,
+ format, glFormat, glType,
+ bufferSize, bufferBits.guestPtr(), getpid(),
+ bufferBits.size(), bufferBits.offset());
+ bufferBits.release();
+
+ *pHandle = handle.release();
+ return 0;
+ }
+
+ int free_buffer(buffer_handle_t h) override {
+ std::unique_ptr<cb_handle_30_t> handle(cb_handle_30_t::from_unconst(h));
+ if (!handle) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ if (handle->bufferPtrPid != getpid()) { RETURN_ERROR_CODE(-EACCES); }
+ if (handle->bufferFd != handle->bufferFdAsInt) { RETURN_ERROR_CODE(-EACCES); }
+
+ if (qemu_pipe_valid(handle->hostHandleRefCountFd)) {
+ qemu_pipe_close(handle->hostHandleRefCountFd);
+ }
+ // We can't recycle the address block and host resources because this
+ // fd could be duped. The kernel will take care of it when the last fd
+ // will be closed.
+ if (handle->mmapedSize > 0) {
+ GoldfishAddressSpaceBlock::memoryUnmap(handle->getBufferPtr(), handle->mmapedSize);
+ }
+ GoldfishAddressSpaceHostMemoryAllocator::closeHandle(handle->bufferFd);
+
+ return 0;
+ }
+
+ int register_buffer(buffer_handle_t h) override {
+#ifndef HOST_BUILD
+ cb_handle_30_t *handle = cb_handle_30_t::from_unconst(h);
+ if (!handle) { RETURN_ERROR_CODE(-EINVAL); }
+
+ if (handle->mmapedSize > 0) {
+ void* ptr;
+ const int res = GoldfishAddressSpaceBlock::memoryMap(
+ handle->getBufferPtr(),
+ handle->mmapedSize,
+ handle->bufferFd,
+ handle->getMmapedOffset(),
+ &ptr);
+ if (res) {
+ RETURN_ERROR_CODE(-res);
+ }
+
+ handle->setBufferPtr(ptr);
+ }
+ if (handle->hostHandle) {
+ const HostConnectionSession conn = m_gr->getHostConnectionSession();
+ ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
+ rcEnc->rcOpenColorBuffer2(rcEnc, handle->hostHandle);
+ }
+
+ handle->bufferFdAsInt = handle->bufferFd;
+ handle->bufferPtrPid = getpid();
+#endif // HOST_BUILD
+
+ return 0;
+ }
+
+ int unregister_buffer(buffer_handle_t h) override {
+#ifndef HOST_BUILD
+ cb_handle_30_t *handle = cb_handle_30_t::from_unconst(h);
+ if (!handle) { RETURN_ERROR_CODE(-EINVAL); }
+
+ if (handle->bufferPtrPid != getpid()) { RETURN_ERROR_CODE(-EACCES); }
+ if (handle->bufferFd != handle->bufferFdAsInt) { RETURN_ERROR_CODE(-EACCES); }
+
+ if (handle->hostHandle) {
+ const HostConnectionSession conn = m_gr->getHostConnectionSession();
+ ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
+ rcEnc->rcCloseColorBuffer(rcEnc, handle->hostHandle);
+ }
+ if (handle->mmapedSize > 0) {
+ GoldfishAddressSpaceBlock::memoryUnmap(handle->getBufferPtr(), handle->mmapedSize);
+ }
+
+ handle->bufferFdAsInt = -1;
+ handle->bufferPtrPid = -1;
+#endif // HOST_BUILD
+ return 0;
+ }
+
+ static bool need_host_cb(const int usage, const int format) {
+ return ((usage & GOLDFISH_GRALLOC_USAGE_GPU_DATA_BUFFER)
+ || (format != HAL_PIXEL_FORMAT_BLOB &&
+ format != HAL_PIXEL_FORMAT_RAW16 &&
+ format != HAL_PIXEL_FORMAT_Y16))
+ && (usage & (GRALLOC_USAGE_HW_TEXTURE
+ | GRALLOC_USAGE_HW_RENDER
+ | GRALLOC_USAGE_HW_2D
+ | GRALLOC_USAGE_HW_COMPOSER
+ | GRALLOC_USAGE_HW_VIDEO_ENCODER
+ | GRALLOC_USAGE_HW_FB
+ | GRALLOC_USAGE_SW_READ_MASK));
+ }
+
+private:
+ goldfish_gralloc30_module_t* m_gr;
+ uint64_t m_physAddrToOffset;
+};
+
+std::unique_ptr<buffer_manager_t> create_buffer_manager(goldfish_gralloc30_module_t* gr) {
+ if (!gr) {
+ RETURN_ERROR(nullptr);
+ }
+
+ // TODO: negotiate with the host the best way to allocate memory.
+
+ return std::make_unique<goldfish_address_space_host_malloc_buffer_manager_t>(gr);
+}
+
+int gralloc_register_buffer(const gralloc_module_t* gralloc_module, buffer_handle_t h) {
+ private_module_t* module = private_module_t::from_gralloc_module(gralloc_module);
+ if (!module) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ return module->impl()->register_buffer(h);
+}
+
+int gralloc_unregister_buffer(const gralloc_module_t* gralloc_module, buffer_handle_t h) {
+ private_module_t* module = private_module_t::from_gralloc_module(gralloc_module);
+ if (!module) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ return module->impl()->unregister_buffer(h);
+}
+
+int gralloc_lock(const gralloc_module_t* gralloc_module,
+ buffer_handle_t bh, int usage,
+ int l, int t, int w, int h,
+ void** vaddr) {
+ private_module_t* module = private_module_t::from_gralloc_module(gralloc_module);
+ if (!module) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ cb_handle_t* handle = cb_handle_t::from_unconst(bh);
+ if (!handle) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ return module->impl()->lock(*handle, usage, l, t, w, h, vaddr);
+}
+
+int gralloc_unlock(const gralloc_module_t* gralloc_module, buffer_handle_t bh) {
+ private_module_t* module = private_module_t::from_gralloc_module(gralloc_module);
+ if (!module) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ cb_handle_t* handle = cb_handle_t::from_unconst(bh);
+ if (!handle) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ return module->impl()->unlock(*handle);
+}
+
+int gralloc_lock_ycbcr(const gralloc_module_t* gralloc_module,
+ buffer_handle_t bh, int usage,
+ int l, int t, int w, int h,
+ android_ycbcr *ycbcr) {
+ private_module_t* module = private_module_t::from_gralloc_module(gralloc_module);
+ if (!module) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ cb_handle_t* handle = cb_handle_t::from_unconst(bh);
+ if (!handle) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ return module->impl()->lock_ycbcr(*handle, usage, l, t, w, h, ycbcr);
+}
+
+int gralloc_device_open_gpu0(private_module_t* module, hw_device_t** device) {
+ std::unique_ptr<goldfish_gralloc30_device_t> gralloc_device =
+ std::make_unique<goldfish_gralloc30_device_t>(module);
+ if (!gralloc_device) {
+ RETURN_ERROR_CODE(-ENOMEM);
+ }
+
+ *device = gralloc_device->get_hw_device_ptr();
+ gralloc_device.release();
+ return 0;
+}
+
+int gralloc_device_open(const hw_module_t* hw_module,
+ const char* name,
+ hw_device_t** device) {
+ private_module_t* module = private_module_t::from_hw_module(hw_module);
+ if (!module) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+ if (!name) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+ if (!device) {
+ RETURN_ERROR_CODE(-EINVAL);
+ }
+
+ if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
+ return gralloc_device_open_gpu0(module, device);
+ }
+
+ RETURN_ERROR_CODE(-EINVAL);
+}
+
+struct hw_module_methods_t gralloc_module_methods = {
+ .open = &gralloc_device_open
+};
+} // namespace
+
+extern "C" __attribute__((visibility("default")))
+struct private_module_t HAL_MODULE_INFO_SYM = {
+ .base = {
+ .common = {
+ .tag = HARDWARE_MODULE_TAG,
+ .module_api_version = GRALLOC_MODULE_API_VERSION_0_2,
+ .hal_api_version = 0,
+ .id = GRALLOC_HARDWARE_MODULE_ID,
+ .name = GOLDFISH_GRALLOC_MODULE_NAME,
+ .author = "The Android Open Source Project",
+ .methods = &gralloc_module_methods,
+ .dso = nullptr,
+ .reserved = {0}
+ },
+ .registerBuffer = &gralloc_register_buffer,
+ .unregisterBuffer = &gralloc_unregister_buffer,
+ .lock = &gralloc_lock,
+ .unlock = &gralloc_unlock,
+ .perform = nullptr, /* reserved for future use */
+ .lock_ycbcr = &gralloc_lock_ycbcr,
+ },
+};
diff --git a/system/gralloc/gralloc_old.cpp b/system/gralloc/gralloc_old.cpp
index 6ab38a2..499c113 100644
--- a/system/gralloc/gralloc_old.cpp
+++ b/system/gralloc/gralloc_old.cpp
@@ -1,4 +1,4 @@
- /*
+/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
#include <string.h>
#include <pthread.h>
#include <limits.h>
@@ -100,7 +99,8 @@
p_glFormat,
p_glType,
p_ashmemSize,
- nullptr),
+ NULL,
+ ~uint64_t(0)),
ashmemBasePid(0),
mappedPid(0) {
numInts = CB_HANDLE_NUM_INTS(numFds);
@@ -127,9 +127,9 @@
}
static cb_handle_old_t* from(void* p) {
- if (!p) { return nullptr; }
+ if (!p) { return NULL; }
cb_handle_old_t* cb = static_cast<cb_handle_old_t*>(p);
- return cb->isValid() ? cb : nullptr;
+ return cb->isValid() ? cb : NULL;
}
static const cb_handle_old_t* from(const void* p) {
@@ -419,13 +419,6 @@
return should_unmap;
}
-//
-// Our framebuffer device structure
-//
-struct fb_device_t {
- framebuffer_device_t device;
-};
-
static int map_buffer(cb_handle_old_t *cb, void **vaddr)
{
if (cb->bufferFd < 0) {
@@ -650,6 +643,7 @@
#endif // PLATFORM_SDK_VERSION
bool yuv_format = false;
+ bool raw_format = false;
int ashmem_size = 0;
int stride = w;
@@ -711,6 +705,7 @@
// Not expecting to actually create any GL surfaces for this
glFormat = GL_LUMINANCE;
glType = GL_UNSIGNED_SHORT;
+ raw_format = true;
break;
#if PLATFORM_SDK_VERSION >= 17
case HAL_PIXEL_FORMAT_BLOB:
@@ -771,6 +766,7 @@
#endif // !(PLATFORM_SDK_VERSION >= 17)
frameworkFormat == HAL_PIXEL_FORMAT_YV12 ||
frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) &&
+ !raw_format &&
#if PLATFORM_SDK_VERSION >= 15
(usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER |
GRALLOC_USAGE_HW_2D | GRALLOC_USAGE_HW_COMPOSER |
@@ -998,107 +994,6 @@
return 0;
}
-static int fb_compositionComplete(struct framebuffer_device_t* dev)
-{
- (void)dev;
-
- return 0;
-}
-
-//
-// Framebuffer device functions
-//
-static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
-{
- fb_device_t *fbdev = (fb_device_t *)dev;
- if (!fbdev) {
- return -EINVAL;
- }
- const cb_handle_old_t *cb = cb_handle_old_t::from(buffer);
- if (!cb) {
- return -EINVAL;
- }
- if (!cb->canBePosted()) {
- return -EINVAL;
- }
-
- // Make sure we have host connection
- DEFINE_AND_VALIDATE_HOST_CONNECTION;
-
- // increment the post count of the buffer
- int32_t *postCountPtr = (int32_t *)cb->getBufferPtr();
- if (!postCountPtr) {
- // This should not happen
- return -EINVAL;
- }
- (*postCountPtr)++;
-
- // send post request to host
- hostCon->lock();
- rcEnc->rcFBPost(rcEnc, cb->hostHandle);
- hostCon->flush();
- hostCon->unlock();
-
- return 0;
-}
-
-/* unused (for now)
-static int fb_setUpdateRect(struct framebuffer_device_t* dev,
- int l, int t, int w, int h)
-{
- fb_device_t *fbdev = (fb_device_t *)dev;
-
- (void)l;
- (void)t;
- (void)w;
- (void)h;
-
- if (!fbdev) {
- return -EINVAL;
- }
-
- // Make sure we have host connection
- DEFINE_AND_VALIDATE_HOST_CONNECTION;
-
- // send request to host
- // TODO: XXX - should be implemented
- //rcEnc->rc_XXX
-
- return 0;
-}
-*/
-
-static int fb_setSwapInterval(struct framebuffer_device_t* dev,
- int interval)
-{
- fb_device_t *fbdev = (fb_device_t *)dev;
-
- if (!fbdev) {
- return -EINVAL;
- }
-
- // Make sure we have host connection
- DEFINE_AND_VALIDATE_HOST_CONNECTION;
-
- // send request to host
- hostCon->lock();
- rcEnc->rcFBSetSwapInterval(rcEnc, interval);
- hostCon->flush();
- hostCon->unlock();
-
- return 0;
-}
-
-static int fb_close(struct hw_device_t *dev)
-{
- fb_device_t *fbdev = (fb_device_t *)dev;
-
- free(fbdev);
-
- return 0;
-}
-
-
//
// gralloc module functions - refcount + locking interface
//
@@ -1595,67 +1490,6 @@
*device = &dev->device.common;
status = 0;
}
- else if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
-
- // return error if connection with host can not be established
- DEFINE_AND_VALIDATE_HOST_CONNECTION;
- hostCon->lock();
-
- //
- // Query the host for Framebuffer attributes
- //
- D("gralloc: query Frabuffer attribs\n");
- EGLint width = rcEnc->rcGetFBParam(rcEnc, FB_WIDTH);
- D("gralloc: width=%d\n", width);
- EGLint height = rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT);
- D("gralloc: height=%d\n", height);
- EGLint xdpi = rcEnc->rcGetFBParam(rcEnc, FB_XDPI);
- D("gralloc: xdpi=%d\n", xdpi);
- EGLint ydpi = rcEnc->rcGetFBParam(rcEnc, FB_YDPI);
- D("gralloc: ydpi=%d\n", ydpi);
- EGLint fps = rcEnc->rcGetFBParam(rcEnc, FB_FPS);
- D("gralloc: fps=%d\n", fps);
- EGLint min_si = rcEnc->rcGetFBParam(rcEnc, FB_MIN_SWAP_INTERVAL);
- D("gralloc: min_swap=%d\n", min_si);
- EGLint max_si = rcEnc->rcGetFBParam(rcEnc, FB_MAX_SWAP_INTERVAL);
- D("gralloc: max_swap=%d\n", max_si);
- hostCon->unlock();
-
- //
- // Allocate memory for the framebuffer device
- //
- fb_device_t *dev;
- dev = (fb_device_t*)malloc(sizeof(fb_device_t));
- if (NULL == dev) {
- return -ENOMEM;
- }
- memset(dev, 0, sizeof(fb_device_t));
-
- // Initialize our device structure
- //
- dev->device.common.tag = HARDWARE_DEVICE_TAG;
- dev->device.common.version = 0;
- dev->device.common.module = const_cast<hw_module_t*>(module);
- dev->device.common.close = fb_close;
- dev->device.setSwapInterval = fb_setSwapInterval;
- dev->device.post = fb_post;
- dev->device.setUpdateRect = 0; //fb_setUpdateRect;
- dev->device.compositionComplete = fb_compositionComplete; //XXX: this is a dummy
-
- const_cast<uint32_t&>(dev->device.flags) = 0;
- const_cast<uint32_t&>(dev->device.width) = width;
- const_cast<uint32_t&>(dev->device.height) = height;
- const_cast<int&>(dev->device.stride) = width;
- const_cast<int&>(dev->device.format) = HAL_PIXEL_FORMAT_RGBA_8888;
- const_cast<float&>(dev->device.xdpi) = xdpi;
- const_cast<float&>(dev->device.ydpi) = ydpi;
- const_cast<float&>(dev->device.fps) = fps;
- const_cast<int&>(dev->device.minSwapInterval) = min_si;
- const_cast<int&>(dev->device.maxSwapInterval) = max_si;
- *device = &dev->device.common;
-
- status = 0;
- }
return status;
}
@@ -1693,13 +1527,13 @@
lock: gralloc_lock,
unlock: gralloc_unlock,
perform: NULL,
-#if PLATFORM_SDK_VERSION >= 29 // For Q and later
- validateBufferSize: NULL,
- getTransportSize: NULL,
-#endif // PLATFORM_SDK_VERSION >= 29
#if PLATFORM_SDK_VERSION >= 18
lock_ycbcr: gralloc_lock_ycbcr,
#endif // PLATFORM_SDK_VERSION >= 18
+#if PLATFORM_SDK_VERSION >= 29 // For Q and later
+ getTransportSize: NULL,
+ validateBufferSize: NULL,
+#endif // PLATFORM_SDK_VERSION >= 29
}
};
@@ -1728,13 +1562,39 @@
char prop[PROPERTY_VALUE_MAX];
void* module;
+ // cuttlefish case: no fallback (if we use sw rendering,
+ // we are not using this lib anyway (would use minigbm))
+ property_get("ro.boot.hardware", prop, "");
+
+ bool isValid = prop[0] != '\0';
+
+ if (isValid && !strcmp(prop, "cutf_cvm")) {
+ return;
+ }
+
// qemu.gles=0 -> no GLES 2.x support (only 1.x through software).
// qemu.gles=1 -> host-side GPU emulation through EmuGL
// qemu.gles=2 -> guest-side GPU emulation.
- property_get("ro.kernel.qemu.gles", prop, "0");
- if (atoi(prop) == 1) {
- return;
+ property_get("ro.kernel.qemu.gles", prop, "999");
+
+ bool useFallback = false;
+ switch (atoi(prop)) {
+ case 0:
+ useFallback = true;
+ break;
+ case 1:
+ useFallback = false;
+ break;
+ case 2:
+ useFallback = true;
+ break;
+ default:
+ useFallback = false;
+ break;
}
+
+ if (!useFallback) return;
+
ALOGD("Emulator without host-side GPU emulation detected. "
"Loading gralloc.default.so from %s...",
kGrallocDefaultVendorPath);
diff --git a/system/hals/Android.mk b/system/hals/Android.mk
new file mode 100644
index 0000000..912a362
--- /dev/null
+++ b/system/hals/Android.mk
@@ -0,0 +1,74 @@
+#
+# Copyright 2015 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := android.hardware.graphics.allocator@3.0-service
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := allocator3.cpp
+LOCAL_INIT_RC := android.hardware.graphics.allocator@3.0-service.rc
+
+LOCAL_SHARED_LIBRARIES += \
+ android.hardware.graphics.allocator@3.0 \
+ android.hardware.graphics.mapper@3.0 \
+ libOpenglSystemCommon \
+ libOpenglCodecCommon$(GOLDFISH_OPENGL_LIB_SUFFIX) \
+ libbase \
+ libcutils \
+ libhidlbase \
+ liblog \
+ libutils
+
+LOCAL_C_INCLUDES += \
+ device/generic/goldfish-opengl/system/include \
+ device/generic/goldfish-opengl/system/OpenglSystemCommon \
+ device/generic/goldfish-opengl/shared/OpenglCodecCommon \
+ device/generic/goldfish-opengl/host/include/libOpenglRender \
+ device/generic/goldfish-opengl/system/renderControl_enc \
+
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := android.hardware.graphics.mapper@3.0-impl
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_VENDOR_MODULE := true
+LOCAL_SRC_FILES := mapper3.cpp
+
+# android.hardware.graphics.allocator@3.0 \
+
+LOCAL_SHARED_LIBRARIES += \
+ android.hardware.graphics.mapper@3.0 \
+ libOpenglSystemCommon \
+ libOpenglCodecCommon$(GOLDFISH_OPENGL_LIB_SUFFIX) \
+ libbase \
+ libcutils \
+ libhidlbase \
+ liblog \
+ libutils \
+ libsync
+
+LOCAL_C_INCLUDES += \
+ device/generic/goldfish-opengl/system/include \
+ device/generic/goldfish-opengl/system/OpenglSystemCommon \
+ device/generic/goldfish-opengl/shared/OpenglCodecCommon \
+ device/generic/goldfish-opengl/host/include/libOpenglRender \
+ device/generic/goldfish-opengl/system/renderControl_enc \
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/system/hals/allocator3.cpp b/system/hals/allocator3.cpp
new file mode 100644
index 0000000..e5e182d
--- /dev/null
+++ b/system/hals/allocator3.cpp
@@ -0,0 +1,425 @@
+/*
+* Copyright (C) 2020 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 <android/hardware/graphics/allocator/3.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <hidl/LegacySupport.h>
+
+#include "glUtils.h"
+#include "cb_handle_30.h"
+#include "host_connection_session.h"
+#include "types.h"
+#include "debug.h"
+
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_bitfield;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+using ::android::hardware::graphics::common::V1_2::PixelFormat;
+using ::android::hardware::graphics::common::V1_0::BufferUsage;
+
+namespace AllocatorV3 = ::android::hardware::graphics::allocator::V3_0;
+namespace MapperV3 = ::android::hardware::graphics::mapper::V3_0;
+
+using IAllocator3 = AllocatorV3::IAllocator;
+using IMapper3 = MapperV3::IMapper;
+using Error3 = MapperV3::Error;
+using BufferDescriptorInfo = IMapper3::BufferDescriptorInfo;
+
+class GoldfishAllocator : public IAllocator3 {
+public:
+ GoldfishAllocator() : m_hostConn(HostConnection::createUnique()) {}
+
+ Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
+ hidl_cb("GoldfishAllocator::dumpDebugInfo is not implemented");
+ return {};
+ }
+
+ Return<void> allocate(const hidl_vec<uint32_t>& rawDescriptor,
+ uint32_t count,
+ allocate_cb hidl_cb) {
+ uint32_t stride = 0;
+ std::vector<cb_handle_30_t*> cbs;
+ cbs.reserve(count);
+
+ const Error3 e = allocateImpl(rawDescriptor, count, &stride, &cbs);
+ if (e == Error3::NONE) {
+ hidl_vec<hidl_handle> handles(cbs.cbegin(), cbs.cend());
+ hidl_cb(Error3::NONE, stride, handles);
+ } else {
+ hidl_cb(e, 0, {});
+ }
+
+ for (cb_handle_30_t* cb : cbs) {
+ freeCb(std::unique_ptr<cb_handle_30_t>(cb));
+ }
+
+ return {};
+ }
+
+private:
+ // this function should be in sync with GoldfishMapper::isSupportedImpl
+ Error3 allocateImpl(const hidl_vec<uint32_t>& rawDescriptor,
+ uint32_t count,
+ uint32_t* pStride,
+ std::vector<cb_handle_30_t*>* cbs) {
+ BufferDescriptorInfo descriptor;
+ if (!decodeBufferDescriptorInfo(rawDescriptor, &descriptor)) {
+ RETURN_ERROR(Error3::BAD_DESCRIPTOR);
+ }
+
+ if (!descriptor.width) { RETURN_ERROR(Error3::UNSUPPORTED); }
+ if (!descriptor.height) { RETURN_ERROR(Error3::UNSUPPORTED); }
+ if (descriptor.layerCount != 1) { RETURN_ERROR(Error3::UNSUPPORTED); }
+
+ const uint32_t usage = descriptor.usage;
+ const bool usageSwWrite = usage & BufferUsage::CPU_WRITE_MASK;
+ const bool usageSwRead = usage & BufferUsage::CPU_READ_MASK;
+ const bool usageHwCamWrite = usage & BufferUsage::CAMERA_OUTPUT;
+ const bool usageHwCamRead = usage & BufferUsage::CAMERA_INPUT;
+
+ int bpp = 1;
+ int glFormat = 0;
+ int glType = 0;
+ int align = 1;
+ bool yuv_format = false;
+ EmulatorFrameworkFormat emulatorFrameworkFormat =
+ EmulatorFrameworkFormat::GL_COMPATIBLE;
+
+ PixelFormat format;
+ Error3 e = getBufferFormat(descriptor.format, usage, &format);
+ if (e != Error3::NONE) {
+ ALOGE("%s:%d Unsupported format: frameworkFormat=%d, usage=%x",
+ __func__, __LINE__, descriptor.format, usage);
+ return e;
+ }
+
+ switch (format) {
+ case PixelFormat::RGBA_8888:
+ case PixelFormat::RGBX_8888:
+ case PixelFormat::BGRA_8888:
+ bpp = 4;
+ glFormat = GL_RGBA;
+ glType = GL_UNSIGNED_BYTE;
+ break;
+
+ case PixelFormat::RGB_888:
+ if (usage & (BufferUsage::GPU_TEXTURE |
+ BufferUsage::GPU_RENDER_TARGET |
+ BufferUsage::COMPOSER_OVERLAY |
+ BufferUsage::COMPOSER_CLIENT_TARGET)) {
+ RETURN_ERROR(Error3::UNSUPPORTED);
+ } else {
+ bpp = 3;
+ glFormat = GL_RGB;
+ glType = GL_UNSIGNED_BYTE;
+ }
+ break;
+
+ case PixelFormat::RGB_565:
+ bpp = 2;
+ glFormat = GL_RGB565;
+ glType = GL_UNSIGNED_SHORT_5_6_5;
+ break;
+
+ case PixelFormat::RGBA_FP16:
+ bpp = 8;
+ glFormat = GL_RGBA16F;
+ glType = GL_HALF_FLOAT;
+ break;
+
+ case PixelFormat::RGBA_1010102:
+ bpp = 4;
+ glFormat = GL_RGB10_A2;
+ glType = GL_UNSIGNED_INT_2_10_10_10_REV;
+ break;
+
+ case PixelFormat::RAW16:
+ case PixelFormat::Y16:
+ bpp = 2;
+ align = 16 * bpp;
+ if (!((usageSwRead || usageHwCamRead) && (usageSwWrite || usageHwCamWrite))) {
+ // Raw sensor data or Y16 only goes between camera and CPU
+ RETURN_ERROR(Error3::UNSUPPORTED);
+ }
+ // Not expecting to actually create any GL surfaces for this
+ glFormat = GL_LUMINANCE;
+ glType = GL_UNSIGNED_SHORT;
+ break;
+
+ case PixelFormat::BLOB:
+ if (!usageSwRead) {
+ // Blob data cannot be used by HW other than camera emulator
+ // But there is a CTS test trying to have access to it
+ // BUG: https://buganizer.corp.google.com/issues/37719518
+ RETURN_ERROR(Error3::UNSUPPORTED);
+ }
+ // Not expecting to actually create any GL surfaces for this
+ glFormat = GL_LUMINANCE;
+ glType = GL_UNSIGNED_BYTE;
+ break;
+
+ case PixelFormat::YCRCB_420_SP:
+ yuv_format = true;
+ // Not expecting to actually create any GL surfaces for this
+ break;
+
+ case PixelFormat::YV12:
+ align = 16;
+ yuv_format = true;
+ // We are going to use RGB8888 on the host for Vulkan
+ glFormat = GL_RGBA;
+ glType = GL_UNSIGNED_BYTE;
+ emulatorFrameworkFormat = EmulatorFrameworkFormat::YV12;
+ break;
+
+ case PixelFormat::YCBCR_420_888:
+ yuv_format = true;
+ // We are going to use RGB888 on the host
+ glFormat = GL_RGB;
+ glType = GL_UNSIGNED_BYTE;
+ emulatorFrameworkFormat = EmulatorFrameworkFormat::YUV_420_888;
+ break;
+
+ default:
+ ALOGE("%s:%d Unsupported format: format=%d, frameworkFormat=%d, usage=%x",
+ __func__, __LINE__, format, descriptor.format, usage);
+ RETURN_ERROR(Error3::UNSUPPORTED);
+ }
+
+ const size_t align1 = align - 1;
+ const uint32_t width = descriptor.width;
+ const uint32_t height = descriptor.height;
+ uint32_t stride;
+ size_t bufferSize;
+
+ if (yuv_format) {
+ const size_t yStride = (width * bpp + align1) & ~align1;
+ const size_t uvStride = (yStride / 2 + align1) & ~align1;
+ const size_t uvHeight = height / 2;
+ bufferSize = yStride * height + 2 * (uvHeight * uvStride);
+ stride = yStride / bpp;
+ } else {
+ const size_t bpr = (width * bpp + align1) & ~align1;
+ bufferSize = bpr * height;
+ stride = bpr / bpp;
+ }
+
+ *pStride = stride;
+
+ return allocateImpl2(usage,
+ width, height,
+ format, emulatorFrameworkFormat,
+ glFormat, glType,
+ bufferSize,
+ bpp, stride,
+ count, cbs);
+ }
+
+ Error3 allocateImpl2(const uint32_t usage,
+ const uint32_t width, const uint32_t height,
+ const PixelFormat format,
+ const EmulatorFrameworkFormat emulatorFrameworkFormat,
+ const int glFormat, const int glType,
+ const size_t bufferSize,
+ const uint32_t bytesPerPixel,
+ const uint32_t stride,
+ const uint32_t count,
+ std::vector<cb_handle_30_t*>* cbs) {
+ for (uint32_t i = 0; i < count; ++i) {
+ cb_handle_30_t* cb;
+ Error3 e = allocateCb(usage,
+ width, height,
+ format, emulatorFrameworkFormat,
+ glFormat, glType,
+ bufferSize,
+ bytesPerPixel, stride,
+ &cb);
+ if (e == Error3::NONE) {
+ cbs->push_back(cb);
+ } else {
+ return e;
+ }
+ }
+
+ RETURN(Error3::NONE);
+ }
+
+ // see GoldfishMapper::encodeBufferDescriptorInfo
+ static bool decodeBufferDescriptorInfo(const hidl_vec<uint32_t>& raw,
+ BufferDescriptorInfo* d) {
+ if (raw.size() == 5) {
+ d->width = raw[0];
+ d->height = raw[1];
+ d->layerCount = raw[2];
+ d->format = static_cast<PixelFormat>(raw[3]);
+ d->usage = raw[4];
+
+ RETURN(true);
+ } else {
+ RETURN_ERROR(false);
+ }
+ }
+
+ static Error3 getBufferFormat(const PixelFormat frameworkFormat,
+ const uint32_t usage,
+ PixelFormat* format) {
+ if (frameworkFormat == PixelFormat::IMPLEMENTATION_DEFINED) {
+ if (usage & BufferUsage::CAMERA_OUTPUT) {
+ if (usage & BufferUsage::GPU_TEXTURE) {
+ // Camera-to-display is RGBA
+ *format = PixelFormat::RGBA_8888;
+ RETURN(Error3::NONE);
+ } else if (usage & BufferUsage::VIDEO_ENCODER) {
+ // Camera-to-encoder is NV21
+ *format = PixelFormat::YCRCB_420_SP;
+ RETURN(Error3::NONE);
+ }
+ }
+ RETURN_ERROR(Error3::UNSUPPORTED);
+ } else {
+ *format = frameworkFormat;
+ RETURN(Error3::NONE);
+ }
+ }
+
+ static bool needHostCb(const uint32_t usage, const PixelFormat format) {
+ return ((usage & BufferUsage::GPU_DATA_BUFFER)
+ || (format != PixelFormat::BLOB &&
+ format != PixelFormat::RAW16 &&
+ format != PixelFormat::Y16))
+ && (usage & (BufferUsage::GPU_TEXTURE
+ | BufferUsage::GPU_RENDER_TARGET
+ | BufferUsage::COMPOSER_OVERLAY
+ | BufferUsage::VIDEO_ENCODER
+ | BufferUsage::COMPOSER_CLIENT_TARGET
+ | BufferUsage::CPU_READ_MASK));
+ }
+
+ Error3 allocateCb(const uint32_t usage,
+ const uint32_t width, const uint32_t height,
+ const PixelFormat format,
+ const EmulatorFrameworkFormat emulatorFrameworkFormat,
+ const int glFormat, const int glType,
+ const size_t bufferSize,
+ const int32_t bytesPerPixel,
+ const int32_t stride,
+ cb_handle_30_t** cb) {
+ GoldfishAddressSpaceHostMemoryAllocator host_memory_allocator;
+ if (!host_memory_allocator.is_opened()) {
+ RETURN_ERROR(Error3::NO_RESOURCES);
+ }
+
+ GoldfishAddressSpaceBlock bufferBits;
+ if (host_memory_allocator.hostMalloc(&bufferBits, bufferSize)) {
+ RETURN_ERROR(Error3::NO_RESOURCES);
+ }
+
+ uint32_t hostHandle = 0;
+ QEMU_PIPE_HANDLE hostHandleRefCountFd = QEMU_PIPE_INVALID_HANDLE;
+ if (needHostCb(usage, format)) {
+ hostHandleRefCountFd = qemu_pipe_open("refcount");
+ if (!qemu_pipe_valid(hostHandleRefCountFd)) {
+ RETURN_ERROR(Error3::NO_RESOURCES);
+ }
+
+ const GLenum allocFormat =
+ (PixelFormat::RGBX_8888 == format) ? GL_RGB : glFormat;
+
+ const HostConnectionSession conn = getHostConnectionSession();
+ ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
+ CRASH_IF(!rcEnc, "conn.getRcEncoder() failed");
+
+ hostHandle = rcEnc->rcCreateColorBufferDMA(
+ rcEnc,
+ width, height,
+ allocFormat, static_cast<int>(emulatorFrameworkFormat));
+
+ if (!hostHandle) {
+ qemu_pipe_close(hostHandleRefCountFd);
+ RETURN_ERROR(Error3::NO_RESOURCES);
+ }
+
+ if (qemu_pipe_write(hostHandleRefCountFd,
+ &hostHandle,
+ sizeof(hostHandle)) != sizeof(hostHandle)) {
+ rcEnc->rcCloseColorBuffer(rcEnc, hostHandle);
+ qemu_pipe_close(hostHandleRefCountFd);
+ RETURN_ERROR(Error3::NO_RESOURCES);
+ }
+ }
+
+ std::unique_ptr<cb_handle_30_t> handle =
+ std::make_unique<cb_handle_30_t>(
+ host_memory_allocator.release(),
+ hostHandleRefCountFd,
+ hostHandle,
+ usage,
+ width,
+ height,
+ static_cast<int>(format),
+ glFormat,
+ glType,
+ bufferSize,
+ bufferBits.guestPtr(),
+ bufferBits.size(),
+ bufferBits.offset(),
+ bytesPerPixel,
+ stride);
+
+ bufferBits.release();
+ *cb = handle.release();
+ RETURN(Error3::NONE);
+ }
+
+ void freeCb(std::unique_ptr<cb_handle_30_t> cb) {
+ // no need to undo .hostMalloc: the kernel will take care of it once the
+ // last bufferFd (duped) is closed.
+
+ if (qemu_pipe_valid(cb->hostHandleRefCountFd)) {
+ qemu_pipe_close(cb->hostHandleRefCountFd);
+ }
+ GoldfishAddressSpaceBlock::memoryUnmap(cb->getBufferPtr(), cb->mmapedSize);
+ GoldfishAddressSpaceHostMemoryAllocator::closeHandle(cb->bufferFd);
+ }
+
+ HostConnectionSession getHostConnectionSession() const {
+ return HostConnectionSession(m_hostConn);
+ }
+
+ //std::unique_ptr<HostConnection> m_hostConn; // b/142677230
+ HostConnection* m_hostConn;
+};
+
+int main(int, char**) {
+ using ::android::sp;
+
+ ::android::hardware::configureRpcThreadpool(4, true /* callerWillJoin */);
+
+ sp<IAllocator3> allocator(new GoldfishAllocator());
+ if (allocator->registerAsService() != ::android::NO_ERROR) {
+ ALOGE("failed to register graphics IAllocator@3.0 service");
+ return -EINVAL;
+ }
+
+ ALOGI("graphics IAllocator@3.0 service is initialized");
+ ::android::hardware::joinRpcThreadpool();
+
+ ALOGI("graphics IAllocator@3.0 service is terminating");
+ return 0;
+}
diff --git a/system/hals/android.hardware.graphics.allocator@3.0-service.rc b/system/hals/android.hardware.graphics.allocator@3.0-service.rc
new file mode 100644
index 0000000..8b9e13a
--- /dev/null
+++ b/system/hals/android.hardware.graphics.allocator@3.0-service.rc
@@ -0,0 +1,8 @@
+service vendor.gralloc-3-0 /vendor/bin/hw/android.hardware.graphics.allocator@3.0-service
+ interface android.hardware.graphics.allocator@3.0::IAllocator default
+ class hal animation
+ interface android.hardware.graphics.allocator@3.0::IAllocator default
+ user system
+ group graphics drmrpc
+ capabilities SYS_NICE
+ onrestart restart surfaceflinger
diff --git a/system/hals/cb_handle_30.h b/system/hals/cb_handle_30.h
new file mode 100644
index 0000000..11ce322
--- /dev/null
+++ b/system/hals/cb_handle_30.h
@@ -0,0 +1,81 @@
+/*
+* Copyright 2011 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef SYSTEM_HALS_CB_HANDLE_30_H
+#define SYSTEM_HALS_CB_HANDLE_30_H
+
+#include "gralloc_cb.h"
+#include "goldfish_address_space.h"
+
+const uint32_t CB_HANDLE_MAGIC_30 = CB_HANDLE_MAGIC_BASE | 0x2;
+
+struct cb_handle_30_t : public cb_handle_t {
+ cb_handle_30_t(address_space_handle_t p_bufferFd,
+ QEMU_PIPE_HANDLE p_hostHandleRefCountFd,
+ uint32_t p_hostHandle,
+ int32_t p_usage,
+ int32_t p_width,
+ int32_t p_height,
+ int32_t p_format,
+ int32_t p_glFormat,
+ int32_t p_glType,
+ uint32_t p_bufSize,
+ void* p_bufPtr,
+ uint32_t p_mmapedSize,
+ uint64_t p_mmapedOffset,
+ uint32_t p_bytesPerPixel,
+ uint32_t p_stride)
+ : cb_handle_t(p_bufferFd,
+ p_hostHandleRefCountFd,
+ CB_HANDLE_MAGIC_30,
+ p_hostHandle,
+ p_usage,
+ p_width,
+ p_height,
+ p_format,
+ p_glFormat,
+ p_glType,
+ p_bufSize,
+ p_bufPtr,
+ p_mmapedOffset),
+ mmapedSize(p_mmapedSize),
+ bytesPerPixel(p_bytesPerPixel),
+ stride(p_stride) {
+ numInts = CB_HANDLE_NUM_INTS(numFds);
+ }
+
+ bool isValid() const { return (version == sizeof(native_handle_t)) && (magic == CB_HANDLE_MAGIC_30); }
+
+ static cb_handle_30_t* from(void* p) {
+ if (!p) { return nullptr; }
+ cb_handle_30_t* cb = static_cast<cb_handle_30_t*>(p);
+ return cb->isValid() ? cb : nullptr;
+ }
+
+ static const cb_handle_30_t* from(const void* p) {
+ return from(const_cast<void*>(p));
+ }
+
+ static cb_handle_30_t* from_unconst(const void* p) {
+ return from(const_cast<void*>(p));
+ }
+
+ uint32_t mmapedSize; // real allocation side
+ uint32_t bytesPerPixel;
+ uint32_t stride;
+};
+
+#endif // SYSTEM_HALS_CB_HANDLE_30_H
diff --git a/system/hals/debug.h b/system/hals/debug.h
new file mode 100644
index 0000000..f8e41b4
--- /dev/null
+++ b/system/hals/debug.h
@@ -0,0 +1,44 @@
+/*
+* Copyright (C) 2020 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef GOLDFISH_OPENGL_SYSTEM_HALS_DEBUG_H_INCLUDED
+#define GOLDFISH_OPENGL_SYSTEM_HALS_DEBUG_H_INCLUDED
+
+#include <log/log.h>
+
+#define RETURN(X) return (X)
+
+#define RETURN_ERROR(X) \
+ do { \
+ ALOGE("%s:%d failed with '%s'", __func__, __LINE__, #X); \
+ return (X); \
+ } while (false)
+
+#define CRASH(MSG) \
+ do { \
+ ALOGE("%s:%d crashed with '%s'", __func__, __LINE__, MSG); \
+ ::abort(); \
+ } while (false)
+
+#define CRASH_IF(COND, MSG) \
+ do { \
+ if ((COND)) { \
+ ALOGE("%s:%d crashed on '%s' with '%s'", __func__, __LINE__, #COND, MSG); \
+ ::abort(); \
+ } \
+ } while (false)
+
+#endif // GOLDFISH_OPENGL_SYSTEM_HALS_DEBUG_H_INCLUDED
diff --git a/system/hals/host_connection_session.h b/system/hals/host_connection_session.h
new file mode 100644
index 0000000..12d3b76
--- /dev/null
+++ b/system/hals/host_connection_session.h
@@ -0,0 +1,56 @@
+/*
+* Copyright (C) 2020 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef GOLDFISH_OPENGL_SYSTEM_HALS_HOST_CONNECTION_SESSION_H_INCLUDED
+#define GOLDFISH_OPENGL_SYSTEM_HALS_HOST_CONNECTION_SESSION_H_INCLUDED
+
+#include "HostConnection.h"
+
+class HostConnectionSession {
+public:
+ explicit HostConnectionSession(HostConnection* hc) : conn(hc) {
+ hc->lock();
+ }
+
+ ~HostConnectionSession() {
+ if (conn) {
+ conn->unlock();
+ }
+ }
+
+ HostConnectionSession(HostConnectionSession&& rhs) : conn(rhs.conn) {
+ rhs.conn = nullptr;
+ }
+
+ HostConnectionSession& operator=(HostConnectionSession&& rhs) {
+ if (this != &rhs) {
+ std::swap(conn, rhs.conn);
+ }
+ return *this;
+ }
+
+ HostConnectionSession(const HostConnectionSession&) = delete;
+ HostConnectionSession& operator=(const HostConnectionSession&) = delete;
+
+ ExtendedRCEncoderContext* getRcEncoder() const {
+ return conn->rcEncoder();
+ }
+
+private:
+ HostConnection* conn;
+};
+
+#endif // GOLDFISH_OPENGL_SYSTEM_HALS_HOST_CONNECTION_SESSION_H_INCLUDED
diff --git a/system/hals/mapper3.cpp b/system/hals/mapper3.cpp
new file mode 100644
index 0000000..99c6514
--- /dev/null
+++ b/system/hals/mapper3.cpp
@@ -0,0 +1,615 @@
+/*
+* Copyright (C) 2020 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 <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <cutils/native_handle.h>
+#include <sync/sync.h>
+
+#include "cb_handle_30.h"
+#include "host_connection_session.h"
+#include "FormatConversions.h"
+#include "debug.h"
+
+using ::android::hardware::hidl_handle;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+using ::android::hardware::graphics::common::V1_2::PixelFormat;
+using ::android::hardware::graphics::common::V1_0::BufferUsage;
+
+namespace MapperV3 = ::android::hardware::graphics::mapper::V3_0;
+
+using IMapper3 = MapperV3::IMapper;
+using Error3 = MapperV3::Error;
+using YCbCrLayout3 = MapperV3::YCbCrLayout;
+
+namespace {
+size_t align(const size_t v, const size_t a) { return (v + a - 1) & ~(a - 1); }
+
+static int waitFenceFd(const int fd, const char* logname) {
+ const int warningTimeout = 5000;
+ if (sync_wait(dup(fd), warningTimeout) < 0) {
+ if (errno == ETIME) {
+ ALOGW("%s: fence %d didn't signal in %d ms", logname, fd, warningTimeout);
+ if (sync_wait(fd, -1) < 0) {
+ RETURN_ERROR(errno);
+ } else {
+ RETURN(0);
+ }
+ } else {
+ RETURN_ERROR(errno);
+ }
+ } else {
+ RETURN(0);
+ }
+}
+
+int waitHidlFence(const hidl_handle& hidlHandle, const char* logname) {
+ const native_handle_t* nativeHandle = hidlHandle.getNativeHandle();
+
+ if (!nativeHandle) {
+ RETURN(0);
+ }
+ if (nativeHandle->numFds > 1) {
+ RETURN_ERROR(-EINVAL);
+ }
+ if (nativeHandle->numInts != 0) {
+ RETURN_ERROR(-EINVAL);
+ }
+
+ return waitFenceFd(nativeHandle->data[0], logname);
+}
+
+class GoldfishMapper : public IMapper3 {
+public:
+ GoldfishMapper() : m_hostConn(HostConnection::createUnique()) {
+ GoldfishAddressSpaceHostMemoryAllocator host_memory_allocator;
+ CRASH_IF(!host_memory_allocator.is_opened(),
+ "GoldfishAddressSpaceHostMemoryAllocator failed to open");
+
+ GoldfishAddressSpaceBlock bufferBits;
+ CRASH_IF(host_memory_allocator.hostMalloc(&bufferBits, 256),
+ "hostMalloc failed");
+
+ m_physAddrToOffset = bufferBits.physAddr() - bufferBits.offset();
+ }
+
+ Return<void> importBuffer(const hidl_handle& hh,
+ importBuffer_cb hidl_cb) {
+ native_handle_t* imported = nullptr;
+ const Error3 e = importBufferImpl(hh.getNativeHandle(), &imported);
+ if (e == Error3::NONE) {
+ hidl_cb(Error3::NONE, imported);
+ } else {
+ hidl_cb(e, nullptr);
+ }
+ return {};
+ }
+
+ Return<Error3> freeBuffer(void* raw) {
+ if (!raw) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ cb_handle_30_t* cb = cb_handle_30_t::from(raw);
+ if (!cb) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+
+ if (cb->hostHandle) {
+ const HostConnectionSession conn = getHostConnectionSession();
+ ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
+ rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle);
+ }
+
+ if (cb->mmapedSize > 0) {
+ GoldfishAddressSpaceBlock::memoryUnmap(cb->getBufferPtr(), cb->mmapedSize);
+ }
+
+ native_handle_close(cb);
+ native_handle_delete(cb);
+
+ RETURN(Error3::NONE);
+ }
+
+ Return<void> lock(void* raw,
+ uint64_t cpuUsage,
+ const Rect& accessRegion,
+ const hidl_handle& acquireFence,
+ lock_cb hidl_cb) {
+ void* ptr = nullptr;
+ int32_t bytesPerPixel = 0;
+ int32_t bytesPerStride = 0;
+
+ const Error3 e = lockImpl(raw, cpuUsage, accessRegion, acquireFence,
+ &ptr, &bytesPerPixel, &bytesPerStride);
+ if (e == Error3::NONE) {
+ hidl_cb(Error3::NONE, ptr, bytesPerPixel, bytesPerStride);
+ } else {
+ hidl_cb(e, nullptr, 0, 0);
+ }
+ return {};
+ }
+
+ Return<void> lockYCbCr(void* raw,
+ uint64_t cpuUsage,
+ const Rect& accessRegion,
+ const hidl_handle& acquireFence,
+ lockYCbCr_cb hidl_cb) {
+ YCbCrLayout3 ycbcr = {};
+ const Error3 e = lockYCbCrImpl(raw, cpuUsage, accessRegion, acquireFence,
+ &ycbcr);
+ if (e == Error3::NONE) {
+ hidl_cb(Error3::NONE, ycbcr);
+ } else {
+ hidl_cb(e, {});
+ }
+ return {};
+ }
+
+ Return<void> unlock(void* raw, unlock_cb hidl_cb) {
+ hidl_cb(unlockImpl(raw), {});
+ return {};
+
+ }
+
+ Return<void> createDescriptor(const BufferDescriptorInfo& description,
+ createDescriptor_cb hidl_cb) {
+ hidl_vec<uint32_t> raw;
+ encodeBufferDescriptorInfo(description, &raw);
+ hidl_cb(Error3::NONE, raw);
+ return {};
+ }
+
+ Return<void> isSupported(const IMapper::BufferDescriptorInfo& description,
+ isSupported_cb hidl_cb) {
+ hidl_cb(Error3::NONE, isSupportedImpl(description));
+ return {};
+ }
+
+ Return<Error3> validateBufferSize(void* buffer,
+ const BufferDescriptorInfo& descriptor,
+ uint32_t stride) {
+ const cb_handle_30_t* cb = cb_handle_30_t::from(buffer);
+ if (cb) {
+ return validateBufferSizeImpl(*cb, descriptor, stride);
+ } else {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ }
+
+ Return<void> getTransportSize(void* buffer,
+ getTransportSize_cb hidl_cb) {
+ const cb_handle_30_t* cb = cb_handle_30_t::from(buffer);
+ if (cb) {
+ hidl_cb(Error3::NONE, cb->numFds, cb->numInts);
+ } else {
+ hidl_cb(Error3::BAD_BUFFER, 0, 0);
+ }
+
+ return {};
+ }
+
+private: // **** impl ****
+ Error3 importBufferImpl(const native_handle_t* nh, native_handle_t** phandle) {
+ if (!nh) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ native_handle_t* imported = native_handle_clone(nh);
+ if (!imported) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ cb_handle_30_t* cb = cb_handle_30_t::from(imported);
+ if (!cb) {
+ native_handle_close(imported);
+ native_handle_delete(imported);
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+
+ if (cb->mmapedSize > 0) {
+ void* ptr;
+ const int res = GoldfishAddressSpaceBlock::memoryMap(
+ cb->getBufferPtr(),
+ cb->mmapedSize,
+ cb->bufferFd,
+ cb->getMmapedOffset(),
+ &ptr);
+ if (res) {
+ native_handle_close(imported);
+ native_handle_delete(imported);
+ RETURN_ERROR(Error3::NO_RESOURCES);
+ }
+ cb->setBufferPtr(ptr);
+ }
+
+ if (cb->hostHandle) {
+ const HostConnectionSession conn = getHostConnectionSession();
+ ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
+ rcEnc->rcOpenColorBuffer2(rcEnc, cb->hostHandle);
+ }
+
+ *phandle = imported;
+ RETURN(Error3::NONE);
+ }
+
+ Error3 lockImpl(void* raw,
+ uint64_t cpuUsage,
+ const Rect& accessRegion,
+ const hidl_handle& acquireFence,
+ void** pptr,
+ int32_t* pBytesPerPixel,
+ int32_t* pBytesPerStride) {
+ if (!raw) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ cb_handle_30_t* cb = cb_handle_30_t::from(raw);
+ if (!cb) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ if (!cb->bufferSize) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ char* const bufferBits = static_cast<char*>(cb->getBufferPtr());
+ if (!bufferBits) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ if (waitHidlFence(acquireFence, __func__)) {
+ RETURN_ERROR(Error3::BAD_VALUE);
+ }
+
+ if (cb->hostHandle) {
+ const Error3 e = lockHostImpl(*cb, cpuUsage, accessRegion, bufferBits);
+ if (e != Error3::NONE) {
+ return e;
+ }
+ }
+
+ *pptr = bufferBits;
+ *pBytesPerPixel = cb->bytesPerPixel;
+ *pBytesPerStride = cb->bytesPerPixel * cb->stride;
+ RETURN(Error3::NONE);
+ }
+
+ Error3 lockYCbCrImpl(void* raw,
+ uint64_t cpuUsage,
+ const Rect& accessRegion,
+ const hidl_handle& acquireFence,
+ YCbCrLayout3* pYcbcr) {
+ if (!raw) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ cb_handle_30_t* cb = cb_handle_30_t::from(raw);
+ if (!cb) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ if (!cb->bufferSize) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ char* const bufferBits = static_cast<char*>(cb->getBufferPtr());
+ if (!bufferBits) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ if (waitHidlFence(acquireFence, __func__)) {
+ RETURN_ERROR(Error3::BAD_VALUE);
+ }
+
+ size_t uOffset;
+ size_t vOffset;
+ size_t yStride;
+ size_t cStride;
+ size_t cStep;
+ switch (static_cast<PixelFormat>(cb->format)) {
+ case PixelFormat::YCRCB_420_SP:
+ yStride = cb->width;
+ cStride = yStride;
+ vOffset = yStride * cb->height;
+ uOffset = vOffset + 1;
+ cStep = 2;
+ break;
+
+ case PixelFormat::YV12:
+ // https://developer.android.com/reference/android/graphics/ImageFormat.html#YV12
+ yStride = align(cb->width, 16);
+ cStride = align(yStride / 2, 16);
+ vOffset = yStride * cb->height;
+ uOffset = vOffset + (cStride * cb->height / 2);
+ cStep = 1;
+ break;
+
+ case PixelFormat::YCBCR_420_888:
+ yStride = cb->width;
+ cStride = yStride / 2;
+ uOffset = cb->height * yStride;
+ vOffset = uOffset + cStride * cb->height / 2;
+ cStep = 1;
+ break;
+
+ default:
+ ALOGE("%s:%d unexpected format (%d)", __func__, __LINE__, cb->format);
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+
+ if (cb->hostHandle) {
+ const Error3 e = lockHostImpl(*cb, cpuUsage, accessRegion, bufferBits);
+ if (e != Error3::NONE) {
+ return e;
+ }
+ }
+
+ pYcbcr->y = bufferBits;
+ pYcbcr->cb = bufferBits + uOffset;
+ pYcbcr->cr = bufferBits + vOffset;
+ pYcbcr->yStride = yStride;
+ pYcbcr->cStride = cStride;
+ pYcbcr->chromaStep = cStep;
+
+ RETURN(Error3::NONE);
+ }
+
+ Error3 lockHostImpl(cb_handle_30_t& cb,
+ const uint32_t usage,
+ const Rect& accessRegion,
+ char* const bufferBits) {
+ const bool usageSwRead = usage & BufferUsage::CPU_READ_MASK;
+ const bool usageSwWrite = usage & BufferUsage::CPU_WRITE_MASK;
+ const bool usageHwCamera = usage & (BufferUsage::CAMERA_INPUT | BufferUsage::CAMERA_OUTPUT);
+ const bool usageHwCameraWrite = usage & BufferUsage::CAMERA_OUTPUT;
+
+ const HostConnectionSession conn = getHostConnectionSession();
+ ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
+
+ const int res = rcEnc->rcColorBufferCacheFlush(
+ rcEnc, cb.hostHandle, 0, usageSwRead);
+ if (res < 0) {
+ RETURN_ERROR(Error3::NO_RESOURCES);
+ }
+
+ // camera delivers bits to the buffer directly and does not require
+ // an explicit read.
+ if (usageSwRead && !usageHwCamera) {
+ if (gralloc_is_yuv_format(cb.format)) {
+ if (rcEnc->hasYUVCache()) {
+ uint32_t bufferSize;
+ switch (static_cast<PixelFormat>(cb.format)) {
+ case PixelFormat::YV12:
+ get_yv12_offsets(cb.width, cb.height,
+ nullptr, nullptr, &bufferSize);
+ break;
+ case PixelFormat::YCBCR_420_888:
+ get_yuv420p_offsets(cb.width, cb.height,
+ nullptr, nullptr, &bufferSize);
+ break;
+ default:
+ CRASH("Unexpected format, switch is out of sync with gralloc_is_yuv_format");
+ break;
+ }
+
+ rcEnc->rcReadColorBufferYUV(rcEnc, cb.hostHandle,
+ 0, 0, cb.width, cb.height,
+ bufferBits, bufferSize);
+ } else {
+ // We are using RGB888
+ std::vector<char> tmpBuf(cb.width * cb.height * 3);
+ rcEnc->rcReadColorBuffer(rcEnc, cb.hostHandle,
+ 0, 0, cb.width, cb.height,
+ cb.glFormat, cb.glType,
+ tmpBuf.data());
+ switch (static_cast<PixelFormat>(cb.format)) {
+ case PixelFormat::YV12:
+ rgb888_to_yv12(bufferBits, tmpBuf.data(),
+ cb.width, cb.height,
+ accessRegion.left,
+ accessRegion.top,
+ accessRegion.left + accessRegion.width - 1,
+ accessRegion.top + accessRegion.height - 1);
+ break;
+ case PixelFormat::YCBCR_420_888:
+ rgb888_to_yuv420p(bufferBits, tmpBuf.data(),
+ cb.width, cb.height,
+ accessRegion.left,
+ accessRegion.top,
+ accessRegion.left + accessRegion.width - 1,
+ accessRegion.top + accessRegion.height - 1);
+ break;
+ default:
+ CRASH("Unexpected format, switch is out of sync with gralloc_is_yuv_format");
+ break;
+ }
+ }
+ } else {
+ rcEnc->rcReadColorBuffer(rcEnc,
+ cb.hostHandle,
+ 0, 0, cb.width, cb.height,
+ cb.glFormat, cb.glType,
+ bufferBits);
+ }
+ }
+
+ if (usageSwWrite || usageHwCameraWrite) {
+ cb.lockedLeft = accessRegion.left;
+ cb.lockedTop = accessRegion.top;
+ cb.lockedWidth = accessRegion.width;
+ cb.lockedHeight = accessRegion.height;
+ } else {
+ cb.lockedLeft = 0;
+ cb.lockedTop = 0;
+ cb.lockedWidth = cb.width;
+ cb.lockedHeight = cb.height;
+ }
+
+ RETURN(Error3::NONE);
+ }
+
+ Error3 unlockImpl(void* raw) {
+ if (!raw) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ cb_handle_30_t* cb = cb_handle_30_t::from(raw);
+ if (!cb) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ if (!cb->bufferSize) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+ char* const bufferBits = static_cast<char*>(cb->getBufferPtr());
+ if (!bufferBits) {
+ RETURN_ERROR(Error3::BAD_BUFFER);
+ }
+
+ if (cb->hostHandle) {
+ unlockHostImpl(*cb, bufferBits);
+ }
+
+ RETURN(Error3::NONE);
+ }
+
+ void unlockHostImpl(cb_handle_30_t& cb, char* const bufferBits) {
+ const int bpp = glUtilsPixelBitSize(cb.glFormat, cb.glType) >> 3;
+ const int left = cb.lockedLeft;
+ const int top = cb.lockedTop;
+ const int width = cb.lockedWidth;
+ const int height = cb.lockedHeight;
+ const uint32_t rgbSize = width * height * bpp;
+ std::vector<char> convertedBuf;
+ const char* bitsToSend;
+ uint32_t sizeToSend;
+
+ if (gralloc_is_yuv_format(cb.format)) {
+ bitsToSend = bufferBits;
+ switch (static_cast<PixelFormat>(cb.format)) {
+ case PixelFormat::YV12:
+ get_yv12_offsets(width, height, nullptr, nullptr, &sizeToSend);
+ break;
+ case PixelFormat::YCBCR_420_888:
+ get_yuv420p_offsets(width, height, nullptr, nullptr, &sizeToSend);
+ break;
+ default:
+ CRASH("Unexpected format, switch is out of sync with gralloc_is_yuv_format");
+ break;
+ }
+ } else {
+ convertedBuf.resize(rgbSize);
+ copy_rgb_buffer_from_unlocked(
+ convertedBuf.data(), bufferBits,
+ cb.width,
+ width, height, top, left, bpp);
+ bitsToSend = convertedBuf.data();
+ sizeToSend = rgbSize;
+ }
+
+ {
+ const HostConnectionSession conn = getHostConnectionSession();
+ ExtendedRCEncoderContext *const rcEnc = conn.getRcEncoder();
+ rcEnc->bindDmaDirectly(bufferBits,
+ getMmapedPhysAddr(cb.getMmapedOffset()));
+ rcEnc->rcUpdateColorBufferDMA(rcEnc, cb.hostHandle,
+ left, top, width, height,
+ cb.glFormat, cb.glType,
+ const_cast<char*>(bitsToSend), sizeToSend);
+ }
+
+ cb.lockedLeft = 0;
+ cb.lockedTop = 0;
+ cb.lockedWidth = 0;
+ cb.lockedHeight = 0;
+ }
+
+ bool isSupportedImpl(const IMapper::BufferDescriptorInfo& descriptor) const {
+ if (!descriptor.width) { RETURN(false); }
+ if (!descriptor.height) { RETURN(false); }
+ if (descriptor.layerCount != 1) { RETURN(false); }
+
+ const uint32_t usage = descriptor.usage;
+ const bool usageSwWrite = usage & BufferUsage::CPU_WRITE_MASK;
+ const bool usageSwRead = usage & BufferUsage::CPU_READ_MASK;
+ const bool usageHwCamWrite = usage & BufferUsage::CAMERA_OUTPUT;
+ const bool usageHwCamRead = usage & BufferUsage::CAMERA_INPUT;
+
+ switch (descriptor.format) {
+ case PixelFormat::RGBA_8888:
+ case PixelFormat::RGBX_8888:
+ case PixelFormat::BGRA_8888:
+ case PixelFormat::RGB_565:
+ case PixelFormat::RGBA_FP16:
+ case PixelFormat::RGBA_1010102:
+ case PixelFormat::YCRCB_420_SP:
+ case PixelFormat::YV12:
+ case PixelFormat::YCBCR_420_888:
+ RETURN(true);
+
+ case PixelFormat::IMPLEMENTATION_DEFINED:
+ if (usage & BufferUsage::CAMERA_OUTPUT) {
+ if (usage & BufferUsage::GPU_TEXTURE) {
+ RETURN(true);
+ } else if (usage & BufferUsage::VIDEO_ENCODER) {
+ RETURN(true);
+ }
+ }
+ RETURN(false);
+
+ case PixelFormat::RGB_888:
+ RETURN(0 == (usage & (BufferUsage::GPU_TEXTURE |
+ BufferUsage::GPU_RENDER_TARGET |
+ BufferUsage::COMPOSER_OVERLAY |
+ BufferUsage::COMPOSER_CLIENT_TARGET)));
+
+ case PixelFormat::RAW16:
+ case PixelFormat::Y16:
+ RETURN((usageSwRead || usageHwCamRead) &&
+ (usageSwWrite || usageHwCamWrite));
+
+ case PixelFormat::BLOB:
+ RETURN(usageSwRead);
+
+ default:
+ RETURN(false);
+ }
+ }
+
+ Error3 validateBufferSizeImpl(const cb_handle_t& /*cb*/,
+ const BufferDescriptorInfo& /*descriptor*/,
+ uint32_t /*stride*/) {
+ RETURN(Error3::NONE);
+ }
+
+ HostConnectionSession getHostConnectionSession() const {
+ return HostConnectionSession(m_hostConn);
+ }
+
+ static void encodeBufferDescriptorInfo(const BufferDescriptorInfo& d,
+ hidl_vec<uint32_t>* raw) {
+ raw->resize(5);
+
+ (*raw)[0] = d.width;
+ (*raw)[1] = d.height;
+ (*raw)[2] = d.layerCount;
+ (*raw)[3] = static_cast<uint32_t>(d.format);
+ (*raw)[4] = d.usage & UINT32_MAX;
+ }
+
+ uint64_t getMmapedPhysAddr(uint64_t offset) const {
+ return m_physAddrToOffset + offset;
+ }
+
+ //std::unique_ptr<HostConnection> m_hostConn; // b/142677230
+ HostConnection* m_hostConn;
+ uint64_t m_physAddrToOffset;
+};
+} // namespace
+
+extern "C" IMapper3* HIDL_FETCH_IMapper(const char* /*name*/) {
+ return new GoldfishMapper;
+}
diff --git a/system/hals/types.h b/system/hals/types.h
new file mode 100644
index 0000000..c7d2646
--- /dev/null
+++ b/system/hals/types.h
@@ -0,0 +1,43 @@
+/*
+* Copyright (C) 2020 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef GOLDFISH_OPENGL_SYSTEM_HALS_TYPES_H_INCLUDED
+#define GOLDFISH_OPENGL_SYSTEM_HALS_TYPES_H_INCLUDED
+
+/* Tell the emulator which formats need special handling. */
+enum class EmulatorFrameworkFormat {
+ GL_COMPATIBLE = 0,
+ YV12 = 1,
+ YUV_420_888 = 2, // (Y+)(U+)(V+)
+};
+
+#ifndef GL_RGBA16F
+#define GL_RGBA16F 0x881A
+#endif // GL_RGBA16F
+
+#ifndef GL_HALF_FLOAT
+#define GL_HALF_FLOAT 0x140B
+#endif // GL_HALF_FLOAT
+
+#ifndef GL_RGB10_A2
+#define GL_RGB10_A2 0x8059
+#endif // GL_RGB10_A2
+
+#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#endif // GL_UNSIGNED_INT_2_10_10_10_REV
+
+#endif // GOLDFISH_OPENGL_SYSTEM_HALS_TYPES_H_INCLUDED
diff --git a/system/hwc2/Android.mk b/system/hwc2/Android.mk
index c46ea11..698de73 100644
--- a/system/hwc2/Android.mk
+++ b/system/hwc2/Android.mk
@@ -27,6 +27,7 @@
libhardware \
libsync \
libui \
+ android.hardware.graphics.mapper@2.0 \
emulator_hwcomposer_cflags += \
-DLOG_TAG=\"hwc2\" \
@@ -52,6 +53,7 @@
LOCAL_VENDOR_MODULE := true
LOCAL_SHARED_LIBRARIES := $(emulator_hwcomposer_shared_libraries)
LOCAL_SHARED_LIBRARIES += libOpenglSystemCommon lib_renderControl_enc
+LOCAL_SHARED_LIBRARIES += libcbmanager
LOCAL_SRC_FILES := $(emulator_hwcomposer2_src_files)
LOCAL_C_INCLUDES := $(emulator_hwcomposer_c_includes)
LOCAL_MODULE_RELATIVE_PATH := $(emulator_hwcomposer_relative_path)
diff --git a/system/hwc2/EmuHWC2.cpp b/system/hwc2/EmuHWC2.cpp
index edf6397..f2fb947 100644
--- a/system/hwc2/EmuHWC2.cpp
+++ b/system/hwc2/EmuHWC2.cpp
@@ -31,7 +31,6 @@
#include "../egl/goldfish_sync.h"
#include "ThreadInfo.h"
-#include "gralloc_cb.h"
#if defined(LOG_NNDEBUG) && LOG_NNDEBUG == 0
#define ALOGVV ALOGV
@@ -67,7 +66,6 @@
return Error::NoResources; \
}
-
using namespace HWC2;
namespace android {
@@ -81,6 +79,21 @@
getCapabilities = getCapabilitiesHook;
getFunction = getFunctionHook;
populateCapabilities();
+ initDisplayParameters();
+}
+
+Error EmuHWC2::initDisplayParameters() {
+ DEFINE_AND_VALIDATE_HOST_CONNECTION
+ hostCon->lock();
+
+ mDisplayWidth = rcEnc->rcGetFBParam(rcEnc, FB_WIDTH);
+ mDisplayHeight = rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT);
+ mDisplayDpiX = rcEnc->rcGetFBParam(rcEnc, FB_XDPI);
+ mDisplayDpiY = rcEnc->rcGetFBParam(rcEnc, FB_YDPI);
+
+ hostCon->unlock();
+
+ return HWC2::Error::None;
}
void EmuHWC2::doGetCapabilities(uint32_t* outCount, int32_t* outCapabilities) {
@@ -376,40 +389,18 @@
return Error::None;
}
-//Gralloc Functions
-EmuHWC2::GrallocModule::GrallocModule() {
- int ret;
+const native_handle_t* EmuHWC2::allocateDisplayColorBuffer() {
+ typedef CbManager::BufferUsage BufferUsage;
- ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mHw);
- assert(ret == 0 && "Gralloc moudle not found");
- mGralloc = reinterpret_cast<const gralloc_module_t*>(mHw);
-
- ret = framebuffer_open(mHw, &mFbDev);
- assert(ret == 0 && "Fail to open FrameBuffer device");
+ return mCbManager.allocateBuffer(
+ mDisplayWidth,
+ mDisplayHeight,
+ CbManager::PixelFormat::RGBA_8888,
+ (BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_RENDER_TARGET));
}
-EmuHWC2::GrallocModule::~GrallocModule() {
- if (mHandle != nullptr) {
- mGralloc->unregisterBuffer(mGralloc, mHandle);
- mAllocDev->free(mAllocDev, mHandle);
- ALOGI("free targetCb %u", cb_handle_t::from(mHandle)->hostHandle);
- }
-}
-
-uint32_t EmuHWC2::GrallocModule::getTargetCb() {
- if (mHandle == nullptr) {
- int ret, stride;
- ret = gralloc_open(mHw, &mAllocDev);
- assert(ret == 0 && "Fail to open GPU device");
- ret = mAllocDev->alloc(mAllocDev,
- mFbDev->width, mFbDev->height, mFbDev->format,
- GRALLOC_USAGE_HW_COMPOSER|GRALLOC_USAGE_HW_RENDER,
- &mHandle, &stride);
- assert(ret == 0 && "Fail to allocate target ColorBuffer");
- mGralloc->registerBuffer(mGralloc, mHandle);
- ALOGI("targetCb %u", cb_handle_t::from(mHandle)->hostHandle);
- }
- return cb_handle_t::from(mHandle)->hostHandle;
+void EmuHWC2::freeDisplayColorBuffer(const native_handle_t* h) {
+ mCbManager.freeBuffer(h);
}
// Display functions
@@ -453,10 +444,14 @@
mActiveConfig(nullptr),
mColorModes(),
mSetColorTransform(false),
- mStateMutex()
- {
+ mStateMutex() {
mVsyncThread.run("", -19 /* ANDROID_PRIORITY_URGENT_AUDIO */);
- }
+ mTargetCb = device.allocateDisplayColorBuffer();
+}
+
+EmuHWC2::Display::~Display() {
+ mDevice.freeDisplayColorBuffer(mTargetCb);
+}
Error EmuHWC2::Display::acceptChanges() {
ALOGVV("%s: displayId %u", __FUNCTION__, (uint32_t)mId);
@@ -759,9 +754,11 @@
mReleaseFences.clear();
if (numLayer == 0) {
- ALOGVV("No layers, exit");
- mGralloc->getFb()->post(mGralloc->getFb(), mClientTarget.getBuffer());
- *outRetireFence = mClientTarget.getFence();
+ ALOGW("No layers, exit, buffer %p", mClientTarget.getBuffer());
+ if (mClientTarget.getBuffer()) {
+ post(hostCon, rcEnc, mClientTarget.getBuffer());
+ *outRetireFence = mClientTarget.getFence();
+ }
return Error::None;
}
@@ -812,10 +809,10 @@
ALOGV("%s: acquire fence not set for layer %u",
__FUNCTION__, (uint32_t)layer->getId());
}
- const cb_handle_t *cb =
- cb_handle_t::from(layer->getLayerBuffer().getBuffer());
+ const native_handle_t *cb =
+ layer->getLayerBuffer().getBuffer();
if (cb != nullptr) {
- l->cbHandle = cb->hostHandle;
+ l->cbHandle = hostCon->grallocHelper()->getHostHandle(cb);
}
else {
ALOGE("%s null buffer for layer %d", __FUNCTION__,
@@ -843,12 +840,12 @@
}
if (hostCompositionV1) {
p->version = 1;
- p->targetHandle = mGralloc->getTargetCb();
+ p->targetHandle = hostCon->grallocHelper()->getHostHandle(mTargetCb);
p->numLayers = numLayer;
} else {
p2->version = 2;
p2->displayId = mHostDisplayId;
- p2->targetHandle = mGralloc->getTargetCb();
+ p2->targetHandle = hostCon->grallocHelper()->getHostHandle(mTargetCb);
p2->numLayers = numLayer;
}
@@ -892,7 +889,7 @@
hostCon->unlock();
} else {
// we set all layers Composition::Client, so do nothing.
- mGralloc->getFb()->post(mGralloc->getFb(), mClientTarget.getBuffer());
+ post(hostCon, rcEnc, mClientTarget.getBuffer());
*outRetireFence = mClientTarget.getFence();
ALOGV("%s fallback to post, returns outRetireFence %d",
__FUNCTION__, *outRetireFence);
@@ -923,9 +920,6 @@
int32_t acquireFence, int32_t /*dataspace*/, hwc_region_t /*damage*/) {
ALOGVV("%s", __FUNCTION__);
- const cb_handle_t *cb = cb_handle_t::from(target);
- ALOGV("%s: display(%u) buffer handle %p cb %d, acquireFence %d", __FUNCTION__,
- (uint32_t)mId, target, cb->hostHandle, acquireFence);
std::unique_lock<std::mutex> lock(mStateMutex);
mClientTarget.setBuffer(target);
mClientTarget.setFence(acquireFence);
@@ -1153,7 +1147,7 @@
// approved pnp ids can be found here: https://uefi.org/pnp_id_list
// pnp id: GGL, name: EMU_display_0, last byte is checksum
// display id is local:8141603649153536
-static const std::vector<uint8_t> sEDID0 {
+static const uint8_t sEDID0[] = {
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27,
0x12, 0x48, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
@@ -1166,7 +1160,7 @@
// pnp id: GGL, name: EMU_display_1
// display id is local:8140900251843329
-static const std::vector<uint8_t> sEDID1 {
+static const uint8_t sEDID1[] = {
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27,
0x12, 0x48, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
@@ -1179,7 +1173,7 @@
// pnp id: GGL, name: EMU_display_2
// display id is local:8140940453066754
-static const std::vector<uint8_t> sEDID2 {
+static const uint8_t sEDID2[] = {
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1c, 0xec, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
0x1b, 0x10, 0x01, 0x03, 0x80, 0x50, 0x2d, 0x78, 0x0a, 0x0d, 0xc9, 0xa0, 0x57, 0x47, 0x98, 0x27,
0x12, 0x48, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
@@ -1190,42 +1184,44 @@
0x00, 0x45, 0x4d, 0x55, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x32, 0x00, 0x49
};
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
Error EmuHWC2::Display::getDisplayIdentificationData(uint8_t* outPort,
uint32_t* outDataSize, uint8_t* outData) {
ALOGVV("%s DisplayId %u", __FUNCTION__, (uint32_t)mId);
if (outPort == nullptr || outDataSize == nullptr)
return Error::BadParameter;
- uint32_t len = std::min(*outDataSize, (uint32_t)(sEDID0.size()));
- if (outData != nullptr && len < (uint32_t)(sEDID0.size())) {
+ uint32_t len = std::min(*outDataSize, (uint32_t)ARRAY_SIZE(sEDID0));
+ if (outData != nullptr && len < (uint32_t)ARRAY_SIZE(sEDID0)) {
ALOGW("%s DisplayId %u, small buffer size: %u is specified",
__FUNCTION__, (uint32_t)mId, len);
}
- *outDataSize = (int32_t)(sEDID0.size());
+ *outDataSize = ARRAY_SIZE(sEDID0);
switch (mId) {
case 0:
*outPort = 0;
if (outData)
- memcpy(outData, sEDID0.data(), len);
+ memcpy(outData, sEDID0, len);
break;
case 1:
*outPort = 1;
if (outData)
- memcpy(outData, sEDID1.data(), len);
+ memcpy(outData, sEDID1, len);
break;
case 2:
*outPort = 2;
if (outData)
- memcpy(outData, sEDID2.data(), len);
+ memcpy(outData, sEDID2, len);
break;
default:
*outPort = (uint8_t)mId;
if (outData) {
- memcpy(outData, sEDID2.data(), len);
- uint32_t size = sEDID0.size();
+ memcpy(outData, sEDID2, len);
+ uint32_t size = ARRAY_SIZE(sEDID0);
// change the name to EMU_display_<mID>
// note the 3rd char from back is the number, _0, _1, _2, etc.
if (len >= size - 2)
@@ -1278,18 +1274,17 @@
return Error::None;
}
-int EmuHWC2::Display::populatePrimaryConfigs() {
+int EmuHWC2::Display::populatePrimaryConfigs(int width, int height, int dpiX, int dpiY) {
ALOGVV("%s DisplayId %u", __FUNCTION__, (uint32_t)mId);
std::unique_lock<std::mutex> lock(mStateMutex);
- mGralloc.reset(new GrallocModule());
auto newConfig = std::make_shared<Config>(*this);
// vsync is 60 hz;
newConfig->setAttribute(Attribute::VsyncPeriod, mVsyncPeriod);
- newConfig->setAttribute(Attribute::Width, mGralloc->getFb()->width);
- newConfig->setAttribute(Attribute::Height, mGralloc->getFb()->height);
- newConfig->setAttribute(Attribute::DpiX, mGralloc->getFb()->xdpi*1000);
- newConfig->setAttribute(Attribute::DpiY, mGralloc->getFb()->ydpi*1000);
+ newConfig->setAttribute(Attribute::Width, width);
+ newConfig->setAttribute(Attribute::Height, height);
+ newConfig->setAttribute(Attribute::DpiX, dpiX * 1000);
+ newConfig->setAttribute(Attribute::DpiY, dpiY * 1000);
newConfig->setId(static_cast<hwc2_config_t>(mConfigs.size()));
ALOGV("Found new config %d: %s", (uint32_t)newConfig->getId(),
@@ -1306,13 +1301,22 @@
return 0;
}
+void EmuHWC2::Display::post(HostConnection *hostCon,
+ ExtendedRCEncoderContext *rcEnc,
+ buffer_handle_t h) {
+ assert(cb && "native_handle_t::from(h) failed");
+
+ hostCon->lock();
+ rcEnc->rcFBPost(rcEnc, hostCon->grallocHelper()->getHostHandle(h));
+ hostCon->unlock();
+}
+
HWC2::Error EmuHWC2::Display::populateSecondaryConfigs(uint32_t width, uint32_t height,
uint32_t dpi) {
ALOGVV("%s DisplayId %u, width %u, height %u, dpi %u",
__FUNCTION__, (uint32_t)mId, width, height, dpi);
std::unique_lock<std::mutex> lock(mStateMutex);
- mGralloc.reset(new GrallocModule());
auto newConfig = std::make_shared<Config>(*this);
// vsync is 60 hz;
newConfig->setAttribute(Attribute::VsyncPeriod, mVsyncPeriod);
@@ -1390,7 +1394,6 @@
return output;
}
-
// VsyncThread function
bool EmuHWC2::Display::VsyncThread::threadLoop() {
struct timespec rt;
@@ -1404,19 +1407,38 @@
int sent = 0;
int lastSent = 0;
bool vsyncEnabled = false;
+
struct timespec wait_time;
wait_time.tv_sec = 0;
wait_time.tv_nsec = mDisplay.mVsyncPeriod;
+ const int64_t kOneRefreshNs = mDisplay.mVsyncPeriod;
+ const int64_t kOneSecondNs = 1000ULL * 1000ULL * 1000ULL;
+ int64_t lastTimeNs = -1;
+ int64_t phasedWaitNs = 0;
+ int64_t currentNs = 0;
while (true) {
- int err = nanosleep(&wait_time, NULL);
- if (err == -1) {
- if (errno == EINTR) {
- break;
- }
- ALOGE("%s: error in vsync thread: %s", __FUNCTION__, strerror(errno));
+ clock_gettime(CLOCK_MONOTONIC, &rt);
+ currentNs = rt.tv_nsec + rt.tv_sec * kOneSecondNs;
+
+ if (lastTimeNs < 0) {
+ phasedWaitNs = currentNs + kOneRefreshNs;
+ } else {
+ phasedWaitNs = kOneRefreshNs *
+ (( currentNs - lastTimeNs) / kOneRefreshNs + 1) +
+ lastTimeNs;
}
+ wait_time.tv_sec = phasedWaitNs / kOneSecondNs;
+ wait_time.tv_nsec = phasedWaitNs - wait_time.tv_sec * kOneSecondNs;
+
+ int ret;
+ do {
+ ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &wait_time, NULL);
+ } while (ret == -1 && errno == EINTR);
+
+ lastTimeNs = phasedWaitNs;
+
std::unique_lock<std::mutex> lock(mDisplay.mStateMutex);
vsyncEnabled = (mDisplay.mVsyncEnabled == Vsync::Enable);
lock.unlock();
@@ -1425,20 +1447,13 @@
continue;
}
- if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
- ALOGE("%s: error in vsync thread clock_gettime: %s",
- __FUNCTION__, strerror(errno));
- }
-
- int64_t timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec;
-
lock.lock();
const auto& callbackInfo = mDisplay.mDevice.mCallbacks[Callback::Vsync];
auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer);
lock.unlock();
if (vsync) {
- vsync(callbackInfo.data, mDisplay.mId, timestamp);
+ vsync(callbackInfo.data, mDisplay.mId, lastTimeNs);
}
if (rt.tv_sec - lastLogged >= logInterval) {
@@ -1596,7 +1611,8 @@
int EmuHWC2::populatePrimary() {
int ret = 0;
auto display = std::make_shared<Display>(*this, HWC2::DisplayType::Physical);
- ret = display->populatePrimaryConfigs();
+ ret = display->populatePrimaryConfigs(mDisplayWidth, mDisplayHeight,
+ mDisplayDpiX, mDisplayDpiY);
if (ret != 0) {
return ret;
}
@@ -1650,11 +1666,11 @@
return -1;
}
while (!values.empty()) {
- uint64_t physicalId = values[0];
+ // uint64_t physicalId = values[0];
uint32_t width = values[1];
uint32_t height = values[2];
uint32_t dpi = values[3];
- uint32_t flags = values[4];
+ // uint32_t flags = values[4];
values.erase(values.begin(), values.begin() + 5);
Error ret = Error::None;
diff --git a/system/hwc2/EmuHWC2.h b/system/hwc2/EmuHWC2.h
index ff056ca..8cb71c1 100644
--- a/system/hwc2/EmuHWC2.h
+++ b/system/hwc2/EmuHWC2.h
@@ -33,8 +33,10 @@
#include <unordered_set>
#include <unordered_map>
#include <set>
+
#include <cutils/native_handle.h>
+#include "cbmanager.h"
#include "MiniFence.h"
#include "HostConnection.h"
@@ -137,20 +139,6 @@
sp<MiniFence> mFence;
};
- class GrallocModule {
- public:
- GrallocModule();
- ~GrallocModule();
- framebuffer_device_t* getFb() { return mFbDev; }
- uint32_t getTargetCb();
- private:
- const hw_module_t* mHw = nullptr;
- const gralloc_module_t* mGralloc = nullptr;
- alloc_device_t* mAllocDev = nullptr;
- framebuffer_device_t* mFbDev = nullptr;
- buffer_handle_t mHandle = nullptr;
- };
-
typedef struct compose_layer {
uint32_t cbHandle;
hwc2_composition_t composeMode;
@@ -216,6 +204,7 @@
class Display {
public:
Display(EmuHWC2& device, HWC2::DisplayType type);
+ ~Display();
hwc2_display_t getId() const {return mId;}
// HWC2 Display functions
@@ -267,11 +256,14 @@
HWC2::Error setDisplayBrightness(float brightness);
// Read configs from PRIMARY Display
- int populatePrimaryConfigs();
+ int populatePrimaryConfigs(int width, int height, int dpiX, int dpiY);
HWC2::Error populateSecondaryConfigs(uint32_t width, uint32_t height,
uint32_t dpi);
private:
+ void post(HostConnection *hostCon, ExtendedRCEncoderContext *rcEnc,
+ buffer_handle_t h);
+
class Config {
public:
Config(Display& display)
@@ -379,12 +371,11 @@
// called. To prevent a bad state from crashing us during a dump
// call, all public calls into Display must acquire this mutex.
mutable std::mutex mStateMutex;
- std::unique_ptr<GrallocModule> mGralloc;
std::unique_ptr<ComposeMsg> mComposeMsg;
std::unique_ptr<ComposeMsg_v2> mComposeMsg_v2;
int mSyncDeviceFd;
-
- };
+ const native_handle_t* mTargetCb;
+ };
template<typename MF, MF memFunc, typename ...Args>
static int32_t displayHook(hwc2_device_t* device, hwc2_display_t displayId,
@@ -472,6 +463,11 @@
std::tuple<Layer*, HWC2::Error> getLayer(hwc2_display_t displayId,
hwc2_layer_t layerId);
+ HWC2::Error initDisplayParameters();
+ const native_handle_t* allocateDisplayColorBuffer();
+ void freeDisplayColorBuffer(const native_handle_t* h);
+
+ CbManager mCbManager;
std::unordered_set<HWC2::Capability> mCapabilities;
// These are potentially accessed from multiple threads, and are protected
@@ -488,6 +484,10 @@
std::map<hwc2_display_t, std::shared_ptr<Display>> mDisplays;
std::unordered_map<hwc2_layer_t, std::shared_ptr<Layer>> mLayers;
+ int mDisplayWidth;
+ int mDisplayHeight;
+ int mDisplayDpiX;
+ int mDisplayDpiY;
};
}
diff --git a/system/include/cbmanager.h b/system/include/cbmanager.h
new file mode 100644
index 0000000..4bddedb
--- /dev/null
+++ b/system/include/cbmanager.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_GOLDFISH_OPENGL_SYSTEM_CBMANAGER_CBMANAGER_H
+#define ANDROID_GOLDFISH_OPENGL_SYSTEM_CBMANAGER_CBMANAGER_H
+
+#include <cutils/native_handle.h>
+#include <log/log.h>
+
+#include <memory>
+#include <android/hardware/graphics/common/1.0/types.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+
+#include "gralloc_cb.h"
+
+namespace android {
+
+class CbManager {
+public:
+ typedef hardware::graphics::common::V1_0::BufferUsage BufferUsage;
+ typedef hardware::graphics::common::V1_0::PixelFormat PixelFormat;
+ typedef hardware::graphics::mapper::V2_0::YCbCrLayout YCbCrLayout;
+ typedef hardware::hidl_bitfield<BufferUsage> BufferUsageBits;
+
+ CbManager();
+
+ class CbManagerImpl {
+ public:
+ virtual ~CbManagerImpl() {}
+ virtual native_handle_t* allocateBuffer(int width,
+ int height,
+ PixelFormat format,
+ BufferUsageBits usage) = 0;
+ virtual void freeBuffer(const native_handle_t* h) = 0;
+
+ virtual int lockBuffer(native_handle_t& handle,
+ BufferUsageBits usage,
+ int left, int top, int width, int height,
+ void** vaddr) = 0;
+
+ virtual int lockYCbCrBuffer(native_handle_t& handle,
+ BufferUsageBits usage,
+ int left, int top, int width, int height,
+ YCbCrLayout* ycbcr) = 0;
+
+ virtual int unlockBuffer(native_handle_t& handle) = 0;
+ };
+
+ native_handle_t* allocateBuffer(
+ int width, int height, PixelFormat format, BufferUsageBits usage) {
+ return mImpl->allocateBuffer(width, height, format, usage);
+ }
+
+ void freeBuffer(const native_handle_t* h) {
+ mImpl->freeBuffer(h);
+ }
+
+ int lockBuffer(native_handle_t& handle,
+ BufferUsageBits usage,
+ int left, int top, int width, int height,
+ void** vaddr) {
+ return mImpl->lockBuffer(handle, usage, left, top, width, height, vaddr);
+ }
+
+ int lockBuffer(buffer_handle_t h,
+ BufferUsageBits usage,
+ int left, int top, int width, int height,
+ void** vaddr) {
+ native_handle_t* cb = const_cast<native_handle_t*>(h);
+ if (cb) {
+ return lockBuffer(*cb, usage, left, top, width, height, vaddr);
+ } else {
+ return -1;
+ }
+ }
+
+
+ int lockYCbCrBuffer(native_handle_t& handle,
+ BufferUsageBits usage,
+ int left, int top, int width, int height,
+ YCbCrLayout* ycbcr) {
+ return mImpl->lockYCbCrBuffer(handle, usage, left, top, width, height, ycbcr);
+ }
+
+ int lockYCbCrBuffer(buffer_handle_t h,
+ BufferUsageBits usage,
+ int left, int top, int width, int height,
+ YCbCrLayout* ycbcr) {
+ native_handle_t* cb = const_cast<native_handle_t*>(h);
+ if (cb) {
+ return lockYCbCrBuffer(*cb, usage, left, top, width, height, ycbcr);
+ } else {
+ return -1;
+ }
+ }
+
+ int unlockBuffer(native_handle_t& handle) {
+ return mImpl->unlockBuffer(handle);
+ }
+
+ int unlockBuffer(buffer_handle_t h) {
+ native_handle_t* cb = const_cast<native_handle_t*>(h);
+ if (cb) {
+ return unlockBuffer(*cb);
+ } else {
+ return -1;
+ }
+ }
+
+ // Specific to goldfish, for obtaining offsets
+ // into host coherent memory
+ // (requires address space devce)
+ static uint64_t getOffset(const buffer_handle_t h) {
+ const cb_handle_t* cb = cb_handle_t::from(h);
+ if (!cb->isValid()) {
+ ALOGE("%s: FATAL: using incompatible native_handle_t for "
+ "host coherent mapping offset",
+ __func__);
+ abort();
+ }
+ return cb ? cb->getMmapedOffset() : -1;
+ }
+
+private:
+ std::unique_ptr<CbManagerImpl> mImpl;
+};
+
+} // namespace android
+
+#endif // ANDROID_GOLDFISH_OPENGL_SYSTEM_CBMANAGER_CBMANAGER_H
diff --git a/system/renderControl_enc/CMakeLists.txt b/system/renderControl_enc/CMakeLists.txt
index d557a99..c874e25 100644
--- a/system/renderControl_enc/CMakeLists.txt
+++ b/system/renderControl_enc/CMakeLists.txt
@@ -3,7 +3,7 @@
# which will re-generate this file.
android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc/Android.mk" "780a007ac7a3d2255372ddf40e03aeb10e4c759343d2532f6ddf769f4df73810")
set(_renderControl_enc_src renderControl_client_context.cpp renderControl_enc.cpp renderControl_entry.cpp)
-android_add_shared_library(_renderControl_enc)
+android_add_library(TARGET _renderControl_enc SHARED LICENSE Apache-2.0 SRC renderControl_client_context.cpp renderControl_enc.cpp renderControl_entry.cpp)
target_include_directories(_renderControl_enc PRIVATE ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest)
target_compile_definitions(_renderControl_enc PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN")
target_compile_options(_renderControl_enc PRIVATE "-fvisibility=default" "-Wno-unused-parameter" "-Wno-unused-function")
diff --git a/system/renderControl_enc/renderControl_client_context.cpp b/system/renderControl_enc/renderControl_client_context.cpp
index 476d0da..54c3f93 100644
--- a/system/renderControl_enc/renderControl_client_context.cpp
+++ b/system/renderControl_enc/renderControl_client_context.cpp
@@ -57,6 +57,7 @@
rcSetDisplayPose = (rcSetDisplayPose_client_proc_t) getProc("rcSetDisplayPose", userData);
rcSetColorBufferVulkanMode = (rcSetColorBufferVulkanMode_client_proc_t) getProc("rcSetColorBufferVulkanMode", userData);
rcReadColorBufferYUV = (rcReadColorBufferYUV_client_proc_t) getProc("rcReadColorBufferYUV", userData);
+ rcIsSyncSignaled = (rcIsSyncSignaled_client_proc_t) getProc("rcIsSyncSignaled", userData);
return 0;
}
diff --git a/system/renderControl_enc/renderControl_client_context.h b/system/renderControl_enc/renderControl_client_context.h
index 8905afa..12486c3 100644
--- a/system/renderControl_enc/renderControl_client_context.h
+++ b/system/renderControl_enc/renderControl_client_context.h
@@ -57,6 +57,7 @@
rcSetDisplayPose_client_proc_t rcSetDisplayPose;
rcSetColorBufferVulkanMode_client_proc_t rcSetColorBufferVulkanMode;
rcReadColorBufferYUV_client_proc_t rcReadColorBufferYUV;
+ rcIsSyncSignaled_client_proc_t rcIsSyncSignaled;
virtual ~renderControl_client_context_t() {}
typedef renderControl_client_context_t *CONTEXT_ACCESSOR_TYPE(void);
diff --git a/system/renderControl_enc/renderControl_client_proc.h b/system/renderControl_enc/renderControl_client_proc.h
index 6bba308..d64cf5c 100644
--- a/system/renderControl_enc/renderControl_client_proc.h
+++ b/system/renderControl_enc/renderControl_client_proc.h
@@ -59,6 +59,7 @@
typedef int (renderControl_APIENTRY *rcSetDisplayPose_client_proc_t) (void * ctx, uint32_t, GLint, GLint, uint32_t, uint32_t);
typedef GLint (renderControl_APIENTRY *rcSetColorBufferVulkanMode_client_proc_t) (void * ctx, uint32_t, uint32_t);
typedef void (renderControl_APIENTRY *rcReadColorBufferYUV_client_proc_t) (void * ctx, uint32_t, GLint, GLint, GLint, GLint, void*, uint32_t);
+typedef int (renderControl_APIENTRY *rcIsSyncSignaled_client_proc_t) (void * ctx, uint64_t);
#endif
diff --git a/system/renderControl_enc/renderControl_enc.cpp b/system/renderControl_enc/renderControl_enc.cpp
index 7b32c29..d0c3c75 100644
--- a/system/renderControl_enc/renderControl_enc.cpp
+++ b/system/renderControl_enc/renderControl_enc.cpp
@@ -1833,6 +1833,46 @@
}
}
+int rcIsSyncSignaled_enc(void *self , uint64_t sync)
+{
+
+ renderControl_encoder_context_t *ctx = (renderControl_encoder_context_t *)self;
+ IOStream *stream = ctx->m_stream;
+ ChecksumCalculator *checksumCalculator = ctx->m_checksumCalculator;
+ bool useChecksum = checksumCalculator->getVersion() > 0;
+
+ unsigned char *ptr;
+ unsigned char *buf;
+ const size_t sizeWithoutChecksum = 8 + 8;
+ const size_t checksumSize = checksumCalculator->checksumByteSize();
+ const size_t totalSize = sizeWithoutChecksum + checksumSize;
+ buf = stream->alloc(totalSize);
+ ptr = buf;
+ int tmp = OP_rcIsSyncSignaled;memcpy(ptr, &tmp, 4); ptr += 4;
+ memcpy(ptr, &totalSize, 4); ptr += 4;
+
+ memcpy(ptr, &sync, 8); ptr += 8;
+
+ if (useChecksum) checksumCalculator->addBuffer(buf, ptr-buf);
+ if (useChecksum) checksumCalculator->writeChecksum(ptr, checksumSize); ptr += checksumSize;
+
+
+ int retval;
+ stream->readback(&retval, 4);
+ if (useChecksum) checksumCalculator->addBuffer(&retval, 4);
+ if (useChecksum) {
+ unsigned char *checksumBufPtr = NULL;
+ unsigned char checksumBuf[ChecksumCalculator::kMaxChecksumSize];
+ if (checksumSize > 0) checksumBufPtr = &checksumBuf[0];
+ stream->readback(checksumBufPtr, checksumSize);
+ if (!checksumCalculator->validate(checksumBufPtr, checksumSize)) {
+ ALOGE("rcIsSyncSignaled: GL communication error, please report this issue to b.android.com.\n");
+ abort();
+ }
+ }
+ return retval;
+}
+
} // namespace
renderControl_encoder_context_t::renderControl_encoder_context_t(IOStream *stream, ChecksumCalculator *checksumCalculator)
@@ -1887,5 +1927,6 @@
this->rcSetDisplayPose = &rcSetDisplayPose_enc;
this->rcSetColorBufferVulkanMode = &rcSetColorBufferVulkanMode_enc;
this->rcReadColorBufferYUV = &rcReadColorBufferYUV_enc;
+ this->rcIsSyncSignaled = &rcIsSyncSignaled_enc;
}
diff --git a/system/renderControl_enc/renderControl_entry.cpp b/system/renderControl_enc/renderControl_entry.cpp
index 0974a96..0395d8b 100644
--- a/system/renderControl_enc/renderControl_entry.cpp
+++ b/system/renderControl_enc/renderControl_entry.cpp
@@ -52,6 +52,7 @@
int rcSetDisplayPose(uint32_t displayId, GLint x, GLint y, uint32_t w, uint32_t h);
GLint rcSetColorBufferVulkanMode(uint32_t colorBuffer, uint32_t mode);
void rcReadColorBufferYUV(uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, void* pixels, uint32_t pixels_size);
+ int rcIsSyncSignaled(uint64_t sync);
};
#ifndef GET_CONTEXT
@@ -342,3 +343,9 @@
ctx->rcReadColorBufferYUV(ctx, colorbuffer, x, y, width, height, pixels, pixels_size);
}
+int rcIsSyncSignaled(uint64_t sync)
+{
+ GET_CONTEXT;
+ return ctx->rcIsSyncSignaled(ctx, sync);
+}
+
diff --git a/system/renderControl_enc/renderControl_ftable.h b/system/renderControl_enc/renderControl_ftable.h
index da58a04..662ade8 100644
--- a/system/renderControl_enc/renderControl_ftable.h
+++ b/system/renderControl_enc/renderControl_ftable.h
@@ -55,6 +55,7 @@
{"rcSetDisplayPose", (void*)rcSetDisplayPose},
{"rcSetColorBufferVulkanMode", (void*)rcSetColorBufferVulkanMode},
{"rcReadColorBufferYUV", (void*)rcReadColorBufferYUV},
+ {"rcIsSyncSignaled", (void*)rcIsSyncSignaled},
};
static const int renderControl_num_funcs = sizeof(renderControl_funcs_by_name) / sizeof(struct _renderControl_funcs_by_name);
diff --git a/system/renderControl_enc/renderControl_opcodes.h b/system/renderControl_enc/renderControl_opcodes.h
index 2c3780b..338a38e 100644
--- a/system/renderControl_enc/renderControl_opcodes.h
+++ b/system/renderControl_enc/renderControl_opcodes.h
@@ -50,7 +50,8 @@
#define OP_rcSetDisplayPose 10044
#define OP_rcSetColorBufferVulkanMode 10045
#define OP_rcReadColorBufferYUV 10046
-#define OP_last 10047
+#define OP_rcIsSyncSignaled 10047
+#define OP_last 10048
#endif
diff --git a/system/vulkan/CMakeLists.txt b/system/vulkan/CMakeLists.txt
index c980bda..a71c07f 100644
--- a/system/vulkan/CMakeLists.txt
+++ b/system/vulkan/CMakeLists.txt
@@ -3,7 +3,7 @@
# which will re-generate this file.
android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/vulkan/Android.mk" "691427017f29de6b082ad25cb73b87443d4072a04b4316897bb92983674ad5bf")
set(vulkan.ranchu_src func_table.cpp goldfish_vulkan.cpp)
-android_add_shared_library(vulkan.ranchu)
+android_add_library(TARGET vulkan.ranchu SHARED LICENSE Apache-2.0 SRC func_table.cpp goldfish_vulkan.cpp)
target_include_directories(vulkan.ranchu PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon/bionic-include ${GOLDFISH_DEVICE_ROOT}/system/OpenglSystemCommon ${GOLDFISH_DEVICE_ROOT}/bionic/libc/private ${GOLDFISH_DEVICE_ROOT}/bionic/libc/platform ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv2_enc ${GOLDFISH_DEVICE_ROOT}/system/GLESv1_enc ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/system/vulkan ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/host/include)
target_compile_definitions(vulkan.ranchu PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"goldfish_vulkan\"" "-DVK_USE_PLATFORM_ANDROID_KHR" "-DVK_NO_PROTOTYPES")
target_compile_options(vulkan.ranchu PRIVATE "-fvisibility=default" "-Wno-unused-parameter" "-Wno-missing-field-initializers" "-fvisibility=hidden" "-fstrict-aliasing" "-Wno-unused-function")
diff --git a/system/vulkan/func_table.cpp b/system/vulkan/func_table.cpp
index 2d0b138..c9dd80d 100644
--- a/system/vulkan/func_table.cpp
+++ b/system/vulkan/func_table.cpp
@@ -31,6 +31,8 @@
#include "goldfish_vk_private_defs.h"
+#include <log/log.h>
+
// Stuff we are not going to use but if included,
// will cause compile errors. These are Android Vulkan
// required extensions, but the approach will be to
@@ -40,6 +42,11 @@
namespace goldfish_vk {
+static void sOnInvalidDynamicallyCheckedCall(const char* apiname, const char* neededFeature)
+{
+ ALOGE("invalid call to %s: %s not supported", apiname, neededFeature);
+ abort();
+}
#ifdef VK_VERSION_1_0
static VkResult entry_vkCreateInstance(
const VkInstanceCreateInfo* pCreateInfo,
@@ -1593,6 +1600,22 @@
vkBindBufferMemory2_VkResult_return = resources->on_vkBindBufferMemory2(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
return vkBindBufferMemory2_VkResult_return;
}
+static VkResult dynCheck_entry_vkBindBufferMemory2(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindBufferMemoryInfo* pBindInfos)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkBindBufferMemory2", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkBindBufferMemory2");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkBindBufferMemory2_VkResult_return = (VkResult)0;
+ vkBindBufferMemory2_VkResult_return = resources->on_vkBindBufferMemory2(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
+ return vkBindBufferMemory2_VkResult_return;
+}
static VkResult entry_vkBindImageMemory2(
VkDevice device,
uint32_t bindInfoCount,
@@ -1605,6 +1628,22 @@
vkBindImageMemory2_VkResult_return = resources->on_vkBindImageMemory2(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
return vkBindImageMemory2_VkResult_return;
}
+static VkResult dynCheck_entry_vkBindImageMemory2(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindImageMemoryInfo* pBindInfos)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkBindImageMemory2", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkBindImageMemory2");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkBindImageMemory2_VkResult_return = (VkResult)0;
+ vkBindImageMemory2_VkResult_return = resources->on_vkBindImageMemory2(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
+ return vkBindImageMemory2_VkResult_return;
+}
static void entry_vkGetDeviceGroupPeerMemoryFeatures(
VkDevice device,
uint32_t heapIndex,
@@ -1616,6 +1655,22 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkGetDeviceGroupPeerMemoryFeatures(device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures);
}
+static void dynCheck_entry_vkGetDeviceGroupPeerMemoryFeatures(
+ VkDevice device,
+ uint32_t heapIndex,
+ uint32_t localDeviceIndex,
+ uint32_t remoteDeviceIndex,
+ VkPeerMemoryFeatureFlags* pPeerMemoryFeatures)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetDeviceGroupPeerMemoryFeatures", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkGetDeviceGroupPeerMemoryFeatures");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkGetDeviceGroupPeerMemoryFeatures(device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures);
+}
static void entry_vkCmdSetDeviceMask(
VkCommandBuffer commandBuffer,
uint32_t deviceMask)
@@ -1660,6 +1715,20 @@
auto resources = ResourceTracker::get();
resources->on_vkGetImageMemoryRequirements2(vkEnc, device, pInfo, pMemoryRequirements);
}
+static void dynCheck_entry_vkGetImageMemoryRequirements2(
+ VkDevice device,
+ const VkImageMemoryRequirementsInfo2* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetImageMemoryRequirements2", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkGetImageMemoryRequirements2");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ resources->on_vkGetImageMemoryRequirements2(vkEnc, device, pInfo, pMemoryRequirements);
+}
static void entry_vkGetBufferMemoryRequirements2(
VkDevice device,
const VkBufferMemoryRequirementsInfo2* pInfo,
@@ -1670,6 +1739,20 @@
auto resources = ResourceTracker::get();
resources->on_vkGetBufferMemoryRequirements2(vkEnc, device, pInfo, pMemoryRequirements);
}
+static void dynCheck_entry_vkGetBufferMemoryRequirements2(
+ VkDevice device,
+ const VkBufferMemoryRequirementsInfo2* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetBufferMemoryRequirements2", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkGetBufferMemoryRequirements2");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ resources->on_vkGetBufferMemoryRequirements2(vkEnc, device, pInfo, pMemoryRequirements);
+}
static void entry_vkGetImageSparseMemoryRequirements2(
VkDevice device,
const VkImageSparseMemoryRequirementsInfo2* pInfo,
@@ -1680,6 +1763,21 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkGetImageSparseMemoryRequirements2(device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
}
+static void dynCheck_entry_vkGetImageSparseMemoryRequirements2(
+ VkDevice device,
+ const VkImageSparseMemoryRequirementsInfo2* pInfo,
+ uint32_t* pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2* pSparseMemoryRequirements)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetImageSparseMemoryRequirements2", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkGetImageSparseMemoryRequirements2");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkGetImageSparseMemoryRequirements2(device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
+}
static void entry_vkGetPhysicalDeviceFeatures2(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceFeatures2* pFeatures)
@@ -1753,6 +1851,20 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkTrimCommandPool(device, commandPool, flags);
}
+static void dynCheck_entry_vkTrimCommandPool(
+ VkDevice device,
+ VkCommandPool commandPool,
+ VkCommandPoolTrimFlags flags)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkTrimCommandPool", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkTrimCommandPool");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkTrimCommandPool(device, commandPool, flags);
+}
static void entry_vkGetDeviceQueue2(
VkDevice device,
const VkDeviceQueueInfo2* pQueueInfo,
@@ -1762,6 +1874,20 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkGetDeviceQueue2(device, pQueueInfo, pQueue);
}
+static void dynCheck_entry_vkGetDeviceQueue2(
+ VkDevice device,
+ const VkDeviceQueueInfo2* pQueueInfo,
+ VkQueue* pQueue)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetDeviceQueue2", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkGetDeviceQueue2");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkGetDeviceQueue2(device, pQueueInfo, pQueue);
+}
static VkResult entry_vkCreateSamplerYcbcrConversion(
VkDevice device,
const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
@@ -1775,6 +1901,23 @@
vkCreateSamplerYcbcrConversion_VkResult_return = resources->on_vkCreateSamplerYcbcrConversion(vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pYcbcrConversion);
return vkCreateSamplerYcbcrConversion_VkResult_return;
}
+static VkResult dynCheck_entry_vkCreateSamplerYcbcrConversion(
+ VkDevice device,
+ const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSamplerYcbcrConversion* pYcbcrConversion)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkCreateSamplerYcbcrConversion", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkCreateSamplerYcbcrConversion");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkCreateSamplerYcbcrConversion_VkResult_return = (VkResult)0;
+ vkCreateSamplerYcbcrConversion_VkResult_return = resources->on_vkCreateSamplerYcbcrConversion(vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pYcbcrConversion);
+ return vkCreateSamplerYcbcrConversion_VkResult_return;
+}
static void entry_vkDestroySamplerYcbcrConversion(
VkDevice device,
VkSamplerYcbcrConversion ycbcrConversion,
@@ -1785,6 +1928,20 @@
auto resources = ResourceTracker::get();
resources->on_vkDestroySamplerYcbcrConversion(vkEnc, device, ycbcrConversion, pAllocator);
}
+static void dynCheck_entry_vkDestroySamplerYcbcrConversion(
+ VkDevice device,
+ VkSamplerYcbcrConversion ycbcrConversion,
+ const VkAllocationCallbacks* pAllocator)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkDestroySamplerYcbcrConversion", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkDestroySamplerYcbcrConversion");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ resources->on_vkDestroySamplerYcbcrConversion(vkEnc, device, ycbcrConversion, pAllocator);
+}
static VkResult entry_vkCreateDescriptorUpdateTemplate(
VkDevice device,
const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
@@ -1797,6 +1954,23 @@
vkCreateDescriptorUpdateTemplate_VkResult_return = vkEnc->vkCreateDescriptorUpdateTemplate(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
return vkCreateDescriptorUpdateTemplate_VkResult_return;
}
+static VkResult dynCheck_entry_vkCreateDescriptorUpdateTemplate(
+ VkDevice device,
+ const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkCreateDescriptorUpdateTemplate", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkCreateDescriptorUpdateTemplate");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkCreateDescriptorUpdateTemplate_VkResult_return = (VkResult)0;
+ vkCreateDescriptorUpdateTemplate_VkResult_return = vkEnc->vkCreateDescriptorUpdateTemplate(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
+ return vkCreateDescriptorUpdateTemplate_VkResult_return;
+}
static void entry_vkDestroyDescriptorUpdateTemplate(
VkDevice device,
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
@@ -1806,6 +1980,20 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkDestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator);
}
+static void dynCheck_entry_vkDestroyDescriptorUpdateTemplate(
+ VkDevice device,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const VkAllocationCallbacks* pAllocator)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkDestroyDescriptorUpdateTemplate", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkDestroyDescriptorUpdateTemplate");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkDestroyDescriptorUpdateTemplate(device, descriptorUpdateTemplate, pAllocator);
+}
static void entry_vkUpdateDescriptorSetWithTemplate(
VkDevice device,
VkDescriptorSet descriptorSet,
@@ -1817,6 +2005,21 @@
auto resources = ResourceTracker::get();
resources->on_vkUpdateDescriptorSetWithTemplate(vkEnc, device, descriptorSet, descriptorUpdateTemplate, pData);
}
+static void dynCheck_entry_vkUpdateDescriptorSetWithTemplate(
+ VkDevice device,
+ VkDescriptorSet descriptorSet,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const void* pData)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkUpdateDescriptorSetWithTemplate", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkUpdateDescriptorSetWithTemplate");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ resources->on_vkUpdateDescriptorSetWithTemplate(vkEnc, device, descriptorSet, descriptorUpdateTemplate, pData);
+}
static void entry_vkGetPhysicalDeviceExternalBufferProperties(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo,
@@ -1854,6 +2057,20 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkGetDescriptorSetLayoutSupport(device, pCreateInfo, pSupport);
}
+static void dynCheck_entry_vkGetDescriptorSetLayoutSupport(
+ VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
+ VkDescriptorSetLayoutSupport* pSupport)
+{
+ auto resources = ResourceTracker::get();
+ if (resources->getApiVersionFromDevice(device) < VK_API_VERSION_1_1)
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetDescriptorSetLayoutSupport", "VK_VERSION_1_1");
+ }
+ AEMU_SCOPED_TRACE("vkGetDescriptorSetLayoutSupport");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkGetDescriptorSetLayoutSupport(device, pCreateInfo, pSupport);
+}
#endif
#ifdef VK_KHR_surface
static void entry_vkDestroySurfaceKHR(
@@ -1926,6 +2143,23 @@
vkCreateSwapchainKHR_VkResult_return = vkEnc->vkCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
return vkCreateSwapchainKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkCreateSwapchainKHR(
+ VkDevice device,
+ const VkSwapchainCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSwapchainKHR* pSwapchain)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_swapchain"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkCreateSwapchainKHR", "VK_KHR_swapchain");
+ }
+ AEMU_SCOPED_TRACE("vkCreateSwapchainKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkCreateSwapchainKHR_VkResult_return = (VkResult)0;
+ vkCreateSwapchainKHR_VkResult_return = vkEnc->vkCreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
+ return vkCreateSwapchainKHR_VkResult_return;
+}
static void entry_vkDestroySwapchainKHR(
VkDevice device,
VkSwapchainKHR swapchain,
@@ -1935,6 +2169,20 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkDestroySwapchainKHR(device, swapchain, pAllocator);
}
+static void dynCheck_entry_vkDestroySwapchainKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ const VkAllocationCallbacks* pAllocator)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_swapchain"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkDestroySwapchainKHR", "VK_KHR_swapchain");
+ }
+ AEMU_SCOPED_TRACE("vkDestroySwapchainKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkDestroySwapchainKHR(device, swapchain, pAllocator);
+}
static VkResult entry_vkGetSwapchainImagesKHR(
VkDevice device,
VkSwapchainKHR swapchain,
@@ -1947,6 +2195,23 @@
vkGetSwapchainImagesKHR_VkResult_return = vkEnc->vkGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
return vkGetSwapchainImagesKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetSwapchainImagesKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint32_t* pSwapchainImageCount,
+ VkImage* pSwapchainImages)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_swapchain"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetSwapchainImagesKHR", "VK_KHR_swapchain");
+ }
+ AEMU_SCOPED_TRACE("vkGetSwapchainImagesKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetSwapchainImagesKHR_VkResult_return = (VkResult)0;
+ vkGetSwapchainImagesKHR_VkResult_return = vkEnc->vkGetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
+ return vkGetSwapchainImagesKHR_VkResult_return;
+}
static VkResult entry_vkAcquireNextImageKHR(
VkDevice device,
VkSwapchainKHR swapchain,
@@ -1961,6 +2226,25 @@
vkAcquireNextImageKHR_VkResult_return = vkEnc->vkAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
return vkAcquireNextImageKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkAcquireNextImageKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint64_t timeout,
+ VkSemaphore semaphore,
+ VkFence fence,
+ uint32_t* pImageIndex)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_swapchain"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkAcquireNextImageKHR", "VK_KHR_swapchain");
+ }
+ AEMU_SCOPED_TRACE("vkAcquireNextImageKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkAcquireNextImageKHR_VkResult_return = (VkResult)0;
+ vkAcquireNextImageKHR_VkResult_return = vkEnc->vkAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
+ return vkAcquireNextImageKHR_VkResult_return;
+}
static VkResult entry_vkQueuePresentKHR(
VkQueue queue,
const VkPresentInfoKHR* pPresentInfo)
@@ -1981,6 +2265,21 @@
vkGetDeviceGroupPresentCapabilitiesKHR_VkResult_return = vkEnc->vkGetDeviceGroupPresentCapabilitiesKHR(device, pDeviceGroupPresentCapabilities);
return vkGetDeviceGroupPresentCapabilitiesKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetDeviceGroupPresentCapabilitiesKHR(
+ VkDevice device,
+ VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_swapchain"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetDeviceGroupPresentCapabilitiesKHR", "VK_KHR_swapchain");
+ }
+ AEMU_SCOPED_TRACE("vkGetDeviceGroupPresentCapabilitiesKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetDeviceGroupPresentCapabilitiesKHR_VkResult_return = (VkResult)0;
+ vkGetDeviceGroupPresentCapabilitiesKHR_VkResult_return = vkEnc->vkGetDeviceGroupPresentCapabilitiesKHR(device, pDeviceGroupPresentCapabilities);
+ return vkGetDeviceGroupPresentCapabilitiesKHR_VkResult_return;
+}
static VkResult entry_vkGetDeviceGroupSurfacePresentModesKHR(
VkDevice device,
VkSurfaceKHR surface,
@@ -1992,6 +2291,22 @@
vkGetDeviceGroupSurfacePresentModesKHR_VkResult_return = vkEnc->vkGetDeviceGroupSurfacePresentModesKHR(device, surface, pModes);
return vkGetDeviceGroupSurfacePresentModesKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetDeviceGroupSurfacePresentModesKHR(
+ VkDevice device,
+ VkSurfaceKHR surface,
+ VkDeviceGroupPresentModeFlagsKHR* pModes)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_swapchain"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetDeviceGroupSurfacePresentModesKHR", "VK_KHR_swapchain");
+ }
+ AEMU_SCOPED_TRACE("vkGetDeviceGroupSurfacePresentModesKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetDeviceGroupSurfacePresentModesKHR_VkResult_return = (VkResult)0;
+ vkGetDeviceGroupSurfacePresentModesKHR_VkResult_return = vkEnc->vkGetDeviceGroupSurfacePresentModesKHR(device, surface, pModes);
+ return vkGetDeviceGroupSurfacePresentModesKHR_VkResult_return;
+}
static VkResult entry_vkGetPhysicalDevicePresentRectanglesKHR(
VkPhysicalDevice physicalDevice,
VkSurfaceKHR surface,
@@ -2015,6 +2330,22 @@
vkAcquireNextImage2KHR_VkResult_return = vkEnc->vkAcquireNextImage2KHR(device, pAcquireInfo, pImageIndex);
return vkAcquireNextImage2KHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkAcquireNextImage2KHR(
+ VkDevice device,
+ const VkAcquireNextImageInfoKHR* pAcquireInfo,
+ uint32_t* pImageIndex)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_swapchain"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkAcquireNextImage2KHR", "VK_KHR_swapchain");
+ }
+ AEMU_SCOPED_TRACE("vkAcquireNextImage2KHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkAcquireNextImage2KHR_VkResult_return = (VkResult)0;
+ vkAcquireNextImage2KHR_VkResult_return = vkEnc->vkAcquireNextImage2KHR(device, pAcquireInfo, pImageIndex);
+ return vkAcquireNextImage2KHR_VkResult_return;
+}
#endif
#ifdef VK_KHR_display
static VkResult entry_vkGetPhysicalDeviceDisplayPropertiesKHR(
@@ -2115,6 +2446,24 @@
vkCreateSharedSwapchainsKHR_VkResult_return = vkEnc->vkCreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
return vkCreateSharedSwapchainsKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkCreateSharedSwapchainsKHR(
+ VkDevice device,
+ uint32_t swapchainCount,
+ const VkSwapchainCreateInfoKHR* pCreateInfos,
+ const VkAllocationCallbacks* pAllocator,
+ VkSwapchainKHR* pSwapchains)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_display_swapchain"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkCreateSharedSwapchainsKHR", "VK_KHR_display_swapchain");
+ }
+ AEMU_SCOPED_TRACE("vkCreateSharedSwapchainsKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkCreateSharedSwapchainsKHR_VkResult_return = (VkResult)0;
+ vkCreateSharedSwapchainsKHR_VkResult_return = vkEnc->vkCreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
+ return vkCreateSharedSwapchainsKHR_VkResult_return;
+}
#endif
#ifdef VK_KHR_xlib_surface
static VkResult entry_vkCreateXlibSurfaceKHR(
@@ -2338,6 +2687,22 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkGetDeviceGroupPeerMemoryFeaturesKHR(device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures);
}
+static void dynCheck_entry_vkGetDeviceGroupPeerMemoryFeaturesKHR(
+ VkDevice device,
+ uint32_t heapIndex,
+ uint32_t localDeviceIndex,
+ uint32_t remoteDeviceIndex,
+ VkPeerMemoryFeatureFlags* pPeerMemoryFeatures)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_device_group"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetDeviceGroupPeerMemoryFeaturesKHR", "VK_KHR_device_group");
+ }
+ AEMU_SCOPED_TRACE("vkGetDeviceGroupPeerMemoryFeaturesKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkGetDeviceGroupPeerMemoryFeaturesKHR(device, heapIndex, localDeviceIndex, remoteDeviceIndex, pPeerMemoryFeatures);
+}
static void entry_vkCmdSetDeviceMaskKHR(
VkCommandBuffer commandBuffer,
uint32_t deviceMask)
@@ -2374,6 +2739,20 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkTrimCommandPoolKHR(device, commandPool, flags);
}
+static void dynCheck_entry_vkTrimCommandPoolKHR(
+ VkDevice device,
+ VkCommandPool commandPool,
+ VkCommandPoolTrimFlags flags)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_maintenance1"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkTrimCommandPoolKHR", "VK_KHR_maintenance1");
+ }
+ AEMU_SCOPED_TRACE("vkTrimCommandPoolKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkTrimCommandPoolKHR(device, commandPool, flags);
+}
#endif
#ifdef VK_KHR_device_group_creation
static VkResult entry_vkEnumeratePhysicalDeviceGroupsKHR(
@@ -2413,6 +2792,22 @@
vkGetMemoryWin32HandleKHR_VkResult_return = vkEnc->vkGetMemoryWin32HandleKHR(device, pGetWin32HandleInfo, pHandle);
return vkGetMemoryWin32HandleKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetMemoryWin32HandleKHR(
+ VkDevice device,
+ const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo,
+ HANDLE* pHandle)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_external_memory_win32"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetMemoryWin32HandleKHR", "VK_KHR_external_memory_win32");
+ }
+ AEMU_SCOPED_TRACE("vkGetMemoryWin32HandleKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetMemoryWin32HandleKHR_VkResult_return = (VkResult)0;
+ vkGetMemoryWin32HandleKHR_VkResult_return = vkEnc->vkGetMemoryWin32HandleKHR(device, pGetWin32HandleInfo, pHandle);
+ return vkGetMemoryWin32HandleKHR_VkResult_return;
+}
static VkResult entry_vkGetMemoryWin32HandlePropertiesKHR(
VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType,
@@ -2425,6 +2820,23 @@
vkGetMemoryWin32HandlePropertiesKHR_VkResult_return = vkEnc->vkGetMemoryWin32HandlePropertiesKHR(device, handleType, handle, pMemoryWin32HandleProperties);
return vkGetMemoryWin32HandlePropertiesKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetMemoryWin32HandlePropertiesKHR(
+ VkDevice device,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ HANDLE handle,
+ VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_external_memory_win32"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetMemoryWin32HandlePropertiesKHR", "VK_KHR_external_memory_win32");
+ }
+ AEMU_SCOPED_TRACE("vkGetMemoryWin32HandlePropertiesKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetMemoryWin32HandlePropertiesKHR_VkResult_return = (VkResult)0;
+ vkGetMemoryWin32HandlePropertiesKHR_VkResult_return = vkEnc->vkGetMemoryWin32HandlePropertiesKHR(device, handleType, handle, pMemoryWin32HandleProperties);
+ return vkGetMemoryWin32HandlePropertiesKHR_VkResult_return;
+}
#endif
#ifdef VK_KHR_external_memory_fd
static VkResult entry_vkGetMemoryFdKHR(
@@ -2438,6 +2850,22 @@
vkGetMemoryFdKHR_VkResult_return = vkEnc->vkGetMemoryFdKHR(device, pGetFdInfo, pFd);
return vkGetMemoryFdKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetMemoryFdKHR(
+ VkDevice device,
+ const VkMemoryGetFdInfoKHR* pGetFdInfo,
+ int* pFd)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_external_memory_fd"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetMemoryFdKHR", "VK_KHR_external_memory_fd");
+ }
+ AEMU_SCOPED_TRACE("vkGetMemoryFdKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetMemoryFdKHR_VkResult_return = (VkResult)0;
+ vkGetMemoryFdKHR_VkResult_return = vkEnc->vkGetMemoryFdKHR(device, pGetFdInfo, pFd);
+ return vkGetMemoryFdKHR_VkResult_return;
+}
static VkResult entry_vkGetMemoryFdPropertiesKHR(
VkDevice device,
VkExternalMemoryHandleTypeFlagBits handleType,
@@ -2450,6 +2878,23 @@
vkGetMemoryFdPropertiesKHR_VkResult_return = vkEnc->vkGetMemoryFdPropertiesKHR(device, handleType, fd, pMemoryFdProperties);
return vkGetMemoryFdPropertiesKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetMemoryFdPropertiesKHR(
+ VkDevice device,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ int fd,
+ VkMemoryFdPropertiesKHR* pMemoryFdProperties)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_external_memory_fd"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetMemoryFdPropertiesKHR", "VK_KHR_external_memory_fd");
+ }
+ AEMU_SCOPED_TRACE("vkGetMemoryFdPropertiesKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetMemoryFdPropertiesKHR_VkResult_return = (VkResult)0;
+ vkGetMemoryFdPropertiesKHR_VkResult_return = vkEnc->vkGetMemoryFdPropertiesKHR(device, handleType, fd, pMemoryFdProperties);
+ return vkGetMemoryFdPropertiesKHR_VkResult_return;
+}
#endif
#ifdef VK_KHR_win32_keyed_mutex
#endif
@@ -2477,6 +2922,21 @@
vkImportSemaphoreWin32HandleKHR_VkResult_return = vkEnc->vkImportSemaphoreWin32HandleKHR(device, pImportSemaphoreWin32HandleInfo);
return vkImportSemaphoreWin32HandleKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkImportSemaphoreWin32HandleKHR(
+ VkDevice device,
+ const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_external_semaphore_win32"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkImportSemaphoreWin32HandleKHR", "VK_KHR_external_semaphore_win32");
+ }
+ AEMU_SCOPED_TRACE("vkImportSemaphoreWin32HandleKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkImportSemaphoreWin32HandleKHR_VkResult_return = (VkResult)0;
+ vkImportSemaphoreWin32HandleKHR_VkResult_return = vkEnc->vkImportSemaphoreWin32HandleKHR(device, pImportSemaphoreWin32HandleInfo);
+ return vkImportSemaphoreWin32HandleKHR_VkResult_return;
+}
static VkResult entry_vkGetSemaphoreWin32HandleKHR(
VkDevice device,
const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo,
@@ -2488,6 +2948,22 @@
vkGetSemaphoreWin32HandleKHR_VkResult_return = vkEnc->vkGetSemaphoreWin32HandleKHR(device, pGetWin32HandleInfo, pHandle);
return vkGetSemaphoreWin32HandleKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetSemaphoreWin32HandleKHR(
+ VkDevice device,
+ const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo,
+ HANDLE* pHandle)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_external_semaphore_win32"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetSemaphoreWin32HandleKHR", "VK_KHR_external_semaphore_win32");
+ }
+ AEMU_SCOPED_TRACE("vkGetSemaphoreWin32HandleKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetSemaphoreWin32HandleKHR_VkResult_return = (VkResult)0;
+ vkGetSemaphoreWin32HandleKHR_VkResult_return = vkEnc->vkGetSemaphoreWin32HandleKHR(device, pGetWin32HandleInfo, pHandle);
+ return vkGetSemaphoreWin32HandleKHR_VkResult_return;
+}
#endif
#ifdef VK_KHR_external_semaphore_fd
static VkResult entry_vkImportSemaphoreFdKHR(
@@ -2501,6 +2977,21 @@
vkImportSemaphoreFdKHR_VkResult_return = resources->on_vkImportSemaphoreFdKHR(vkEnc, VK_SUCCESS, device, pImportSemaphoreFdInfo);
return vkImportSemaphoreFdKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkImportSemaphoreFdKHR(
+ VkDevice device,
+ const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_external_semaphore_fd"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkImportSemaphoreFdKHR", "VK_KHR_external_semaphore_fd");
+ }
+ AEMU_SCOPED_TRACE("vkImportSemaphoreFdKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkImportSemaphoreFdKHR_VkResult_return = (VkResult)0;
+ vkImportSemaphoreFdKHR_VkResult_return = resources->on_vkImportSemaphoreFdKHR(vkEnc, VK_SUCCESS, device, pImportSemaphoreFdInfo);
+ return vkImportSemaphoreFdKHR_VkResult_return;
+}
static VkResult entry_vkGetSemaphoreFdKHR(
VkDevice device,
const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
@@ -2513,6 +3004,22 @@
vkGetSemaphoreFdKHR_VkResult_return = resources->on_vkGetSemaphoreFdKHR(vkEnc, VK_SUCCESS, device, pGetFdInfo, pFd);
return vkGetSemaphoreFdKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetSemaphoreFdKHR(
+ VkDevice device,
+ const VkSemaphoreGetFdInfoKHR* pGetFdInfo,
+ int* pFd)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_external_semaphore_fd"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetSemaphoreFdKHR", "VK_KHR_external_semaphore_fd");
+ }
+ AEMU_SCOPED_TRACE("vkGetSemaphoreFdKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetSemaphoreFdKHR_VkResult_return = (VkResult)0;
+ vkGetSemaphoreFdKHR_VkResult_return = resources->on_vkGetSemaphoreFdKHR(vkEnc, VK_SUCCESS, device, pGetFdInfo, pFd);
+ return vkGetSemaphoreFdKHR_VkResult_return;
+}
#endif
#ifdef VK_KHR_push_descriptor
static void entry_vkCmdPushDescriptorSetKHR(
@@ -2558,6 +3065,23 @@
vkCreateDescriptorUpdateTemplateKHR_VkResult_return = vkEnc->vkCreateDescriptorUpdateTemplateKHR(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
return vkCreateDescriptorUpdateTemplateKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkCreateDescriptorUpdateTemplateKHR(
+ VkDevice device,
+ const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_descriptor_update_template"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkCreateDescriptorUpdateTemplateKHR", "VK_KHR_descriptor_update_template");
+ }
+ AEMU_SCOPED_TRACE("vkCreateDescriptorUpdateTemplateKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkCreateDescriptorUpdateTemplateKHR_VkResult_return = (VkResult)0;
+ vkCreateDescriptorUpdateTemplateKHR_VkResult_return = vkEnc->vkCreateDescriptorUpdateTemplateKHR(device, pCreateInfo, pAllocator, pDescriptorUpdateTemplate);
+ return vkCreateDescriptorUpdateTemplateKHR_VkResult_return;
+}
static void entry_vkDestroyDescriptorUpdateTemplateKHR(
VkDevice device,
VkDescriptorUpdateTemplate descriptorUpdateTemplate,
@@ -2567,6 +3091,20 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkDestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
}
+static void dynCheck_entry_vkDestroyDescriptorUpdateTemplateKHR(
+ VkDevice device,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const VkAllocationCallbacks* pAllocator)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_descriptor_update_template"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkDestroyDescriptorUpdateTemplateKHR", "VK_KHR_descriptor_update_template");
+ }
+ AEMU_SCOPED_TRACE("vkDestroyDescriptorUpdateTemplateKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkDestroyDescriptorUpdateTemplateKHR(device, descriptorUpdateTemplate, pAllocator);
+}
static void entry_vkUpdateDescriptorSetWithTemplateKHR(
VkDevice device,
VkDescriptorSet descriptorSet,
@@ -2577,6 +3115,21 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkUpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData);
}
+static void dynCheck_entry_vkUpdateDescriptorSetWithTemplateKHR(
+ VkDevice device,
+ VkDescriptorSet descriptorSet,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ const void* pData)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_descriptor_update_template"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkUpdateDescriptorSetWithTemplateKHR", "VK_KHR_descriptor_update_template");
+ }
+ AEMU_SCOPED_TRACE("vkUpdateDescriptorSetWithTemplateKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkUpdateDescriptorSetWithTemplateKHR(device, descriptorSet, descriptorUpdateTemplate, pData);
+}
#endif
#ifdef VK_KHR_create_renderpass2
static VkResult entry_vkCreateRenderPass2KHR(
@@ -2591,6 +3144,23 @@
vkCreateRenderPass2KHR_VkResult_return = vkEnc->vkCreateRenderPass2KHR(device, pCreateInfo, pAllocator, pRenderPass);
return vkCreateRenderPass2KHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkCreateRenderPass2KHR(
+ VkDevice device,
+ const VkRenderPassCreateInfo2KHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkRenderPass* pRenderPass)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_create_renderpass2"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkCreateRenderPass2KHR", "VK_KHR_create_renderpass2");
+ }
+ AEMU_SCOPED_TRACE("vkCreateRenderPass2KHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkCreateRenderPass2KHR_VkResult_return = (VkResult)0;
+ vkCreateRenderPass2KHR_VkResult_return = vkEnc->vkCreateRenderPass2KHR(device, pCreateInfo, pAllocator, pRenderPass);
+ return vkCreateRenderPass2KHR_VkResult_return;
+}
static void entry_vkCmdBeginRenderPass2KHR(
VkCommandBuffer commandBuffer,
const VkRenderPassBeginInfo* pRenderPassBegin,
@@ -2632,6 +3202,21 @@
vkGetSwapchainStatusKHR_VkResult_return = vkEnc->vkGetSwapchainStatusKHR(device, swapchain);
return vkGetSwapchainStatusKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetSwapchainStatusKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_shared_presentable_image"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetSwapchainStatusKHR", "VK_KHR_shared_presentable_image");
+ }
+ AEMU_SCOPED_TRACE("vkGetSwapchainStatusKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetSwapchainStatusKHR_VkResult_return = (VkResult)0;
+ vkGetSwapchainStatusKHR_VkResult_return = vkEnc->vkGetSwapchainStatusKHR(device, swapchain);
+ return vkGetSwapchainStatusKHR_VkResult_return;
+}
#endif
#ifdef VK_KHR_external_fence_capabilities
static void entry_vkGetPhysicalDeviceExternalFencePropertiesKHR(
@@ -2658,6 +3243,21 @@
vkImportFenceWin32HandleKHR_VkResult_return = vkEnc->vkImportFenceWin32HandleKHR(device, pImportFenceWin32HandleInfo);
return vkImportFenceWin32HandleKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkImportFenceWin32HandleKHR(
+ VkDevice device,
+ const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_external_fence_win32"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkImportFenceWin32HandleKHR", "VK_KHR_external_fence_win32");
+ }
+ AEMU_SCOPED_TRACE("vkImportFenceWin32HandleKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkImportFenceWin32HandleKHR_VkResult_return = (VkResult)0;
+ vkImportFenceWin32HandleKHR_VkResult_return = vkEnc->vkImportFenceWin32HandleKHR(device, pImportFenceWin32HandleInfo);
+ return vkImportFenceWin32HandleKHR_VkResult_return;
+}
static VkResult entry_vkGetFenceWin32HandleKHR(
VkDevice device,
const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo,
@@ -2669,6 +3269,22 @@
vkGetFenceWin32HandleKHR_VkResult_return = vkEnc->vkGetFenceWin32HandleKHR(device, pGetWin32HandleInfo, pHandle);
return vkGetFenceWin32HandleKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetFenceWin32HandleKHR(
+ VkDevice device,
+ const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo,
+ HANDLE* pHandle)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_external_fence_win32"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetFenceWin32HandleKHR", "VK_KHR_external_fence_win32");
+ }
+ AEMU_SCOPED_TRACE("vkGetFenceWin32HandleKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetFenceWin32HandleKHR_VkResult_return = (VkResult)0;
+ vkGetFenceWin32HandleKHR_VkResult_return = vkEnc->vkGetFenceWin32HandleKHR(device, pGetWin32HandleInfo, pHandle);
+ return vkGetFenceWin32HandleKHR_VkResult_return;
+}
#endif
#ifdef VK_KHR_external_fence_fd
static VkResult entry_vkImportFenceFdKHR(
@@ -2682,6 +3298,21 @@
vkImportFenceFdKHR_VkResult_return = resources->on_vkImportFenceFdKHR(vkEnc, VK_SUCCESS, device, pImportFenceFdInfo);
return vkImportFenceFdKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkImportFenceFdKHR(
+ VkDevice device,
+ const VkImportFenceFdInfoKHR* pImportFenceFdInfo)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_external_fence_fd"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkImportFenceFdKHR", "VK_KHR_external_fence_fd");
+ }
+ AEMU_SCOPED_TRACE("vkImportFenceFdKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkImportFenceFdKHR_VkResult_return = (VkResult)0;
+ vkImportFenceFdKHR_VkResult_return = resources->on_vkImportFenceFdKHR(vkEnc, VK_SUCCESS, device, pImportFenceFdInfo);
+ return vkImportFenceFdKHR_VkResult_return;
+}
static VkResult entry_vkGetFenceFdKHR(
VkDevice device,
const VkFenceGetFdInfoKHR* pGetFdInfo,
@@ -2694,6 +3325,22 @@
vkGetFenceFdKHR_VkResult_return = resources->on_vkGetFenceFdKHR(vkEnc, VK_SUCCESS, device, pGetFdInfo, pFd);
return vkGetFenceFdKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetFenceFdKHR(
+ VkDevice device,
+ const VkFenceGetFdInfoKHR* pGetFdInfo,
+ int* pFd)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_external_fence_fd"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetFenceFdKHR", "VK_KHR_external_fence_fd");
+ }
+ AEMU_SCOPED_TRACE("vkGetFenceFdKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetFenceFdKHR_VkResult_return = (VkResult)0;
+ vkGetFenceFdKHR_VkResult_return = resources->on_vkGetFenceFdKHR(vkEnc, VK_SUCCESS, device, pGetFdInfo, pFd);
+ return vkGetFenceFdKHR_VkResult_return;
+}
#endif
#ifdef VK_KHR_maintenance2
#endif
@@ -2788,6 +3435,20 @@
auto resources = ResourceTracker::get();
resources->on_vkGetImageMemoryRequirements2KHR(vkEnc, device, pInfo, pMemoryRequirements);
}
+static void dynCheck_entry_vkGetImageMemoryRequirements2KHR(
+ VkDevice device,
+ const VkImageMemoryRequirementsInfo2* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_get_memory_requirements2"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetImageMemoryRequirements2KHR", "VK_KHR_get_memory_requirements2");
+ }
+ AEMU_SCOPED_TRACE("vkGetImageMemoryRequirements2KHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ resources->on_vkGetImageMemoryRequirements2KHR(vkEnc, device, pInfo, pMemoryRequirements);
+}
static void entry_vkGetBufferMemoryRequirements2KHR(
VkDevice device,
const VkBufferMemoryRequirementsInfo2* pInfo,
@@ -2798,6 +3459,20 @@
auto resources = ResourceTracker::get();
resources->on_vkGetBufferMemoryRequirements2KHR(vkEnc, device, pInfo, pMemoryRequirements);
}
+static void dynCheck_entry_vkGetBufferMemoryRequirements2KHR(
+ VkDevice device,
+ const VkBufferMemoryRequirementsInfo2* pInfo,
+ VkMemoryRequirements2* pMemoryRequirements)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_get_memory_requirements2"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetBufferMemoryRequirements2KHR", "VK_KHR_get_memory_requirements2");
+ }
+ AEMU_SCOPED_TRACE("vkGetBufferMemoryRequirements2KHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ resources->on_vkGetBufferMemoryRequirements2KHR(vkEnc, device, pInfo, pMemoryRequirements);
+}
static void entry_vkGetImageSparseMemoryRequirements2KHR(
VkDevice device,
const VkImageSparseMemoryRequirementsInfo2* pInfo,
@@ -2808,6 +3483,21 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkGetImageSparseMemoryRequirements2KHR(device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
}
+static void dynCheck_entry_vkGetImageSparseMemoryRequirements2KHR(
+ VkDevice device,
+ const VkImageSparseMemoryRequirementsInfo2* pInfo,
+ uint32_t* pSparseMemoryRequirementCount,
+ VkSparseImageMemoryRequirements2* pSparseMemoryRequirements)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_get_memory_requirements2"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetImageSparseMemoryRequirements2KHR", "VK_KHR_get_memory_requirements2");
+ }
+ AEMU_SCOPED_TRACE("vkGetImageSparseMemoryRequirements2KHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkGetImageSparseMemoryRequirements2KHR(device, pInfo, pSparseMemoryRequirementCount, pSparseMemoryRequirements);
+}
#endif
#ifdef VK_KHR_image_format_list
#endif
@@ -2825,6 +3515,23 @@
vkCreateSamplerYcbcrConversionKHR_VkResult_return = resources->on_vkCreateSamplerYcbcrConversionKHR(vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pYcbcrConversion);
return vkCreateSamplerYcbcrConversionKHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkCreateSamplerYcbcrConversionKHR(
+ VkDevice device,
+ const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSamplerYcbcrConversion* pYcbcrConversion)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_sampler_ycbcr_conversion"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkCreateSamplerYcbcrConversionKHR", "VK_KHR_sampler_ycbcr_conversion");
+ }
+ AEMU_SCOPED_TRACE("vkCreateSamplerYcbcrConversionKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkCreateSamplerYcbcrConversionKHR_VkResult_return = (VkResult)0;
+ vkCreateSamplerYcbcrConversionKHR_VkResult_return = resources->on_vkCreateSamplerYcbcrConversionKHR(vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pYcbcrConversion);
+ return vkCreateSamplerYcbcrConversionKHR_VkResult_return;
+}
static void entry_vkDestroySamplerYcbcrConversionKHR(
VkDevice device,
VkSamplerYcbcrConversion ycbcrConversion,
@@ -2835,6 +3542,20 @@
auto resources = ResourceTracker::get();
resources->on_vkDestroySamplerYcbcrConversionKHR(vkEnc, device, ycbcrConversion, pAllocator);
}
+static void dynCheck_entry_vkDestroySamplerYcbcrConversionKHR(
+ VkDevice device,
+ VkSamplerYcbcrConversion ycbcrConversion,
+ const VkAllocationCallbacks* pAllocator)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_sampler_ycbcr_conversion"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkDestroySamplerYcbcrConversionKHR", "VK_KHR_sampler_ycbcr_conversion");
+ }
+ AEMU_SCOPED_TRACE("vkDestroySamplerYcbcrConversionKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ resources->on_vkDestroySamplerYcbcrConversionKHR(vkEnc, device, ycbcrConversion, pAllocator);
+}
#endif
#ifdef VK_KHR_bind_memory2
static VkResult entry_vkBindBufferMemory2KHR(
@@ -2849,6 +3570,22 @@
vkBindBufferMemory2KHR_VkResult_return = resources->on_vkBindBufferMemory2KHR(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
return vkBindBufferMemory2KHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkBindBufferMemory2KHR(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindBufferMemoryInfo* pBindInfos)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_bind_memory2"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkBindBufferMemory2KHR", "VK_KHR_bind_memory2");
+ }
+ AEMU_SCOPED_TRACE("vkBindBufferMemory2KHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkBindBufferMemory2KHR_VkResult_return = (VkResult)0;
+ vkBindBufferMemory2KHR_VkResult_return = resources->on_vkBindBufferMemory2KHR(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
+ return vkBindBufferMemory2KHR_VkResult_return;
+}
static VkResult entry_vkBindImageMemory2KHR(
VkDevice device,
uint32_t bindInfoCount,
@@ -2861,6 +3598,22 @@
vkBindImageMemory2KHR_VkResult_return = resources->on_vkBindImageMemory2KHR(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
return vkBindImageMemory2KHR_VkResult_return;
}
+static VkResult dynCheck_entry_vkBindImageMemory2KHR(
+ VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindImageMemoryInfo* pBindInfos)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_bind_memory2"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkBindImageMemory2KHR", "VK_KHR_bind_memory2");
+ }
+ AEMU_SCOPED_TRACE("vkBindImageMemory2KHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkBindImageMemory2KHR_VkResult_return = (VkResult)0;
+ vkBindImageMemory2KHR_VkResult_return = resources->on_vkBindImageMemory2KHR(vkEnc, VK_SUCCESS, device, bindInfoCount, pBindInfos);
+ return vkBindImageMemory2KHR_VkResult_return;
+}
#endif
#ifdef VK_KHR_maintenance3
static void entry_vkGetDescriptorSetLayoutSupportKHR(
@@ -2872,6 +3625,20 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkGetDescriptorSetLayoutSupportKHR(device, pCreateInfo, pSupport);
}
+static void dynCheck_entry_vkGetDescriptorSetLayoutSupportKHR(
+ VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
+ VkDescriptorSetLayoutSupport* pSupport)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_KHR_maintenance3"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetDescriptorSetLayoutSupportKHR", "VK_KHR_maintenance3");
+ }
+ AEMU_SCOPED_TRACE("vkGetDescriptorSetLayoutSupportKHR");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkGetDescriptorSetLayoutSupportKHR(device, pCreateInfo, pSupport);
+}
#endif
#ifdef VK_KHR_draw_indirect_count
static void entry_vkCmdDrawIndirectCountKHR(
@@ -2918,6 +3685,23 @@
vkGetSwapchainGrallocUsageANDROID_VkResult_return = vkEnc->vkGetSwapchainGrallocUsageANDROID(device, format, imageUsage, grallocUsage);
return vkGetSwapchainGrallocUsageANDROID_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetSwapchainGrallocUsageANDROID(
+ VkDevice device,
+ VkFormat format,
+ VkImageUsageFlags imageUsage,
+ int* grallocUsage)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_ANDROID_native_buffer"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetSwapchainGrallocUsageANDROID", "VK_ANDROID_native_buffer");
+ }
+ AEMU_SCOPED_TRACE("vkGetSwapchainGrallocUsageANDROID");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetSwapchainGrallocUsageANDROID_VkResult_return = (VkResult)0;
+ vkGetSwapchainGrallocUsageANDROID_VkResult_return = vkEnc->vkGetSwapchainGrallocUsageANDROID(device, format, imageUsage, grallocUsage);
+ return vkGetSwapchainGrallocUsageANDROID_VkResult_return;
+}
static VkResult entry_vkAcquireImageANDROID(
VkDevice device,
VkImage image,
@@ -2931,6 +3715,24 @@
vkAcquireImageANDROID_VkResult_return = vkEnc->vkAcquireImageANDROID(device, image, nativeFenceFd, semaphore, fence);
return vkAcquireImageANDROID_VkResult_return;
}
+static VkResult dynCheck_entry_vkAcquireImageANDROID(
+ VkDevice device,
+ VkImage image,
+ int nativeFenceFd,
+ VkSemaphore semaphore,
+ VkFence fence)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_ANDROID_native_buffer"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkAcquireImageANDROID", "VK_ANDROID_native_buffer");
+ }
+ AEMU_SCOPED_TRACE("vkAcquireImageANDROID");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkAcquireImageANDROID_VkResult_return = (VkResult)0;
+ vkAcquireImageANDROID_VkResult_return = vkEnc->vkAcquireImageANDROID(device, image, nativeFenceFd, semaphore, fence);
+ return vkAcquireImageANDROID_VkResult_return;
+}
static VkResult entry_vkQueueSignalReleaseImageANDROID(
VkQueue queue,
uint32_t waitSemaphoreCount,
@@ -3005,6 +3807,21 @@
vkDebugMarkerSetObjectTagEXT_VkResult_return = vkEnc->vkDebugMarkerSetObjectTagEXT(device, pTagInfo);
return vkDebugMarkerSetObjectTagEXT_VkResult_return;
}
+static VkResult dynCheck_entry_vkDebugMarkerSetObjectTagEXT(
+ VkDevice device,
+ const VkDebugMarkerObjectTagInfoEXT* pTagInfo)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_debug_marker"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkDebugMarkerSetObjectTagEXT", "VK_EXT_debug_marker");
+ }
+ AEMU_SCOPED_TRACE("vkDebugMarkerSetObjectTagEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkDebugMarkerSetObjectTagEXT_VkResult_return = (VkResult)0;
+ vkDebugMarkerSetObjectTagEXT_VkResult_return = vkEnc->vkDebugMarkerSetObjectTagEXT(device, pTagInfo);
+ return vkDebugMarkerSetObjectTagEXT_VkResult_return;
+}
static VkResult entry_vkDebugMarkerSetObjectNameEXT(
VkDevice device,
const VkDebugMarkerObjectNameInfoEXT* pNameInfo)
@@ -3015,6 +3832,21 @@
vkDebugMarkerSetObjectNameEXT_VkResult_return = vkEnc->vkDebugMarkerSetObjectNameEXT(device, pNameInfo);
return vkDebugMarkerSetObjectNameEXT_VkResult_return;
}
+static VkResult dynCheck_entry_vkDebugMarkerSetObjectNameEXT(
+ VkDevice device,
+ const VkDebugMarkerObjectNameInfoEXT* pNameInfo)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_debug_marker"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkDebugMarkerSetObjectNameEXT", "VK_EXT_debug_marker");
+ }
+ AEMU_SCOPED_TRACE("vkDebugMarkerSetObjectNameEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkDebugMarkerSetObjectNameEXT_VkResult_return = (VkResult)0;
+ vkDebugMarkerSetObjectNameEXT_VkResult_return = vkEnc->vkDebugMarkerSetObjectNameEXT(device, pNameInfo);
+ return vkDebugMarkerSetObjectNameEXT_VkResult_return;
+}
static void entry_vkCmdDebugMarkerBeginEXT(
VkCommandBuffer commandBuffer,
const VkDebugMarkerMarkerInfoEXT* pMarkerInfo)
@@ -3099,6 +3931,25 @@
vkGetShaderInfoAMD_VkResult_return = vkEnc->vkGetShaderInfoAMD(device, pipeline, shaderStage, infoType, pInfoSize, pInfo);
return vkGetShaderInfoAMD_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetShaderInfoAMD(
+ VkDevice device,
+ VkPipeline pipeline,
+ VkShaderStageFlagBits shaderStage,
+ VkShaderInfoTypeAMD infoType,
+ size_t* pInfoSize,
+ void* pInfo)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_AMD_shader_info"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetShaderInfoAMD", "VK_AMD_shader_info");
+ }
+ AEMU_SCOPED_TRACE("vkGetShaderInfoAMD");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetShaderInfoAMD_VkResult_return = (VkResult)0;
+ vkGetShaderInfoAMD_VkResult_return = vkEnc->vkGetShaderInfoAMD(device, pipeline, shaderStage, infoType, pInfoSize, pInfo);
+ return vkGetShaderInfoAMD_VkResult_return;
+}
#endif
#ifdef VK_AMD_shader_image_load_store_lod
#endif
@@ -3137,6 +3988,23 @@
vkGetMemoryWin32HandleNV_VkResult_return = vkEnc->vkGetMemoryWin32HandleNV(device, memory, handleType, pHandle);
return vkGetMemoryWin32HandleNV_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetMemoryWin32HandleNV(
+ VkDevice device,
+ VkDeviceMemory memory,
+ VkExternalMemoryHandleTypeFlagsNV handleType,
+ HANDLE* pHandle)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_NV_external_memory_win32"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetMemoryWin32HandleNV", "VK_NV_external_memory_win32");
+ }
+ AEMU_SCOPED_TRACE("vkGetMemoryWin32HandleNV");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetMemoryWin32HandleNV_VkResult_return = (VkResult)0;
+ vkGetMemoryWin32HandleNV_VkResult_return = vkEnc->vkGetMemoryWin32HandleNV(device, memory, handleType, pHandle);
+ return vkGetMemoryWin32HandleNV_VkResult_return;
+}
#endif
#ifdef VK_NV_win32_keyed_mutex
#endif
@@ -3210,6 +4078,23 @@
vkCreateIndirectCommandsLayoutNVX_VkResult_return = vkEnc->vkCreateIndirectCommandsLayoutNVX(device, pCreateInfo, pAllocator, pIndirectCommandsLayout);
return vkCreateIndirectCommandsLayoutNVX_VkResult_return;
}
+static VkResult dynCheck_entry_vkCreateIndirectCommandsLayoutNVX(
+ VkDevice device,
+ const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_NVX_device_generated_commands"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkCreateIndirectCommandsLayoutNVX", "VK_NVX_device_generated_commands");
+ }
+ AEMU_SCOPED_TRACE("vkCreateIndirectCommandsLayoutNVX");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkCreateIndirectCommandsLayoutNVX_VkResult_return = (VkResult)0;
+ vkCreateIndirectCommandsLayoutNVX_VkResult_return = vkEnc->vkCreateIndirectCommandsLayoutNVX(device, pCreateInfo, pAllocator, pIndirectCommandsLayout);
+ return vkCreateIndirectCommandsLayoutNVX_VkResult_return;
+}
static void entry_vkDestroyIndirectCommandsLayoutNVX(
VkDevice device,
VkIndirectCommandsLayoutNVX indirectCommandsLayout,
@@ -3219,6 +4104,20 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkDestroyIndirectCommandsLayoutNVX(device, indirectCommandsLayout, pAllocator);
}
+static void dynCheck_entry_vkDestroyIndirectCommandsLayoutNVX(
+ VkDevice device,
+ VkIndirectCommandsLayoutNVX indirectCommandsLayout,
+ const VkAllocationCallbacks* pAllocator)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_NVX_device_generated_commands"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkDestroyIndirectCommandsLayoutNVX", "VK_NVX_device_generated_commands");
+ }
+ AEMU_SCOPED_TRACE("vkDestroyIndirectCommandsLayoutNVX");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkDestroyIndirectCommandsLayoutNVX(device, indirectCommandsLayout, pAllocator);
+}
static VkResult entry_vkCreateObjectTableNVX(
VkDevice device,
const VkObjectTableCreateInfoNVX* pCreateInfo,
@@ -3231,6 +4130,23 @@
vkCreateObjectTableNVX_VkResult_return = vkEnc->vkCreateObjectTableNVX(device, pCreateInfo, pAllocator, pObjectTable);
return vkCreateObjectTableNVX_VkResult_return;
}
+static VkResult dynCheck_entry_vkCreateObjectTableNVX(
+ VkDevice device,
+ const VkObjectTableCreateInfoNVX* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkObjectTableNVX* pObjectTable)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_NVX_device_generated_commands"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkCreateObjectTableNVX", "VK_NVX_device_generated_commands");
+ }
+ AEMU_SCOPED_TRACE("vkCreateObjectTableNVX");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkCreateObjectTableNVX_VkResult_return = (VkResult)0;
+ vkCreateObjectTableNVX_VkResult_return = vkEnc->vkCreateObjectTableNVX(device, pCreateInfo, pAllocator, pObjectTable);
+ return vkCreateObjectTableNVX_VkResult_return;
+}
static void entry_vkDestroyObjectTableNVX(
VkDevice device,
VkObjectTableNVX objectTable,
@@ -3240,6 +4156,20 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkDestroyObjectTableNVX(device, objectTable, pAllocator);
}
+static void dynCheck_entry_vkDestroyObjectTableNVX(
+ VkDevice device,
+ VkObjectTableNVX objectTable,
+ const VkAllocationCallbacks* pAllocator)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_NVX_device_generated_commands"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkDestroyObjectTableNVX", "VK_NVX_device_generated_commands");
+ }
+ AEMU_SCOPED_TRACE("vkDestroyObjectTableNVX");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkDestroyObjectTableNVX(device, objectTable, pAllocator);
+}
static VkResult entry_vkRegisterObjectsNVX(
VkDevice device,
VkObjectTableNVX objectTable,
@@ -3253,6 +4183,24 @@
vkRegisterObjectsNVX_VkResult_return = vkEnc->vkRegisterObjectsNVX(device, objectTable, objectCount, ppObjectTableEntries, pObjectIndices);
return vkRegisterObjectsNVX_VkResult_return;
}
+static VkResult dynCheck_entry_vkRegisterObjectsNVX(
+ VkDevice device,
+ VkObjectTableNVX objectTable,
+ uint32_t objectCount,
+ const VkObjectTableEntryNVX* const* ppObjectTableEntries,
+ const uint32_t* pObjectIndices)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_NVX_device_generated_commands"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkRegisterObjectsNVX", "VK_NVX_device_generated_commands");
+ }
+ AEMU_SCOPED_TRACE("vkRegisterObjectsNVX");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkRegisterObjectsNVX_VkResult_return = (VkResult)0;
+ vkRegisterObjectsNVX_VkResult_return = vkEnc->vkRegisterObjectsNVX(device, objectTable, objectCount, ppObjectTableEntries, pObjectIndices);
+ return vkRegisterObjectsNVX_VkResult_return;
+}
static VkResult entry_vkUnregisterObjectsNVX(
VkDevice device,
VkObjectTableNVX objectTable,
@@ -3266,6 +4214,24 @@
vkUnregisterObjectsNVX_VkResult_return = vkEnc->vkUnregisterObjectsNVX(device, objectTable, objectCount, pObjectEntryTypes, pObjectIndices);
return vkUnregisterObjectsNVX_VkResult_return;
}
+static VkResult dynCheck_entry_vkUnregisterObjectsNVX(
+ VkDevice device,
+ VkObjectTableNVX objectTable,
+ uint32_t objectCount,
+ const VkObjectEntryTypeNVX* pObjectEntryTypes,
+ const uint32_t* pObjectIndices)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_NVX_device_generated_commands"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkUnregisterObjectsNVX", "VK_NVX_device_generated_commands");
+ }
+ AEMU_SCOPED_TRACE("vkUnregisterObjectsNVX");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkUnregisterObjectsNVX_VkResult_return = (VkResult)0;
+ vkUnregisterObjectsNVX_VkResult_return = vkEnc->vkUnregisterObjectsNVX(device, objectTable, objectCount, pObjectEntryTypes, pObjectIndices);
+ return vkUnregisterObjectsNVX_VkResult_return;
+}
static void entry_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX(
VkPhysicalDevice physicalDevice,
VkDeviceGeneratedCommandsFeaturesNVX* pFeatures,
@@ -3351,6 +4317,22 @@
vkDisplayPowerControlEXT_VkResult_return = vkEnc->vkDisplayPowerControlEXT(device, display, pDisplayPowerInfo);
return vkDisplayPowerControlEXT_VkResult_return;
}
+static VkResult dynCheck_entry_vkDisplayPowerControlEXT(
+ VkDevice device,
+ VkDisplayKHR display,
+ const VkDisplayPowerInfoEXT* pDisplayPowerInfo)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_display_control"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkDisplayPowerControlEXT", "VK_EXT_display_control");
+ }
+ AEMU_SCOPED_TRACE("vkDisplayPowerControlEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkDisplayPowerControlEXT_VkResult_return = (VkResult)0;
+ vkDisplayPowerControlEXT_VkResult_return = vkEnc->vkDisplayPowerControlEXT(device, display, pDisplayPowerInfo);
+ return vkDisplayPowerControlEXT_VkResult_return;
+}
static VkResult entry_vkRegisterDeviceEventEXT(
VkDevice device,
const VkDeviceEventInfoEXT* pDeviceEventInfo,
@@ -3363,6 +4345,23 @@
vkRegisterDeviceEventEXT_VkResult_return = vkEnc->vkRegisterDeviceEventEXT(device, pDeviceEventInfo, pAllocator, pFence);
return vkRegisterDeviceEventEXT_VkResult_return;
}
+static VkResult dynCheck_entry_vkRegisterDeviceEventEXT(
+ VkDevice device,
+ const VkDeviceEventInfoEXT* pDeviceEventInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkFence* pFence)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_display_control"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkRegisterDeviceEventEXT", "VK_EXT_display_control");
+ }
+ AEMU_SCOPED_TRACE("vkRegisterDeviceEventEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkRegisterDeviceEventEXT_VkResult_return = (VkResult)0;
+ vkRegisterDeviceEventEXT_VkResult_return = vkEnc->vkRegisterDeviceEventEXT(device, pDeviceEventInfo, pAllocator, pFence);
+ return vkRegisterDeviceEventEXT_VkResult_return;
+}
static VkResult entry_vkRegisterDisplayEventEXT(
VkDevice device,
VkDisplayKHR display,
@@ -3376,6 +4375,24 @@
vkRegisterDisplayEventEXT_VkResult_return = vkEnc->vkRegisterDisplayEventEXT(device, display, pDisplayEventInfo, pAllocator, pFence);
return vkRegisterDisplayEventEXT_VkResult_return;
}
+static VkResult dynCheck_entry_vkRegisterDisplayEventEXT(
+ VkDevice device,
+ VkDisplayKHR display,
+ const VkDisplayEventInfoEXT* pDisplayEventInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkFence* pFence)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_display_control"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkRegisterDisplayEventEXT", "VK_EXT_display_control");
+ }
+ AEMU_SCOPED_TRACE("vkRegisterDisplayEventEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkRegisterDisplayEventEXT_VkResult_return = (VkResult)0;
+ vkRegisterDisplayEventEXT_VkResult_return = vkEnc->vkRegisterDisplayEventEXT(device, display, pDisplayEventInfo, pAllocator, pFence);
+ return vkRegisterDisplayEventEXT_VkResult_return;
+}
static VkResult entry_vkGetSwapchainCounterEXT(
VkDevice device,
VkSwapchainKHR swapchain,
@@ -3388,6 +4405,23 @@
vkGetSwapchainCounterEXT_VkResult_return = vkEnc->vkGetSwapchainCounterEXT(device, swapchain, counter, pCounterValue);
return vkGetSwapchainCounterEXT_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetSwapchainCounterEXT(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ VkSurfaceCounterFlagBitsEXT counter,
+ uint64_t* pCounterValue)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_display_control"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetSwapchainCounterEXT", "VK_EXT_display_control");
+ }
+ AEMU_SCOPED_TRACE("vkGetSwapchainCounterEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetSwapchainCounterEXT_VkResult_return = (VkResult)0;
+ vkGetSwapchainCounterEXT_VkResult_return = vkEnc->vkGetSwapchainCounterEXT(device, swapchain, counter, pCounterValue);
+ return vkGetSwapchainCounterEXT_VkResult_return;
+}
#endif
#ifdef VK_GOOGLE_display_timing
static VkResult entry_vkGetRefreshCycleDurationGOOGLE(
@@ -3401,6 +4435,22 @@
vkGetRefreshCycleDurationGOOGLE_VkResult_return = vkEnc->vkGetRefreshCycleDurationGOOGLE(device, swapchain, pDisplayTimingProperties);
return vkGetRefreshCycleDurationGOOGLE_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetRefreshCycleDurationGOOGLE(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_GOOGLE_display_timing"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetRefreshCycleDurationGOOGLE", "VK_GOOGLE_display_timing");
+ }
+ AEMU_SCOPED_TRACE("vkGetRefreshCycleDurationGOOGLE");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetRefreshCycleDurationGOOGLE_VkResult_return = (VkResult)0;
+ vkGetRefreshCycleDurationGOOGLE_VkResult_return = vkEnc->vkGetRefreshCycleDurationGOOGLE(device, swapchain, pDisplayTimingProperties);
+ return vkGetRefreshCycleDurationGOOGLE_VkResult_return;
+}
static VkResult entry_vkGetPastPresentationTimingGOOGLE(
VkDevice device,
VkSwapchainKHR swapchain,
@@ -3413,6 +4463,23 @@
vkGetPastPresentationTimingGOOGLE_VkResult_return = vkEnc->vkGetPastPresentationTimingGOOGLE(device, swapchain, pPresentationTimingCount, pPresentationTimings);
return vkGetPastPresentationTimingGOOGLE_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetPastPresentationTimingGOOGLE(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint32_t* pPresentationTimingCount,
+ VkPastPresentationTimingGOOGLE* pPresentationTimings)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_GOOGLE_display_timing"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetPastPresentationTimingGOOGLE", "VK_GOOGLE_display_timing");
+ }
+ AEMU_SCOPED_TRACE("vkGetPastPresentationTimingGOOGLE");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetPastPresentationTimingGOOGLE_VkResult_return = (VkResult)0;
+ vkGetPastPresentationTimingGOOGLE_VkResult_return = vkEnc->vkGetPastPresentationTimingGOOGLE(device, swapchain, pPresentationTimingCount, pPresentationTimings);
+ return vkGetPastPresentationTimingGOOGLE_VkResult_return;
+}
#endif
#ifdef VK_NV_sample_mask_override_coverage
#endif
@@ -3452,6 +4519,21 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkSetHdrMetadataEXT(device, swapchainCount, pSwapchains, pMetadata);
}
+static void dynCheck_entry_vkSetHdrMetadataEXT(
+ VkDevice device,
+ uint32_t swapchainCount,
+ const VkSwapchainKHR* pSwapchains,
+ const VkHdrMetadataEXT* pMetadata)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_hdr_metadata"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkSetHdrMetadataEXT", "VK_EXT_hdr_metadata");
+ }
+ AEMU_SCOPED_TRACE("vkSetHdrMetadataEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkSetHdrMetadataEXT(device, swapchainCount, pSwapchains, pMetadata);
+}
#endif
#ifdef VK_MVK_ios_surface
static VkResult entry_vkCreateIOSSurfaceMVK(
@@ -3496,6 +4578,21 @@
vkSetDebugUtilsObjectNameEXT_VkResult_return = vkEnc->vkSetDebugUtilsObjectNameEXT(device, pNameInfo);
return vkSetDebugUtilsObjectNameEXT_VkResult_return;
}
+static VkResult dynCheck_entry_vkSetDebugUtilsObjectNameEXT(
+ VkDevice device,
+ const VkDebugUtilsObjectNameInfoEXT* pNameInfo)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_debug_utils"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkSetDebugUtilsObjectNameEXT", "VK_EXT_debug_utils");
+ }
+ AEMU_SCOPED_TRACE("vkSetDebugUtilsObjectNameEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkSetDebugUtilsObjectNameEXT_VkResult_return = (VkResult)0;
+ vkSetDebugUtilsObjectNameEXT_VkResult_return = vkEnc->vkSetDebugUtilsObjectNameEXT(device, pNameInfo);
+ return vkSetDebugUtilsObjectNameEXT_VkResult_return;
+}
static VkResult entry_vkSetDebugUtilsObjectTagEXT(
VkDevice device,
const VkDebugUtilsObjectTagInfoEXT* pTagInfo)
@@ -3506,6 +4603,21 @@
vkSetDebugUtilsObjectTagEXT_VkResult_return = vkEnc->vkSetDebugUtilsObjectTagEXT(device, pTagInfo);
return vkSetDebugUtilsObjectTagEXT_VkResult_return;
}
+static VkResult dynCheck_entry_vkSetDebugUtilsObjectTagEXT(
+ VkDevice device,
+ const VkDebugUtilsObjectTagInfoEXT* pTagInfo)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_debug_utils"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkSetDebugUtilsObjectTagEXT", "VK_EXT_debug_utils");
+ }
+ AEMU_SCOPED_TRACE("vkSetDebugUtilsObjectTagEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkSetDebugUtilsObjectTagEXT_VkResult_return = (VkResult)0;
+ vkSetDebugUtilsObjectTagEXT_VkResult_return = vkEnc->vkSetDebugUtilsObjectTagEXT(device, pTagInfo);
+ return vkSetDebugUtilsObjectTagEXT_VkResult_return;
+}
static void entry_vkQueueBeginDebugUtilsLabelEXT(
VkQueue queue,
const VkDebugUtilsLabelEXT* pLabelInfo)
@@ -3600,6 +4712,22 @@
vkGetAndroidHardwareBufferPropertiesANDROID_VkResult_return = resources->on_vkGetAndroidHardwareBufferPropertiesANDROID(vkEnc, VK_SUCCESS, device, buffer, pProperties);
return vkGetAndroidHardwareBufferPropertiesANDROID_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetAndroidHardwareBufferPropertiesANDROID(
+ VkDevice device,
+ const AHardwareBuffer* buffer,
+ VkAndroidHardwareBufferPropertiesANDROID* pProperties)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_ANDROID_external_memory_android_hardware_buffer"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetAndroidHardwareBufferPropertiesANDROID", "VK_ANDROID_external_memory_android_hardware_buffer");
+ }
+ AEMU_SCOPED_TRACE("vkGetAndroidHardwareBufferPropertiesANDROID");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetAndroidHardwareBufferPropertiesANDROID_VkResult_return = (VkResult)0;
+ vkGetAndroidHardwareBufferPropertiesANDROID_VkResult_return = resources->on_vkGetAndroidHardwareBufferPropertiesANDROID(vkEnc, VK_SUCCESS, device, buffer, pProperties);
+ return vkGetAndroidHardwareBufferPropertiesANDROID_VkResult_return;
+}
static VkResult entry_vkGetMemoryAndroidHardwareBufferANDROID(
VkDevice device,
const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo,
@@ -3612,6 +4740,22 @@
vkGetMemoryAndroidHardwareBufferANDROID_VkResult_return = resources->on_vkGetMemoryAndroidHardwareBufferANDROID(vkEnc, VK_SUCCESS, device, pInfo, pBuffer);
return vkGetMemoryAndroidHardwareBufferANDROID_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetMemoryAndroidHardwareBufferANDROID(
+ VkDevice device,
+ const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo,
+ AHardwareBuffer** pBuffer)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_ANDROID_external_memory_android_hardware_buffer"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetMemoryAndroidHardwareBufferANDROID", "VK_ANDROID_external_memory_android_hardware_buffer");
+ }
+ AEMU_SCOPED_TRACE("vkGetMemoryAndroidHardwareBufferANDROID");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetMemoryAndroidHardwareBufferANDROID_VkResult_return = (VkResult)0;
+ vkGetMemoryAndroidHardwareBufferANDROID_VkResult_return = resources->on_vkGetMemoryAndroidHardwareBufferANDROID(vkEnc, VK_SUCCESS, device, pInfo, pBuffer);
+ return vkGetMemoryAndroidHardwareBufferANDROID_VkResult_return;
+}
#endif
#ifdef VK_EXT_sampler_filter_minmax
#endif
@@ -3666,6 +4810,23 @@
vkCreateValidationCacheEXT_VkResult_return = vkEnc->vkCreateValidationCacheEXT(device, pCreateInfo, pAllocator, pValidationCache);
return vkCreateValidationCacheEXT_VkResult_return;
}
+static VkResult dynCheck_entry_vkCreateValidationCacheEXT(
+ VkDevice device,
+ const VkValidationCacheCreateInfoEXT* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkValidationCacheEXT* pValidationCache)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_validation_cache"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkCreateValidationCacheEXT", "VK_EXT_validation_cache");
+ }
+ AEMU_SCOPED_TRACE("vkCreateValidationCacheEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkCreateValidationCacheEXT_VkResult_return = (VkResult)0;
+ vkCreateValidationCacheEXT_VkResult_return = vkEnc->vkCreateValidationCacheEXT(device, pCreateInfo, pAllocator, pValidationCache);
+ return vkCreateValidationCacheEXT_VkResult_return;
+}
static void entry_vkDestroyValidationCacheEXT(
VkDevice device,
VkValidationCacheEXT validationCache,
@@ -3675,6 +4836,20 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkDestroyValidationCacheEXT(device, validationCache, pAllocator);
}
+static void dynCheck_entry_vkDestroyValidationCacheEXT(
+ VkDevice device,
+ VkValidationCacheEXT validationCache,
+ const VkAllocationCallbacks* pAllocator)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_validation_cache"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkDestroyValidationCacheEXT", "VK_EXT_validation_cache");
+ }
+ AEMU_SCOPED_TRACE("vkDestroyValidationCacheEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkDestroyValidationCacheEXT(device, validationCache, pAllocator);
+}
static VkResult entry_vkMergeValidationCachesEXT(
VkDevice device,
VkValidationCacheEXT dstCache,
@@ -3687,6 +4862,23 @@
vkMergeValidationCachesEXT_VkResult_return = vkEnc->vkMergeValidationCachesEXT(device, dstCache, srcCacheCount, pSrcCaches);
return vkMergeValidationCachesEXT_VkResult_return;
}
+static VkResult dynCheck_entry_vkMergeValidationCachesEXT(
+ VkDevice device,
+ VkValidationCacheEXT dstCache,
+ uint32_t srcCacheCount,
+ const VkValidationCacheEXT* pSrcCaches)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_validation_cache"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkMergeValidationCachesEXT", "VK_EXT_validation_cache");
+ }
+ AEMU_SCOPED_TRACE("vkMergeValidationCachesEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkMergeValidationCachesEXT_VkResult_return = (VkResult)0;
+ vkMergeValidationCachesEXT_VkResult_return = vkEnc->vkMergeValidationCachesEXT(device, dstCache, srcCacheCount, pSrcCaches);
+ return vkMergeValidationCachesEXT_VkResult_return;
+}
static VkResult entry_vkGetValidationCacheDataEXT(
VkDevice device,
VkValidationCacheEXT validationCache,
@@ -3699,6 +4891,23 @@
vkGetValidationCacheDataEXT_VkResult_return = vkEnc->vkGetValidationCacheDataEXT(device, validationCache, pDataSize, pData);
return vkGetValidationCacheDataEXT_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetValidationCacheDataEXT(
+ VkDevice device,
+ VkValidationCacheEXT validationCache,
+ size_t* pDataSize,
+ void* pData)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_validation_cache"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetValidationCacheDataEXT", "VK_EXT_validation_cache");
+ }
+ AEMU_SCOPED_TRACE("vkGetValidationCacheDataEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetValidationCacheDataEXT_VkResult_return = (VkResult)0;
+ vkGetValidationCacheDataEXT_VkResult_return = vkEnc->vkGetValidationCacheDataEXT(device, validationCache, pDataSize, pData);
+ return vkGetValidationCacheDataEXT_VkResult_return;
+}
#endif
#ifdef VK_EXT_descriptor_indexing
#endif
@@ -3719,6 +4928,23 @@
vkGetMemoryHostPointerPropertiesEXT_VkResult_return = vkEnc->vkGetMemoryHostPointerPropertiesEXT(device, handleType, pHostPointer, pMemoryHostPointerProperties);
return vkGetMemoryHostPointerPropertiesEXT_VkResult_return;
}
+static VkResult dynCheck_entry_vkGetMemoryHostPointerPropertiesEXT(
+ VkDevice device,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ const void* pHostPointer,
+ VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_EXT_external_memory_host"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkGetMemoryHostPointerPropertiesEXT", "VK_EXT_external_memory_host");
+ }
+ AEMU_SCOPED_TRACE("vkGetMemoryHostPointerPropertiesEXT");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkGetMemoryHostPointerPropertiesEXT_VkResult_return = (VkResult)0;
+ vkGetMemoryHostPointerPropertiesEXT_VkResult_return = vkEnc->vkGetMemoryHostPointerPropertiesEXT(device, handleType, pHostPointer, pMemoryHostPointerProperties);
+ return vkGetMemoryHostPointerPropertiesEXT_VkResult_return;
+}
#endif
#ifdef VK_AMD_buffer_marker
static void entry_vkCmdWriteBufferMarkerAMD(
@@ -3772,6 +4998,22 @@
vkMapMemoryIntoAddressSpaceGOOGLE_VkResult_return = vkEnc->vkMapMemoryIntoAddressSpaceGOOGLE(device, memory, pAddress);
return vkMapMemoryIntoAddressSpaceGOOGLE_VkResult_return;
}
+static VkResult dynCheck_entry_vkMapMemoryIntoAddressSpaceGOOGLE(
+ VkDevice device,
+ VkDeviceMemory memory,
+ uint64_t* pAddress)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_GOOGLE_address_space"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkMapMemoryIntoAddressSpaceGOOGLE", "VK_GOOGLE_address_space");
+ }
+ AEMU_SCOPED_TRACE("vkMapMemoryIntoAddressSpaceGOOGLE");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkMapMemoryIntoAddressSpaceGOOGLE_VkResult_return = (VkResult)0;
+ vkMapMemoryIntoAddressSpaceGOOGLE_VkResult_return = vkEnc->vkMapMemoryIntoAddressSpaceGOOGLE(device, memory, pAddress);
+ return vkMapMemoryIntoAddressSpaceGOOGLE_VkResult_return;
+}
#endif
#ifdef VK_GOOGLE_color_buffer
static VkResult entry_vkRegisterImageColorBufferGOOGLE(
@@ -3785,6 +5027,22 @@
vkRegisterImageColorBufferGOOGLE_VkResult_return = vkEnc->vkRegisterImageColorBufferGOOGLE(device, image, colorBuffer);
return vkRegisterImageColorBufferGOOGLE_VkResult_return;
}
+static VkResult dynCheck_entry_vkRegisterImageColorBufferGOOGLE(
+ VkDevice device,
+ VkImage image,
+ uint32_t colorBuffer)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_GOOGLE_color_buffer"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkRegisterImageColorBufferGOOGLE", "VK_GOOGLE_color_buffer");
+ }
+ AEMU_SCOPED_TRACE("vkRegisterImageColorBufferGOOGLE");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkRegisterImageColorBufferGOOGLE_VkResult_return = (VkResult)0;
+ vkRegisterImageColorBufferGOOGLE_VkResult_return = vkEnc->vkRegisterImageColorBufferGOOGLE(device, image, colorBuffer);
+ return vkRegisterImageColorBufferGOOGLE_VkResult_return;
+}
static VkResult entry_vkRegisterBufferColorBufferGOOGLE(
VkDevice device,
VkBuffer buffer,
@@ -3796,6 +5054,22 @@
vkRegisterBufferColorBufferGOOGLE_VkResult_return = vkEnc->vkRegisterBufferColorBufferGOOGLE(device, buffer, colorBuffer);
return vkRegisterBufferColorBufferGOOGLE_VkResult_return;
}
+static VkResult dynCheck_entry_vkRegisterBufferColorBufferGOOGLE(
+ VkDevice device,
+ VkBuffer buffer,
+ uint32_t colorBuffer)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_GOOGLE_color_buffer"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkRegisterBufferColorBufferGOOGLE", "VK_GOOGLE_color_buffer");
+ }
+ AEMU_SCOPED_TRACE("vkRegisterBufferColorBufferGOOGLE");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkRegisterBufferColorBufferGOOGLE_VkResult_return = (VkResult)0;
+ vkRegisterBufferColorBufferGOOGLE_VkResult_return = vkEnc->vkRegisterBufferColorBufferGOOGLE(device, buffer, colorBuffer);
+ return vkRegisterBufferColorBufferGOOGLE_VkResult_return;
+}
#endif
#ifdef VK_GOOGLE_sized_descriptor_update_template
static void entry_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(
@@ -3816,6 +5090,29 @@
auto vkEnc = HostConnection::get()->vkEncoder();
vkEnc->vkUpdateDescriptorSetWithTemplateSizedGOOGLE(device, descriptorSet, descriptorUpdateTemplate, imageInfoCount, bufferInfoCount, bufferViewCount, pImageInfoEntryIndices, pBufferInfoEntryIndices, pBufferViewEntryIndices, pImageInfos, pBufferInfos, pBufferViews);
}
+static void dynCheck_entry_vkUpdateDescriptorSetWithTemplateSizedGOOGLE(
+ VkDevice device,
+ VkDescriptorSet descriptorSet,
+ VkDescriptorUpdateTemplate descriptorUpdateTemplate,
+ uint32_t imageInfoCount,
+ uint32_t bufferInfoCount,
+ uint32_t bufferViewCount,
+ const uint32_t* pImageInfoEntryIndices,
+ const uint32_t* pBufferInfoEntryIndices,
+ const uint32_t* pBufferViewEntryIndices,
+ const VkDescriptorImageInfo* pImageInfos,
+ const VkDescriptorBufferInfo* pBufferInfos,
+ const VkBufferView* pBufferViews)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_GOOGLE_sized_descriptor_update_template"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkUpdateDescriptorSetWithTemplateSizedGOOGLE", "VK_GOOGLE_sized_descriptor_update_template");
+ }
+ AEMU_SCOPED_TRACE("vkUpdateDescriptorSetWithTemplateSizedGOOGLE");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ vkEnc->vkUpdateDescriptorSetWithTemplateSizedGOOGLE(device, descriptorSet, descriptorUpdateTemplate, imageInfoCount, bufferInfoCount, bufferViewCount, pImageInfoEntryIndices, pBufferInfoEntryIndices, pBufferViewEntryIndices, pImageInfos, pBufferInfos, pBufferViews);
+}
#endif
#ifdef VK_GOOGLE_async_command_buffers
static void entry_vkBeginCommandBufferAsyncGOOGLE(
@@ -3869,6 +5166,24 @@
vkCreateImageWithRequirementsGOOGLE_VkResult_return = vkEnc->vkCreateImageWithRequirementsGOOGLE(device, pCreateInfo, pAllocator, pImage, pMemoryRequirements);
return vkCreateImageWithRequirementsGOOGLE_VkResult_return;
}
+static VkResult dynCheck_entry_vkCreateImageWithRequirementsGOOGLE(
+ VkDevice device,
+ const VkImageCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkImage* pImage,
+ VkMemoryRequirements* pMemoryRequirements)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_GOOGLE_create_resources_with_requirements"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkCreateImageWithRequirementsGOOGLE", "VK_GOOGLE_create_resources_with_requirements");
+ }
+ AEMU_SCOPED_TRACE("vkCreateImageWithRequirementsGOOGLE");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkCreateImageWithRequirementsGOOGLE_VkResult_return = (VkResult)0;
+ vkCreateImageWithRequirementsGOOGLE_VkResult_return = vkEnc->vkCreateImageWithRequirementsGOOGLE(device, pCreateInfo, pAllocator, pImage, pMemoryRequirements);
+ return vkCreateImageWithRequirementsGOOGLE_VkResult_return;
+}
static VkResult entry_vkCreateBufferWithRequirementsGOOGLE(
VkDevice device,
const VkBufferCreateInfo* pCreateInfo,
@@ -3882,6 +5197,24 @@
vkCreateBufferWithRequirementsGOOGLE_VkResult_return = vkEnc->vkCreateBufferWithRequirementsGOOGLE(device, pCreateInfo, pAllocator, pBuffer, pMemoryRequirements);
return vkCreateBufferWithRequirementsGOOGLE_VkResult_return;
}
+static VkResult dynCheck_entry_vkCreateBufferWithRequirementsGOOGLE(
+ VkDevice device,
+ const VkBufferCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkBuffer* pBuffer,
+ VkMemoryRequirements* pMemoryRequirements)
+{
+ auto resources = ResourceTracker::get();
+ if (!resources->hasDeviceExtension(device, "VK_GOOGLE_create_resources_with_requirements"))
+ {
+ sOnInvalidDynamicallyCheckedCall("vkCreateBufferWithRequirementsGOOGLE", "VK_GOOGLE_create_resources_with_requirements");
+ }
+ AEMU_SCOPED_TRACE("vkCreateBufferWithRequirementsGOOGLE");
+ auto vkEnc = HostConnection::get()->vkEncoder();
+ VkResult vkCreateBufferWithRequirementsGOOGLE_VkResult_return = (VkResult)0;
+ vkCreateBufferWithRequirementsGOOGLE_VkResult_return = vkEnc->vkCreateBufferWithRequirementsGOOGLE(device, pCreateInfo, pAllocator, pBuffer, pMemoryRequirements);
+ return vkCreateBufferWithRequirementsGOOGLE_VkResult_return;
+}
#endif
void* goldfish_vulkan_get_proc_address(const char* name){
#ifdef VK_VERSION_1_0
@@ -5890,15 +7223,15 @@
}
if (!strcmp(name, "vkBindBufferMemory2"))
{
- return has1_1OrHigher ? (void*)entry_vkBindBufferMemory2 : nullptr;
+ return (void*)dynCheck_entry_vkBindBufferMemory2;
}
if (!strcmp(name, "vkBindImageMemory2"))
{
- return has1_1OrHigher ? (void*)entry_vkBindImageMemory2 : nullptr;
+ return (void*)dynCheck_entry_vkBindImageMemory2;
}
if (!strcmp(name, "vkGetDeviceGroupPeerMemoryFeatures"))
{
- return has1_1OrHigher ? (void*)entry_vkGetDeviceGroupPeerMemoryFeatures : nullptr;
+ return (void*)dynCheck_entry_vkGetDeviceGroupPeerMemoryFeatures;
}
if (!strcmp(name, "vkCmdSetDeviceMask"))
{
@@ -5914,15 +7247,15 @@
}
if (!strcmp(name, "vkGetImageMemoryRequirements2"))
{
- return has1_1OrHigher ? (void*)entry_vkGetImageMemoryRequirements2 : nullptr;
+ return (void*)dynCheck_entry_vkGetImageMemoryRequirements2;
}
if (!strcmp(name, "vkGetBufferMemoryRequirements2"))
{
- return has1_1OrHigher ? (void*)entry_vkGetBufferMemoryRequirements2 : nullptr;
+ return (void*)dynCheck_entry_vkGetBufferMemoryRequirements2;
}
if (!strcmp(name, "vkGetImageSparseMemoryRequirements2"))
{
- return has1_1OrHigher ? (void*)entry_vkGetImageSparseMemoryRequirements2 : nullptr;
+ return (void*)dynCheck_entry_vkGetImageSparseMemoryRequirements2;
}
if (!strcmp(name, "vkGetPhysicalDeviceFeatures2"))
{
@@ -5954,31 +7287,31 @@
}
if (!strcmp(name, "vkTrimCommandPool"))
{
- return has1_1OrHigher ? (void*)entry_vkTrimCommandPool : nullptr;
+ return (void*)dynCheck_entry_vkTrimCommandPool;
}
if (!strcmp(name, "vkGetDeviceQueue2"))
{
- return has1_1OrHigher ? (void*)entry_vkGetDeviceQueue2 : nullptr;
+ return (void*)dynCheck_entry_vkGetDeviceQueue2;
}
if (!strcmp(name, "vkCreateSamplerYcbcrConversion"))
{
- return has1_1OrHigher ? (void*)entry_vkCreateSamplerYcbcrConversion : nullptr;
+ return (void*)dynCheck_entry_vkCreateSamplerYcbcrConversion;
}
if (!strcmp(name, "vkDestroySamplerYcbcrConversion"))
{
- return has1_1OrHigher ? (void*)entry_vkDestroySamplerYcbcrConversion : nullptr;
+ return (void*)dynCheck_entry_vkDestroySamplerYcbcrConversion;
}
if (!strcmp(name, "vkCreateDescriptorUpdateTemplate"))
{
- return has1_1OrHigher ? (void*)entry_vkCreateDescriptorUpdateTemplate : nullptr;
+ return (void*)dynCheck_entry_vkCreateDescriptorUpdateTemplate;
}
if (!strcmp(name, "vkDestroyDescriptorUpdateTemplate"))
{
- return has1_1OrHigher ? (void*)entry_vkDestroyDescriptorUpdateTemplate : nullptr;
+ return (void*)dynCheck_entry_vkDestroyDescriptorUpdateTemplate;
}
if (!strcmp(name, "vkUpdateDescriptorSetWithTemplate"))
{
- return has1_1OrHigher ? (void*)entry_vkUpdateDescriptorSetWithTemplate : nullptr;
+ return (void*)dynCheck_entry_vkUpdateDescriptorSetWithTemplate;
}
if (!strcmp(name, "vkGetPhysicalDeviceExternalBufferProperties"))
{
@@ -5994,7 +7327,7 @@
}
if (!strcmp(name, "vkGetDescriptorSetLayoutSupport"))
{
- return has1_1OrHigher ? (void*)entry_vkGetDescriptorSetLayoutSupport : nullptr;
+ return (void*)dynCheck_entry_vkGetDescriptorSetLayoutSupport;
}
#endif
#ifdef VK_KHR_surface
@@ -6027,23 +7360,19 @@
#ifdef VK_KHR_swapchain
if (!strcmp(name, "vkCreateSwapchainKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_swapchain");
- return hasExt ? (void*)entry_vkCreateSwapchainKHR : nullptr;
+ return (void*)dynCheck_entry_vkCreateSwapchainKHR;
}
if (!strcmp(name, "vkDestroySwapchainKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_swapchain");
- return hasExt ? (void*)entry_vkDestroySwapchainKHR : nullptr;
+ return (void*)dynCheck_entry_vkDestroySwapchainKHR;
}
if (!strcmp(name, "vkGetSwapchainImagesKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_swapchain");
- return hasExt ? (void*)entry_vkGetSwapchainImagesKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetSwapchainImagesKHR;
}
if (!strcmp(name, "vkAcquireNextImageKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_swapchain");
- return hasExt ? (void*)entry_vkAcquireNextImageKHR : nullptr;
+ return (void*)dynCheck_entry_vkAcquireNextImageKHR;
}
if (!strcmp(name, "vkQueuePresentKHR"))
{
@@ -6052,13 +7381,11 @@
}
if (!strcmp(name, "vkGetDeviceGroupPresentCapabilitiesKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_swapchain");
- return hasExt ? (void*)entry_vkGetDeviceGroupPresentCapabilitiesKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetDeviceGroupPresentCapabilitiesKHR;
}
if (!strcmp(name, "vkGetDeviceGroupSurfacePresentModesKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_swapchain");
- return hasExt ? (void*)entry_vkGetDeviceGroupSurfacePresentModesKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetDeviceGroupSurfacePresentModesKHR;
}
if (!strcmp(name, "vkGetPhysicalDevicePresentRectanglesKHR"))
{
@@ -6067,8 +7394,7 @@
}
if (!strcmp(name, "vkAcquireNextImage2KHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_swapchain");
- return hasExt ? (void*)entry_vkAcquireNextImage2KHR : nullptr;
+ return (void*)dynCheck_entry_vkAcquireNextImage2KHR;
}
#endif
#ifdef VK_KHR_display
@@ -6111,8 +7437,7 @@
#ifdef VK_KHR_display_swapchain
if (!strcmp(name, "vkCreateSharedSwapchainsKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_display_swapchain");
- return hasExt ? (void*)entry_vkCreateSharedSwapchainsKHR : nullptr;
+ return (void*)dynCheck_entry_vkCreateSharedSwapchainsKHR;
}
#endif
#ifdef VK_KHR_xlib_surface
@@ -6222,8 +7547,7 @@
#ifdef VK_KHR_device_group
if (!strcmp(name, "vkGetDeviceGroupPeerMemoryFeaturesKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_device_group");
- return hasExt ? (void*)entry_vkGetDeviceGroupPeerMemoryFeaturesKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetDeviceGroupPeerMemoryFeaturesKHR;
}
if (!strcmp(name, "vkCmdSetDeviceMaskKHR"))
{
@@ -6239,8 +7563,7 @@
#ifdef VK_KHR_maintenance1
if (!strcmp(name, "vkTrimCommandPoolKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_maintenance1");
- return hasExt ? (void*)entry_vkTrimCommandPoolKHR : nullptr;
+ return (void*)dynCheck_entry_vkTrimCommandPoolKHR;
}
#endif
#ifdef VK_KHR_device_group_creation
@@ -6260,25 +7583,21 @@
#ifdef VK_KHR_external_memory_win32
if (!strcmp(name, "vkGetMemoryWin32HandleKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_external_memory_win32");
- return hasExt ? (void*)entry_vkGetMemoryWin32HandleKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetMemoryWin32HandleKHR;
}
if (!strcmp(name, "vkGetMemoryWin32HandlePropertiesKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_external_memory_win32");
- return hasExt ? (void*)entry_vkGetMemoryWin32HandlePropertiesKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetMemoryWin32HandlePropertiesKHR;
}
#endif
#ifdef VK_KHR_external_memory_fd
if (!strcmp(name, "vkGetMemoryFdKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_external_memory_fd");
- return hasExt ? (void*)entry_vkGetMemoryFdKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetMemoryFdKHR;
}
if (!strcmp(name, "vkGetMemoryFdPropertiesKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_external_memory_fd");
- return hasExt ? (void*)entry_vkGetMemoryFdPropertiesKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetMemoryFdPropertiesKHR;
}
#endif
#ifdef VK_KHR_external_semaphore_capabilities
@@ -6291,25 +7610,21 @@
#ifdef VK_KHR_external_semaphore_win32
if (!strcmp(name, "vkImportSemaphoreWin32HandleKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_external_semaphore_win32");
- return hasExt ? (void*)entry_vkImportSemaphoreWin32HandleKHR : nullptr;
+ return (void*)dynCheck_entry_vkImportSemaphoreWin32HandleKHR;
}
if (!strcmp(name, "vkGetSemaphoreWin32HandleKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_external_semaphore_win32");
- return hasExt ? (void*)entry_vkGetSemaphoreWin32HandleKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetSemaphoreWin32HandleKHR;
}
#endif
#ifdef VK_KHR_external_semaphore_fd
if (!strcmp(name, "vkImportSemaphoreFdKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_external_semaphore_fd");
- return hasExt ? (void*)entry_vkImportSemaphoreFdKHR : nullptr;
+ return (void*)dynCheck_entry_vkImportSemaphoreFdKHR;
}
if (!strcmp(name, "vkGetSemaphoreFdKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_external_semaphore_fd");
- return hasExt ? (void*)entry_vkGetSemaphoreFdKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetSemaphoreFdKHR;
}
#endif
#ifdef VK_KHR_push_descriptor
@@ -6327,25 +7642,21 @@
#ifdef VK_KHR_descriptor_update_template
if (!strcmp(name, "vkCreateDescriptorUpdateTemplateKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_descriptor_update_template");
- return hasExt ? (void*)entry_vkCreateDescriptorUpdateTemplateKHR : nullptr;
+ return (void*)dynCheck_entry_vkCreateDescriptorUpdateTemplateKHR;
}
if (!strcmp(name, "vkDestroyDescriptorUpdateTemplateKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_descriptor_update_template");
- return hasExt ? (void*)entry_vkDestroyDescriptorUpdateTemplateKHR : nullptr;
+ return (void*)dynCheck_entry_vkDestroyDescriptorUpdateTemplateKHR;
}
if (!strcmp(name, "vkUpdateDescriptorSetWithTemplateKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_descriptor_update_template");
- return hasExt ? (void*)entry_vkUpdateDescriptorSetWithTemplateKHR : nullptr;
+ return (void*)dynCheck_entry_vkUpdateDescriptorSetWithTemplateKHR;
}
#endif
#ifdef VK_KHR_create_renderpass2
if (!strcmp(name, "vkCreateRenderPass2KHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_create_renderpass2");
- return hasExt ? (void*)entry_vkCreateRenderPass2KHR : nullptr;
+ return (void*)dynCheck_entry_vkCreateRenderPass2KHR;
}
if (!strcmp(name, "vkCmdBeginRenderPass2KHR"))
{
@@ -6366,8 +7677,7 @@
#ifdef VK_KHR_shared_presentable_image
if (!strcmp(name, "vkGetSwapchainStatusKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_shared_presentable_image");
- return hasExt ? (void*)entry_vkGetSwapchainStatusKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetSwapchainStatusKHR;
}
#endif
#ifdef VK_KHR_external_fence_capabilities
@@ -6380,25 +7690,21 @@
#ifdef VK_KHR_external_fence_win32
if (!strcmp(name, "vkImportFenceWin32HandleKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_external_fence_win32");
- return hasExt ? (void*)entry_vkImportFenceWin32HandleKHR : nullptr;
+ return (void*)dynCheck_entry_vkImportFenceWin32HandleKHR;
}
if (!strcmp(name, "vkGetFenceWin32HandleKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_external_fence_win32");
- return hasExt ? (void*)entry_vkGetFenceWin32HandleKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetFenceWin32HandleKHR;
}
#endif
#ifdef VK_KHR_external_fence_fd
if (!strcmp(name, "vkImportFenceFdKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_external_fence_fd");
- return hasExt ? (void*)entry_vkImportFenceFdKHR : nullptr;
+ return (void*)dynCheck_entry_vkImportFenceFdKHR;
}
if (!strcmp(name, "vkGetFenceFdKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_external_fence_fd");
- return hasExt ? (void*)entry_vkGetFenceFdKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetFenceFdKHR;
}
#endif
#ifdef VK_KHR_get_surface_capabilities2
@@ -6438,49 +7744,41 @@
#ifdef VK_KHR_get_memory_requirements2
if (!strcmp(name, "vkGetImageMemoryRequirements2KHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_get_memory_requirements2");
- return hasExt ? (void*)entry_vkGetImageMemoryRequirements2KHR : nullptr;
+ return (void*)dynCheck_entry_vkGetImageMemoryRequirements2KHR;
}
if (!strcmp(name, "vkGetBufferMemoryRequirements2KHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_get_memory_requirements2");
- return hasExt ? (void*)entry_vkGetBufferMemoryRequirements2KHR : nullptr;
+ return (void*)dynCheck_entry_vkGetBufferMemoryRequirements2KHR;
}
if (!strcmp(name, "vkGetImageSparseMemoryRequirements2KHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_get_memory_requirements2");
- return hasExt ? (void*)entry_vkGetImageSparseMemoryRequirements2KHR : nullptr;
+ return (void*)dynCheck_entry_vkGetImageSparseMemoryRequirements2KHR;
}
#endif
#ifdef VK_KHR_sampler_ycbcr_conversion
if (!strcmp(name, "vkCreateSamplerYcbcrConversionKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_sampler_ycbcr_conversion");
- return hasExt ? (void*)entry_vkCreateSamplerYcbcrConversionKHR : nullptr;
+ return (void*)dynCheck_entry_vkCreateSamplerYcbcrConversionKHR;
}
if (!strcmp(name, "vkDestroySamplerYcbcrConversionKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_sampler_ycbcr_conversion");
- return hasExt ? (void*)entry_vkDestroySamplerYcbcrConversionKHR : nullptr;
+ return (void*)dynCheck_entry_vkDestroySamplerYcbcrConversionKHR;
}
#endif
#ifdef VK_KHR_bind_memory2
if (!strcmp(name, "vkBindBufferMemory2KHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_bind_memory2");
- return hasExt ? (void*)entry_vkBindBufferMemory2KHR : nullptr;
+ return (void*)dynCheck_entry_vkBindBufferMemory2KHR;
}
if (!strcmp(name, "vkBindImageMemory2KHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_bind_memory2");
- return hasExt ? (void*)entry_vkBindImageMemory2KHR : nullptr;
+ return (void*)dynCheck_entry_vkBindImageMemory2KHR;
}
#endif
#ifdef VK_KHR_maintenance3
if (!strcmp(name, "vkGetDescriptorSetLayoutSupportKHR"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_KHR_maintenance3");
- return hasExt ? (void*)entry_vkGetDescriptorSetLayoutSupportKHR : nullptr;
+ return (void*)dynCheck_entry_vkGetDescriptorSetLayoutSupportKHR;
}
#endif
#ifdef VK_KHR_draw_indirect_count
@@ -6498,13 +7796,11 @@
#ifdef VK_ANDROID_native_buffer
if (!strcmp(name, "vkGetSwapchainGrallocUsageANDROID"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_ANDROID_native_buffer");
- return hasExt ? (void*)entry_vkGetSwapchainGrallocUsageANDROID : nullptr;
+ return (void*)dynCheck_entry_vkGetSwapchainGrallocUsageANDROID;
}
if (!strcmp(name, "vkAcquireImageANDROID"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_ANDROID_native_buffer");
- return hasExt ? (void*)entry_vkAcquireImageANDROID : nullptr;
+ return (void*)dynCheck_entry_vkAcquireImageANDROID;
}
if (!strcmp(name, "vkQueueSignalReleaseImageANDROID"))
{
@@ -6532,13 +7828,11 @@
#ifdef VK_EXT_debug_marker
if (!strcmp(name, "vkDebugMarkerSetObjectTagEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_debug_marker");
- return hasExt ? (void*)entry_vkDebugMarkerSetObjectTagEXT : nullptr;
+ return (void*)dynCheck_entry_vkDebugMarkerSetObjectTagEXT;
}
if (!strcmp(name, "vkDebugMarkerSetObjectNameEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_debug_marker");
- return hasExt ? (void*)entry_vkDebugMarkerSetObjectNameEXT : nullptr;
+ return (void*)dynCheck_entry_vkDebugMarkerSetObjectNameEXT;
}
if (!strcmp(name, "vkCmdDebugMarkerBeginEXT"))
{
@@ -6571,8 +7865,7 @@
#ifdef VK_AMD_shader_info
if (!strcmp(name, "vkGetShaderInfoAMD"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_AMD_shader_info");
- return hasExt ? (void*)entry_vkGetShaderInfoAMD : nullptr;
+ return (void*)dynCheck_entry_vkGetShaderInfoAMD;
}
#endif
#ifdef VK_NV_external_memory_capabilities
@@ -6585,8 +7878,7 @@
#ifdef VK_NV_external_memory_win32
if (!strcmp(name, "vkGetMemoryWin32HandleNV"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_NV_external_memory_win32");
- return hasExt ? (void*)entry_vkGetMemoryWin32HandleNV : nullptr;
+ return (void*)dynCheck_entry_vkGetMemoryWin32HandleNV;
}
#endif
#ifdef VK_NN_vi_surface
@@ -6621,33 +7913,27 @@
}
if (!strcmp(name, "vkCreateIndirectCommandsLayoutNVX"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_NVX_device_generated_commands");
- return hasExt ? (void*)entry_vkCreateIndirectCommandsLayoutNVX : nullptr;
+ return (void*)dynCheck_entry_vkCreateIndirectCommandsLayoutNVX;
}
if (!strcmp(name, "vkDestroyIndirectCommandsLayoutNVX"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_NVX_device_generated_commands");
- return hasExt ? (void*)entry_vkDestroyIndirectCommandsLayoutNVX : nullptr;
+ return (void*)dynCheck_entry_vkDestroyIndirectCommandsLayoutNVX;
}
if (!strcmp(name, "vkCreateObjectTableNVX"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_NVX_device_generated_commands");
- return hasExt ? (void*)entry_vkCreateObjectTableNVX : nullptr;
+ return (void*)dynCheck_entry_vkCreateObjectTableNVX;
}
if (!strcmp(name, "vkDestroyObjectTableNVX"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_NVX_device_generated_commands");
- return hasExt ? (void*)entry_vkDestroyObjectTableNVX : nullptr;
+ return (void*)dynCheck_entry_vkDestroyObjectTableNVX;
}
if (!strcmp(name, "vkRegisterObjectsNVX"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_NVX_device_generated_commands");
- return hasExt ? (void*)entry_vkRegisterObjectsNVX : nullptr;
+ return (void*)dynCheck_entry_vkRegisterObjectsNVX;
}
if (!strcmp(name, "vkUnregisterObjectsNVX"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_NVX_device_generated_commands");
- return hasExt ? (void*)entry_vkUnregisterObjectsNVX : nullptr;
+ return (void*)dynCheck_entry_vkUnregisterObjectsNVX;
}
if (!strcmp(name, "vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX"))
{
@@ -6691,35 +7977,29 @@
#ifdef VK_EXT_display_control
if (!strcmp(name, "vkDisplayPowerControlEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_display_control");
- return hasExt ? (void*)entry_vkDisplayPowerControlEXT : nullptr;
+ return (void*)dynCheck_entry_vkDisplayPowerControlEXT;
}
if (!strcmp(name, "vkRegisterDeviceEventEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_display_control");
- return hasExt ? (void*)entry_vkRegisterDeviceEventEXT : nullptr;
+ return (void*)dynCheck_entry_vkRegisterDeviceEventEXT;
}
if (!strcmp(name, "vkRegisterDisplayEventEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_display_control");
- return hasExt ? (void*)entry_vkRegisterDisplayEventEXT : nullptr;
+ return (void*)dynCheck_entry_vkRegisterDisplayEventEXT;
}
if (!strcmp(name, "vkGetSwapchainCounterEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_display_control");
- return hasExt ? (void*)entry_vkGetSwapchainCounterEXT : nullptr;
+ return (void*)dynCheck_entry_vkGetSwapchainCounterEXT;
}
#endif
#ifdef VK_GOOGLE_display_timing
if (!strcmp(name, "vkGetRefreshCycleDurationGOOGLE"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_display_timing");
- return hasExt ? (void*)entry_vkGetRefreshCycleDurationGOOGLE : nullptr;
+ return (void*)dynCheck_entry_vkGetRefreshCycleDurationGOOGLE;
}
if (!strcmp(name, "vkGetPastPresentationTimingGOOGLE"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_display_timing");
- return hasExt ? (void*)entry_vkGetPastPresentationTimingGOOGLE : nullptr;
+ return (void*)dynCheck_entry_vkGetPastPresentationTimingGOOGLE;
}
#endif
#ifdef VK_EXT_discard_rectangles
@@ -6732,8 +8012,7 @@
#ifdef VK_EXT_hdr_metadata
if (!strcmp(name, "vkSetHdrMetadataEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_hdr_metadata");
- return hasExt ? (void*)entry_vkSetHdrMetadataEXT : nullptr;
+ return (void*)dynCheck_entry_vkSetHdrMetadataEXT;
}
#endif
#ifdef VK_MVK_ios_surface
@@ -6753,13 +8032,11 @@
#ifdef VK_EXT_debug_utils
if (!strcmp(name, "vkSetDebugUtilsObjectNameEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_debug_utils");
- return hasExt ? (void*)entry_vkSetDebugUtilsObjectNameEXT : nullptr;
+ return (void*)dynCheck_entry_vkSetDebugUtilsObjectNameEXT;
}
if (!strcmp(name, "vkSetDebugUtilsObjectTagEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_debug_utils");
- return hasExt ? (void*)entry_vkSetDebugUtilsObjectTagEXT : nullptr;
+ return (void*)dynCheck_entry_vkSetDebugUtilsObjectTagEXT;
}
if (!strcmp(name, "vkQueueBeginDebugUtilsLabelEXT"))
{
@@ -6810,13 +8087,11 @@
#ifdef VK_ANDROID_external_memory_android_hardware_buffer
if (!strcmp(name, "vkGetAndroidHardwareBufferPropertiesANDROID"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_ANDROID_external_memory_android_hardware_buffer");
- return hasExt ? (void*)entry_vkGetAndroidHardwareBufferPropertiesANDROID : nullptr;
+ return (void*)dynCheck_entry_vkGetAndroidHardwareBufferPropertiesANDROID;
}
if (!strcmp(name, "vkGetMemoryAndroidHardwareBufferANDROID"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_ANDROID_external_memory_android_hardware_buffer");
- return hasExt ? (void*)entry_vkGetMemoryAndroidHardwareBufferANDROID : nullptr;
+ return (void*)dynCheck_entry_vkGetMemoryAndroidHardwareBufferANDROID;
}
#endif
#ifdef VK_EXT_sample_locations
@@ -6834,30 +8109,25 @@
#ifdef VK_EXT_validation_cache
if (!strcmp(name, "vkCreateValidationCacheEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_validation_cache");
- return hasExt ? (void*)entry_vkCreateValidationCacheEXT : nullptr;
+ return (void*)dynCheck_entry_vkCreateValidationCacheEXT;
}
if (!strcmp(name, "vkDestroyValidationCacheEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_validation_cache");
- return hasExt ? (void*)entry_vkDestroyValidationCacheEXT : nullptr;
+ return (void*)dynCheck_entry_vkDestroyValidationCacheEXT;
}
if (!strcmp(name, "vkMergeValidationCachesEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_validation_cache");
- return hasExt ? (void*)entry_vkMergeValidationCachesEXT : nullptr;
+ return (void*)dynCheck_entry_vkMergeValidationCachesEXT;
}
if (!strcmp(name, "vkGetValidationCacheDataEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_validation_cache");
- return hasExt ? (void*)entry_vkGetValidationCacheDataEXT : nullptr;
+ return (void*)dynCheck_entry_vkGetValidationCacheDataEXT;
}
#endif
#ifdef VK_EXT_external_memory_host
if (!strcmp(name, "vkGetMemoryHostPointerPropertiesEXT"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_EXT_external_memory_host");
- return hasExt ? (void*)entry_vkGetMemoryHostPointerPropertiesEXT : nullptr;
+ return (void*)dynCheck_entry_vkGetMemoryHostPointerPropertiesEXT;
}
#endif
#ifdef VK_AMD_buffer_marker
@@ -6882,27 +8152,23 @@
#ifdef VK_GOOGLE_address_space
if (!strcmp(name, "vkMapMemoryIntoAddressSpaceGOOGLE"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_address_space");
- return hasExt ? (void*)entry_vkMapMemoryIntoAddressSpaceGOOGLE : nullptr;
+ return (void*)dynCheck_entry_vkMapMemoryIntoAddressSpaceGOOGLE;
}
#endif
#ifdef VK_GOOGLE_color_buffer
if (!strcmp(name, "vkRegisterImageColorBufferGOOGLE"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_color_buffer");
- return hasExt ? (void*)entry_vkRegisterImageColorBufferGOOGLE : nullptr;
+ return (void*)dynCheck_entry_vkRegisterImageColorBufferGOOGLE;
}
if (!strcmp(name, "vkRegisterBufferColorBufferGOOGLE"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_color_buffer");
- return hasExt ? (void*)entry_vkRegisterBufferColorBufferGOOGLE : nullptr;
+ return (void*)dynCheck_entry_vkRegisterBufferColorBufferGOOGLE;
}
#endif
#ifdef VK_GOOGLE_sized_descriptor_update_template
if (!strcmp(name, "vkUpdateDescriptorSetWithTemplateSizedGOOGLE"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_sized_descriptor_update_template");
- return hasExt ? (void*)entry_vkUpdateDescriptorSetWithTemplateSizedGOOGLE : nullptr;
+ return (void*)dynCheck_entry_vkUpdateDescriptorSetWithTemplateSizedGOOGLE;
}
#endif
#ifdef VK_GOOGLE_async_command_buffers
@@ -6930,13 +8196,11 @@
#ifdef VK_GOOGLE_create_resources_with_requirements
if (!strcmp(name, "vkCreateImageWithRequirementsGOOGLE"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_create_resources_with_requirements");
- return hasExt ? (void*)entry_vkCreateImageWithRequirementsGOOGLE : nullptr;
+ return (void*)dynCheck_entry_vkCreateImageWithRequirementsGOOGLE;
}
if (!strcmp(name, "vkCreateBufferWithRequirementsGOOGLE"))
{
- bool hasExt = resources->hasInstanceExtension(instance, "VK_GOOGLE_create_resources_with_requirements");
- return hasExt ? (void*)entry_vkCreateBufferWithRequirementsGOOGLE : nullptr;
+ return (void*)dynCheck_entry_vkCreateBufferWithRequirementsGOOGLE;
}
#endif
return nullptr;
diff --git a/system/vulkan/goldfish_vulkan.cpp b/system/vulkan/goldfish_vulkan.cpp
index 9187f94..9884d90 100644
--- a/system/vulkan/goldfish_vulkan.cpp
+++ b/system/vulkan/goldfish_vulkan.cpp
@@ -18,7 +18,15 @@
#include <errno.h>
#include <string.h>
#ifdef VK_USE_PLATFORM_FUCHSIA
+#include <fuchsia/logger/llcpp/fidl.h>
+#include <lib/syslog/global.h>
+#include <lib/zx/channel.h>
+#include <lib/zx/socket.h>
+#include <lib/zxio/zxio.h>
+#include <lib/zxio/inception.h>
#include <unistd.h>
+
+#include "services/service_connector.h"
#endif
#include "HostConnection.h"
@@ -662,10 +670,32 @@
class VulkanDevice {
public:
- VulkanDevice() : mHostSupportsGoldfish(access(QEMU_PIPE_PATH, F_OK) != -1) {
+ VulkanDevice() : mHostSupportsGoldfish(IsAccessible(QEMU_PIPE_PATH)) {
+ InitLogger();
goldfish_vk::ResourceTracker::get();
}
+ static void InitLogger();
+
+ static bool IsAccessible(const char* name) {
+ zx_handle_t handle = GetConnectToServiceFunction()(name);
+ if (handle == ZX_HANDLE_INVALID)
+ return false;
+
+ zxio_storage_t io_storage;
+ zx_status_t status = zxio_remote_init(&io_storage, handle, ZX_HANDLE_INVALID);
+ if (status != ZX_OK)
+ return false;
+
+ zxio_node_attr_t attr;
+ status = zxio_attr_get(&io_storage.io, &attr);
+ zxio_close(&io_storage.io);
+ if (status != ZX_OK)
+ return false;
+
+ return true;
+ }
+
static VulkanDevice& GetInstance() {
static VulkanDevice g_instance;
return g_instance;
@@ -682,6 +712,32 @@
const bool mHostSupportsGoldfish;
};
+void VulkanDevice::InitLogger() {
+ zx_handle_t channel = GetConnectToServiceFunction()("/svc/fuchsia.logger.LogSink");
+ if (channel == ZX_HANDLE_INVALID)
+ return;
+
+ zx::socket local_socket, remote_socket;
+ zx_status_t status = zx::socket::create(ZX_SOCKET_DATAGRAM, &local_socket, &remote_socket);
+ if (status != ZX_OK)
+ return;
+
+ auto result = llcpp::fuchsia::logger::LogSink::Call::Connect(
+ zx::unowned_channel(channel), std::move(remote_socket));
+ zx_handle_close(channel);
+
+ if (result.status() != ZX_OK)
+ return;
+
+ fx_logger_config_t config = {.min_severity = FX_LOG_INFO,
+ .console_fd = -1,
+ .log_service_channel = local_socket.release(),
+ .tags = nullptr,
+ .num_tags = 0};
+
+ fx_log_init_with_config(&config);
+}
+
extern "C" __attribute__((visibility("default"))) PFN_vkVoidFunction
vk_icdGetInstanceProcAddr(VkInstance instance, const char* name) {
return VulkanDevice::GetInstance().GetInstanceProcAddr(instance, name);
@@ -693,6 +749,34 @@
return VK_SUCCESS;
}
+typedef VkResult(VKAPI_PTR *PFN_vkConnectToServiceAddr)(const char *pName, uint32_t handle);
+
+namespace {
+
+PFN_vkConnectToServiceAddr g_vulkan_connector;
+
+zx_handle_t LocalConnectToServiceFunction(const char* pName) {
+ zx::channel remote_endpoint, local_endpoint;
+ zx_status_t status;
+ if ((status = zx::channel::create(0, &remote_endpoint, &local_endpoint)) != ZX_OK) {
+ ALOGE("zx::channel::create failed: %d", status);
+ return ZX_HANDLE_INVALID;
+ }
+ if ((status = g_vulkan_connector(pName, remote_endpoint.release())) != ZX_OK) {
+ ALOGE("vulkan_connector failed: %d", status);
+ return ZX_HANDLE_INVALID;
+ }
+ return local_endpoint.release();
+}
+
+}
+
+extern "C" __attribute__((visibility("default"))) void
+vk_icdInitializeConnectToServiceCallback(PFN_vkConnectToServiceAddr callback) {
+ g_vulkan_connector = callback;
+ SetConnectToServiceFunction(&LocalConnectToServiceFunction);
+}
+
#endif
} // namespace
diff --git a/system/vulkan_enc/AndroidHardwareBuffer.cpp b/system/vulkan_enc/AndroidHardwareBuffer.cpp
index 0a71d6d..a40a3a7 100644
--- a/system/vulkan_enc/AndroidHardwareBuffer.cpp
+++ b/system/vulkan_enc/AndroidHardwareBuffer.cpp
@@ -14,7 +14,8 @@
// limitations under the License.
#include "AndroidHardwareBuffer.h"
-#include "gralloc_cb.h"
+#include "../OpenglSystemCommon/HostConnection.h"
+
#include "vk_format_info.h"
#include "vk_util.h"
@@ -53,6 +54,7 @@
}
VkResult getAndroidHardwareBufferPropertiesANDROID(
+ Gralloc* grallocHelper,
const HostVisibleMemoryVirtualizationInfo* hostMemVirtInfo,
VkDevice,
const AHardwareBuffer* buffer,
@@ -111,12 +113,8 @@
const native_handle_t *handle =
AHardwareBuffer_getNativeHandle(buffer);
- const cb_handle_t* cb_handle = cb_handle_t::from(handle);
- if (!cb_handle) {
- return VK_ERROR_INVALID_EXTERNAL_HANDLE;
- }
-
- uint32_t colorBufferHandle = cb_handle->hostHandle;
+ uint32_t colorBufferHandle =
+ grallocHelper->getHostHandle(handle);
if (!colorBufferHandle) {
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
@@ -131,7 +129,8 @@
}
pProperties->memoryTypeBits = memoryTypeBits;
- pProperties->allocationSize = cb_handle->allocatedSize();
+ pProperties->allocationSize =
+ grallocHelper->getAllocatedSize(handle);
return VK_SUCCESS;
}
@@ -158,6 +157,7 @@
}
VkResult importAndroidHardwareBuffer(
+ Gralloc* grallocHelper,
const VkImportAndroidHardwareBufferInfoANDROID* info,
struct AHardwareBuffer **importOut) {
@@ -165,14 +165,9 @@
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
- const native_handle_t *handle =
- AHardwareBuffer_getNativeHandle(info->buffer);
- const cb_handle_t* cb_handle = cb_handle_t::from(handle);
- if (!cb_handle) {
- return VK_ERROR_INVALID_EXTERNAL_HANDLE;
- }
-
- uint32_t colorBufferHandle = cb_handle->hostHandle;
+ uint32_t colorBufferHandle =
+ grallocHelper->getHostHandle(
+ AHardwareBuffer_getNativeHandle(info->buffer));
if (!colorBufferHandle) {
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
diff --git a/system/vulkan_enc/AndroidHardwareBuffer.h b/system/vulkan_enc/AndroidHardwareBuffer.h
index 81e8cd9..6cd72bc 100644
--- a/system/vulkan_enc/AndroidHardwareBuffer.h
+++ b/system/vulkan_enc/AndroidHardwareBuffer.h
@@ -22,6 +22,8 @@
// Structure similar to
// https://github.com/mesa3d/mesa/blob/master/src/intel/vulkan/anv_android.c
+class Gralloc;
+
namespace goldfish_vk {
uint64_t
@@ -30,6 +32,7 @@
const VkImageUsageFlags vk_usage);
VkResult getAndroidHardwareBufferPropertiesANDROID(
+ Gralloc* grallocHelper,
const HostVisibleMemoryVirtualizationInfo* hostMemVirtInfo,
VkDevice device,
const AHardwareBuffer* buffer,
@@ -39,6 +42,7 @@
struct AHardwareBuffer **pBuffer);
VkResult importAndroidHardwareBuffer(
+ Gralloc* grallocHelper,
const VkImportAndroidHardwareBufferInfoANDROID* info,
struct AHardwareBuffer **importOut);
diff --git a/system/vulkan_enc/CMakeLists.txt b/system/vulkan_enc/CMakeLists.txt
index 051a85a..39cd64a 100644
--- a/system/vulkan_enc/CMakeLists.txt
+++ b/system/vulkan_enc/CMakeLists.txt
@@ -3,7 +3,7 @@
# which will re-generate this file.
android_validate_sha256("${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc/Android.mk" "c6bf087d25d8e5fa86d79a5ace0bde2b5b79a583e6cc12f0f2ab6a2131e29ab8")
set(vulkan_enc_src AndroidHardwareBuffer.cpp HostVisibleMemoryVirtualization.cpp Resources.cpp Validation.cpp VulkanStreamGuest.cpp VulkanHandleMapping.cpp ResourceTracker.cpp VkEncoder.cpp goldfish_vk_extension_structs_guest.cpp goldfish_vk_marshaling_guest.cpp goldfish_vk_deepcopy_guest.cpp goldfish_vk_handlemap_guest.cpp goldfish_vk_transform_guest.cpp)
-android_add_shared_library(vulkan_enc)
+android_add_library(TARGET vulkan_enc SHARED LICENSE Apache-2.0 SRC AndroidHardwareBuffer.cpp HostVisibleMemoryVirtualization.cpp Resources.cpp Validation.cpp VulkanStreamGuest.cpp VulkanHandleMapping.cpp ResourceTracker.cpp VkEncoder.cpp goldfish_vk_extension_structs_guest.cpp goldfish_vk_marshaling_guest.cpp goldfish_vk_deepcopy_guest.cpp goldfish_vk_handlemap_guest.cpp goldfish_vk_transform_guest.cpp)
target_include_directories(vulkan_enc PRIVATE ${GOLDFISH_DEVICE_ROOT}/system/renderControl_enc ${GOLDFISH_DEVICE_ROOT}/android-emu ${GOLDFISH_DEVICE_ROOT}/shared/OpenglCodecCommon ${GOLDFISH_DEVICE_ROOT}/system/vulkan_enc ${GOLDFISH_DEVICE_ROOT}/./host/include/libOpenglRender ${GOLDFISH_DEVICE_ROOT}/./system/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/guest ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/host/include ${GOLDFISH_DEVICE_ROOT}/./../../../external/qemu/android/android-emugl/host/include/vulkan)
target_compile_definitions(vulkan_enc PRIVATE "-DWITH_GLES2" "-DPLATFORM_SDK_VERSION=29" "-DGOLDFISH_HIDL_GRALLOC" "-DEMULATOR_OPENGL_POST_O=1" "-DHOST_BUILD" "-DANDROID" "-DGL_GLEXT_PROTOTYPES" "-DPAGE_SIZE=4096" "-DGOLDFISH_VULKAN" "-DLOG_TAG=\"goldfish_vulkan\"" "-DVK_ANDROID_native_buffer" "-DVK_GOOGLE_address_space" "-DVK_USE_PLATFORM_ANDROID_KHR" "-DVK_NO_PROTOTYPES" "-D__ANDROID_API__=28")
target_compile_options(vulkan_enc PRIVATE "-fvisibility=default" "-Wno-unused-parameter" "-Wno-missing-field-initializers" "-Werror" "-fstrict-aliasing")
diff --git a/system/vulkan_enc/HostVisibleMemoryVirtualization.cpp b/system/vulkan_enc/HostVisibleMemoryVirtualization.cpp
index 2780d2a..b6bd91a 100644
--- a/system/vulkan_enc/HostVisibleMemoryVirtualization.cpp
+++ b/system/vulkan_enc/HostVisibleMemoryVirtualization.cpp
@@ -14,7 +14,7 @@
// limitations under the License.
#include "HostVisibleMemoryVirtualization.h"
-#include "android/base/SubAllocator.h"
+#include "android/base/AndroidSubAllocator.h"
#include "Resources.h"
#include "VkEncoder.h"
@@ -23,7 +23,7 @@
#include <set>
-using android::base::SubAllocator;
+using android::base::guest::SubAllocator;
namespace goldfish_vk {
@@ -296,7 +296,7 @@
memset(toFree, 0x0, sizeof(SubAlloc));
}
-bool canSubAlloc(android::base::SubAllocator* subAlloc, VkDeviceSize size) {
+bool canSubAlloc(android::base::guest::SubAllocator* subAlloc, VkDeviceSize size) {
auto ptr = subAlloc->alloc(size);
if (!ptr) return false;
subAlloc->free(ptr);
diff --git a/system/vulkan_enc/HostVisibleMemoryVirtualization.h b/system/vulkan_enc/HostVisibleMemoryVirtualization.h
index ad25353..84e39bb 100644
--- a/system/vulkan_enc/HostVisibleMemoryVirtualization.h
+++ b/system/vulkan_enc/HostVisibleMemoryVirtualization.h
@@ -20,9 +20,11 @@
namespace android {
namespace base {
+namespace guest {
class SubAllocator;
+} // namespace guest
} // namespace base
} // namespace android
@@ -81,7 +83,7 @@
VkDeviceSize allocSize = 0;
VkDeviceSize mappedSize = 0;
uint8_t* mappedPtr = nullptr;
- android::base::SubAllocator* subAlloc = nullptr;
+ android::base::guest::SubAllocator* subAlloc = nullptr;
};
VkResult finishHostMemAllocInit(
@@ -106,7 +108,7 @@
VkDeviceMemory baseMemory = VK_NULL_HANDLE;
VkDeviceSize baseOffset = 0;
- android::base::SubAllocator* subAlloc = nullptr;
+ android::base::guest::SubAllocator* subAlloc = nullptr;
VkDeviceMemory subMemory = VK_NULL_HANDLE;
};
@@ -117,5 +119,5 @@
void subFreeHostMemory(SubAlloc* toFree);
-bool canSubAlloc(android::base::SubAllocator* subAlloc, VkDeviceSize size);
+bool canSubAlloc(android::base::guest::SubAllocator* subAlloc, VkDeviceSize size);
} // namespace goldfish_vk
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 363d3b9..84e41fc 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -38,18 +38,16 @@
#ifdef VK_USE_PLATFORM_FUCHSIA
#include <cutils/native_handle.h>
-#include <fuchsia/hardware/goldfish/control/cpp/fidl.h>
+#include <fuchsia/hardware/goldfish/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
-#include <lib/fdio/directory.h>
-#include <lib/fdio/fd.h>
-#include <lib/fdio/fdio.h>
-#include <lib/fdio/io.h>
#include <lib/zx/channel.h>
#include <lib/zx/vmo.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/object.h>
+#include "services/service_connector.h"
+
struct AHardwareBuffer;
void AHardwareBuffer_release(AHardwareBuffer*) { }
@@ -63,6 +61,7 @@
}
VkResult importAndroidHardwareBuffer(
+ Gralloc *grallocHelper,
const VkImportAndroidHardwareBufferInfoANDROID* info,
struct AHardwareBuffer **importOut) {
return VK_SUCCESS;
@@ -87,6 +86,7 @@
}
VkResult getAndroidHardwareBufferPropertiesANDROID(
+ Gralloc *grallocHelper,
const goldfish_vk::HostVisibleMemoryVirtualizationInfo*,
VkDevice,
const AHardwareBuffer*,
@@ -103,7 +103,6 @@
#include "android/base/AlignedBuf.h"
#include "android/base/synchronization/AndroidLock.h"
-#include "gralloc_cb.h"
#include "goldfish_address_space.h"
#include "goldfish_vk_private_defs.h"
#include "vk_format_info.h"
@@ -271,6 +270,9 @@
VkDeviceSize currentBackingSize = 0;
bool baseRequirementsKnown = false;
VkMemoryRequirements baseRequirements;
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ bool isSysmemBackedMemory = false;
+#endif
};
struct VkBuffer_Info {
@@ -594,37 +596,32 @@
if (mFeatureInfo->hasDirectMem) {
mGoldfishAddressSpaceBlockProvider.reset(
new GoldfishAddressSpaceBlockProvider(
- GoldfishAddressSpaceBlockProvider::SUBDEVICE_TYPE_NO_SUBDEVICE_ID));
+ GoldfishAddressSpaceSubdeviceType::NoSubdevice));
}
#ifdef VK_USE_PLATFORM_FUCHSIA
if (mFeatureInfo->hasVulkan) {
- int fd = open("/dev/class/goldfish-control/000", O_RDWR);
- if (fd < 0) {
+ zx::channel channel(GetConnectToServiceFunction()("/dev/class/goldfish-control/000"));
+ if (!channel) {
ALOGE("failed to open control device");
abort();
}
- zx::channel channel;
- zx_status_t status = fdio_get_service_handle(fd, channel.reset_and_get_address());
- if (status != ZX_OK) {
- ALOGE("failed to get control service handle, status %d", status);
- abort();
- }
mControlDevice.Bind(std::move(channel));
- status = fdio_service_connect(
- "/svc/fuchsia.sysmem.Allocator",
- mSysmemAllocator.NewRequest().TakeChannel().release());
- if (status != ZX_OK) {
- ALOGE("failed to get sysmem connection, status %d", status);
- abort();
+ zx::channel sysmem_channel(GetConnectToServiceFunction()("/svc/fuchsia.sysmem.Allocator"));
+ if (!sysmem_channel) {
+ ALOGE("failed to open sysmem connection");
}
+ mSysmemAllocator.Bind(std::move(sysmem_channel));
}
#endif
if (mFeatureInfo->hasVulkanNullOptionalStrings) {
mStreamFeatureBits |= VULKAN_STREAM_FEATURE_NULL_OPTIONAL_STRINGS_BIT;
}
+ if (mFeatureInfo->hasVulkanIgnoredHandles) {
+ mStreamFeatureBits |= VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT;
+ }
}
void setThreadingCallbacks(const ResourceTracker::ThreadingCallbacks& callbacks) {
@@ -890,10 +887,15 @@
std::vector<const char*> allowedExtensionNames = {
"VK_KHR_maintenance1",
+ "VK_KHR_maintenance2",
+ "VK_KHR_maintenance3",
"VK_KHR_get_memory_requirements2",
"VK_KHR_dedicated_allocation",
"VK_KHR_bind_memory2",
"VK_KHR_sampler_ycbcr_conversion",
+ "VK_KHR_shader_float16_int8",
+ "VK_AMD_gpu_shader_half_float",
+ "VK_NV_shader_subgroup_partitioned",
#ifdef VK_USE_PLATFORM_ANDROID_KHR
"VK_KHR_external_semaphore",
"VK_KHR_external_semaphore_fd",
@@ -902,8 +904,6 @@
"VK_KHR_external_fence",
"VK_KHR_external_fence_fd",
#endif
- // "VK_KHR_maintenance2",
- // "VK_KHR_maintenance3",
// TODO:
// VK_KHR_external_memory_capabilities
};
@@ -1244,7 +1244,10 @@
VkDevice device,
const AHardwareBuffer* buffer,
VkAndroidHardwareBufferPropertiesANDROID* pProperties) {
+ auto grallocHelper =
+ mThreadingCallbacks.hostConnectionGetFunc()->grallocHelper();
return getAndroidHardwareBufferPropertiesANDROID(
+ grallocHelper,
&mHostVisibleMemoryVirtInfo,
device, buffer, pProperties);
}
@@ -1829,15 +1832,15 @@
ahw = importAhbInfoPtr->buffer;
// We still need to acquire the AHardwareBuffer.
importAndroidHardwareBuffer(
+ mThreadingCallbacks.hostConnectionGetFunc()->grallocHelper(),
importAhbInfoPtr, nullptr);
}
if (ahw) {
- ALOGD("%s: Import AHardwareBulffer", __func__);
- const native_handle_t *handle =
- AHardwareBuffer_getNativeHandle(ahw);
- const cb_handle_t* cb_handle = cb_handle_t::from(handle);
- importCbInfo.colorBuffer = cb_handle->hostHandle;
+ ALOGD("%s: Import AHardwareBuffer", __func__);
+ importCbInfo.colorBuffer =
+ mThreadingCallbacks.hostConnectionGetFunc()->grallocHelper()->
+ getHostHandle(AHardwareBuffer_getNativeHandle(ahw));
vk_append_struct(&structChainIter, &importCbInfo);
}
@@ -1938,7 +1941,7 @@
std::move(vmo_copy),
imageCreateInfo.extent.width,
imageCreateInfo.extent.height,
- fuchsia::hardware::goldfish::control::FormatType::BGRA,
+ fuchsia::hardware::goldfish::ColorBufferFormatType::BGRA,
&status2);
if (status != ZX_OK || status2 != ZX_OK) {
ALOGE("CreateColorBuffer failed: %d:%d", status, status2);
@@ -2210,6 +2213,8 @@
}
transformExternalResourceMemoryRequirementsForGuest(reqs);
+
+ setMemoryRequirementsForSysmemBackedImage(image, reqs);
}
void transformBufferMemoryRequirementsForGuestLocked(
@@ -2250,6 +2255,8 @@
transformExternalResourceMemoryRequirementsForGuest(&reqs2->memoryRequirements);
+ setMemoryRequirementsForSysmemBackedImage(image, &reqs2->memoryRequirements);
+
VkMemoryDedicatedRequirements* dedicatedReqs =
vk_find_struct<VkMemoryDedicatedRequirements>(reqs2);
@@ -2336,6 +2343,7 @@
#ifdef VK_USE_PLATFORM_FUCHSIA
const VkBufferCollectionImageCreateInfoFUCHSIA* extBufferCollectionPtr =
vk_find_struct<VkBufferCollectionImageCreateInfoFUCHSIA>(pCreateInfo);
+ bool isSysmemBackedMemory = false;
if (extBufferCollectionPtr) {
auto collection = reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(
extBufferCollectionPtr->collection);
@@ -2359,12 +2367,13 @@
std::move(vmo),
localCreateInfo.extent.width,
localCreateInfo.extent.height,
- fuchsia::hardware::goldfish::control::FormatType::BGRA,
+ fuchsia::hardware::goldfish::ColorBufferFormatType::BGRA,
&status2);
if (status != ZX_OK || (status2 != ZX_OK && status2 != ZX_ERR_ALREADY_EXISTS)) {
ALOGE("CreateColorBuffer failed: %d:%d", status, status2);
}
}
+ isSysmemBackedMemory = true;
}
#endif
@@ -2399,11 +2408,16 @@
info.externalCreateInfo = *extImgCiPtr;
}
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ if (isSysmemBackedMemory) {
+ info.isSysmemBackedMemory = true;
+ }
+#endif
+
if (info.baseRequirementsKnown) {
transformImageMemoryRequirementsForGuestLocked(*pImage, &memReqs);
info.baseRequirements = memReqs;
}
-
return res;
}
@@ -2503,7 +2517,7 @@
const VkAllocationCallbacks* pAllocator) {
VkEncoder* enc = (VkEncoder*)context;
if (ycbcrConversion != VK_YCBCR_CONVERSION_DO_NOTHING) {
- enc->vkDestroySamplerYcbcrConversion(device, ycbcrConversion, pAllocator);
+ enc->vkDestroySamplerYcbcrConversionKHR(device, ycbcrConversion, pAllocator);
}
}
@@ -2898,6 +2912,24 @@
enc->vkDestroyImage(device, image, pAllocator);
}
+ void setMemoryRequirementsForSysmemBackedImage(
+ VkImage image, VkMemoryRequirements *pMemoryRequirements) {
+#ifdef VK_USE_PLATFORM_FUCHSIA
+ auto it = info_VkImage.find(image);
+ if (it == info_VkImage.end()) return;
+ auto& info = it->second;
+ if (info.isSysmemBackedMemory) {
+ auto width = info.createInfo.extent.width;
+ auto height = info.createInfo.extent.height;
+ pMemoryRequirements->size = width * height * 4;
+ }
+#else
+ // Bypass "unused parameter" checks.
+ (void)image;
+ (void)pMemoryRequirements;
+#endif
+ }
+
void on_vkGetImageMemoryRequirements(
void *context, VkDevice device, VkImage image,
VkMemoryRequirements *pMemoryRequirements) {
@@ -2925,6 +2957,7 @@
transformImageMemoryRequirementsForGuestLocked(
image, pMemoryRequirements);
+
info.baseRequirementsKnown = true;
info.baseRequirements = *pMemoryRequirements;
}
@@ -3463,8 +3496,7 @@
return;
}
- const cb_handle_t* cb_handle = cb_handle_t::from(nativeInfo->handle);
- if (!cb_handle) return;
+ if (!nativeInfo->handle) return;
VkNativeBufferANDROID* nativeInfoOut =
reinterpret_cast<VkNativeBufferANDROID*>(
@@ -3476,10 +3508,14 @@
abort();
}
- *(uint32_t*)(nativeInfoOut->handle) = cb_handle->hostHandle;
+ *(uint32_t*)(nativeInfoOut->handle) =
+ mThreadingCallbacks.hostConnectionGetFunc()->
+ grallocHelper()->getHostHandle(
+ (const native_handle_t*)nativeInfo->handle);
}
void unwrap_vkAcquireImageANDROID_nativeFenceFd(int fd, int*) {
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
if (fd != -1) {
// Implicit Synchronization
sync_wait(fd, 3000);
@@ -3496,6 +3532,7 @@
// Therefore, assume contract where we need to close fd in this driver
close(fd);
}
+#endif
}
// Action of vkMapMemoryIntoAddressSpaceGOOGLE:
@@ -3989,7 +4026,7 @@
int mSyncDeviceFd = -1;
#ifdef VK_USE_PLATFORM_FUCHSIA
- fuchsia::hardware::goldfish::control::DeviceSyncPtr mControlDevice;
+ fuchsia::hardware::goldfish::ControlDeviceSyncPtr mControlDevice;
fuchsia::sysmem::AllocatorSyncPtr mSysmemAllocator;
#endif
diff --git a/system/vulkan_enc/goldfish_vk_marshaling_guest.cpp b/system/vulkan_enc/goldfish_vk_marshaling_guest.cpp
index 0ed32d3..1ef4d04 100644
--- a/system/vulkan_enc/goldfish_vk_marshaling_guest.cpp
+++ b/system/vulkan_enc/goldfish_vk_marshaling_guest.cpp
@@ -2594,6 +2594,20 @@
VulkanStreamGuest* vkStream,
const VkGraphicsPipelineCreateInfo* forMarshaling)
{
+ uint32_t hasRasterization = 1;
+ if (vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT)
+ {
+ hasRasterization = (((0 == forMarshaling->pRasterizationState)) ? (0) : (!((*(forMarshaling->pRasterizationState)).rasterizerDiscardEnable)));
+ uint32_t cgen_var_70 = (uint32_t)hasRasterization;
+ vkStream->putBe32(cgen_var_70);
+ }
+ uint32_t hasTessellation = 1;
+ if (vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT)
+ {
+ hasTessellation = arrayany(forMarshaling->pStages, 0, forMarshaling->stageCount, [](VkPipelineShaderStageCreateInfo s) { return ((s.stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) || (s.stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)); });
+ uint32_t cgen_var_71 = (uint32_t)hasTessellation;
+ vkStream->putBe32(cgen_var_71);
+ }
vkStream->write((VkStructureType*)&forMarshaling->sType, sizeof(VkStructureType));
size_t pNext_size = goldfish_vk_extension_struct_size(forMarshaling->pNext);
vkStream->putBe32(pNext_size);
@@ -2608,61 +2622,103 @@
{
marshal_VkPipelineShaderStageCreateInfo(vkStream, (const VkPipelineShaderStageCreateInfo*)(forMarshaling->pStages + i));
}
- marshal_VkPipelineVertexInputStateCreateInfo(vkStream, (const VkPipelineVertexInputStateCreateInfo*)(forMarshaling->pVertexInputState));
- marshal_VkPipelineInputAssemblyStateCreateInfo(vkStream, (const VkPipelineInputAssemblyStateCreateInfo*)(forMarshaling->pInputAssemblyState));
// WARNING PTR CHECK
- uint64_t cgen_var_70 = (uint64_t)(uintptr_t)forMarshaling->pTessellationState;
- vkStream->putBe64(cgen_var_70);
+ if (vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT)
+ {
+ uint64_t cgen_var_72 = (uint64_t)(uintptr_t)forMarshaling->pVertexInputState;
+ vkStream->putBe64(cgen_var_72);
+ }
+ if ((!(vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT) || forMarshaling->pVertexInputState))
+ {
+ marshal_VkPipelineVertexInputStateCreateInfo(vkStream, (const VkPipelineVertexInputStateCreateInfo*)(forMarshaling->pVertexInputState));
+ }
+ // WARNING PTR CHECK
+ if (vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT)
+ {
+ uint64_t cgen_var_73 = (uint64_t)(uintptr_t)forMarshaling->pInputAssemblyState;
+ vkStream->putBe64(cgen_var_73);
+ }
+ if ((!(vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT) || forMarshaling->pInputAssemblyState))
+ {
+ marshal_VkPipelineInputAssemblyStateCreateInfo(vkStream, (const VkPipelineInputAssemblyStateCreateInfo*)(forMarshaling->pInputAssemblyState));
+ }
+ // WARNING PTR CHECK
+ uint64_t cgen_var_74 = (uint64_t)(uintptr_t)forMarshaling->pTessellationState;
+ vkStream->putBe64(cgen_var_74);
if (forMarshaling->pTessellationState)
{
- marshal_VkPipelineTessellationStateCreateInfo(vkStream, (const VkPipelineTessellationStateCreateInfo*)(forMarshaling->pTessellationState));
+ if (hasTessellation)
+ {
+ marshal_VkPipelineTessellationStateCreateInfo(vkStream, (const VkPipelineTessellationStateCreateInfo*)(forMarshaling->pTessellationState));
+ }
}
// WARNING PTR CHECK
- uint64_t cgen_var_71 = (uint64_t)(uintptr_t)forMarshaling->pViewportState;
- vkStream->putBe64(cgen_var_71);
+ uint64_t cgen_var_75 = (uint64_t)(uintptr_t)forMarshaling->pViewportState;
+ vkStream->putBe64(cgen_var_75);
if (forMarshaling->pViewportState)
{
- marshal_VkPipelineViewportStateCreateInfo(vkStream, (const VkPipelineViewportStateCreateInfo*)(forMarshaling->pViewportState));
+ if (hasRasterization)
+ {
+ marshal_VkPipelineViewportStateCreateInfo(vkStream, (const VkPipelineViewportStateCreateInfo*)(forMarshaling->pViewportState));
+ }
}
- marshal_VkPipelineRasterizationStateCreateInfo(vkStream, (const VkPipelineRasterizationStateCreateInfo*)(forMarshaling->pRasterizationState));
// WARNING PTR CHECK
- uint64_t cgen_var_72 = (uint64_t)(uintptr_t)forMarshaling->pMultisampleState;
- vkStream->putBe64(cgen_var_72);
+ if (vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT)
+ {
+ uint64_t cgen_var_76 = (uint64_t)(uintptr_t)forMarshaling->pRasterizationState;
+ vkStream->putBe64(cgen_var_76);
+ }
+ if ((!(vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT) || forMarshaling->pRasterizationState))
+ {
+ marshal_VkPipelineRasterizationStateCreateInfo(vkStream, (const VkPipelineRasterizationStateCreateInfo*)(forMarshaling->pRasterizationState));
+ }
+ // WARNING PTR CHECK
+ uint64_t cgen_var_77 = (uint64_t)(uintptr_t)forMarshaling->pMultisampleState;
+ vkStream->putBe64(cgen_var_77);
if (forMarshaling->pMultisampleState)
{
- marshal_VkPipelineMultisampleStateCreateInfo(vkStream, (const VkPipelineMultisampleStateCreateInfo*)(forMarshaling->pMultisampleState));
+ if (hasRasterization)
+ {
+ marshal_VkPipelineMultisampleStateCreateInfo(vkStream, (const VkPipelineMultisampleStateCreateInfo*)(forMarshaling->pMultisampleState));
+ }
}
// WARNING PTR CHECK
- uint64_t cgen_var_73 = (uint64_t)(uintptr_t)forMarshaling->pDepthStencilState;
- vkStream->putBe64(cgen_var_73);
+ uint64_t cgen_var_78 = (uint64_t)(uintptr_t)forMarshaling->pDepthStencilState;
+ vkStream->putBe64(cgen_var_78);
if (forMarshaling->pDepthStencilState)
{
- marshal_VkPipelineDepthStencilStateCreateInfo(vkStream, (const VkPipelineDepthStencilStateCreateInfo*)(forMarshaling->pDepthStencilState));
+ if (hasRasterization)
+ {
+ marshal_VkPipelineDepthStencilStateCreateInfo(vkStream, (const VkPipelineDepthStencilStateCreateInfo*)(forMarshaling->pDepthStencilState));
+ }
}
// WARNING PTR CHECK
- uint64_t cgen_var_74 = (uint64_t)(uintptr_t)forMarshaling->pColorBlendState;
- vkStream->putBe64(cgen_var_74);
+ uint64_t cgen_var_79 = (uint64_t)(uintptr_t)forMarshaling->pColorBlendState;
+ vkStream->putBe64(cgen_var_79);
if (forMarshaling->pColorBlendState)
{
- marshal_VkPipelineColorBlendStateCreateInfo(vkStream, (const VkPipelineColorBlendStateCreateInfo*)(forMarshaling->pColorBlendState));
+ if (hasRasterization)
+ {
+ marshal_VkPipelineColorBlendStateCreateInfo(vkStream, (const VkPipelineColorBlendStateCreateInfo*)(forMarshaling->pColorBlendState));
+ }
}
// WARNING PTR CHECK
- uint64_t cgen_var_75 = (uint64_t)(uintptr_t)forMarshaling->pDynamicState;
- vkStream->putBe64(cgen_var_75);
+ uint64_t cgen_var_80 = (uint64_t)(uintptr_t)forMarshaling->pDynamicState;
+ vkStream->putBe64(cgen_var_80);
if (forMarshaling->pDynamicState)
{
marshal_VkPipelineDynamicStateCreateInfo(vkStream, (const VkPipelineDynamicStateCreateInfo*)(forMarshaling->pDynamicState));
}
- uint64_t cgen_var_76;
- vkStream->handleMapping()->mapHandles_VkPipelineLayout_u64(&forMarshaling->layout, &cgen_var_76, 1);
- vkStream->write((uint64_t*)&cgen_var_76, 1 * 8);
- uint64_t cgen_var_77;
- vkStream->handleMapping()->mapHandles_VkRenderPass_u64(&forMarshaling->renderPass, &cgen_var_77, 1);
- vkStream->write((uint64_t*)&cgen_var_77, 1 * 8);
+ uint64_t cgen_var_81;
+ vkStream->handleMapping()->mapHandles_VkPipelineLayout_u64(&forMarshaling->layout, &cgen_var_81, 1);
+ vkStream->write((uint64_t*)&cgen_var_81, 1 * 8);
+ uint64_t cgen_var_82;
+ vkStream->handleMapping()->mapHandles_VkRenderPass_u64(&forMarshaling->renderPass, &cgen_var_82, 1);
+ vkStream->write((uint64_t*)&cgen_var_82, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->subpass, sizeof(uint32_t));
- uint64_t cgen_var_78;
- vkStream->handleMapping()->mapHandles_VkPipeline_u64(&forMarshaling->basePipelineHandle, &cgen_var_78, 1);
- vkStream->write((uint64_t*)&cgen_var_78, 1 * 8);
+ uint64_t cgen_var_83;
+ vkStream->handleMapping()->mapHandles_VkPipeline_u64(&forMarshaling->basePipelineHandle, &cgen_var_83, 1);
+ vkStream->write((uint64_t*)&cgen_var_83, 1 * 8);
vkStream->write((int32_t*)&forMarshaling->basePipelineIndex, sizeof(int32_t));
}
@@ -2670,6 +2726,16 @@
VulkanStreamGuest* vkStream,
VkGraphicsPipelineCreateInfo* forUnmarshaling)
{
+ uint32_t hasRasterization = 1;
+ if (vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT)
+ {
+ hasRasterization = (const uint32_t)vkStream->getBe32();
+ }
+ uint32_t hasTessellation = 1;
+ if (vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT)
+ {
+ hasTessellation = (const uint32_t)vkStream->getBe32();
+ }
vkStream->read((VkStructureType*)&forUnmarshaling->sType, sizeof(VkStructureType));
size_t pNext_size;
pNext_size = vkStream->getBe32();
@@ -2685,8 +2751,26 @@
{
unmarshal_VkPipelineShaderStageCreateInfo(vkStream, (VkPipelineShaderStageCreateInfo*)(forUnmarshaling->pStages + i));
}
- unmarshal_VkPipelineVertexInputStateCreateInfo(vkStream, (VkPipelineVertexInputStateCreateInfo*)(forUnmarshaling->pVertexInputState));
- unmarshal_VkPipelineInputAssemblyStateCreateInfo(vkStream, (VkPipelineInputAssemblyStateCreateInfo*)(forUnmarshaling->pInputAssemblyState));
+ // WARNING PTR CHECK
+ const VkPipelineVertexInputStateCreateInfo* check_pVertexInputState;
+ if (vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT)
+ {
+ check_pVertexInputState = (const VkPipelineVertexInputStateCreateInfo*)(uintptr_t)vkStream->getBe64();
+ }
+ if ((!(vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT) || forUnmarshaling->pVertexInputState))
+ {
+ unmarshal_VkPipelineVertexInputStateCreateInfo(vkStream, (VkPipelineVertexInputStateCreateInfo*)(forUnmarshaling->pVertexInputState));
+ }
+ // WARNING PTR CHECK
+ const VkPipelineInputAssemblyStateCreateInfo* check_pInputAssemblyState;
+ if (vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT)
+ {
+ check_pInputAssemblyState = (const VkPipelineInputAssemblyStateCreateInfo*)(uintptr_t)vkStream->getBe64();
+ }
+ if ((!(vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT) || forUnmarshaling->pInputAssemblyState))
+ {
+ unmarshal_VkPipelineInputAssemblyStateCreateInfo(vkStream, (VkPipelineInputAssemblyStateCreateInfo*)(forUnmarshaling->pInputAssemblyState));
+ }
// WARNING PTR CHECK
const VkPipelineTessellationStateCreateInfo* check_pTessellationState;
check_pTessellationState = (const VkPipelineTessellationStateCreateInfo*)(uintptr_t)vkStream->getBe64();
@@ -2696,7 +2780,14 @@
{
fprintf(stderr, "fatal: forUnmarshaling->pTessellationState inconsistent between guest and host\n");
}
- unmarshal_VkPipelineTessellationStateCreateInfo(vkStream, (VkPipelineTessellationStateCreateInfo*)(forUnmarshaling->pTessellationState));
+ if (hasTessellation)
+ {
+ unmarshal_VkPipelineTessellationStateCreateInfo(vkStream, (VkPipelineTessellationStateCreateInfo*)(forUnmarshaling->pTessellationState));
+ }
+ else
+ {
+ forUnmarshaling->pTessellationState = 0;
+ }
}
// WARNING PTR CHECK
const VkPipelineViewportStateCreateInfo* check_pViewportState;
@@ -2707,9 +2798,25 @@
{
fprintf(stderr, "fatal: forUnmarshaling->pViewportState inconsistent between guest and host\n");
}
- unmarshal_VkPipelineViewportStateCreateInfo(vkStream, (VkPipelineViewportStateCreateInfo*)(forUnmarshaling->pViewportState));
+ if (hasRasterization)
+ {
+ unmarshal_VkPipelineViewportStateCreateInfo(vkStream, (VkPipelineViewportStateCreateInfo*)(forUnmarshaling->pViewportState));
+ }
+ else
+ {
+ forUnmarshaling->pViewportState = 0;
+ }
}
- unmarshal_VkPipelineRasterizationStateCreateInfo(vkStream, (VkPipelineRasterizationStateCreateInfo*)(forUnmarshaling->pRasterizationState));
+ // WARNING PTR CHECK
+ const VkPipelineRasterizationStateCreateInfo* check_pRasterizationState;
+ if (vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT)
+ {
+ check_pRasterizationState = (const VkPipelineRasterizationStateCreateInfo*)(uintptr_t)vkStream->getBe64();
+ }
+ if ((!(vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT) || forUnmarshaling->pRasterizationState))
+ {
+ unmarshal_VkPipelineRasterizationStateCreateInfo(vkStream, (VkPipelineRasterizationStateCreateInfo*)(forUnmarshaling->pRasterizationState));
+ }
// WARNING PTR CHECK
const VkPipelineMultisampleStateCreateInfo* check_pMultisampleState;
check_pMultisampleState = (const VkPipelineMultisampleStateCreateInfo*)(uintptr_t)vkStream->getBe64();
@@ -2719,7 +2826,14 @@
{
fprintf(stderr, "fatal: forUnmarshaling->pMultisampleState inconsistent between guest and host\n");
}
- unmarshal_VkPipelineMultisampleStateCreateInfo(vkStream, (VkPipelineMultisampleStateCreateInfo*)(forUnmarshaling->pMultisampleState));
+ if (hasRasterization)
+ {
+ unmarshal_VkPipelineMultisampleStateCreateInfo(vkStream, (VkPipelineMultisampleStateCreateInfo*)(forUnmarshaling->pMultisampleState));
+ }
+ else
+ {
+ forUnmarshaling->pMultisampleState = 0;
+ }
}
// WARNING PTR CHECK
const VkPipelineDepthStencilStateCreateInfo* check_pDepthStencilState;
@@ -2730,7 +2844,14 @@
{
fprintf(stderr, "fatal: forUnmarshaling->pDepthStencilState inconsistent between guest and host\n");
}
- unmarshal_VkPipelineDepthStencilStateCreateInfo(vkStream, (VkPipelineDepthStencilStateCreateInfo*)(forUnmarshaling->pDepthStencilState));
+ if (hasRasterization)
+ {
+ unmarshal_VkPipelineDepthStencilStateCreateInfo(vkStream, (VkPipelineDepthStencilStateCreateInfo*)(forUnmarshaling->pDepthStencilState));
+ }
+ else
+ {
+ forUnmarshaling->pDepthStencilState = 0;
+ }
}
// WARNING PTR CHECK
const VkPipelineColorBlendStateCreateInfo* check_pColorBlendState;
@@ -2741,7 +2862,14 @@
{
fprintf(stderr, "fatal: forUnmarshaling->pColorBlendState inconsistent between guest and host\n");
}
- unmarshal_VkPipelineColorBlendStateCreateInfo(vkStream, (VkPipelineColorBlendStateCreateInfo*)(forUnmarshaling->pColorBlendState));
+ if (hasRasterization)
+ {
+ unmarshal_VkPipelineColorBlendStateCreateInfo(vkStream, (VkPipelineColorBlendStateCreateInfo*)(forUnmarshaling->pColorBlendState));
+ }
+ else
+ {
+ forUnmarshaling->pColorBlendState = 0;
+ }
}
// WARNING PTR CHECK
const VkPipelineDynamicStateCreateInfo* check_pDynamicState;
@@ -2754,16 +2882,16 @@
}
unmarshal_VkPipelineDynamicStateCreateInfo(vkStream, (VkPipelineDynamicStateCreateInfo*)(forUnmarshaling->pDynamicState));
}
- uint64_t cgen_var_85;
- vkStream->read((uint64_t*)&cgen_var_85, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkPipelineLayout(&cgen_var_85, (VkPipelineLayout*)&forUnmarshaling->layout, 1);
- uint64_t cgen_var_86;
- vkStream->read((uint64_t*)&cgen_var_86, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkRenderPass(&cgen_var_86, (VkRenderPass*)&forUnmarshaling->renderPass, 1);
+ uint64_t cgen_var_95;
+ vkStream->read((uint64_t*)&cgen_var_95, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkPipelineLayout(&cgen_var_95, (VkPipelineLayout*)&forUnmarshaling->layout, 1);
+ uint64_t cgen_var_96;
+ vkStream->read((uint64_t*)&cgen_var_96, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkRenderPass(&cgen_var_96, (VkRenderPass*)&forUnmarshaling->renderPass, 1);
vkStream->read((uint32_t*)&forUnmarshaling->subpass, sizeof(uint32_t));
- uint64_t cgen_var_87;
- vkStream->read((uint64_t*)&cgen_var_87, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkPipeline(&cgen_var_87, (VkPipeline*)&forUnmarshaling->basePipelineHandle, 1);
+ uint64_t cgen_var_97;
+ vkStream->read((uint64_t*)&cgen_var_97, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkPipeline(&cgen_var_97, (VkPipeline*)&forUnmarshaling->basePipelineHandle, 1);
vkStream->read((int32_t*)&forUnmarshaling->basePipelineIndex, sizeof(int32_t));
}
@@ -2781,12 +2909,12 @@
}
vkStream->write((VkPipelineCreateFlags*)&forMarshaling->flags, sizeof(VkPipelineCreateFlags));
marshal_VkPipelineShaderStageCreateInfo(vkStream, (VkPipelineShaderStageCreateInfo*)(&forMarshaling->stage));
- uint64_t cgen_var_88;
- vkStream->handleMapping()->mapHandles_VkPipelineLayout_u64(&forMarshaling->layout, &cgen_var_88, 1);
- vkStream->write((uint64_t*)&cgen_var_88, 1 * 8);
- uint64_t cgen_var_89;
- vkStream->handleMapping()->mapHandles_VkPipeline_u64(&forMarshaling->basePipelineHandle, &cgen_var_89, 1);
- vkStream->write((uint64_t*)&cgen_var_89, 1 * 8);
+ uint64_t cgen_var_98;
+ vkStream->handleMapping()->mapHandles_VkPipelineLayout_u64(&forMarshaling->layout, &cgen_var_98, 1);
+ vkStream->write((uint64_t*)&cgen_var_98, 1 * 8);
+ uint64_t cgen_var_99;
+ vkStream->handleMapping()->mapHandles_VkPipeline_u64(&forMarshaling->basePipelineHandle, &cgen_var_99, 1);
+ vkStream->write((uint64_t*)&cgen_var_99, 1 * 8);
vkStream->write((int32_t*)&forMarshaling->basePipelineIndex, sizeof(int32_t));
}
@@ -2805,12 +2933,12 @@
}
vkStream->read((VkPipelineCreateFlags*)&forUnmarshaling->flags, sizeof(VkPipelineCreateFlags));
unmarshal_VkPipelineShaderStageCreateInfo(vkStream, (VkPipelineShaderStageCreateInfo*)(&forUnmarshaling->stage));
- uint64_t cgen_var_90;
- vkStream->read((uint64_t*)&cgen_var_90, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkPipelineLayout(&cgen_var_90, (VkPipelineLayout*)&forUnmarshaling->layout, 1);
- uint64_t cgen_var_91;
- vkStream->read((uint64_t*)&cgen_var_91, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkPipeline(&cgen_var_91, (VkPipeline*)&forUnmarshaling->basePipelineHandle, 1);
+ uint64_t cgen_var_100;
+ vkStream->read((uint64_t*)&cgen_var_100, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkPipelineLayout(&cgen_var_100, (VkPipelineLayout*)&forUnmarshaling->layout, 1);
+ uint64_t cgen_var_101;
+ vkStream->read((uint64_t*)&cgen_var_101, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkPipeline(&cgen_var_101, (VkPipeline*)&forUnmarshaling->basePipelineHandle, 1);
vkStream->read((int32_t*)&forUnmarshaling->basePipelineIndex, sizeof(int32_t));
}
@@ -2848,10 +2976,10 @@
vkStream->write((uint32_t*)&forMarshaling->setLayoutCount, sizeof(uint32_t));
if (forMarshaling->setLayoutCount)
{
- uint64_t* cgen_var_92;
- vkStream->alloc((void**)&cgen_var_92, forMarshaling->setLayoutCount * 8);
- vkStream->handleMapping()->mapHandles_VkDescriptorSetLayout_u64(forMarshaling->pSetLayouts, cgen_var_92, forMarshaling->setLayoutCount);
- vkStream->write((uint64_t*)cgen_var_92, forMarshaling->setLayoutCount * 8);
+ uint64_t* cgen_var_102;
+ vkStream->alloc((void**)&cgen_var_102, forMarshaling->setLayoutCount * 8);
+ vkStream->handleMapping()->mapHandles_VkDescriptorSetLayout_u64(forMarshaling->pSetLayouts, cgen_var_102, forMarshaling->setLayoutCount);
+ vkStream->write((uint64_t*)cgen_var_102, forMarshaling->setLayoutCount * 8);
}
vkStream->write((uint32_t*)&forMarshaling->pushConstantRangeCount, sizeof(uint32_t));
for (uint32_t i = 0; i < (uint32_t)forMarshaling->pushConstantRangeCount; ++i)
@@ -2877,10 +3005,10 @@
vkStream->read((uint32_t*)&forUnmarshaling->setLayoutCount, sizeof(uint32_t));
if (forUnmarshaling->setLayoutCount)
{
- uint64_t* cgen_var_93;
- vkStream->alloc((void**)&cgen_var_93, forUnmarshaling->setLayoutCount * 8);
- vkStream->read((uint64_t*)cgen_var_93, forUnmarshaling->setLayoutCount * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDescriptorSetLayout(cgen_var_93, (VkDescriptorSetLayout*)forUnmarshaling->pSetLayouts, forUnmarshaling->setLayoutCount);
+ uint64_t* cgen_var_103;
+ vkStream->alloc((void**)&cgen_var_103, forUnmarshaling->setLayoutCount * 8);
+ vkStream->read((uint64_t*)cgen_var_103, forUnmarshaling->setLayoutCount * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDescriptorSetLayout(cgen_var_103, (VkDescriptorSetLayout*)forUnmarshaling->pSetLayouts, forUnmarshaling->setLayoutCount);
}
vkStream->read((uint32_t*)&forUnmarshaling->pushConstantRangeCount, sizeof(uint32_t));
for (uint32_t i = 0; i < (uint32_t)forUnmarshaling->pushConstantRangeCount; ++i)
@@ -2959,16 +3087,16 @@
vkStream->write((uint32_t*)&forMarshaling->descriptorCount, sizeof(uint32_t));
vkStream->write((VkShaderStageFlags*)&forMarshaling->stageFlags, sizeof(VkShaderStageFlags));
// WARNING PTR CHECK
- uint64_t cgen_var_94 = (uint64_t)(uintptr_t)forMarshaling->pImmutableSamplers;
- vkStream->putBe64(cgen_var_94);
+ uint64_t cgen_var_104 = (uint64_t)(uintptr_t)forMarshaling->pImmutableSamplers;
+ vkStream->putBe64(cgen_var_104);
if (forMarshaling->pImmutableSamplers)
{
if (forMarshaling->descriptorCount)
{
- uint64_t* cgen_var_95;
- vkStream->alloc((void**)&cgen_var_95, forMarshaling->descriptorCount * 8);
- vkStream->handleMapping()->mapHandles_VkSampler_u64(forMarshaling->pImmutableSamplers, cgen_var_95, forMarshaling->descriptorCount);
- vkStream->write((uint64_t*)cgen_var_95, forMarshaling->descriptorCount * 8);
+ uint64_t* cgen_var_105;
+ vkStream->alloc((void**)&cgen_var_105, forMarshaling->descriptorCount * 8);
+ vkStream->handleMapping()->mapHandles_VkSampler_u64(forMarshaling->pImmutableSamplers, cgen_var_105, forMarshaling->descriptorCount);
+ vkStream->write((uint64_t*)cgen_var_105, forMarshaling->descriptorCount * 8);
}
}
}
@@ -2992,10 +3120,10 @@
}
if (forUnmarshaling->descriptorCount)
{
- uint64_t* cgen_var_97;
- vkStream->alloc((void**)&cgen_var_97, forUnmarshaling->descriptorCount * 8);
- vkStream->read((uint64_t*)cgen_var_97, forUnmarshaling->descriptorCount * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSampler(cgen_var_97, (VkSampler*)forUnmarshaling->pImmutableSamplers, forUnmarshaling->descriptorCount);
+ uint64_t* cgen_var_107;
+ vkStream->alloc((void**)&cgen_var_107, forUnmarshaling->descriptorCount * 8);
+ vkStream->read((uint64_t*)cgen_var_107, forUnmarshaling->descriptorCount * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSampler(cgen_var_107, (VkSampler*)forUnmarshaling->pImmutableSamplers, forUnmarshaling->descriptorCount);
}
}
}
@@ -3112,16 +3240,16 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_98;
- vkStream->handleMapping()->mapHandles_VkDescriptorPool_u64(&forMarshaling->descriptorPool, &cgen_var_98, 1);
- vkStream->write((uint64_t*)&cgen_var_98, 1 * 8);
+ uint64_t cgen_var_108;
+ vkStream->handleMapping()->mapHandles_VkDescriptorPool_u64(&forMarshaling->descriptorPool, &cgen_var_108, 1);
+ vkStream->write((uint64_t*)&cgen_var_108, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->descriptorSetCount, sizeof(uint32_t));
if (forMarshaling->descriptorSetCount)
{
- uint64_t* cgen_var_99;
- vkStream->alloc((void**)&cgen_var_99, forMarshaling->descriptorSetCount * 8);
- vkStream->handleMapping()->mapHandles_VkDescriptorSetLayout_u64(forMarshaling->pSetLayouts, cgen_var_99, forMarshaling->descriptorSetCount);
- vkStream->write((uint64_t*)cgen_var_99, forMarshaling->descriptorSetCount * 8);
+ uint64_t* cgen_var_109;
+ vkStream->alloc((void**)&cgen_var_109, forMarshaling->descriptorSetCount * 8);
+ vkStream->handleMapping()->mapHandles_VkDescriptorSetLayout_u64(forMarshaling->pSetLayouts, cgen_var_109, forMarshaling->descriptorSetCount);
+ vkStream->write((uint64_t*)cgen_var_109, forMarshaling->descriptorSetCount * 8);
}
}
@@ -3138,16 +3266,16 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_100;
- vkStream->read((uint64_t*)&cgen_var_100, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDescriptorPool(&cgen_var_100, (VkDescriptorPool*)&forUnmarshaling->descriptorPool, 1);
+ uint64_t cgen_var_110;
+ vkStream->read((uint64_t*)&cgen_var_110, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDescriptorPool(&cgen_var_110, (VkDescriptorPool*)&forUnmarshaling->descriptorPool, 1);
vkStream->read((uint32_t*)&forUnmarshaling->descriptorSetCount, sizeof(uint32_t));
if (forUnmarshaling->descriptorSetCount)
{
- uint64_t* cgen_var_101;
- vkStream->alloc((void**)&cgen_var_101, forUnmarshaling->descriptorSetCount * 8);
- vkStream->read((uint64_t*)cgen_var_101, forUnmarshaling->descriptorSetCount * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDescriptorSetLayout(cgen_var_101, (VkDescriptorSetLayout*)forUnmarshaling->pSetLayouts, forUnmarshaling->descriptorSetCount);
+ uint64_t* cgen_var_111;
+ vkStream->alloc((void**)&cgen_var_111, forUnmarshaling->descriptorSetCount * 8);
+ vkStream->read((uint64_t*)cgen_var_111, forUnmarshaling->descriptorSetCount * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDescriptorSetLayout(cgen_var_111, (VkDescriptorSetLayout*)forUnmarshaling->pSetLayouts, forUnmarshaling->descriptorSetCount);
}
}
@@ -3155,12 +3283,12 @@
VulkanStreamGuest* vkStream,
const VkDescriptorImageInfo* forMarshaling)
{
- uint64_t cgen_var_102;
- vkStream->handleMapping()->mapHandles_VkSampler_u64(&forMarshaling->sampler, &cgen_var_102, 1);
- vkStream->write((uint64_t*)&cgen_var_102, 1 * 8);
- uint64_t cgen_var_103;
- vkStream->handleMapping()->mapHandles_VkImageView_u64(&forMarshaling->imageView, &cgen_var_103, 1);
- vkStream->write((uint64_t*)&cgen_var_103, 1 * 8);
+ uint64_t cgen_var_112;
+ vkStream->handleMapping()->mapHandles_VkSampler_u64(&forMarshaling->sampler, &cgen_var_112, 1);
+ vkStream->write((uint64_t*)&cgen_var_112, 1 * 8);
+ uint64_t cgen_var_113;
+ vkStream->handleMapping()->mapHandles_VkImageView_u64(&forMarshaling->imageView, &cgen_var_113, 1);
+ vkStream->write((uint64_t*)&cgen_var_113, 1 * 8);
vkStream->write((VkImageLayout*)&forMarshaling->imageLayout, sizeof(VkImageLayout));
}
@@ -3168,12 +3296,12 @@
VulkanStreamGuest* vkStream,
VkDescriptorImageInfo* forUnmarshaling)
{
- uint64_t cgen_var_104;
- vkStream->read((uint64_t*)&cgen_var_104, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSampler(&cgen_var_104, (VkSampler*)&forUnmarshaling->sampler, 1);
- uint64_t cgen_var_105;
- vkStream->read((uint64_t*)&cgen_var_105, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkImageView(&cgen_var_105, (VkImageView*)&forUnmarshaling->imageView, 1);
+ uint64_t cgen_var_114;
+ vkStream->read((uint64_t*)&cgen_var_114, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSampler(&cgen_var_114, (VkSampler*)&forUnmarshaling->sampler, 1);
+ uint64_t cgen_var_115;
+ vkStream->read((uint64_t*)&cgen_var_115, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkImageView(&cgen_var_115, (VkImageView*)&forUnmarshaling->imageView, 1);
vkStream->read((VkImageLayout*)&forUnmarshaling->imageLayout, sizeof(VkImageLayout));
}
@@ -3181,9 +3309,9 @@
VulkanStreamGuest* vkStream,
const VkDescriptorBufferInfo* forMarshaling)
{
- uint64_t cgen_var_106;
- vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_106, 1);
- vkStream->write((uint64_t*)&cgen_var_106, 1 * 8);
+ uint64_t cgen_var_116;
+ vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_116, 1);
+ vkStream->write((uint64_t*)&cgen_var_116, 1 * 8);
vkStream->write((VkDeviceSize*)&forMarshaling->offset, sizeof(VkDeviceSize));
vkStream->write((VkDeviceSize*)&forMarshaling->range, sizeof(VkDeviceSize));
}
@@ -3192,9 +3320,9 @@
VulkanStreamGuest* vkStream,
VkDescriptorBufferInfo* forUnmarshaling)
{
- uint64_t cgen_var_107;
- vkStream->read((uint64_t*)&cgen_var_107, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_107, (VkBuffer*)&forUnmarshaling->buffer, 1);
+ uint64_t cgen_var_117;
+ vkStream->read((uint64_t*)&cgen_var_117, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_117, (VkBuffer*)&forUnmarshaling->buffer, 1);
vkStream->read((VkDeviceSize*)&forUnmarshaling->offset, sizeof(VkDeviceSize));
vkStream->read((VkDeviceSize*)&forUnmarshaling->range, sizeof(VkDeviceSize));
}
@@ -3211,44 +3339,53 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_108;
- vkStream->handleMapping()->mapHandles_VkDescriptorSet_u64(&forMarshaling->dstSet, &cgen_var_108, 1);
- vkStream->write((uint64_t*)&cgen_var_108, 1 * 8);
+ uint64_t cgen_var_118;
+ vkStream->handleMapping()->mapHandles_VkDescriptorSet_u64(&forMarshaling->dstSet, &cgen_var_118, 1);
+ vkStream->write((uint64_t*)&cgen_var_118, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->dstBinding, sizeof(uint32_t));
vkStream->write((uint32_t*)&forMarshaling->dstArrayElement, sizeof(uint32_t));
vkStream->write((uint32_t*)&forMarshaling->descriptorCount, sizeof(uint32_t));
vkStream->write((VkDescriptorType*)&forMarshaling->descriptorType, sizeof(VkDescriptorType));
// WARNING PTR CHECK
- uint64_t cgen_var_109 = (uint64_t)(uintptr_t)forMarshaling->pImageInfo;
- vkStream->putBe64(cgen_var_109);
+ uint64_t cgen_var_119 = (uint64_t)(uintptr_t)forMarshaling->pImageInfo;
+ vkStream->putBe64(cgen_var_119);
if (forMarshaling->pImageInfo)
{
- for (uint32_t i = 0; i < (uint32_t)forMarshaling->descriptorCount; ++i)
+ if ((!(vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT) || ((VK_DESCRIPTOR_TYPE_SAMPLER == forMarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == forMarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE == forMarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_STORAGE_IMAGE == forMarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT == forMarshaling->descriptorType))))
{
- marshal_VkDescriptorImageInfo(vkStream, (const VkDescriptorImageInfo*)(forMarshaling->pImageInfo + i));
+ for (uint32_t i = 0; i < (uint32_t)forMarshaling->descriptorCount; ++i)
+ {
+ marshal_VkDescriptorImageInfo(vkStream, (const VkDescriptorImageInfo*)(forMarshaling->pImageInfo + i));
+ }
}
}
// WARNING PTR CHECK
- uint64_t cgen_var_110 = (uint64_t)(uintptr_t)forMarshaling->pBufferInfo;
- vkStream->putBe64(cgen_var_110);
+ uint64_t cgen_var_120 = (uint64_t)(uintptr_t)forMarshaling->pBufferInfo;
+ vkStream->putBe64(cgen_var_120);
if (forMarshaling->pBufferInfo)
{
- for (uint32_t i = 0; i < (uint32_t)forMarshaling->descriptorCount; ++i)
+ if ((!(vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT) || ((VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == forMarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC == forMarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == forMarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC == forMarshaling->descriptorType))))
{
- marshal_VkDescriptorBufferInfo(vkStream, (const VkDescriptorBufferInfo*)(forMarshaling->pBufferInfo + i));
+ for (uint32_t i = 0; i < (uint32_t)forMarshaling->descriptorCount; ++i)
+ {
+ marshal_VkDescriptorBufferInfo(vkStream, (const VkDescriptorBufferInfo*)(forMarshaling->pBufferInfo + i));
+ }
}
}
// WARNING PTR CHECK
- uint64_t cgen_var_111 = (uint64_t)(uintptr_t)forMarshaling->pTexelBufferView;
- vkStream->putBe64(cgen_var_111);
+ uint64_t cgen_var_121 = (uint64_t)(uintptr_t)forMarshaling->pTexelBufferView;
+ vkStream->putBe64(cgen_var_121);
if (forMarshaling->pTexelBufferView)
{
- if (forMarshaling->descriptorCount)
+ if ((!(vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT) || ((VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == forMarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER == forMarshaling->descriptorType))))
{
- uint64_t* cgen_var_112;
- vkStream->alloc((void**)&cgen_var_112, forMarshaling->descriptorCount * 8);
- vkStream->handleMapping()->mapHandles_VkBufferView_u64(forMarshaling->pTexelBufferView, cgen_var_112, forMarshaling->descriptorCount);
- vkStream->write((uint64_t*)cgen_var_112, forMarshaling->descriptorCount * 8);
+ if (forMarshaling->descriptorCount)
+ {
+ uint64_t* cgen_var_122;
+ vkStream->alloc((void**)&cgen_var_122, forMarshaling->descriptorCount * 8);
+ vkStream->handleMapping()->mapHandles_VkBufferView_u64(forMarshaling->pTexelBufferView, cgen_var_122, forMarshaling->descriptorCount);
+ vkStream->write((uint64_t*)cgen_var_122, forMarshaling->descriptorCount * 8);
+ }
}
}
}
@@ -3266,9 +3403,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_113;
- vkStream->read((uint64_t*)&cgen_var_113, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDescriptorSet(&cgen_var_113, (VkDescriptorSet*)&forUnmarshaling->dstSet, 1);
+ uint64_t cgen_var_123;
+ vkStream->read((uint64_t*)&cgen_var_123, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDescriptorSet(&cgen_var_123, (VkDescriptorSet*)&forUnmarshaling->dstSet, 1);
vkStream->read((uint32_t*)&forUnmarshaling->dstBinding, sizeof(uint32_t));
vkStream->read((uint32_t*)&forUnmarshaling->dstArrayElement, sizeof(uint32_t));
vkStream->read((uint32_t*)&forUnmarshaling->descriptorCount, sizeof(uint32_t));
@@ -3282,9 +3419,16 @@
{
fprintf(stderr, "fatal: forUnmarshaling->pImageInfo inconsistent between guest and host\n");
}
- for (uint32_t i = 0; i < (uint32_t)forUnmarshaling->descriptorCount; ++i)
+ if ((!(vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT) || ((VK_DESCRIPTOR_TYPE_SAMPLER == forUnmarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER == forUnmarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE == forUnmarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_STORAGE_IMAGE == forUnmarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT == forUnmarshaling->descriptorType))))
{
- unmarshal_VkDescriptorImageInfo(vkStream, (VkDescriptorImageInfo*)(forUnmarshaling->pImageInfo + i));
+ for (uint32_t i = 0; i < (uint32_t)forUnmarshaling->descriptorCount; ++i)
+ {
+ unmarshal_VkDescriptorImageInfo(vkStream, (VkDescriptorImageInfo*)(forUnmarshaling->pImageInfo + i));
+ }
+ }
+ else
+ {
+ forUnmarshaling->pImageInfo = 0;
}
}
// WARNING PTR CHECK
@@ -3296,9 +3440,16 @@
{
fprintf(stderr, "fatal: forUnmarshaling->pBufferInfo inconsistent between guest and host\n");
}
- for (uint32_t i = 0; i < (uint32_t)forUnmarshaling->descriptorCount; ++i)
+ if ((!(vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT) || ((VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == forUnmarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC == forUnmarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == forUnmarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC == forUnmarshaling->descriptorType))))
{
- unmarshal_VkDescriptorBufferInfo(vkStream, (VkDescriptorBufferInfo*)(forUnmarshaling->pBufferInfo + i));
+ for (uint32_t i = 0; i < (uint32_t)forUnmarshaling->descriptorCount; ++i)
+ {
+ unmarshal_VkDescriptorBufferInfo(vkStream, (VkDescriptorBufferInfo*)(forUnmarshaling->pBufferInfo + i));
+ }
+ }
+ else
+ {
+ forUnmarshaling->pBufferInfo = 0;
}
}
// WARNING PTR CHECK
@@ -3310,12 +3461,19 @@
{
fprintf(stderr, "fatal: forUnmarshaling->pTexelBufferView inconsistent between guest and host\n");
}
- if (forUnmarshaling->descriptorCount)
+ if ((!(vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT) || ((VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER == forUnmarshaling->descriptorType) || (VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER == forUnmarshaling->descriptorType))))
{
- uint64_t* cgen_var_117;
- vkStream->alloc((void**)&cgen_var_117, forUnmarshaling->descriptorCount * 8);
- vkStream->read((uint64_t*)cgen_var_117, forUnmarshaling->descriptorCount * 8);
- vkStream->handleMapping()->mapHandles_u64_VkBufferView(cgen_var_117, (VkBufferView*)forUnmarshaling->pTexelBufferView, forUnmarshaling->descriptorCount);
+ if (forUnmarshaling->descriptorCount)
+ {
+ uint64_t* cgen_var_127;
+ vkStream->alloc((void**)&cgen_var_127, forUnmarshaling->descriptorCount * 8);
+ vkStream->read((uint64_t*)cgen_var_127, forUnmarshaling->descriptorCount * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkBufferView(cgen_var_127, (VkBufferView*)forUnmarshaling->pTexelBufferView, forUnmarshaling->descriptorCount);
+ }
+ }
+ else
+ {
+ forUnmarshaling->pTexelBufferView = 0;
}
}
}
@@ -3332,14 +3490,14 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_118;
- vkStream->handleMapping()->mapHandles_VkDescriptorSet_u64(&forMarshaling->srcSet, &cgen_var_118, 1);
- vkStream->write((uint64_t*)&cgen_var_118, 1 * 8);
+ uint64_t cgen_var_128;
+ vkStream->handleMapping()->mapHandles_VkDescriptorSet_u64(&forMarshaling->srcSet, &cgen_var_128, 1);
+ vkStream->write((uint64_t*)&cgen_var_128, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->srcBinding, sizeof(uint32_t));
vkStream->write((uint32_t*)&forMarshaling->srcArrayElement, sizeof(uint32_t));
- uint64_t cgen_var_119;
- vkStream->handleMapping()->mapHandles_VkDescriptorSet_u64(&forMarshaling->dstSet, &cgen_var_119, 1);
- vkStream->write((uint64_t*)&cgen_var_119, 1 * 8);
+ uint64_t cgen_var_129;
+ vkStream->handleMapping()->mapHandles_VkDescriptorSet_u64(&forMarshaling->dstSet, &cgen_var_129, 1);
+ vkStream->write((uint64_t*)&cgen_var_129, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->dstBinding, sizeof(uint32_t));
vkStream->write((uint32_t*)&forMarshaling->dstArrayElement, sizeof(uint32_t));
vkStream->write((uint32_t*)&forMarshaling->descriptorCount, sizeof(uint32_t));
@@ -3358,14 +3516,14 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_120;
- vkStream->read((uint64_t*)&cgen_var_120, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDescriptorSet(&cgen_var_120, (VkDescriptorSet*)&forUnmarshaling->srcSet, 1);
+ uint64_t cgen_var_130;
+ vkStream->read((uint64_t*)&cgen_var_130, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDescriptorSet(&cgen_var_130, (VkDescriptorSet*)&forUnmarshaling->srcSet, 1);
vkStream->read((uint32_t*)&forUnmarshaling->srcBinding, sizeof(uint32_t));
vkStream->read((uint32_t*)&forUnmarshaling->srcArrayElement, sizeof(uint32_t));
- uint64_t cgen_var_121;
- vkStream->read((uint64_t*)&cgen_var_121, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDescriptorSet(&cgen_var_121, (VkDescriptorSet*)&forUnmarshaling->dstSet, 1);
+ uint64_t cgen_var_131;
+ vkStream->read((uint64_t*)&cgen_var_131, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDescriptorSet(&cgen_var_131, (VkDescriptorSet*)&forUnmarshaling->dstSet, 1);
vkStream->read((uint32_t*)&forUnmarshaling->dstBinding, sizeof(uint32_t));
vkStream->read((uint32_t*)&forUnmarshaling->dstArrayElement, sizeof(uint32_t));
vkStream->read((uint32_t*)&forUnmarshaling->descriptorCount, sizeof(uint32_t));
@@ -3384,16 +3542,16 @@
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
vkStream->write((VkFramebufferCreateFlags*)&forMarshaling->flags, sizeof(VkFramebufferCreateFlags));
- uint64_t cgen_var_122;
- vkStream->handleMapping()->mapHandles_VkRenderPass_u64(&forMarshaling->renderPass, &cgen_var_122, 1);
- vkStream->write((uint64_t*)&cgen_var_122, 1 * 8);
+ uint64_t cgen_var_132;
+ vkStream->handleMapping()->mapHandles_VkRenderPass_u64(&forMarshaling->renderPass, &cgen_var_132, 1);
+ vkStream->write((uint64_t*)&cgen_var_132, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->attachmentCount, sizeof(uint32_t));
if (forMarshaling->attachmentCount)
{
- uint64_t* cgen_var_123;
- vkStream->alloc((void**)&cgen_var_123, forMarshaling->attachmentCount * 8);
- vkStream->handleMapping()->mapHandles_VkImageView_u64(forMarshaling->pAttachments, cgen_var_123, forMarshaling->attachmentCount);
- vkStream->write((uint64_t*)cgen_var_123, forMarshaling->attachmentCount * 8);
+ uint64_t* cgen_var_133;
+ vkStream->alloc((void**)&cgen_var_133, forMarshaling->attachmentCount * 8);
+ vkStream->handleMapping()->mapHandles_VkImageView_u64(forMarshaling->pAttachments, cgen_var_133, forMarshaling->attachmentCount);
+ vkStream->write((uint64_t*)cgen_var_133, forMarshaling->attachmentCount * 8);
}
vkStream->write((uint32_t*)&forMarshaling->width, sizeof(uint32_t));
vkStream->write((uint32_t*)&forMarshaling->height, sizeof(uint32_t));
@@ -3414,16 +3572,16 @@
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
vkStream->read((VkFramebufferCreateFlags*)&forUnmarshaling->flags, sizeof(VkFramebufferCreateFlags));
- uint64_t cgen_var_124;
- vkStream->read((uint64_t*)&cgen_var_124, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkRenderPass(&cgen_var_124, (VkRenderPass*)&forUnmarshaling->renderPass, 1);
+ uint64_t cgen_var_134;
+ vkStream->read((uint64_t*)&cgen_var_134, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkRenderPass(&cgen_var_134, (VkRenderPass*)&forUnmarshaling->renderPass, 1);
vkStream->read((uint32_t*)&forUnmarshaling->attachmentCount, sizeof(uint32_t));
if (forUnmarshaling->attachmentCount)
{
- uint64_t* cgen_var_125;
- vkStream->alloc((void**)&cgen_var_125, forUnmarshaling->attachmentCount * 8);
- vkStream->read((uint64_t*)cgen_var_125, forUnmarshaling->attachmentCount * 8);
- vkStream->handleMapping()->mapHandles_u64_VkImageView(cgen_var_125, (VkImageView*)forUnmarshaling->pAttachments, forUnmarshaling->attachmentCount);
+ uint64_t* cgen_var_135;
+ vkStream->alloc((void**)&cgen_var_135, forUnmarshaling->attachmentCount * 8);
+ vkStream->read((uint64_t*)cgen_var_135, forUnmarshaling->attachmentCount * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkImageView(cgen_var_135, (VkImageView*)forUnmarshaling->pAttachments, forUnmarshaling->attachmentCount);
}
vkStream->read((uint32_t*)&forUnmarshaling->width, sizeof(uint32_t));
vkStream->read((uint32_t*)&forUnmarshaling->height, sizeof(uint32_t));
@@ -3493,8 +3651,8 @@
marshal_VkAttachmentReference(vkStream, (const VkAttachmentReference*)(forMarshaling->pColorAttachments + i));
}
// WARNING PTR CHECK
- uint64_t cgen_var_126 = (uint64_t)(uintptr_t)forMarshaling->pResolveAttachments;
- vkStream->putBe64(cgen_var_126);
+ uint64_t cgen_var_136 = (uint64_t)(uintptr_t)forMarshaling->pResolveAttachments;
+ vkStream->putBe64(cgen_var_136);
if (forMarshaling->pResolveAttachments)
{
for (uint32_t i = 0; i < (uint32_t)forMarshaling->colorAttachmentCount; ++i)
@@ -3503,8 +3661,8 @@
}
}
// WARNING PTR CHECK
- uint64_t cgen_var_127 = (uint64_t)(uintptr_t)forMarshaling->pDepthStencilAttachment;
- vkStream->putBe64(cgen_var_127);
+ uint64_t cgen_var_137 = (uint64_t)(uintptr_t)forMarshaling->pDepthStencilAttachment;
+ vkStream->putBe64(cgen_var_137);
if (forMarshaling->pDepthStencilAttachment)
{
marshal_VkAttachmentReference(vkStream, (const VkAttachmentReference*)(forMarshaling->pDepthStencilAttachment));
@@ -3690,9 +3848,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_130;
- vkStream->handleMapping()->mapHandles_VkCommandPool_u64(&forMarshaling->commandPool, &cgen_var_130, 1);
- vkStream->write((uint64_t*)&cgen_var_130, 1 * 8);
+ uint64_t cgen_var_140;
+ vkStream->handleMapping()->mapHandles_VkCommandPool_u64(&forMarshaling->commandPool, &cgen_var_140, 1);
+ vkStream->write((uint64_t*)&cgen_var_140, 1 * 8);
vkStream->write((VkCommandBufferLevel*)&forMarshaling->level, sizeof(VkCommandBufferLevel));
vkStream->write((uint32_t*)&forMarshaling->commandBufferCount, sizeof(uint32_t));
}
@@ -3710,9 +3868,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_131;
- vkStream->read((uint64_t*)&cgen_var_131, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkCommandPool(&cgen_var_131, (VkCommandPool*)&forUnmarshaling->commandPool, 1);
+ uint64_t cgen_var_141;
+ vkStream->read((uint64_t*)&cgen_var_141, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkCommandPool(&cgen_var_141, (VkCommandPool*)&forUnmarshaling->commandPool, 1);
vkStream->read((VkCommandBufferLevel*)&forUnmarshaling->level, sizeof(VkCommandBufferLevel));
vkStream->read((uint32_t*)&forUnmarshaling->commandBufferCount, sizeof(uint32_t));
}
@@ -3729,13 +3887,13 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_132;
- vkStream->handleMapping()->mapHandles_VkRenderPass_u64(&forMarshaling->renderPass, &cgen_var_132, 1);
- vkStream->write((uint64_t*)&cgen_var_132, 1 * 8);
+ uint64_t cgen_var_142;
+ vkStream->handleMapping()->mapHandles_VkRenderPass_u64(&forMarshaling->renderPass, &cgen_var_142, 1);
+ vkStream->write((uint64_t*)&cgen_var_142, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->subpass, sizeof(uint32_t));
- uint64_t cgen_var_133;
- vkStream->handleMapping()->mapHandles_VkFramebuffer_u64(&forMarshaling->framebuffer, &cgen_var_133, 1);
- vkStream->write((uint64_t*)&cgen_var_133, 1 * 8);
+ uint64_t cgen_var_143;
+ vkStream->handleMapping()->mapHandles_VkFramebuffer_u64(&forMarshaling->framebuffer, &cgen_var_143, 1);
+ vkStream->write((uint64_t*)&cgen_var_143, 1 * 8);
vkStream->write((VkBool32*)&forMarshaling->occlusionQueryEnable, sizeof(VkBool32));
vkStream->write((VkQueryControlFlags*)&forMarshaling->queryFlags, sizeof(VkQueryControlFlags));
vkStream->write((VkQueryPipelineStatisticFlags*)&forMarshaling->pipelineStatistics, sizeof(VkQueryPipelineStatisticFlags));
@@ -3754,13 +3912,13 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_134;
- vkStream->read((uint64_t*)&cgen_var_134, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkRenderPass(&cgen_var_134, (VkRenderPass*)&forUnmarshaling->renderPass, 1);
+ uint64_t cgen_var_144;
+ vkStream->read((uint64_t*)&cgen_var_144, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkRenderPass(&cgen_var_144, (VkRenderPass*)&forUnmarshaling->renderPass, 1);
vkStream->read((uint32_t*)&forUnmarshaling->subpass, sizeof(uint32_t));
- uint64_t cgen_var_135;
- vkStream->read((uint64_t*)&cgen_var_135, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkFramebuffer(&cgen_var_135, (VkFramebuffer*)&forUnmarshaling->framebuffer, 1);
+ uint64_t cgen_var_145;
+ vkStream->read((uint64_t*)&cgen_var_145, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkFramebuffer(&cgen_var_145, (VkFramebuffer*)&forUnmarshaling->framebuffer, 1);
vkStream->read((VkBool32*)&forUnmarshaling->occlusionQueryEnable, sizeof(VkBool32));
vkStream->read((VkQueryControlFlags*)&forUnmarshaling->queryFlags, sizeof(VkQueryControlFlags));
vkStream->read((VkQueryPipelineStatisticFlags*)&forUnmarshaling->pipelineStatistics, sizeof(VkQueryPipelineStatisticFlags));
@@ -3780,8 +3938,8 @@
}
vkStream->write((VkCommandBufferUsageFlags*)&forMarshaling->flags, sizeof(VkCommandBufferUsageFlags));
// WARNING PTR CHECK
- uint64_t cgen_var_136 = (uint64_t)(uintptr_t)forMarshaling->pInheritanceInfo;
- vkStream->putBe64(cgen_var_136);
+ uint64_t cgen_var_146 = (uint64_t)(uintptr_t)forMarshaling->pInheritanceInfo;
+ vkStream->putBe64(cgen_var_146);
if (forMarshaling->pInheritanceInfo)
{
marshal_VkCommandBufferInheritanceInfo(vkStream, (const VkCommandBufferInheritanceInfo*)(forMarshaling->pInheritanceInfo));
@@ -4082,9 +4240,9 @@
vkStream->write((VkAccessFlags*)&forMarshaling->dstAccessMask, sizeof(VkAccessFlags));
vkStream->write((uint32_t*)&forMarshaling->srcQueueFamilyIndex, sizeof(uint32_t));
vkStream->write((uint32_t*)&forMarshaling->dstQueueFamilyIndex, sizeof(uint32_t));
- uint64_t cgen_var_138;
- vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_138, 1);
- vkStream->write((uint64_t*)&cgen_var_138, 1 * 8);
+ uint64_t cgen_var_148;
+ vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_148, 1);
+ vkStream->write((uint64_t*)&cgen_var_148, 1 * 8);
vkStream->write((VkDeviceSize*)&forMarshaling->offset, sizeof(VkDeviceSize));
vkStream->write((VkDeviceSize*)&forMarshaling->size, sizeof(VkDeviceSize));
}
@@ -4106,9 +4264,9 @@
vkStream->read((VkAccessFlags*)&forUnmarshaling->dstAccessMask, sizeof(VkAccessFlags));
vkStream->read((uint32_t*)&forUnmarshaling->srcQueueFamilyIndex, sizeof(uint32_t));
vkStream->read((uint32_t*)&forUnmarshaling->dstQueueFamilyIndex, sizeof(uint32_t));
- uint64_t cgen_var_139;
- vkStream->read((uint64_t*)&cgen_var_139, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_139, (VkBuffer*)&forUnmarshaling->buffer, 1);
+ uint64_t cgen_var_149;
+ vkStream->read((uint64_t*)&cgen_var_149, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_149, (VkBuffer*)&forUnmarshaling->buffer, 1);
vkStream->read((VkDeviceSize*)&forUnmarshaling->offset, sizeof(VkDeviceSize));
vkStream->read((VkDeviceSize*)&forUnmarshaling->size, sizeof(VkDeviceSize));
}
@@ -4131,9 +4289,9 @@
vkStream->write((VkImageLayout*)&forMarshaling->newLayout, sizeof(VkImageLayout));
vkStream->write((uint32_t*)&forMarshaling->srcQueueFamilyIndex, sizeof(uint32_t));
vkStream->write((uint32_t*)&forMarshaling->dstQueueFamilyIndex, sizeof(uint32_t));
- uint64_t cgen_var_140;
- vkStream->handleMapping()->mapHandles_VkImage_u64(&forMarshaling->image, &cgen_var_140, 1);
- vkStream->write((uint64_t*)&cgen_var_140, 1 * 8);
+ uint64_t cgen_var_150;
+ vkStream->handleMapping()->mapHandles_VkImage_u64(&forMarshaling->image, &cgen_var_150, 1);
+ vkStream->write((uint64_t*)&cgen_var_150, 1 * 8);
marshal_VkImageSubresourceRange(vkStream, (VkImageSubresourceRange*)(&forMarshaling->subresourceRange));
}
@@ -4156,9 +4314,9 @@
vkStream->read((VkImageLayout*)&forUnmarshaling->newLayout, sizeof(VkImageLayout));
vkStream->read((uint32_t*)&forUnmarshaling->srcQueueFamilyIndex, sizeof(uint32_t));
vkStream->read((uint32_t*)&forUnmarshaling->dstQueueFamilyIndex, sizeof(uint32_t));
- uint64_t cgen_var_141;
- vkStream->read((uint64_t*)&cgen_var_141, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkImage(&cgen_var_141, (VkImage*)&forUnmarshaling->image, 1);
+ uint64_t cgen_var_151;
+ vkStream->read((uint64_t*)&cgen_var_151, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkImage(&cgen_var_151, (VkImage*)&forUnmarshaling->image, 1);
unmarshal_VkImageSubresourceRange(vkStream, (VkImageSubresourceRange*)(&forUnmarshaling->subresourceRange));
}
@@ -4174,17 +4332,17 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_142;
- vkStream->handleMapping()->mapHandles_VkRenderPass_u64(&forMarshaling->renderPass, &cgen_var_142, 1);
- vkStream->write((uint64_t*)&cgen_var_142, 1 * 8);
- uint64_t cgen_var_143;
- vkStream->handleMapping()->mapHandles_VkFramebuffer_u64(&forMarshaling->framebuffer, &cgen_var_143, 1);
- vkStream->write((uint64_t*)&cgen_var_143, 1 * 8);
+ uint64_t cgen_var_152;
+ vkStream->handleMapping()->mapHandles_VkRenderPass_u64(&forMarshaling->renderPass, &cgen_var_152, 1);
+ vkStream->write((uint64_t*)&cgen_var_152, 1 * 8);
+ uint64_t cgen_var_153;
+ vkStream->handleMapping()->mapHandles_VkFramebuffer_u64(&forMarshaling->framebuffer, &cgen_var_153, 1);
+ vkStream->write((uint64_t*)&cgen_var_153, 1 * 8);
marshal_VkRect2D(vkStream, (VkRect2D*)(&forMarshaling->renderArea));
vkStream->write((uint32_t*)&forMarshaling->clearValueCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_144 = (uint64_t)(uintptr_t)forMarshaling->pClearValues;
- vkStream->putBe64(cgen_var_144);
+ uint64_t cgen_var_154 = (uint64_t)(uintptr_t)forMarshaling->pClearValues;
+ vkStream->putBe64(cgen_var_154);
if (forMarshaling->pClearValues)
{
for (uint32_t i = 0; i < (uint32_t)forMarshaling->clearValueCount; ++i)
@@ -4207,12 +4365,12 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_145;
- vkStream->read((uint64_t*)&cgen_var_145, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkRenderPass(&cgen_var_145, (VkRenderPass*)&forUnmarshaling->renderPass, 1);
- uint64_t cgen_var_146;
- vkStream->read((uint64_t*)&cgen_var_146, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkFramebuffer(&cgen_var_146, (VkFramebuffer*)&forUnmarshaling->framebuffer, 1);
+ uint64_t cgen_var_155;
+ vkStream->read((uint64_t*)&cgen_var_155, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkRenderPass(&cgen_var_155, (VkRenderPass*)&forUnmarshaling->renderPass, 1);
+ uint64_t cgen_var_156;
+ vkStream->read((uint64_t*)&cgen_var_156, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkFramebuffer(&cgen_var_156, (VkFramebuffer*)&forUnmarshaling->framebuffer, 1);
unmarshal_VkRect2D(vkStream, (VkRect2D*)(&forUnmarshaling->renderArea));
vkStream->read((uint32_t*)&forUnmarshaling->clearValueCount, sizeof(uint32_t));
// WARNING PTR CHECK
@@ -4400,12 +4558,12 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_148;
- vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_148, 1);
- vkStream->write((uint64_t*)&cgen_var_148, 1 * 8);
- uint64_t cgen_var_149;
- vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(&forMarshaling->memory, &cgen_var_149, 1);
- vkStream->write((uint64_t*)&cgen_var_149, 1 * 8);
+ uint64_t cgen_var_158;
+ vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_158, 1);
+ vkStream->write((uint64_t*)&cgen_var_158, 1 * 8);
+ uint64_t cgen_var_159;
+ vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(&forMarshaling->memory, &cgen_var_159, 1);
+ vkStream->write((uint64_t*)&cgen_var_159, 1 * 8);
vkStream->write((VkDeviceSize*)&forMarshaling->memoryOffset, sizeof(VkDeviceSize));
}
@@ -4422,12 +4580,12 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_150;
- vkStream->read((uint64_t*)&cgen_var_150, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_150, (VkBuffer*)&forUnmarshaling->buffer, 1);
- uint64_t cgen_var_151;
- vkStream->read((uint64_t*)&cgen_var_151, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(&cgen_var_151, (VkDeviceMemory*)&forUnmarshaling->memory, 1);
+ uint64_t cgen_var_160;
+ vkStream->read((uint64_t*)&cgen_var_160, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_160, (VkBuffer*)&forUnmarshaling->buffer, 1);
+ uint64_t cgen_var_161;
+ vkStream->read((uint64_t*)&cgen_var_161, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(&cgen_var_161, (VkDeviceMemory*)&forUnmarshaling->memory, 1);
vkStream->read((VkDeviceSize*)&forUnmarshaling->memoryOffset, sizeof(VkDeviceSize));
}
@@ -4443,12 +4601,12 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_152;
- vkStream->handleMapping()->mapHandles_VkImage_u64(&forMarshaling->image, &cgen_var_152, 1);
- vkStream->write((uint64_t*)&cgen_var_152, 1 * 8);
- uint64_t cgen_var_153;
- vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(&forMarshaling->memory, &cgen_var_153, 1);
- vkStream->write((uint64_t*)&cgen_var_153, 1 * 8);
+ uint64_t cgen_var_162;
+ vkStream->handleMapping()->mapHandles_VkImage_u64(&forMarshaling->image, &cgen_var_162, 1);
+ vkStream->write((uint64_t*)&cgen_var_162, 1 * 8);
+ uint64_t cgen_var_163;
+ vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(&forMarshaling->memory, &cgen_var_163, 1);
+ vkStream->write((uint64_t*)&cgen_var_163, 1 * 8);
vkStream->write((VkDeviceSize*)&forMarshaling->memoryOffset, sizeof(VkDeviceSize));
}
@@ -4465,12 +4623,12 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_154;
- vkStream->read((uint64_t*)&cgen_var_154, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkImage(&cgen_var_154, (VkImage*)&forUnmarshaling->image, 1);
- uint64_t cgen_var_155;
- vkStream->read((uint64_t*)&cgen_var_155, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(&cgen_var_155, (VkDeviceMemory*)&forUnmarshaling->memory, 1);
+ uint64_t cgen_var_164;
+ vkStream->read((uint64_t*)&cgen_var_164, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkImage(&cgen_var_164, (VkImage*)&forUnmarshaling->image, 1);
+ uint64_t cgen_var_165;
+ vkStream->read((uint64_t*)&cgen_var_165, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(&cgen_var_165, (VkDeviceMemory*)&forUnmarshaling->memory, 1);
vkStream->read((VkDeviceSize*)&forUnmarshaling->memoryOffset, sizeof(VkDeviceSize));
}
@@ -4556,12 +4714,12 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_156;
- vkStream->handleMapping()->mapHandles_VkImage_u64(&forMarshaling->image, &cgen_var_156, 1);
- vkStream->write((uint64_t*)&cgen_var_156, 1 * 8);
- uint64_t cgen_var_157;
- vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_157, 1);
- vkStream->write((uint64_t*)&cgen_var_157, 1 * 8);
+ uint64_t cgen_var_166;
+ vkStream->handleMapping()->mapHandles_VkImage_u64(&forMarshaling->image, &cgen_var_166, 1);
+ vkStream->write((uint64_t*)&cgen_var_166, 1 * 8);
+ uint64_t cgen_var_167;
+ vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_167, 1);
+ vkStream->write((uint64_t*)&cgen_var_167, 1 * 8);
}
void unmarshal_VkMemoryDedicatedAllocateInfo(
@@ -4577,12 +4735,12 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_158;
- vkStream->read((uint64_t*)&cgen_var_158, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkImage(&cgen_var_158, (VkImage*)&forUnmarshaling->image, 1);
- uint64_t cgen_var_159;
- vkStream->read((uint64_t*)&cgen_var_159, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_159, (VkBuffer*)&forUnmarshaling->buffer, 1);
+ uint64_t cgen_var_168;
+ vkStream->read((uint64_t*)&cgen_var_168, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkImage(&cgen_var_168, (VkImage*)&forUnmarshaling->image, 1);
+ uint64_t cgen_var_169;
+ vkStream->read((uint64_t*)&cgen_var_169, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_169, (VkBuffer*)&forUnmarshaling->buffer, 1);
}
void marshal_VkMemoryAllocateFlagsInfo(
@@ -4890,10 +5048,10 @@
vkStream->write((uint32_t*)&forMarshaling->physicalDeviceCount, sizeof(uint32_t));
if (forMarshaling->physicalDeviceCount)
{
- uint64_t* cgen_var_160;
- vkStream->alloc((void**)&cgen_var_160, forMarshaling->physicalDeviceCount * 8);
- vkStream->handleMapping()->mapHandles_VkPhysicalDevice_u64(forMarshaling->pPhysicalDevices, cgen_var_160, forMarshaling->physicalDeviceCount);
- vkStream->write((uint64_t*)cgen_var_160, forMarshaling->physicalDeviceCount * 8);
+ uint64_t* cgen_var_170;
+ vkStream->alloc((void**)&cgen_var_170, forMarshaling->physicalDeviceCount * 8);
+ vkStream->handleMapping()->mapHandles_VkPhysicalDevice_u64(forMarshaling->pPhysicalDevices, cgen_var_170, forMarshaling->physicalDeviceCount);
+ vkStream->write((uint64_t*)cgen_var_170, forMarshaling->physicalDeviceCount * 8);
}
}
@@ -4913,10 +5071,10 @@
vkStream->read((uint32_t*)&forUnmarshaling->physicalDeviceCount, sizeof(uint32_t));
if (forUnmarshaling->physicalDeviceCount)
{
- uint64_t* cgen_var_161;
- vkStream->alloc((void**)&cgen_var_161, forUnmarshaling->physicalDeviceCount * 8);
- vkStream->read((uint64_t*)cgen_var_161, forUnmarshaling->physicalDeviceCount * 8);
- vkStream->handleMapping()->mapHandles_u64_VkPhysicalDevice(cgen_var_161, (VkPhysicalDevice*)forUnmarshaling->pPhysicalDevices, forUnmarshaling->physicalDeviceCount);
+ uint64_t* cgen_var_171;
+ vkStream->alloc((void**)&cgen_var_171, forUnmarshaling->physicalDeviceCount * 8);
+ vkStream->read((uint64_t*)cgen_var_171, forUnmarshaling->physicalDeviceCount * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkPhysicalDevice(cgen_var_171, (VkPhysicalDevice*)forUnmarshaling->pPhysicalDevices, forUnmarshaling->physicalDeviceCount);
}
}
@@ -4932,9 +5090,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_162;
- vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_162, 1);
- vkStream->write((uint64_t*)&cgen_var_162, 1 * 8);
+ uint64_t cgen_var_172;
+ vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_172, 1);
+ vkStream->write((uint64_t*)&cgen_var_172, 1 * 8);
}
void unmarshal_VkBufferMemoryRequirementsInfo2(
@@ -4950,9 +5108,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_163;
- vkStream->read((uint64_t*)&cgen_var_163, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_163, (VkBuffer*)&forUnmarshaling->buffer, 1);
+ uint64_t cgen_var_173;
+ vkStream->read((uint64_t*)&cgen_var_173, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_173, (VkBuffer*)&forUnmarshaling->buffer, 1);
}
void marshal_VkImageMemoryRequirementsInfo2(
@@ -4967,9 +5125,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_164;
- vkStream->handleMapping()->mapHandles_VkImage_u64(&forMarshaling->image, &cgen_var_164, 1);
- vkStream->write((uint64_t*)&cgen_var_164, 1 * 8);
+ uint64_t cgen_var_174;
+ vkStream->handleMapping()->mapHandles_VkImage_u64(&forMarshaling->image, &cgen_var_174, 1);
+ vkStream->write((uint64_t*)&cgen_var_174, 1 * 8);
}
void unmarshal_VkImageMemoryRequirementsInfo2(
@@ -4985,9 +5143,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_165;
- vkStream->read((uint64_t*)&cgen_var_165, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkImage(&cgen_var_165, (VkImage*)&forUnmarshaling->image, 1);
+ uint64_t cgen_var_175;
+ vkStream->read((uint64_t*)&cgen_var_175, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkImage(&cgen_var_175, (VkImage*)&forUnmarshaling->image, 1);
}
void marshal_VkImageSparseMemoryRequirementsInfo2(
@@ -5002,9 +5160,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_166;
- vkStream->handleMapping()->mapHandles_VkImage_u64(&forMarshaling->image, &cgen_var_166, 1);
- vkStream->write((uint64_t*)&cgen_var_166, 1 * 8);
+ uint64_t cgen_var_176;
+ vkStream->handleMapping()->mapHandles_VkImage_u64(&forMarshaling->image, &cgen_var_176, 1);
+ vkStream->write((uint64_t*)&cgen_var_176, 1 * 8);
}
void unmarshal_VkImageSparseMemoryRequirementsInfo2(
@@ -5020,9 +5178,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_167;
- vkStream->read((uint64_t*)&cgen_var_167, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkImage(&cgen_var_167, (VkImage*)&forUnmarshaling->image, 1);
+ uint64_t cgen_var_177;
+ vkStream->read((uint64_t*)&cgen_var_177, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkImage(&cgen_var_177, (VkImage*)&forUnmarshaling->image, 1);
}
void marshal_VkMemoryRequirements2(
@@ -5859,9 +6017,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_168;
- vkStream->handleMapping()->mapHandles_VkSamplerYcbcrConversion_u64(&forMarshaling->conversion, &cgen_var_168, 1);
- vkStream->write((uint64_t*)&cgen_var_168, 1 * 8);
+ uint64_t cgen_var_178;
+ vkStream->handleMapping()->mapHandles_VkSamplerYcbcrConversion_u64(&forMarshaling->conversion, &cgen_var_178, 1);
+ vkStream->write((uint64_t*)&cgen_var_178, 1 * 8);
}
void unmarshal_VkSamplerYcbcrConversionInfo(
@@ -5877,9 +6035,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_169;
- vkStream->read((uint64_t*)&cgen_var_169, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSamplerYcbcrConversion(&cgen_var_169, (VkSamplerYcbcrConversion*)&forUnmarshaling->conversion, 1);
+ uint64_t cgen_var_179;
+ vkStream->read((uint64_t*)&cgen_var_179, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSamplerYcbcrConversion(&cgen_var_179, (VkSamplerYcbcrConversion*)&forUnmarshaling->conversion, 1);
}
void marshal_VkBindImagePlaneMemoryInfo(
@@ -6014,10 +6172,10 @@
vkStream->write((uint32_t*)&forMarshaling->dstArrayElement, sizeof(uint32_t));
vkStream->write((uint32_t*)&forMarshaling->descriptorCount, sizeof(uint32_t));
vkStream->write((VkDescriptorType*)&forMarshaling->descriptorType, sizeof(VkDescriptorType));
- uint64_t cgen_var_170 = (uint64_t)forMarshaling->offset;
- vkStream->putBe64(cgen_var_170);
- uint64_t cgen_var_171 = (uint64_t)forMarshaling->stride;
- vkStream->putBe64(cgen_var_171);
+ uint64_t cgen_var_180 = (uint64_t)forMarshaling->offset;
+ vkStream->putBe64(cgen_var_180);
+ uint64_t cgen_var_181 = (uint64_t)forMarshaling->stride;
+ vkStream->putBe64(cgen_var_181);
}
void unmarshal_VkDescriptorUpdateTemplateEntry(
@@ -6051,13 +6209,13 @@
marshal_VkDescriptorUpdateTemplateEntry(vkStream, (const VkDescriptorUpdateTemplateEntry*)(forMarshaling->pDescriptorUpdateEntries + i));
}
vkStream->write((VkDescriptorUpdateTemplateType*)&forMarshaling->templateType, sizeof(VkDescriptorUpdateTemplateType));
- uint64_t cgen_var_174;
- vkStream->handleMapping()->mapHandles_VkDescriptorSetLayout_u64(&forMarshaling->descriptorSetLayout, &cgen_var_174, 1);
- vkStream->write((uint64_t*)&cgen_var_174, 1 * 8);
+ uint64_t cgen_var_184;
+ vkStream->handleMapping()->mapHandles_VkDescriptorSetLayout_u64(&forMarshaling->descriptorSetLayout, &cgen_var_184, 1);
+ vkStream->write((uint64_t*)&cgen_var_184, 1 * 8);
vkStream->write((VkPipelineBindPoint*)&forMarshaling->pipelineBindPoint, sizeof(VkPipelineBindPoint));
- uint64_t cgen_var_175;
- vkStream->handleMapping()->mapHandles_VkPipelineLayout_u64(&forMarshaling->pipelineLayout, &cgen_var_175, 1);
- vkStream->write((uint64_t*)&cgen_var_175, 1 * 8);
+ uint64_t cgen_var_185;
+ vkStream->handleMapping()->mapHandles_VkPipelineLayout_u64(&forMarshaling->pipelineLayout, &cgen_var_185, 1);
+ vkStream->write((uint64_t*)&cgen_var_185, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->set, sizeof(uint32_t));
}
@@ -6081,13 +6239,13 @@
unmarshal_VkDescriptorUpdateTemplateEntry(vkStream, (VkDescriptorUpdateTemplateEntry*)(forUnmarshaling->pDescriptorUpdateEntries + i));
}
vkStream->read((VkDescriptorUpdateTemplateType*)&forUnmarshaling->templateType, sizeof(VkDescriptorUpdateTemplateType));
- uint64_t cgen_var_176;
- vkStream->read((uint64_t*)&cgen_var_176, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDescriptorSetLayout(&cgen_var_176, (VkDescriptorSetLayout*)&forUnmarshaling->descriptorSetLayout, 1);
+ uint64_t cgen_var_186;
+ vkStream->read((uint64_t*)&cgen_var_186, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDescriptorSetLayout(&cgen_var_186, (VkDescriptorSetLayout*)&forUnmarshaling->descriptorSetLayout, 1);
vkStream->read((VkPipelineBindPoint*)&forUnmarshaling->pipelineBindPoint, sizeof(VkPipelineBindPoint));
- uint64_t cgen_var_177;
- vkStream->read((uint64_t*)&cgen_var_177, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkPipelineLayout(&cgen_var_177, (VkPipelineLayout*)&forUnmarshaling->pipelineLayout, 1);
+ uint64_t cgen_var_187;
+ vkStream->read((uint64_t*)&cgen_var_187, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkPipelineLayout(&cgen_var_187, (VkPipelineLayout*)&forUnmarshaling->pipelineLayout, 1);
vkStream->read((uint32_t*)&forUnmarshaling->set, sizeof(uint32_t));
}
@@ -6723,9 +6881,9 @@
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
vkStream->write((VkSwapchainCreateFlagsKHR*)&forMarshaling->flags, sizeof(VkSwapchainCreateFlagsKHR));
- uint64_t cgen_var_178;
- vkStream->handleMapping()->mapHandles_VkSurfaceKHR_u64(&forMarshaling->surface, &cgen_var_178, 1);
- vkStream->write((uint64_t*)&cgen_var_178, 1 * 8);
+ uint64_t cgen_var_188;
+ vkStream->handleMapping()->mapHandles_VkSurfaceKHR_u64(&forMarshaling->surface, &cgen_var_188, 1);
+ vkStream->write((uint64_t*)&cgen_var_188, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->minImageCount, sizeof(uint32_t));
vkStream->write((VkFormat*)&forMarshaling->imageFormat, sizeof(VkFormat));
vkStream->write((VkColorSpaceKHR*)&forMarshaling->imageColorSpace, sizeof(VkColorSpaceKHR));
@@ -6735,8 +6893,8 @@
vkStream->write((VkSharingMode*)&forMarshaling->imageSharingMode, sizeof(VkSharingMode));
vkStream->write((uint32_t*)&forMarshaling->queueFamilyIndexCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_179 = (uint64_t)(uintptr_t)forMarshaling->pQueueFamilyIndices;
- vkStream->putBe64(cgen_var_179);
+ uint64_t cgen_var_189 = (uint64_t)(uintptr_t)forMarshaling->pQueueFamilyIndices;
+ vkStream->putBe64(cgen_var_189);
if (forMarshaling->pQueueFamilyIndices)
{
vkStream->write((const uint32_t*)forMarshaling->pQueueFamilyIndices, forMarshaling->queueFamilyIndexCount * sizeof(const uint32_t));
@@ -6745,9 +6903,9 @@
vkStream->write((VkCompositeAlphaFlagBitsKHR*)&forMarshaling->compositeAlpha, sizeof(VkCompositeAlphaFlagBitsKHR));
vkStream->write((VkPresentModeKHR*)&forMarshaling->presentMode, sizeof(VkPresentModeKHR));
vkStream->write((VkBool32*)&forMarshaling->clipped, sizeof(VkBool32));
- uint64_t cgen_var_180;
- vkStream->handleMapping()->mapHandles_VkSwapchainKHR_u64(&forMarshaling->oldSwapchain, &cgen_var_180, 1);
- vkStream->write((uint64_t*)&cgen_var_180, 1 * 8);
+ uint64_t cgen_var_190;
+ vkStream->handleMapping()->mapHandles_VkSwapchainKHR_u64(&forMarshaling->oldSwapchain, &cgen_var_190, 1);
+ vkStream->write((uint64_t*)&cgen_var_190, 1 * 8);
}
void unmarshal_VkSwapchainCreateInfoKHR(
@@ -6764,9 +6922,9 @@
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
vkStream->read((VkSwapchainCreateFlagsKHR*)&forUnmarshaling->flags, sizeof(VkSwapchainCreateFlagsKHR));
- uint64_t cgen_var_181;
- vkStream->read((uint64_t*)&cgen_var_181, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSurfaceKHR(&cgen_var_181, (VkSurfaceKHR*)&forUnmarshaling->surface, 1);
+ uint64_t cgen_var_191;
+ vkStream->read((uint64_t*)&cgen_var_191, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSurfaceKHR(&cgen_var_191, (VkSurfaceKHR*)&forUnmarshaling->surface, 1);
vkStream->read((uint32_t*)&forUnmarshaling->minImageCount, sizeof(uint32_t));
vkStream->read((VkFormat*)&forUnmarshaling->imageFormat, sizeof(VkFormat));
vkStream->read((VkColorSpaceKHR*)&forUnmarshaling->imageColorSpace, sizeof(VkColorSpaceKHR));
@@ -6790,9 +6948,9 @@
vkStream->read((VkCompositeAlphaFlagBitsKHR*)&forUnmarshaling->compositeAlpha, sizeof(VkCompositeAlphaFlagBitsKHR));
vkStream->read((VkPresentModeKHR*)&forUnmarshaling->presentMode, sizeof(VkPresentModeKHR));
vkStream->read((VkBool32*)&forUnmarshaling->clipped, sizeof(VkBool32));
- uint64_t cgen_var_183;
- vkStream->read((uint64_t*)&cgen_var_183, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSwapchainKHR(&cgen_var_183, (VkSwapchainKHR*)&forUnmarshaling->oldSwapchain, 1);
+ uint64_t cgen_var_193;
+ vkStream->read((uint64_t*)&cgen_var_193, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSwapchainKHR(&cgen_var_193, (VkSwapchainKHR*)&forUnmarshaling->oldSwapchain, 1);
}
void marshal_VkPresentInfoKHR(
@@ -6810,23 +6968,23 @@
vkStream->write((uint32_t*)&forMarshaling->waitSemaphoreCount, sizeof(uint32_t));
if (forMarshaling->waitSemaphoreCount)
{
- uint64_t* cgen_var_184;
- vkStream->alloc((void**)&cgen_var_184, forMarshaling->waitSemaphoreCount * 8);
- vkStream->handleMapping()->mapHandles_VkSemaphore_u64(forMarshaling->pWaitSemaphores, cgen_var_184, forMarshaling->waitSemaphoreCount);
- vkStream->write((uint64_t*)cgen_var_184, forMarshaling->waitSemaphoreCount * 8);
+ uint64_t* cgen_var_194;
+ vkStream->alloc((void**)&cgen_var_194, forMarshaling->waitSemaphoreCount * 8);
+ vkStream->handleMapping()->mapHandles_VkSemaphore_u64(forMarshaling->pWaitSemaphores, cgen_var_194, forMarshaling->waitSemaphoreCount);
+ vkStream->write((uint64_t*)cgen_var_194, forMarshaling->waitSemaphoreCount * 8);
}
vkStream->write((uint32_t*)&forMarshaling->swapchainCount, sizeof(uint32_t));
if (forMarshaling->swapchainCount)
{
- uint64_t* cgen_var_185;
- vkStream->alloc((void**)&cgen_var_185, forMarshaling->swapchainCount * 8);
- vkStream->handleMapping()->mapHandles_VkSwapchainKHR_u64(forMarshaling->pSwapchains, cgen_var_185, forMarshaling->swapchainCount);
- vkStream->write((uint64_t*)cgen_var_185, forMarshaling->swapchainCount * 8);
+ uint64_t* cgen_var_195;
+ vkStream->alloc((void**)&cgen_var_195, forMarshaling->swapchainCount * 8);
+ vkStream->handleMapping()->mapHandles_VkSwapchainKHR_u64(forMarshaling->pSwapchains, cgen_var_195, forMarshaling->swapchainCount);
+ vkStream->write((uint64_t*)cgen_var_195, forMarshaling->swapchainCount * 8);
}
vkStream->write((const uint32_t*)forMarshaling->pImageIndices, forMarshaling->swapchainCount * sizeof(const uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_186 = (uint64_t)(uintptr_t)forMarshaling->pResults;
- vkStream->putBe64(cgen_var_186);
+ uint64_t cgen_var_196 = (uint64_t)(uintptr_t)forMarshaling->pResults;
+ vkStream->putBe64(cgen_var_196);
if (forMarshaling->pResults)
{
vkStream->write((VkResult*)forMarshaling->pResults, forMarshaling->swapchainCount * sizeof(VkResult));
@@ -6849,18 +7007,18 @@
vkStream->read((uint32_t*)&forUnmarshaling->waitSemaphoreCount, sizeof(uint32_t));
if (forUnmarshaling->waitSemaphoreCount)
{
- uint64_t* cgen_var_187;
- vkStream->alloc((void**)&cgen_var_187, forUnmarshaling->waitSemaphoreCount * 8);
- vkStream->read((uint64_t*)cgen_var_187, forUnmarshaling->waitSemaphoreCount * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSemaphore(cgen_var_187, (VkSemaphore*)forUnmarshaling->pWaitSemaphores, forUnmarshaling->waitSemaphoreCount);
+ uint64_t* cgen_var_197;
+ vkStream->alloc((void**)&cgen_var_197, forUnmarshaling->waitSemaphoreCount * 8);
+ vkStream->read((uint64_t*)cgen_var_197, forUnmarshaling->waitSemaphoreCount * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSemaphore(cgen_var_197, (VkSemaphore*)forUnmarshaling->pWaitSemaphores, forUnmarshaling->waitSemaphoreCount);
}
vkStream->read((uint32_t*)&forUnmarshaling->swapchainCount, sizeof(uint32_t));
if (forUnmarshaling->swapchainCount)
{
- uint64_t* cgen_var_188;
- vkStream->alloc((void**)&cgen_var_188, forUnmarshaling->swapchainCount * 8);
- vkStream->read((uint64_t*)cgen_var_188, forUnmarshaling->swapchainCount * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSwapchainKHR(cgen_var_188, (VkSwapchainKHR*)forUnmarshaling->pSwapchains, forUnmarshaling->swapchainCount);
+ uint64_t* cgen_var_198;
+ vkStream->alloc((void**)&cgen_var_198, forUnmarshaling->swapchainCount * 8);
+ vkStream->read((uint64_t*)cgen_var_198, forUnmarshaling->swapchainCount * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSwapchainKHR(cgen_var_198, (VkSwapchainKHR*)forUnmarshaling->pSwapchains, forUnmarshaling->swapchainCount);
}
vkStream->read((uint32_t*)forUnmarshaling->pImageIndices, forUnmarshaling->swapchainCount * sizeof(const uint32_t));
// WARNING PTR CHECK
@@ -6888,9 +7046,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_190;
- vkStream->handleMapping()->mapHandles_VkSwapchainKHR_u64(&forMarshaling->swapchain, &cgen_var_190, 1);
- vkStream->write((uint64_t*)&cgen_var_190, 1 * 8);
+ uint64_t cgen_var_200;
+ vkStream->handleMapping()->mapHandles_VkSwapchainKHR_u64(&forMarshaling->swapchain, &cgen_var_200, 1);
+ vkStream->write((uint64_t*)&cgen_var_200, 1 * 8);
}
void unmarshal_VkImageSwapchainCreateInfoKHR(
@@ -6906,9 +7064,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_191;
- vkStream->read((uint64_t*)&cgen_var_191, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSwapchainKHR(&cgen_var_191, (VkSwapchainKHR*)&forUnmarshaling->swapchain, 1);
+ uint64_t cgen_var_201;
+ vkStream->read((uint64_t*)&cgen_var_201, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSwapchainKHR(&cgen_var_201, (VkSwapchainKHR*)&forUnmarshaling->swapchain, 1);
}
void marshal_VkBindImageMemorySwapchainInfoKHR(
@@ -6923,9 +7081,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_192;
- vkStream->handleMapping()->mapHandles_VkSwapchainKHR_u64(&forMarshaling->swapchain, &cgen_var_192, 1);
- vkStream->write((uint64_t*)&cgen_var_192, 1 * 8);
+ uint64_t cgen_var_202;
+ vkStream->handleMapping()->mapHandles_VkSwapchainKHR_u64(&forMarshaling->swapchain, &cgen_var_202, 1);
+ vkStream->write((uint64_t*)&cgen_var_202, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->imageIndex, sizeof(uint32_t));
}
@@ -6942,9 +7100,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_193;
- vkStream->read((uint64_t*)&cgen_var_193, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSwapchainKHR(&cgen_var_193, (VkSwapchainKHR*)&forUnmarshaling->swapchain, 1);
+ uint64_t cgen_var_203;
+ vkStream->read((uint64_t*)&cgen_var_203, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSwapchainKHR(&cgen_var_203, (VkSwapchainKHR*)&forUnmarshaling->swapchain, 1);
vkStream->read((uint32_t*)&forUnmarshaling->imageIndex, sizeof(uint32_t));
}
@@ -6960,16 +7118,16 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_194;
- vkStream->handleMapping()->mapHandles_VkSwapchainKHR_u64(&forMarshaling->swapchain, &cgen_var_194, 1);
- vkStream->write((uint64_t*)&cgen_var_194, 1 * 8);
+ uint64_t cgen_var_204;
+ vkStream->handleMapping()->mapHandles_VkSwapchainKHR_u64(&forMarshaling->swapchain, &cgen_var_204, 1);
+ vkStream->write((uint64_t*)&cgen_var_204, 1 * 8);
vkStream->write((uint64_t*)&forMarshaling->timeout, sizeof(uint64_t));
- uint64_t cgen_var_195;
- vkStream->handleMapping()->mapHandles_VkSemaphore_u64(&forMarshaling->semaphore, &cgen_var_195, 1);
- vkStream->write((uint64_t*)&cgen_var_195, 1 * 8);
- uint64_t cgen_var_196;
- vkStream->handleMapping()->mapHandles_VkFence_u64(&forMarshaling->fence, &cgen_var_196, 1);
- vkStream->write((uint64_t*)&cgen_var_196, 1 * 8);
+ uint64_t cgen_var_205;
+ vkStream->handleMapping()->mapHandles_VkSemaphore_u64(&forMarshaling->semaphore, &cgen_var_205, 1);
+ vkStream->write((uint64_t*)&cgen_var_205, 1 * 8);
+ uint64_t cgen_var_206;
+ vkStream->handleMapping()->mapHandles_VkFence_u64(&forMarshaling->fence, &cgen_var_206, 1);
+ vkStream->write((uint64_t*)&cgen_var_206, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->deviceMask, sizeof(uint32_t));
}
@@ -6986,16 +7144,16 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_197;
- vkStream->read((uint64_t*)&cgen_var_197, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSwapchainKHR(&cgen_var_197, (VkSwapchainKHR*)&forUnmarshaling->swapchain, 1);
+ uint64_t cgen_var_207;
+ vkStream->read((uint64_t*)&cgen_var_207, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSwapchainKHR(&cgen_var_207, (VkSwapchainKHR*)&forUnmarshaling->swapchain, 1);
vkStream->read((uint64_t*)&forUnmarshaling->timeout, sizeof(uint64_t));
- uint64_t cgen_var_198;
- vkStream->read((uint64_t*)&cgen_var_198, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSemaphore(&cgen_var_198, (VkSemaphore*)&forUnmarshaling->semaphore, 1);
- uint64_t cgen_var_199;
- vkStream->read((uint64_t*)&cgen_var_199, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkFence(&cgen_var_199, (VkFence*)&forUnmarshaling->fence, 1);
+ uint64_t cgen_var_208;
+ vkStream->read((uint64_t*)&cgen_var_208, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSemaphore(&cgen_var_208, (VkSemaphore*)&forUnmarshaling->semaphore, 1);
+ uint64_t cgen_var_209;
+ vkStream->read((uint64_t*)&cgen_var_209, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkFence(&cgen_var_209, (VkFence*)&forUnmarshaling->fence, 1);
vkStream->read((uint32_t*)&forUnmarshaling->deviceMask, sizeof(uint32_t));
}
@@ -7104,9 +7262,9 @@
VulkanStreamGuest* vkStream,
const VkDisplayPropertiesKHR* forMarshaling)
{
- uint64_t cgen_var_200;
- vkStream->handleMapping()->mapHandles_VkDisplayKHR_u64(&forMarshaling->display, &cgen_var_200, 1);
- vkStream->write((uint64_t*)&cgen_var_200, 1 * 8);
+ uint64_t cgen_var_210;
+ vkStream->handleMapping()->mapHandles_VkDisplayKHR_u64(&forMarshaling->display, &cgen_var_210, 1);
+ vkStream->write((uint64_t*)&cgen_var_210, 1 * 8);
vkStream->putString(forMarshaling->displayName);
marshal_VkExtent2D(vkStream, (VkExtent2D*)(&forMarshaling->physicalDimensions));
marshal_VkExtent2D(vkStream, (VkExtent2D*)(&forMarshaling->physicalResolution));
@@ -7119,9 +7277,9 @@
VulkanStreamGuest* vkStream,
VkDisplayPropertiesKHR* forUnmarshaling)
{
- uint64_t cgen_var_201;
- vkStream->read((uint64_t*)&cgen_var_201, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDisplayKHR(&cgen_var_201, (VkDisplayKHR*)&forUnmarshaling->display, 1);
+ uint64_t cgen_var_211;
+ vkStream->read((uint64_t*)&cgen_var_211, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDisplayKHR(&cgen_var_211, (VkDisplayKHR*)&forUnmarshaling->display, 1);
vkStream->loadStringInPlace((char**)&forUnmarshaling->displayName);
unmarshal_VkExtent2D(vkStream, (VkExtent2D*)(&forUnmarshaling->physicalDimensions));
unmarshal_VkExtent2D(vkStream, (VkExtent2D*)(&forUnmarshaling->physicalResolution));
@@ -7150,9 +7308,9 @@
VulkanStreamGuest* vkStream,
const VkDisplayModePropertiesKHR* forMarshaling)
{
- uint64_t cgen_var_202;
- vkStream->handleMapping()->mapHandles_VkDisplayModeKHR_u64(&forMarshaling->displayMode, &cgen_var_202, 1);
- vkStream->write((uint64_t*)&cgen_var_202, 1 * 8);
+ uint64_t cgen_var_212;
+ vkStream->handleMapping()->mapHandles_VkDisplayModeKHR_u64(&forMarshaling->displayMode, &cgen_var_212, 1);
+ vkStream->write((uint64_t*)&cgen_var_212, 1 * 8);
marshal_VkDisplayModeParametersKHR(vkStream, (VkDisplayModeParametersKHR*)(&forMarshaling->parameters));
}
@@ -7160,9 +7318,9 @@
VulkanStreamGuest* vkStream,
VkDisplayModePropertiesKHR* forUnmarshaling)
{
- uint64_t cgen_var_203;
- vkStream->read((uint64_t*)&cgen_var_203, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDisplayModeKHR(&cgen_var_203, (VkDisplayModeKHR*)&forUnmarshaling->displayMode, 1);
+ uint64_t cgen_var_213;
+ vkStream->read((uint64_t*)&cgen_var_213, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDisplayModeKHR(&cgen_var_213, (VkDisplayModeKHR*)&forUnmarshaling->displayMode, 1);
unmarshal_VkDisplayModeParametersKHR(vkStream, (VkDisplayModeParametersKHR*)(&forUnmarshaling->parameters));
}
@@ -7233,9 +7391,9 @@
VulkanStreamGuest* vkStream,
const VkDisplayPlanePropertiesKHR* forMarshaling)
{
- uint64_t cgen_var_204;
- vkStream->handleMapping()->mapHandles_VkDisplayKHR_u64(&forMarshaling->currentDisplay, &cgen_var_204, 1);
- vkStream->write((uint64_t*)&cgen_var_204, 1 * 8);
+ uint64_t cgen_var_214;
+ vkStream->handleMapping()->mapHandles_VkDisplayKHR_u64(&forMarshaling->currentDisplay, &cgen_var_214, 1);
+ vkStream->write((uint64_t*)&cgen_var_214, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->currentStackIndex, sizeof(uint32_t));
}
@@ -7243,9 +7401,9 @@
VulkanStreamGuest* vkStream,
VkDisplayPlanePropertiesKHR* forUnmarshaling)
{
- uint64_t cgen_var_205;
- vkStream->read((uint64_t*)&cgen_var_205, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDisplayKHR(&cgen_var_205, (VkDisplayKHR*)&forUnmarshaling->currentDisplay, 1);
+ uint64_t cgen_var_215;
+ vkStream->read((uint64_t*)&cgen_var_215, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDisplayKHR(&cgen_var_215, (VkDisplayKHR*)&forUnmarshaling->currentDisplay, 1);
vkStream->read((uint32_t*)&forUnmarshaling->currentStackIndex, sizeof(uint32_t));
}
@@ -7262,9 +7420,9 @@
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
vkStream->write((VkDisplaySurfaceCreateFlagsKHR*)&forMarshaling->flags, sizeof(VkDisplaySurfaceCreateFlagsKHR));
- uint64_t cgen_var_206;
- vkStream->handleMapping()->mapHandles_VkDisplayModeKHR_u64(&forMarshaling->displayMode, &cgen_var_206, 1);
- vkStream->write((uint64_t*)&cgen_var_206, 1 * 8);
+ uint64_t cgen_var_216;
+ vkStream->handleMapping()->mapHandles_VkDisplayModeKHR_u64(&forMarshaling->displayMode, &cgen_var_216, 1);
+ vkStream->write((uint64_t*)&cgen_var_216, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->planeIndex, sizeof(uint32_t));
vkStream->write((uint32_t*)&forMarshaling->planeStackIndex, sizeof(uint32_t));
vkStream->write((VkSurfaceTransformFlagBitsKHR*)&forMarshaling->transform, sizeof(VkSurfaceTransformFlagBitsKHR));
@@ -7287,9 +7445,9 @@
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
vkStream->read((VkDisplaySurfaceCreateFlagsKHR*)&forUnmarshaling->flags, sizeof(VkDisplaySurfaceCreateFlagsKHR));
- uint64_t cgen_var_207;
- vkStream->read((uint64_t*)&cgen_var_207, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDisplayModeKHR(&cgen_var_207, (VkDisplayModeKHR*)&forUnmarshaling->displayMode, 1);
+ uint64_t cgen_var_217;
+ vkStream->read((uint64_t*)&cgen_var_217, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDisplayModeKHR(&cgen_var_217, (VkDisplayModeKHR*)&forUnmarshaling->displayMode, 1);
vkStream->read((uint32_t*)&forUnmarshaling->planeIndex, sizeof(uint32_t));
vkStream->read((uint32_t*)&forUnmarshaling->planeStackIndex, sizeof(uint32_t));
vkStream->read((VkSurfaceTransformFlagBitsKHR*)&forUnmarshaling->transform, sizeof(VkSurfaceTransformFlagBitsKHR));
@@ -7351,8 +7509,8 @@
}
vkStream->write((VkXlibSurfaceCreateFlagsKHR*)&forMarshaling->flags, sizeof(VkXlibSurfaceCreateFlagsKHR));
// WARNING PTR CHECK
- uint64_t cgen_var_208 = (uint64_t)(uintptr_t)forMarshaling->dpy;
- vkStream->putBe64(cgen_var_208);
+ uint64_t cgen_var_218 = (uint64_t)(uintptr_t)forMarshaling->dpy;
+ vkStream->putBe64(cgen_var_218);
if (forMarshaling->dpy)
{
vkStream->write((Display*)forMarshaling->dpy, sizeof(Display));
@@ -7404,8 +7562,8 @@
}
vkStream->write((VkXcbSurfaceCreateFlagsKHR*)&forMarshaling->flags, sizeof(VkXcbSurfaceCreateFlagsKHR));
// WARNING PTR CHECK
- uint64_t cgen_var_210 = (uint64_t)(uintptr_t)forMarshaling->connection;
- vkStream->putBe64(cgen_var_210);
+ uint64_t cgen_var_220 = (uint64_t)(uintptr_t)forMarshaling->connection;
+ vkStream->putBe64(cgen_var_220);
if (forMarshaling->connection)
{
vkStream->write((xcb_connection_t*)forMarshaling->connection, sizeof(xcb_connection_t));
@@ -7457,15 +7615,15 @@
}
vkStream->write((VkWaylandSurfaceCreateFlagsKHR*)&forMarshaling->flags, sizeof(VkWaylandSurfaceCreateFlagsKHR));
// WARNING PTR CHECK
- uint64_t cgen_var_212 = (uint64_t)(uintptr_t)forMarshaling->display;
- vkStream->putBe64(cgen_var_212);
+ uint64_t cgen_var_222 = (uint64_t)(uintptr_t)forMarshaling->display;
+ vkStream->putBe64(cgen_var_222);
if (forMarshaling->display)
{
vkStream->write((wl_display*)forMarshaling->display, sizeof(wl_display));
}
// WARNING PTR CHECK
- uint64_t cgen_var_213 = (uint64_t)(uintptr_t)forMarshaling->surface;
- vkStream->putBe64(cgen_var_213);
+ uint64_t cgen_var_223 = (uint64_t)(uintptr_t)forMarshaling->surface;
+ vkStream->putBe64(cgen_var_223);
if (forMarshaling->surface)
{
vkStream->write((wl_surface*)forMarshaling->surface, sizeof(wl_surface));
@@ -7526,15 +7684,15 @@
}
vkStream->write((VkMirSurfaceCreateFlagsKHR*)&forMarshaling->flags, sizeof(VkMirSurfaceCreateFlagsKHR));
// WARNING PTR CHECK
- uint64_t cgen_var_216 = (uint64_t)(uintptr_t)forMarshaling->connection;
- vkStream->putBe64(cgen_var_216);
+ uint64_t cgen_var_226 = (uint64_t)(uintptr_t)forMarshaling->connection;
+ vkStream->putBe64(cgen_var_226);
if (forMarshaling->connection)
{
vkStream->write((MirConnection*)forMarshaling->connection, sizeof(MirConnection));
}
// WARNING PTR CHECK
- uint64_t cgen_var_217 = (uint64_t)(uintptr_t)forMarshaling->mirSurface;
- vkStream->putBe64(cgen_var_217);
+ uint64_t cgen_var_227 = (uint64_t)(uintptr_t)forMarshaling->mirSurface;
+ vkStream->putBe64(cgen_var_227);
if (forMarshaling->mirSurface)
{
vkStream->write((MirSurface*)forMarshaling->mirSurface, sizeof(MirSurface));
@@ -7595,8 +7753,8 @@
}
vkStream->write((VkAndroidSurfaceCreateFlagsKHR*)&forMarshaling->flags, sizeof(VkAndroidSurfaceCreateFlagsKHR));
// WARNING PTR CHECK
- uint64_t cgen_var_220 = (uint64_t)(uintptr_t)forMarshaling->window;
- vkStream->putBe64(cgen_var_220);
+ uint64_t cgen_var_230 = (uint64_t)(uintptr_t)forMarshaling->window;
+ vkStream->putBe64(cgen_var_230);
if (forMarshaling->window)
{
vkStream->write((ANativeWindow*)forMarshaling->window, sizeof(ANativeWindow));
@@ -7735,8 +7893,8 @@
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
// WARNING PTR CHECK
- uint64_t cgen_var_222 = (uint64_t)(uintptr_t)forMarshaling->pAttributes;
- vkStream->putBe64(cgen_var_222);
+ uint64_t cgen_var_232 = (uint64_t)(uintptr_t)forMarshaling->pAttributes;
+ vkStream->putBe64(cgen_var_232);
if (forMarshaling->pAttributes)
{
vkStream->write((const SECURITY_ATTRIBUTES*)forMarshaling->pAttributes, sizeof(const SECURITY_ATTRIBUTES));
@@ -7816,9 +7974,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_224;
- vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(&forMarshaling->memory, &cgen_var_224, 1);
- vkStream->write((uint64_t*)&cgen_var_224, 1 * 8);
+ uint64_t cgen_var_234;
+ vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(&forMarshaling->memory, &cgen_var_234, 1);
+ vkStream->write((uint64_t*)&cgen_var_234, 1 * 8);
vkStream->write((VkExternalMemoryHandleTypeFlagBits*)&forMarshaling->handleType, sizeof(VkExternalMemoryHandleTypeFlagBits));
}
@@ -7835,9 +7993,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_225;
- vkStream->read((uint64_t*)&cgen_var_225, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(&cgen_var_225, (VkDeviceMemory*)&forUnmarshaling->memory, 1);
+ uint64_t cgen_var_235;
+ vkStream->read((uint64_t*)&cgen_var_235, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(&cgen_var_235, (VkDeviceMemory*)&forUnmarshaling->memory, 1);
vkStream->read((VkExternalMemoryHandleTypeFlagBits*)&forUnmarshaling->handleType, sizeof(VkExternalMemoryHandleTypeFlagBits));
}
@@ -7919,9 +8077,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_226;
- vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(&forMarshaling->memory, &cgen_var_226, 1);
- vkStream->write((uint64_t*)&cgen_var_226, 1 * 8);
+ uint64_t cgen_var_236;
+ vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(&forMarshaling->memory, &cgen_var_236, 1);
+ vkStream->write((uint64_t*)&cgen_var_236, 1 * 8);
vkStream->write((VkExternalMemoryHandleTypeFlagBits*)&forMarshaling->handleType, sizeof(VkExternalMemoryHandleTypeFlagBits));
}
@@ -7938,9 +8096,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_227;
- vkStream->read((uint64_t*)&cgen_var_227, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(&cgen_var_227, (VkDeviceMemory*)&forUnmarshaling->memory, 1);
+ uint64_t cgen_var_237;
+ vkStream->read((uint64_t*)&cgen_var_237, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(&cgen_var_237, (VkDeviceMemory*)&forUnmarshaling->memory, 1);
vkStream->read((VkExternalMemoryHandleTypeFlagBits*)&forUnmarshaling->handleType, sizeof(VkExternalMemoryHandleTypeFlagBits));
}
@@ -7961,20 +8119,20 @@
vkStream->write((uint32_t*)&forMarshaling->acquireCount, sizeof(uint32_t));
if (forMarshaling->acquireCount)
{
- uint64_t* cgen_var_228;
- vkStream->alloc((void**)&cgen_var_228, forMarshaling->acquireCount * 8);
- vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(forMarshaling->pAcquireSyncs, cgen_var_228, forMarshaling->acquireCount);
- vkStream->write((uint64_t*)cgen_var_228, forMarshaling->acquireCount * 8);
+ uint64_t* cgen_var_238;
+ vkStream->alloc((void**)&cgen_var_238, forMarshaling->acquireCount * 8);
+ vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(forMarshaling->pAcquireSyncs, cgen_var_238, forMarshaling->acquireCount);
+ vkStream->write((uint64_t*)cgen_var_238, forMarshaling->acquireCount * 8);
}
vkStream->write((const uint64_t*)forMarshaling->pAcquireKeys, forMarshaling->acquireCount * sizeof(const uint64_t));
vkStream->write((const uint32_t*)forMarshaling->pAcquireTimeouts, forMarshaling->acquireCount * sizeof(const uint32_t));
vkStream->write((uint32_t*)&forMarshaling->releaseCount, sizeof(uint32_t));
if (forMarshaling->releaseCount)
{
- uint64_t* cgen_var_229;
- vkStream->alloc((void**)&cgen_var_229, forMarshaling->releaseCount * 8);
- vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(forMarshaling->pReleaseSyncs, cgen_var_229, forMarshaling->releaseCount);
- vkStream->write((uint64_t*)cgen_var_229, forMarshaling->releaseCount * 8);
+ uint64_t* cgen_var_239;
+ vkStream->alloc((void**)&cgen_var_239, forMarshaling->releaseCount * 8);
+ vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(forMarshaling->pReleaseSyncs, cgen_var_239, forMarshaling->releaseCount);
+ vkStream->write((uint64_t*)cgen_var_239, forMarshaling->releaseCount * 8);
}
vkStream->write((const uint64_t*)forMarshaling->pReleaseKeys, forMarshaling->releaseCount * sizeof(const uint64_t));
}
@@ -7995,20 +8153,20 @@
vkStream->read((uint32_t*)&forUnmarshaling->acquireCount, sizeof(uint32_t));
if (forUnmarshaling->acquireCount)
{
- uint64_t* cgen_var_230;
- vkStream->alloc((void**)&cgen_var_230, forUnmarshaling->acquireCount * 8);
- vkStream->read((uint64_t*)cgen_var_230, forUnmarshaling->acquireCount * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(cgen_var_230, (VkDeviceMemory*)forUnmarshaling->pAcquireSyncs, forUnmarshaling->acquireCount);
+ uint64_t* cgen_var_240;
+ vkStream->alloc((void**)&cgen_var_240, forUnmarshaling->acquireCount * 8);
+ vkStream->read((uint64_t*)cgen_var_240, forUnmarshaling->acquireCount * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(cgen_var_240, (VkDeviceMemory*)forUnmarshaling->pAcquireSyncs, forUnmarshaling->acquireCount);
}
vkStream->read((uint64_t*)forUnmarshaling->pAcquireKeys, forUnmarshaling->acquireCount * sizeof(const uint64_t));
vkStream->read((uint32_t*)forUnmarshaling->pAcquireTimeouts, forUnmarshaling->acquireCount * sizeof(const uint32_t));
vkStream->read((uint32_t*)&forUnmarshaling->releaseCount, sizeof(uint32_t));
if (forUnmarshaling->releaseCount)
{
- uint64_t* cgen_var_231;
- vkStream->alloc((void**)&cgen_var_231, forUnmarshaling->releaseCount * 8);
- vkStream->read((uint64_t*)cgen_var_231, forUnmarshaling->releaseCount * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(cgen_var_231, (VkDeviceMemory*)forUnmarshaling->pReleaseSyncs, forUnmarshaling->releaseCount);
+ uint64_t* cgen_var_241;
+ vkStream->alloc((void**)&cgen_var_241, forUnmarshaling->releaseCount * 8);
+ vkStream->read((uint64_t*)cgen_var_241, forUnmarshaling->releaseCount * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(cgen_var_241, (VkDeviceMemory*)forUnmarshaling->pReleaseSyncs, forUnmarshaling->releaseCount);
}
vkStream->read((uint64_t*)forUnmarshaling->pReleaseKeys, forUnmarshaling->releaseCount * sizeof(const uint64_t));
}
@@ -8031,9 +8189,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_232;
- vkStream->handleMapping()->mapHandles_VkSemaphore_u64(&forMarshaling->semaphore, &cgen_var_232, 1);
- vkStream->write((uint64_t*)&cgen_var_232, 1 * 8);
+ uint64_t cgen_var_242;
+ vkStream->handleMapping()->mapHandles_VkSemaphore_u64(&forMarshaling->semaphore, &cgen_var_242, 1);
+ vkStream->write((uint64_t*)&cgen_var_242, 1 * 8);
vkStream->write((VkSemaphoreImportFlags*)&forMarshaling->flags, sizeof(VkSemaphoreImportFlags));
vkStream->write((VkExternalSemaphoreHandleTypeFlagBits*)&forMarshaling->handleType, sizeof(VkExternalSemaphoreHandleTypeFlagBits));
vkStream->write((HANDLE*)&forMarshaling->handle, sizeof(HANDLE));
@@ -8053,9 +8211,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_233;
- vkStream->read((uint64_t*)&cgen_var_233, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSemaphore(&cgen_var_233, (VkSemaphore*)&forUnmarshaling->semaphore, 1);
+ uint64_t cgen_var_243;
+ vkStream->read((uint64_t*)&cgen_var_243, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSemaphore(&cgen_var_243, (VkSemaphore*)&forUnmarshaling->semaphore, 1);
vkStream->read((VkSemaphoreImportFlags*)&forUnmarshaling->flags, sizeof(VkSemaphoreImportFlags));
vkStream->read((VkExternalSemaphoreHandleTypeFlagBits*)&forUnmarshaling->handleType, sizeof(VkExternalSemaphoreHandleTypeFlagBits));
vkStream->read((HANDLE*)&forUnmarshaling->handle, sizeof(HANDLE));
@@ -8075,8 +8233,8 @@
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
// WARNING PTR CHECK
- uint64_t cgen_var_234 = (uint64_t)(uintptr_t)forMarshaling->pAttributes;
- vkStream->putBe64(cgen_var_234);
+ uint64_t cgen_var_244 = (uint64_t)(uintptr_t)forMarshaling->pAttributes;
+ vkStream->putBe64(cgen_var_244);
if (forMarshaling->pAttributes)
{
vkStream->write((const SECURITY_ATTRIBUTES*)forMarshaling->pAttributes, sizeof(const SECURITY_ATTRIBUTES));
@@ -8127,16 +8285,16 @@
}
vkStream->write((uint32_t*)&forMarshaling->waitSemaphoreValuesCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_236 = (uint64_t)(uintptr_t)forMarshaling->pWaitSemaphoreValues;
- vkStream->putBe64(cgen_var_236);
+ uint64_t cgen_var_246 = (uint64_t)(uintptr_t)forMarshaling->pWaitSemaphoreValues;
+ vkStream->putBe64(cgen_var_246);
if (forMarshaling->pWaitSemaphoreValues)
{
vkStream->write((const uint64_t*)forMarshaling->pWaitSemaphoreValues, forMarshaling->waitSemaphoreValuesCount * sizeof(const uint64_t));
}
vkStream->write((uint32_t*)&forMarshaling->signalSemaphoreValuesCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_237 = (uint64_t)(uintptr_t)forMarshaling->pSignalSemaphoreValues;
- vkStream->putBe64(cgen_var_237);
+ uint64_t cgen_var_247 = (uint64_t)(uintptr_t)forMarshaling->pSignalSemaphoreValues;
+ vkStream->putBe64(cgen_var_247);
if (forMarshaling->pSignalSemaphoreValues)
{
vkStream->write((const uint64_t*)forMarshaling->pSignalSemaphoreValues, forMarshaling->signalSemaphoreValuesCount * sizeof(const uint64_t));
@@ -8194,9 +8352,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_240;
- vkStream->handleMapping()->mapHandles_VkSemaphore_u64(&forMarshaling->semaphore, &cgen_var_240, 1);
- vkStream->write((uint64_t*)&cgen_var_240, 1 * 8);
+ uint64_t cgen_var_250;
+ vkStream->handleMapping()->mapHandles_VkSemaphore_u64(&forMarshaling->semaphore, &cgen_var_250, 1);
+ vkStream->write((uint64_t*)&cgen_var_250, 1 * 8);
vkStream->write((VkExternalSemaphoreHandleTypeFlagBits*)&forMarshaling->handleType, sizeof(VkExternalSemaphoreHandleTypeFlagBits));
}
@@ -8213,9 +8371,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_241;
- vkStream->read((uint64_t*)&cgen_var_241, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSemaphore(&cgen_var_241, (VkSemaphore*)&forUnmarshaling->semaphore, 1);
+ uint64_t cgen_var_251;
+ vkStream->read((uint64_t*)&cgen_var_251, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSemaphore(&cgen_var_251, (VkSemaphore*)&forUnmarshaling->semaphore, 1);
vkStream->read((VkExternalSemaphoreHandleTypeFlagBits*)&forUnmarshaling->handleType, sizeof(VkExternalSemaphoreHandleTypeFlagBits));
}
@@ -8233,9 +8391,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_242;
- vkStream->handleMapping()->mapHandles_VkSemaphore_u64(&forMarshaling->semaphore, &cgen_var_242, 1);
- vkStream->write((uint64_t*)&cgen_var_242, 1 * 8);
+ uint64_t cgen_var_252;
+ vkStream->handleMapping()->mapHandles_VkSemaphore_u64(&forMarshaling->semaphore, &cgen_var_252, 1);
+ vkStream->write((uint64_t*)&cgen_var_252, 1 * 8);
vkStream->write((VkSemaphoreImportFlags*)&forMarshaling->flags, sizeof(VkSemaphoreImportFlags));
vkStream->write((VkExternalSemaphoreHandleTypeFlagBits*)&forMarshaling->handleType, sizeof(VkExternalSemaphoreHandleTypeFlagBits));
vkStream->write((int*)&forMarshaling->fd, sizeof(int));
@@ -8254,9 +8412,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_243;
- vkStream->read((uint64_t*)&cgen_var_243, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSemaphore(&cgen_var_243, (VkSemaphore*)&forUnmarshaling->semaphore, 1);
+ uint64_t cgen_var_253;
+ vkStream->read((uint64_t*)&cgen_var_253, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSemaphore(&cgen_var_253, (VkSemaphore*)&forUnmarshaling->semaphore, 1);
vkStream->read((VkSemaphoreImportFlags*)&forUnmarshaling->flags, sizeof(VkSemaphoreImportFlags));
vkStream->read((VkExternalSemaphoreHandleTypeFlagBits*)&forUnmarshaling->handleType, sizeof(VkExternalSemaphoreHandleTypeFlagBits));
vkStream->read((int*)&forUnmarshaling->fd, sizeof(int));
@@ -8274,9 +8432,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_244;
- vkStream->handleMapping()->mapHandles_VkSemaphore_u64(&forMarshaling->semaphore, &cgen_var_244, 1);
- vkStream->write((uint64_t*)&cgen_var_244, 1 * 8);
+ uint64_t cgen_var_254;
+ vkStream->handleMapping()->mapHandles_VkSemaphore_u64(&forMarshaling->semaphore, &cgen_var_254, 1);
+ vkStream->write((uint64_t*)&cgen_var_254, 1 * 8);
vkStream->write((VkExternalSemaphoreHandleTypeFlagBits*)&forMarshaling->handleType, sizeof(VkExternalSemaphoreHandleTypeFlagBits));
}
@@ -8293,9 +8451,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_245;
- vkStream->read((uint64_t*)&cgen_var_245, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSemaphore(&cgen_var_245, (VkSemaphore*)&forUnmarshaling->semaphore, 1);
+ uint64_t cgen_var_255;
+ vkStream->read((uint64_t*)&cgen_var_255, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSemaphore(&cgen_var_255, (VkSemaphore*)&forUnmarshaling->semaphore, 1);
vkStream->read((VkExternalSemaphoreHandleTypeFlagBits*)&forUnmarshaling->handleType, sizeof(VkExternalSemaphoreHandleTypeFlagBits));
}
@@ -8360,8 +8518,8 @@
{
vkStream->write((uint32_t*)&forMarshaling->rectangleCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_246 = (uint64_t)(uintptr_t)forMarshaling->pRectangles;
- vkStream->putBe64(cgen_var_246);
+ uint64_t cgen_var_256 = (uint64_t)(uintptr_t)forMarshaling->pRectangles;
+ vkStream->putBe64(cgen_var_256);
if (forMarshaling->pRectangles)
{
for (uint32_t i = 0; i < (uint32_t)forMarshaling->rectangleCount; ++i)
@@ -8406,8 +8564,8 @@
}
vkStream->write((uint32_t*)&forMarshaling->swapchainCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_248 = (uint64_t)(uintptr_t)forMarshaling->pRegions;
- vkStream->putBe64(cgen_var_248);
+ uint64_t cgen_var_258 = (uint64_t)(uintptr_t)forMarshaling->pRegions;
+ vkStream->putBe64(cgen_var_258);
if (forMarshaling->pRegions)
{
for (uint32_t i = 0; i < (uint32_t)forMarshaling->swapchainCount; ++i)
@@ -8559,8 +8717,8 @@
marshal_VkAttachmentReference2KHR(vkStream, (const VkAttachmentReference2KHR*)(forMarshaling->pColorAttachments + i));
}
// WARNING PTR CHECK
- uint64_t cgen_var_250 = (uint64_t)(uintptr_t)forMarshaling->pResolveAttachments;
- vkStream->putBe64(cgen_var_250);
+ uint64_t cgen_var_260 = (uint64_t)(uintptr_t)forMarshaling->pResolveAttachments;
+ vkStream->putBe64(cgen_var_260);
if (forMarshaling->pResolveAttachments)
{
for (uint32_t i = 0; i < (uint32_t)forMarshaling->colorAttachmentCount; ++i)
@@ -8569,8 +8727,8 @@
}
}
// WARNING PTR CHECK
- uint64_t cgen_var_251 = (uint64_t)(uintptr_t)forMarshaling->pDepthStencilAttachment;
- vkStream->putBe64(cgen_var_251);
+ uint64_t cgen_var_261 = (uint64_t)(uintptr_t)forMarshaling->pDepthStencilAttachment;
+ vkStream->putBe64(cgen_var_261);
if (forMarshaling->pDepthStencilAttachment)
{
marshal_VkAttachmentReference2KHR(vkStream, (const VkAttachmentReference2KHR*)(forMarshaling->pDepthStencilAttachment));
@@ -8855,9 +9013,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_254;
- vkStream->handleMapping()->mapHandles_VkFence_u64(&forMarshaling->fence, &cgen_var_254, 1);
- vkStream->write((uint64_t*)&cgen_var_254, 1 * 8);
+ uint64_t cgen_var_264;
+ vkStream->handleMapping()->mapHandles_VkFence_u64(&forMarshaling->fence, &cgen_var_264, 1);
+ vkStream->write((uint64_t*)&cgen_var_264, 1 * 8);
vkStream->write((VkFenceImportFlags*)&forMarshaling->flags, sizeof(VkFenceImportFlags));
vkStream->write((VkExternalFenceHandleTypeFlagBits*)&forMarshaling->handleType, sizeof(VkExternalFenceHandleTypeFlagBits));
vkStream->write((HANDLE*)&forMarshaling->handle, sizeof(HANDLE));
@@ -8877,9 +9035,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_255;
- vkStream->read((uint64_t*)&cgen_var_255, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkFence(&cgen_var_255, (VkFence*)&forUnmarshaling->fence, 1);
+ uint64_t cgen_var_265;
+ vkStream->read((uint64_t*)&cgen_var_265, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkFence(&cgen_var_265, (VkFence*)&forUnmarshaling->fence, 1);
vkStream->read((VkFenceImportFlags*)&forUnmarshaling->flags, sizeof(VkFenceImportFlags));
vkStream->read((VkExternalFenceHandleTypeFlagBits*)&forUnmarshaling->handleType, sizeof(VkExternalFenceHandleTypeFlagBits));
vkStream->read((HANDLE*)&forUnmarshaling->handle, sizeof(HANDLE));
@@ -8899,8 +9057,8 @@
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
// WARNING PTR CHECK
- uint64_t cgen_var_256 = (uint64_t)(uintptr_t)forMarshaling->pAttributes;
- vkStream->putBe64(cgen_var_256);
+ uint64_t cgen_var_266 = (uint64_t)(uintptr_t)forMarshaling->pAttributes;
+ vkStream->putBe64(cgen_var_266);
if (forMarshaling->pAttributes)
{
vkStream->write((const SECURITY_ATTRIBUTES*)forMarshaling->pAttributes, sizeof(const SECURITY_ATTRIBUTES));
@@ -8949,9 +9107,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_258;
- vkStream->handleMapping()->mapHandles_VkFence_u64(&forMarshaling->fence, &cgen_var_258, 1);
- vkStream->write((uint64_t*)&cgen_var_258, 1 * 8);
+ uint64_t cgen_var_268;
+ vkStream->handleMapping()->mapHandles_VkFence_u64(&forMarshaling->fence, &cgen_var_268, 1);
+ vkStream->write((uint64_t*)&cgen_var_268, 1 * 8);
vkStream->write((VkExternalFenceHandleTypeFlagBits*)&forMarshaling->handleType, sizeof(VkExternalFenceHandleTypeFlagBits));
}
@@ -8968,9 +9126,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_259;
- vkStream->read((uint64_t*)&cgen_var_259, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkFence(&cgen_var_259, (VkFence*)&forUnmarshaling->fence, 1);
+ uint64_t cgen_var_269;
+ vkStream->read((uint64_t*)&cgen_var_269, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkFence(&cgen_var_269, (VkFence*)&forUnmarshaling->fence, 1);
vkStream->read((VkExternalFenceHandleTypeFlagBits*)&forUnmarshaling->handleType, sizeof(VkExternalFenceHandleTypeFlagBits));
}
@@ -8988,9 +9146,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_260;
- vkStream->handleMapping()->mapHandles_VkFence_u64(&forMarshaling->fence, &cgen_var_260, 1);
- vkStream->write((uint64_t*)&cgen_var_260, 1 * 8);
+ uint64_t cgen_var_270;
+ vkStream->handleMapping()->mapHandles_VkFence_u64(&forMarshaling->fence, &cgen_var_270, 1);
+ vkStream->write((uint64_t*)&cgen_var_270, 1 * 8);
vkStream->write((VkFenceImportFlags*)&forMarshaling->flags, sizeof(VkFenceImportFlags));
vkStream->write((VkExternalFenceHandleTypeFlagBits*)&forMarshaling->handleType, sizeof(VkExternalFenceHandleTypeFlagBits));
vkStream->write((int*)&forMarshaling->fd, sizeof(int));
@@ -9009,9 +9167,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_261;
- vkStream->read((uint64_t*)&cgen_var_261, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkFence(&cgen_var_261, (VkFence*)&forUnmarshaling->fence, 1);
+ uint64_t cgen_var_271;
+ vkStream->read((uint64_t*)&cgen_var_271, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkFence(&cgen_var_271, (VkFence*)&forUnmarshaling->fence, 1);
vkStream->read((VkFenceImportFlags*)&forUnmarshaling->flags, sizeof(VkFenceImportFlags));
vkStream->read((VkExternalFenceHandleTypeFlagBits*)&forUnmarshaling->handleType, sizeof(VkExternalFenceHandleTypeFlagBits));
vkStream->read((int*)&forUnmarshaling->fd, sizeof(int));
@@ -9029,9 +9187,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_262;
- vkStream->handleMapping()->mapHandles_VkFence_u64(&forMarshaling->fence, &cgen_var_262, 1);
- vkStream->write((uint64_t*)&cgen_var_262, 1 * 8);
+ uint64_t cgen_var_272;
+ vkStream->handleMapping()->mapHandles_VkFence_u64(&forMarshaling->fence, &cgen_var_272, 1);
+ vkStream->write((uint64_t*)&cgen_var_272, 1 * 8);
vkStream->write((VkExternalFenceHandleTypeFlagBits*)&forMarshaling->handleType, sizeof(VkExternalFenceHandleTypeFlagBits));
}
@@ -9048,9 +9206,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_263;
- vkStream->read((uint64_t*)&cgen_var_263, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkFence(&cgen_var_263, (VkFence*)&forUnmarshaling->fence, 1);
+ uint64_t cgen_var_273;
+ vkStream->read((uint64_t*)&cgen_var_273, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkFence(&cgen_var_273, (VkFence*)&forUnmarshaling->fence, 1);
vkStream->read((VkExternalFenceHandleTypeFlagBits*)&forUnmarshaling->handleType, sizeof(VkExternalFenceHandleTypeFlagBits));
}
@@ -9070,9 +9228,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_264;
- vkStream->handleMapping()->mapHandles_VkSurfaceKHR_u64(&forMarshaling->surface, &cgen_var_264, 1);
- vkStream->write((uint64_t*)&cgen_var_264, 1 * 8);
+ uint64_t cgen_var_274;
+ vkStream->handleMapping()->mapHandles_VkSurfaceKHR_u64(&forMarshaling->surface, &cgen_var_274, 1);
+ vkStream->write((uint64_t*)&cgen_var_274, 1 * 8);
}
void unmarshal_VkPhysicalDeviceSurfaceInfo2KHR(
@@ -9088,9 +9246,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_265;
- vkStream->read((uint64_t*)&cgen_var_265, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkSurfaceKHR(&cgen_var_265, (VkSurfaceKHR*)&forUnmarshaling->surface, 1);
+ uint64_t cgen_var_275;
+ vkStream->read((uint64_t*)&cgen_var_275, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkSurfaceKHR(&cgen_var_275, (VkSurfaceKHR*)&forUnmarshaling->surface, 1);
}
void marshal_VkSurfaceCapabilities2KHR(
@@ -9264,9 +9422,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_266;
- vkStream->handleMapping()->mapHandles_VkDisplayModeKHR_u64(&forMarshaling->mode, &cgen_var_266, 1);
- vkStream->write((uint64_t*)&cgen_var_266, 1 * 8);
+ uint64_t cgen_var_276;
+ vkStream->handleMapping()->mapHandles_VkDisplayModeKHR_u64(&forMarshaling->mode, &cgen_var_276, 1);
+ vkStream->write((uint64_t*)&cgen_var_276, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->planeIndex, sizeof(uint32_t));
}
@@ -9283,9 +9441,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_267;
- vkStream->read((uint64_t*)&cgen_var_267, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDisplayModeKHR(&cgen_var_267, (VkDisplayModeKHR*)&forUnmarshaling->mode, 1);
+ uint64_t cgen_var_277;
+ vkStream->read((uint64_t*)&cgen_var_277, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDisplayModeKHR(&cgen_var_277, (VkDisplayModeKHR*)&forUnmarshaling->mode, 1);
vkStream->read((uint32_t*)&forUnmarshaling->planeIndex, sizeof(uint32_t));
}
@@ -9423,8 +9581,8 @@
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
// WARNING PTR CHECK
- uint64_t cgen_var_268 = (uint64_t)(uintptr_t)forMarshaling->handle;
- vkStream->putBe64(cgen_var_268);
+ uint64_t cgen_var_278 = (uint64_t)(uintptr_t)forMarshaling->handle;
+ vkStream->putBe64(cgen_var_278);
if (forMarshaling->handle)
{
vkStream->write((const uint32_t*)forMarshaling->handle, sizeof(const uint32_t));
@@ -9482,11 +9640,11 @@
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
vkStream->write((VkDebugReportFlagsEXT*)&forMarshaling->flags, sizeof(VkDebugReportFlagsEXT));
- uint64_t cgen_var_270 = (uint64_t)forMarshaling->pfnCallback;
- vkStream->putBe64(cgen_var_270);
+ uint64_t cgen_var_280 = (uint64_t)forMarshaling->pfnCallback;
+ vkStream->putBe64(cgen_var_280);
// WARNING PTR CHECK
- uint64_t cgen_var_271 = (uint64_t)(uintptr_t)forMarshaling->pUserData;
- vkStream->putBe64(cgen_var_271);
+ uint64_t cgen_var_281 = (uint64_t)(uintptr_t)forMarshaling->pUserData;
+ vkStream->putBe64(cgen_var_281);
if (forMarshaling->pUserData)
{
vkStream->write((void*)forMarshaling->pUserData, sizeof(uint8_t));
@@ -9616,8 +9774,8 @@
vkStream->write((VkDebugReportObjectTypeEXT*)&forMarshaling->objectType, sizeof(VkDebugReportObjectTypeEXT));
vkStream->write((uint64_t*)&forMarshaling->object, sizeof(uint64_t));
vkStream->write((uint64_t*)&forMarshaling->tagName, sizeof(uint64_t));
- uint64_t cgen_var_274 = (uint64_t)forMarshaling->tagSize;
- vkStream->putBe64(cgen_var_274);
+ uint64_t cgen_var_284 = (uint64_t)forMarshaling->tagSize;
+ vkStream->putBe64(cgen_var_284);
vkStream->write((const void*)forMarshaling->pTag, forMarshaling->tagSize * sizeof(const uint8_t));
}
@@ -9752,12 +9910,12 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_276;
- vkStream->handleMapping()->mapHandles_VkImage_u64(&forMarshaling->image, &cgen_var_276, 1);
- vkStream->write((uint64_t*)&cgen_var_276, 1 * 8);
- uint64_t cgen_var_277;
- vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_277, 1);
- vkStream->write((uint64_t*)&cgen_var_277, 1 * 8);
+ uint64_t cgen_var_286;
+ vkStream->handleMapping()->mapHandles_VkImage_u64(&forMarshaling->image, &cgen_var_286, 1);
+ vkStream->write((uint64_t*)&cgen_var_286, 1 * 8);
+ uint64_t cgen_var_287;
+ vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_287, 1);
+ vkStream->write((uint64_t*)&cgen_var_287, 1 * 8);
}
void unmarshal_VkDedicatedAllocationMemoryAllocateInfoNV(
@@ -9773,12 +9931,12 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_278;
- vkStream->read((uint64_t*)&cgen_var_278, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkImage(&cgen_var_278, (VkImage*)&forUnmarshaling->image, 1);
- uint64_t cgen_var_279;
- vkStream->read((uint64_t*)&cgen_var_279, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_279, (VkBuffer*)&forUnmarshaling->buffer, 1);
+ uint64_t cgen_var_288;
+ vkStream->read((uint64_t*)&cgen_var_288, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkImage(&cgen_var_288, (VkImage*)&forUnmarshaling->image, 1);
+ uint64_t cgen_var_289;
+ vkStream->read((uint64_t*)&cgen_var_289, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_289, (VkBuffer*)&forUnmarshaling->buffer, 1);
}
#endif
@@ -9831,10 +9989,10 @@
vkStream->write((uint32_t*)&forMarshaling->numUsedVgprs, sizeof(uint32_t));
vkStream->write((uint32_t*)&forMarshaling->numUsedSgprs, sizeof(uint32_t));
vkStream->write((uint32_t*)&forMarshaling->ldsSizePerLocalWorkGroup, sizeof(uint32_t));
- uint64_t cgen_var_280 = (uint64_t)forMarshaling->ldsUsageSizeInBytes;
- vkStream->putBe64(cgen_var_280);
- uint64_t cgen_var_281 = (uint64_t)forMarshaling->scratchMemUsageInBytes;
- vkStream->putBe64(cgen_var_281);
+ uint64_t cgen_var_290 = (uint64_t)forMarshaling->ldsUsageSizeInBytes;
+ vkStream->putBe64(cgen_var_290);
+ uint64_t cgen_var_291 = (uint64_t)forMarshaling->scratchMemUsageInBytes;
+ vkStream->putBe64(cgen_var_291);
}
void unmarshal_VkShaderResourceUsageAMD(
@@ -10012,8 +10170,8 @@
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
// WARNING PTR CHECK
- uint64_t cgen_var_284 = (uint64_t)(uintptr_t)forMarshaling->pAttributes;
- vkStream->putBe64(cgen_var_284);
+ uint64_t cgen_var_294 = (uint64_t)(uintptr_t)forMarshaling->pAttributes;
+ vkStream->putBe64(cgen_var_294);
if (forMarshaling->pAttributes)
{
vkStream->write((const SECURITY_ATTRIBUTES*)forMarshaling->pAttributes, sizeof(const SECURITY_ATTRIBUTES));
@@ -10065,20 +10223,20 @@
vkStream->write((uint32_t*)&forMarshaling->acquireCount, sizeof(uint32_t));
if (forMarshaling->acquireCount)
{
- uint64_t* cgen_var_286;
- vkStream->alloc((void**)&cgen_var_286, forMarshaling->acquireCount * 8);
- vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(forMarshaling->pAcquireSyncs, cgen_var_286, forMarshaling->acquireCount);
- vkStream->write((uint64_t*)cgen_var_286, forMarshaling->acquireCount * 8);
+ uint64_t* cgen_var_296;
+ vkStream->alloc((void**)&cgen_var_296, forMarshaling->acquireCount * 8);
+ vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(forMarshaling->pAcquireSyncs, cgen_var_296, forMarshaling->acquireCount);
+ vkStream->write((uint64_t*)cgen_var_296, forMarshaling->acquireCount * 8);
}
vkStream->write((const uint64_t*)forMarshaling->pAcquireKeys, forMarshaling->acquireCount * sizeof(const uint64_t));
vkStream->write((const uint32_t*)forMarshaling->pAcquireTimeoutMilliseconds, forMarshaling->acquireCount * sizeof(const uint32_t));
vkStream->write((uint32_t*)&forMarshaling->releaseCount, sizeof(uint32_t));
if (forMarshaling->releaseCount)
{
- uint64_t* cgen_var_287;
- vkStream->alloc((void**)&cgen_var_287, forMarshaling->releaseCount * 8);
- vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(forMarshaling->pReleaseSyncs, cgen_var_287, forMarshaling->releaseCount);
- vkStream->write((uint64_t*)cgen_var_287, forMarshaling->releaseCount * 8);
+ uint64_t* cgen_var_297;
+ vkStream->alloc((void**)&cgen_var_297, forMarshaling->releaseCount * 8);
+ vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(forMarshaling->pReleaseSyncs, cgen_var_297, forMarshaling->releaseCount);
+ vkStream->write((uint64_t*)cgen_var_297, forMarshaling->releaseCount * 8);
}
vkStream->write((const uint64_t*)forMarshaling->pReleaseKeys, forMarshaling->releaseCount * sizeof(const uint64_t));
}
@@ -10099,20 +10257,20 @@
vkStream->read((uint32_t*)&forUnmarshaling->acquireCount, sizeof(uint32_t));
if (forUnmarshaling->acquireCount)
{
- uint64_t* cgen_var_288;
- vkStream->alloc((void**)&cgen_var_288, forUnmarshaling->acquireCount * 8);
- vkStream->read((uint64_t*)cgen_var_288, forUnmarshaling->acquireCount * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(cgen_var_288, (VkDeviceMemory*)forUnmarshaling->pAcquireSyncs, forUnmarshaling->acquireCount);
+ uint64_t* cgen_var_298;
+ vkStream->alloc((void**)&cgen_var_298, forUnmarshaling->acquireCount * 8);
+ vkStream->read((uint64_t*)cgen_var_298, forUnmarshaling->acquireCount * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(cgen_var_298, (VkDeviceMemory*)forUnmarshaling->pAcquireSyncs, forUnmarshaling->acquireCount);
}
vkStream->read((uint64_t*)forUnmarshaling->pAcquireKeys, forUnmarshaling->acquireCount * sizeof(const uint64_t));
vkStream->read((uint32_t*)forUnmarshaling->pAcquireTimeoutMilliseconds, forUnmarshaling->acquireCount * sizeof(const uint32_t));
vkStream->read((uint32_t*)&forUnmarshaling->releaseCount, sizeof(uint32_t));
if (forUnmarshaling->releaseCount)
{
- uint64_t* cgen_var_289;
- vkStream->alloc((void**)&cgen_var_289, forUnmarshaling->releaseCount * 8);
- vkStream->read((uint64_t*)cgen_var_289, forUnmarshaling->releaseCount * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(cgen_var_289, (VkDeviceMemory*)forUnmarshaling->pReleaseSyncs, forUnmarshaling->releaseCount);
+ uint64_t* cgen_var_299;
+ vkStream->alloc((void**)&cgen_var_299, forUnmarshaling->releaseCount * 8);
+ vkStream->read((uint64_t*)cgen_var_299, forUnmarshaling->releaseCount * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(cgen_var_299, (VkDeviceMemory*)forUnmarshaling->pReleaseSyncs, forUnmarshaling->releaseCount);
}
vkStream->read((uint64_t*)forUnmarshaling->pReleaseKeys, forUnmarshaling->releaseCount * sizeof(const uint64_t));
}
@@ -10168,8 +10326,8 @@
}
vkStream->write((VkViSurfaceCreateFlagsNN*)&forMarshaling->flags, sizeof(VkViSurfaceCreateFlagsNN));
// WARNING PTR CHECK
- uint64_t cgen_var_290 = (uint64_t)(uintptr_t)forMarshaling->window;
- vkStream->putBe64(cgen_var_290);
+ uint64_t cgen_var_300 = (uint64_t)(uintptr_t)forMarshaling->window;
+ vkStream->putBe64(cgen_var_300);
if (forMarshaling->window)
{
vkStream->write((void*)forMarshaling->window, sizeof(uint8_t));
@@ -10221,9 +10379,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_292;
- vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_292, 1);
- vkStream->write((uint64_t*)&cgen_var_292, 1 * 8);
+ uint64_t cgen_var_302;
+ vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_302, 1);
+ vkStream->write((uint64_t*)&cgen_var_302, 1 * 8);
vkStream->write((VkDeviceSize*)&forMarshaling->offset, sizeof(VkDeviceSize));
vkStream->write((VkConditionalRenderingFlagsEXT*)&forMarshaling->flags, sizeof(VkConditionalRenderingFlagsEXT));
}
@@ -10241,9 +10399,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_293;
- vkStream->read((uint64_t*)&cgen_var_293, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_293, (VkBuffer*)&forUnmarshaling->buffer, 1);
+ uint64_t cgen_var_303;
+ vkStream->read((uint64_t*)&cgen_var_303, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_303, (VkBuffer*)&forUnmarshaling->buffer, 1);
vkStream->read((VkDeviceSize*)&forUnmarshaling->offset, sizeof(VkDeviceSize));
vkStream->read((VkConditionalRenderingFlagsEXT*)&forUnmarshaling->flags, sizeof(VkConditionalRenderingFlagsEXT));
}
@@ -10389,9 +10547,9 @@
const VkIndirectCommandsTokenNVX* forMarshaling)
{
vkStream->write((VkIndirectCommandsTokenTypeNVX*)&forMarshaling->tokenType, sizeof(VkIndirectCommandsTokenTypeNVX));
- uint64_t cgen_var_294;
- vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_294, 1);
- vkStream->write((uint64_t*)&cgen_var_294, 1 * 8);
+ uint64_t cgen_var_304;
+ vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_304, 1);
+ vkStream->write((uint64_t*)&cgen_var_304, 1 * 8);
vkStream->write((VkDeviceSize*)&forMarshaling->offset, sizeof(VkDeviceSize));
}
@@ -10400,9 +10558,9 @@
VkIndirectCommandsTokenNVX* forUnmarshaling)
{
vkStream->read((VkIndirectCommandsTokenTypeNVX*)&forUnmarshaling->tokenType, sizeof(VkIndirectCommandsTokenTypeNVX));
- uint64_t cgen_var_295;
- vkStream->read((uint64_t*)&cgen_var_295, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_295, (VkBuffer*)&forUnmarshaling->buffer, 1);
+ uint64_t cgen_var_305;
+ vkStream->read((uint64_t*)&cgen_var_305, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_305, (VkBuffer*)&forUnmarshaling->buffer, 1);
vkStream->read((VkDeviceSize*)&forUnmarshaling->offset, sizeof(VkDeviceSize));
}
@@ -10481,28 +10639,28 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_296;
- vkStream->handleMapping()->mapHandles_VkObjectTableNVX_u64(&forMarshaling->objectTable, &cgen_var_296, 1);
- vkStream->write((uint64_t*)&cgen_var_296, 1 * 8);
- uint64_t cgen_var_297;
- vkStream->handleMapping()->mapHandles_VkIndirectCommandsLayoutNVX_u64(&forMarshaling->indirectCommandsLayout, &cgen_var_297, 1);
- vkStream->write((uint64_t*)&cgen_var_297, 1 * 8);
+ uint64_t cgen_var_306;
+ vkStream->handleMapping()->mapHandles_VkObjectTableNVX_u64(&forMarshaling->objectTable, &cgen_var_306, 1);
+ vkStream->write((uint64_t*)&cgen_var_306, 1 * 8);
+ uint64_t cgen_var_307;
+ vkStream->handleMapping()->mapHandles_VkIndirectCommandsLayoutNVX_u64(&forMarshaling->indirectCommandsLayout, &cgen_var_307, 1);
+ vkStream->write((uint64_t*)&cgen_var_307, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->indirectCommandsTokenCount, sizeof(uint32_t));
for (uint32_t i = 0; i < (uint32_t)forMarshaling->indirectCommandsTokenCount; ++i)
{
marshal_VkIndirectCommandsTokenNVX(vkStream, (const VkIndirectCommandsTokenNVX*)(forMarshaling->pIndirectCommandsTokens + i));
}
vkStream->write((uint32_t*)&forMarshaling->maxSequencesCount, sizeof(uint32_t));
- uint64_t cgen_var_298;
- vkStream->handleMapping()->mapHandles_VkCommandBuffer_u64(&forMarshaling->targetCommandBuffer, &cgen_var_298, 1);
- vkStream->write((uint64_t*)&cgen_var_298, 1 * 8);
- uint64_t cgen_var_299;
- vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->sequencesCountBuffer, &cgen_var_299, 1);
- vkStream->write((uint64_t*)&cgen_var_299, 1 * 8);
+ uint64_t cgen_var_308;
+ vkStream->handleMapping()->mapHandles_VkCommandBuffer_u64(&forMarshaling->targetCommandBuffer, &cgen_var_308, 1);
+ vkStream->write((uint64_t*)&cgen_var_308, 1 * 8);
+ uint64_t cgen_var_309;
+ vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->sequencesCountBuffer, &cgen_var_309, 1);
+ vkStream->write((uint64_t*)&cgen_var_309, 1 * 8);
vkStream->write((VkDeviceSize*)&forMarshaling->sequencesCountOffset, sizeof(VkDeviceSize));
- uint64_t cgen_var_300;
- vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->sequencesIndexBuffer, &cgen_var_300, 1);
- vkStream->write((uint64_t*)&cgen_var_300, 1 * 8);
+ uint64_t cgen_var_310;
+ vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->sequencesIndexBuffer, &cgen_var_310, 1);
+ vkStream->write((uint64_t*)&cgen_var_310, 1 * 8);
vkStream->write((VkDeviceSize*)&forMarshaling->sequencesIndexOffset, sizeof(VkDeviceSize));
}
@@ -10519,28 +10677,28 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_301;
- vkStream->read((uint64_t*)&cgen_var_301, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkObjectTableNVX(&cgen_var_301, (VkObjectTableNVX*)&forUnmarshaling->objectTable, 1);
- uint64_t cgen_var_302;
- vkStream->read((uint64_t*)&cgen_var_302, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkIndirectCommandsLayoutNVX(&cgen_var_302, (VkIndirectCommandsLayoutNVX*)&forUnmarshaling->indirectCommandsLayout, 1);
+ uint64_t cgen_var_311;
+ vkStream->read((uint64_t*)&cgen_var_311, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkObjectTableNVX(&cgen_var_311, (VkObjectTableNVX*)&forUnmarshaling->objectTable, 1);
+ uint64_t cgen_var_312;
+ vkStream->read((uint64_t*)&cgen_var_312, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkIndirectCommandsLayoutNVX(&cgen_var_312, (VkIndirectCommandsLayoutNVX*)&forUnmarshaling->indirectCommandsLayout, 1);
vkStream->read((uint32_t*)&forUnmarshaling->indirectCommandsTokenCount, sizeof(uint32_t));
for (uint32_t i = 0; i < (uint32_t)forUnmarshaling->indirectCommandsTokenCount; ++i)
{
unmarshal_VkIndirectCommandsTokenNVX(vkStream, (VkIndirectCommandsTokenNVX*)(forUnmarshaling->pIndirectCommandsTokens + i));
}
vkStream->read((uint32_t*)&forUnmarshaling->maxSequencesCount, sizeof(uint32_t));
- uint64_t cgen_var_303;
- vkStream->read((uint64_t*)&cgen_var_303, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkCommandBuffer(&cgen_var_303, (VkCommandBuffer*)&forUnmarshaling->targetCommandBuffer, 1);
- uint64_t cgen_var_304;
- vkStream->read((uint64_t*)&cgen_var_304, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_304, (VkBuffer*)&forUnmarshaling->sequencesCountBuffer, 1);
+ uint64_t cgen_var_313;
+ vkStream->read((uint64_t*)&cgen_var_313, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkCommandBuffer(&cgen_var_313, (VkCommandBuffer*)&forUnmarshaling->targetCommandBuffer, 1);
+ uint64_t cgen_var_314;
+ vkStream->read((uint64_t*)&cgen_var_314, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_314, (VkBuffer*)&forUnmarshaling->sequencesCountBuffer, 1);
vkStream->read((VkDeviceSize*)&forUnmarshaling->sequencesCountOffset, sizeof(VkDeviceSize));
- uint64_t cgen_var_305;
- vkStream->read((uint64_t*)&cgen_var_305, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_305, (VkBuffer*)&forUnmarshaling->sequencesIndexBuffer, 1);
+ uint64_t cgen_var_315;
+ vkStream->read((uint64_t*)&cgen_var_315, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_315, (VkBuffer*)&forUnmarshaling->sequencesIndexBuffer, 1);
vkStream->read((VkDeviceSize*)&forUnmarshaling->sequencesIndexOffset, sizeof(VkDeviceSize));
}
@@ -10556,12 +10714,12 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_306;
- vkStream->handleMapping()->mapHandles_VkObjectTableNVX_u64(&forMarshaling->objectTable, &cgen_var_306, 1);
- vkStream->write((uint64_t*)&cgen_var_306, 1 * 8);
- uint64_t cgen_var_307;
- vkStream->handleMapping()->mapHandles_VkIndirectCommandsLayoutNVX_u64(&forMarshaling->indirectCommandsLayout, &cgen_var_307, 1);
- vkStream->write((uint64_t*)&cgen_var_307, 1 * 8);
+ uint64_t cgen_var_316;
+ vkStream->handleMapping()->mapHandles_VkObjectTableNVX_u64(&forMarshaling->objectTable, &cgen_var_316, 1);
+ vkStream->write((uint64_t*)&cgen_var_316, 1 * 8);
+ uint64_t cgen_var_317;
+ vkStream->handleMapping()->mapHandles_VkIndirectCommandsLayoutNVX_u64(&forMarshaling->indirectCommandsLayout, &cgen_var_317, 1);
+ vkStream->write((uint64_t*)&cgen_var_317, 1 * 8);
vkStream->write((uint32_t*)&forMarshaling->maxSequencesCount, sizeof(uint32_t));
}
@@ -10578,12 +10736,12 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_308;
- vkStream->read((uint64_t*)&cgen_var_308, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkObjectTableNVX(&cgen_var_308, (VkObjectTableNVX*)&forUnmarshaling->objectTable, 1);
- uint64_t cgen_var_309;
- vkStream->read((uint64_t*)&cgen_var_309, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkIndirectCommandsLayoutNVX(&cgen_var_309, (VkIndirectCommandsLayoutNVX*)&forUnmarshaling->indirectCommandsLayout, 1);
+ uint64_t cgen_var_318;
+ vkStream->read((uint64_t*)&cgen_var_318, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkObjectTableNVX(&cgen_var_318, (VkObjectTableNVX*)&forUnmarshaling->objectTable, 1);
+ uint64_t cgen_var_319;
+ vkStream->read((uint64_t*)&cgen_var_319, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkIndirectCommandsLayoutNVX(&cgen_var_319, (VkIndirectCommandsLayoutNVX*)&forUnmarshaling->indirectCommandsLayout, 1);
vkStream->read((uint32_t*)&forUnmarshaling->maxSequencesCount, sizeof(uint32_t));
}
@@ -10656,9 +10814,9 @@
{
vkStream->write((VkObjectEntryTypeNVX*)&forMarshaling->type, sizeof(VkObjectEntryTypeNVX));
vkStream->write((VkObjectEntryUsageFlagsNVX*)&forMarshaling->flags, sizeof(VkObjectEntryUsageFlagsNVX));
- uint64_t cgen_var_310;
- vkStream->handleMapping()->mapHandles_VkPipeline_u64(&forMarshaling->pipeline, &cgen_var_310, 1);
- vkStream->write((uint64_t*)&cgen_var_310, 1 * 8);
+ uint64_t cgen_var_320;
+ vkStream->handleMapping()->mapHandles_VkPipeline_u64(&forMarshaling->pipeline, &cgen_var_320, 1);
+ vkStream->write((uint64_t*)&cgen_var_320, 1 * 8);
}
void unmarshal_VkObjectTablePipelineEntryNVX(
@@ -10667,9 +10825,9 @@
{
vkStream->read((VkObjectEntryTypeNVX*)&forUnmarshaling->type, sizeof(VkObjectEntryTypeNVX));
vkStream->read((VkObjectEntryUsageFlagsNVX*)&forUnmarshaling->flags, sizeof(VkObjectEntryUsageFlagsNVX));
- uint64_t cgen_var_311;
- vkStream->read((uint64_t*)&cgen_var_311, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkPipeline(&cgen_var_311, (VkPipeline*)&forUnmarshaling->pipeline, 1);
+ uint64_t cgen_var_321;
+ vkStream->read((uint64_t*)&cgen_var_321, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkPipeline(&cgen_var_321, (VkPipeline*)&forUnmarshaling->pipeline, 1);
}
void marshal_VkObjectTableDescriptorSetEntryNVX(
@@ -10678,12 +10836,12 @@
{
vkStream->write((VkObjectEntryTypeNVX*)&forMarshaling->type, sizeof(VkObjectEntryTypeNVX));
vkStream->write((VkObjectEntryUsageFlagsNVX*)&forMarshaling->flags, sizeof(VkObjectEntryUsageFlagsNVX));
- uint64_t cgen_var_312;
- vkStream->handleMapping()->mapHandles_VkPipelineLayout_u64(&forMarshaling->pipelineLayout, &cgen_var_312, 1);
- vkStream->write((uint64_t*)&cgen_var_312, 1 * 8);
- uint64_t cgen_var_313;
- vkStream->handleMapping()->mapHandles_VkDescriptorSet_u64(&forMarshaling->descriptorSet, &cgen_var_313, 1);
- vkStream->write((uint64_t*)&cgen_var_313, 1 * 8);
+ uint64_t cgen_var_322;
+ vkStream->handleMapping()->mapHandles_VkPipelineLayout_u64(&forMarshaling->pipelineLayout, &cgen_var_322, 1);
+ vkStream->write((uint64_t*)&cgen_var_322, 1 * 8);
+ uint64_t cgen_var_323;
+ vkStream->handleMapping()->mapHandles_VkDescriptorSet_u64(&forMarshaling->descriptorSet, &cgen_var_323, 1);
+ vkStream->write((uint64_t*)&cgen_var_323, 1 * 8);
}
void unmarshal_VkObjectTableDescriptorSetEntryNVX(
@@ -10692,12 +10850,12 @@
{
vkStream->read((VkObjectEntryTypeNVX*)&forUnmarshaling->type, sizeof(VkObjectEntryTypeNVX));
vkStream->read((VkObjectEntryUsageFlagsNVX*)&forUnmarshaling->flags, sizeof(VkObjectEntryUsageFlagsNVX));
- uint64_t cgen_var_314;
- vkStream->read((uint64_t*)&cgen_var_314, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkPipelineLayout(&cgen_var_314, (VkPipelineLayout*)&forUnmarshaling->pipelineLayout, 1);
- uint64_t cgen_var_315;
- vkStream->read((uint64_t*)&cgen_var_315, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDescriptorSet(&cgen_var_315, (VkDescriptorSet*)&forUnmarshaling->descriptorSet, 1);
+ uint64_t cgen_var_324;
+ vkStream->read((uint64_t*)&cgen_var_324, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkPipelineLayout(&cgen_var_324, (VkPipelineLayout*)&forUnmarshaling->pipelineLayout, 1);
+ uint64_t cgen_var_325;
+ vkStream->read((uint64_t*)&cgen_var_325, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDescriptorSet(&cgen_var_325, (VkDescriptorSet*)&forUnmarshaling->descriptorSet, 1);
}
void marshal_VkObjectTableVertexBufferEntryNVX(
@@ -10706,9 +10864,9 @@
{
vkStream->write((VkObjectEntryTypeNVX*)&forMarshaling->type, sizeof(VkObjectEntryTypeNVX));
vkStream->write((VkObjectEntryUsageFlagsNVX*)&forMarshaling->flags, sizeof(VkObjectEntryUsageFlagsNVX));
- uint64_t cgen_var_316;
- vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_316, 1);
- vkStream->write((uint64_t*)&cgen_var_316, 1 * 8);
+ uint64_t cgen_var_326;
+ vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_326, 1);
+ vkStream->write((uint64_t*)&cgen_var_326, 1 * 8);
}
void unmarshal_VkObjectTableVertexBufferEntryNVX(
@@ -10717,9 +10875,9 @@
{
vkStream->read((VkObjectEntryTypeNVX*)&forUnmarshaling->type, sizeof(VkObjectEntryTypeNVX));
vkStream->read((VkObjectEntryUsageFlagsNVX*)&forUnmarshaling->flags, sizeof(VkObjectEntryUsageFlagsNVX));
- uint64_t cgen_var_317;
- vkStream->read((uint64_t*)&cgen_var_317, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_317, (VkBuffer*)&forUnmarshaling->buffer, 1);
+ uint64_t cgen_var_327;
+ vkStream->read((uint64_t*)&cgen_var_327, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_327, (VkBuffer*)&forUnmarshaling->buffer, 1);
}
void marshal_VkObjectTableIndexBufferEntryNVX(
@@ -10728,9 +10886,9 @@
{
vkStream->write((VkObjectEntryTypeNVX*)&forMarshaling->type, sizeof(VkObjectEntryTypeNVX));
vkStream->write((VkObjectEntryUsageFlagsNVX*)&forMarshaling->flags, sizeof(VkObjectEntryUsageFlagsNVX));
- uint64_t cgen_var_318;
- vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_318, 1);
- vkStream->write((uint64_t*)&cgen_var_318, 1 * 8);
+ uint64_t cgen_var_328;
+ vkStream->handleMapping()->mapHandles_VkBuffer_u64(&forMarshaling->buffer, &cgen_var_328, 1);
+ vkStream->write((uint64_t*)&cgen_var_328, 1 * 8);
vkStream->write((VkIndexType*)&forMarshaling->indexType, sizeof(VkIndexType));
}
@@ -10740,9 +10898,9 @@
{
vkStream->read((VkObjectEntryTypeNVX*)&forUnmarshaling->type, sizeof(VkObjectEntryTypeNVX));
vkStream->read((VkObjectEntryUsageFlagsNVX*)&forUnmarshaling->flags, sizeof(VkObjectEntryUsageFlagsNVX));
- uint64_t cgen_var_319;
- vkStream->read((uint64_t*)&cgen_var_319, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_319, (VkBuffer*)&forUnmarshaling->buffer, 1);
+ uint64_t cgen_var_329;
+ vkStream->read((uint64_t*)&cgen_var_329, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkBuffer(&cgen_var_329, (VkBuffer*)&forUnmarshaling->buffer, 1);
vkStream->read((VkIndexType*)&forUnmarshaling->indexType, sizeof(VkIndexType));
}
@@ -10752,9 +10910,9 @@
{
vkStream->write((VkObjectEntryTypeNVX*)&forMarshaling->type, sizeof(VkObjectEntryTypeNVX));
vkStream->write((VkObjectEntryUsageFlagsNVX*)&forMarshaling->flags, sizeof(VkObjectEntryUsageFlagsNVX));
- uint64_t cgen_var_320;
- vkStream->handleMapping()->mapHandles_VkPipelineLayout_u64(&forMarshaling->pipelineLayout, &cgen_var_320, 1);
- vkStream->write((uint64_t*)&cgen_var_320, 1 * 8);
+ uint64_t cgen_var_330;
+ vkStream->handleMapping()->mapHandles_VkPipelineLayout_u64(&forMarshaling->pipelineLayout, &cgen_var_330, 1);
+ vkStream->write((uint64_t*)&cgen_var_330, 1 * 8);
vkStream->write((VkShaderStageFlags*)&forMarshaling->stageFlags, sizeof(VkShaderStageFlags));
}
@@ -10764,9 +10922,9 @@
{
vkStream->read((VkObjectEntryTypeNVX*)&forUnmarshaling->type, sizeof(VkObjectEntryTypeNVX));
vkStream->read((VkObjectEntryUsageFlagsNVX*)&forUnmarshaling->flags, sizeof(VkObjectEntryUsageFlagsNVX));
- uint64_t cgen_var_321;
- vkStream->read((uint64_t*)&cgen_var_321, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkPipelineLayout(&cgen_var_321, (VkPipelineLayout*)&forUnmarshaling->pipelineLayout, 1);
+ uint64_t cgen_var_331;
+ vkStream->read((uint64_t*)&cgen_var_331, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkPipelineLayout(&cgen_var_331, (VkPipelineLayout*)&forUnmarshaling->pipelineLayout, 1);
vkStream->read((VkShaderStageFlags*)&forUnmarshaling->stageFlags, sizeof(VkShaderStageFlags));
}
@@ -10803,8 +10961,8 @@
vkStream->write((VkBool32*)&forMarshaling->viewportWScalingEnable, sizeof(VkBool32));
vkStream->write((uint32_t*)&forMarshaling->viewportCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_322 = (uint64_t)(uintptr_t)forMarshaling->pViewportWScalings;
- vkStream->putBe64(cgen_var_322);
+ uint64_t cgen_var_332 = (uint64_t)(uintptr_t)forMarshaling->pViewportWScalings;
+ vkStream->putBe64(cgen_var_332);
if (forMarshaling->pViewportWScalings)
{
for (uint32_t i = 0; i < (uint32_t)forMarshaling->viewportCount; ++i)
@@ -11096,8 +11254,8 @@
}
vkStream->write((uint32_t*)&forMarshaling->swapchainCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_324 = (uint64_t)(uintptr_t)forMarshaling->pTimes;
- vkStream->putBe64(cgen_var_324);
+ uint64_t cgen_var_334 = (uint64_t)(uintptr_t)forMarshaling->pTimes;
+ vkStream->putBe64(cgen_var_334);
if (forMarshaling->pTimes)
{
for (uint32_t i = 0; i < (uint32_t)forMarshaling->swapchainCount; ++i)
@@ -11213,8 +11371,8 @@
vkStream->write((VkPipelineViewportSwizzleStateCreateFlagsNV*)&forMarshaling->flags, sizeof(VkPipelineViewportSwizzleStateCreateFlagsNV));
vkStream->write((uint32_t*)&forMarshaling->viewportCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_326 = (uint64_t)(uintptr_t)forMarshaling->pViewportSwizzles;
- vkStream->putBe64(cgen_var_326);
+ uint64_t cgen_var_336 = (uint64_t)(uintptr_t)forMarshaling->pViewportSwizzles;
+ vkStream->putBe64(cgen_var_336);
if (forMarshaling->pViewportSwizzles)
{
for (uint32_t i = 0; i < (uint32_t)forMarshaling->viewportCount; ++i)
@@ -11304,8 +11462,8 @@
vkStream->write((VkDiscardRectangleModeEXT*)&forMarshaling->discardRectangleMode, sizeof(VkDiscardRectangleModeEXT));
vkStream->write((uint32_t*)&forMarshaling->discardRectangleCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_328 = (uint64_t)(uintptr_t)forMarshaling->pDiscardRectangles;
- vkStream->putBe64(cgen_var_328);
+ uint64_t cgen_var_338 = (uint64_t)(uintptr_t)forMarshaling->pDiscardRectangles;
+ vkStream->putBe64(cgen_var_338);
if (forMarshaling->pDiscardRectangles)
{
for (uint32_t i = 0; i < (uint32_t)forMarshaling->discardRectangleCount; ++i)
@@ -11512,8 +11670,8 @@
}
vkStream->write((VkIOSSurfaceCreateFlagsMVK*)&forMarshaling->flags, sizeof(VkIOSSurfaceCreateFlagsMVK));
// WARNING PTR CHECK
- uint64_t cgen_var_330 = (uint64_t)(uintptr_t)forMarshaling->pView;
- vkStream->putBe64(cgen_var_330);
+ uint64_t cgen_var_340 = (uint64_t)(uintptr_t)forMarshaling->pView;
+ vkStream->putBe64(cgen_var_340);
if (forMarshaling->pView)
{
vkStream->write((const void*)forMarshaling->pView, sizeof(const uint8_t));
@@ -11563,8 +11721,8 @@
}
vkStream->write((VkMacOSSurfaceCreateFlagsMVK*)&forMarshaling->flags, sizeof(VkMacOSSurfaceCreateFlagsMVK));
// WARNING PTR CHECK
- uint64_t cgen_var_332 = (uint64_t)(uintptr_t)forMarshaling->pView;
- vkStream->putBe64(cgen_var_332);
+ uint64_t cgen_var_342 = (uint64_t)(uintptr_t)forMarshaling->pView;
+ vkStream->putBe64(cgen_var_342);
if (forMarshaling->pView)
{
vkStream->write((const void*)forMarshaling->pView, sizeof(const uint8_t));
@@ -11621,8 +11779,8 @@
if (vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_NULL_OPTIONAL_STRINGS_BIT)
{
// WARNING PTR CHECK
- uint64_t cgen_var_334 = (uint64_t)(uintptr_t)forMarshaling->pObjectName;
- vkStream->putBe64(cgen_var_334);
+ uint64_t cgen_var_344 = (uint64_t)(uintptr_t)forMarshaling->pObjectName;
+ vkStream->putBe64(cgen_var_344);
if (forMarshaling->pObjectName)
{
vkStream->putString(forMarshaling->pObjectName);
@@ -11684,8 +11842,8 @@
vkStream->write((VkObjectType*)&forMarshaling->objectType, sizeof(VkObjectType));
vkStream->write((uint64_t*)&forMarshaling->objectHandle, sizeof(uint64_t));
vkStream->write((uint64_t*)&forMarshaling->tagName, sizeof(uint64_t));
- uint64_t cgen_var_336 = (uint64_t)forMarshaling->tagSize;
- vkStream->putBe64(cgen_var_336);
+ uint64_t cgen_var_346 = (uint64_t)forMarshaling->tagSize;
+ vkStream->putBe64(cgen_var_346);
vkStream->write((const void*)forMarshaling->pTag, forMarshaling->tagSize * sizeof(const uint8_t));
}
@@ -11758,8 +11916,8 @@
if (vkStream->getFeatureBits() & VULKAN_STREAM_FEATURE_NULL_OPTIONAL_STRINGS_BIT)
{
// WARNING PTR CHECK
- uint64_t cgen_var_338 = (uint64_t)(uintptr_t)forMarshaling->pMessageIdName;
- vkStream->putBe64(cgen_var_338);
+ uint64_t cgen_var_348 = (uint64_t)(uintptr_t)forMarshaling->pMessageIdName;
+ vkStream->putBe64(cgen_var_348);
if (forMarshaling->pMessageIdName)
{
vkStream->putString(forMarshaling->pMessageIdName);
@@ -11773,8 +11931,8 @@
vkStream->putString(forMarshaling->pMessage);
vkStream->write((uint32_t*)&forMarshaling->queueLabelCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_339 = (uint64_t)(uintptr_t)forMarshaling->pQueueLabels;
- vkStream->putBe64(cgen_var_339);
+ uint64_t cgen_var_349 = (uint64_t)(uintptr_t)forMarshaling->pQueueLabels;
+ vkStream->putBe64(cgen_var_349);
if (forMarshaling->pQueueLabels)
{
for (uint32_t i = 0; i < (uint32_t)forMarshaling->queueLabelCount; ++i)
@@ -11784,8 +11942,8 @@
}
vkStream->write((uint32_t*)&forMarshaling->cmdBufLabelCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_340 = (uint64_t)(uintptr_t)forMarshaling->pCmdBufLabels;
- vkStream->putBe64(cgen_var_340);
+ uint64_t cgen_var_350 = (uint64_t)(uintptr_t)forMarshaling->pCmdBufLabels;
+ vkStream->putBe64(cgen_var_350);
if (forMarshaling->pCmdBufLabels)
{
for (uint32_t i = 0; i < (uint32_t)forMarshaling->cmdBufLabelCount; ++i)
@@ -11795,8 +11953,8 @@
}
vkStream->write((uint32_t*)&forMarshaling->objectCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_341 = (uint64_t)(uintptr_t)forMarshaling->pObjects;
- vkStream->putBe64(cgen_var_341);
+ uint64_t cgen_var_351 = (uint64_t)(uintptr_t)forMarshaling->pObjects;
+ vkStream->putBe64(cgen_var_351);
if (forMarshaling->pObjects)
{
for (uint32_t i = 0; i < (uint32_t)forMarshaling->objectCount; ++i)
@@ -11902,11 +12060,11 @@
vkStream->write((VkDebugUtilsMessengerCreateFlagsEXT*)&forMarshaling->flags, sizeof(VkDebugUtilsMessengerCreateFlagsEXT));
vkStream->write((VkDebugUtilsMessageSeverityFlagsEXT*)&forMarshaling->messageSeverity, sizeof(VkDebugUtilsMessageSeverityFlagsEXT));
vkStream->write((VkDebugUtilsMessageTypeFlagsEXT*)&forMarshaling->messageType, sizeof(VkDebugUtilsMessageTypeFlagsEXT));
- uint64_t cgen_var_346 = (uint64_t)forMarshaling->pfnUserCallback;
- vkStream->putBe64(cgen_var_346);
+ uint64_t cgen_var_356 = (uint64_t)forMarshaling->pfnUserCallback;
+ vkStream->putBe64(cgen_var_356);
// WARNING PTR CHECK
- uint64_t cgen_var_347 = (uint64_t)(uintptr_t)forMarshaling->pUserData;
- vkStream->putBe64(cgen_var_347);
+ uint64_t cgen_var_357 = (uint64_t)(uintptr_t)forMarshaling->pUserData;
+ vkStream->putBe64(cgen_var_357);
if (forMarshaling->pUserData)
{
vkStream->write((void*)forMarshaling->pUserData, sizeof(uint8_t));
@@ -12097,9 +12255,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_350;
- vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(&forMarshaling->memory, &cgen_var_350, 1);
- vkStream->write((uint64_t*)&cgen_var_350, 1 * 8);
+ uint64_t cgen_var_360;
+ vkStream->handleMapping()->mapHandles_VkDeviceMemory_u64(&forMarshaling->memory, &cgen_var_360, 1);
+ vkStream->write((uint64_t*)&cgen_var_360, 1 * 8);
}
void unmarshal_VkMemoryGetAndroidHardwareBufferInfoANDROID(
@@ -12115,9 +12273,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_351;
- vkStream->read((uint64_t*)&cgen_var_351, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(&cgen_var_351, (VkDeviceMemory*)&forUnmarshaling->memory, 1);
+ uint64_t cgen_var_361;
+ vkStream->read((uint64_t*)&cgen_var_361, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkDeviceMemory(&cgen_var_361, (VkDeviceMemory*)&forUnmarshaling->memory, 1);
}
void marshal_VkExternalFormatANDROID(
@@ -12635,8 +12793,8 @@
vkStream->write((VkBool32*)&forMarshaling->coverageModulationTableEnable, sizeof(VkBool32));
vkStream->write((uint32_t*)&forMarshaling->coverageModulationTableCount, sizeof(uint32_t));
// WARNING PTR CHECK
- uint64_t cgen_var_352 = (uint64_t)(uintptr_t)forMarshaling->pCoverageModulationTable;
- vkStream->putBe64(cgen_var_352);
+ uint64_t cgen_var_362 = (uint64_t)(uintptr_t)forMarshaling->pCoverageModulationTable;
+ vkStream->putBe64(cgen_var_362);
if (forMarshaling->pCoverageModulationTable)
{
vkStream->write((const float*)forMarshaling->pCoverageModulationTable, forMarshaling->coverageModulationTableCount * sizeof(const float));
@@ -12692,8 +12850,8 @@
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
vkStream->write((VkValidationCacheCreateFlagsEXT*)&forMarshaling->flags, sizeof(VkValidationCacheCreateFlagsEXT));
- uint64_t cgen_var_354 = (uint64_t)forMarshaling->initialDataSize;
- vkStream->putBe64(cgen_var_354);
+ uint64_t cgen_var_364 = (uint64_t)forMarshaling->initialDataSize;
+ vkStream->putBe64(cgen_var_364);
vkStream->write((const void*)forMarshaling->pInitialData, forMarshaling->initialDataSize * sizeof(const uint8_t));
}
@@ -12727,9 +12885,9 @@
vkStream->write((const void*)forMarshaling->pNext, sizeof(VkStructureType));
marshal_extension_struct(vkStream, forMarshaling->pNext);
}
- uint64_t cgen_var_356;
- vkStream->handleMapping()->mapHandles_VkValidationCacheEXT_u64(&forMarshaling->validationCache, &cgen_var_356, 1);
- vkStream->write((uint64_t*)&cgen_var_356, 1 * 8);
+ uint64_t cgen_var_366;
+ vkStream->handleMapping()->mapHandles_VkValidationCacheEXT_u64(&forMarshaling->validationCache, &cgen_var_366, 1);
+ vkStream->write((uint64_t*)&cgen_var_366, 1 * 8);
}
void unmarshal_VkShaderModuleValidationCacheCreateInfoEXT(
@@ -12745,9 +12903,9 @@
vkStream->read((void*)(&pNext_placeholder), sizeof(VkStructureType));
unmarshal_extension_struct(vkStream, (void*)(forUnmarshaling->pNext));
}
- uint64_t cgen_var_357;
- vkStream->read((uint64_t*)&cgen_var_357, 1 * 8);
- vkStream->handleMapping()->mapHandles_u64_VkValidationCacheEXT(&cgen_var_357, (VkValidationCacheEXT*)&forUnmarshaling->validationCache, 1);
+ uint64_t cgen_var_367;
+ vkStream->read((uint64_t*)&cgen_var_367, 1 * 8);
+ vkStream->handleMapping()->mapHandles_u64_VkValidationCacheEXT(&cgen_var_367, (VkValidationCacheEXT*)&forUnmarshaling->validationCache, 1);
}
#endif
@@ -13044,8 +13202,8 @@
}
vkStream->write((VkExternalMemoryHandleTypeFlagBits*)&forMarshaling->handleType, sizeof(VkExternalMemoryHandleTypeFlagBits));
// WARNING PTR CHECK
- uint64_t cgen_var_358 = (uint64_t)(uintptr_t)forMarshaling->pHostPointer;
- vkStream->putBe64(cgen_var_358);
+ uint64_t cgen_var_368 = (uint64_t)(uintptr_t)forMarshaling->pHostPointer;
+ vkStream->putBe64(cgen_var_368);
if (forMarshaling->pHostPointer)
{
vkStream->write((void*)forMarshaling->pHostPointer, sizeof(uint8_t));
@@ -13339,8 +13497,8 @@
}
vkStream->write((VkPipelineStageFlagBits*)&forMarshaling->stage, sizeof(VkPipelineStageFlagBits));
// WARNING PTR CHECK
- uint64_t cgen_var_360 = (uint64_t)(uintptr_t)forMarshaling->pCheckpointMarker;
- vkStream->putBe64(cgen_var_360);
+ uint64_t cgen_var_370 = (uint64_t)(uintptr_t)forMarshaling->pCheckpointMarker;
+ vkStream->putBe64(cgen_var_370);
if (forMarshaling->pCheckpointMarker)
{
vkStream->write((void*)forMarshaling->pCheckpointMarker, sizeof(uint8_t));
diff --git a/system/vulkan_enc/goldfish_vk_private_defs.h b/system/vulkan_enc/goldfish_vk_private_defs.h
index 21eb730..b967d89 100644
--- a/system/vulkan_enc/goldfish_vk_private_defs.h
+++ b/system/vulkan_enc/goldfish_vk_private_defs.h
@@ -17,6 +17,7 @@
#include <vulkan/vulkan.h>
#ifdef __cplusplus
+#include <algorithm>
extern "C" {
#endif
@@ -534,9 +535,20 @@
// VulkanStream features
#define VULKAN_STREAM_FEATURE_NULL_OPTIONAL_STRINGS_BIT (1 << 0)
+#define VULKAN_STREAM_FEATURE_IGNORED_HANDLES_BIT (1 << 1)
#define VK_YCBCR_CONVERSION_DO_NOTHING ((VkSamplerYcbcrConversion)0x1111111111111111)
#ifdef __cplusplus
} // extern "C"
#endif
+
+#ifdef __cplusplus
+
+template<class T, typename F>
+bool arrayany(const T* arr, uint32_t begin, uint32_t end, const F& func) {
+ const T* e = arr + end;
+ return std::find_if(arr + begin, e, func) != e;
+}
+
+#endif
diff --git a/system/vulkan_enc/vk_format_info.h b/system/vulkan_enc/vk_format_info.h
index c517cb1..dd9c99b 100644
--- a/system/vulkan_enc/vk_format_info.h
+++ b/system/vulkan_enc/vk_format_info.h
@@ -27,7 +27,9 @@
#define VK_FORMAT_INFO_H
#include <stdbool.h>
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
#include <system/graphics.h>
+#endif
#include <vulkan/vulkan.h>
#include <vndk/hardware_buffer.h>