1 /*
2  * Copyright (C) 2018 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 
17 #pragma once
18 
19 #include "HostConnection.h"
20 #include "IOStream.h"
21 
22 #include <stdlib.h>
23 
24 /* This file implements an IOStream that uses VIRTGPU_EXECBUFFER ioctls on a
25  * virtio-gpu DRM rendernode device to communicate with the host.
26  */
27 
28 struct VirtioGpuCmd;
29 
30 class VirtioGpuProcessPipe : public ProcessPipe
31 {
32 public:
33     virtual bool processPipeInit(HostConnectionType connType, renderControl_encoder_context_t *rcEnc);
34 };
35 
36 class VirtioGpuStream : public IOStream
37 {
38 public:
39     explicit VirtioGpuStream(size_t bufSize);
40     ~VirtioGpuStream();
41 
42     int connect();
getProcessPipe()43     ProcessPipe *getProcessPipe() { return &m_processPipe; }
44 
45     // override IOStream so we can see non-rounded allocation sizes
alloc(size_t len)46     virtual unsigned char *alloc(size_t len)
47     {
48         return static_cast<unsigned char *>(allocBuffer(len));
49     }
50 
51     // override IOStream so we can model the caller's writes
52     virtual int flush();
53 
54     virtual void *allocBuffer(size_t minSize);
55     virtual int writeFully(const void *buf, size_t len);
56     virtual const unsigned char *readFully(void *buf, size_t len);
57     virtual int commitBuffer(size_t size);
commitBufferAndReadFully(size_t size,void * buf,size_t len)58     virtual const unsigned char* commitBufferAndReadFully(size_t size, void *buf, size_t len)
59     {
60         return commitBuffer(size) ? nullptr : readFully(buf, len);
61     }
read(void * buf,size_t * inout_len)62     virtual const unsigned char *read(void *buf, size_t *inout_len) final
63     {
64         return readFully(buf, *inout_len);
65     }
66 
valid()67     bool valid()
68     {
69         return m_fd >= 0 && m_cmdResp_bo > 0 && m_cmdResp;
70     }
71 
getRendernodeFd()72     int getRendernodeFd() { return m_fd; }
73 
74 private:
75     // rendernode fd
76     int m_fd;
77 
78     // command memory buffer
79     size_t m_bufSize;
80     unsigned char *m_buf;
81 
82     // response buffer res handle
83     uint32_t m_cmdResp_rh;
84 
85     // response buffer ttm buffer object
86     uint32_t m_cmdResp_bo;
87 
88     // user mapping of response buffer object
89     VirtioGpuCmd *m_cmdResp;
90 
91     // byte offset to read cursor for last response
92     size_t m_cmdRespPos;
93 
94     // byte offset to command being assembled
95     size_t m_cmdPos;
96 
97     // byte offset to flush cursor
98     size_t m_flushPos;
99 
100     // byte counter of allocs since last command boundary
101     size_t m_allocSize;
102 
103     // bytes of an alloc flushed through flush() API
104     size_t m_allocFlushSize;
105 
106     // Fake process pipe implementation
107     VirtioGpuProcessPipe m_processPipe;
108 
109     // commits all commands, resets buffer offsets
110     int commitAll();
111 };
112