1static ResourceTracker* sResourceTracker = nullptr; 2static uint32_t sFeatureBits = 0; 3static constexpr uint32_t kWatchdogBufferMax = 1'000; 4 5class VkEncoder::Impl { 6 public: 7 Impl(gfxstream::guest::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(gfxstream::guest::IOStream* stream, 64 gfxstream::guest::HealthMonitor<>* healthMonitor) 65 : mImpl(new VkEncoder::Impl(stream)), mHealthMonitor(healthMonitor) {} 66 67void VkEncoder::flush() { mImpl->flush(); } 68 69void VkEncoder::lock() { mImpl->lock(); } 70 71void VkEncoder::unlock() { mImpl->unlock(); } 72 73void VkEncoder::incRef() { __atomic_add_fetch(&refCount, 1, __ATOMIC_SEQ_CST); } 74 75bool VkEncoder::decRef() { 76 if (0 == __atomic_sub_fetch(&refCount, 1, __ATOMIC_SEQ_CST)) { 77 delete this; 78 return true; 79 } 80 return false; 81} 82 83std::string VkEncoder::getPacketContents(const uint8_t* ptr, size_t len) { 84 std::string result; 85 result.reserve(3 * len); 86 char buf[4]; 87 for (size_t i = 0; i < len; i++) { 88 std::snprintf(buf, 4, " %02X", ptr[i]); 89 result.append(buf, 3); 90 } 91 return result; 92} 93