瀏覽代碼

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

Lasse Öörni 12 年之前
父節點
當前提交
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_);
     
     // Clean up FBO's that have not been used for a long time, and too large scratch buffers
-    CleanupFramebuffers(false);
+    CleanupFramebuffers();
     CleanupScratchBuffers();
 }
 
@@ -2146,6 +2146,17 @@ void Graphics::Restore()
     if (!impl_->window_)
         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
     if (!impl_->context_)
     {
@@ -2621,15 +2632,15 @@ bool Graphics::CheckFramebuffer()
     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();
             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_);
                 i = impl_->frameBuffers_.Erase(i);

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

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

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

@@ -75,13 +75,17 @@ void IndexBuffer::Release()
     
     if (object_)
     {
-        if (!graphics_ || graphics_->IsDeviceLost())
+        if (!graphics_)
             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;
     }
 }

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

@@ -157,23 +157,25 @@ void RenderSurface::Release()
     if (!graphics)
         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

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

@@ -64,17 +64,21 @@ void ShaderProgram::Release()
         if (!graphics_)
             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;
         linked_ = false;
         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_)
             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;
         compiled_ = false;
         compilerOutput_.Clear();

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

@@ -117,19 +117,23 @@ void Texture2D::Release()
 {
     if (object_)
     {
-        if (!graphics_ || graphics_->IsDeviceLost())
+        if (!graphics_)
             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_)
             renderSurface_->Release();
         
-        glDeleteTextures(1, &object_);
         object_ = 0;
     }
     else

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

@@ -105,13 +105,18 @@ void TextureCube::Release()
 {
     if (object_)
     {
-        if (!graphics_ || graphics_->IsDeviceLost())
+        if (!graphics_)
             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)
@@ -120,7 +125,6 @@ void TextureCube::Release()
                 renderSurfaces_[i]->Release();
         }
         
-        glDeleteTextures(1, &object_);
         object_ = 0;
     }
 }

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

@@ -144,16 +144,20 @@ void VertexBuffer::Release()
     
     if (object_)
     {
-        if (!graphics_ || graphics_->IsDeviceLost())
+        if (!graphics_)
             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;
     }
 }

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

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

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

@@ -18,6 +18,9 @@
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
 */
+
+// Modified by Lasse Oorni for Urho3D
+
 #include "SDL_config.h"
 
 #if SDL_VIDEO_DRIVER_ANDROID
@@ -37,10 +40,8 @@ android_egl_context_restore()
 {
     SDL_WindowData *data = (SDL_WindowData *) Android_Window->driverdata;
     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;
     }
 }