• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2016 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 #pragma once
15 
16 #include "aemu/base/EnumFlags.h"
17 #include "aemu/base/containers/SmallVector.h"
18 #include "aemu/base/files/Stream.h"
19 #include "aemu/base/containers/BufferQueue.h"
20 
21 #include <functional>
22 #include <memory>
23 
24 namespace gfxstream {
25 
26 // Turn the RenderChannel::State enum into flags.
27 using namespace ::android::base::EnumFlags;
28 
29 // RenderChannel - For each guest-to-host renderer connection, this provides
30 // an interface for the guest side to interact with the corresponding renderer
31 // thread on the host. Its main purpose is to send and receive wire protocol
32 // bytes in an asynchronous way (compatible with Android pipes).
33 //
34 // Usage is the following:
35 //    1) Get an instance pointer through a dedicated Renderer function
36 //       (e.g. RendererImpl::createRenderChannel()).
37 //
38 //    2) Call setEventCallback() to indicate which callback should be called
39 //       when the channel's state has changed due to a host thread event.
40 //
41 class RenderChannel {
42 public:
43     // A type used to pass byte packets between the guest and the
44     // RenderChannel instance. Experience has shown that using a
45     // SmallFixedVector<char, N> instance instead of a std::vector<char>
46     // avoids a lot of un-necessary heap allocations. The current size
47     // of 512 was selected after profiling existing traffic, including
48     // the one used in protocol-heavy benchmark like Antutu3D.
49     using Buffer = android::base::SmallFixedVector<char, 512>;
50 
51     // Bit-flags for the channel state.
52     // |CanRead| means there is data from the host to read.
53     // |CanWrite| means there is room to send data to the host.
54     // |Stopped| means the channel was stopped.
55     enum class State {
56         // Can't use None here, some system header declares it as a macro.
57         Empty = 0,
58         CanRead = 1 << 0,
59         CanWrite = 1 << 1,
60         Stopped = 1 << 2,
61     };
62 
63     using IoResult = android::base::BufferQueueResult;
64     using Duration = uint64_t;
65 
66     // Type of a callback used to tell the guest when the RenderChannel
67     // state changes. Used by setEventCallback(). The parameter contains
68     // the State bits matching the event, i.e. it is the logical AND of
69     // the last value passed to setWantedEvents() and the current
70     // RenderChannel state.
71     using EventCallback = std::function<void(State)>;
72 
73     // Sets a single (!) callback that is called when the channel state's
74     // changes due to an event *from* *the* *host* only. |callback| is a
75     // guest-provided callback that will be called from the host renderer
76     // thread, not the guest one.
77     virtual void setEventCallback(EventCallback&& callback) = 0;
78 
79     // Used to indicate which i/o events the guest wants to be notified
80     // through its StateChangeCallback. |state| must be a combination of
81     // State::CanRead or State::CanWrite only. This will *not* call the
82     // callback directly since this happens in the guest thread.
83     virtual void setWantedEvents(State state) = 0;
84 
85     // Get the current state flags.
86     virtual State state() const = 0;
87 
88     // Try to writes the data in |buffer| into the channel. On success,
89     // return IoResult::Ok and moves |buffer|. On failure, return
90     // IoResult::TryAgain if the channel was full, or IoResult::Error
91     // if it is stopped.
92     virtual IoResult tryWrite(Buffer&& buffer) = 0;
93 
94     // Blocking call that waits until able to write into the channel.
95     virtual void waitUntilWritable() = 0;
96 
97     // Try to read data from the channel. On success, return IoResult::Ok and
98     // sets |*buffer| to contain the data. On failure, return
99     // IoResult::TryAgain if the channel was empty, or IoResult::Error if
100     // it was stopped.
101     virtual IoResult tryRead(Buffer* buffer) = 0;
102 
103     // Try to read data from the channel. On success, return IoResult::Ok and
104     // sets |*buffer| to contain the data. On failure, return IoResult::Error
105     // if it was stopped. Returns IoResult::Timeout if we waited passed
106     // waitUntilUs.
107     virtual IoResult readBefore(Buffer* buffer, Duration waitUntilUs) = 0;
108 
109     // Blocking call that waits until data is available to read from the channel.
110     virtual void waitUntilReadable() = 0;
111 
112     // Abort all pending operations. Any following operation is a noop.
113     // Once a channel is stopped, it cannot be re-started.
114     virtual void stop() = 0;
115 
116     // Callback function when snapshotting the virtual machine.
117     virtual void onSave(android::base::Stream* stream) = 0;
118 
119 protected:
120     ~RenderChannel() = default;
121 };
122 
123 // Shared pointer to RenderChannel instance.
124 using RenderChannelPtr = std::shared_ptr<RenderChannel>;
125 
126 }  // namespace gfxstream
127