Browse Source

Fixed Android GL context destroy / restore. Removed project.properties file, as it's generated by the command "android update project".

Lasse Öörni 12 years ago
parent
commit
f299c0d815

+ 0 - 14
Source/Android/project.properties

@@ -1,14 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system edit
-# "ant.properties", and override values to adapt the script to your
-# project structure.
-#
-# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
-#proguard.config=${sdk.dir}\tools\proguard\proguard-android.txt:proguard-project.txt
-
-# Project target.
-target=android-10

+ 16 - 5
Source/Engine/Graphics/OpenGL/OGLGraphics.cpp

@@ -533,7 +533,7 @@ void Graphics::EndFrame()
     SDL_GL_SwapWindow(impl_->window_);
     SDL_GL_SwapWindow(impl_->window_);
     
     
     // Clean up FBO's that have not been used for a long time, and too large scratch buffers
     // Clean up FBO's that have not been used for a long time, and too large scratch buffers
-    CleanupFramebuffers(false);
+    CleanupFramebuffers();
     CleanupScratchBuffers();
     CleanupScratchBuffers();
 }
 }
 
 
@@ -2146,6 +2146,17 @@ void Graphics::Restore()
     if (!impl_->window_)
     if (!impl_->window_)
         return;
         return;
     
     
+    #ifdef ANDROID
+    // On Android the context may be lost behind the scenes as the application is minimized
+    if (impl_->context_ && !SDL_GL_GetCurrentContext())
+    {
+        impl_->context_ = 0;
+        // Mark GPU objects lost without a current context. In this case they just mark their internal state lost
+        // but do not perform OpenGL commands to delete the GL objects
+        Release(false, false);
+    }
+    #endif
+    
     // Ensure first that the context exists
     // Ensure first that the context exists
     if (!impl_->context_)
     if (!impl_->context_)
     {
     {
@@ -2621,15 +2632,15 @@ bool Graphics::CheckFramebuffer()
     return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT;
     return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT;
 }
 }
 
 
-void Graphics::CleanupFramebuffers(bool contextLost)
+void Graphics::CleanupFramebuffers(bool force)
 {
 {
-    if (!contextLost)
+    if (!IsDeviceLost())
     {
     {
         for (HashMap<unsigned long long, FrameBufferObject>::Iterator i = impl_->frameBuffers_.Begin();
         for (HashMap<unsigned long long, FrameBufferObject>::Iterator i = impl_->frameBuffers_.Begin();
             i != impl_->frameBuffers_.End();)
             i != impl_->frameBuffers_.End();)
         {
         {
-            if (i->second_.fbo_ != impl_->boundFbo_ && i->second_.useTimer_.GetMSec(false) >
-                MAX_FRAMEBUFFER_AGE)
+            if (i->second_.fbo_ != impl_->boundFbo_ && (force || i->second_.useTimer_.GetMSec(false) >
+                MAX_FRAMEBUFFER_AGE))
             {
             {
                 glDeleteFramebuffersEXT(1, &i->second_.fbo_);
                 glDeleteFramebuffersEXT(1, &i->second_.fbo_);
                 i = impl_->frameBuffers_.Erase(i);
                 i = impl_->frameBuffers_.Erase(i);

+ 1 - 1
Source/Engine/Graphics/OpenGL/OGLGraphics.h

@@ -418,7 +418,7 @@ private:
     /// Check FBO completeness.
     /// Check FBO completeness.
     bool CheckFramebuffer();
     bool CheckFramebuffer();
     /// Cleanup unused and unbound FBO's.
     /// Cleanup unused and unbound FBO's.
-    void CleanupFramebuffers(bool contextLost);
+    void CleanupFramebuffers(bool force = false);
     /// Reset cached rendering state.
     /// Reset cached rendering state.
     void ResetCachedState();
     void ResetCachedState();
     /// Initialize texture unit mappings.
     /// Initialize texture unit mappings.

+ 8 - 4
Source/Engine/Graphics/OpenGL/OGLIndexBuffer.cpp

@@ -75,13 +75,17 @@ void IndexBuffer::Release()
     
     
     if (object_)
     if (object_)
     {
     {
-        if (!graphics_ || graphics_->IsDeviceLost())
+        if (!graphics_)
             return;
             return;
         
         
-        if (graphics_->GetIndexBuffer() == this)
-            graphics_->SetIndexBuffer(0);
+        if (!graphics_->IsDeviceLost())
+        {
+            if (graphics_->GetIndexBuffer() == this)
+                graphics_->SetIndexBuffer(0);
+            
+            glDeleteBuffers(1, &object_);
+        }
         
         
-        glDeleteBuffers(1, &object_);
         object_ = 0;
         object_ = 0;
     }
     }
 }
 }

+ 16 - 14
Source/Engine/Graphics/OpenGL/OGLRenderSurface.cpp

@@ -157,23 +157,25 @@ void RenderSurface::Release()
     if (!graphics)
     if (!graphics)
         return;
         return;
     
     
-    for (unsigned i = 0; i < MAX_RENDERTARGETS; ++i)
+    if (!graphics->IsDeviceLost())
     {
     {
-        if (graphics->GetRenderTarget(i) == this)
-            graphics->ResetRenderTarget(i);
+        for (unsigned i = 0; i < MAX_RENDERTARGETS; ++i)
+        {
+            if (graphics->GetRenderTarget(i) == this)
+                graphics->ResetRenderTarget(i);
+        }
+        
+        if (graphics->GetDepthStencil() == this)
+            graphics->ResetDepthStencil();
+        
+        // Clean up also from non-active FBOs
+        graphics->CleanupRenderSurface(this);
+        
+        if (renderBuffer_)
+            glDeleteRenderbuffersEXT(1, &renderBuffer_);
     }
     }
     
     
-    if (graphics->GetDepthStencil() == this)
-        graphics->ResetDepthStencil();
-    
-    // Clean up also from non-active FBOs
-    graphics->CleanupRenderSurface(this);
-    
-    if (renderBuffer_)
-    {
-        glDeleteRenderbuffersEXT(1, &renderBuffer_);
-        renderBuffer_ = 0;
-    }
+    renderBuffer_ = 0;
 }
 }
 
 
 int RenderSurface::GetWidth() const
 int RenderSurface::GetWidth() const

+ 11 - 7
Source/Engine/Graphics/OpenGL/OGLShaderProgram.cpp

@@ -64,17 +64,21 @@ void ShaderProgram::Release()
         if (!graphics_)
         if (!graphics_)
             return;
             return;
         
         
-        for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
-            useTextureUnit_[i] = false;
-        shaderParameters_.Clear();
-        
-        if (graphics_->GetShaderProgram() == this)
-            graphics_->SetShaders(0, 0);
+        if (!graphics_->IsDeviceLost())
+        {
+            if (graphics_->GetShaderProgram() == this)
+                graphics_->SetShaders(0, 0);
+            
+            glDeleteProgram(object_);
+        }
         
         
-        glDeleteProgram(object_);
         object_ = 0;
         object_ = 0;
         linked_ = false;
         linked_ = false;
         linkerOutput_.Clear();
         linkerOutput_.Clear();
+        shaderParameters_.Clear();
+        
+        for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
+            useTextureUnit_[i] = false;
     }
     }
 }
 }
 
 

+ 13 - 9
Source/Engine/Graphics/OpenGL/OGLShaderVariation.cpp

@@ -63,18 +63,22 @@ void ShaderVariation::Release()
         if (!graphics_)
         if (!graphics_)
             return;
             return;
         
         
-        if (shaderType_ == VS)
+        if (!graphics_->IsDeviceLost())
         {
         {
-            if (graphics_->GetVertexShader() == this)
-                graphics_->SetShaders(0, 0);
-        }
-        else
-        {
-            if (graphics_->GetPixelShader() == this)
-                graphics_->SetShaders(0, 0);
+            if (shaderType_ == VS)
+            {
+                if (graphics_->GetVertexShader() == this)
+                    graphics_->SetShaders(0, 0);
+            }
+            else
+            {
+                if (graphics_->GetPixelShader() == this)
+                    graphics_->SetShaders(0, 0);
+            }
+            
+            glDeleteShader(object_);
         }
         }
         
         
-        glDeleteShader(object_);
         object_ = 0;
         object_ = 0;
         compiled_ = false;
         compiled_ = false;
         compilerOutput_.Clear();
         compilerOutput_.Clear();

+ 9 - 5
Source/Engine/Graphics/OpenGL/OGLTexture2D.cpp

@@ -117,19 +117,23 @@ void Texture2D::Release()
 {
 {
     if (object_)
     if (object_)
     {
     {
-        if (!graphics_ || graphics_->IsDeviceLost())
+        if (!graphics_)
             return;
             return;
         
         
-        for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
+        if (!graphics_->IsDeviceLost())
         {
         {
-            if (graphics_->GetTexture(i) == this)
-                graphics_->SetTexture(i, 0);
+            for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
+            {
+                if (graphics_->GetTexture(i) == this)
+                    graphics_->SetTexture(i, 0);
+            }
+            
+            glDeleteTextures(1, &object_);
         }
         }
         
         
         if (renderSurface_)
         if (renderSurface_)
             renderSurface_->Release();
             renderSurface_->Release();
         
         
-        glDeleteTextures(1, &object_);
         object_ = 0;
         object_ = 0;
     }
     }
     else
     else

+ 9 - 5
Source/Engine/Graphics/OpenGL/OGLTextureCube.cpp

@@ -105,13 +105,18 @@ void TextureCube::Release()
 {
 {
     if (object_)
     if (object_)
     {
     {
-        if (!graphics_ || graphics_->IsDeviceLost())
+        if (!graphics_)
             return;
             return;
         
         
-        for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
+        if (!graphics_->IsDeviceLost())
         {
         {
-            if (graphics_->GetTexture(i) == this)
-                graphics_->SetTexture(i, 0);
+            for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
+            {
+                if (graphics_->GetTexture(i) == this)
+                    graphics_->SetTexture(i, 0);
+            }
+            
+            glDeleteTextures(1, &object_);
         }
         }
         
         
         for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
         for (unsigned i = 0; i < MAX_CUBEMAP_FACES; ++i)
@@ -120,7 +125,6 @@ void TextureCube::Release()
                 renderSurfaces_[i]->Release();
                 renderSurfaces_[i]->Release();
         }
         }
         
         
-        glDeleteTextures(1, &object_);
         object_ = 0;
         object_ = 0;
     }
     }
 }
 }

+ 9 - 5
Source/Engine/Graphics/OpenGL/OGLVertexBuffer.cpp

@@ -144,16 +144,20 @@ void VertexBuffer::Release()
     
     
     if (object_)
     if (object_)
     {
     {
-        if (!graphics_ || graphics_->IsDeviceLost())
+        if (!graphics_)
             return;
             return;
         
         
-        for (unsigned i = 0; i < MAX_VERTEX_STREAMS; ++i)
+        if (!graphics_->IsDeviceLost())
         {
         {
-            if (graphics_->GetVertexBuffer(i) == this)
-                graphics_->SetVertexBuffer(0);
+            for (unsigned i = 0; i < MAX_VERTEX_STREAMS; ++i)
+            {
+                if (graphics_->GetVertexBuffer(i) == this)
+                    graphics_->SetVertexBuffer(0);
+            }
+            
+            glDeleteBuffers(1, &object_);
         }
         }
         
         
-        glDeleteBuffers(1, &object_);
         object_ = 0;
         object_ = 0;
     }
     }
 }
 }

+ 1 - 6
Source/Engine/Input/Input.cpp

@@ -837,13 +837,8 @@ void Input::HandleSDLEvent(void* sdlEvent)
                 break;
                 break;
 
 
             #ifdef ANDROID
             #ifdef ANDROID
-            case SDL_WINDOWEVENT_FOCUS_LOST:
-                // Mark GPU objects lost
-                graphics_->Release(false, false);
-                break;
-
             case SDL_WINDOWEVENT_FOCUS_GAINED:
             case SDL_WINDOWEVENT_FOCUS_GAINED:
-                // Restore GPU objects
+                // Restore GPU objects to the new GL context
                 graphics_->Restore();
                 graphics_->Restore();
                 break;
                 break;
             #endif
             #endif

+ 5 - 4
Source/ThirdParty/SDL/src/video/android/SDL_androidevents.c

@@ -18,6 +18,9 @@
      misrepresented as being the original software.
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
   3. This notice may not be removed or altered from any source distribution.
 */
 */
+
+// Modified by Lasse Oorni for Urho3D
+
 #include "SDL_config.h"
 #include "SDL_config.h"
 
 
 #if SDL_VIDEO_DRIVER_ANDROID
 #if SDL_VIDEO_DRIVER_ANDROID
@@ -37,10 +40,8 @@ android_egl_context_restore()
 {
 {
     SDL_WindowData *data = (SDL_WindowData *) Android_Window->driverdata;
     SDL_WindowData *data = (SDL_WindowData *) Android_Window->driverdata;
     if (SDL_GL_MakeCurrent(Android_Window, (SDL_GLContext) data->egl_context) < 0) {
     if (SDL_GL_MakeCurrent(Android_Window, (SDL_GLContext) data->egl_context) < 0) {
-        /* The context is no longer valid, create a new one */
-        /* FIXME: Notify the user that the context changed and textures need to be re created */
-        data->egl_context = (EGLContext) SDL_GL_CreateContext(Android_Window);
-        SDL_GL_MakeCurrent(Android_Window, (SDL_GLContext) data->egl_context);
+        // Urho3D: if the old context could not be restored, leave it to the Graphics subsystem to create a new one
+        data->egl_context = NULL;
     }
     }
 }
 }