Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libopenage/gamestate/resource.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

#include <string>
#include <cmath>

#include "resource.h"
Expand Down
3 changes: 3 additions & 0 deletions libopenage/gui/guisys/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ list(APPEND QT_SDL_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/private/game_logic_caller.cpp
${CMAKE_CURRENT_SOURCE_DIR}/private/gui_application_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/private/gui_callback.cpp
${CMAKE_CURRENT_SOURCE_DIR}/private/gui_ctx_setup.cpp
${CMAKE_CURRENT_SOURCE_DIR}/private/gui_dedicated_thread.cpp
${CMAKE_CURRENT_SOURCE_DIR}/private/gui_engine_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/private/gui_event_queue_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/private/gui_image_provider_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/private/gui_input_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/private/gui_renderer_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/private/gui_rendering_setup_routines.cpp
${CMAKE_CURRENT_SOURCE_DIR}/private/gui_subtree_impl.cpp
${CMAKE_CURRENT_SOURCE_DIR}/private/opengl_debug_logger.cpp
)

list(APPEND QT_SDL_SOURCES
Expand Down
105 changes: 105 additions & 0 deletions libopenage/gui/guisys/private/gui_ctx_setup.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright 2017-2017 the openage authors. See copying.md for legal info.

#include "gui_ctx_setup.h"

#include <cassert>

#include <QOpenGLDebugLogger>

#include "platforms/context_extraction.h"
#include "opengl_debug_logger.h"

namespace qtsdl {

CtxExtractionException::CtxExtractionException(const std::string &what_arg)
:
std::runtime_error{what_arg} {
}

QOpenGLContext* CtxExtractionMode::get_ctx() {
return &this->ctx;
}

GuiUniqueRenderingContext::GuiUniqueRenderingContext(SDL_Window *window)
:
CtxExtractionMode{} {

QVariant handle;
WId id;

std::tie(handle, id) = extract_native_context(window);

if (handle.isValid()) {
// pass the SDL opengl context so qt can use it
this->ctx.setNativeHandle(handle);
this->ctx.create();
assert(this->ctx.isValid());

// reuse the sdl window
QWindow *w = QWindow::fromWinId(id);
w->setSurfaceType(QSurface::OpenGLSurface);

if (this->ctx.makeCurrent(w)) {
return;
}
}

throw CtxExtractionException("adding GUI to the main rendering context failed");
}

void GuiUniqueRenderingContext::pre_render() {
}

void GuiUniqueRenderingContext::post_render() {
}

GuiSeparateRenderingContext::GuiSeparateRenderingContext(SDL_Window *window)
:
CtxExtractionMode{} {

QVariant handle;

std::tie(handle, this->make_current_back) = extract_native_context_and_switchback_func(window);

if (handle.isValid()) {
this->main_ctx.setNativeHandle(handle);
this->main_ctx.create();
assert(this->main_ctx.isValid());

auto context_debug_parameters = get_current_opengl_debug_parameters(this->main_ctx);

this->ctx.setFormat(this->main_ctx.format());
this->ctx.setShareContext(&this->main_ctx);
this->ctx.create();
assert(this->ctx.isValid());
assert(!(this->main_ctx.format().options() ^ this->ctx.format().options()).testFlag(QSurfaceFormat::DebugContext));

this->offscreen_surface.setFormat(this->ctx.format());
this->offscreen_surface.create();

this->pre_render();
apply_opengl_debug_parameters(context_debug_parameters, this->ctx);
this->post_render();
} else {
throw CtxExtractionException("creating separate context for GUI failed");
}
}

GuiSeparateRenderingContext::~GuiSeparateRenderingContext() {
this->pre_render();
this->ctx_logger.reset();
this->post_render();
}

void GuiSeparateRenderingContext::pre_render() {
if (!this->ctx.makeCurrent(&this->offscreen_surface)) {
assert(false);
return;
}
}

void GuiSeparateRenderingContext::post_render() {
this->make_current_back();
}

} // namespace qtsdl
94 changes: 94 additions & 0 deletions libopenage/gui/guisys/private/gui_ctx_setup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright 2017-2017 the openage authors. See copying.md for legal info.

#pragma once

#include <stdexcept>
#include <memory>
#include <functional>

#include <QOpenGLContext>
#include <QOffscreenSurface>

struct SDL_Window;

QT_FORWARD_DECLARE_CLASS(QOpenGLDebugLogger)

namespace qtsdl {

class CtxExtractionException : public std::runtime_error {
public:
explicit CtxExtractionException(const std::string &what_arg);
};

/**
* Abstract base for the method of getting a Qt-usable context.
*/
class CtxExtractionMode {
public:
virtual ~CtxExtractionMode() {
}

/**
* @return context that can be used by Qt
*/
QOpenGLContext* get_ctx();

/**
* Function that must be called before rendering the GUI.
*/
virtual void pre_render() = 0;

/**
* Function that must be called after rendering the GUI.
*/
virtual void post_render() = 0;

protected:
QOpenGLContext ctx;
};

/**
* Use the same context to render the GUI.
*/
class GuiUniqueRenderingContext : public CtxExtractionMode {
public:
explicit GuiUniqueRenderingContext(SDL_Window *window);

virtual void pre_render() override;
virtual void post_render() override;
};

/**
* Create a separate context to render the GUI, make it shared with the main context.
*/
class GuiSeparateRenderingContext : public CtxExtractionMode {
public:
explicit GuiSeparateRenderingContext(SDL_Window *window);
virtual ~GuiSeparateRenderingContext();

virtual void pre_render() override;
virtual void post_render() override;

private:
/**
* GL context of the game
*/
QOpenGLContext main_ctx;

/**
* GL debug logger of the GL context of the GUI
*/
std::unique_ptr<QOpenGLDebugLogger> ctx_logger;

/**
* Function to make the game context current
*/
std::function<void()> make_current_back;

/**
* Surface that is needed to make the GUI context current
*/
QOffscreenSurface offscreen_surface;
};

} // namespace qtsdl
32 changes: 7 additions & 25 deletions libopenage/gui/guisys/private/gui_renderer_impl.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2015-2016 the openage authors. See copying.md for legal info.
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

#include "gui_renderer_impl.h"

Expand All @@ -12,7 +12,6 @@
#include <QThread>

#include "../public/gui_renderer.h"
#include "platforms/context_extraction.h"


namespace qtsdl {
Expand Down Expand Up @@ -77,6 +76,7 @@ void EventHandlingQuickWindow::on_resized(const QSize &size) {
GuiRendererImpl::GuiRendererImpl(SDL_Window *window)
:
QObject{},
gui_rendering_setup_routines{window},
need_fbo_resize{true},
need_sync{},
need_render{},
Expand All @@ -85,26 +85,6 @@ GuiRendererImpl::GuiRendererImpl(SDL_Window *window)

this->moveToThread(QCoreApplication::instance()->thread());

QVariant handle;
WId id;

std::tie(handle, id) = extract_native_context(window);

// pass the SDL opengl context so qt can use it
this->ctx = std::make_unique<QOpenGLContext>();
this->ctx->setNativeHandle(handle);
this->ctx->create();
assert(this->ctx->isValid());

// reuse the sdl window
QWindow *w = QWindow::fromWinId(id);
w->setSurfaceType(QSurface::OpenGLSurface);

if (!this->ctx->makeCurrent(w)) {
assert(false);
return;
}

QObject::connect(&this->render_control, &QQuickRenderControl::renderRequested, [&] () {
this->need_render = true;
});
Expand All @@ -125,9 +105,9 @@ GuiRendererImpl::GuiRendererImpl(SDL_Window *window)
QObject::connect(&*this->window, &QQuickWindow::widthChanged, [this] { this->new_fbo_width = this->window->width(); this->need_fbo_resize = true; });
QObject::connect(&*this->window, &QQuickWindow::heightChanged, [this] { this->new_fbo_height = this->window->height(); this->need_fbo_resize = true; });

this->render_control.initialize(&*this->ctx);
GuiRenderingCtxActivator activate_render(this->gui_rendering_setup_routines);

assert(this->ctx->isValid());
this->render_control.initialize(this->gui_rendering_setup_routines.get_ctx());
}

void GuiRendererImpl::on_scene_changed() {
Expand All @@ -137,7 +117,7 @@ void GuiRendererImpl::on_scene_changed() {
}

void GuiRendererImpl::reinit_fbo_if_needed() {
assert(QThread::currentThread() == this->ctx->thread());
assert(QThread::currentThread() == this->gui_rendering_setup_routines.get_ctx()->thread());

if (this->need_fbo_resize) {
this->fbo = std::make_unique<QOpenGLFramebufferObject>(QSize(this->new_fbo_width, this->new_fbo_height), QOpenGLFramebufferObject::CombinedDepthStencil);
Expand All @@ -163,6 +143,8 @@ GuiRendererImpl* GuiRendererImpl::impl(GuiRenderer *renderer) {
}

GLuint GuiRendererImpl::render() {
GuiRenderingCtxActivator activate_render(this->gui_rendering_setup_routines);

this->reinit_fbo_if_needed();

// QQuickRenderControl::sync() must be called from the render thread while the gui thread is stopped.
Expand Down
11 changes: 6 additions & 5 deletions libopenage/gui/guisys/private/gui_renderer_impl.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
// Copyright 2015-2016 the openage authors. See copying.md for legal info.
// Copyright 2015-2017 the openage authors. See copying.md for legal info.

#pragma once

#include <memory>
#include <functional>
#include <atomic>
#include <mutex>
#include <condition_variable>
Expand All @@ -14,9 +13,10 @@
#include <QQuickRenderControl>
#include <QOffscreenSurface>

#include "gui_rendering_setup_routines.h"

struct SDL_Window;

QT_FORWARD_DECLARE_CLASS(QOpenGLContext)
QT_FORWARD_DECLARE_CLASS(QOpenGLFramebufferObject)

namespace qtsdl {
Expand Down Expand Up @@ -111,9 +111,10 @@ private slots:
void reinit_fbo_if_needed();

/**
* GL context of the game
* Contains rendering context
* Use GuiRenderingCtxActivator to enable it
*/
std::unique_ptr<QOpenGLContext> ctx;
GuiRenderingSetupRoutines gui_rendering_setup_routines;

/**
* Contains scene graph of the GUI
Expand Down
Loading