/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
damagedRects.clear();
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
TestApplication::DEFAULT_SURFACE_HEIGHT,
- 0, 0);
+ 0,
+ 0);
// Check current orientations
- int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
int32_t screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should not be changed yet.
DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
// Check current orientations
- orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ orientation = application.GetScene().GetCurrentSurfaceOrientation();
screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should be changed.
damagedRects.clear();
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
TestApplication::DEFAULT_SURFACE_HEIGHT,
- 90, 0);
+ 90,
+ 0);
// Check current surface orientation
- int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
int32_t screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should not be changed yet.
DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
// Check current orientations
- orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ orientation = application.GetScene().GetCurrentSurfaceOrientation();
screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should be changed.
damagedRects.clear();
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
TestApplication::DEFAULT_SURFACE_HEIGHT,
- 0, 90);
+ 0,
+ 90);
// Check current surface orientation
- int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
int32_t screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should not be changed yet.
DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
// Check current orientations
- orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ orientation = application.GetScene().GetCurrentSurfaceOrientation();
screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should be changed.
damagedRects.clear();
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
TestApplication::DEFAULT_SURFACE_HEIGHT,
- 90, 90);
+ 90,
+ 90);
// Check current surface orientation
- int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
int32_t screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should not be changed yet.
DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
// Check current orientations
- orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ orientation = application.GetScene().GetCurrentSurfaceOrientation();
screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should be changed.
damagedRects.clear();
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
TestApplication::DEFAULT_SURFACE_HEIGHT,
- 180, 0);
+ 180,
+ 0);
// Check current surface orientation
- int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
int32_t screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should not be changed yet.
DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
// Check current orientations
- orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ orientation = application.GetScene().GetCurrentSurfaceOrientation();
screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should be changed.
damagedRects.clear();
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
TestApplication::DEFAULT_SURFACE_HEIGHT,
- 0, 180);
+ 0,
+ 180);
// Check current surface orientation
- int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
int32_t screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should not be changed yet.
DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
// Check current orientations
- orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ orientation = application.GetScene().GetCurrentSurfaceOrientation();
screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should be changed.
damagedRects.clear();
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
TestApplication::DEFAULT_SURFACE_HEIGHT,
- 180, 180);
+ 180,
+ 180);
// Check current orientations
- int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
int32_t screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should not be changed yet.
DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
// Check current orientations
- orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ orientation = application.GetScene().GetCurrentSurfaceOrientation();
screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should be changed.
damagedRects.clear();
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
TestApplication::DEFAULT_SURFACE_HEIGHT,
- 270, 0);
+ 270,
+ 0);
// Check current surface orientation
- int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
int32_t screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should not be changed yet.
DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
// Check current orientations
- orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ orientation = application.GetScene().GetCurrentSurfaceOrientation();
screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should be changed.
damagedRects.clear();
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
TestApplication::DEFAULT_SURFACE_HEIGHT,
- 0, 270);
+ 0,
+ 270);
// Check current surface orientation
- int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
int32_t screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should not be changed yet.
DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
// Check current orientations
- orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ orientation = application.GetScene().GetCurrentSurfaceOrientation();
screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should be changed.
damagedRects.clear();
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
TestApplication::DEFAULT_SURFACE_HEIGHT,
- 270, 270);
+ 270,
+ 270);
// Check current surface orientation
- int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
int32_t screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should not be changed yet.
DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
// Check current orientations
- orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ orientation = application.GetScene().GetCurrentSurfaceOrientation();
screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should be changed.
damagedRects.clear();
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
TestApplication::DEFAULT_SURFACE_HEIGHT,
- 90, 0);
+ 90,
+ 0);
// Check current surface orientation
- int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
int32_t screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should not be changed yet.
DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
// Check current orientations
- orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ orientation = application.GetScene().GetCurrentSurfaceOrientation();
screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should be changed.
damagedRects.clear();
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
TestApplication::DEFAULT_SURFACE_HEIGHT,
- 0, 90);
+ 0,
+ 90);
// Check current surface orientation
- int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
int32_t screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should not be changed yet.
DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
// Check current orientations
- orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ orientation = application.GetScene().GetCurrentSurfaceOrientation();
screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should be changed.
damagedRects.clear();
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_WIDTH,
TestApplication::DEFAULT_SURFACE_HEIGHT,
- 90, 90);
+ 90,
+ 90);
// Check current surface orientation
- int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ int32_t orientation = application.GetScene().GetCurrentSurfaceOrientation();
int32_t screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should not be changed yet.
DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
// Check current orientations
- orientation = application.GetScene().GetCurrentSurfaceOrientation();
+ orientation = application.GetScene().GetCurrentSurfaceOrientation();
screenOrientation = application.GetScene().GetCurrentScreenOrientation();
// It should be changed.
// Rotate surface
application.GetScene().SurfaceRotated(TestApplication::DEFAULT_SURFACE_HEIGHT,
TestApplication::DEFAULT_SURFACE_WIDTH,
- 90, 0);
+ 90,
+ 0);
damagedRects.clear();
DALI_TEST_EQUALS(scene.GetRootLayer(), defaultTask.GetSourceActor(), TEST_LOCATION);
// Ensure stage size matches the scene size
- auto stage = Stage::GetCurrent();
- Vector2 sceneSize = stage.GetSize();
+ auto stage = Stage::GetCurrent();
+ Vector2 sceneSize = stage.GetSize();
Viewport sceneViewport(0, 0, sceneSize.x, sceneSize.y);
DALI_TEST_EQUALS(stage.GetSize(), scene.GetSize(), TEST_LOCATION);
Viewport defaultViewport = defaultTask.GetViewport();
Layer layer = scene.GetOverlayLayer();
// There should be 2 task by default.
DALI_TEST_EQUALS(tasks.GetTaskCount(), 2u, TEST_LOCATION);
- RenderTask overlayTask = tasks.GetTask(1u);
- Viewport overlayViewport = overlayTask.GetViewport();
+ RenderTask overlayTask = tasks.GetTask(1u);
+ Viewport overlayViewport = overlayTask.GetViewport();
DALI_TEST_EQUALS(defaultViewport, overlayViewport, TEST_LOCATION);
// Resize the scene
END_TEST;
}
+
+int UtcDaliSceneKeepRendering(void)
+{
+ tet_infoline("Test keep rendering");
+
+ TestApplication application;
+
+ auto scene = application.GetScene();
+ DALI_TEST_CHECK(scene);
+
+ Actor actor = CreateRenderableActor();
+ scene.Add(actor);
+
+ // Run core until it wants to sleep
+ bool keepUpdating(true);
+ while(keepUpdating)
+ {
+ application.SendNotification();
+ keepUpdating = application.Render(1000.0f /*1 second*/);
+ }
+
+ // Force rendering for the next 5 seconds
+ scene.KeepRendering(5.0f);
+
+ application.SendNotification();
+
+ keepUpdating = application.Render(1000.0f /*1 second*/);
+ DALI_TEST_CHECK(keepUpdating);
+ keepUpdating = application.Render(1000.0f /*2 seconds*/);
+ DALI_TEST_CHECK(keepUpdating);
+ keepUpdating = application.Render(1000.0f /*3 seconds*/);
+ DALI_TEST_CHECK(keepUpdating);
+ keepUpdating = application.Render(1000.0f /*4 seconds*/);
+ DALI_TEST_CHECK(keepUpdating);
+ keepUpdating = application.Render(1000.0f /*5 seconds*/);
+ DALI_TEST_CHECK(keepUpdating);
+ keepUpdating = application.Render(1000.0f /*6 seconds*/); // After 5 sec
+ DALI_TEST_CHECK(!keepUpdating);
+
+ END_TEST;
+}
+
+int UtcDaliSceneKeepRenderingMultipleScene(void)
+{
+ tet_infoline("Test keep rendering - multiple scene");
+
+ TestApplication application(
+ TestApplication::DEFAULT_SURFACE_WIDTH,
+ TestApplication::DEFAULT_SURFACE_HEIGHT,
+ TestApplication::DEFAULT_HORIZONTAL_DPI,
+ TestApplication::DEFAULT_VERTICAL_DPI,
+ true,
+ true);
+ TraceCallStack& drawTrace = application.GetGlAbstraction().GetDrawTrace();
+
+ auto defaultScene = application.GetScene();
+ DALI_TEST_CHECK(defaultScene);
+
+ Actor actor1 = CreateRenderableActor();
+ actor1.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+ actor1.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+ defaultScene.Add(actor1);
+
+ // Create a Scene
+ Dali::Integration::Scene scene = Dali::Integration::Scene::New(Size(480.0f, 800.0f));
+ DALI_TEST_CHECK(scene);
+
+ application.AddScene(scene);
+
+ Actor actor2 = CreateRenderableActor();
+ actor2.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+ actor2.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
+ scene.Add(actor2);
+
+ // Run core until it wants to sleep
+ bool keepUpdating(true);
+ while(keepUpdating)
+ {
+ application.SendNotification();
+ keepUpdating = application.RenderWithPartialUpdate(1000.0f /*1 second*/);
+ }
+
+ drawTrace.Enable(true);
+
+ // Force rendering of the default scene for the next 5 seconds (0sec ~ 5sec)
+ defaultScene.KeepRendering(5.0f);
+
+ application.SendNotification();
+ keepUpdating = application.RenderWithPartialUpdate(1000.0f /*1 second*/);
+
+ DALI_TEST_CHECK(keepUpdating);
+ DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION); // Only default scene should be drawn
+
+ drawTrace.Reset();
+
+ // Force rendering of the new scene for the next 5 seconds (1sec ~ 6sec)
+ scene.KeepRendering(5.0f);
+
+ application.SendNotification();
+ keepUpdating = application.RenderWithPartialUpdate(3000.0f /*4 second*/);
+
+ DALI_TEST_CHECK(keepUpdating);
+ DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 2, TEST_LOCATION); // Both scenes should be drawn
+
+ drawTrace.Reset();
+
+ keepUpdating = application.RenderWithPartialUpdate(1000.0f /*5 second*/);
+
+ DALI_TEST_CHECK(keepUpdating);
+ DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 2, TEST_LOCATION); // Still both scenes should be drawn
+
+ drawTrace.Reset();
+
+ keepUpdating = application.RenderWithPartialUpdate(1000.0f /*6 second*/);
+
+ DALI_TEST_CHECK(keepUpdating);
+ DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 1, TEST_LOCATION); // Only the new scenes should be drawn
+
+ drawTrace.Reset();
+
+ keepUpdating = application.RenderWithPartialUpdate(1000.0f /*7 second*/);
+
+ DALI_TEST_CHECK(!keepUpdating);
+ DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 0, TEST_LOCATION); // Nothing drawn
+
+ END_TEST;
+}
panGestureProcessor(nullptr),
messageQueue(renderController, sceneGraphBuffers),
frameCallbackProcessor(nullptr),
- keepRenderingSeconds(0.0f),
nodeDirtyFlags(NodePropertyFlags::TRANSFORM), // set to TransformFlag to ensure full update the first time through Update()
frameCounter(0),
renderingBehavior(DevelStage::Rendering::IF_REQUIRED),
OwnerPointer<FrameCallbackProcessor> frameCallbackProcessor; ///< Owned FrameCallbackProcessor, only created if required.
std::atomic<std::size_t> renderInstructionCapacity{0u};
- float keepRenderingSeconds; ///< Set via Dali::Stage::KeepRendering
- NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
- uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
- DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior
+ NodePropertyFlags nodeDirtyFlags; ///< cumulative node dirty flags from previous frame
+ uint32_t frameCounter; ///< Frame counter used in debugging to choose which frame to debug and which to ignore.
+ DevelStage::Rendering renderingBehavior; ///< Set via DevelStage::SetRenderingBehavior
bool animationFinishedDuringUpdate; ///< Flag whether any animations finished during the Update()
bool previousUpdateScene; ///< True if the scene was updated in the previous frame (otherwise it was optimized out)
mImpl->frameCallbackProcessor || // ..a frame callback processor is existed OR
gestureUpdated; // ..a gesture property was updated
- bool keepRendererRendering = false;
- mImpl->renderingRequired = false;
+ uint32_t keepUpdating = 0;
+ bool keepRendererRendering = false;
+ mImpl->renderingRequired = false;
// Although the scene-graph may not require an update, we still need to synchronize double-buffered
// values if the scene was updated in the previous frame.
scene->scene->GetRenderInstructions().ResetAndReserve(bufferIndex,
static_cast<uint32_t>(scene->taskList->GetTasks().Count()));
+ bool sceneKeepUpdating = scene->scene->KeepRenderingCheck(elapsedSeconds);
+ if(sceneKeepUpdating)
+ {
+ keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
+ }
+
// If there are animations running, only add render instruction if at least one animation is currently active (i.e. not delayed)
// or the nodes are dirty
- if(!isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags))
+ // or keep rendering is requested
+ if(!isAnimationRunning || animationActive || mImpl->renderingRequired || (mImpl->nodeDirtyFlags & RenderableUpdateFlags) || sceneKeepUpdating)
{
keepRendererRendering |= mImpl->renderTaskProcessor.Process(bufferIndex,
*scene->taskList,
mImpl->previousUpdateScene = updateScene;
// Check whether further updates are required
- uint32_t keepUpdating = KeepUpdatingCheck(elapsedSeconds);
+ keepUpdating |= KeepUpdatingCheck(elapsedSeconds);
if(keepRendererRendering)
{
keepUpdating |= KeepUpdating::STAGE_KEEP_RENDERING;
+ }
+ if(keepUpdating & KeepUpdating::STAGE_KEEP_RENDERING)
+ {
// Set dirty flags for next frame to continue rendering
mImpl->nodeDirtyFlags |= RenderableUpdateFlags;
}
uint32_t UpdateManager::KeepUpdatingCheck(float elapsedSeconds) const
{
- // Update the duration set via Stage::KeepRendering()
- if(mImpl->keepRenderingSeconds > 0.0f)
- {
- mImpl->keepRenderingSeconds -= elapsedSeconds;
- }
-
uint32_t keepUpdatingRequest = KeepUpdating::NOT_REQUESTED;
// If the rendering behavior is set to continuously render, then continue to render.
- // If Stage::KeepRendering() has been called, then continue until the duration has elapsed.
// Keep updating until no messages are received and no animations are running.
// If an animation has just finished, update at least once more for Discard end-actions.
// No need to check for renderQueue as there is always a render after update and if that
// render needs another update it will tell the adaptor to call update again
- if((mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY) ||
- (mImpl->keepRenderingSeconds > 0.0f))
+ if(mImpl->renderingBehavior == DevelStage::Rendering::CONTINUOUSLY)
{
keepUpdatingRequest |= KeepUpdating::STAGE_KEEP_RENDERING;
}
void UpdateManager::KeepRendering(float durationSeconds)
{
- mImpl->keepRenderingSeconds = std::max(mImpl->keepRenderingSeconds, durationSeconds);
+ for(auto&& scene : mImpl->scenes)
+ {
+ scene->scene->KeepRendering(durationSeconds);
+ }
}
void UpdateManager::SetRenderingBehavior(DevelStage::Rendering renderingBehavior)