/* * Copyright (C) 2017 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 #include #include #include #include #include "Compositor.h" #include "ContextHelper.h" #include "Hwc2.h" #include "PostCommands.h" #include "aemu/base/Compiler.h" #include "aemu/base/synchronization/Lock.h" #include "aemu/base/synchronization/MessageChannel.h" #include "host-common/window_agent.h" namespace gfxstream { class ColorBuffer; class FrameBuffer; struct RenderThreadInfo; class PostWorker { public: PostWorker(bool mainThreadPostingOnly, FrameBuffer* fb, Compositor* compositor); virtual ~PostWorker(); // post: posts the next color buffer. // Assumes framebuffer lock is held. void post(ColorBuffer* cb, std::unique_ptr postCallback); // viewport: (re)initializes viewport dimensions. // Assumes framebuffer lock is held. // This is called whenever the subwindow needs a refresh // (FrameBuffer::setupSubWindow). void viewport(int width, int height); // compose: compse the layers into final framebuffer. The callback will be // called when the CPU side job completes. The passed in future in the // callback will be completed when the GPU opereation completes. void compose(std::unique_ptr composeRequest, std::unique_ptr composeCallback); // clear: blanks out emulator display when refreshing the subwindow // if there is no last posted color buffer to show yet. void clear(); virtual void screenshot(ColorBuffer* cb, int screenwidth, int screenheight, GLenum format, GLenum type, int skinRotation, void* pixels, Rect rect) = 0; // The block task will set the scheduledSignal promise when the task is scheduled, and wait // until continueSignal is ready before completes. void block(std::promise scheduledSignal, std::future continueSignal); // Exit post worker, unbind gl context if necessary. void exit(); protected: void runTask(std::packaged_task); // Impl versions of the above, so we can run it from separate threads virtual std::shared_future postImpl(ColorBuffer* cb) = 0; virtual void viewportImpl(int width, int height) = 0; virtual void clearImpl() = 0; virtual void exitImpl() = 0; virtual std::shared_future composeImpl(const FlatComposeRequest& composeRequest); protected: FrameBuffer* mFb; Compositor* m_compositor = nullptr; protected: // If m_mainThreadPostingOnly is true, schedule the task to UI thread by // using m_runOnUiThread. Otherwise, execute the task on the current thread. bool m_mainThreadPostingOnly = false; private: using UiThreadRunner = std::function; UiThreadRunner m_runOnUiThread = 0; std::unordered_map> m_composeTargetToComposeFuture; bool isComposeTargetReady(uint32_t targetHandle); DISALLOW_COPY_AND_ASSIGN(PostWorker); }; } // namespace gfxstream