1/* 2 * Copyright 2018 Google 3 * SPDX-License-Identifier: MIT 4 */ 5 6static ResourceTracker* sResourceTracker = nullptr; 7static uint32_t sFeatureBits = 0; 8static constexpr uint32_t kWatchdogBufferMax = 1'000; 9 10#if defined(__ANDROID__) 11#include <cutils/properties.h> 12#endif 13 14class VkEncoder::Impl { 15 public: 16 Impl(gfxstream::guest::IOStream* stream) : m_stream(stream), m_logEncodes(false) { 17 if (!sResourceTracker) sResourceTracker = ResourceTracker::get(); 18 m_stream.incStreamRef(); 19#if defined(__ANDROID__) 20 const char* emuVkLogEncodesPropName = "qemu.vk.log"; 21 char encodeProp[PROPERTY_VALUE_MAX]; 22 if (property_get(emuVkLogEncodesPropName, encodeProp, nullptr) > 0) { 23 m_logEncodes = atoi(encodeProp) > 0; 24 } 25#endif 26 sFeatureBits = m_stream.getFeatureBits(); 27 } 28 29 ~Impl() { m_stream.decStreamRef(); } 30 31 VulkanCountingStream* countingStream() { return &m_countingStream; } 32 VulkanStreamGuest* stream() { return &m_stream; } 33 BumpPool* pool() { return &m_pool; } 34 ResourceTracker* resources() { return ResourceTracker::get(); } 35 Validation* validation() { return &m_validation; } 36 37 void log(const char* text) { 38 if (!m_logEncodes) return; 39 } 40 41 void flush() { 42 lock(); 43 m_stream.flush(); 44 unlock(); 45 } 46 47 // can be recursive 48 void lock() { 49 while (mLock.test_and_set(std::memory_order_acquire)) 50 ; 51 } 52 53 void unlock() { mLock.clear(std::memory_order_release); } 54 55 private: 56 VulkanCountingStream m_countingStream; 57 VulkanStreamGuest m_stream; 58 BumpPool m_pool; 59 60 Validation m_validation; 61 bool m_logEncodes; 62 std::atomic_flag mLock = ATOMIC_FLAG_INIT; 63}; 64 65VkEncoder::~VkEncoder() {} 66 67VkEncoder::VkEncoder(gfxstream::guest::IOStream* stream) 68 : mImpl(new VkEncoder::Impl(stream)) {} 69 70void VkEncoder::flush() { mImpl->flush(); } 71 72void VkEncoder::lock() { mImpl->lock(); } 73 74void VkEncoder::unlock() { mImpl->unlock(); } 75 76void VkEncoder::incRef() { __atomic_add_fetch(&refCount, 1, __ATOMIC_SEQ_CST); } 77 78bool VkEncoder::decRef() { 79 if (0 == __atomic_sub_fetch(&refCount, 1, __ATOMIC_SEQ_CST)) { 80 delete this; 81 return true; 82 } 83 return false; 84} 85 86std::string VkEncoder::getPacketContents(const uint8_t* ptr, size_t len) { 87 std::string result; 88 result.reserve(3 * len); 89 char buf[4]; 90 for (size_t i = 0; i < len; i++) { 91 std::snprintf(buf, 4, " %02X", ptr[i]); 92 result.append(buf, 3); 93 } 94 return result; 95} 96