blob: 1cfe1053e1b725a959e2fd1e5350934575de10bd [file] [log] [blame]
/*
* 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 <functional>
#include <future>
#include <optional>
#include <unordered_map>
#include <vector>
#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<Post::CompletionCallback> 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<FlatComposeRequest> composeRequest,
std::unique_ptr<Post::CompletionCallback> 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<void> scheduledSignal, std::future<void> continueSignal);
// Exit post worker, unbind gl context if necessary.
void exit();
protected:
void runTask(std::packaged_task<void()>);
// Impl versions of the above, so we can run it from separate threads
virtual std::shared_future<void> postImpl(ColorBuffer* cb) = 0;
virtual void viewportImpl(int width, int height) = 0;
virtual void clearImpl() = 0;
virtual void exitImpl() = 0;
virtual std::shared_future<void> 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<void(UiUpdateFunc, void*, bool)>;
UiThreadRunner m_runOnUiThread = 0;
std::unordered_map<uint32_t, std::shared_future<void>> m_composeTargetToComposeFuture;
bool isComposeTargetReady(uint32_t targetHandle);
DISALLOW_COPY_AND_ASSIGN(PostWorker);
};
} // namespace gfxstream