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