1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include "aemu/base/files/Stream.h" 19 #include "host-common/logging.h" 20 21 #include <assert.h> 22 #include <inttypes.h> 23 #include <stdlib.h> 24 #include <stdio.h> 25 26 namespace gfxstream { 27 28 class IOStream { 29 protected: IOStream(size_t bufSize)30 explicit IOStream(size_t bufSize) : m_bufsize(bufSize) {} 31 ~IOStream()32 ~IOStream() { 33 // NOTE: m_buf was owned by the child class thus we expect it to be 34 // released before the object destruction. 35 } 36 37 public: 38 virtual void *allocBuffer(size_t minSize) = 0; 39 virtual int commitBuffer(size_t size) = 0; 40 virtual int writeFully(const void* buf, size_t len) = 0; 41 virtual const unsigned char *readFully( void *buf, size_t len) = 0; 42 read(void * buf,size_t bufLen)43 size_t read(void* buf, size_t bufLen) { 44 if (!readRaw(buf, &bufLen)) { 45 return 0; 46 } 47 return bufLen; 48 } 49 alloc(size_t len)50 unsigned char* alloc(size_t len) { 51 if (m_buf && len > m_free) { 52 if (flush() < 0) { 53 ERR("Failed to flush in alloc\n"); 54 return NULL; // we failed to flush so something is wrong 55 } 56 } 57 58 if (!m_buf || len > m_bufsize) { 59 int allocLen = m_bufsize < len ? len : m_bufsize; 60 m_buf = (unsigned char *)allocBuffer(allocLen); 61 if (!m_buf) { 62 ERR("Alloc (%u bytes) failed\n", allocLen); 63 return NULL; 64 } 65 m_bufsize = m_free = allocLen; 66 } 67 68 unsigned char* ptr = m_buf + (m_bufsize - m_free); 69 m_free -= len; 70 71 return ptr; 72 } 73 flush()74 int flush() { 75 if (!m_buf || m_free == m_bufsize) return 0; 76 77 int stat = commitBuffer(m_bufsize - m_free); 78 m_buf = NULL; 79 m_free = 0; 80 return stat; 81 } 82 readback(void * buf,size_t len)83 const unsigned char *readback(void *buf, size_t len) { 84 flush(); 85 return readFully(buf, len); 86 } 87 save(android::base::Stream * stream)88 void save(android::base::Stream* stream) { 89 stream->putBe32(m_bufsize); 90 stream->putBe32(m_free); 91 stream->putByte(m_buf != nullptr); 92 onSave(stream); 93 } 94 load(android::base::Stream * stream)95 void load(android::base::Stream* stream) { 96 m_bufsize = stream->getBe32(); 97 m_free = stream->getBe32(); 98 const bool haveBuf = stream->getByte(); 99 const auto buf = onLoad(stream); 100 m_buf = haveBuf ? buf : nullptr; 101 } 102 103 virtual void* getDmaForReading(uint64_t guest_paddr) = 0; 104 virtual void unlockDma(uint64_t guest_paddr) = 0; 105 106 protected: 107 virtual const unsigned char *readRaw(void *buf, size_t *inout_len) = 0; 108 virtual void onSave(android::base::Stream* stream) = 0; 109 virtual unsigned char* onLoad(android::base::Stream* stream) = 0; 110 111 unsigned char* m_buf = nullptr; 112 size_t m_bufsize; 113 size_t m_free = 0; 114 }; 115 116 } // namespace gfxstream