From 62033ab64ddbaa011c94e671fcbd2c4de46a49df Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Thu, 25 May 2023 07:43:09 +0200 Subject: [PATCH] move renderer ownership to engine (WIP) --- src/demo/credits.cc | 2 +- src/engine/engine.cc | 196 +++++++++++------- src/engine/engine.h | 26 ++- src/engine/image_quad.cc | 5 +- src/engine/image_quad.h | 2 +- src/engine/input_event.h | 2 + src/engine/platform/platform.cc | 61 ++---- src/engine/platform/platform.h | 25 ++- src/engine/platform/platform_android.cc | 69 +++--- src/engine/platform/platform_linux.cc | 63 +++--- src/engine/platform/platform_observer.h | 23 ++ src/engine/renderer/opengl/renderer_opengl.h | 4 - .../renderer/opengl/renderer_opengl_linux.cc | 13 +- src/engine/renderer/renderer.h | 4 - src/engine/renderer/vulkan/renderer_vulkan.h | 4 - .../renderer/vulkan/renderer_vulkan_linux.cc | 9 - 16 files changed, 267 insertions(+), 241 deletions(-) create mode 100644 src/engine/platform/platform_observer.h diff --git a/src/demo/credits.cc b/src/demo/credits.cc index 898903a..fe721ee 100644 --- a/src/demo/credits.cc +++ b/src/demo/credits.cc @@ -95,7 +95,7 @@ void Credits::Show() { void Credits::Hide() { text_animator_.SetEndCallback(Animator::kBlending, [&]() -> void { for (int i = 0; i < kNumLines; ++i) - text_[i].Destory(); + text_[i].Destroy(); text_animator_.SetEndCallback(Animator::kBlending, nullptr); text_animator_.SetVisible(false); }); diff --git a/src/engine/engine.cc b/src/engine/engine.cc index 7a6de43..dbfb718 100644 --- a/src/engine/engine.cc +++ b/src/engine/engine.cc @@ -13,36 +13,53 @@ #include "engine/mesh.h" #include "engine/platform/platform.h" #include "engine/renderer/geometry.h" +#include "engine/renderer/opengl/renderer_opengl.h" #include "engine/renderer/renderer.h" #include "engine/renderer/shader.h" #include "engine/renderer/texture.h" +#include "engine/renderer/vulkan/renderer_vulkan.h" #include "engine/shader_source.h" #include "third_party/texture_compressor/texture_compressor.h" +#define USE_VULKAN_RENDERER 1 + using namespace base; namespace eng { Engine* Engine::singleton = nullptr; -Engine::Engine(Platform* platform, Renderer* renderer) +Engine::Engine(Platform* platform) : platform_(platform), - renderer_(renderer), - audio_mixer_{std::make_unique()} { +#if (USE_VULKAN_RENDERER == 1) + renderer_{std::make_unique()}, +#else + renderer_{std::make_unique()}, +#endif + audio_mixer_{std::make_unique()}, + quad_{CreateRenderResource()}, + pass_through_shader_{CreateRenderResource()}, + solid_shader_{CreateRenderResource()} { DCHECK(!singleton); singleton = this; + platform_->SetObserver(this); renderer_->SetContextLostCB(std::bind(&Engine::ContextLost, this)); - quad_ = CreateRenderResource(); - pass_through_shader_ = CreateRenderResource(); - solid_shader_ = CreateRenderResource(); - stats_ = std::make_unique(); } Engine::~Engine() { + LOG << "Shutting down engine."; + + game_.reset(); stats_.reset(); + textures_.clear(); + shaders_.clear(); + quad_.reset(); + pass_through_shader_.reset(); + solid_shader_.reset(); + renderer_.reset(); singleton = nullptr; } @@ -51,6 +68,8 @@ Engine& Engine::Get() { } bool Engine::Initialize() { + InitializeRenderer(); + // Normalize viewport. if (GetScreenWidth() > GetScreenHeight()) { float aspect_ratio = (float)GetScreenWidth() / (float)GetScreenHeight(); @@ -91,14 +110,6 @@ bool Engine::Initialize() { return true; } -void Engine::Shutdown() { - LOG << "Shutting down engine."; - game_.reset(); - stats_->Destory(); - textures_.clear(); - shaders_.clear(); -} - void Engine::Update(float delta_time) { seconds_accumulated_ += delta_time; ++tick_; @@ -137,20 +148,6 @@ void Engine::Draw(float frame_frac) { renderer_->Present(); } -void Engine::LostFocus() { - audio_mixer_->Suspend(); - - if (game_) - game_->LostFocus(); -} - -void Engine::GainedFocus(bool from_interstitial_ad) { - audio_mixer_->Resume(); - - if (game_) - game_->GainedFocus(from_interstitial_ad); -} - void Engine::AddDrawable(Drawable* drawable) { DCHECK(std::find(drawables_.begin(), drawables_.end(), drawable) == drawables_.end()); @@ -180,25 +177,25 @@ void Engine::RemoveAnimator(Animator* animator) { } void Engine::SwitchRenderer(bool vulkan) { - Renderer* new_renderer = platform_->SwitchRenderer(vulkan); - if (new_renderer == renderer_) - return; + // Renderer* new_renderer = platform_->SwitchRenderer(vulkan); + // if (new_renderer == renderer_) + // return; - renderer_ = new_renderer; - renderer_->SetContextLostCB(std::bind(&Engine::ContextLost, this)); - CreateTextureCompressors(); + // renderer_ = new_renderer; + // renderer_->SetContextLostCB(std::bind(&Engine::ContextLost, this)); + // CreateTextureCompressors(); - for (auto& t : textures_) - t.second.texture->SetRenderer(renderer_); + // for (auto& t : textures_) + // t.second.texture->SetRenderer(renderer_); - for (auto& s : shaders_) - s.second.shader->SetRenderer(renderer_); + // for (auto& s : shaders_) + // s.second.shader->SetRenderer(renderer_); - quad_->SetRenderer(renderer_); - pass_through_shader_->SetRenderer(renderer_); - solid_shader_->SetRenderer(renderer_); + // quad_->SetRenderer(renderer_); + // pass_through_shader_->SetRenderer(renderer_); + // solid_shader_->SetRenderer(renderer_); - ContextLost(); + // ContextLost(); } void Engine::Exit() { @@ -323,40 +320,6 @@ void Engine::RemoveCustomShader(const std::string& asset_name) { shaders_.erase(it); } -void Engine::AddInputEvent(std::unique_ptr event) { - if (replaying_) - return; - - switch (event->GetType()) { - case InputEvent::kDragEnd: - if (((GetScreenSize() / 2) * 0.9f - event->GetVector()).Length() <= - 0.25f) { - SetSatsVisible(!stats_->IsVisible()); - // TODO: Enqueue DragCancel so we can consume this event. - } - break; - case InputEvent::kKeyPress: - if (event->GetKeyPress() == 's') { - SetSatsVisible(!stats_->IsVisible()); - // Consume event. - return; - } - break; - case InputEvent::kDrag: - if (stats_->IsVisible()) { - if ((stats_->GetPosition() - event->GetVector()).Length() <= - stats_->GetSize().y) - stats_->SetPosition(event->GetVector()); - // TODO: Enqueue DragCancel so we can consume this event. - } - break; - default: - break; - } - - input_queue_.push_back(std::move(event)); -} - std::unique_ptr Engine::GetNextInputEvent() { std::unique_ptr event; @@ -490,6 +453,83 @@ bool Engine::IsMobile() const { return platform_->mobile_device(); } +void Engine::OnWindowCreated() { + InitializeRenderer(); +} + +void Engine::OnWindowDestroyed() { + renderer_->Shutdown(); +} + +void Engine::OnWindowResized(int width, int height) { + if (width != renderer_->screen_width() || + height != renderer_->screen_height()) { + renderer_->Shutdown(); + InitializeRenderer(); + } +} + +void Engine::LostFocus() { + audio_mixer_->Suspend(); + + if (game_) + game_->LostFocus(); +} + +void Engine::GainedFocus(bool from_interstitial_ad) { + audio_mixer_->Resume(); + + if (game_) + game_->GainedFocus(from_interstitial_ad); +} + +void Engine::AddInputEvent(std::unique_ptr event) { + if (replaying_) + return; + + event->SetVector(ToPosition(event->GetVector()) * Vector2f(1, -1)); + + switch (event->GetType()) { + case InputEvent::kDragEnd: + if (((GetScreenSize() / 2) * 0.9f - event->GetVector()).Length() <= + 0.25f) { + SetSatsVisible(!stats_->IsVisible()); + // TODO: Enqueue DragCancel so we can consume this event. + } + break; + case InputEvent::kKeyPress: + if (event->GetKeyPress() == 's') { + SetSatsVisible(!stats_->IsVisible()); + // Consume event. + return; + } + break; + case InputEvent::kDrag: + if (stats_->IsVisible()) { + if ((stats_->GetPosition() - event->GetVector()).Length() <= + stats_->GetSize().y) + stats_->SetPosition(event->GetVector()); + // TODO: Enqueue DragCancel so we can consume this event. + } + break; + default: + break; + } + + input_queue_.push_back(std::move(event)); +} + +void Engine::InitializeRenderer() { + bool res; +#if defined(__ANDROID__) + res = renderer_->Initialize(platform_->GetWindow()); +#elif defined(__linux__) + res = renderer_->Initialize(platform_->GetDisplay(), platform_->GetWindow()); +#endif + CHECK(res) << "Failed to initialize " << renderer_->GetDebugName() + << " renderer."; +} + void Engine::CreateTextureCompressors() { tex_comp_alpha_.reset(); tex_comp_opaque_.reset(); @@ -569,7 +609,7 @@ void Engine::SetSatsVisible(bool visible) { if (visible) stats_->Create("stats_tex"); else - stats_->Destory(); + stats_->Destroy(); } std::unique_ptr Engine::PrintStats() { diff --git a/src/engine/engine.h b/src/engine/engine.h index 5bf42a1..0ac97e3 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -10,6 +10,7 @@ #include "base/random.h" #include "base/vecmath.h" #include "engine/persistent_data.h" +#include "engine/platform/platform_observer.h" class TextureCompressor; @@ -29,25 +30,20 @@ class Shader; class Texture; class Platform; -class Engine { +class Engine : public PlatformObserver { public: using CreateImageCB = std::function()>; - Engine(Platform* platform, Renderer* renderer); + Engine(Platform* platform); ~Engine(); static Engine& Get(); bool Initialize(); - void Shutdown(); - void Update(float delta_time); void Draw(float frame_frac); - void LostFocus(); - void GainedFocus(bool from_interstitial_ad); - void AddDrawable(Drawable* drawable); void RemoveDrawable(Drawable* drawable); @@ -66,7 +62,7 @@ class Engine { template std::unique_ptr CreateRenderResource() { - return std::unique_ptr(static_cast(new T(renderer_))); + return std::unique_ptr(static_cast(new T(renderer_.get()))); } void SetImageSource(const std::string& asset_name, @@ -86,7 +82,6 @@ class Engine { Shader* GetCustomShader(const std::string& asset_name); void RemoveCustomShader(const std::string& asset_name); - void AddInputEvent(std::unique_ptr event); std::unique_ptr GetNextInputEvent(); void StartRecording(const Json::Value& payload); @@ -174,10 +169,9 @@ class Engine { static Engine* singleton; Platform* platform_ = nullptr; - Renderer* renderer_ = nullptr; + std::unique_ptr renderer_; std::unique_ptr audio_mixer_; - std::unique_ptr game_; std::unique_ptr quad_; @@ -223,6 +217,16 @@ class Engine { base::Randomf random_; + // PlatformObserver implementation + void OnWindowCreated() final; + void OnWindowDestroyed() final; + void OnWindowResized(int width, int height) final; + void LostFocus() final; + void GainedFocus(bool from_interstitial_ad) final; + void AddInputEvent(std::unique_ptr event) final; + + void InitializeRenderer(); + void CreateTextureCompressors(); void ContextLost(); diff --git a/src/engine/image_quad.cc b/src/engine/image_quad.cc index ab2e11a..dee7504 100644 --- a/src/engine/image_quad.cc +++ b/src/engine/image_quad.cc @@ -13,7 +13,7 @@ namespace eng { ImageQuad::ImageQuad() = default; ImageQuad::~ImageQuad() { - Destory(); + Destroy(); } void ImageQuad::Create(const std::string& asset_name, @@ -32,7 +32,8 @@ void ImageQuad::Create(const std::string& asset_name, asset_name_ = asset_name; } -void ImageQuad::Destory() { +// TODO: typo +void ImageQuad::Destroy() { if (texture_) { Engine::Get().ReleaseTexture(asset_name_); texture_ = nullptr; diff --git a/src/engine/image_quad.h b/src/engine/image_quad.h index d483774..c7e7629 100644 --- a/src/engine/image_quad.h +++ b/src/engine/image_quad.h @@ -24,7 +24,7 @@ class ImageQuad final : public Animatable { int frame_width = 0, int frame_height = 0); - void Destory(); + void Destroy(); void AutoScale(); diff --git a/src/engine/input_event.h b/src/engine/input_event.h index e99fa33..e37d808 100644 --- a/src/engine/input_event.h +++ b/src/engine/input_event.h @@ -27,6 +27,8 @@ class InputEvent { InputEvent(Type type, char key) : type_(type), key_(key) {} ~InputEvent() = default; + void SetVector(base::Vector2f vec) { vec_ = vec; } + Type GetType() const { return type_; } size_t GetPointerId() const { return pointer_id_; } diff --git a/src/engine/platform/platform.cc b/src/engine/platform/platform.cc index c65d6ea..e1a7370 100644 --- a/src/engine/platform/platform.cc +++ b/src/engine/platform/platform.cc @@ -1,12 +1,10 @@ #include "engine/platform/platform.h" +#include + #include "base/log.h" #include "base/task_runner.h" #include "engine/engine.h" -#include "engine/renderer/opengl/renderer_opengl.h" -#include "engine/renderer/vulkan/renderer_vulkan.h" - -#define USE_VULKAN_RENDERER 1 using namespace base; @@ -16,59 +14,46 @@ Platform::Platform() = default; Platform::~Platform() = default; -Renderer* Platform::SwitchRenderer(bool vulkan) { - DCHECK(renderer_); +// Renderer* Platform::SwitchRenderer(bool vulkan) { +// DCHECK(renderer_); - if ((dynamic_cast(renderer_.get()) && vulkan) || - (dynamic_cast(renderer_.get()) && !vulkan)) - return renderer_.get(); +// if ((dynamic_cast(renderer_.get()) && vulkan) || +// (dynamic_cast(renderer_.get()) && !vulkan)) +// return renderer_.get(); - if (vulkan) - renderer_ = std::make_unique(); - else - renderer_ = std::make_unique(); +// if (vulkan) +// renderer_ = std::make_unique(); +// else +// renderer_ = std::make_unique(); - bool result = InitializeRenderer(); - CHECK(result) << "Failed to initialize " << renderer_->GetDebugName() - << " renderer."; - LOG << "Switched to " << renderer_->GetDebugName() << " renderer."; - return renderer_.get(); -} +// bool result = InitializeRenderer(); +// CHECK(result) << "Failed to initialize " << renderer_->GetDebugName() +// << " renderer."; +// LOG << "Switched to " << renderer_->GetDebugName() << " renderer."; +// return renderer_.get(); +// } void Platform::InitializeCommon() { LOG << "Initializing platform."; thread_pool_.Initialize(); TaskRunner::CreateThreadLocalTaskRunner(); - -#if (USE_VULKAN_RENDERER == 1) - renderer_ = std::make_unique(); -#else - renderer_ = std::make_unique(); -#endif -} - -void Platform::ShutdownCommon() { - LOG << "Shutting down platform."; - - renderer_->Shutdown(); } void Platform::RunMainLoop() { - engine_ = - std::make_unique(this, renderer_.get()); - bool res = engine_->Initialize(); + std::unique_ptr engine = std::make_unique(this); + bool res = engine->Initialize(); CHECK(res) << "Failed to initialize the engine."; // Use fixed time steps. - float time_step = engine_->time_step(); + float time_step = engine->time_step(); timer_.Reset(); float accumulator = 0.0; float frame_frac = 0.0f; for (;;) { - engine_->Draw(frame_frac); + engine->Draw(frame_frac); // Accumulate time. timer_.Update(); @@ -79,12 +64,10 @@ void Platform::RunMainLoop() { TaskRunner::GetThreadLocalTaskRunner()->SingleConsumerRun(); Update(); - engine_->Update(time_step); + engine->Update(time_step); if (should_exit_) { thread_pool_.Shutdown(); - engine_->Shutdown(); - engine_.reset(); return; } accumulator -= time_step; diff --git a/src/engine/platform/platform.h b/src/engine/platform/platform.h index 977a868..370f189 100644 --- a/src/engine/platform/platform.h +++ b/src/engine/platform/platform.h @@ -1,7 +1,6 @@ #ifndef ENGINE_PLATFORM_PLATFORM_H #define ENGINE_PLATFORM_PLATFORM_H -#include #include #include "base/thread_pool.h" @@ -24,8 +23,7 @@ struct ANativeWindow; namespace eng { -class Renderer; -class Engine; +class PlatformObserver; class Platform { public: @@ -44,7 +42,9 @@ class Platform { void Exit(); - Renderer* SwitchRenderer(bool vulkan); + void SetObserver(PlatformObserver* observer) { observer_ = observer; } + + // Renderer* SwitchRenderer(bool vulkan); void Vibrate(int duration); @@ -66,7 +66,14 @@ class Platform { bool mobile_device() const { return mobile_device_; } - protected: +#if defined(__ANDROID__) + ANativeWindow* GetWindow(); +#elif defined(__linux__) + Display* GetDisplay(); + Window GetWindow(); +#endif + + private: base::Timer timer_; bool mobile_device_ = false; @@ -78,8 +85,7 @@ class Platform { bool has_focus_ = false; bool should_exit_ = false; - std::unique_ptr renderer_; - std::unique_ptr engine_; + PlatformObserver* observer_ = nullptr; base::ThreadPool thread_pool_; @@ -116,12 +122,11 @@ class Platform { bool CreateWindow(int width, int height); void DestroyWindow(); + XVisualInfo* GetXVisualInfo(Display* display); + #endif void InitializeCommon(); - void ShutdownCommon(); - - bool InitializeRenderer(); Platform(const Platform&) = delete; Platform& operator=(const Platform&) = delete; diff --git a/src/engine/platform/platform_android.cc b/src/engine/platform/platform_android.cc index 1bf6c13..934efcf 100644 --- a/src/engine/platform/platform_android.cc +++ b/src/engine/platform/platform_android.cc @@ -1,5 +1,7 @@ #include "engine/platform/platform.h" +#include + #include #include #include @@ -7,9 +9,8 @@ #include "base/log.h" #include "base/task_runner.h" -#include "engine/engine.h" #include "engine/input_event.h" -#include "engine/renderer/renderer.h" +#include "engine/platform/platform_observer.h" using namespace base; @@ -204,7 +205,7 @@ namespace eng { int32_t Platform::HandleInput(android_app* app, AInputEvent* event) { Platform* platform = reinterpret_cast(app->userData); - if (!platform->engine_) + if (!platform->observer_) return 0; if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY && @@ -212,7 +213,7 @@ int32_t Platform::HandleInput(android_app* app, AInputEvent* event) { if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_UP) { auto input_event = std::make_unique(InputEvent::kNavigateBack); - platform->engine_->AddInputEvent(std::move(input_event)); + platform->observer_->AddInputEvent(std::move(input_event)); } return 1; } else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { @@ -227,7 +228,6 @@ int32_t Platform::HandleInput(android_app* app, AInputEvent* event) { int32_t id = AMotionEvent_getPointerId(event, i); if (id < 2) { pos[id] = {AMotionEvent_getX(event, i), AMotionEvent_getY(event, i)}; - pos[id] = platform->engine_->ToPosition(pos[id]); } } @@ -239,34 +239,30 @@ int32_t Platform::HandleInput(android_app* app, AInputEvent* event) { switch (flags) { case AMOTION_EVENT_ACTION_DOWN: case AMOTION_EVENT_ACTION_POINTER_DOWN: - // DLOG << "AMOTION_EVENT_ACTION_DOWN - pointer_id: " << pointer_id; platform->pointer_pos_[pointer_id] = pos[pointer_id]; platform->pointer_down_[pointer_id] = true; - input_event = - std::make_unique(InputEvent::kDragStart, pointer_id, - pos[pointer_id] * Vector2f(1, -1)); + input_event = std::make_unique(InputEvent::kDragStart, + pointer_id, pos[pointer_id]); break; case AMOTION_EVENT_ACTION_UP: case AMOTION_EVENT_ACTION_POINTER_UP: - // DLOG << "AMOTION_EVENT_ACTION_UP - pointer_id: " << pointer_id; platform->pointer_pos_[pointer_id] = pos[pointer_id]; platform->pointer_down_[pointer_id] = false; - input_event = - std::make_unique(InputEvent::kDragEnd, pointer_id, - pos[pointer_id] * Vector2f(1, -1)); + input_event = std::make_unique(InputEvent::kDragEnd, + pointer_id, pos[pointer_id]); break; case AMOTION_EVENT_ACTION_MOVE: if (platform->pointer_down_[0] && pos[0] != platform->pointer_pos_[0]) { platform->pointer_pos_[0] = pos[0]; - input_event = std::make_unique(InputEvent::kDrag, 0, - pos[0] * Vector2f(1, -1)); + input_event = + std::make_unique(InputEvent::kDrag, 0, pos[0]); } if (platform->pointer_down_[1] && pos[1] != platform->pointer_pos_[1]) { platform->pointer_pos_[1] = pos[1]; - input_event = std::make_unique(InputEvent::kDrag, 1, - pos[1] * Vector2f(1, -1)); + input_event = + std::make_unique(InputEvent::kDrag, 1, pos[1]); } break; @@ -276,7 +272,7 @@ int32_t Platform::HandleInput(android_app* app, AInputEvent* event) { } if (input_event) { - platform->engine_->AddInputEvent(std::move(input_event)); + platform->observer_->AddInputEvent(std::move(input_event)); return 1; } } @@ -295,30 +291,23 @@ void Platform::HandleCmd(android_app* app, int32_t cmd) { DLOG << "APP_CMD_INIT_WINDOW"; if (app->window != NULL) { platform->SetFrameRate(60); - bool res = platform->InitializeRenderer(); - CHECK(res) << "Failed to initialize " - << platform->renderer_->GetDebugName() << " renderer."; + if (platform->observer_) + platform->observer_->OnWindowCreated(); } break; case APP_CMD_TERM_WINDOW: DLOG << "APP_CMD_TERM_WINDOW"; - platform->renderer_->Shutdown(); + if (platform->observer_) + platform->observer_->OnWindowDestroyed(); break; case APP_CMD_CONFIG_CHANGED: DLOG << "APP_CMD_CONFIG_CHANGED"; - if (platform->app_->window != NULL) { - int width = platform->renderer_->screen_width(); - int height = platform->renderer_->screen_height(); - if (width != ANativeWindow_getWidth(app->window) || - height != ANativeWindow_getHeight(app->window)) { - platform->renderer_->Shutdown(); - bool res = platform->InitializeRenderer(); - CHECK(res) << "Failed to initialize " - << platform->renderer_->GetDebugName() << " renderer."; - } - } + if (platform->app_->window != NULL && platform->observer_) + platform->observer_->OnWindowResized( + ANativeWindow_getWidth(app->window), + ANativeWindow_getHeight(app->window)); break; case APP_CMD_STOP: @@ -329,16 +318,16 @@ void Platform::HandleCmd(android_app* app, int32_t cmd) { DLOG << "APP_CMD_GAINED_FOCUS"; platform->timer_.Reset(); platform->has_focus_ = true; - if (platform->engine_) - platform->engine_->GainedFocus(g_showing_interstitial_ad); + if (platform->observer_) + platform->observer_->GainedFocus(g_showing_interstitial_ad); g_showing_interstitial_ad = false; break; case APP_CMD_LOST_FOCUS: DLOG << "APP_CMD_LOST_FOCUS"; platform->has_focus_ = false; - if (platform->engine_) - platform->engine_->LostFocus(); + if (platform->observer_) + platform->observer_->LostFocus(); break; case APP_CMD_LOW_MEMORY: @@ -386,7 +375,7 @@ void Platform::Initialize(android_app* app) { } void Platform::Shutdown() { - Platform::ShutdownCommon(); + LOG << "Shutting down platform."; } void Platform::Update() { @@ -439,8 +428,8 @@ void Platform::SetFrameRate(float frame_rate) { } } -bool Platform::InitializeRenderer() { - return renderer_->Initialize(app_->window); +ANativeWindow* Platform::GetWindow() { + return app_->window; } } // namespace eng diff --git a/src/engine/platform/platform_linux.cc b/src/engine/platform/platform_linux.cc index 4d0982d..dde7862 100644 --- a/src/engine/platform/platform_linux.cc +++ b/src/engine/platform/platform_linux.cc @@ -1,11 +1,12 @@ #include "engine/platform/platform.h" +#include + #include "base/log.h" #include "base/task_runner.h" #include "base/vecmath.h" -#include "engine/engine.h" #include "engine/input_event.h" -#include "engine/renderer/renderer.h" +#include "engine/platform/platform_observer.h" using namespace base; @@ -26,10 +27,6 @@ void Platform::Initialize() { bool res = CreateWindow(800, 1205); CHECK(res) << "Failed to create window."; - res = InitializeRenderer(); - CHECK(res) << "Failed to initialize " << renderer_->GetDebugName() - << " renderer."; - XSelectInput(display_, window_, KeyPressMask | Button1MotionMask | ButtonPressMask | ButtonReleaseMask | FocusChangeMask); @@ -38,8 +35,7 @@ void Platform::Initialize() { } void Platform::Shutdown() { - Platform::ShutdownCommon(); - + LOG << "Shutting down platform."; DestroyWindow(); } @@ -52,47 +48,41 @@ void Platform::Update() { KeySym key = XLookupKeysym(&e.xkey, 0); auto input_event = std::make_unique(InputEvent::kKeyPress, (char)key); - engine_->AddInputEvent(std::move(input_event)); + observer_->AddInputEvent(std::move(input_event)); // TODO: e.xkey.state & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask)) break; } case MotionNotify: { Vector2f v(e.xmotion.x, e.xmotion.y); - v = engine_->ToPosition(v); - // DLOG << "drag: " << v; - auto input_event = std::make_unique(InputEvent::kDrag, 0, - v * Vector2f(1, -1)); - engine_->AddInputEvent(std::move(input_event)); + auto input_event = + std::make_unique(InputEvent::kDrag, 0, v); + observer_->AddInputEvent(std::move(input_event)); break; } case ButtonPress: { if (e.xbutton.button == 1) { Vector2f v(e.xbutton.x, e.xbutton.y); - v = engine_->ToPosition(v); - // DLOG << "drag-start: " << v; - auto input_event = std::make_unique( - InputEvent::kDragStart, 0, v * Vector2f(1, -1)); - engine_->AddInputEvent(std::move(input_event)); + auto input_event = + std::make_unique(InputEvent::kDragStart, 0, v); + observer_->AddInputEvent(std::move(input_event)); } break; } case ButtonRelease: { if (e.xbutton.button == 1) { Vector2f v(e.xbutton.x, e.xbutton.y); - v = engine_->ToPosition(v); - // DLOG << "drag-end!"; - auto input_event = std::make_unique( - InputEvent::kDragEnd, 0, v * Vector2f(1, -1)); - engine_->AddInputEvent(std::move(input_event)); + auto input_event = + std::make_unique(InputEvent::kDragEnd, 0, v); + observer_->AddInputEvent(std::move(input_event)); } break; } case FocusOut: { - engine_->LostFocus(); + observer_->LostFocus(); break; } case FocusIn: { - engine_->GainedFocus(false); + observer_->GainedFocus(false); break; } case ClientMessage: { @@ -127,7 +117,7 @@ bool Platform::CreateWindow(int width, int height) { Window root_window = DefaultRootWindow(display_); - XVisualInfo* visual_info = renderer_->GetXVisualInfo(display_); + XVisualInfo* visual_info = GetXVisualInfo(display_); if (!visual_info) { LOG << "No appropriate visual found."; return false; @@ -151,14 +141,29 @@ bool Platform::CreateWindow(int width, int height) { void Platform::DestroyWindow() { if (display_) { XDestroyWindow(display_, window_); +#if 0 // TODO: Figure out why XCloseDisplay is crashing XCloseDisplay(display_); +#endif display_ = nullptr; window_ = 0; } } -bool Platform::InitializeRenderer() { - return renderer_->Initialize(display_, window_); +Display* Platform::GetDisplay() { + return display_; +} + +Window Platform::GetWindow() { + return window_; +} + +XVisualInfo* Platform::GetXVisualInfo(Display* display) { + long visual_mask = VisualScreenMask; + int num_visuals; + XVisualInfo visual_info_template = {}; + visual_info_template.screen = DefaultScreen(display); + return XGetVisualInfo(display, visual_mask, &visual_info_template, + &num_visuals); } } // namespace eng diff --git a/src/engine/platform/platform_observer.h b/src/engine/platform/platform_observer.h new file mode 100644 index 0000000..d6c11a8 --- /dev/null +++ b/src/engine/platform/platform_observer.h @@ -0,0 +1,23 @@ +#ifndef ENGINE_PLATFORM_PLATFORM_OBSERVER_H +#define ENGINE_PLATFORM_PLATFORM_OBSERVER_H + +namespace eng { + +class InputEvent; + +class PlatformObserver { + public: + PlatformObserver() = default; + virtual ~PlatformObserver() = default; + + virtual void OnWindowCreated() = 0; + virtual void OnWindowDestroyed() = 0; + virtual void OnWindowResized(int width, int height) = 0; + virtual void LostFocus() = 0; + virtual void GainedFocus(bool from_interstitial_ad) = 0; + virtual void AddInputEvent(std::unique_ptr event) = 0; +}; + +} // namespace eng + +#endif // ENGINE_PLATFORM_PLATFORM_OBSERVER_H diff --git a/src/engine/renderer/opengl/renderer_opengl.h b/src/engine/renderer/opengl/renderer_opengl.h index 75f983a..aa7c9f4 100644 --- a/src/engine/renderer/opengl/renderer_opengl.h +++ b/src/engine/renderer/opengl/renderer_opengl.h @@ -89,10 +89,6 @@ class RendererOpenGL final : public Renderer { const char* GetDebugName() final { return "OpenGL"; } -#if defined(__linux__) && !defined(__ANDROID__) - XVisualInfo* GetXVisualInfo(Display* display) final; -#endif - private: struct GeometryOpenGL { struct Element { diff --git a/src/engine/renderer/opengl/renderer_opengl_linux.cc b/src/engine/renderer/opengl/renderer_opengl_linux.cc index 5bb452a..267a5bf 100644 --- a/src/engine/renderer/opengl/renderer_opengl_linux.cc +++ b/src/engine/renderer/opengl/renderer_opengl_linux.cc @@ -21,9 +21,11 @@ bool RendererOpenGL::Initialize(Display* display, Window window) { void RendererOpenGL::OnDestroy() {} bool RendererOpenGL::InitInternal() { - // Create the OpenGL context. + GLint glx_attributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, + None}; + XVisualInfo* visual_info = glXChooseVisual(display_, 0, glx_attributes); glx_context_ = - glXCreateContext(display_, GetXVisualInfo(display_), NULL, GL_TRUE); + glXCreateContext(display_, visual_info, NULL, GL_TRUE); if (!glx_context_) { LOG << "Couldn't create the glx context."; return false; @@ -59,11 +61,4 @@ void RendererOpenGL::HandleCmdPresent(RenderCommand* cmd) { } } -XVisualInfo* RendererOpenGL::GetXVisualInfo(Display* display) { - // Look for the right visual to set up the OpenGL context. - GLint glx_attributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, - None}; - return glXChooseVisual(display, 0, glx_attributes); -} - } // namespace eng diff --git a/src/engine/renderer/renderer.h b/src/engine/renderer/renderer.h index e6bed68..2ce496b 100644 --- a/src/engine/renderer/renderer.h +++ b/src/engine/renderer/renderer.h @@ -94,10 +94,6 @@ class Renderer { virtual const char* GetDebugName() = 0; -#if defined(__linux__) && !defined(__ANDROID__) - virtual XVisualInfo* GetXVisualInfo(Display* display) = 0; -#endif - protected: struct TextureCompression { unsigned etc1 : 1; diff --git a/src/engine/renderer/vulkan/renderer_vulkan.h b/src/engine/renderer/vulkan/renderer_vulkan.h index 38b9bee..5e54c98 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan.h +++ b/src/engine/renderer/vulkan/renderer_vulkan.h @@ -74,10 +74,6 @@ class RendererVulkan final : public Renderer { const char* GetDebugName() final { return "Vulkan"; } -#if defined(__linux__) && !defined(__ANDROID__) - XVisualInfo* GetXVisualInfo(Display* display) final; -#endif - private: // VkBuffer or VkImage with allocator. template diff --git a/src/engine/renderer/vulkan/renderer_vulkan_linux.cc b/src/engine/renderer/vulkan/renderer_vulkan_linux.cc index 4cb66bd..35eea3d 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan_linux.cc +++ b/src/engine/renderer/vulkan/renderer_vulkan_linux.cc @@ -24,13 +24,4 @@ bool RendererVulkan::Initialize(Display* display, Window window) { return InitializeInternal(); } -XVisualInfo* RendererVulkan::GetXVisualInfo(Display* display) { - long visual_mask = VisualScreenMask; - int num_visuals; - XVisualInfo visual_info_template = {}; - visual_info_template.screen = DefaultScreen(display); - return XGetVisualInfo(display, visual_mask, &visual_info_template, - &num_visuals); -} - } // namespace eng