CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/headless/WindowsHeadlessHost.cpp
Views: 1401
// Copyright (c) 2012- PPSSPP Project.12// This program is free software: you can redistribute it and/or modify3// it under the terms of the GNU General Public License as published by4// the Free Software Foundation, version 2.0 or later versions.56// This program is distributed in the hope that it will be useful,7// but WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9// GNU General Public License 2.0 for more details.1011// A copy of the GPL 2.0 should have been included with the program.12// If not, see http://www.gnu.org/licenses/1314// Official git repository and contact information can be found at15// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.1617#include "ppsspp_config.h"18#include <cstdio>1920#include "headless/WindowsHeadlessHost.h"2122#include "Common/GPU/OpenGL/GLCommon.h"23#include "Common/GPU/OpenGL/GLFeatures.h"24#include "Common/File/VFS/VFS.h"25#include "Common/File/VFS/DirectoryReader.h"2627#include "Common/CommonWindows.h"28#include "Common/Log.h"29#include "Common/File/FileUtil.h"30#include "Common/TimeUtil.h"3132#include "Core/CoreParameter.h"33#include "Core/System.h"34#include "GPU/Common/GPUDebugInterface.h"35#include "GPU/GPUState.h"36#if PPSSPP_API(ANY_GL)37#include "Windows/GPU/WindowsGLContext.h"38#endif39#include "Windows/GPU/D3D9Context.h"40#include "Windows/GPU/D3D11Context.h"41#include "Windows/GPU/WindowsVulkanContext.h"4243const bool WINDOW_VISIBLE = false;44const int WINDOW_WIDTH = 480;45const int WINDOW_HEIGHT = 272;4647HWND CreateHiddenWindow() {48static WNDCLASSEX wndClass = {49sizeof(WNDCLASSEX),50CS_HREDRAW | CS_VREDRAW | CS_OWNDC,51DefWindowProc,520,530,54NULL,55NULL,56LoadCursor(NULL, IDC_ARROW),57(HBRUSH) GetStockObject(BLACK_BRUSH),58NULL,59L"PPSSPPHeadless",60NULL,61};62RegisterClassEx(&wndClass);6364DWORD style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP;65return CreateWindowEx(0, L"PPSSPPHeadless", L"PPSSPPHeadless", style, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, NULL, NULL);66}6768void WindowsHeadlessHost::SendDebugOutput(const std::string &output) {69if (writeDebugOutput_)70fwrite(output.data(), sizeof(char), output.length(), stdout);71OutputDebugStringUTF8(output.c_str());72}7374bool WindowsHeadlessHost::InitGraphics(std::string *error_message, GraphicsContext **ctx, GPUCore core) {75hWnd = CreateHiddenWindow();76gpuCore_ = core;7778if (WINDOW_VISIBLE) {79ShowWindow(hWnd, TRUE);80SetFocus(hWnd);81}8283WindowsGraphicsContext *graphicsContext = nullptr;84bool needRenderThread = false;85switch (gpuCore_) {86case GPUCORE_GLES:87#if PPSSPP_API(ANY_GL)88case GPUCORE_SOFTWARE:89graphicsContext = new WindowsGLContext();90needRenderThread = true;91break;92#endif93case GPUCORE_DIRECTX9:94graphicsContext = new D3D9Context();95break;9697case GPUCORE_DIRECTX11:98graphicsContext = new D3D11Context();99break;100101case GPUCORE_VULKAN:102graphicsContext = new WindowsVulkanContext();103break;104}105106if (graphicsContext->Init(NULL, hWnd, error_message)) {107*ctx = graphicsContext;108gfx_ = graphicsContext;109} else {110delete graphicsContext;111*ctx = nullptr;112gfx_ = nullptr;113return false;114}115116if (needRenderThread) {117std::thread th([&]{118while (threadState_ == RenderThreadState::IDLE)119sleep_ms(1);120threadState_ = RenderThreadState::STARTING;121122std::string err;123if (!gfx_->InitFromRenderThread(&err)) {124threadState_ = RenderThreadState::START_FAILED;125return;126}127gfx_->ThreadStart();128threadState_ = RenderThreadState::STARTED;129130while (threadState_ != RenderThreadState::STOP_REQUESTED) {131if (!gfx_->ThreadFrame()) {132break;133}134}135136threadState_ = RenderThreadState::STOPPING;137gfx_->ThreadEnd();138gfx_->ShutdownFromRenderThread();139threadState_ = RenderThreadState::STOPPED;140});141th.detach();142}143144if (needRenderThread) {145threadState_ = RenderThreadState::START_REQUESTED;146while (threadState_ == RenderThreadState::START_REQUESTED || threadState_ == RenderThreadState::STARTING)147sleep_ms(1);148149return threadState_ == RenderThreadState::STARTED;150}151152return true;153}154155void WindowsHeadlessHost::ShutdownGraphics() {156gfx_->StopThread();157while (threadState_ != RenderThreadState::STOPPED && threadState_ != RenderThreadState::IDLE)158sleep_ms(1);159160gfx_->Shutdown();161delete gfx_;162gfx_ = nullptr;163DestroyWindow(hWnd);164hWnd = NULL;165}166167void WindowsHeadlessHost::SwapBuffers() {168if (gpuCore_ == GPUCORE_DIRECTX9) {169MSG msg;170PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);171TranslateMessage(&msg);172DispatchMessage(&msg);173}174}175176177