destroy all textures on window destruction and restore OpenGL objects when Android resumes the app

This commit is contained in:
2017-04-28 15:06:23 +01:00
parent 96401a1e5d
commit 2e47ccb0c6
12 changed files with 87 additions and 42 deletions

View File

@@ -357,6 +357,7 @@ static void engine_term_display(struct engine* engine) {
engine->display = EGL_NO_DISPLAY; engine->display = EGL_NO_DISPLAY;
engine->context = EGL_NO_CONTEXT; engine->context = EGL_NO_CONTEXT;
engine->surface = EGL_NO_SURFACE; engine->surface = EGL_NO_SURFACE;
App::I.terminate();
} }
/** /**
@@ -528,7 +529,7 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd) {
case APP_CMD_TERM_WINDOW: case APP_CMD_TERM_WINDOW:
// The window is being hidden or closed, clean it up. // The window is being hidden or closed, clean it up.
engine_term_display(engine); engine_term_display(engine);
exit(0); //exit(0);
break; break;
case APP_CMD_GAINED_FOCUS: case APP_CMD_GAINED_FOCUS:
// When our app gains focus, we start monitoring the accelerometer. // When our app gains focus, we start monitoring the accelerometer.

View File

@@ -499,18 +499,16 @@ void App::initLayout()
} }
}; };
LOG("initializing layout xml"); LOG("initializing layout xml");
#ifdef _WIN32 if (layout.m_loaded)
//layout.load("C:\\Users\\omar\\Desktop\\new_engine\\data\\layout.xml"); layout[main_id]->restore_context();
layout.load("data/layout.xml"); else
#else layout.load("data/layout.xml");
layout.load("data/layout.xml");
#endif
LOG("initializing layout completed"); LOG("initializing layout completed");
} }
void App::initLog() void App::initLog()
{ {
LogRemote::I.start(); //LogRemote::I.start();
} }
void App::init() void App::init()
{ {
@@ -721,3 +719,8 @@ bool App::key_char(char key)
layout[main_id]->update(); layout[main_id]->update();
return ret == kEventResult::Consumed; return ret == kEventResult::Consumed;
} }
void App::terminate()
{
TextureManager::invalidate();
}

View File

@@ -47,6 +47,7 @@ public:
void initAssets(); void initAssets();
void initLayout(); void initLayout();
void create(); void create();
void terminate();
void clear(); void clear();
void update(float dt); void update(float dt);
void resize(float w, float h); void resize(float w, float h);

View File

@@ -364,3 +364,13 @@ bool ui::Canvas::create(int width, int height)
m_mesh.create(); m_mesh.create();
return true; return true;
} }
void ui::Canvas::snapshot_save()
{
}
void ui::Canvas::snapshot_restore()
{
};

View File

@@ -16,6 +16,10 @@ public:
bool m_locked = false; bool m_locked = false;
float m_opacity = 1.f; float m_opacity = 1.f;
std::string m_name; std::string m_name;
struct Snapshot
{
std::unique_ptr<uint8_t[]> image[6];
};
bool create(int width, int height, std::string name) bool create(int width, int height, std::string name)
{ {
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
@@ -44,6 +48,16 @@ public:
// restore clear color state // restore clear color state
glClearColor(cc[0], cc[1], cc[2], cc[3]); glClearColor(cc[0], cc[1], cc[2], cc[3]);
} }
Snapshot snapshot()
{
Snapshot snap;
for (int i = 0; i < 6; i++)
{
snap.image[i] = std::make_unique<uint8_t[]>(m_rtt[i].bytes());
m_rtt[i].readTextureData(snap.image[i].get());
}
return snap;
}
}; };
class Canvas class Canvas
@@ -79,6 +93,8 @@ public:
glm::vec2 m_cam_rot; glm::vec2 m_cam_rot;
float m_cam_fov = 85; float m_cam_fov = 85;
std::vector<Layer::Snapshot> m_layers_snapshot;
bool create(int width, int height); bool create(int width, int height);
void resize(int width, int height); void resize(int width, int height);
void layer_add(std::string name); void layer_add(std::string name);
@@ -89,6 +105,8 @@ public:
void stroke_end(); void stroke_end();
void stroke_commit(); void stroke_commit();
void clear(const glm::vec4& color = { 1, 1, 1, 1 }); void clear(const glm::vec4& color = { 1, 1, 1, 1 });
void snapshot_save();
void snapshot_restore();
}; };

View File

@@ -534,6 +534,9 @@ void Node::clone_children(Node* dest) const
bool LayoutManager::load(const char* path) bool LayoutManager::load(const char* path)
{ {
if (m_loaded)
return true; // already loaded
#ifndef __ANDROID__ #ifndef __ANDROID__
struct stat tmp_info; struct stat tmp_info;
if (stat(path, &tmp_info) != 0) if (stat(path, &tmp_info) != 0)
@@ -598,6 +601,7 @@ bool LayoutManager::load(const char* path)
} }
if (on_loaded) if (on_loaded)
on_loaded(); on_loaded();
m_loaded = true;
return true; return true;
} }

View File

@@ -92,6 +92,7 @@ class LayoutManager
std::string m_path; std::string m_path;
struct stat m_file_info { 0 }; struct stat m_file_info { 0 };
public: public:
bool m_loaded = false;
std::function<void()> on_loaded; std::function<void()> on_loaded;
bool load(const char* path); bool load(const char* path);
bool reload(); bool reload();
@@ -218,6 +219,13 @@ public:
return o; return o;
} }
virtual void restore_context()
{
for (auto& c : m_children)
{
c->restore_context();
}
};
void update(float width, float height, float zoom); void update(float width, float height, float zoom);
void update(); void update();
void update_internal(const glm::vec2& origin, const glm::mat4& proj); void update_internal(const glm::vec2& origin, const glm::mat4& proj);
@@ -275,39 +283,6 @@ public:
void mouse_release() { root()->current_mouse_capture = nullptr; m_mouse_captured = false; } void mouse_release() { root()->current_mouse_capture = nullptr; m_mouse_captured = false; }
void key_capture() { root()->current_key_capture = this; m_key_captured = true; } void key_capture() { root()->current_key_capture = this; m_key_captured = true; }
void key_release() { root()->current_key_capture = nullptr; m_key_captured = false; } void key_release() { root()->current_key_capture = nullptr; m_key_captured = false; }
// class iterator
// {
// std::stack<Node*> m_nodes;
// Node* m_current;
// public:
// iterator(Node* root)
// {
// m_current = root;
// if (root)
// m_nodes.push(root);
// }
// iterator& operator++()
// {
// m_nodes.pop();
// for (auto& c : m_current->m_children)
// m_nodes.push(c.get());
// m_current = m_nodes.size() ? m_nodes.top() : nullptr;
// return *this;
// }
// Node& operator*() { return *m_current; }
// Node* operator->() { return m_current; }
// bool operator==(const iterator& rhs) { return m_current == rhs.m_current; }
// bool operator!=(const iterator& rhs) { return m_current != rhs.m_current; }
// };
// iterator begin()
// {
// return this;
// }
// iterator end()
// {
// return nullptr;
// }
}; };
class NodeBorder : public Node class NodeBorder : public Node
@@ -421,6 +396,11 @@ public:
m_text_mesh.update(font_id, m_text.c_str()); m_text_mesh.update(font_id, m_text.c_str());
SetSize(m_text_mesh.bb); SetSize(m_text_mesh.bb);
} }
virtual void restore_context() override
{
Node::restore_context();
create();
}
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override
{ {
Node::parse_attributes(ka, attr); Node::parse_attributes(ka, attr);
@@ -507,6 +487,11 @@ public:
m_sz = (m_region.zw - m_region.xy) / tex_sz; m_sz = (m_region.zw - m_region.xy) / tex_sz;
} }
} }
virtual void restore_context() override
{
Node::restore_context();
create();
}
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override
{ {
Node::parse_attributes(ka, attr); Node::parse_attributes(ka, attr);
@@ -1711,6 +1696,12 @@ public:
TextureManager::load("data/Icons/Round-Hard.png"); TextureManager::load("data/Icons/Round-Hard.png");
m_brush.m_tex_id = const_hash("data/Icons/Round-Hard.png"); m_brush.m_tex_id = const_hash("data/Icons/Round-Hard.png");
} }
virtual void restore_context() override
{
NodeBorder::restore_context();
init_controls();
m_rtt.create(m_rtt.getWidth(), m_rtt.getHeight());
}
void draw_stroke() void draw_stroke()
{ {
m_rtt.bindFramebuffer(); m_rtt.bindFramebuffer();
@@ -1880,6 +1871,13 @@ public:
m_sampler.create(); m_sampler.create();
m_face_plane.create<1>(2, 2); m_face_plane.create<1>(2, 2);
} }
virtual void restore_context() override
{
Node::restore_context();
m_canvas->create(512, 512);
m_sampler.create();
m_face_plane.create<1>(2, 2);
}
virtual void draw() override virtual void draw() override
{ {
using namespace ui; using namespace ui;

View File

@@ -12,6 +12,9 @@ static size_t data_handler(void *contents, size_t size, size_t nmemb, void *user
void LogRemote::start() void LogRemote::start()
{ {
if (m_running)
return; // already running
m_running = true; m_running = true;
m_thread = std::thread([&] { m_thread = std::thread([&] {
net_init(); net_init();

View File

@@ -144,7 +144,7 @@ void RTT::readTextureData(uint8_t* buffer)
uint8_t* RTT::createBuffer() uint8_t* RTT::createBuffer()
{ {
return new uint8_t[w * h * 3]; return new uint8_t[w * h * 4];
} }
void RTT::bindTexture() void RTT::bindTexture()

View File

@@ -26,5 +26,6 @@ public:
GLuint getTextureID() { return texID; } GLuint getTextureID() { return texID; }
int getWidth() { return w; } int getWidth() { return w; }
int getHeight() { return h; } int getHeight() { return h; }
int bytes() { return w * h * 4; }
GLuint getFBO() { return fboID; } GLuint getFBO() { return fboID; }
}; };

View File

@@ -25,6 +25,11 @@ Texture2D& TextureManager::get(uint16_t id)
return m_textures[id]; return m_textures[id];
} }
void TextureManager::invalidate()
{
m_textures.clear();
}
bool Texture2D::create(int width, int height, GLint internal_format, GLint format, const uint8_t* data) bool Texture2D::create(int width, int height, GLint internal_format, GLint format, const uint8_t* data)
{ {
m_width = width; m_width = width;

View File

@@ -40,4 +40,5 @@ public:
static bool load(const char* path); static bool load(const char* path);
static void assign(uint16_t id, GLuint tex, int w = -1, int h = -1, GLuint internal_format = GL_RGBA8, GLuint format = GL_RGBA); static void assign(uint16_t id, GLuint tex, int w = -1, int h = -1, GLuint internal_format = GL_RGBA8, GLuint format = GL_RGBA);
static Texture2D& get(uint16_t id); static Texture2D& get(uint16_t id);
static void invalidate();
}; };