Repository navigation
Expand file tree
/
Copy pathchannel_stream.cpp
More file actions
126 lines (110 loc) · 3.99 KB
/
Copy pathchannel_stream.cpp
File metadata and controls
126 lines (110 loc) · 3.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "channel_stream.h"
#include <assert.h>
#include <memory.h>
#include "gfxstream/host/stream_utils.h"
#include "gfxstream/host/dma_device.h"
#include "gfxstream/common/logging.h"
#include "render-utils/RenderChannel.h"
namespace gfxstream {
namespace host {
using IoResult = RenderChannel::IoResult;
ChannelStream::ChannelStream(RenderChannelImpl* channel, size_t bufSize)
: IOStream(bufSize), mChannel(channel) {
mWriteBuffer.resize_noinit(bufSize);
}
void* ChannelStream::allocBuffer(size_t minSize) {
if (mWriteBuffer.size() < minSize) {
mWriteBuffer.resize_noinit(minSize);
}
return mWriteBuffer.data();
}
int ChannelStream::commitBuffer(size_t size) {
assert(size <= mWriteBuffer.size());
if (mWriteBuffer.isAllocated()) {
mWriteBuffer.resize(size);
mChannel->writeToGuest(std::move(mWriteBuffer));
} else {
mChannel->writeToGuest(
RenderChannel::Buffer(mWriteBuffer.data(), mWriteBuffer.data() + size));
}
return size;
}
const unsigned char* ChannelStream::readRaw(void* buf, size_t* inout_len) {
size_t wanted = *inout_len;
size_t count = 0U;
auto dst = static_cast<uint8_t*>(buf);
while (count < wanted) {
if (mReadBufferLeft > 0) {
size_t avail = std::min<size_t>(wanted - count, mReadBufferLeft);
memcpy(dst + count,
mReadBuffer.data() + (mReadBuffer.size() - mReadBufferLeft),
avail);
count += avail;
mReadBufferLeft -= avail;
continue;
}
bool blocking = (count == 0);
auto result = mChannel->readFromGuest(&mReadBuffer, blocking);
if (result == IoResult::Ok) {
mReadBufferLeft = mReadBuffer.size();
continue;
}
if (count > 0) { // There is some data to return.
break;
}
// Result can only be IoResult::Error if |count| == 0
// since |blocking| was true, it cannot be IoResult::TryAgain.
assert(result == IoResult::Error);
return nullptr;
}
*inout_len = count;
return (const unsigned char*)buf;
}
void* ChannelStream::getDmaForReading(uint64_t guest_paddr) {
return g_gfxstream_dma_get_host_addr(guest_paddr);
}
void ChannelStream::unlockDma(uint64_t guest_paddr) {
g_gfxstream_dma_unlock(guest_paddr);
}
void ChannelStream::forceStop() {
mChannel->stopFromHost();
}
int ChannelStream::writeFully(const void* buf, size_t len) {
void* dstBuf = alloc(len);
memcpy(dstBuf, buf, len);
flush();
return 0;
}
const unsigned char* ChannelStream::readFully(void *buf, size_t len) {
GFXSTREAM_FATAL("Not intended for use with ChannelStream");
return nullptr;
}
void ChannelStream::onSave(gfxstream::Stream* stream) {
// Write only the data that's left in read buffer, but in the same format
// as saveBuffer() does.
stream->putBe32(mReadBufferLeft);
stream->write(mReadBuffer.data() + mReadBuffer.size() - mReadBufferLeft,
mReadBufferLeft);
gfxstream::host::saveBuffer(stream, mWriteBuffer);
}
unsigned char* ChannelStream::onLoad(gfxstream::Stream* stream) {
gfxstream::host::loadBuffer(stream, &mReadBuffer);
mReadBufferLeft = mReadBuffer.size();
gfxstream::host::loadBuffer(stream, &mWriteBuffer);
return reinterpret_cast<unsigned char*>(mWriteBuffer.data());
}
} // namespace host
} // namespace gfxstream