1 /* 2 * Copyright 2011 Google LLC 3 * SPDX-License-Identifier: MIT 4 */ 5 #ifndef __IO_STREAM_H__ 6 #define __IO_STREAM_H__ 7 8 #include <stdlib.h> 9 #include <stdint.h> 10 #include <stdio.h> 11 12 namespace gfxstream { 13 namespace guest { 14 15 class IOStream { 16 public: 17 IOStream(size_t bufSize)18 IOStream(size_t bufSize) { 19 m_iostreamBuf = NULL; 20 m_bufsizeOrig = bufSize; 21 m_bufsize = bufSize; 22 m_free = 0; 23 m_refcount = 1; 24 } 25 incRef()26 void incRef() { 27 __atomic_add_fetch(&m_refcount, 1, __ATOMIC_SEQ_CST); 28 } 29 decRef()30 bool decRef() { 31 if (0 == __atomic_sub_fetch(&m_refcount, 1, __ATOMIC_SEQ_CST)) { 32 delete this; 33 return true; 34 } 35 return false; 36 } 37 idealAllocSize(size_t len)38 virtual size_t idealAllocSize(size_t len) { 39 return m_bufsize < len ? len : m_bufsize; 40 } 41 42 virtual int connect(const char* serviceName = nullptr) { return 0; } processPipeInit()43 virtual uint64_t processPipeInit() { return 0; } 44 45 virtual void *allocBuffer(size_t minSize) = 0; 46 virtual int commitBuffer(size_t size) = 0; 47 virtual const unsigned char *readFully( void *buf, size_t len) = 0; 48 virtual const unsigned char *commitBufferAndReadFully(size_t size, void *buf, size_t len) = 0; 49 virtual const unsigned char *read( void *buf, size_t *inout_len) = 0; 50 virtual int writeFully(const void* buf, size_t len) = 0; writeFullyAsync(const void * buf,size_t len)51 virtual int writeFullyAsync(const void* buf, size_t len) { 52 return writeFully(buf, len); 53 } 54 ~IOStream()55 virtual ~IOStream() { 56 57 // NOTE: m_iostreamBuf is 'owned' by the child class thus we expect it to be released by it 58 } 59 alloc(size_t len)60 virtual unsigned char *alloc(size_t len) { 61 62 if (m_iostreamBuf && len > m_free) { 63 if (flush() < 0) { 64 return NULL; // we failed to flush so something is wrong 65 } 66 } 67 68 if (!m_iostreamBuf || len > m_bufsize) { 69 size_t allocLen = this->idealAllocSize(len); 70 m_iostreamBuf = (unsigned char *)allocBuffer(allocLen); 71 if (!m_iostreamBuf) { 72 return NULL; 73 } 74 m_bufsize = m_free = allocLen; 75 } 76 77 unsigned char *ptr; 78 79 ptr = m_iostreamBuf + (m_bufsize - m_free); 80 m_free -= len; 81 82 return ptr; 83 } 84 flush()85 virtual int flush() { 86 87 if (!m_iostreamBuf || m_free == m_bufsize) return 0; 88 89 int stat = commitBuffer(m_bufsize - m_free); 90 m_iostreamBuf = NULL; 91 m_free = 0; 92 return stat; 93 } 94 readback(void * buf,size_t len)95 const unsigned char *readback(void *buf, size_t len) { 96 if (m_iostreamBuf && m_free != m_bufsize) { 97 size_t size = m_bufsize - m_free; 98 m_iostreamBuf = NULL; 99 m_free = 0; 100 return commitBufferAndReadFully(size, buf, len); 101 } 102 return readFully(buf, len); 103 } 104 105 // These two methods are defined and used in GLESv2_enc. Any reference 106 // outside of GLESv2_enc will produce a link error. This is intentional 107 // (technical debt). 108 void readbackPixels(void* context, int width, int height, unsigned int format, unsigned int type, void* pixels); 109 void uploadPixels(void* context, int width, int height, int depth, unsigned int format, unsigned int type, const void* pixels); 110 111 112 protected: rewind()113 void rewind() { 114 m_iostreamBuf = NULL; 115 m_bufsize = m_bufsizeOrig; 116 m_free = 0; 117 } 118 119 private: 120 unsigned char *m_iostreamBuf; 121 size_t m_bufsizeOrig; 122 size_t m_bufsize; 123 size_t m_free; 124 uint32_t m_refcount; 125 }; 126 127 } // namespace guest 128 } // namespace gfxstream 129 130 // 131 // When a client opens a connection to the renderer, it should 132 // send unsigned int value indicating the "clientFlags". 133 // The following are the bitmask of the clientFlags. 134 // currently only one bit is used which flags the server 135 // it should exit. 136 // 137 #define IOSTREAM_CLIENT_EXIT_SERVER 1 138 139 #endif 140