Updates to handle context loss and regain 69/27369/18
authorDavid Steele <david.steele@partner.samsung.com>
Wed, 10 Sep 2014 17:59:50 +0000 (18:59 +0100)
committerDavid Steele <david.steele@partner.samsung.com>
Wed, 5 Nov 2014 11:39:25 +0000 (11:39 +0000)
[Problem]  Dali doesn't handle context loss
[Cause]    Context loss code, e.g. ReplaceSurface(), has never been tested,
but is required for new platforms.

[Solution] Allow the application to choose either to handle context
loss itself (i.e.  it should connect to the new stage signals
ContextLost and ContextRegained), or to let Dali handle context loss
( which means it needs to retain bitmap data and mesh data, adding a
memory overhead )

For Tizen, if the application doesn't handle context loss, DALi only
actually needs to retain the mesh data, as it can reload bitmaps from
file based images (No other bitmap type is discardable).

It also triggers a reload of the font atlas, although that should be
relatively quick, as the glyphs have already been cached, so it should
be as quick as resizing texture atlas.

It also triggers a refresh of all render tasks with framebuffers and RefreshOnce.

For controls and applications that delete their render tasks after they have finished
rendering, they will need to listen for ContextRegained in order to re-run them to
recreate the resultant framebuffer.

Added tests for mesh data discard using public meshes and meshes loaded via model.

Change-Id: I0d89f0dee2dfcf79fcabce19c36ac129de077fa8
Signed-off-by: David Steele <david.steele@partner.samsung.com>
75 files changed:
automated-tests/src/dali-internal/CMakeLists.txt
automated-tests/src/dali-internal/utc-Dali-Internal-Image-Culling.cpp
automated-tests/src/dali-internal/utc-Dali-Internal-ImageFactory.cpp
automated-tests/src/dali-internal/utc-Dali-Internal-Material.cpp
automated-tests/src/dali-internal/utc-Dali-Internal-Mesh.cpp [new file with mode: 0644]
automated-tests/src/dali-internal/utc-Dali-Internal-ResourceClient.cpp
automated-tests/src/dali-unmanaged/dali-test-suite-utils/test-platform-abstraction.cpp
automated-tests/src/dali-unmanaged/dali-test-suite-utils/test-platform-abstraction.h
automated-tests/src/dali-unmanaged/utc-Dali-NinePatchImages.cpp
automated-tests/src/dali/dali-test-suite-utils/test-application.cpp
automated-tests/src/dali/dali-test-suite-utils/test-application.h
automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h
automated-tests/src/dali/dali-test-suite-utils/test-platform-abstraction.cpp
automated-tests/src/dali/dali-test-suite-utils/test-platform-abstraction.h
automated-tests/src/dali/utc-Dali-Image.cpp
automated-tests/src/dali/utc-Dali-ImageActor.cpp
automated-tests/src/dali/utc-Dali-Material.cpp
automated-tests/src/dali/utc-Dali-RenderTask.cpp
automated-tests/src/dali/utc-Dali-Stage.cpp
dali/integration-api/bitmap.cpp
dali/integration-api/bitmap.h
dali/integration-api/context-notifier.h [new file with mode: 0644]
dali/integration-api/core.cpp
dali/integration-api/core.h
dali/integration-api/file.list
dali/integration-api/platform-abstraction.h
dali/integration-api/resource-policies.h [new file with mode: 0644]
dali/internal/common/core-impl.cpp
dali/internal/common/core-impl.h
dali/internal/event/common/stage-impl.cpp
dali/internal/event/common/stage-impl.h
dali/internal/event/images/bitmap-compressed.cpp
dali/internal/event/images/bitmap-compressed.h
dali/internal/event/images/bitmap-external.cpp
dali/internal/event/images/bitmap-packed-pixel.cpp
dali/internal/event/images/bitmap-packed-pixel.h
dali/internal/event/images/image-factory.cpp
dali/internal/event/images/image-factory.h
dali/internal/event/modeling/mesh-impl.cpp
dali/internal/event/modeling/model-data-impl.cpp
dali/internal/event/render-tasks/render-task-list-impl.cpp
dali/internal/event/render-tasks/render-task-list-impl.h
dali/internal/event/resources/resource-client.cpp
dali/internal/event/resources/resource-client.h
dali/internal/event/text/atlas/glyph-atlas-manager.cpp
dali/internal/event/text/atlas/glyph-atlas-manager.h
dali/internal/event/text/font-factory.cpp
dali/internal/event/text/font-factory.h
dali/internal/event/text/font-impl.cpp
dali/internal/render/common/render-manager.cpp
dali/internal/render/gl-resources/bitmap-texture.cpp
dali/internal/render/gl-resources/bitmap-texture.h
dali/internal/render/gl-resources/compressed-bitmap-texture.cpp
dali/internal/render/gl-resources/compressed-bitmap-texture.h
dali/internal/render/gl-resources/context.cpp
dali/internal/render/gl-resources/context.h
dali/internal/render/gl-resources/texture-cache.cpp
dali/internal/render/gl-resources/texture-cache.h
dali/internal/render/gl-resources/texture-factory.cpp
dali/internal/render/gl-resources/texture-factory.h
dali/internal/render/gl-resources/texture.cpp
dali/internal/render/gl-resources/texture.h
dali/internal/render/renderers/scene-graph-image-renderer.cpp
dali/internal/render/shaders/program.cpp
dali/internal/render/shaders/program.h
dali/internal/render/shaders/shader.cpp
dali/internal/update/modeling/internal-mesh-data.cpp
dali/internal/update/modeling/internal-mesh-data.h
dali/internal/update/modeling/scene-graph-mesh.cpp
dali/internal/update/modeling/scene-graph-mesh.h
dali/internal/update/node-attachments/scene-graph-image-attachment.cpp
dali/internal/update/resources/resource-manager.cpp
dali/internal/update/resources/resource-manager.h
dali/public-api/common/stage.cpp
dali/public-api/common/stage.h

index 39598b87b679facc464814a280b95c9beded616f..c41360ed0e292af091c033353bcc5c2fe2a0234f 100644 (file)
@@ -11,6 +11,7 @@ SET(TC_SOURCES
         utc-Dali-Internal-Handles.cpp
         utc-Dali-Internal-ImageFactory.cpp
         utc-Dali-Internal-Material.cpp
+        utc-Dali-Internal-Mesh.cpp
         utc-Dali-Internal-Text.cpp
         utc-Dali-Internal-ResourceClient.cpp
         utc-Dali-Internal-Image-Culling.cpp
index 95edd1962e0c54d3519776c2a64648a3c94bf917..8945a75878002e438d5e3d102353774b1e70b507 100644 (file)
@@ -65,7 +65,7 @@ Image LoadImage( TestApplication& application, GLuint textureId, int width, int
   ids.push_back( textureId );
   application.GetGlAbstraction().SetNextTextureIds( ids );
 
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, width, height, width, height);
   DALI_TEST_CHECK( application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc) );
index 93648bf8d5f0c38d49b8c5905a2655025e0bd904..59bc9ad28b7a61886d947f7bc86ac80bb59383d3 100644 (file)
@@ -42,7 +42,7 @@ static void EmulateImageLoaded( TestApplication& application, unsigned int width
 {
   // emulate load success
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS,  true  );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS,  ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource( bitmap );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, width, height, width, height );
   if( request )
index 01190b579b45d90f2b8e02efedd957e76b69a2ae..f0446fdd084c0c40e3cae498c39c7bf114097606 100644 (file)
@@ -184,7 +184,7 @@ Internal::ResourceTicketPtr CheckLoadBitmap(TestApplication& application, const
   application.SendNotification(); // Flush update messages
   application.Render();           // Process resource request
   Integration::ResourceRequest*   req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, w, h, w, h );
   Integration::ResourcePointer resourcePtr(bitmap); // reference it
   application.GetPlatform().SetResourceLoaded(req->GetId(), req->GetType()->id, resourcePtr);
@@ -206,7 +206,7 @@ Internal::ImagePtr LoadImage(TestApplication& application, const char* name)
   application.SendNotification(); // Flush update messages
   application.Render();           // Process resource request
   Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 80,80,80,80 );
   Integration::ResourcePointer resourcePtr(bitmap); // reference it
 
@@ -338,7 +338,7 @@ int UtcDaliMaterialUnreadyTextureOffstage(void)
   DALI_TEST_CHECK( textureId == textureId2 );
 
   Integration::ResourceRequest*   req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 80, 80, 80, 80 );
   Integration::ResourcePointer resourcePtr(bitmap); // reference it
   application.GetPlatform().SetResourceLoaded(req->GetId(), req->GetType()->id, resourcePtr);
@@ -569,7 +569,7 @@ int UtcDaliMaterialSetUnreadyTextureWhilstStaged(void)
   DALI_TEST_EQUALS( boundTextures.GetNumBoundTextures(), 0u, TEST_LOCATION );
 
   Integration::ResourceRequest*   req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 80, 80, 80, 80 );
   Integration::ResourcePointer resourcePtr(bitmap); // reference it
   application.GetPlatform().SetResourceLoaded(req->GetId(), req->GetType()->id, resourcePtr);
diff --git a/automated-tests/src/dali-internal/utc-Dali-Internal-Mesh.cpp b/automated-tests/src/dali-internal/utc-Dali-Internal-Mesh.cpp
new file mode 100644 (file)
index 0000000..637f2f1
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+
+#include <stdlib.h>
+#include <dali/public-api/dali-core.h>
+#include <dali-test-suite-utils.h>
+
+// Internal headers are allowed here
+
+#include <dali/internal/event/common/thread-local-storage.h>
+#include <dali/internal/update/resources/resource-manager.h>
+#include <dali/internal/event/resources/resource-client.h>
+#include <dali/internal/event/resources/resource-ticket.h>
+#include <dali/internal/update/modeling/scene-graph-mesh.h>
+
+using namespace Dali;
+#include "mesh-builder.h"
+
+void utc_dali_mesh_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_mesh_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+namespace
+{
+
+unsigned int GetNextResourceId(TestApplication& application)
+{
+  // Attempt to determine what the next resource ID will be
+  Internal::ResourceClient& resourceClient  = Internal::ThreadLocalStorage::Get().GetResourceClient();
+  Internal::ResourceTicketPtr resourceTicket = resourceClient.AllocateTexture( 80, 80, Pixel::RGBA8888 );
+  unsigned int nextResourceId = resourceTicket->GetId();
+  nextResourceId++;
+
+  // Clear allocation request through the system
+  application.SendNotification();
+  application.Render();
+  application.SendNotification();
+
+  return nextResourceId;
+}
+
+Mesh CreateMesh( TestApplication& application )
+{
+  Dali::MeshData publicMeshData;
+  {
+    MeshData::VertexContainer    publicVertices;
+    MeshData::FaceIndices        publicFaces;
+    BoneContainer                bones;
+    ConstructVertices(publicVertices, 60);
+    ConstructFaces(publicVertices, publicFaces);
+    Dali::Material material  = ConstructMaterial();
+    publicMeshData.SetData(publicVertices, publicFaces, bones, material);
+  }
+  Mesh publicMesh = Mesh::New(publicMeshData); // Will generate new request
+
+  application.SendNotification();
+  application.Render(); // Should allocate mesh, pass ownership to ResourceManager
+  application.SendNotification();
+  return publicMesh;
+}
+
+Model CreateModel(TestApplication& application)
+{
+  TestPlatformAbstraction& platform = application.GetPlatform();
+
+  // Raise a request
+  Model model = Model::New("Tree");
+
+  application.SendNotification();
+  application.Render();
+
+  Dali::ModelData modelData = BuildTreeModel();
+  Integration::ResourceRequest* request = platform.GetRequest(); // Return modelData
+  if(request)
+  {
+    platform.SetResourceLoaded(request->GetId(), request->GetType()->id, Integration::ResourcePointer(&(modelData.GetBaseObject())));
+  }
+  application.Render();           // This will perform the GetResources() to get the model data
+  application.SendNotification(); // This will handle model loaded (triggering mesh allocation)
+  application.Render();           // This will allocate meshes in update manager
+  application.SendNotification();
+
+  return model;
+}
+
+
+Internal::MeshData& GetStagedMeshData( unsigned int resourceId )
+{
+    // ResourceManager::GetMesh() will give us the scene graph mesh from resource id
+  Internal::ResourceManager& resourceManager  = Internal::ThreadLocalStorage::Get().GetResourceManager();
+  Internal::SceneGraph::Mesh* internalMesh = resourceManager.GetMesh(resourceId);
+  DALI_TEST_CHECK( internalMesh != NULL );
+  return internalMesh->GetMeshData(Internal::SceneGraph::Mesh::UPDATE_THREAD);
+}
+
+
+void TestMeshDiscard( ResourcePolicy::DataRetention policy, bool expectedDiscardResult )
+{
+  TestApplication application( TestApplication::DEFAULT_SURFACE_WIDTH,
+                               TestApplication::DEFAULT_SURFACE_HEIGHT,
+                               TestApplication::DEFAULT_HORIZONTAL_DPI,
+                               TestApplication::DEFAULT_VERTICAL_DPI,
+                               policy );
+
+  // run through startup, clearing all requests/messages
+  application.SendNotification();
+  application.Render();
+  application.SendNotification();
+
+  unsigned int nextResourceId = GetNextResourceId(application);
+  Mesh publicMesh = CreateMesh(application);
+  Internal::MeshData& meshData = GetStagedMeshData(nextResourceId);
+
+  // Check that the vertex data is allocated
+  const Internal::MeshData::VertexContainer& internalVertices = meshData.GetVertices();
+  const Internal::MeshData::FaceIndices& internalFaces = meshData.GetFaces();
+  DALI_TEST_CHECK( meshData.GetVertexCount() > 0 );
+  DALI_TEST_CHECK( meshData.GetFaceCount() > 0 );
+  DALI_TEST_CHECK( internalVertices.size() > 0 );
+  DALI_TEST_CHECK( internalFaces.size() > 0 );
+
+  // Create an actor that will render the mesh
+  MeshActor actor = MeshActor::New( publicMesh );
+  std::string name = "AMeshActor";
+  actor.SetName(name);
+  actor.SetAffectedByLighting(false);
+  Stage::GetCurrent().Add(actor);
+
+  // render it
+  application.SendNotification();
+  application.Render();
+  application.SendNotification();
+
+  // Check that the vertex data has been discarded
+  DALI_TEST_CHECK( meshData.GetVertexCount() > 0 );
+  DALI_TEST_CHECK( meshData.GetFaceCount() > 0 );
+  if( expectedDiscardResult == false )
+  {
+    DALI_TEST_CHECK( internalVertices.size() > 0 );
+    DALI_TEST_CHECK( internalFaces.size() > 0 );
+  }
+  else
+  {
+    DALI_TEST_CHECK( internalVertices.size() == 0 );
+    DALI_TEST_CHECK( internalFaces.size() == 0 );
+  }
+}
+
+
+
+void TestModelDiscard( ResourcePolicy::DataRetention policy, bool expectedDiscardResult )
+{
+  TestApplication application( TestApplication::DEFAULT_SURFACE_WIDTH,
+                               TestApplication::DEFAULT_SURFACE_HEIGHT,
+                               TestApplication::DEFAULT_HORIZONTAL_DPI,
+                               TestApplication::DEFAULT_VERTICAL_DPI,
+                               policy );
+
+  // run through startup, clearing all requests/messages
+  application.SendNotification();
+  application.Render();
+  application.SendNotification();
+
+  unsigned int nextResourceId = GetNextResourceId(application);
+  Model model = CreateModel(application);
+
+  // 2 resource id's should be generated, 1st for the model, 2nd for the only mesh
+  Internal::MeshData& meshData = GetStagedMeshData(nextResourceId+1);
+
+  // Check that the vertex data is allocated
+  const Internal::MeshData::VertexContainer& internalVertices = meshData.GetVertices();
+  const Internal::MeshData::FaceIndices& internalFaces = meshData.GetFaces();
+  DALI_TEST_CHECK( meshData.GetVertexCount() > 0 );
+  DALI_TEST_CHECK( meshData.GetFaceCount() > 0 );
+  DALI_TEST_CHECK( internalVertices.size() > 0 );
+  DALI_TEST_CHECK( internalFaces.size() > 0 );
+
+  // Create an actor that will render the mesh
+  Actor actor = ModelActorFactory::BuildActorTree(model, ""); // model should be loaded
+  Light light = Light::New("KeyLight");
+  light.SetFallOff(Vector2(10000.0f, 10000.0f));
+  LightActor keyLightActor = LightActor::New();
+  keyLightActor.SetParentOrigin(ParentOrigin::CENTER);
+  keyLightActor.SetPosition(200.0f, 500.0f, 300.0f);
+  keyLightActor.SetName(light.GetName());
+  keyLightActor.SetLight(light);
+  keyLightActor.SetActive(true);
+  Stage::GetCurrent().Add(keyLightActor);
+  Stage::GetCurrent().Add(actor);
+
+  // render it
+  application.SendNotification();
+  application.Render();
+  application.SendNotification();
+
+  // Check that the vertex data has been discarded
+  DALI_TEST_CHECK( meshData.GetVertexCount() > 0 );
+  DALI_TEST_CHECK( meshData.GetFaceCount() > 0 );
+  if( expectedDiscardResult == false )
+  {
+    DALI_TEST_CHECK( internalVertices.size() > 0 );
+    DALI_TEST_CHECK( internalFaces.size() > 0 );
+  }
+  else
+  {
+    DALI_TEST_CHECK( internalVertices.size() == 0 );
+    DALI_TEST_CHECK( internalFaces.size() == 0 );
+  }
+}
+
+
+} // anon namespace
+
+
+int utcDaliInternalMeshDiscard01(void)
+{
+  tet_infoline("Test that internal mesh data is discarded after rendering with policy=DISCARD_ALL");
+  TestMeshDiscard( ResourcePolicy::DALI_DISCARDS_ALL_DATA, true /* Not discarded */);
+  END_TEST;
+}
+
+int utcDaliInternalMeshDiscard02(void)
+{
+  tet_infoline("Test that internal mesh data is not discarded after rendering with policy=RETAIN_ALL");
+  TestMeshDiscard( ResourcePolicy::DALI_RETAINS_ALL_DATA, false /* Not discarded */);
+  END_TEST;
+}
+
+int utcDaliInternalMeshDiscard03(void)
+{
+  tet_infoline("Test that internal mesh data is not discarded after rendering with policy=RETAIN_MESH");
+  TestMeshDiscard( ResourcePolicy::DALI_RETAINS_MESH_DATA, false /* Not discarded */);
+  END_TEST;
+}
+
+int utcDaliInternalModelDiscard01(void)
+{
+  tet_infoline("Test that model's internal mesh data is discarded after rendering with policy=DISCARD_ALL");
+  TestModelDiscard( ResourcePolicy::DALI_DISCARDS_ALL_DATA, true /* Not discarded */);
+  END_TEST;
+}
+
+int utcDaliInternalModelDiscard02(void)
+{
+  tet_infoline("Test that model's internal mesh data is not discarded after rendering with policy=RETAIN_ALL");
+  TestModelDiscard( ResourcePolicy::DALI_RETAINS_ALL_DATA, false /* Not discarded */);
+  END_TEST;
+}
+
+int utcDaliInternalModelDiscard03(void)
+{
+  tet_infoline("Test that model's internal mesh data is not discarded after rendering with policy=RETAIN_MESH");
+  TestModelDiscard( ResourcePolicy::DALI_RETAINS_MESH_DATA, false /* Not discarded */);
+  END_TEST;
+}
index c93981c9b221a557865a199f130e4848ccee286d..0fb9244319d458ae00c9c172784a3ada6788677a 100644 (file)
@@ -121,7 +121,7 @@ Internal::ImagePtr LoadImage(TestApplication& application, char* name)
   application.SendNotification(); // Flush update messages
   application.Render();           // Process resource request
   Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 80,80,80,80 );
   Integration::ResourcePointer resourcePtr(bitmap); // reference it
   application.GetPlatform().SetResourceLoaded(req->GetId(), req->GetType()->id, resourcePtr);
@@ -144,7 +144,7 @@ Internal::ResourceTicketPtr CheckLoadBitmap(TestApplication& application, const
   application.SendNotification(); // Flush update messages
   application.Render();           // Process resource request
   Integration::ResourceRequest*   req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, w, h, w, h );
   Integration::ResourcePointer resourcePtr(bitmap); // reference it
   application.GetPlatform().SetResourceLoaded(req->GetId(), req->GetType()->id, resourcePtr);
@@ -234,7 +234,7 @@ int UtcDaliInternalRequestResourceBitmapRequests01(void)
 
     // Create a resource
     Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
-    Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+    Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
     bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 80, 80, 80, 80 );
     Integration::ResourcePointer resourcePtr(bitmap); // reference it
 
@@ -449,7 +449,7 @@ int UtcDaliInternalRequestReloadBitmapRequests01(void)
 
     // Create a new resource - the image size could have changed in the meantime
     Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
-    Integration::Bitmap* bitmap2 = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+    Integration::Bitmap* bitmap2 = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
     bitmap2->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 120, 120, 120, 120 );
     Integration::ResourcePointer resourcePtr2(bitmap2); // reference it
     DALI_TEST_CHECK( req->GetId() == ticket->GetId() );
@@ -548,7 +548,7 @@ int UtcDaliInternalRequestReloadBitmapRequests02(void)
     DALI_TEST_CHECK( application.GetPlatform().WasCalled(TestPlatformAbstraction::GetResourcesFunc ) );
     // Create a resource
     Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
-    Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+    Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
     bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 80, 80, 80, 80 );
     Integration::ResourcePointer resourcePtr(bitmap); // reference it
 
@@ -658,7 +658,7 @@ int UtcDaliInternalRequestReloadBitmapRequests03(void)
 
     // Create a resource
     Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
-    Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+    Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
     bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 80, 80, 80, 80 );
     Integration::ResourcePointer resourcePtr(bitmap); // reference it
 
@@ -702,7 +702,7 @@ int UtcDaliInternalRequestReloadBitmapRequests03(void)
 
     // Create a new resource - the image size could have changed in the meantime
     req = application.GetPlatform().GetRequest();
-    Integration::Bitmap* bitmap2 = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+    Integration::Bitmap* bitmap2 = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
     bitmap2->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 120, 120, 120, 120 );
     Integration::ResourcePointer resourcePtr2(bitmap2); // reference it
     DALI_TEST_CHECK( req->GetId() == id );
@@ -1119,7 +1119,7 @@ int UtcDaliInternalAddBitmapImage01(void)
   tet_infoline("Testing AddBitmap with reserved buffer()");
   testTicketObserver.Reset();
   Internal::ResourceClient& resourceClient  = Internal::ThreadLocalStorage::Get().GetResourceClient();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS,  false  );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS,  ResourcePolicy::RETAIN  );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGB565, 80, 80, 80, 80 );
 
   Internal::ImageTicketPtr imageTicket = resourceClient.AddBitmapImage( bitmap );
@@ -1158,7 +1158,7 @@ int UtcDaliInternalAddBitmapImage02(void)
   tet_infoline("Testing AddBitmap without reserved buffer()");
   testTicketObserver.Reset();
   Internal::ResourceClient& resourceClient  = Internal::ThreadLocalStorage::Get().GetResourceClient();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS,  false  );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS,  ResourcePolicy::RETAIN  );
 
   Internal::ImageTicketPtr imageTicket = resourceClient.AddBitmapImage( bitmap );
   DALI_TEST_CHECK( imageTicket );
@@ -1225,7 +1225,7 @@ int UtcDaliInternalGetBitmapImage01(void)
   testTicketObserver.Reset();
 
   Internal::ResourceClient& resourceClient  = Internal::ThreadLocalStorage::Get().GetResourceClient();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS,  false  );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS,  ResourcePolicy::RETAIN  );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 20, 20, 80, 80 );
   Internal::ImageTicketPtr imageTicket = resourceClient.AddBitmapImage( bitmap );
 
@@ -1404,7 +1404,7 @@ int UtcDaliInternalAllocateMesh01(void)
 
   testTicketObserver.Reset();
   Internal::ResourceClient& resourceClient  = Internal::ThreadLocalStorage::Get().GetResourceClient();
-  Internal::OwnerPointer<Internal::MeshData> meshDataPtr( new Internal::MeshData( publicMeshData, true, true ) );
+  Internal::OwnerPointer<Internal::MeshData> meshDataPtr( new Internal::MeshData( publicMeshData, ResourcePolicy::DISCARD, true ) );
   Internal::ResourceTicketPtr meshTicket = resourceClient.AllocateMesh(meshDataPtr);
   DALI_TEST_CHECK( meshTicket );
   meshTicket->AddObserver( testTicketObserver );
index 22b046692da43405a6038384ca9231cbde7a42a3..d5f24ab063fc1769b0eb367d9065fa8d48d5166b 100644 (file)
@@ -217,7 +217,7 @@ Integration::GlyphSet* TestPlatformAbstraction::GetGlyphData ( const Integration
 
       if( getBitmap )
       {
-        bitmapData = Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true);
+        bitmapData = Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD);
         bitmapData->GetPackedPixelsProfile()->ReserveBuffer(Pixel::A8, 64, 64);
         PixelBuffer* pixelBuffer = bitmapData->GetBuffer();
         memset( pixelBuffer, it->character, 64*64 );
@@ -258,7 +258,7 @@ Integration::GlyphSet* TestPlatformAbstraction::GetCachedGlyphData( const Integr
       characters.insert( it->character );
       Integration::GlyphMetrics character = {it->character, Integration::GlyphMetrics::HIGH_QUALITY,  10.0f,  10.0f, 9.0f, 1.0f, 10.0f, it->xPosition, it->yPosition };
 
-      bitmapData = Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true);
+      bitmapData = Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD);
       bitmapData->GetPackedPixelsProfile()->ReserveBuffer(Pixel::A8, 64, 64);
       PixelBuffer* pixelBuffer = bitmapData->GetBuffer();
       memset( pixelBuffer, it->character, 64*64 );
@@ -447,7 +447,7 @@ void TestPlatformAbstraction::GetFileNamesFromDirectory( const std::string& dire
 
 Integration::BitmapPtr TestPlatformAbstraction::GetGlyphImage( const std::string& fontFamily, const std::string& fontStyle, float fontSize, uint32_t character ) const
 {
-  Integration::BitmapPtr image = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::BitmapPtr image = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   image->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 1, 1 );
 
   mTrace.PushCall("GetGlyphImage", "");
@@ -455,7 +455,6 @@ Integration::BitmapPtr TestPlatformAbstraction::GetGlyphImage( const std::string
   return image;
 }
 
-
 /** Call this every test */
 void TestPlatformAbstraction::Initialize()
 {
index 6ecfe0781aa53a1d0e4582d6871d31021c1bd9f4..e8614ec3a0eb07df8de149e5d5115a0a482f90fa 100644 (file)
@@ -235,7 +235,6 @@ public:
 
   virtual Integration::BitmapPtr GetGlyphImage( const std::string& fontFamily, const std::string& fontStyle, float fontSize, uint32_t character ) const;
 
-
 public: // TEST FUNCTIONS
 
   // Enumeration of Platform Abstraction methods
@@ -323,7 +322,6 @@ public: // TEST FUNCTIONS
 
   void SetReadMetricsResult( bool success, std::vector<Integration::GlyphMetrics>& glyphMetricsContainer );
 
-
 private:
   mutable TraceCallStack        mTrace;
   size_t                        mSeconds;
index 9f1b8fd34a7312af072961be51c695c925b8059b..bd2560b6a5eb41851a219058ab8a10393ed35b39 100644 (file)
@@ -27,7 +27,7 @@ namespace {
 
 Integration::Bitmap* CreateBitmap( unsigned int imageHeight, unsigned int imageWidth, unsigned int initialColor, Pixel::Format pixelFormat )
 {
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   Integration::PixelBuffer* pixbuffer = bitmap->GetPackedPixelsProfile()->ReserveBuffer( pixelFormat,  imageWidth,imageHeight,imageWidth,imageHeight );
   unsigned int bytesPerPixel = GetBytesPerPixel(  pixelFormat );
 
index c2680b229b4a5ba368f247b761de8bfc3dbe47ee..ff8ec11f4f8370ae06275dc194e44a74fcf86098 100644 (file)
@@ -24,13 +24,15 @@ namespace Dali
 TestApplication::TestApplication( size_t surfaceWidth,
                                   size_t surfaceHeight,
                                   float  horizontalDpi,
-                                  float  verticalDpi)
+                                  float  verticalDpi,
+                                  ResourcePolicy::DataRetention policy)
 : mCore( NULL ),
   mSurfaceWidth( surfaceWidth ),
   mSurfaceHeight( surfaceHeight ),
   mFrame( 0u ),
   mDpi( horizontalDpi, verticalDpi ),
-  mLastVSyncTime(0u)
+  mLastVSyncTime(0u),
+  mDataRetentionPolicy(policy)
 {
   Initialize();
 }
@@ -39,12 +41,15 @@ TestApplication::TestApplication( bool   initialize,
                                   size_t surfaceWidth,
                                   size_t surfaceHeight,
                                   float  horizontalDpi,
-                                  float  verticalDpi )
+                                  float  verticalDpi,
+                                  ResourcePolicy::DataRetention policy)
 : mCore( NULL ),
   mSurfaceWidth( surfaceWidth ),
   mSurfaceHeight( surfaceHeight ),
   mFrame( 0u ),
-  mDpi( horizontalDpi, verticalDpi )
+  mDpi( horizontalDpi, verticalDpi ),
+  mLastVSyncTime(0u),
+  mDataRetentionPolicy( policy )
 {
   if ( initialize )
   {
@@ -59,7 +64,8 @@ void TestApplication::Initialize()
     mPlatformAbstraction,
     mGlAbstraction,
     mGlSyncAbstraction,
-    mGestureManager );
+    mGestureManager,
+    mDataRetentionPolicy);
 
   mCore->ContextCreated();
   mCore->SurfaceResized( mSurfaceWidth, mSurfaceHeight );
@@ -190,7 +196,7 @@ bool TestApplication::RenderOnly( )
 
 void TestApplication::ResetContext()
 {
-  mCore->ContextToBeDestroyed();
+  mCore->ContextDestroyed();
   mCore->ContextCreated();
 }
 
index bcc2dd8dd85b5df48ae750326ec2b004ceb679b4..c91086e3bcb9e7fa399aaf344ea0c1b098ec9cb8 100644 (file)
@@ -25,6 +25,7 @@
 #include "test-gl-abstraction.h"
 #include "test-render-controller.h"
 #include <dali/public-api/common/dali-common.h>
+#include <dali/integration-api/resource-policies.h>
 
 namespace Dali
 {
@@ -50,13 +51,15 @@ public:
   TestApplication( size_t surfaceWidth  = DEFAULT_SURFACE_WIDTH,
                    size_t surfaceHeight = DEFAULT_SURFACE_HEIGHT,
                    float  horizontalDpi = DEFAULT_HORIZONTAL_DPI,
-                   float  verticalDpi   = DEFAULT_VERTICAL_DPI );
+                   float  verticalDpi   = DEFAULT_VERTICAL_DPI,
+                   ResourcePolicy::DataRetention policy = ResourcePolicy::DALI_DISCARDS_ALL_DATA);
 
   TestApplication( bool   initialize,
                    size_t surfaceWidth  = DEFAULT_SURFACE_WIDTH,
                    size_t surfaceHeight = DEFAULT_SURFACE_HEIGHT,
                    float  horizontalDpi = DEFAULT_HORIZONTAL_DPI,
-                   float  verticalDpi   = DEFAULT_VERTICAL_DPI );
+                   float  verticalDpi   = DEFAULT_VERTICAL_DPI,
+                   ResourcePolicy::DataRetention policy = ResourcePolicy::DALI_DISCARDS_ALL_DATA);
 
   void Initialize();
   virtual ~TestApplication();
@@ -97,6 +100,7 @@ protected:
 
   Vector2 mDpi;
   unsigned int mLastVSyncTime;
+  ResourcePolicy::DataRetention mDataRetentionPolicy;
 };
 
 } // Dali
index b094fdec5b62c86a4d189e9aa5a16bb92be2bff8..52ab7a6bb899c0c744d4e0a67907865642f068c6 100644 (file)
@@ -489,7 +489,7 @@ public:
         out << ", ";
       }
     }
-    mTextureTrace.PushCall("GenTexture", out.str());
+    mTextureTrace.PushCall("GenTextures", out.str());
   }
 
   inline void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
index ef3eb772e2b3bb42425a8651b8f5d1191b249fb9..779fd2ab50002a7efa37e2c4cfc9b4fd0397b256 100644 (file)
@@ -227,7 +227,7 @@ Integration::GlyphSet* TestPlatformAbstraction::GetGlyphData ( const Integration
 
       if( getBitmap )
       {
-        bitmapData = Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true);
+        bitmapData = Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD);
         bitmapData->GetPackedPixelsProfile()->ReserveBuffer(Pixel::A8, 64, 64);
         PixelBuffer* pixelBuffer = bitmapData->GetBuffer();
         memset( pixelBuffer, it->character, 64*64 );
@@ -268,7 +268,7 @@ Integration::GlyphSet* TestPlatformAbstraction::GetCachedGlyphData( const Integr
       characters.insert( it->character );
       Integration::GlyphMetrics character = {it->character, Integration::GlyphMetrics::HIGH_QUALITY,  10.0f,  10.0f, 9.0f, 1.0f, 10.0f, it->xPosition, it->yPosition };
 
-      bitmapData = Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true);
+      bitmapData = Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD);
       bitmapData->GetPackedPixelsProfile()->ReserveBuffer(Pixel::A8, 64, 64);
       PixelBuffer* pixelBuffer = bitmapData->GetBuffer();
       memset( pixelBuffer, it->character, 64*64 );
@@ -455,7 +455,7 @@ void TestPlatformAbstraction::GetFileNamesFromDirectory( const std::string& dire
 
 Integration::BitmapPtr TestPlatformAbstraction::GetGlyphImage( const std::string& fontFamily, const std::string& fontStyle, float fontSize, uint32_t character ) const
 {
-  Integration::BitmapPtr image = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::BitmapPtr image = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   image->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 1, 1 );
 
   mTrace.PushCall("GetGlyphImage", "");
@@ -645,4 +645,5 @@ void TestPlatformAbstraction::SetReadMetricsResult( bool success, std::vector<In
   mReadMetrics = glyphMetricsContainer; // copy
 }
 
+
 } // namespace Dali
index 2d4c38c9d467769b4a146815d062f66e0986b280..f3f22ac81c4f4baf789951b939b0d4ff5d4978e3 100644 (file)
@@ -325,8 +325,6 @@ public: // TEST FUNCTIONS
   void SetReadGlobalMetricsResult( bool success, Integration::GlobalMetrics& globalMetrics );
 
   void SetReadMetricsResult( bool success, std::vector<Integration::GlyphMetrics>& glyphMetricsContainer );
-
-
 private:
   mutable TraceCallStack        mTrace;
   size_t                        mSeconds;
index f070c16c4515c8b9c9376a21f2203b4edffd4f4d..491f61855f06b54a4827d29e5fa201f53b0ac736 100644 (file)
@@ -131,7 +131,7 @@ int UtcDaliImageNewWithPolicies01(void)
   ids.push_back( 23 );
   application.GetGlAbstraction().SetNextTextureIds( ids );
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
 
@@ -189,7 +189,7 @@ int UtcDaliImageNewWithPolicies02(void)
   ids.push_back( 23 );
   application.GetGlAbstraction().SetNextTextureIds( ids );
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
 
@@ -245,7 +245,7 @@ int UtcDaliImageNewWithPolicies03(void)
   ids.push_back( 23 );
   application.GetGlAbstraction().SetNextTextureIds( ids );
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
 
@@ -311,7 +311,7 @@ int UtcDaliImageNewWithPolicies04(void)
   ids.push_back( 23 );
   application.GetGlAbstraction().SetNextTextureIds( ids );
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
 
@@ -398,7 +398,7 @@ int UtcDaliImageNewDistanceFieldWithPolicies01(void)
   ids.push_back( 23 );
   application.GetGlAbstraction().SetNextTextureIds( ids );
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
 
@@ -457,7 +457,7 @@ int UtcDaliImageNewDistanceFieldWithPolicies02(void)
   ids.push_back( 23 );
   application.GetGlAbstraction().SetNextTextureIds( ids );
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
 
@@ -513,7 +513,7 @@ int UtcDaliImageNewDistanceFieldWithPolicies03(void)
   ids.push_back( 23 );
   application.GetGlAbstraction().SetNextTextureIds( ids );
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
 
@@ -579,7 +579,7 @@ int UtcDaliImageNewDistanceFieldWithPolicies04(void)
   ids.push_back( 23 );
   application.GetGlAbstraction().SetNextTextureIds( ids );
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
 
@@ -671,7 +671,7 @@ int UtcDaliImageNewDistanceFieldWithAttrandPol(void)
   ids.push_back( 23 );
   application.GetGlAbstraction().SetNextTextureIds( ids );
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
 
@@ -769,7 +769,7 @@ int UtcDaliImageGetLoadingState01(void)
 
   // simulate load success
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
 
@@ -886,7 +886,7 @@ int UtcDaliImageSignalLoadingFinished(void)
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
   if(request)
   {
-    application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, Integration::ResourcePointer(Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true)));
+    application.GetPlatform().SetResourceLoaded(request->GetId(), request->GetType()->id, Integration::ResourcePointer(Integration::Bitmap::New(Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD)));
   }
 
   application.Render(16);
@@ -916,7 +916,7 @@ int UtcDaliImageSignalUploaded(void)
   ids.push_back( 23 );
   application.GetGlAbstraction().SetNextTextureIds( ids );
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
   if(request)
@@ -983,7 +983,7 @@ int UtcDaliImageDiscard01(void)
     ids.push_back( 23 );
     application.GetGlAbstraction().SetNextTextureIds( ids );
     Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-    Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+    Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
     Integration::ResourcePointer resource(bitmap);
     bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
     if(request)
@@ -1032,7 +1032,7 @@ int UtcDaliImageDiscard02(void)
         application.GetGlAbstraction().SetNextTextureIds( ids );
 
         Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-        Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+        Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
         Integration::ResourcePointer resource(bitmap);
         bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
         if(request)
@@ -1086,7 +1086,8 @@ int UtcDaliImageDiscard03(void)
   application.GetGlAbstraction().SetNextTextureIds( ids );
 
   Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
+
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
   if(request)
@@ -1113,3 +1114,97 @@ int UtcDaliImageDiscard03(void)
 
   END_TEST;
 }
+
+
+namespace
+{
+void LoadBitmapResource(TestPlatformAbstraction& platform)
+{
+  Integration::ResourceRequest* request = platform.GetRequest();
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
+  Integration::ResourcePointer resource(bitmap);
+  bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
+
+  if(request)
+  {
+    platform.SetResourceLoaded(request->GetId(), request->GetType()->id, resource);
+  }
+}
+
+}
+
+int UtcDaliImageContextLoss(void)
+{
+  TestApplication application; // Default config: DALI_DISCARDS_ALL_DATA
+
+  const Vector2 closestImageSize( 80, 80 );
+  TestPlatformAbstraction& platform = application.GetPlatform();
+  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
+
+  platform.SetClosestImageSize(closestImageSize);
+
+  tet_infoline("UtcDaliImageContextLoss - Load image with LoadPolicy::Immediate, ReleasePolicy::Never, bitmap discard. Check that the image is re-requested on context regain\n");
+
+  Image image = Image::New("image.png", Image::Immediate, Image::Never);
+
+  DALI_TEST_CHECK( image );
+
+  application.SendNotification();
+  application.Render(16);
+
+  // request file loading immediately
+
+  DALI_TEST_CHECK( platform.WasCalled(TestPlatformAbstraction::LoadResourceFunc) );
+  ImageActor actor = ImageActor::New(image);
+  Stage::GetCurrent().Add(actor);
+
+  application.SendNotification();
+  application.Render(16);
+
+  TraceCallStack& textureTrace = glAbstraction.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  std::vector<GLuint> ids;
+  ids.push_back( 23 );
+  glAbstraction.SetNextTextureIds( ids );
+
+  LoadBitmapResource(platform);
+
+  application.Render(16);
+  application.SendNotification();
+
+  DALI_TEST_CHECK( textureTrace.FindMethod("GenTextures") );
+
+  textureTrace.Reset();
+  textureTrace.Enable(true);
+  platform.ResetTrace();
+  platform.EnableTrace(true);
+
+  // Lose & regain context (in render 'thread')
+  application.ResetContext();
+
+  application.GetCore().RecoverFromContextLoss(); // start the recovery process
+  application.SendNotification();
+
+  // Run update/render loop
+  application.Render(16);
+  application.SendNotification();
+
+  // Expect new load request
+  DALI_TEST_CHECK( platform.WasCalled(TestPlatformAbstraction::LoadResourceFunc) );
+
+  // Finish loading image
+  LoadBitmapResource(platform);
+  ids.clear();
+  ids.push_back( 57 );
+  glAbstraction.SetNextTextureIds(ids);
+
+  // Run update/render loop
+  application.Render(16);
+  application.SendNotification();
+
+  // Expect new GenTextures
+  DALI_TEST_CHECK( textureTrace.FindMethod("GenTextures") );
+
+  END_TEST;
+}
index 42c4846b1223eb261367477b8c108f71605581a3..25342cc501d0b8bc80d489087c24462376ed315a 100644 (file)
@@ -240,7 +240,7 @@ int UtcDaliImageActorGetCurrentSize02(void)
 
   // Now complete the image load
   Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888,  initialImageSize.width,initialImageSize.height, initialImageSize.width,initialImageSize.height );
 
   Integration::ResourcePointer resourcePtr(bitmap); // reference it
@@ -292,7 +292,7 @@ int UtcDaliImageActorGetCurrentSize03(void)
 
   // Now complete the image load
   Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888,  closestImageSize.width, closestImageSize.height, closestImageSize.width, closestImageSize.height );
 
   Integration::ResourcePointer resourcePtr(bitmap); // reference it
@@ -343,7 +343,7 @@ int UtcDaliImageActorGetCurrentSize04(void)
 
   // Now complete the image load
   Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888,  closestImageSize.width, closestImageSize.height, closestImageSize.width, closestImageSize.height );
 
   Integration::ResourcePointer resourcePtr(bitmap); // reference it
@@ -383,7 +383,7 @@ int UtcDaliImageActorGetCurrentSize04(void)
 
   // Now complete the image load
   req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap2 = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap2 = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap2->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888,  image2ClosestSize.width, image2ClosestSize.height, image2ClosestSize.width, image2ClosestSize.height );
 
   Integration::ResourcePointer resourcePtr2(bitmap2); // reference it
@@ -427,7 +427,7 @@ int UtcDaliImageActorGetCurrentSize05(void)
 
   // Now complete the image load
   Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888,  closestImageSize.width, closestImageSize.height, closestImageSize.width, closestImageSize.height );
 
   Integration::ResourcePointer resourcePtr(bitmap); // reference it
@@ -459,7 +459,7 @@ int UtcDaliImageActorGetCurrentSize05(void)
 
   // Now complete the image load
   req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap2 = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap2 = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap2->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888,  image2ClosestSize.width, image2ClosestSize.height, image2ClosestSize.width, image2ClosestSize.height );
 
   Integration::ResourcePointer resourcePtr2(bitmap2); // reference it
@@ -506,7 +506,7 @@ int UtcDaliImageActorNaturalPixelAreaSize01(void)
 
   // Now complete the image load
   Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888,  closestImageSize.width, closestImageSize.height, closestImageSize.width, closestImageSize.height );
 
   Integration::ResourcePointer resourcePtr(bitmap); // reference it
@@ -569,7 +569,7 @@ int UtcDaliImageActorNaturalPixelAreaSize02(void)
 
   // Now complete the image load
   Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888,  closestImageSize.width, closestImageSize.height, closestImageSize.width, closestImageSize.height );
 
   Integration::ResourcePointer resourcePtr(bitmap); // reference it
@@ -914,7 +914,7 @@ int UtcDaliImageActorNinePatch01(void)
   tet_infoline("Test the successful loading of a nine-patch image\n");
 
   platform.SetClosestImageSize(Vector2(4, 4));
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   Integration::PixelBuffer* pixels = bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888,  4,4,4,4 );
   memset( pixels, 0, 64 );
 
@@ -1007,7 +1007,7 @@ int UtcDaliImageActorNinePatch03(void)
   tet_infoline("Test the successful loading of a nine-patch image added using ImageActor::SetImage()\n");
 
   platform.SetClosestImageSize(Vector2(4, 4));
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   Integration::PixelBuffer* pixels = bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888,  4,4,4,4 );
   memset( pixels, 0, 64 );
 
index 77c8eac72caf143e0824c80a4049e91455688bd8..1c0d9e2e3cecb3d676f9fb26229e44d45599e65d 100644 (file)
@@ -183,7 +183,7 @@ int UtcDaliMaterialStage01(void)
     std::vector<GLuint> ids;
     ids.push_back( 23 );
     application.GetGlAbstraction().SetNextTextureIds( ids );
-    Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+    Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
     Integration::ResourcePointer resource(bitmap);
     bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
     DALI_TEST_CHECK( application.GetPlatform().WasCalled(TestPlatformAbstraction::LoadResourceFunc) );
@@ -295,7 +295,7 @@ int UtcDaliMaterialStage02(void)
       Integration::ResourceRequest* request = application.GetPlatform().GetRequest();
       DALI_TEST_CHECK( request != NULL );
 
-      Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+      Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
       Integration::ResourcePointer resource(bitmap);
       bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
       if(request)
index 0e2b2ba48f7f7bc9d79706ea20f4f5f8ddbc1a85..899853ce4634ecbd8f34bc07c598f110c04c9aa8 100644 (file)
@@ -201,7 +201,7 @@ void CompleteImageLoad(TestApplication& application, Integration::ResourceId res
   ids.push_back( 23 );
   application.GetGlAbstraction().SetNextTextureIds( ids );
 
-  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, true );
+  Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::DISCARD );
   Integration::ResourcePointer resource(bitmap);
   bitmap->GetPackedPixelsProfile()->ReserveBuffer(Pixel::RGBA8888, 80, 80, 80, 80);
 
index 1ab455933e8bc12abbeb989899a4fccafee1b9dc..57c730fa452af87c7f0a6458d3059ccd2cb09fd3 100644 (file)
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 
 #include <dali/public-api/dali-core.h>
+#include <dali/integration-api/context-notifier.h>
 #include <dali/integration-api/events/key-event-integ.h>
 #include <dali/integration-api/events/touch-event-integ.h>
 
@@ -135,6 +136,26 @@ bool DummyTouchCallback( Actor actor, const TouchEvent& touch )
   return true;
 }
 
+
+struct ContextStatusFunctor
+{
+  ContextStatusFunctor(bool& calledFlag) : mCalledFlag( calledFlag )
+  {
+    mCalledFlag = false;
+  }
+
+  void operator()()
+  {
+    mCalledFlag = true;
+  }
+  void Reset()
+  {
+    mCalledFlag = false;
+  }
+
+  bool& mCalledFlag;
+};
+
 } // unnamed namespace
 
 
@@ -595,3 +616,26 @@ int UtcDaliStageTouchedSignal(void)
   }
   END_TEST;
 }
+
+int UtcDaliStageContextLostRegainedSignals(void)
+{
+  TestApplication app;
+  Stage stage = Stage::GetCurrent();
+
+  bool contextLost = false;
+  bool contextRegained = false;
+  ContextStatusFunctor contextLostFunctor( contextLost );
+  ContextStatusFunctor contextRegainedFunctor( contextRegained );
+  stage.ContextLostSignal().Connect(&app, contextLostFunctor );
+  stage.ContextRegainedSignal().Connect(&app, contextRegainedFunctor );
+
+  Integration::Core& core = app.GetCore();
+  Integration::ContextNotifierInterface* notifier = core.GetContextNotifier();
+  notifier->NotifyContextLost();
+  DALI_TEST_EQUALS( contextLost, true, TEST_LOCATION );
+
+  notifier->NotifyContextRegained();
+  DALI_TEST_EQUALS( contextRegained, true, TEST_LOCATION );
+
+  END_TEST;
+}
index 617cab8283fbfaa0959555354285b46fd33e4686..1eb95b40ef3b047d47af71504b89495161d7312d 100644 (file)
@@ -22,6 +22,8 @@
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
+#include <dali/integration-api/platform-abstraction.h>
+#include <dali/internal/event/common/thread-local-storage.h>
 #include <dali/internal/event/images/bitmap-packed-pixel.h>
 #include <dali/internal/event/images/bitmap-compressed.h>
 #include <dali/internal/event/images/bitmap-external.h>
@@ -242,7 +244,8 @@ void ConvertToGlFormat( Format pixelformat, unsigned& pixelDataType, unsigned& i
   }
 }
 
-Bitmap* Bitmap::New(const Profile profile = BITMAP_2D_PACKED_PIXELS, const bool managePixelBuffer = true)
+Bitmap* Bitmap::New( const Profile profile = BITMAP_2D_PACKED_PIXELS,
+                     ResourcePolicy::Discardable discardable = ResourcePolicy::DISCARD )
 {
   DALI_ASSERT_DEBUG(profile == BITMAP_2D_PACKED_PIXELS || profile == BITMAP_COMPRESSED);
 
@@ -254,20 +257,21 @@ Bitmap* Bitmap::New(const Profile profile = BITMAP_2D_PACKED_PIXELS, const bool
      * scanlines past the bottom of the image in the buffer if requested.*/
     case BITMAP_2D_PACKED_PIXELS:
     {
-      Bitmap * const bitmap = new Dali::Internal::BitmapPackedPixel(managePixelBuffer);
+      Bitmap * const bitmap = new Dali::Internal::BitmapPackedPixel( discardable );
       return bitmap;
     }
 
     /** The data for the bitmap is buffered in an opaque form.*/
     case BITMAP_COMPRESSED:
     {
-      return new Dali::Internal::BitmapCompressed(managePixelBuffer);
+      return new Dali::Internal::BitmapCompressed( discardable );
     }
   }
   return 0;
 }
 
-Bitmap::Bitmap( bool discardable, Dali::Integration::PixelBuffer* pixBuf)
+
+Bitmap::Bitmap( ResourcePolicy::Discardable discardable, Dali::Integration::PixelBuffer* pixBuf)
 : mImageWidth(0),
   mImageHeight(0),
   mPixelFormat(Pixel::RGBA8888),
@@ -280,7 +284,7 @@ Bitmap::Bitmap( bool discardable, Dali::Integration::PixelBuffer* pixBuf)
 
 void Bitmap::DiscardBuffer()
 {
-  if ( mDiscardable )
+  if( mDiscardable == ResourcePolicy::DISCARD )
   {
     DeletePixelBuffer();
   }
@@ -299,7 +303,10 @@ PixelBuffer* Bitmap::ReleaseBuffer()
 Bitmap::~Bitmap()
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
-  DeletePixelBuffer();
+  if( mDiscardable == ResourcePolicy::DISCARD )
+  {
+    DeletePixelBuffer();
+  }
 }
 
 /**
@@ -330,4 +337,3 @@ void Bitmap::Initialize( Pixel::Format pixelFormat,
 } //namespace Integration
 
 } //namespace Dali
-
index f4b447239a11911038aba479ea5dc88c2e123800..977fb1e2a707bc7802733a3fae7aa2580d1f6f61 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/images/pixel.h>
 #include <dali/public-api/object/ref-object.h>
+#include <dali/integration-api/resource-policies.h>
 
 namespace Dali
 {
@@ -53,13 +54,14 @@ typedef unsigned char                 PixelBuffer;  ///< Pixel data buffers are
 class DALI_IMPORT_API Bitmap : public Dali::RefObject
 {
 protected:
+
   /**
    * Constructor
-   * Use the static function Bitmap::Create() to create instances.
+   * Use the static function Bitmap::New() to create instances.
    * @param[in] discardable Flag to tell the bitmap if it can delete the buffer with the pixel data.
    * @param[in] pixBuf External buffer of pixel data or null.
    */
-  Bitmap( bool discardable = false, Dali::Integration::PixelBuffer* pixBuf = 0 );
+  Bitmap( ResourcePolicy::Discardable discardable = ResourcePolicy::RETAIN, Dali::Integration::PixelBuffer* pixBuf = 0 );
 
   /**
    * Initializes internal class members
@@ -87,17 +89,18 @@ public:
   };
 
   /**
-   * Create a new instance of a Bitmap with the profile asked for.
+   * Create a new instance of a Bitmap with the required profile.
    * @return Pointer to created Bitmap subclass. Clients should immediately
    * wrap this in a reference-counting smart pointer or store it in a similarly
    * automatic owning collection.
    * @param[in] profile Defines required features of the bitmap (\sa Profile).
-   * @param[in] managePixelBuffer If true, the bitmap object owns it's own
-   * buffer of pixel data and can delete it, else the lifetime of the pixel
-   * buffer is managed by an external component and is guaranteed to remain
+   * @param[in] discardable If this is set to DISCARD, the bitmap
+   * object owns it's own buffer of pixel data and can delete it. If
+   * it's set to RETAIN, then the lifetime of the pixel buffer is
+   * managed by an external component and is guaranteed to remain
    * dereferenceable at least as long as the Bitmap remains alive.
    **/
-  static Bitmap* New(Profile profile, bool managePixelBuffer);
+  static Bitmap* New( Profile profile, ResourcePolicy::Discardable discardable );
 
   /** \name GeneralFeatures
    * Features that are generic between profiles. */
@@ -131,13 +134,13 @@ public:
   }
 
   /**
-   * Get the pixel buffer
-   * @return The buffer. You can modify its contents.
+   * Get the pixel buffer if it's present.
+   * @return The buffer if present, or NULL if there is no pixel buffer.
+   * You can modify its contents.
    * @sa ReserveBuffer GetBufferSize
    */
   virtual PixelBuffer* GetBuffer()
   {
-    DALI_ASSERT_DEBUG(mData != NULL);
     return mData;
   }
 
@@ -304,7 +307,7 @@ public:
    */
   bool IsDiscardable() const
   {
-    return mDiscardable;
+    return mDiscardable == ResourcePolicy::DISCARD;
   }
 
  /**
@@ -334,7 +337,7 @@ protected:
 
 private:
 
-  bool mDiscardable; ///< Should delete the buffer when discard buffer is called.
+  ResourcePolicy::Discardable mDiscardable; ///< Should delete the buffer when discard buffer is called.
 
   Bitmap(const Bitmap& other);  ///< defined private to prevent use
   Bitmap& operator = (const Bitmap& other); ///< defined private to prevent use
diff --git a/dali/integration-api/context-notifier.h b/dali/integration-api/context-notifier.h
new file mode 100644 (file)
index 0000000..348f292
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef __DALI_INTEGRATION_CONTEXT_NOTIFIER_H__
+#define __DALI_INTEGRATION_CONTEXT_NOTIFIER_H__
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Dali
+{
+namespace Integration
+{
+
+/**
+ * Interface to inform dali core of context loss and regain
+ */
+class ContextNotifierInterface
+{
+public:
+  /**
+   * Notify that the GL context has been lost, e.g. during ReplaceSurface
+   * or Pause.
+   *
+   * Multi-threading note: this method should be called from the main thread
+   */
+  virtual void NotifyContextLost() = 0;
+
+  /**
+   * Notify that the GL context has been re-created, e.g. after ReplaceSurface
+   * or Context loss.
+   *
+   * In the case of ReplaceSurface, both ContextDestroyed() and ContextCreated() will have
+   * been called on the render thread before this is called on the event thread.
+   *
+   * Multi-threading note: this method should be called from the main thread
+   */
+  virtual void NotifyContextRegained() = 0;
+};
+
+} // namespace Integration
+} // namespace Dali
+
+
+#endif // __DALI_INTEGRATION_CONTEXT_NOTIFICATION_H__
index 186209d8f6d2768ac7cde8f2438d4707637a9070..44a4323402572cbc18bd89dc474e2a66570e58b6 100644 (file)
@@ -51,10 +51,10 @@ const unsigned int RENDER_TASK_SYNC       = 0x40;  ///< The refresh once render
 } // namespace KeepUpdating
 
 Core* Core::New(RenderController& renderController, PlatformAbstraction& platformAbstraction,
-                GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction, GestureManager& gestureManager)
+                GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction, GestureManager& gestureManager, ResourcePolicy::DataRetention policy )
 {
   Core* instance = new Core;
-  instance->mImpl = new Internal::Core( renderController, platformAbstraction, glAbstraction, glSyncAbstraction, gestureManager );
+  instance->mImpl = new Internal::Core( renderController, platformAbstraction, glAbstraction, glSyncAbstraction, gestureManager, policy );
 
   return instance;
 }
@@ -64,14 +64,28 @@ Core::~Core()
   delete mImpl;
 }
 
+ContextNotifierInterface* Core::GetContextNotifier()
+{
+  return mImpl->GetContextNotifier();
+}
+
+// @todo Rename to ResetGlContext
 void Core::ContextCreated()
 {
   mImpl->ContextCreated();
 }
 
-void Core::ContextToBeDestroyed()
+// @todo Replace with StopRendering that prevents RenderManager from rendering
+// until we get ResetGLContext again, change ContextCreated to reset gpu buffer cache,
+// gl texture id's
+void Core::ContextDestroyed()
+{
+  mImpl->ContextDestroyed();
+}
+
+void Core::RecoverFromContextLoss()
 {
-  mImpl->ContextToBeDestroyed();
+  mImpl->RecoverFromContextLoss();
 }
 
 void Core::SurfaceResized(unsigned int width, unsigned int height)
index d9d533251695ecde27384f5d1e62046a9678b11d..2a2fbb08ce4faf4bfd12a17e6b8b54c2da165b12 100644 (file)
@@ -21,6 +21,8 @@
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/common/view-mode.h>
+#include <dali/integration-api/context-notifier.h>
+#include <dali/integration-api/resource-policies.h>
 
 namespace Dali
 {
@@ -43,6 +45,7 @@ class SystemOverlay;
 struct Event;
 struct TouchData;
 
+
 /**
  * The reasons why further updates are required.
  */
@@ -205,13 +208,17 @@ public:
    * @param[in] glAbstraction The interface providing OpenGL services.
    * @param[in] glSyncAbstraction The interface providing OpenGL sync objects.
    * @param[in] gestureManager The interface providing gesture manager services.
+   * @param[in] policy The data retention policy. This depends on application setting
+   * and platform support. Dali should honour this policy when deciding to discard
+   * intermediate resource data.
    * @return A newly allocated Core.
    */
   static Core* New(RenderController& renderController,
                    PlatformAbstraction& platformAbstraction,
                    GlAbstraction& glAbstraction,
                    GlSyncAbstraction& glSyncAbstraction,
-                   GestureManager& gestureManager);
+                   GestureManager& gestureManager,
+                   ResourcePolicy::DataRetention policy);
 
   /**
    * Non-virtual destructor. Core is not intended as a base class.
@@ -220,6 +227,11 @@ public:
 
   // GL Context Lifecycle
 
+  /**
+   * Get the object that will notify the application/toolkit when context is lost/regained
+   */
+  ContextNotifierInterface* GetContextNotifier();
+
   /**
    * Notify the Core that the GL context has been created.
    * The context must be created before the Core can render.
@@ -234,7 +246,18 @@ public:
    * Multi-threading note: this method should be called from the rendering thread only
    * @post The Core is unaware of any GL context.
    */
-  void ContextToBeDestroyed();
+  void ContextDestroyed();
+
+  /**
+   * Notify the Core that the GL context has been re-created, e.g. after ReplaceSurface
+   * or Context loss.
+   *
+   * In the case of ReplaceSurface, both ContextToBeDestroyed() and ContextCreated() will have
+   * been called on the render thread before this is called on the event thread.
+   *
+   * Multi-threading note: this method should be called from the main thread
+   */
+  void RecoverFromContextLoss();
 
   /**
    * Notify the Core that the GL surface has been resized.
index c8208822f5e7ff30055b7b795c811747f586ff01..3742942271dab89c05e7e5f6e6650d37fbc4f2b0 100644 (file)
@@ -26,11 +26,13 @@ platform_abstraction_src_files = \
 
 platform_abstraction_header_files = \
    $(platform_abstraction_src_dir)/core.h \
+   $(platform_abstraction_src_dir)/context-notifier.h \
    $(platform_abstraction_src_dir)/glyph-set.h \
    $(platform_abstraction_src_dir)/debug.h \
    $(platform_abstraction_src_dir)/profiling.h \
    $(platform_abstraction_src_dir)/input-options.h \
    $(platform_abstraction_src_dir)/bitmap.h \
+   $(platform_abstraction_src_dir)/resource-policies.h \
    $(platform_abstraction_src_dir)/image-data.h \
    $(platform_abstraction_src_dir)/resource-types.h \
    $(platform_abstraction_src_dir)/resource-request.h \
index 925546e69955baec0b878f925148cb20ddd6f4bd..a5111a78c3d56c6ebdea7082999bc49fa77a9e1e 100644 (file)
@@ -32,6 +32,7 @@ namespace Integration
 class Bitmap;
 class DynamicsFactory;
 
+
 /**
  * PlatformAbstraction is an abstract interface, used by Dali to access platform specific services.
  * A concrete implementation must be created for each platform, and provided when creating the
diff --git a/dali/integration-api/resource-policies.h b/dali/integration-api/resource-policies.h
new file mode 100644 (file)
index 0000000..524e5aa
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef __DALI_INTEGRATION_RESOURCE_POLICIES_H__
+#define __DALI_INTEGRATION_RESOURCE_POLICIES_H__
+
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Dali
+{
+namespace ResourcePolicy
+{
+
+/**
+ * The data retention policy describes how dali should retain resource data.
+ */
+enum DataRetention
+{
+  DALI_RETAINS_ALL_DATA,  // retains Meshes and bitmaps
+  DALI_RETAINS_MESH_DATA, // retains meshes, but discards bitmaps loaded from files
+  DALI_DISCARDS_ALL_DATA, // discards all data (expects application to regenerate UI on context loss)
+};
+
+/**
+ * The discardable policy describes whether a resource can be discarded (i.e. it is throw-away
+ * or recoverable)
+ */
+enum Discardable
+{
+  DISCARD, // @todo Change to IS_RECOVERABLE?
+  RETAIN
+};
+
+} // namespace ResourcePolicy
+} // namespace Dali
+
+#endif // __DALI_INTEGRATION_DISCARD_POLICY_H__
index ba9f87460ccfce480700058ab15ead88c631db4d..97787c74bef8f8f8f2bb1874eeeda9faa6b5b6ad 100644 (file)
@@ -21,6 +21,7 @@
 // INTERNAL INCLUDES
 #include <dali/integration-api/system-overlay.h>
 #include <dali/integration-api/core.h>
+#include <dali/integration-api/debug.h>
 #include <dali/integration-api/platform-abstraction.h>
 #include <dali/integration-api/gl-sync-abstraction.h>
 #include <dali/integration-api/render-controller.h>
@@ -46,6 +47,7 @@
 #include <dali/internal/event/effects/shader-factory.h>
 #include <dali/internal/update/touch/touch-resampler.h>
 #include <dali/internal/event/common/type-registry-impl.h>
+#include <dali/internal/event/render-tasks/render-task-list-impl.h>
 
 #include <dali/internal/render/gl-resources/texture-cache.h>
 #include <dali/internal/render/gl-resources/context.h>
@@ -56,8 +58,15 @@ using Dali::Internal::SceneGraph::DiscardQueue;
 using Dali::Internal::SceneGraph::RenderQueue;
 using Dali::Internal::SceneGraph::TextureCache;
 
+namespace
+{
 // The Update for frame N+1 may be processed whilst frame N is being rendered.
-static const unsigned int MAXIMUM_UPDATE_COUNT = 2u;
+const unsigned int MAXIMUM_UPDATE_COUNT = 2u;
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gCoreFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CORE");
+#endif
+}
 
 namespace Dali
 {
@@ -76,7 +85,7 @@ using Integration::RenderStatus;
 
 Core::Core( RenderController& renderController, PlatformAbstraction& platform,
             GlAbstraction& glAbstraction, GlSyncAbstraction& glSyncAbstraction,
-            GestureManager& gestureManager)
+            GestureManager& gestureManager, ResourcePolicy::DataRetention dataRetentionPolicy)
 : mRenderController( renderController ),
   mPlatform(platform),
   mGestureEventProcessor(NULL),
@@ -113,6 +122,14 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform,
 
   RenderQueue& renderQueue = mRenderManager->GetRenderQueue();
   TextureCache& textureCache = mRenderManager->GetTextureCache();
+
+  ResourcePolicy::Discardable discardPolicy = ResourcePolicy::DISCARD;
+  if( dataRetentionPolicy == ResourcePolicy::DALI_RETAINS_ALL_DATA )
+  {
+    discardPolicy = ResourcePolicy::RETAIN;
+  }
+  textureCache.SetDiscardBitmapsPolicy(discardPolicy);
+
   mDiscardQueue = new DiscardQueue( renderQueue );
 
   mResourceManager = new ResourceManager(  mPlatform,
@@ -137,7 +154,7 @@ Core::Core( RenderController& renderController, PlatformAbstraction& platform,
                                        textureCache,
                                       *mTouchResampler );
 
-  mResourceClient = new ResourceClient( *mResourceManager, *mUpdateManager );
+  mResourceClient = new ResourceClient( *mResourceManager, *mUpdateManager, dataRetentionPolicy );
 
   mStage = IntrusivePtr<Stage>( Stage::New( *mAnimationPlaylist, *mPropertyNotificationManager, *mUpdateManager, *mNotificationManager ) );
 
@@ -196,12 +213,26 @@ Core::~Core()
   delete mResourcePostProcessQueue;
 }
 
+Integration::ContextNotifierInterface* Core::GetContextNotifier()
+{
+  return mStage.Get();
+}
+
+void Core::RecoverFromContextLoss()
+{
+  DALI_LOG_INFO(gCoreFilter, Debug::Verbose, "Core::RecoverFromContextLoss()\n");
+
+  mImageFactory->RecoverFromContextLoss(); // Reload images from files
+  mFontFactory->RecoverFromContextLoss();  // Reload glyphs from cache into new atlas
+  mStage->GetRenderTaskList().RecoverFromContextLoss(); // Re-trigger render-tasks
+}
+
 void Core::ContextCreated()
 {
   mRenderManager->ContextCreated();
 }
 
-void Core::ContextToBeDestroyed()
+void Core::ContextDestroyed()
 {
   mRenderManager->ContextDestroyed();
 }
@@ -213,7 +244,7 @@ void Core::SurfaceResized(unsigned int width, unsigned int height)
 
 void Core::SetDpi(unsigned int dpiHorizontal, unsigned int dpiVertical)
 {
-  mPlatform.SetDpi( dpiHorizontal, dpiVertical  );
+  mPlatform.SetDpi( dpiHorizontal, dpiVertical );
   mFontFactory->SetDpi( dpiHorizontal, dpiVertical);
   mStage->SetDpi( Vector2( dpiHorizontal , dpiVertical) );
 }
index c42183800ca78718c8413c1968db8a04e0a9c9b1..b456e82fc6389d766fde1521aea7c6a07eacea1b 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali/public-api/object/ref-object.h>
+#include <dali/integration-api/context-notifier.h>
 #include <dali/internal/common/owner-pointer.h>
 #include <dali/internal/event/animation/animation-playlist-declarations.h>
 #include <dali/internal/event/common/stage-def.h>
 #include <dali/internal/update/resources/resource-manager-declarations.h>
 #include <dali/public-api/common/view-mode.h>
+#include <dali/integration-api/resource-policies.h>
 
 namespace Dali
 {
@@ -82,22 +84,33 @@ public:
         Integration::PlatformAbstraction& platform,
         Integration::GlAbstraction& glAbstraction,
         Integration::GlSyncAbstraction& glSyncAbstraction,
-        Integration::GestureManager& gestureManager );
+        Integration::GestureManager& gestureManager,
+        ResourcePolicy::DataRetention dataRetentionPolicy );
 
   /**
    * Destructor
    */
   ~Core();
 
+  /**
+   * @copydoc Dali::Integration::Core::GetContextNotifier()
+   */
+  Integration::ContextNotifierInterface* GetContextNotifier();
+
   /**
    * @copydoc Dali::Integration::Core::ContextCreated()
    */
   void ContextCreated();
 
   /**
-   * @copydoc Dali::Integration::Core::ContextToBeDestroyed()
+   * @copydoc Dali::Integration::Core::ContextDestroyed()
+   */
+  void ContextDestroyed();
+
+  /**
+   * @copydoc Dali::Integration::Core::RecoverFromContextLoss()
    */
-  void ContextToBeDestroyed();
+  void RecoverFromContextLoss();
 
   /**
    * @copydoc Dali::Integration::Core::SurfaceResized(unsigned int, unsigned int)
index 7dce84e4bfed382493af57cf225f24803690b3ba..de0c28143dd94c3a46b0cf2a191e9fae05a45f50 100644 (file)
@@ -524,6 +524,26 @@ Dali::Stage::TouchedSignalV2& Stage::TouchedSignal()
   return mTouchedSignalV2;
 }
 
+Dali::Stage::ContextStatusSignal& Stage::ContextLostSignal()
+{
+  return mContextLostSignal;
+}
+
+Dali::Stage::ContextStatusSignal& Stage::ContextRegainedSignal()
+{
+  return mContextRegainedSignal;
+}
+
+void Stage::NotifyContextLost()
+{
+  mContextLostSignal.Emit();
+}
+
+void Stage::NotifyContextRegained()
+{
+  mContextRegainedSignal.Emit();
+}
+
 Stage::Stage( AnimationPlaylist& playlist,
               PropertyNotificationManager& propertyNotificationManager,
               SceneGraph::UpdateManager& updateManager,
index a7c164565d7e96aac3ffbd2cb9b94e5928955de8..a0e9d6a76f5d4eacafad1c676593d09105ba06e2 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/public-api/object/ref-object.h>
 #include <dali/public-api/common/stage.h>
 #include <dali/public-api/object/base-object.h>
+#include <dali/integration-api/context-notifier.h>
 #include <dali/internal/common/owner-pointer.h>
 #include <dali/internal/event/actors/layer-impl.h>
 #include <dali/internal/event/common/object-registry-impl.h>
@@ -69,7 +70,7 @@ class RenderTaskList;
 /**
  * Implementation of Stage
  */
-class Stage : public BaseObject, public RenderTaskDefaults
+class Stage : public BaseObject, public RenderTaskDefaults, public Integration::ContextNotifierInterface
 {
 public:
 
@@ -331,6 +332,7 @@ public:
     return mNotificationManager;
   }
 
+
   /**
    * @copydoc Dali::Stage::KeepRendering()
    */
@@ -370,6 +372,28 @@ public:
     */
   Dali::Stage::TouchedSignalV2& TouchedSignal();
 
+  /**
+   * @copydoc Dali::Stage::ContextLostSignal()
+   */
+  Dali::Stage::ContextStatusSignal& ContextLostSignal();
+
+  /**
+   * @copydoc Dali::Stage::ContextRegainedSignal()
+   */
+  Dali::Stage::ContextStatusSignal& ContextRegainedSignal();
+
+private: // Implementation of ContextNotificationInterface:
+
+  /**
+   * @copydoc Dali::Integration::NotifyContextLost();
+   */
+  virtual void NotifyContextLost();
+
+  /**
+   * @copydoc Dali::Integration::NotifyContextRegained();
+   */
+  virtual void NotifyContextRegained();
+
 private:
 
   /**
@@ -445,6 +469,9 @@ private:
 
   // The touched signal
   Dali::Stage::TouchedSignalV2                  mTouchedSignalV2;
+
+  Dali::Stage::ContextStatusSignal mContextLostSignal;
+  Dali::Stage::ContextStatusSignal mContextRegainedSignal;
 };
 
 } // namespace Internal
index 7a336fb778fa58d83125e16d910e670121491966..7e41ca921eac74455d7427e6cd3150621e84a7c1 100644 (file)
@@ -33,8 +33,11 @@ namespace Internal
 {
 using namespace Dali::Pixel;
 
-BitmapCompressed::BitmapCompressed( const bool bitmapOwnsBuffer ) : Bitmap(bitmapOwnsBuffer), mBufferSize(0)
-{}
+BitmapCompressed::BitmapCompressed( const ResourcePolicy::Discardable discardable )
+: Bitmap( discardable ),
+  mBufferSize(0)
+{
+}
 
 BitmapCompressed::~BitmapCompressed()
 {
index a476f9d27c73426c48149d541c3994ea8f63d6e3..6835ad87c5d99635bb8926aeff760277963b03ce 100644 (file)
@@ -45,7 +45,7 @@ public:
    * Constructor
    * @param[in] discardable Flag to tell the bitmap if it can delete the buffer with the pixel data.
    */
-  BitmapCompressed( bool discardable = false );
+  BitmapCompressed( ResourcePolicy::Discardable discardable = ResourcePolicy::RETAIN );
 
   virtual const Bitmap::CompressedProfile* GetCompressedProfile() const { return this; }
   virtual Bitmap::CompressedProfile* GetCompressedProfile() { return this; }
index f1e36faf1810dae58c301f756ba3c22aa577b8c8..58d56092dc575b36804de216b60769162544a3be 100644 (file)
@@ -34,7 +34,7 @@ BitmapExternal::BitmapExternal(Dali::Integration::PixelBuffer* pixBuf,
                Pixel::Format pixelFormat,
                unsigned int bufferWidth,
                unsigned int bufferHeight)
-: BitmapPackedPixel(false, NULL/*pixBuf is externally owned*/),
+: BitmapPackedPixel(ResourcePolicy::RETAIN, NULL/*pixBuf is externally owned*/),
   mExternalData(pixBuf)
 {
   mImageWidth   = width;
index 1ba1aa08d962e842d6ff9437a0de5e5148969937..d97b1d49fae6fad39fee1251c1343423ac8609e1 100644 (file)
@@ -31,7 +31,7 @@ namespace Internal
 using namespace Dali::Pixel;
 
 
-BitmapPackedPixel::BitmapPackedPixel( bool discardable, Dali::Integration::PixelBuffer* pixBuf )
+BitmapPackedPixel::BitmapPackedPixel( ResourcePolicy::Discardable discardable, Dali::Integration::PixelBuffer* pixBuf )
 : Bitmap( discardable, pixBuf ),
   mBufferWidth(0),
   mBufferHeight(0),
index 20cdb39df52d3eeb7481c309a8b1d53a56c43b44..12c6777e12f7145409ae6012f5039e50a993692d 100644 (file)
@@ -48,7 +48,7 @@ public:
    * Constructor
    * @param[in] discardable Flag to tell the bitmap if it can delete the buffer with the pixel data.
    */
-  BitmapPackedPixel( bool discardable = false, Dali::Integration::PixelBuffer* pixBuf = 0 );
+  BitmapPackedPixel( ResourcePolicy::Discardable discardable = ResourcePolicy::RETAIN, Dali::Integration::PixelBuffer* pixBuf = 0 );
 
 public:
   virtual const Bitmap::PackedPixelsProfile* GetPackedPixelsProfile() const { return this; }
index 67e08955810c8a8a452e46782cd4e8a2fd7310d2..0dc4c101d66b68fed0b7f7f34cb4232576bbe08a 100644 (file)
@@ -170,7 +170,7 @@ ResourceTicketPtr ImageFactory::Reload( Request* request )
 
     if( size == attrib.GetSize() )
     {
-      mResourceClient.ReloadResource( ticket->GetId() );
+      mResourceClient.ReloadResource( ticket->GetId(), false );
     }
     else
     {
@@ -182,6 +182,26 @@ ResourceTicketPtr ImageFactory::Reload( Request* request )
   return ticket;
 }
 
+void ImageFactory::RecoverFromContextLoss()
+{
+  for( RequestIdMap::iterator it = mRequestCache.begin(); it != mRequestCache.end(); ++it )
+  {
+    // go through requests, reload with resource ticket's attributes.
+    Request* request = (*it).second;
+    if( request->resourceId )
+    {
+      ResourceTicketPtr ticket = mResourceClient.RequestResourceTicket( request->resourceId );
+
+      // do not reload if still loading
+      if ( ticket->GetLoadingState() != ResourceLoading )
+      {
+        // Ensure the finished status is reset
+        mResourceClient.ReloadResource( ticket->GetId(), true );
+      }
+    }
+  }
+}
+
 const std::string& ImageFactory::GetRequestPath( const ImageFactoryCache::RequestPtr& request ) const
 {
   if( request )
index 5232ccf71482f9c8364265b5f2cef2099fbbe061..89511aff056d6bc41a61caf5e99e81bd2b3e6f73 100644 (file)
@@ -78,10 +78,25 @@ public:
    * This operation uses the originally requested attributes when reloading the image.
    * @pre req must be registered with ImageFactory
    * @note if image is still loading, no new load request will be issued
-   * @param [in]  req Request pointer
-   * @return[out] the ResourceTicket mapped to the request
+   * @param[in]  requestPtr Request pointer
+   * @return the ResourceTicket mapped to the request
    */
-  ResourceTicketPtr Reload( ImageFactoryCache::Request* req );
+  ResourceTicketPtr Reload( ImageFactoryCache::Request* requestPtr );
+
+  /**
+   * Ensures all filesystem images are reloaded into textures.
+   * This operation uses the originally requested attributes when reloading the image.
+   *
+   * Recovering from context loss does not change the number of tickets if the
+   * image size has changed on the file system since the last load/reload.
+   *
+   * If two different requests mapped to the same resource before, they will still
+   * map to the same resource after context regain even if there would be a better
+   * fitting texture.
+   * @pre requests must be registered with ImageFactory
+   * @note If an image is still loading, no new load request will be issued.
+   */
+  void RecoverFromContextLoss();
 
   /**
    * Get resource path used in request.
index adc1d2f86f36d9685e7a66bd5c64bca510b99613..1b5d69c49262b7a3a006cfe2c691370d4b70ad61 100644 (file)
@@ -24,6 +24,7 @@
 // INTERNAL INCLUDES
 #include <dali/public-api/math/matrix.h>
 #include <dali/public-api/geometry/mesh.h>
+#include <dali/integration-api/platform-abstraction.h>
 #include <dali/internal/event/common/thread-local-storage.h>
 #include <dali/internal/event/modeling/material-impl.h>
 #include <dali/internal/update/modeling/scene-graph-mesh.h>
@@ -47,10 +48,19 @@ MeshIPtr Mesh::New( const Dali::MeshData& meshData, bool discardable, bool scali
 Mesh::Mesh( const Dali::MeshData& publicMeshData, bool discardable, bool scalingRequired )
 : mBoneContainer( publicMeshData.GetBones() )
 {
-  ResourceClient& resourceClient = ThreadLocalStorage::Get().GetResourceClient();
+  ThreadLocalStorage tls = ThreadLocalStorage::Get();
+  ResourceClient& resourceClient = tls.GetResourceClient();
+  ResourcePolicy::DataRetention dataRetentionPolicy = resourceClient.GetResourceDataRetentionPolicy();
+
+  ResourcePolicy::Discardable discard = ResourcePolicy::DISCARD;
+  if( ! (dataRetentionPolicy == ResourcePolicy::DALI_DISCARDS_ALL_DATA) ||
+      ! discardable )
+  {
+    discard = ResourcePolicy::RETAIN;
+  }
 
   // Copy the mesh-data into an internal structure, and pass ownership to the resourceClient
-  OwnerPointer<MeshData> meshDataPtr( new MeshData( publicMeshData, discardable, scalingRequired ) );
+  OwnerPointer<MeshData> meshDataPtr( new MeshData( publicMeshData, discard, scalingRequired ) );
   const ResourceTicketPtr& ticket = resourceClient.AllocateMesh( meshDataPtr );
 
   mTicket = ticket.Get();
@@ -118,4 +128,3 @@ void Mesh::ResourceSavingFailed( const ResourceTicket& ticket )
 } // namespace Internal
 
 } // namespace Dali
-
index 00bdb5635b9176c4499076c6445363cfb4af585c..4514cc93cbf44919e2d4553d766366acb6551133 100644 (file)
@@ -25,6 +25,8 @@
 // INTERNAL INCLUDES
 #include <dali/public-api/common/light.h>
 #include <dali/integration-api/debug.h>
+#include <dali/integration-api/platform-abstraction.h>
+#include <dali/internal/event/common/thread-local-storage.h>
 #include <dali/internal/event/modeling/entity-impl.h>
 #include <dali/internal/event/modeling/material-impl.h>
 #include <dali/internal/event/modeling/mesh-impl.h>
@@ -228,6 +230,11 @@ unsigned int ModelData::NumberOfLights() const
 
 void ModelData::Unpack( ResourceClient& resourceClient )
 {
+  ResourcePolicy::DataRetention dataRetentionPolicy = resourceClient.GetResourceDataRetentionPolicy();
+  ResourcePolicy::Discardable discardable = (dataRetentionPolicy == ResourcePolicy::DALI_DISCARDS_ALL_DATA ) ? ResourcePolicy::DISCARD : ResourcePolicy::RETAIN;
+
+  bool scalable = false; /* scaling is transmitted through parent Node */
+
   // Only unpack once
   if ( !mUnpacked )
   {
@@ -235,7 +242,7 @@ void ModelData::Unpack( ResourceClient& resourceClient )
     for ( size_t meshIdx = 0; meshIdx < NumberOfMeshes(); meshIdx++ )
     {
       // Copy the mesh-data into an internal structure, and pass ownership to the resourceClient
-      OwnerPointer<MeshData> meshDataPtr( new MeshData( GetMesh( meshIdx ), true /* discardable */, false /* scaling is transmitted through parent Node */ ) );
+      OwnerPointer<MeshData> meshDataPtr( new MeshData( GetMesh( meshIdx ), discardable, scalable ));
       ResourceTicketPtr meshTicket = resourceClient.AllocateMesh( meshDataPtr );
 
       AddMeshTicket( meshTicket );
index ef10943086ad360a70a12f0372141233ccaca40a..e0d8c664891933f9676fe37bccdcea816d397c75 100644 (file)
@@ -163,6 +163,20 @@ void RenderTaskList::NotifyCompleted()
   }
 }
 
+void RenderTaskList::RecoverFromContextLoss()
+{
+  for ( RenderTaskContainer::iterator iter = mTasks.begin(); mTasks.end() != iter; ++iter )
+  {
+    Dali::RenderTask task = *iter;
+
+    // If the render target renders only once to an offscreen, re-render the render task
+    if( task.GetRefreshRate() == Dali::RenderTask::REFRESH_ONCE && task.GetTargetFrameBuffer() )
+    {
+      task.SetRefreshRate( Dali::RenderTask::REFRESH_ONCE );
+    }
+  }
+}
+
 } // namespace Internal
 
 } // namespace Dali
index 4c2f73deac2620d594698b38d9774ad4bda21b80..25e5b7904ebb972964b463a61102ad6f126e634c 100644 (file)
@@ -96,6 +96,12 @@ public:
    */
   static void NotifyFinished( void* object );
 
+  /**
+   * This method refreshes all render tasks that have a frame buffer
+   * and a refresh rate of RefreshOnce.
+   */
+  void RecoverFromContextLoss();
+
 protected:
 
   /**
index 53fb3e16c769a68c10667e306f6679c7b20a7814..b8dd6cfb8b88102d8061ea06dded994ee591fe73 100644 (file)
@@ -46,9 +46,10 @@ typedef BitmapCache::iterator                        BitmapCacheIter;
 
 struct ResourceClient::Impl
 {
-  Impl()
+  Impl(ResourcePolicy::DataRetention dataRetentionPolicy)
   : mNextId(0),
-    mGlyphLoadObserver( NULL)
+    mGlyphLoadObserver(NULL),
+    mDataRetentionPolicy( dataRetentionPolicy )
   {
   }
 
@@ -56,14 +57,16 @@ struct ResourceClient::Impl
   TicketContainer  mTickets;
   BitmapCache      mBitmaps;
   GlyphLoadObserver* mGlyphLoadObserver;
+  ResourcePolicy::DataRetention mDataRetentionPolicy;
 };
 
 ResourceClient::ResourceClient( ResourceManager& resourceManager,
-                                SceneGraph::UpdateManager& updateManager )
+                                SceneGraph::UpdateManager& updateManager,
+                                ResourcePolicy::DataRetention dataRetentionPolicy)
 : mResourceManager(resourceManager),
   mUpdateManager(updateManager)
 {
-  mImpl = new ResourceClient::Impl();
+  mImpl = new ResourceClient::Impl(dataRetentionPolicy);
   mResourceManager.SetClient(*this);
 }
 
@@ -80,6 +83,11 @@ ResourceClient::~ResourceClient()
   delete mImpl;
 }
 
+ResourcePolicy::DataRetention ResourceClient::GetResourceDataRetentionPolicy()
+{
+  return mImpl->mDataRetentionPolicy;
+}
+
 ResourceTicketPtr ResourceClient::RequestResource(
   const ResourceType& type,
   const std::string& path,
@@ -202,7 +210,7 @@ ResourceTicketPtr ResourceClient::LoadShader( ShaderResourceType& type,
   return newTicket;
 }
 
-bool ResourceClient::ReloadResource( ResourceId id, LoadResourcePriority priority )
+bool ResourceClient::ReloadResource( ResourceId id, bool resetFinishedStatus, LoadResourcePriority priority )
 {
   DALI_LOG_INFO(Debug::Filter::gResource, Debug::General, "ResourceClient: ReloadResource(Id: %u)\n", id);
 
@@ -218,7 +226,7 @@ bool ResourceClient::ReloadResource( ResourceId id, LoadResourcePriority priorit
     DALI_ASSERT_DEBUG(ticket && "Null ticket for tracked resource request." );
     const ResourceTypePath * const typePathPtr = &ticket->GetTypePath();
     DALI_ASSERT_DEBUG( typePathPtr );
-    RequestReloadResourceMessage( mUpdateManager.GetEventToUpdate(), mResourceManager, id, *typePathPtr, priority );
+    RequestReloadResourceMessage( mUpdateManager.GetEventToUpdate(), mResourceManager, id, *typePathPtr, priority, resetFinishedStatus );
   }
   else
   {
@@ -271,7 +279,8 @@ ImageTicketPtr ResourceClient::AllocateBitmapImage( unsigned int width,
                                                     unsigned int bufferHeight,
                                                     Pixel::Format pixelformat )
 {
-  Bitmap* const bitmap = Bitmap::New( Bitmap::BITMAP_2D_PACKED_PIXELS, false/*buffer is available via public-api, therefore not discardable*/ );
+  /* buffer is available via public-api, therefore not discardable */
+  Bitmap* const bitmap = Bitmap::New( Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::RETAIN );
   Bitmap::PackedPixelsProfile* const packedBitmap = bitmap->GetPackedPixelsProfile();
   DALI_ASSERT_DEBUG(packedBitmap);
 
@@ -432,10 +441,17 @@ void ResourceClient::UpdateMesh( ResourceTicketPtr ticket, const Dali::MeshData&
 {
   DALI_ASSERT_DEBUG( ticket );
 
+  ResourcePolicy::Discardable discardable = ResourcePolicy::RETAIN;
+  if( mImpl->mDataRetentionPolicy == ResourcePolicy::DALI_DISCARDS_ALL_DATA )
+  {
+    discardable = ResourcePolicy::DISCARD;
+  }
+
   RequestUpdateMeshMessage( mUpdateManager.GetEventToUpdate(),
                             mResourceManager,
                             ticket->GetId(),
-                            meshData );
+                            meshData,
+                            discardable );
 }
 
 Bitmap* ResourceClient::GetBitmap(ResourceTicketPtr ticket)
index 1b0180e57694324ac471eee6c8316ab567ec9146..923e73f1de203b8470102baa4d4b44ee8d87d086 100644 (file)
@@ -80,14 +80,21 @@ public:
    * @param[in] resourceManager The resource manager
    * @param[in] updateManager The update manager
    */
-  ResourceClient( ResourceManager& resourceManager, SceneGraph::UpdateManager& updateManager );
+  ResourceClient( ResourceManager& resourceManager,
+                  SceneGraph::UpdateManager& updateManager,
+                  ResourcePolicy::DataRetention dataRetentionPolicy );
 
   /**
    * Virtual destructor.
    */
   virtual ~ResourceClient();
 
-public: // Used by application-side objects e.g. Dali::Image
+public:
+  /**
+   * Get the global data retention policy.
+   * @return the global data retention policy
+   */
+  ResourcePolicy::DataRetention GetResourceDataRetentionPolicy();
 
   /**
    * Request a resource from the native filesystem.
@@ -134,10 +141,11 @@ public: // Used by application-side objects e.g. Dali::Image
    * ResourceLoadingFailed()
    *
    * @param[in] id resource id
+   * @param[in] resetFinishedStatus True if the finished status of the current image should be reset.
    * @param[in] priority The priority of the request. This is ignored if the resource is already being refreshed.
    * @return true if successful, false if resource doesn't exist
    */
-  bool ReloadResource( ResourceId id, Integration::LoadResourcePriority priority = Integration::LoadPriorityNormal );
+  bool ReloadResource( ResourceId id, bool resetFinishedStatus = false, Integration::LoadResourcePriority priority = Integration::LoadPriorityNormal );
 
   /**
    * Save a resource to the given url.
index eabda3141a18b35593a6b5e0f86c37195848cec5..24449f32140f9395b0d26d1d84d2a4ae0f58ec7f 100644 (file)
@@ -143,6 +143,37 @@ GlyphLoadObserver& GlyphAtlasManager::GetLoadObserver()
   return mGlyphResourceManager;
 }
 
+void GlyphAtlasManager::ReloadAtlases()
+{
+  std::vector<GlyphAtlas*> newAtlasList;
+
+  // Copy all atlases to a new list
+  for( AtlasList::Iterator it = mAtlasList.Begin(), end = mAtlasList.End() ;
+       it != end ; ++it )
+  {
+    // Create a new atlas the same size as the previous atlas.
+    GlyphAtlas* oldAtlas = *it;
+
+    GlyphAtlas* newAtlas = GlyphAtlas::New(oldAtlas->GetSize());
+    newAtlas->CloneContents( oldAtlas );
+
+    // Add it to temporary list
+    newAtlasList.push_back(newAtlas);
+
+    mGlyphResourceManager.RemoveObserver( *oldAtlas );
+  }
+  // destroy old atlases
+  mAtlasList.Clear();
+
+  // Add new atlases to proper list
+  for( std::vector<GlyphAtlas*>::iterator it = newAtlasList.begin(); it != newAtlasList.end(); ++it )
+  {
+    AddAtlas( *it );
+  }
+
+  mAtlasesChanged = true;
+}
+
 GlyphAtlas* GlyphAtlasManager::CreateAtlas( unsigned int size )
 {
   GlyphAtlas* atlas =  GlyphAtlas::New( size  );
index 958d66b5458d9d27d3f5a314c514f47340a5a6b5..2663f92f625a6ac7415f92122775a70a1cd6e8ac 100644 (file)
@@ -118,6 +118,12 @@ public:
    */
   GlyphLoadObserver& GetLoadObserver();
 
+  /**
+   * Reload glyphs into atlas, should be used after GL context has been regained
+   * (i.e. the GL texture backing the atlas has been lost)
+   */
+  void ReloadAtlases();
+
 private:
 
   // Undefined copy constructor.
index c088d0fd4a1d3d500c0bcc61d2d8742ee8c0a267..3062a3cfdae4e932286a0a13319eb61398b0744d 100644 (file)
@@ -140,6 +140,11 @@ void FontFactory::SetDpi( float horizontalDpi, float verticalDpi )
   mVerticalDpi = verticalDpi;
 }
 
+void FontFactory::RecoverFromContextLoss()
+{
+  mAtlasManager->ReloadAtlases();
+}
+
 } // namespace Internal
 
 } // namespace Dali
index 3974b6fe9e177e0b418a67bc29711edf1e91cd47..cdd530fb9d47a4b3b726c2737442ec1564fc89c1 100644 (file)
@@ -92,6 +92,12 @@ public:
    */
   void SetDpi( float horizontalDpi, float verticalDpi );
 
+  /**
+   * Called when context has been regained after a loss. The text subsystem will
+   * reload the glyphs into a new atlas and inform their observers.
+   */
+  void RecoverFromContextLoss();
+
 public: // FontLookupInterface
 
   /**
index c510a19adc8f9ce427cc395cc0aa930e49b82ea5..f9f9c8377b50a839eaa3efdab5277cff58ad8e17 100644 (file)
@@ -337,7 +337,6 @@ TextVertexBuffer* Font::TextRequired( const Integration::TextArray& text, const
 
   mMetrics->LoadMetricsSynchronously( text );
 
-
   return mAtlasManager.TextRequired(text, format, *(mMetrics.Get()));
 }
 
index 641441f2b03e2003c79cc5d1d3a89b2fb1622675..a154eeeeed5959d62b09679eaff4fcebd2d1d2d0 100644 (file)
@@ -208,10 +208,13 @@ void RenderManager::ContextCreated()
 
 void RenderManager::ContextDestroyed()
 {
+  // @todo Set an atomic value to prevent render manager rendering again until
+  // ContextCreated has been called.
+
   mImpl->context.GlContextDestroyed();
 
   // inform texture cache
-  mImpl->textureCache.GlContextDestroyed();
+  mImpl->textureCache.GlContextDestroyed(); // Clears gl texture ids
 
   // inform renderers
   RendererOwnerContainer::Iterator end = mImpl->rendererContainer.End();
@@ -219,7 +222,7 @@ void RenderManager::ContextDestroyed()
   for( ; iter != end; ++iter )
   {
     GlResourceOwner* renderer = *iter;
-    renderer->GlContextDestroyed();
+    renderer->GlContextDestroyed(); // Clear up vertex buffers
   }
 }
 
index 0900dc61cac623d2ce03e7b4146d04dbd3a10a5b..75c44f1e7e3e86cee82e78393b4c068f3b3da3f7 100644 (file)
@@ -36,32 +36,39 @@ namespace Dali
 namespace Internal
 {
 
-BitmapTexture::BitmapTexture(Integration::Bitmap* const bitmap, const Integration::Bitmap::PackedPixelsProfile * const bitmapPackedPixelsProfile, Context& context)
-: Texture(context,
-          bitmapPackedPixelsProfile->GetBufferWidth(),
-          bitmapPackedPixelsProfile->GetBufferHeight(),
-          bitmap->GetImageWidth(),
-          bitmap->GetImageHeight(),
-          bitmap->GetPixelFormat()),
+BitmapTexture::BitmapTexture(
+  Integration::Bitmap* const bitmap,
+  const Integration::Bitmap::PackedPixelsProfile * const bitmapPackedPixelsProfile,
+  Context& context,
+  ResourcePolicy::Discardable policy)
+: Texture( context,
+           bitmapPackedPixelsProfile->GetBufferWidth(),
+           bitmapPackedPixelsProfile->GetBufferHeight(),
+           bitmap->GetImageWidth(),
+           bitmap->GetImageHeight(),
+           bitmap->GetPixelFormat()),
   mBitmap(bitmap),
-  mClearPixels(false)
+  mClearPixels(false),
+  mDiscardPolicy(policy)
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
   DALI_LOG_SET_OBJECT_STRING(this, DALI_LOG_GET_OBJECT_STRING(bitmap));
 }
 
 BitmapTexture::BitmapTexture(
-  unsigned int  width,
-  unsigned int  height,
+  unsigned int width,
+  unsigned int height,
   Pixel::Format pixelFormat,
-  bool          clearPixels,
-  Context&      context)
-: Texture(context,
-          width, height,
-          width, height,
-          pixelFormat),
+  bool clearPixels,
+  Context& context,
+  ResourcePolicy::Discardable policy)
+: Texture( context,
+           width, height,
+           width, height,
+           pixelFormat),
   mBitmap(NULL),
-  mClearPixels(clearPixels)
+  mClearPixels(clearPixels),
+  mDiscardPolicy(policy)
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
 }
@@ -69,12 +76,15 @@ BitmapTexture::BitmapTexture(
 BitmapTexture::~BitmapTexture()
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
+
   // GlCleanup() should already have been called by TextureCache ensuring the resource is destroyed
   // on the render thread. (And avoiding a potentially problematic virtual call in the destructor)
 }
 
 void BitmapTexture::UploadBitmapArray( const BitmapUploadArray& bitmapArray )
 {
+  DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
+
   if( mId == 0 )
   {
     CreateGlTexture();
@@ -110,20 +120,20 @@ void BitmapTexture::UploadBitmapArray( const BitmapUploadArray& bitmapArray )
                             bitmapWidth,
                             bitmapHeight);
 
-     mContext.TexSubImage2D(GL_TEXTURE_2D,
-                            0,                   /* mip map level */
-                            bitmapItem.mXpos,    /* X pos */
-                            bitmapItem.mYpos,    /* Y pos */
-                            bitmapWidth,         /* width */
-                            bitmapHeight,        /* height */
-                            pixelFormat,         /* our bitmap format (should match internal format) */
-                            pixelDataType,       /* pixel data type */
-                            pixels);             /* texture data */
-
-     if( BitmapUpload::DISCARD_PIXEL_DATA == bitmapItem.mDiscard)
-     {
-       delete [] bitmapItem.mPixelData;
-     }
+    mContext.TexSubImage2D(GL_TEXTURE_2D,
+                           0,                   /* mip map level */
+                           bitmapItem.mXpos,    /* X pos */
+                           bitmapItem.mYpos,    /* Y pos */
+                           bitmapWidth,         /* width */
+                           bitmapHeight,        /* height */
+                           pixelFormat,         /* our bitmap format (should match internal format) */
+                           pixelDataType,       /* pixel data type */
+                           pixels);             /* texture data */
+
+    if( BitmapUpload::DISCARD_PIXEL_DATA == bitmapItem.mDiscard)
+    {
+      delete [] bitmapItem.mPixelData;
+    }
   }
 }
 
@@ -248,14 +258,15 @@ void BitmapTexture::Update( Integration::Bitmap* bitmap )
 
   const unsigned char* pixels = mBitmap->GetBuffer();
 
+  // We should never have null pixel data here - resource manager has deliberately loaded/reloaded data
+
   DALI_ASSERT_DEBUG( pixels != NULL );
 
-  if ( NULL == pixels )
+  if( NULL == pixels )
   {
-    DALI_LOG_ERROR("bitmap has no data\n");
-    GlCleanup(); // Note, We suicide here in the case of bad input.
+    DALI_LOG_ERROR("BitmapTexture::Upload() - Bitmap has no pixel data.\n");
   }
-  else
+  else if( mId != 0 )
   {
     if( mImageWidth == mBitmap->GetImageWidth() &&
         mImageHeight == mBitmap->GetImageHeight() &&
@@ -263,26 +274,19 @@ void BitmapTexture::Update( Integration::Bitmap* bitmap )
         mHeight == bitmapPackedPixels->GetBufferHeight() &&
         mPixelFormat == mBitmap->GetPixelFormat() ) // and size hasn't changed
     {
-      if ( mId ) // If the texture is already bound
-      {
-        RectArea area(0, 0, mImageWidth, mImageHeight);  // just update whole texture
-        AreaUpdated( area, pixels );
-        mBitmap->DiscardBuffer();
-      }
+      RectArea area(0, 0, mImageWidth, mImageHeight);  // just update whole texture
+      AreaUpdated( area, pixels );
+      DiscardBitmapBuffer();
     }
-    else
-    {                                           // Otherwise, reload the pixel data
+    else // Otherwise, reload the pixel data
+    {
       mImageWidth  = mBitmap->GetImageWidth();
       mImageHeight = mBitmap->GetImageHeight();
       mWidth       = bitmapPackedPixels->GetBufferWidth();
       mHeight      = bitmapPackedPixels->GetBufferHeight();
       mPixelFormat = mBitmap->GetPixelFormat();
 
-      if ( mId ) // If the texture is already bound
-      {
-        AssignBitmap( false, pixels );
-        mBitmap->DiscardBuffer();
-      }
+      AssignBitmap( false, pixels );
     }
   }
 }
@@ -294,14 +298,12 @@ void BitmapTexture::UpdateArea( const RectArea& updateArea )
   if( mBitmap != 0 )
   {
     const unsigned char* pixels = mBitmap->GetBuffer();
-    if ( NULL == pixels )
-    {
-      DALI_LOG_ERROR("bitmap has no data\n");
-      GlCleanup(); ///!ToDo: Why do we suicide in the case of bad input?
-    }
-    else
+
+    // Pixel data could be null if we've uploaded to GL and discarded the data.
+
+    if( NULL != pixels )
     {
-      if ( mId ) // If the texture is already bound
+      if( mId ) // If the texture is already bound
       {
         if( updateArea.IsEmpty() )
         {
@@ -376,18 +378,21 @@ bool BitmapTexture::UpdateOnCreate()
 bool BitmapTexture::CreateGlTexture()
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
-  DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Bitmap: %s\n", DALI_LOG_GET_OBJECT_C_STR(this));
+  DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "BitmapTexture::CreateGlTexture() Bitmap: %s\n", DALI_LOG_GET_OBJECT_C_STR(this));
 
   if( mBitmap )
   {
     const unsigned char* pixels = mBitmap->GetBuffer();
 
-    DALI_ASSERT_DEBUG(pixels != NULL);
+    // pixel data could be NULL here if we've had a context loss and we previously discarded
+    // the pixel data on the previous upload. If it is null, then we shouldn't generate a
+    // new GL Texture; leaving mId as zero. Eventually, the bitmap will get reloaded,
+    // and pixels will become non-null.
 
     if( NULL != pixels )
     {
       AssignBitmap( true, pixels );
-      mBitmap->DiscardBuffer();
+      DiscardBitmapBuffer();
     }
   }
   else
@@ -433,6 +438,18 @@ unsigned int BitmapTexture::GetHeight() const
   return height;
 }
 
+void BitmapTexture::DiscardBitmapBuffer()
+{
+  DALI_LOG_INFO(Debug::Filter::gImage, Debug::General, "BitmapTexture::DiscardBitmapBuffer() DiscardPolicy: %s\n", mDiscardPolicy == ResourcePolicy::DISCARD?"DISCARD":"RETAIN");
+
+  if( ResourcePolicy::DISCARD == mDiscardPolicy )
+  {
+    DALI_LOG_INFO(Debug::Filter::gImage, Debug::General, "  Discarding bitmap\n");
+    mBitmap->DiscardBuffer();
+  }
+}
+
+
 } //namespace Internal
 
 } //namespace Dali
index 4e33d90ea57a18e75e45cb4f8c08ad6ce28d5227..46073c8c083bf5ffdf65a793b804cb64a7a49c24 100644 (file)
@@ -27,6 +27,7 @@
 #include <dali/internal/common/bitmap-upload.h>
 #include <dali/integration-api/bitmap.h>
 #include <dali/integration-api/debug.h>
+#include <dali/internal/render/gl-resources/texture-cache.h>
 
 namespace Dali
 {
@@ -54,7 +55,7 @@ public:
    * @param[in] bitmapPackedPixelsProfile The Bitmap features related to an addressable array of raw pixel data
    * @param     context The GL context
    */
-  BitmapTexture(Integration::Bitmap* const bitmap, const Integration::Bitmap::PackedPixelsProfile * const bitmapPackedPixelsProfile, Context& context);
+  BitmapTexture(Integration::Bitmap* const bitmap, const Integration::Bitmap::PackedPixelsProfile * const bitmapPackedPixelsProfile, Context& context, ResourcePolicy::Discardable discardPolicy);
 
   /**
    * Constructor
@@ -66,7 +67,7 @@ public:
    * @param[in] context Dali context
    */
   BitmapTexture( unsigned int width, unsigned int height, Pixel::Format pixelFormat,
-                 bool clearPixels, Context& context );
+                 bool clearPixels, Context& context, ResourcePolicy::Discardable discardPolicy );
 
   /**
    * Destructor.
@@ -159,9 +160,15 @@ private:
    */
   void AssignBitmap( bool generateTexture, const unsigned char* pixels );
 
+  /**
+   * If the discard policy is not RETAIN, then discards the bitmap's pixel buffer
+   */
+  void DiscardBitmapBuffer();
+
 private:
   Integration::BitmapPtr mBitmap;      ///< The Bitmap the Texture was created from (may be NULL)
   bool                   mClearPixels; ///< true if initial texture should be cleared on creation
+  ResourcePolicy::Discardable mDiscardPolicy; ///< The bitmap discard policy
 
   // Changes scope, should be at end of class
   DALI_LOG_OBJECT_STRING_DECLARATION;
index 76428333a84427d430a0d9696851c4534bd3e490..ba5ff0d90088489aadbc4bf08a0a418612aed3b1 100644 (file)
@@ -36,14 +36,15 @@ namespace Dali
 namespace Internal
 {
 
-CompressedBitmapTexture::CompressedBitmapTexture(Internal::BitmapCompressed* const bitmap, Context& context)
+CompressedBitmapTexture::CompressedBitmapTexture(Internal::BitmapCompressed* const bitmap, Context& context, ResourcePolicy::Discardable discardPolicy)
 : Texture(context,
           bitmap->GetImageWidth(),
           bitmap->GetImageHeight(),
           bitmap->GetImageWidth(),
           bitmap->GetImageHeight(),
           bitmap->GetPixelFormat()),
-  mBitmap(bitmap)
+  mBitmap(bitmap),
+  mDiscardPolicy(discardPolicy)
 {
   DALI_LOG_TRACE_METHOD(Debug::Filter::gImage);
   DALI_LOG_SET_OBJECT_STRING(this, DALI_LOG_GET_OBJECT_STRING(bitmap));
@@ -139,7 +140,11 @@ void CompressedBitmapTexture::Update( Integration::Bitmap* bitmap )
     if ( mId ) // If the texture is already bound
     {
       AssignBitmap( false, pixels, mBitmap->GetBufferSize() );
-      mBitmap->DiscardBuffer();
+
+      if( mDiscardPolicy == ResourcePolicy::DISCARD )
+      {
+        mBitmap->DiscardBuffer();
+      }
     }
   }
 }
index 45f124b6d279da5137eb25c96dfccc217b90f7bd..583c1ff0fc5c596e17fe22eb8496b521f54e6e61 100644 (file)
@@ -26,6 +26,7 @@
 #include <dali/public-api/images/bitmap-image.h>
 #include <dali/internal/common/message.h>
 #include <dali/internal/render/gl-resources/texture.h>
+#include <dali/internal/render/gl-resources/texture-cache.h>
 #include <dali/internal/common/bitmap-upload.h>
 #include <dali/integration-api/bitmap.h>
 #include <dali/internal/event/images/bitmap-compressed.h>
@@ -55,9 +56,10 @@ public:
    * Constructor
    * Creates a new texture object from a Bitmap
    * @param[in] bitmap The Bitmap
-   * @param     context The GL context
+   * @param[in] context The GL context
+   * @param[in] discardPolicy The discard policy
    */
-  CompressedBitmapTexture( Internal::BitmapCompressed* const bitmap, Context& context );
+  CompressedBitmapTexture( Internal::BitmapCompressed* const bitmap, Context& context, ResourcePolicy::Discardable discardPolicy );
 
   /**
    * Destructor.
@@ -121,6 +123,7 @@ private:
 
 private:
   Internal::BitmapCompressedPtr mBitmap;      ///< The Bitmap the Texture was created from (may be NULL)
+  ResourcePolicy::Discardable mDiscardPolicy;
 
   // Changes scope, should be at end of class
   DALI_LOG_OBJECT_STRING_DECLARATION;
index f66426818192e8d63729cfb32b7e9d2679502afb..6d5aef8a7616fea84e1b011bf146e7acb2dceee2 100644 (file)
@@ -72,6 +72,7 @@ const unsigned int UNINITIALIZED_TEXTURE_UNIT = std::numeric_limits<unsigned int
 
 #ifdef DEBUG_ENABLED
 Debug::Filter* Context::gGlLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CONTEXT");
+Debug::Filter* gContextLogFilter = Debug::Filter::New(Debug::Concise, false, "LOG_CONTEXT_META");
 #endif
 
 Context::Context(Integration::GlAbstraction& glAbstraction)
@@ -118,6 +119,8 @@ Context::~Context()
 
 void Context::GlContextCreated()
 {
+  DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextCreated()\n");
+
   DALI_ASSERT_DEBUG(!mGlContextCreated);
 
   mGlContextCreated = true;
@@ -125,15 +128,14 @@ void Context::GlContextCreated()
   // Set the initial GL state, and check it.
   ResetGlState();
 
-  const ProgramContainer::iterator endp = mProgramCache.end();
-  for ( ProgramContainer::iterator itp = mProgramCache.begin(); itp != endp; ++itp )
-  {
-    (*itp).second->GlContextCreated();
-  }
+  // Programs now load on demand
 }
 
 void Context::GlContextDestroyed()
 {
+  DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::GlContextDestroyed()\n");
+
+  // Inform programs they are no longer valid
   const ProgramContainer::iterator endp = mProgramCache.end();
   for ( ProgramContainer::iterator itp = mProgramCache.begin(); itp != endp; ++itp )
   {
@@ -252,6 +254,7 @@ void Context::ResetVertexAttributeState()
 
 void Context::ResetGlState()
 {
+  DALI_LOG_INFO(gContextLogFilter, Debug::Verbose, "Context::ResetGlState()\n");
   DALI_ASSERT_DEBUG(mGlContextCreated);
 
   mClearColorSet = false;
index 9b37ad63a328eadc29b3c58e32f4527076242514..073a2a08dc84e8a42496e812c7498175733fca06 100644 (file)
@@ -584,7 +584,7 @@ public:
    */
   void DeleteBuffers(GLsizei n, const GLuint* buffers)
   {
-    // TODO: this is to prevent mesh destructor from doing GL calls when DALi core is being deleted
+    // @todo: this is to prevent mesh destructor from doing GL calls when DALi core is being deleted
     // can be taken out once render manages either knows about meshes or gpubuffers and can tell them directly that context is lost
     if( this->IsGlContextCreated() )
     {
index c8249ffc7e976eb05f97d5831cf146139d3122f1..2191b2325da1599d85ef150d89c32328bc0bdc8d 100644 (file)
@@ -36,6 +36,14 @@ using Dali::Internal::Texture;
 using Dali::Internal::FrameBufferTexture;
 using Dali::Integration::Bitmap;
 
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gTextureCacheFilter = Debug::Filter::New(Debug::Concise, false, "LOG_TEXTURE_CACHE");
+#endif
+}
+
+
 namespace Dali
 {
 namespace Internal
@@ -52,7 +60,8 @@ TextureCache::TextureCache( RenderQueue& renderQueue,
                             Context& context)
 : TextureCacheDispatcher(renderQueue),
   mPostProcessResourceDispatcher(postProcessResourceDispatcher),
-  mContext(context)
+  mContext(context),
+  mDiscardBitmapsPolicy(ResourcePolicy::DISCARD)
 {
 }
 
@@ -68,7 +77,7 @@ void TextureCache::CreateTexture( ResourceId        id,
 {
   DALI_LOG_INFO(Debug::Filter::gGLResource, Debug::General, "TextureCache::CreateTexture(id=%i width:%u height:%u)\n", id, width, height);
 
-  Texture* texture = TextureFactory::NewBitmapTexture(width, height, pixelFormat, clearPixels, mContext);
+  Texture* texture = TextureFactory::NewBitmapTexture(width, height, pixelFormat, clearPixels, mContext, GetDiscardBitmapsPolicy() );
   mTextures.insert(TexturePair(id, texture));
 }
 
@@ -76,7 +85,7 @@ void TextureCache::AddBitmap(ResourceId id, Integration::BitmapPtr bitmap)
 {
   DALI_LOG_INFO(Debug::Filter::gGLResource, Debug::General, "TextureCache::AddBitmap(id=%i Bitmap:%p)\n", id, bitmap.Get());
 
-  Texture* texture = TextureFactory::NewBitmapTexture(bitmap.Get(), mContext);
+  Texture* texture = TextureFactory::NewBitmapTexture(bitmap.Get(), mContext, GetDiscardBitmapsPolicy());
   mTextures.insert(TexturePair(id, texture));
 }
 
@@ -120,7 +129,7 @@ void TextureCache::UpdateTexture( ResourceId id, Integration::BitmapPtr bitmap )
     TexturePointer texturePtr = textureIter->second;
     if( texturePtr )
     {
-      texturePtr->Update(bitmap.Get());
+      texturePtr->Update( bitmap.Get() );
 
       ResourcePostProcessRequest ppRequest( id, ResourcePostProcessRequest::UPLOADED );
       mPostProcessResourceDispatcher.DispatchPostProcessRequest(ppRequest);
@@ -372,6 +381,19 @@ void TextureCache::GlContextDestroyed()
   }
 }
 
+void TextureCache::SetDiscardBitmapsPolicy( ResourcePolicy::Discardable policy )
+{
+  DALI_LOG_INFO( gTextureCacheFilter, Debug::General, "TextureCache::SetDiscardBitmapsPolicy(%s)\n",
+                 policy==ResourcePolicy::RETAIN?"RETAIN":"DISCARD" );
+  mDiscardBitmapsPolicy = policy;
+}
+
+ResourcePolicy::Discardable TextureCache::GetDiscardBitmapsPolicy()
+{
+  return mDiscardBitmapsPolicy;
+}
+
+
 /********************************************************************************
  **********************  Implements TextureCacheDispatcher  *********************
  ********************************************************************************/
index 581b082fac7073012a6c03ae65ca0b05927ff820..dad0f549fbd9bd3739194079fd2a0c6f4f72ea47 100644 (file)
@@ -27,6 +27,8 @@
 #include <dali/public-api/images/native-image.h>
 #include <dali/public-api/math/rect.h>
 #include <dali/public-api/math/vector4.h>
+#include <dali/integration-api/platform-abstraction.h>
+#include <dali/integration-api/resource-policies.h>
 #include <dali/integration-api/gl-abstraction.h>
 #include <dali/internal/common/owner-pointer.h>
 #include <dali/internal/update/common/scene-graph-buffers.h>
@@ -68,7 +70,7 @@ typedef TextureContainer::const_iterator        TextureConstIter;
 class TextureCache : public TextureCacheDispatcher
 {
 public:
 /**
+ /**
    * Constructor
    * @param[in] renderQueue Queue to use for dispatching messages to this object
    * @param[in] postProcessDispatcher Dispatcher for resource post processing requests
@@ -215,6 +217,18 @@ public:
    */
   void GlContextDestroyed();
 
+  /**
+   * Set whether textures should retain or discard their bitmaps after upload to GL
+   * @param[in] policy Whether to retain or discard bitmaps
+   */
+  void SetDiscardBitmapsPolicy( ResourcePolicy::Discardable policy );
+
+  /**
+   * Get the discard policy.
+   * @return The discard policy.
+   */
+  ResourcePolicy::Discardable GetDiscardBitmapsPolicy();
+
 protected: // Implements TextureCacheDispatcher
 
   /**
@@ -285,6 +299,7 @@ private:
   typedef TextureResourceObservers::iterator       TextureResourceObserversIter;
 
   TextureResourceObservers mObservers;
+  ResourcePolicy::Discardable mDiscardBitmapsPolicy;
 };
 
 
index 87fa20af539efa427aaf0790c8a6eadfdc31d1a6..72ac11ab80001a4d502353c40901f2e27443befa 100644 (file)
@@ -38,21 +38,21 @@ namespace Internal
 namespace TextureFactory
 {
 
-Internal::Texture* NewBitmapTexture( Integration::Bitmap* const bitmap, Context& context )
+Internal::Texture* NewBitmapTexture( Integration::Bitmap* const bitmap, Context& context, ResourcePolicy::Discardable discardPolicy )
 {
   DALI_ASSERT_DEBUG( bitmap );
   Texture * texture = 0;
   Integration::Bitmap::PackedPixelsProfile * const  packedPixelBitmapView = bitmap->GetPackedPixelsProfile();
   if( packedPixelBitmapView )
   {
-    texture = new BitmapTexture( bitmap, packedPixelBitmapView, context );
+    texture = new BitmapTexture( bitmap, packedPixelBitmapView, context, discardPolicy );
   }
   else
   {
     Internal::BitmapCompressed * const compressedBitmap = dynamic_cast<Dali::Internal::BitmapCompressed*>( bitmap );
     if( compressedBitmap != 0 )
     {
-      texture = new CompressedBitmapTexture( compressedBitmap, context );
+      texture = new CompressedBitmapTexture( compressedBitmap, context, discardPolicy );
     }
   }
   if( texture )
@@ -70,9 +70,10 @@ Internal::Texture* NewBitmapTexture( unsigned int      width,
                                      unsigned int      height,
                                      Pixel::Format     pixelFormat,
                                      bool              clearPixels,
-                                     Context&          context )
+                                     Context&          context,
+                                     ResourcePolicy::Discardable discardPolicy )
 {
-  Texture *texture=new BitmapTexture(width, height, pixelFormat, clearPixels, context);
+  Texture *texture=new BitmapTexture(width, height, pixelFormat, clearPixels, context, discardPolicy);
 
   return texture;
 }
@@ -120,4 +121,3 @@ Internal::Texture* NewFrameBufferTexture( NativeImagePtr nativeImage,
 } // TextureFactory
 } // Internal
 } // Dali
-
index c71dd30c83699deacc8ca7eadf221bb5c2c803bb..59131ebf6db625204bf4c78c7d381c50184132fa 100644 (file)
@@ -21,7 +21,7 @@
 // INTERNAL INCLUDES
 #include <dali/public-api/object/ref-object.h>
 #include <dali/public-api/images/native-image.h>
-
+#include <dali/internal/render/gl-resources/texture-cache.h>
 
 namespace Dali
 {
@@ -45,7 +45,9 @@ namespace TextureFactory
  * @param[in] context The GL context
  * @return A newly allocated texture
  */
-Internal::Texture* NewBitmapTexture( Integration::Bitmap* const bitmap, Context& context );
+Internal::Texture* NewBitmapTexture( Integration::Bitmap* const bitmap,
+                                     Context& context,
+                                     ResourcePolicy::Discardable discardPolicy );
 
 /**
  * Creates a new bitmap texture object of the given dimensions.
@@ -59,7 +61,8 @@ Internal::Texture* NewBitmapTexture( unsigned int      width,
                                      unsigned int      height,
                                      Pixel::Format     pixelFormat,
                                      bool              clearPixels,
-                                     Context&          context );
+                                     Context&          context,
+                                     ResourcePolicy::Discardable discardPolicy );
 
 /**
  * Creates a texture object from a native image (eg.: EGLImage).
index 6e2c98db854bbe6e415c9f0542b78b19c085a8f6..32b41a59ca07b4da36022ed4e908b5e9e5a96fcb 100644 (file)
@@ -98,8 +98,7 @@ Texture::Texture(Context&      context,
   mHeight(height),
   mImageWidth(imageWidth),
   mImageHeight(imageHeight),
-  mPixelFormat(pixelFormat),
-  mDiscarded(false)
+  mPixelFormat(pixelFormat)
 {
 }
 
@@ -275,7 +274,7 @@ void Texture::ApplyTextureParameter( GLint filterType, FilterMode::Type currentF
 
 void Texture::ApplySampler( unsigned int samplerBitfield )
 {
-  if( mSamplerBitfield != samplerBitfield )
+  if( mSamplerBitfield != samplerBitfield && mId != 0 )
   {
     ApplyTextureParameter( GL_TEXTURE_MIN_FILTER,
                            ImageSampler::GetMinifyFilterMode( mSamplerBitfield ),
index 1ff8a7ea4a21044f19b0018223602f8a65262353..805c47d76f645b69d30ff2d342db2adead4a219c 100644 (file)
@@ -85,11 +85,12 @@ public:
 
   /**
    * Binds the texture for use.
-   * Only when Bind() is first called, does a texture create an
-   * an opengl texture.
+   * If there is no GL texture yet, it tries to create one.
+   *
    * @param target (e.g. GL_TEXTURE_2D)
    * @param textureunit to bind to
-   * @return True if the opengl texture was created
+   * @return True if the opengl texture was created, false if there was already a texture
+   * or no texture could be created yet ( e.g. no bitmap data after context loss )
    */
   virtual bool Bind(GLenum target, GLenum textureunit);
 
@@ -274,7 +275,6 @@ protected:
   unsigned int  mImageHeight;  ///< height of the original image (may be smaller than texture height)
 
   Pixel::Format mPixelFormat;  ///< Pixel format of the contained image data.
-  bool          mDiscarded;    ///< True if texture was added to the DiscardQueue
 
 };
 
index 292cf661ff57141ea1cdadebcb7684c9a870ba35..96bd12a40c4bf3c38852e4fc71e24e5d4ca85aa4 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/dali-common.h>
+#include <dali/integration-api/debug.h>
 #include <dali/internal/common/internal-constants.h>
 #include <dali/internal/render/common/culling-algorithms.h>
 #include <dali/internal/render/common/performance-monitor.h>
@@ -36,6 +37,10 @@ using namespace std;
 
 namespace
 {
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gImageRenderFilter=Debug::Filter::New(Debug::NoLogging, false, "LOG_IMAGE_RENDERER");
+#endif
+
 /**
  * VertexToTextureCoord
  * Represents a mapping between a 1 dimensional vertex coordinate
@@ -184,6 +189,8 @@ void ImageRenderer::GlContextDestroyed()
 
 void ImageRenderer::GlCleanup()
 {
+  DALI_LOG_INFO( gImageRenderFilter, Debug::Verbose, "GlCleanup() textureId=%d  texture:%p\n", mTextureId, mTexture);
+
   mVertexBuffer.Reset();
   mIndexBuffer.Reset();
 }
@@ -245,6 +252,8 @@ bool ImageRenderer::IsOutsideClipSpace( const Matrix& modelMatrix, const Matrix&
 
 void ImageRenderer::DoRender( BufferIndex bufferIndex, Program& program, const Matrix& modelViewMatrix, const Matrix& viewMatrix )
 {
+  DALI_LOG_INFO( gImageRenderFilter, Debug::Verbose, "DoRender() textureId=%d  texture:%p\n", mTextureId, mTexture);
+
   DALI_ASSERT_DEBUG( 0 != mTextureId && "ImageRenderer::DoRender. mTextureId == 0." );
   DALI_ASSERT_DEBUG( NULL != mTexture && "ImageRenderer::DoRender. mTexture == NULL." );
 
@@ -256,6 +265,12 @@ void ImageRenderer::DoRender( BufferIndex bufferIndex, Program& program, const M
   DALI_ASSERT_DEBUG( mVertexBuffer );
 
   mTextureCache->BindTexture( mTexture, mTextureId,  GL_TEXTURE_2D, GL_TEXTURE0 );
+
+  if( mTexture->GetTextureId() == 0 )
+  {
+    return; // early out if we haven't got a GL texture yet (e.g. due to context loss)
+  }
+
   mTexture->ApplySampler( mSamplerBitfield );
 
   // make sure the vertex is bound, this has to be done before
index b014a48f98494fc4d6fb98b5da40d9c308f257a2..c6b605cc6c4f751eb14c3431edf258a8410feab5 100644 (file)
@@ -169,9 +169,9 @@ GLint Program::GetAttribLocation( AttribType type )
 
   if( mAttribLocations[ type ] == ATTRIB_UNKNOWN )
   {
-    LOG_GL( "GetAttribLocation(program=%d,%s) = %d\n", mProgramId, gStdAttribs[type], mAttribLocations[type] );
     GLint loc = CHECK_GL( mContext, mGlAbstraction.GetAttribLocation( mProgramId, gStdAttribs[type] ) );
     mAttribLocations[ type ] = loc;
+    LOG_GL( "GetAttribLocation(program=%d,%s) = %d\n", mProgramId, gStdAttribs[type], mAttribLocations[type] );
   }
 
   return mAttribLocations[type];
@@ -204,10 +204,10 @@ GLint Program::GetUniformLocation( unsigned int uniformIndex )
 
   if( location == UNIFORM_NOT_QUERIED )
   {
-    LOG_GL( "GetUniformLocation(program=%d,%s) = %d\n", mProgramId, mUniformLocations[ uniformIndex ].first.c_str(), mUniformLocations[ uniformIndex ].second );
     location = CHECK_GL( mContext, mGlAbstraction.GetUniformLocation( mProgramId, mUniformLocations[ uniformIndex ].first.c_str() ) );
 
     mUniformLocations[ uniformIndex ].second = location;
+    LOG_GL( "GetUniformLocation(program=%d,%s) = %d\n", mProgramId, mUniformLocations[ uniformIndex ].first.c_str(), mUniformLocations[ uniformIndex ].second );
   }
 
   return location;
@@ -412,22 +412,18 @@ void Program::SetUniformMatrix3fv( GLint location, GLsizei count, const GLfloat*
 
 void Program::GlContextCreated()
 {
-  if (!mLinked)
-  {
-    Load();
-  }
 }
 
 void Program::GlContextDestroyed()
 {
-  Unload();
+  mLinked = false;
 
   mVertexShaderId = 0;
   mFragmentShaderId = 0;
   mProgramId = 0;
   mContext.SetCurrentProgram( NULL );
 
-  ResetAttribsUniforms();
+  ResetAttribsUniformCache();
 }
 
 bool Program::ModifiesGeometry()
@@ -455,7 +451,7 @@ Program::Program(Integration::ShaderDataPtr shaderData, Context& context, bool m
     RegisterUniform( gStdUniforms[ i ] );
   }
   // reset values
-  ResetAttribsUniforms();
+  ResetAttribsUniformCache();
 }
 
 Program::~Program()
@@ -656,7 +652,7 @@ void Program::FreeShaders()
   }
 }
 
-void Program::ResetAttribsUniforms()
+void Program::ResetAttribsUniformCache()
 {
   // reset attribute locations
   for( unsigned i = 0; i < ATTRIB_TYPE_LAST; ++i )
index 5cd97a3f1e0bc8c87b165f015fae6154d91a1729..b9efaccd21d6347a0b7ffaaf601d11fbaff6f705 100644 (file)
@@ -348,7 +348,7 @@ private:
   /**
    * Resets caches
    */
-  void ResetAttribsUniforms();
+  void ResetAttribsUniformCache();
 
 private:  // Data
 
index be32605ff8e4dbbf05991078201701a6d5388f1f..2cd7859c645168d67850152c78cb5fffe4c6c162 100644 (file)
@@ -317,7 +317,8 @@ void Shader::SetUniforms( Context& context,
   if( mTexture )
   {
     // got effect texture, bind it to texture unit 1
-    mTexture->Bind( GL_TEXTURE_2D, GL_TEXTURE1 );
+    mTextureCache->BindTexture( mTexture, mRenderTextureId, GL_TEXTURE_2D, GL_TEXTURE1 );
+
     // Just apply the default sampling options for now
     mTexture->ApplySampler( ImageSampler::PackBitfield( FilterMode::DEFAULT, FilterMode::DEFAULT ) );
 
index 69227ab38fb66676175dcbac7956117d30199b67..13bbf9045debcc22c1ebdb616f8817298a52665c 100644 (file)
 
 #include <dali/internal/update/modeling/internal-mesh-data.h>
 
+#include <dali/integration-api/platform-abstraction.h>
+#include <dali/internal/event/common/thread-local-storage.h>
+
 namespace Dali
 {
 
 namespace Internal
 {
 
-MeshData::MeshData( const Dali::MeshData& meshData, bool discardable, bool scalingRequired )
+MeshData::MeshData( const Dali::MeshData& meshData, ResourcePolicy::Discardable discardable, bool scalingRequired )
 : mVertices( meshData.GetVertices() ),
   mFaces( meshData.GetFaces() ),
   mBones( meshData.GetBones() ),
@@ -32,7 +35,7 @@ MeshData::MeshData( const Dali::MeshData& meshData, bool discardable, bool scali
   mGeometryType( meshData.GetVertexGeometryType() ),
   mHasNormals( meshData.HasNormals() ),
   mHasColor( meshData.HasColor() ),
-  mDiscardable( discardable ),
+  mDiscardable( discardable==ResourcePolicy::DISCARD ),
   mDiscarded( false ),
   mScalingRequired( scalingRequired )
 {
@@ -118,7 +121,7 @@ bool MeshData::HasColor() const
 
 void MeshData::Discard()
 {
-  if (mDiscardable)
+  if( mDiscardable )
   {
     DALI_ASSERT_DEBUG( !mDiscarded );
     VertexContainer().swap(mVertices);  // this will enforce releasing the memory
index ae3e33a6f7d84fcf1b66a8b51d2972b55aaa48d6..73b05392cfab2f6e1087b93724663467ccaf38de 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <dali/public-api/geometry/mesh-data.h>
+#include <dali/integration-api/resource-policies.h>
 
 namespace Dali
 {
@@ -52,7 +53,7 @@ public:
    * @param[in] discardable if true, the vertex and index data will be discarded after they are uploaded to gl
    * @param[in] scalingRequired - True if this Mesh should be scaled to fit actor size
    */
-  explicit MeshData( const Dali::MeshData& meshData, bool discardable, bool scalingRequired );
+  explicit MeshData( const Dali::MeshData& meshData, ResourcePolicy::Discardable discardable, bool scalingRequired );
 
   /**
    * @copydoc Dali::MeshData::GetVertexCount
index 4bdf15e22d834527278217dffe9dd0139ee4d323..321498d537de9a4327402217adbae9cfc4e21861 100644 (file)
@@ -124,6 +124,18 @@ void Mesh::UploadVertexData( Context& context, BufferIndex renderBufferIndex )
     return;
   }
 
+  DoUpload(context);
+
+  // Note, dispatcher should only be used in Render Thread (as should the rest of this method!)
+  ResourcePostProcessRequest ppRequest( mResourceId, ResourcePostProcessRequest::UPLOADED );
+  mPostProcessResourceDispatcher.DispatchPostProcessRequest(ppRequest);
+
+  mRenderMeshData->Discard();
+  mRefreshVertexBuffer = false;
+}
+
+void Mesh::DoUpload( Context& context )
+{
   const MeshData::VertexContainer& vertices = mRenderMeshData->GetVertices();
 
   DALI_ASSERT_DEBUG( !vertices.empty() );
@@ -149,13 +161,6 @@ void Mesh::UploadVertexData( Context& context, BufferIndex renderBufferIndex )
     mIndicesBuffer->UpdateDataBuffer( numberOfIndices * sizeof(GLushort), &(faces.at(0)) );
     mNumberOfFaces = mRenderMeshData->GetFaceCount();
   }
-
-  // Note, dispatcher should only be used in Render Thread (as should the rest of this method!)
-  ResourcePostProcessRequest ppRequest( mResourceId, ResourcePostProcessRequest::UPLOADED );
-  mPostProcessResourceDispatcher.DispatchPostProcessRequest(ppRequest);
-
-  mRenderMeshData->Discard();
-  mRefreshVertexBuffer = false;
 }
 
 void Mesh::BindBuffers(Context& context)
@@ -168,9 +173,18 @@ void Mesh::BindBuffers(Context& context)
 
   DALI_ASSERT_DEBUG( mIndicesBuffer || mRenderMeshData->GetVertexGeometryType() == Dali::MeshData::POINTS );
 
-  mVertexBuffer->Bind();
+  // Try and recover from context loss using retained data.
+  if( ! mVertexBuffer->BufferIsValid() && ! mRenderMeshData->GetVertices().empty() )
+  {
+    DoUpload( context );
+  }
+
+  if( mVertexBuffer->BufferIsValid() )
+  {
+    mVertexBuffer->Bind();
+  }
 
-  if( mIndicesBuffer)
+  if( mIndicesBuffer && mIndicesBuffer->BufferIsValid())
   {
     mIndicesBuffer->Bind();
   }
index 5c694c23b9c9beb709115fe6ead6def8c35928e6..f463fe6a70a34305c2d570ef3398b7a40213b46e 100644 (file)
@@ -107,13 +107,19 @@ public:
   void MeshDataUpdated( BufferIndex bufferIndex, ThreadBuffer threadBuffer, MeshData* meshData );
 
   /**
-   * Sends the vertex data to GL
+   * Sends the vertex data to GL if it has been refreshed. Notify resource manager when it has finished.
    * @pre this function should only be called from the render thread
    * @param[in] context The GL context.
    * @param[in] renderBufferIndex The index that should be accessed in double buffered values.
    */
   void UploadVertexData( Context& context, BufferIndex renderBufferIndex );
 
+  /**
+   * Actually perform the vertex upload.
+   * @param[in] context The GL context.
+   */
+  void DoUpload( Context& context );
+
   /**
    * Bind the vertex and index buffers.
    * @pre this function should only be called from the render thread
index 0f7e805690c8cdebabe1f7fe806daab773aa11b1..cf8e95fab3b6348379a85a62253d398c78a6e9ae 100644 (file)
@@ -255,7 +255,9 @@ bool ImageAttachment::DoPrepareResources( BufferIndex updateBufferIndex, Resourc
     break;
   }
 
-  ATTACHMENT_LOG_FMT(Debug::General, " finished:%s ready:%s \n", mFinishedResourceAcquisition?"T":"F", ready?"T":"F");
+  ATTACHMENT_LOG_FMT(Debug::General, " ObjName:%s finished:%s ready:%s \n",
+                     DALI_LOG_GET_OBJECT_C_STR(mParent),
+                     mFinishedResourceAcquisition?"T":"F", ready?"T":"F");
 
   return ready;
 }
@@ -264,7 +266,9 @@ void ImageAttachment::DoPrepareRender( BufferIndex updateBufferIndex )
 {
   DALI_ASSERT_DEBUG( mSceneController && mImageRenderer );
 
-  ATTACHMENT_LOG_FMT(Debug::General, " textureId:%d\n", mTextureId);
+  ATTACHMENT_LOG_FMT(Debug::General, "ObjName:%s textureId:%d\n",
+                     DALI_LOG_GET_OBJECT_C_STR(mParent),
+                     mTextureId);
 
   // Check whether we need to refresh the vertex buffer.
   if ( mRefreshMeshData )
index c56833a7207d23cbf165af08b4513256a69df9c0..8c28a814f6d187b136327a13757900be1bf41b46 100644 (file)
@@ -88,6 +88,11 @@ typedef ShaderCache::iterator                 ShaderCacheIter;
 typedef ShaderCache::size_type                ShaderCacheSize;
 typedef pair<ResourceId, ShaderDataPtr>       ShaderDataPair;
 
+static inline bool RemoveId( LiveRequestContainer& container, ResourceId id )
+{
+  return container.erase(id) != 0;
+}
+
 struct ResourceManager::ResourceManagerImpl
 {
   ResourceManagerImpl( PlatformAbstraction& platformAbstraction,
@@ -445,13 +450,21 @@ void ResourceManager::HandleUpdateMeshRequest( BufferIndex updateBufferIndex, Re
   new (slot) DerivedType( mesh, &SceneGraph::Mesh::MeshDataUpdated, SceneGraph::Mesh::RENDER_THREAD, meshData );
 }
 
-void ResourceManager::HandleReloadResourceRequest( ResourceId id, const ResourceTypePath& typePath, LoadResourcePriority priority )
+void ResourceManager::HandleReloadResourceRequest( ResourceId id, const ResourceTypePath& typePath, LoadResourcePriority priority, bool resetFinishedStatus )
 {
   DALI_ASSERT_DEBUG( mImpl->mResourceClient != NULL );
   DALI_LOG_INFO( Debug::Filter::gResource, Debug::General, "ResourceManager: HandleReloadRequest(id:%u, path:%s)\n", id, typePath.path.c_str() );
 
   bool resourceIsAlreadyLoading = true;
 
+  if( resetFinishedStatus )
+  {
+    if( ! RemoveId( mImpl->newCompleteRequests, id ) )
+    {
+      RemoveId( mImpl->oldCompleteRequests, id );
+    }
+  }
+
   // ID might be in the loading set
   LiveRequestIter iter = mImpl->loadingRequests.find( id );
   if ( iter == mImpl->loadingRequests.end() )
@@ -463,7 +476,7 @@ void ResourceManager::HandleReloadResourceRequest( ResourceId id, const Resource
 
   if ( !resourceIsAlreadyLoading )
   {
-    //load resource again
+    // load resource again
     mImpl->mPlatformAbstraction.LoadResource(ResourceRequest(id, *typePath.type, typePath.path, priority));
     SendToClient( LoadingMessage( *mImpl->mResourceClient, id ) );
   }
@@ -539,11 +552,6 @@ void ResourceManager::HandleSaveResourceRequest( ResourceId id, const ResourceTy
   }
 }
 
-static inline bool RemoveId( LiveRequestContainer& container, ResourceId id )
-{
-  return container.erase(id) != 0;
-}
-
 void ResourceManager::HandleDiscardResourceRequest( ResourceId deadId, ResourceTypeId typeId )
 {
   bool wasComplete = false;
index 56bfd55df02898c0186f170417f28d87857603ec..2a2a947a8c644aba8ec5167f9138483e57e9619a 100644 (file)
@@ -34,6 +34,7 @@
 
 #include <dali/internal/common/event-to-update.h>
 #include <dali/internal/common/message.h>
+#include <dali/internal/event/common/thread-local-storage.h>
 #include <dali/internal/common/bitmap-upload.h>
 #include <dali/internal/event/text/font-impl.h>
 #include <dali/internal/event/modeling/model-data-impl.h>
@@ -284,8 +285,9 @@ public: // Used by ResourceClient
    * @param[in] id The resource id
    * @param[in] typePath The type & path of the resource
    * @param[in] priority The priority of the request. This is ignored if the resource is already being refreshed.
+   * @param[in] resetFinishedStatus True if the finished status of the resource id should be reset
    */
-  void HandleReloadResourceRequest( ResourceId id, const ResourceTypePath& typePath, Integration::LoadResourcePriority priority );
+  void HandleReloadResourceRequest( ResourceId id, const ResourceTypePath& typePath, Integration::LoadResourcePriority priority, bool resetFinishedStatus );
 
   /**
    * Save a resource to the given url
@@ -631,14 +633,14 @@ inline void RequestUpdateBitmapAreaMessage( EventToUpdate& eventToUpdate,
 inline void RequestUpdateMeshMessage( EventToUpdate& eventToUpdate,
                                       ResourceManager& manager,
                                       ResourceId id,
-                                      const Dali::MeshData& meshData )
+                                      const Dali::MeshData& meshData,
+                                      ResourcePolicy::Discardable discardable )
 {
   typedef MessageDoubleBuffered2< ResourceManager, ResourceId, OwnerPointer< MeshData > > LocalType;
-
   // Reserve some memory inside the message queue
   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
 
-  MeshData* internalMeshData = new MeshData( meshData, true, false );
+  MeshData* internalMeshData = new MeshData( meshData, discardable, false );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
   new (slot) LocalType( &manager, &ResourceManager::HandleUpdateMeshRequest, id, internalMeshData );
@@ -648,15 +650,16 @@ inline void RequestReloadResourceMessage( EventToUpdate& eventToUpdate,
                                           ResourceManager& manager,
                                           ResourceId id,
                                           const ResourceTypePath& typePath,
-                                          Integration::LoadResourcePriority priority )
+                                          Integration::LoadResourcePriority priority,
+                                          bool resetFinishedStatus )
 {
-  typedef MessageValue3< ResourceManager, ResourceId, ResourceTypePath, Integration::LoadResourcePriority > LocalType;
+  typedef MessageValue4< ResourceManager, ResourceId, ResourceTypePath, Integration::LoadResourcePriority, bool > LocalType;
 
   // Reserve some memory inside the message queue
   unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ), false );
 
   // Construct message in the message queue memory; note that delete should not be called on the return value
-  new (slot) LocalType( &manager, &ResourceManager::HandleReloadResourceRequest, id, typePath, priority );
+  new (slot) LocalType( &manager, &ResourceManager::HandleReloadResourceRequest, id, typePath, priority, resetFinishedStatus );
 }
 
 inline void RequestSaveResourceMessage( EventToUpdate& eventToUpdate,
index 0a1d842320988e2fa7ae5e3b5793ef3e0bf9b644..8be0a89f6ec974f85a2821f4b032ca4cb6f8f2b1 100644 (file)
@@ -194,4 +194,15 @@ Stage::TouchedSignalV2& Stage::TouchedSignal()
   return GetImplementation(*this).TouchedSignal();
 }
 
+
+Stage::ContextStatusSignal& Stage::ContextLostSignal()
+{
+  return GetImplementation(*this).ContextLostSignal();
+}
+
+Stage::ContextStatusSignal& Stage::ContextRegainedSignal()
+{
+  return GetImplementation(*this).ContextRegainedSignal();
+}
+
 } // namespace Dali
index 9884e5df0f1bfb6261e0da7d1ec2689e578e241e..de8add0c4941305a34e1f80b878dfe165e1c4076 100644 (file)
@@ -54,6 +54,7 @@ public:
   typedef SignalV2< void (const KeyEvent&)> KeyEventSignalV2;  ///< Key event signal type
   typedef SignalV2< void () > EventProcessingFinishedSignalV2; ///< Event Processing finished signal type
   typedef SignalV2< void (const TouchEvent&)> TouchedSignalV2; ///< Touched signal type
+  typedef SignalV2< void () > ContextStatusSignal; // Context status signal type
 
   static const Vector4 DEFAULT_BACKGROUND_COLOR; ///< Default black background.
   static const Vector4 DEBUG_BACKGROUND_COLOR;   ///< Green background, useful when debugging.
@@ -62,6 +63,8 @@ public:
   static const char* const SIGNAL_KEY_EVENT; ///< name "key-event"
   static const char* const SIGNAL_EVENT_PROCESSING_FINISHED; ///< name "event-processing-finished"
   static const char* const SIGNAL_TOUCHED; ///< name "touched"
+  static const char* const SIGNAL_CONTEXT_LOST; ///< name "context-lost"
+  static const char* const SIGNAL_CONTEXT_REGAINED; ///< name "context-regained"
 
   /**
    * @brief Allows the creation of an empty stage handle.
@@ -289,6 +292,25 @@ public:
    */
   TouchedSignalV2& TouchedSignal();
 
+  /**
+   * @brief This signal is emitted when the GL context is lost (Platform specific behaviour).
+   *
+   * If the application is responsible for handling context loss, it should listen to
+   * this signal and tear down UI components when recieved.
+   * @return The ContextLost signal to connect to.
+   */
+  ContextStatusSignal& ContextLostSignal();
+
+  /**
+   * @brief This signal is emitted when the GL context is regained (Platform specific
+   * behaviour).
+   *
+   * If the application is responsible for handling context loss, it should listen to
+   * this signal and rebuild UI components on receipt.
+   * @return The ContextRegained signal to connect to.
+   */
+  ContextStatusSignal& ContextRegainedSignal();
+
 public: // Not intended for application developers
 
   /**