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