| // 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. |
| #pragma once |
| |
| #include "aemu/base/containers/BufferQueue.h" |
| #include "render-utils/RenderChannel.h" |
| #include "RendererImpl.h" |
| |
| namespace gfxstream { |
| |
| class RenderThread; |
| |
| using android::base::BufferQueue; |
| |
| // Implementation of the RenderChannel interface that connects a guest |
| // client thread (really an AndroidPipe implementation) to a host |
| // RenderThread instance. |
| class RenderChannelImpl final : public RenderChannel { |
| public: |
| explicit RenderChannelImpl(android::base::Stream* loadStream = nullptr, |
| uint32_t contextId = -1); |
| ~RenderChannelImpl(); |
| |
| ///////////////////////////////////////////////////////////////// |
| // RenderChannel overriden methods. These are called from the guest |
| // client thread. |
| |
| // Set the event |callback| to be notified when the host changes the |
| // state of the channel, according to the event mask provided by |
| // setWantedEvents(). Call this function right after creating the |
| // instance. |
| virtual void setEventCallback(EventCallback&& callback) override final; |
| |
| // Set the mask of events the guest wants to be notified of from the |
| // host thread. |
| virtual void setWantedEvents(State state) override final; |
| |
| // Return the current channel state relative to the guest. |
| virtual State state() const override final; |
| |
| // Try to send a buffer from the guest to the host render thread. |
| virtual IoResult tryWrite(Buffer&& buffer) override final; |
| |
| // Blocking call that waits until a buffer is ready to be sent from guest to host. |
| virtual void waitUntilWritable() override final; |
| |
| // Try to read a buffer from the host render thread into the guest. |
| virtual IoResult tryRead(Buffer* buffer) override final; |
| |
| // Read a buffer from the host render thread into the guest. |
| virtual IoResult readBefore(Buffer* buffer, Duration waitUntilUs) override final; |
| |
| // Blocking call that waits until a buffer is ready to be read from host to guest. |
| virtual void waitUntilReadable() override final; |
| |
| // Close the channel from the guest. |
| virtual void stop() override final; |
| |
| // Callback function when snapshotting the virtual machine. |
| virtual void onSave(android::base::Stream* stream) override; |
| |
| ///////////////////////////////////////////////////////////////// |
| // These functions are called from the host render thread or renderer. |
| |
| // Send a buffer to the guest, this call is blocking. On success, |
| // move |buffer| into the channel and return true. On failure, return |
| // false (meaning that the channel was closed). |
| bool writeToGuest(Buffer&& buffer); |
| |
| // Read data from the guest. If |blocking| is true, the call will be |
| // blocking. On success, move item into |*buffer| and return true. On |
| // failure, return IoResult::Error to indicate the channel was closed, |
| // or IoResult::TryAgain to indicate it was empty (this can happen only |
| // if |blocking| is false). |
| IoResult readFromGuest(Buffer* buffer, bool blocking); |
| |
| // Close the channel from the host. |
| void stopFromHost(); |
| |
| // Check if either guest or host stopped the channel. |
| bool isStopped() const; |
| |
| // Return the underlying render thread object. |
| RenderThread* renderThread() const; |
| |
| // Pause normal operations and enter the snapshot mode. In snapshot mode |
| // RenderChannel is supposed to allow everyone to write data into the |
| // channel, but it should not return any data back. This way we can make |
| // sure all data at the snapshot time is here and is saved, and we won't |
| // miss some important rendering call. |
| void pausePreSnapshot(); |
| |
| // Resume the normal operation after saving or loading a snapshot. |
| void resume(); |
| |
| private: |
| void updateStateLocked(); |
| void notifyStateChangeLocked(); |
| |
| EventCallback mEventCallback; |
| std::unique_ptr<RenderThread> mRenderThread; |
| |
| // A single lock to protect the state and the two buffer queues at the |
| // same time. NOTE: This needs to appear before the BufferQueue instances. |
| mutable android::base::Lock mLock; |
| State mState = State::Empty; |
| State mWantedEvents = State::Empty; |
| BufferQueue<RenderChannel::Buffer> mFromGuest; |
| BufferQueue<RenderChannel::Buffer> mToGuest; |
| }; |
| |
| } // namespace gfxstream |