| // 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 "VulkanStreamGuest.h" |
| |
| namespace goldfish_vk { |
| |
| VulkanStreamGuest::VulkanStreamGuest(IOStream *stream): mStream(stream) { |
| unsetHandleMapping(); |
| mFeatureBits = ResourceTracker::get()->getStreamFeatures(); |
| } |
| |
| VulkanStreamGuest::~VulkanStreamGuest() = default; |
| |
| bool VulkanStreamGuest::valid() { |
| return true; |
| } |
| |
| void VulkanStreamGuest::alloc(void** ptrAddr, size_t bytes) { |
| if (!bytes) { |
| *ptrAddr = nullptr; |
| return; |
| } |
| |
| *ptrAddr = mPool.alloc(bytes); |
| } |
| |
| void VulkanStreamGuest::loadStringInPlace(char** forOutput) { |
| size_t len = getBe32(); |
| |
| alloc((void**)forOutput, len + 1); |
| |
| memset(*forOutput, 0x0, len + 1); |
| |
| if (len > 0) read(*forOutput, len); |
| } |
| |
| void VulkanStreamGuest::loadStringArrayInPlace(char*** forOutput) { |
| size_t count = getBe32(); |
| |
| if (!count) { |
| *forOutput = nullptr; |
| return; |
| } |
| |
| alloc((void**)forOutput, count * sizeof(char*)); |
| |
| char **stringsForOutput = *forOutput; |
| |
| for (size_t i = 0; i < count; i++) { |
| loadStringInPlace(stringsForOutput + i); |
| } |
| } |
| |
| void VulkanStreamGuest::loadStringInPlaceWithStreamPtr(char** forOutput, uint8_t** streamPtr) { |
| uint32_t len; |
| memcpy(&len, *streamPtr, sizeof(uint32_t)); |
| *streamPtr += sizeof(uint32_t); |
| android::base::Stream::fromBe32((uint8_t*)&len); |
| |
| alloc((void**)forOutput, len + 1); |
| |
| memset(*forOutput, 0x0, len + 1); |
| |
| if (len > 0) { |
| memcpy(*forOutput, *streamPtr, len); |
| *streamPtr += len; |
| } |
| } |
| |
| void VulkanStreamGuest::loadStringArrayInPlaceWithStreamPtr(char*** forOutput, uint8_t** streamPtr) { |
| uint32_t count; |
| memcpy(&count, *streamPtr, sizeof(uint32_t)); |
| *streamPtr += sizeof(uint32_t); |
| android::base::Stream::fromBe32((uint8_t*)&count); |
| if (!count) { |
| *forOutput = nullptr; |
| return; |
| } |
| |
| alloc((void**)forOutput, count * sizeof(char*)); |
| |
| char **stringsForOutput = *forOutput; |
| |
| for (size_t i = 0; i < count; i++) { |
| loadStringInPlaceWithStreamPtr(stringsForOutput + i, streamPtr); |
| } |
| } |
| |
| |
| ssize_t VulkanStreamGuest::read(void *buffer, size_t size) { |
| if (!mStream->readback(buffer, size)) { |
| ALOGE("FATAL: Could not read back %zu bytes", size); |
| abort(); |
| } |
| return size; |
| } |
| |
| ssize_t VulkanStreamGuest::write(const void *buffer, size_t size) { |
| uint8_t* streamBuf = (uint8_t*)mStream->alloc(size); |
| memcpy(streamBuf, buffer, size); |
| return size; |
| } |
| |
| void VulkanStreamGuest::writeLarge(const void* buffer, size_t size) { |
| mStream->writeFullyAsync(buffer, size); |
| } |
| |
| void VulkanStreamGuest::clearPool() { |
| mPool.freeAll(); |
| } |
| |
| void VulkanStreamGuest::setHandleMapping(VulkanHandleMapping* mapping) { |
| mCurrentHandleMapping = mapping; |
| } |
| |
| void VulkanStreamGuest::unsetHandleMapping() { |
| mCurrentHandleMapping = &mDefaultHandleMapping; |
| } |
| |
| VulkanHandleMapping* VulkanStreamGuest::handleMapping() const { |
| return mCurrentHandleMapping; |
| } |
| |
| void VulkanStreamGuest::flush() { |
| AEMU_SCOPED_TRACE("VulkanStreamGuest device write"); |
| mStream->flush(); |
| } |
| |
| uint32_t VulkanStreamGuest::getFeatureBits() const { |
| return mFeatureBits; |
| } |
| |
| void VulkanStreamGuest::incStreamRef() { |
| mStream->incRef(); |
| } |
| |
| bool VulkanStreamGuest::decStreamRef() { |
| return mStream->decRef(); |
| } |
| |
| uint8_t* VulkanStreamGuest::reserve(size_t size) { |
| return (uint8_t*)mStream->alloc(size); |
| } |
| |
| VulkanCountingStream::VulkanCountingStream() : VulkanStreamGuest(nullptr) { } |
| VulkanCountingStream::~VulkanCountingStream() = default; |
| |
| ssize_t VulkanCountingStream::read(void*, size_t size) { |
| m_read += size; |
| return size; |
| } |
| |
| ssize_t VulkanCountingStream::write(const void*, size_t size) { |
| m_written += size; |
| return size; |
| } |
| |
| void VulkanCountingStream::rewind() { |
| m_written = 0; |
| m_read = 0; |
| } |
| |
| } // namespace goldfish_vk |