• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include "VulkanStreamGuest.h"
15 
16 #include "IOStream.h"
17 
18 #include "android/base/Pool.h"
19 #include "android/base/Tracing.h"
20 
21 #include <vector>
22 
23 #include <log/log.h>
24 #include <inttypes.h>
25 
26 namespace goldfish_vk {
27 
28 class VulkanStreamGuest::Impl : public android::base::Stream {
29 public:
Impl(IOStream * stream)30     Impl(IOStream* stream) : mStream(stream) { unsetHandleMapping(); }
31 
~Impl()32     ~Impl() { }
33 
valid()34     bool valid() { return true; }
35 
alloc(void ** ptrAddr,size_t bytes)36     void alloc(void **ptrAddr, size_t bytes) {
37         if (!bytes) {
38             *ptrAddr = nullptr;
39             return;
40         }
41 
42         *ptrAddr = mPool.alloc(bytes);
43     }
44 
write(const void * buffer,size_t size)45     ssize_t write(const void *buffer, size_t size) override {
46         uint8_t* streamBuf = (uint8_t*)mStream->alloc(size);
47         memcpy(streamBuf, buffer, size);
48         return size;
49     }
50 
read(void * buffer,size_t size)51     ssize_t read(void *buffer, size_t size) override {
52         commitWrite();
53         if (!mStream->readFully(buffer, size)) {
54             ALOGE("FATAL: Could not read back %zu bytes", size);
55             abort();
56         }
57         return size;
58     }
59 
clearPool()60     void clearPool() {
61         mPool.freeAll();
62     }
63 
setHandleMapping(VulkanHandleMapping * mapping)64     void setHandleMapping(VulkanHandleMapping* mapping) {
65         mCurrentHandleMapping = mapping;
66     }
67 
unsetHandleMapping()68     void unsetHandleMapping() {
69         mCurrentHandleMapping = &mDefaultHandleMapping;
70     }
71 
handleMapping() const72     VulkanHandleMapping* handleMapping() const {
73         return mCurrentHandleMapping;
74     }
75 
flush()76     void flush() {
77         commitWrite();
78     }
79 
80 private:
oustandingWriteBuffer() const81     size_t oustandingWriteBuffer() const {
82         return mWritePos;
83     }
84 
remainingWriteBufferSize() const85     size_t remainingWriteBufferSize() const {
86         return mWriteBuffer.size() - mWritePos;
87     }
88 
commitWrite()89     void commitWrite() {
90         AEMU_SCOPED_TRACE("VulkanStreamGuest device write");
91         mStream->flush();
92     }
93 
bufferedWrite(const void * buffer,size_t size)94     ssize_t bufferedWrite(const void *buffer, size_t size) {
95         if (size > remainingWriteBufferSize()) {
96             mWriteBuffer.resize((mWritePos + size) << 1);
97         }
98         memcpy(mWriteBuffer.data() + mWritePos, buffer, size);
99         mWritePos += size;
100         return size;
101     }
102 
103     android::base::Pool mPool { 8, 4096, 64 };
104 
105     size_t mWritePos = 0;
106     std::vector<uint8_t> mWriteBuffer;
107     IOStream* mStream = nullptr;
108     DefaultHandleMapping mDefaultHandleMapping;
109     VulkanHandleMapping* mCurrentHandleMapping;
110 };
111 
VulkanStreamGuest(IOStream * stream)112 VulkanStreamGuest::VulkanStreamGuest(IOStream *stream) :
113     mImpl(new VulkanStreamGuest::Impl(stream)) { }
114 
115 VulkanStreamGuest::~VulkanStreamGuest() = default;
116 
valid()117 bool VulkanStreamGuest::valid() {
118     return mImpl->valid();
119 }
120 
alloc(void ** ptrAddr,size_t bytes)121 void VulkanStreamGuest::alloc(void** ptrAddr, size_t bytes) {
122     mImpl->alloc(ptrAddr, bytes);
123 }
124 
loadStringInPlace(char ** forOutput)125 void VulkanStreamGuest::loadStringInPlace(char** forOutput) {
126     size_t len = getBe32();
127 
128     alloc((void**)forOutput, len + 1);
129 
130     memset(*forOutput, 0x0, len + 1);
131 
132     if (len > 0) read(*forOutput, len);
133 }
134 
loadStringArrayInPlace(char *** forOutput)135 void VulkanStreamGuest::loadStringArrayInPlace(char*** forOutput) {
136     size_t count = getBe32();
137 
138     if (!count) {
139         *forOutput = nullptr;
140         return;
141     }
142 
143     alloc((void**)forOutput, count * sizeof(char*));
144 
145     char **stringsForOutput = *forOutput;
146 
147     for (size_t i = 0; i < count; i++) {
148         loadStringInPlace(stringsForOutput + i);
149     }
150 }
151 
152 
read(void * buffer,size_t size)153 ssize_t VulkanStreamGuest::read(void *buffer, size_t size) {
154     return mImpl->read(buffer, size);
155 }
156 
write(const void * buffer,size_t size)157 ssize_t VulkanStreamGuest::write(const void *buffer, size_t size) {
158     return mImpl->write(buffer, size);
159 }
160 
clearPool()161 void VulkanStreamGuest::clearPool() {
162     mImpl->clearPool();
163 }
164 
setHandleMapping(VulkanHandleMapping * mapping)165 void VulkanStreamGuest::setHandleMapping(VulkanHandleMapping* mapping) {
166     mImpl->setHandleMapping(mapping);
167 }
168 
unsetHandleMapping()169 void VulkanStreamGuest::unsetHandleMapping() {
170     mImpl->unsetHandleMapping();
171 }
172 
handleMapping() const173 VulkanHandleMapping* VulkanStreamGuest::handleMapping() const {
174     return mImpl->handleMapping();
175 }
176 
flush()177 void VulkanStreamGuest::flush() {
178     mImpl->flush();
179 }
180 
VulkanCountingStream()181 VulkanCountingStream::VulkanCountingStream() : VulkanStreamGuest(nullptr) { }
182 VulkanCountingStream::~VulkanCountingStream() = default;
183 
read(void *,size_t size)184 ssize_t VulkanCountingStream::read(void*, size_t size) {
185     m_read += size;
186     return size;
187 }
188 
write(const void *,size_t size)189 ssize_t VulkanCountingStream::write(const void*, size_t size) {
190     m_written += size;
191     return size;
192 }
193 
rewind()194 void VulkanCountingStream::rewind() {
195     m_written = 0;
196     m_read = 0;
197 }
198 
199 } // namespace goldfish_vk
200