1 /* 2 * Copyright (C) 2011 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 #pragma once 17 18 #include "aemu/base/files/MemStream.h" 19 #include "aemu/base/Optional.h" 20 #include "host-common/address_space_graphics_types.h" 21 #include "aemu/base/synchronization/ConditionVariable.h" 22 #include "aemu/base/synchronization/Lock.h" 23 #include "aemu/base/threads/Thread.h" 24 25 #include <atomic> 26 #include <memory> 27 28 namespace gfxstream { 29 30 class RenderChannelImpl; 31 class RendererImpl; 32 class ReadBuffer; 33 class RingStream; 34 35 // A class used to model a thread of the RenderServer. Each one of them 36 // handles a single guest client / protocol byte stream. 37 class RenderThread : public android::base::Thread { 38 using MemStream = android::base::MemStream; 39 40 public: 41 static constexpr uint32_t INVALID_CONTEXT_ID = std::numeric_limits<uint32_t>::max(); 42 // Create a new RenderThread instance. 43 RenderThread(RenderChannelImpl* channel, 44 android::base::Stream* loadStream = nullptr, 45 uint32_t virtioGpuContextId = INVALID_CONTEXT_ID); 46 47 // Create a new RenderThread instance tied to the address space device. 48 RenderThread( 49 struct asg_context context, 50 android::base::Stream* loadStream, 51 android::emulation::asg::ConsumerCallbacks callbacks, 52 uint32_t contextId, uint32_t capsetId, 53 std::optional<std::string> nameOpt); 54 virtual ~RenderThread(); 55 56 // Returns true iff the thread has finished. isFinished()57 bool isFinished() const { return mFinished.load(std::memory_order_relaxed); } 58 void waitForFinished(); 59 60 void pausePreSnapshot(); 61 void resume(); 62 void save(android::base::Stream* stream); 63 64 // RenderThreads are blocked from exiting after finished to workaround driver bugs. 65 // `sendExitSignal` allows us to control when we can allow the thread to exit to synchronize 66 // between exits and other RenderThreads calling vkDestroyDevice, eglMakeCurrent, etc. 67 // This must be called after RenderThread has finished (use `waitForFinished`), as a deadlock 68 // can occur if vulkan commands are still processing. 69 void sendExitSignal(); 70 private: 71 virtual intptr_t main(); 72 void setFinished(); 73 void waitForExitSignal(); 74 75 // Snapshot support. 76 enum class SnapshotState { 77 Empty, 78 StartSaving, 79 StartLoading, 80 InProgress, 81 Finished, 82 }; 83 84 // Whether using RenderChannel or a ring buffer. 85 enum TransportMode { 86 Channel, 87 Ring, 88 }; 89 90 struct SnapshotObjects; 91 92 bool doSnapshotOp(const SnapshotObjects& objects, SnapshotState expectedState, 93 std::function<void()> op); 94 95 bool loadSnapshot(const SnapshotObjects& objects); 96 bool saveSnapshot(const SnapshotObjects& objects); 97 98 void waitForSnapshotCompletion(android::base::AutoLock* lock); 99 void loadImpl(android::base::AutoLock* lock, const SnapshotObjects& objects); 100 void saveImpl(android::base::AutoLock* lock, const SnapshotObjects& objects); 101 102 bool isPausedForSnapshotLocked() const; 103 104 RenderChannelImpl* mChannel = nullptr; 105 std::unique_ptr<RingStream> mRingStream; 106 107 SnapshotState mState = SnapshotState::Empty; 108 std::atomic<bool> mFinished { false }; 109 android::base::Lock mLock; 110 android::base::ConditionVariable mSnapshotSignal; 111 android::base::ConditionVariable mFinishedSignal; 112 android::base::ConditionVariable mExitSignal; 113 std::atomic<bool> mCanExit { false }; 114 android::base::Optional<android::base::MemStream> mStream; 115 116 bool mRunInLimitedMode = false; 117 uint32_t mContextId = 0; 118 uint32_t mCapsetId = 0; 119 // If we need to reload process resources. 120 // This happens in snapshot testing where we don't snapshot render threads. 121 bool mNeedReloadProcessResources = false; 122 }; 123 124 } // namespace gfxstream 125