damagedRects.clear();
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
damagedRects.clear();
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
// 2. Set new color
actor.SetProperty(Actor::Property::COLOR, Vector3(1.0f, 0.0f, 0.0f));
END_TEST;
}
-int utcDaliActorPartialUpdateActorsWithSizeHint(void)
+int utcDaliActorPartialUpdateActorsWithSizeHint01(void)
{
TestApplication application(
TestApplication::DEFAULT_SURFACE_WIDTH,
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
- damagedRects.clear();
- application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
- application.RenderWithPartialUpdate(damagedRects, clippingRect);
-
// Ensure the damaged rect is empty
DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+ // Chnage UPDATE_AREA_HINT
+ actor.SetProperty(Actor::Property::UPDATE_AREA_HINT, Vector4(-32.0f, -16.0f, 64.0f, 64.0f));
+ application.GetScene().Add(actor);
+
+ application.SendNotification();
+ application.PreRenderWithPartialUpdate(TestApplication::DEFAULT_RENDER_INTERVAL, nullptr, damagedRects);
+
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+ clippingRect = Rect<int>(0, 720, 80, 80);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int utcDaliActorPartialUpdateActorsWithSizeHint02(void)
+{
+ TestApplication application(
+ TestApplication::DEFAULT_SURFACE_WIDTH,
+ TestApplication::DEFAULT_SURFACE_HEIGHT,
+ TestApplication::DEFAULT_HORIZONTAL_DPI,
+ TestApplication::DEFAULT_VERTICAL_DPI,
+ true,
+ true);
+
+ tet_infoline("Check the damaged rect with partial update and actor size hint");
+
+ const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+ Actor actor = CreateRenderableActor();
+ actor.SetProperty(Actor::Property::POSITION, Vector3(64.0f, 64.0f, 0.0f));
+ actor.SetProperty(Actor::Property::SIZE, Vector3(32.0f, 32.0f, 0.0f));
+ actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(actor);
+
+ application.SendNotification();
+ std::vector<Rect<int>> damagedRects;
+ application.PreRenderWithPartialUpdate(TestApplication::DEFAULT_RENDER_INTERVAL, nullptr, damagedRects);
+
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+ Rect<int> clippingRect = Rect<int>(48, 720, 48, 48);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
damagedRects.clear();
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
// Chnage UPDATE_AREA_HINT
- actor.SetProperty(Actor::Property::UPDATE_AREA_HINT, Vector4(-32.0f, -16.0f, 64.0f, 64.0f));
+ actor.SetProperty(Actor::Property::UPDATE_AREA_HINT, Vector4(0.0f, 0.0f, 64.0f, 64.0f));
+
+ application.SendNotification();
+ application.PreRenderWithPartialUpdate(TestApplication::DEFAULT_RENDER_INTERVAL, nullptr, damagedRects);
+
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+ clippingRect = Rect<int>(32, 704, 80, 80);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+ // Chnage UPDATE_AREA_HINT
+ actor.SetProperty(Actor::Property::UPDATE_AREA_HINT, Vector4(16.0f, 16.0f, 64.0f, 64.0f));
application.GetScene().Add(actor);
application.SendNotification();
DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
- clippingRect = Rect<int>(0, 720, 80, 80);
+ clippingRect = Rect<int>(32, 688, 96, 96);
DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
clippingRect = TestApplication::DEFAULT_SURFACE_RECT;
application.RenderWithPartialUpdate(damagedRects, clippingRect);
- damagedRects.clear();
- clippingRect = TestApplication::DEFAULT_SURFACE_RECT;
- application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
- application.RenderWithPartialUpdate(damagedRects, clippingRect);
-
// Make an animation
Animation animation = Animation::New(1.0f);
animation.AnimateTo(Property(actor2, Actor::Property::POSITION_X), 160.0f, TimePeriod(0.5f, 0.5f));
damagedRects.clear();
application.PreRenderWithPartialUpdate(500, nullptr, damagedRects);
- DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
- DALI_TEST_EQUALS<Rect<int>>(expectedRect2, damagedRects[0], TEST_LOCATION);
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
clippingRect = TestApplication::DEFAULT_SURFACE_RECT;
application.RenderWithPartialUpdate(damagedRects, clippingRect);
DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
// Aligned by 16
- Rect<int> clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates, includes 3 last frames updates
+ Rect<int> clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates
DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
- damagedRects.clear();
- application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
- application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
// Make the actor transparent by changing opacity of the Renderer
// It changes a uniform value
// The damaged rect should be same
damagedRects.clear();
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
- application.RenderWithPartialUpdate(damagedRects, clippingRect);
- DALI_TEST_CHECK(damagedRects.size() > 0);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
damagedRects.clear();
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
// The damaged rect should not be empty
damagedRects.clear();
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
- application.RenderWithPartialUpdate(damagedRects, clippingRect);
DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
-
- damagedRects.clear();
- application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
damagedRects.clear();
// The damaged rect should not be empty
damagedRects.clear();
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
- application.RenderWithPartialUpdate(damagedRects, clippingRect);
DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
-
- damagedRects.clear();
- application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
damagedRects.clear();
// The damaged rect should not be empty
damagedRects.clear();
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
- application.RenderWithPartialUpdate(damagedRects, clippingRect);
DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
-
- damagedRects.clear();
- application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
damagedRects.clear();
// The damaged rect should be same
damagedRects.clear();
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
- application.RenderWithPartialUpdate(damagedRects, clippingRect);
DALI_TEST_CHECK(damagedRects.size() > 0);
DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
damagedRects.clear();
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
// The damaged rect should not be empty
damagedRects.clear();
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
- application.RenderWithPartialUpdate(damagedRects, clippingRect);
DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
END_TEST;
}
END_TEST;
}
+int utcDaliActorPartialUpdateOneActorMultipleRenderers(void)
+{
+ TestApplication application(
+ TestApplication::DEFAULT_SURFACE_WIDTH,
+ TestApplication::DEFAULT_SURFACE_HEIGHT,
+ TestApplication::DEFAULT_HORIZONTAL_DPI,
+ TestApplication::DEFAULT_VERTICAL_DPI,
+ true,
+ true);
+
+ tet_infoline("Check the damaged rect with one actor which has multiple renderers");
+
+ const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+ Actor actor = CreateRenderableActor();
+
+ // Create another renderer
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = CreateShader();
+ Renderer renderer2 = Renderer::New(geometry, shader);
+ actor.AddRenderer(renderer2);
+
+ actor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT;
+ actor[Actor::Property::POSITION] = Vector3(16.0f, 16.0f, 0.0f);
+ actor[Actor::Property::SIZE] = Vector3(16.0f, 16.0f, 0.0f);
+ actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(actor);
+
+ application.SendNotification();
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 2u, TEST_LOCATION);
+
+ std::vector<Rect<int>> damagedRects;
+
+ // Actor added, damaged rect is added size of actor
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ DALI_TEST_EQUALS(damagedRects.size(), 2, TEST_LOCATION);
+
+ // Aligned by 16
+ Rect<int> clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[1], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+ // Make renderer2 dirty
+ renderer2[DevelRenderer::Property::OPACITY] = 0.5f;
+
+ application.SendNotification();
+
+ // The damaged rect should be the actor area
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+ clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+ // Make renderer2 dirty
+ renderer2[Renderer::Property::FACE_CULLING_MODE] = FaceCullingMode::BACK;
+
+ application.SendNotification();
+
+ // The damaged rect should be the actor area
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+ clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int utcDaliActorPartialUpdateMultipleActorsOneRenderer(void)
+{
+ TestApplication application(
+ TestApplication::DEFAULT_SURFACE_WIDTH,
+ TestApplication::DEFAULT_SURFACE_HEIGHT,
+ TestApplication::DEFAULT_HORIZONTAL_DPI,
+ TestApplication::DEFAULT_VERTICAL_DPI,
+ true,
+ true);
+
+ tet_infoline("Check the damaged rect with multiple actors which share a same renderer");
+
+ const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+ Actor actor = CreateRenderableActor();
+ actor[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT;
+ actor[Actor::Property::POSITION] = Vector3(16.0f, 16.0f, 0.0f);
+ actor[Actor::Property::SIZE] = Vector3(16.0f, 16.0f, 0.0f);
+ actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(actor);
+
+ // Create another actor which has the same renderer with actor1
+ Actor actor2 = Actor::New();
+ Renderer renderer = actor.GetRendererAt(0);
+ actor2.AddRenderer(renderer);
+ actor2[Actor::Property::ANCHOR_POINT] = AnchorPoint::TOP_LEFT;
+ actor2[Actor::Property::POSITION] = Vector3(16.0f, 16.0f, 0.0f);
+ actor2[Actor::Property::SIZE] = Vector3(16.0f, 16.0f, 0.0f);
+ actor2.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(actor2);
+
+ application.SendNotification();
+
+ std::vector<Rect<int>> damagedRects;
+
+ // Actor added, damaged rect is added size of actor
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ DALI_TEST_EQUALS(damagedRects.size(), 2, TEST_LOCATION);
+
+ // Aligned by 16
+ Rect<int> clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[1], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+ // Make renderer dirty
+ renderer[DevelRenderer::Property::OPACITY] = 0.5f;
+
+ application.SendNotification();
+
+ // The damaged rect should be the actor area
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+ clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates
+ DALI_TEST_EQUALS(damagedRects.size(), 2, TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[1], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliActorCaptureAllTouchAfterStartPropertyP(void)
{
TestApplication application;
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
- damagedRects.clear();
- application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
- application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
// Set clippingRect as full surface now. TODO : Set valid rect if we can.
clippingRect = TestApplication::DEFAULT_SURFACE_RECT;
DALI_TEST_EQUALS(renderer.GetProperty<float>(index), -1.0f, TEST_LOCATION);
END_TEST;
-}
\ No newline at end of file
+}
END_TEST;
}
+
+int utcDaliRendererPartialUpdateChangeUniform(void)
+{
+ TestApplication application(
+ TestApplication::DEFAULT_SURFACE_WIDTH,
+ TestApplication::DEFAULT_SURFACE_HEIGHT,
+ TestApplication::DEFAULT_HORIZONTAL_DPI,
+ TestApplication::DEFAULT_VERTICAL_DPI,
+ true,
+ true);
+
+ tet_infoline("Check the damaged rect with changing uniform");
+
+ const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+ std::vector<Rect<int>> damagedRects;
+ Rect<int> clippingRect;
+ application.SendNotification();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+ // First render pass, nothing to render, adaptor would just do swap buffer.
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ Shader shader = Shader::New("VertexSource", "FragmentSource");
+ Geometry geometry = CreateQuadGeometry();
+ Renderer renderer = Renderer::New(geometry, shader);
+
+ Property::Index colorIndex = renderer.RegisterProperty("uFadeColor", Color::WHITE);
+
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+ actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+ actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+ actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+ Stage::GetCurrent().Add(actor);
+
+ application.SendNotification();
+
+ // 1. Actor added, damaged rect is added size of actor
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+ // Aligned by 16
+ clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+ // 2. Change the uniform value
+ renderer.SetProperty(colorIndex, Color::RED);
+ application.SendNotification();
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+ // Aligned by 16
+ clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // 3. Change the uniform value and another property together
+ actor.SetProperty(Actor::Property::COLOR, Color::YELLOW);
+ renderer.SetProperty(colorIndex, Color::BLUE);
+ application.SendNotification();
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+ // Aligned by 16
+ clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // 4. Change the uniform value only
+ renderer.SetProperty(colorIndex, Color::RED); // Set the previous value (#2)
+ application.SendNotification();
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+ // Aligned by 16
+ clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int utcDaliRendererPartialUpdateAddRemoveRenderer(void)
+{
+ TestApplication application(
+ TestApplication::DEFAULT_SURFACE_WIDTH,
+ TestApplication::DEFAULT_SURFACE_HEIGHT,
+ TestApplication::DEFAULT_HORIZONTAL_DPI,
+ TestApplication::DEFAULT_VERTICAL_DPI,
+ true,
+ true);
+
+ tet_infoline("Check the damaged rect with adding / removing renderer");
+
+ const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+ Shader shader = Shader::New("VertexSource", "FragmentSource");
+ Geometry geometry = CreateQuadGeometry();
+ Renderer renderer = Renderer::New(geometry, shader);
+
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+ actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+ actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+ actor.SetResizePolicy(ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS);
+ Stage::GetCurrent().Add(actor);
+
+ application.SendNotification();
+
+ std::vector<Rect<int>> damagedRects;
+ Rect<int> clippingRect;
+
+ // 1. Actor added, damaged rect is added size of actor
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+ // Aligned by 16
+ clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ // 2. Remove renderer
+ actor.RemoveRenderer(renderer);
+ application.SendNotification();
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // 3. Change a property value of the Renderer
+ renderer.SetProperty(DevelRenderer::Property::OPACITY, 0.5f);
+ application.SendNotification();
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // 4. Add renderer again
+ actor.AddRenderer(renderer);
+ application.SendNotification();
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // 5. Remove renderer agin
+ actor.RemoveRenderer(renderer);
+ application.SendNotification();
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+ DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ END_TEST;
+}
END_TEST;
}
+
+int utcDaliTexturePartialUpdate01(void)
+{
+ TestApplication application(
+ TestApplication::DEFAULT_SURFACE_WIDTH,
+ TestApplication::DEFAULT_SURFACE_HEIGHT,
+ TestApplication::DEFAULT_HORIZONTAL_DPI,
+ TestApplication::DEFAULT_VERTICAL_DPI,
+ true,
+ true);
+
+ tet_infoline("Check the damaged rect with partial update and texture change");
+
+ const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+ std::vector<Rect<int32_t>> damagedRects;
+ Rect<int32_t> clippingRect;
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = Shader::New("vertexSrc", "fragmentSrc");
+ Renderer renderer = Renderer::New(geometry, shader);
+
+ uint32_t width(4);
+ uint32_t height(4);
+ Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+ TextureSet textureSet = TextureSet::New();
+ textureSet.SetTexture(0u, texture);
+ renderer.SetTextures(textureSet);
+
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+
+ actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+ actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+ application.GetScene().Add(actor);
+
+ damagedRects.clear();
+ application.SendNotification();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+ // Aligned by 16
+ clippingRect = Rect<int32_t>(16, 768, 32, 32); // in screen coordinates
+ DALI_TEST_EQUALS<Rect<int32_t>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+ // Upload texture
+ uint32_t bufferSize(width * height * 4);
+ uint8_t* buffer = reinterpret_cast<unsigned char*>(malloc(bufferSize));
+ PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE);
+ texture.Upload(pixelData);
+
+ damagedRects.clear();
+ application.SendNotification();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+ // Aligned by 16
+ clippingRect = Rect<int32_t>(16, 768, 32, 32); // in screen coordinates
+ DALI_TEST_EQUALS<Rect<int32_t>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int utcDaliTexturePartialUpdate02(void)
+{
+ TestApplication application(
+ TestApplication::DEFAULT_SURFACE_WIDTH,
+ TestApplication::DEFAULT_SURFACE_HEIGHT,
+ TestApplication::DEFAULT_HORIZONTAL_DPI,
+ TestApplication::DEFAULT_VERTICAL_DPI,
+ true,
+ true);
+
+ tet_infoline("Check the damaged rect with partial update and texture change");
+
+ const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+ std::vector<Rect<int32_t>> damagedRects;
+ Rect<int32_t> clippingRect;
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = Shader::New("vertexSrc", "fragmentSrc");
+ Renderer renderer = Renderer::New(geometry, shader);
+
+ uint32_t width(4);
+ uint32_t height(4);
+ Texture texture1 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+ Texture texture2 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+ TextureSet textureSet = TextureSet::New();
+ textureSet.SetTexture(0u, texture1);
+ renderer.SetTextures(textureSet);
+
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+
+ actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+ actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+ application.GetScene().Add(actor);
+
+ damagedRects.clear();
+ application.SendNotification();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+ // Aligned by 16
+ clippingRect = Rect<int32_t>(16, 768, 32, 32); // in screen coordinates, includes 3 last frames updates
+ DALI_TEST_EQUALS<Rect<int32_t>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+ // Set another texture
+ textureSet.SetTexture(0u, texture2);
+
+ damagedRects.clear();
+ application.SendNotification();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+ // Aligned by 16
+ clippingRect = Rect<int32_t>(16, 768, 32, 32); // in screen coordinates, includes 3 last frames updates
+ DALI_TEST_EQUALS<Rect<int32_t>>(clippingRect, damagedRects[0], TEST_LOCATION);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+ DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+ damagedRects.clear();
+ application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+ application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+ END_TEST;
+}
DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
// Aligned by 16
- Rect<int> clippingRect = Rect<int>(64, 672, 80, 80); // in screen coordinates, includes 3 last frames updates
+ Rect<int> clippingRect = Rect<int>(64, 672, 80, 80); // in screen coordinates
DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
application.RenderWithPartialUpdate(damagedRects, clippingRect);
- damagedRects.clear();
- application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
- application.RenderWithPartialUpdate(damagedRects, clippingRect);
+ // Ensure the damaged rect is empty
+ DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
// Set clippingRect as full surface now. TODO : Set valid rect if we can.
clippingRect = TestApplication::DEFAULT_SURFACE_RECT;
DALI_TEST_EQUALS(renderer.GetProperty<Vector2>(index), Vector2(0.5f, 2.0f), TEST_LOCATION);
END_TEST;
-}
\ No newline at end of file
+}
void Core::PostRender()
{
+ mUpdateManager->PostRender();
mRenderManager->PostRender();
}
bool skip = true;
if(!rootClippingRect.IsEmpty())
{
- auto rect = RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, Vector3(item.mUpdateArea.x, item.mUpdateArea.y, 0.0f), Vector3(item.mUpdateArea.z, item.mUpdateArea.w, 0.0f), mViewportRectangle.width, mViewportRectangle.height);
+ Vector4 updateArea = item.mRenderer ? item.mRenderer->GetVisualTransformedUpdateArea(bufferIndex, item.mUpdateArea) : item.mUpdateArea;
+ auto rect = RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, Vector3(updateArea.x, updateArea.y, 0.0f), Vector3(updateArea.z, updateArea.w, 0.0f), mViewportRectangle.width, mViewportRectangle.height);
if(rect.Intersect(rootClippingRect))
{
// If the item refers to updated node or renderer.
if(item.mIsUpdated ||
(item.mNode &&
- (item.mNode->Updated() || (item.mRenderer && item.mRenderer->Updated(mImpl->renderBufferIndex, item.mNode)))))
+ (item.mNode->Updated() || (item.mRenderer && item.mRenderer->Updated(mImpl->renderBufferIndex)))))
{
item.mIsUpdated = false;
- rect = RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, Vector3(item.mUpdateArea.x, item.mUpdateArea.y, 0.0f), Vector3(item.mUpdateArea.z, item.mUpdateArea.w, 0.0f), viewportRect.width, viewportRect.height);
+ Vector4 updateArea = item.mRenderer ? item.mRenderer->GetVisualTransformedUpdateArea(mImpl->renderBufferIndex, item.mUpdateArea) : item.mUpdateArea;
+
+ rect = RenderItem::CalculateViewportSpaceAABB(item.mModelViewMatrix, Vector3(updateArea.x, updateArea.y, 0.0f), Vector3(updateArea.z, updateArea.w, 0.0f), viewportRect.width, viewportRect.height);
if(rect.IsValid() && rect.Intersect(viewportRect) && !rect.IsEmpty())
{
const int left = rect.x;
{
damagedRectCleaner.SetCleanOnReturn(false);
}
-
- // Reset updated flag from the root
- Layer* root = sceneObject->GetRoot();
- if(root)
- {
- root->SetUpdatedTree(false);
- }
}
void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::Scene& scene, bool renderToFbo)
iter->OnRenderFinished();
}
+ // Notify RenderTexture that rendering has finished
+ for(auto&& iter : mImpl->textureContainer)
+ {
+ iter->OnRenderFinished();
+ }
+
mImpl->UpdateTrackers();
uint32_t count = 0u;
#define DALI_INTERNAL_SCENE_GRAPH_RENDER_DATA_PROVIDER_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
/**
* Get the opacity
+ * @param[in] bufferIndex The current buffer index.
* @return The opacity
*/
virtual float GetOpacity(BufferIndex bufferIndex) const = 0;
+
+ /**
+ * @brief Retrieve if the render data is updated
+ * @return An updated flag
+ */
+ virtual bool IsUpdated() const = 0;
+
+ /**
+ * @brief Get the update area after visual properties applied.
+ * @param[in] bufferIndex The current buffer index.
+ * @param[in] originalUpdateArea The original update area before apply the visual properties.
+ * @return The recalculated size after visual properties applied.
+ */
+ virtual Vector4 GetVisualTransformedUpdateArea(BufferIndex bufferIndex, const Vector4& originalUpdateArea) noexcept = 0;
};
} // namespace SceneGraph
mDepthWriteMode(depthWriteMode),
mDepthTestMode(depthTestMode),
mPremultipliedAlphaEnabled(preMultipliedAlphaEnabled),
- mShaderChanged(false),
- mUpdated(true)
+ mShaderChanged(false)
{
if(blendingBitmask != 0u)
{
void Renderer::SetGeometry(Render::Geometry* geometry)
{
mGeometry = geometry;
- mUpdated = true;
}
void Renderer::SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size)
{
void Renderer::SetFaceCullingMode(FaceCullingMode::Type mode)
{
mFaceCullingMode = mode;
- mUpdated = true;
}
void Renderer::SetBlendingBitMask(uint32_t bitmask)
{
mBlendingOptions.SetBitmask(bitmask);
- mUpdated = true;
}
void Renderer::SetBlendColor(const Vector4& color)
{
mBlendingOptions.SetBlendColor(color);
- mUpdated = true;
}
void Renderer::SetIndexedDrawFirstElement(uint32_t firstElement)
{
mIndexedDrawFirstElement = firstElement;
- mUpdated = true;
}
void Renderer::SetIndexedDrawElementsCount(uint32_t elementsCount)
{
mIndexedDrawElementsCount = elementsCount;
- mUpdated = true;
}
void Renderer::EnablePreMultipliedAlpha(bool enable)
{
mPremultipliedAlphaEnabled = enable;
- mUpdated = true;
}
void Renderer::SetDepthWriteMode(DepthWriteMode::Type depthWriteMode)
{
mDepthWriteMode = depthWriteMode;
- mUpdated = true;
}
void Renderer::SetDepthTestMode(DepthTestMode::Type depthTestMode)
{
mDepthTestMode = depthTestMode;
- mUpdated = true;
}
DepthWriteMode::Type Renderer::GetDepthWriteMode() const
void Renderer::SetDepthFunction(DepthFunction::Type depthFunction)
{
mDepthFunction = depthFunction;
- mUpdated = true;
}
DepthFunction::Type Renderer::GetDepthFunction() const
void Renderer::SetRenderMode(RenderMode::Type renderMode)
{
mStencilParameters.renderMode = renderMode;
- mUpdated = true;
}
RenderMode::Type Renderer::GetRenderMode() const
void Renderer::SetStencilFunction(StencilFunction::Type stencilFunction)
{
mStencilParameters.stencilFunction = stencilFunction;
- mUpdated = true;
}
StencilFunction::Type Renderer::GetStencilFunction() const
void Renderer::SetStencilFunctionMask(int stencilFunctionMask)
{
mStencilParameters.stencilFunctionMask = stencilFunctionMask;
- mUpdated = true;
}
int Renderer::GetStencilFunctionMask() const
void Renderer::SetStencilFunctionReference(int stencilFunctionReference)
{
mStencilParameters.stencilFunctionReference = stencilFunctionReference;
- mUpdated = true;
}
int Renderer::GetStencilFunctionReference() const
void Renderer::SetStencilMask(int stencilMask)
{
mStencilParameters.stencilMask = stencilMask;
- mUpdated = true;
}
int Renderer::GetStencilMask() const
void Renderer::SetStencilOperationOnFail(StencilOperation::Type stencilOperationOnFail)
{
mStencilParameters.stencilOperationOnFail = stencilOperationOnFail;
- mUpdated = true;
}
StencilOperation::Type Renderer::GetStencilOperationOnFail() const
void Renderer::SetStencilOperationOnZFail(StencilOperation::Type stencilOperationOnZFail)
{
mStencilParameters.stencilOperationOnZFail = stencilOperationOnZFail;
- mUpdated = true;
}
StencilOperation::Type Renderer::GetStencilOperationOnZFail() const
void Renderer::SetStencilOperationOnZPass(StencilOperation::Type stencilOperationOnZPass)
{
mStencilParameters.stencilOperationOnZPass = stencilOperationOnZPass;
- mUpdated = true;
}
StencilOperation::Type Renderer::GetStencilOperationOnZPass() const
}
}
- mUpdated = false;
return drawn;
}
mShaderChanged = value;
}
-bool Renderer::Updated(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider* node)
+bool Renderer::Updated(BufferIndex bufferIndex)
{
- if(mUpdated)
- {
- mUpdated = false;
- return true;
- }
-
- if(mRenderCallback || mShaderChanged || mGeometry->AttributesChanged())
+ if(mRenderCallback || mShaderChanged || mGeometry->AttributesChanged() || mRenderDataProvider->IsUpdated())
{
return true;
}
for(auto iter = textures->Begin(), end = textures->End(); iter < end; ++iter)
{
auto texture = *iter;
- if(texture && texture->IsNativeImage())
+ if(texture && texture->Updated())
{
return true;
}
}
}
-
- // Hash the property values. If the values are different, then rendering is required.
- uint64_t hash = 0xc70f6907UL;
- const SceneGraph::UniformMap& uniformMapNode = node->GetNodeUniformMap();
- for(uint32_t i = 0u, count = uniformMapNode.Count(); i < count; ++i)
- {
- hash = uniformMapNode[i].propertyPtr->Hash(bufferIndex, hash);
- }
-
- const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = mRenderDataProvider->GetUniformMapDataProvider();
- const SceneGraph::CollectedUniformMap& collectedUniformMap = uniformMapDataProvider.GetCollectedUniformMap();
- for(uint32_t i = 0u, count = collectedUniformMap.Count(); i < count; ++i)
- {
- hash = collectedUniformMap.mUniformMap[i].propertyPtr->Hash(bufferIndex, hash);
- }
-
- if(mUniformsHash != hash)
- {
- mUniformsHash = hash;
- return true;
- }
-
return false;
}
+Vector4 Renderer::GetVisualTransformedUpdateArea(BufferIndex bufferIndex, const Vector4& originalUpdateArea) const noexcept
+{
+ return mRenderDataProvider->GetVisualTransformedUpdateArea(bufferIndex, originalUpdateArea);
+}
+
Graphics::Pipeline& Renderer::PrepareGraphicsPipeline(
Program& program,
const Dali::Internal::SceneGraph::RenderInstruction& instruction,
const SceneGraph::NodeDataProvider& node,
bool blend)
{
- if(mGeometry->AttributesChanged())
- {
- mUpdated = true;
- }
-
// Prepare query info
PipelineCacheQueryInfo queryInfo{};
queryInfo.program = &program;
* Check if the renderer attributes/uniforms are updated and returns the flag
*
* @param[in] bufferIndex The current update buffer index.
- * @param[in] node The node using this renderer
*/
- bool Updated(BufferIndex bufferIndex, const SceneGraph::NodeDataProvider* node);
+ bool Updated(BufferIndex bufferIndex);
template<class T>
bool WriteDefaultUniform(const Graphics::UniformInfo* uniformInfo,
return mFaceCullingMode;
}
+ /**
+ * @brief Gets update area after visual properties applied.
+ *
+ * @param[in] bufferIndex The index of the previous update buffer.
+ * @param[in] originalUpdateArea The original update area before apply the visual properties.
+ *
+ * @return The recalculated update area after visual properties applied.
+ */
+ Vector4 GetVisualTransformedUpdateArea(BufferIndex bufferIndex, const Vector4& originalUpdateArea) const noexcept;
+
private:
struct UniformIndexMap;
using UniformIndexMappings = std::vector<UniformIndexMap>;
std::vector<UniformIndexMappings> mUniformIndexMaps; ///< Cached map per node/renderer/shader.
- uint64_t mUniformsHash{0}; ///< Hash of uniform map property values
-
DepthFunction::Type mDepthFunction : 4; ///< The depth function
FaceCullingMode::Type mFaceCullingMode : 3; ///< The mode of face culling
DepthWriteMode::Type mDepthWriteMode : 3; ///< The depth write mode
DepthTestMode::Type mDepthTestMode : 3; ///< The depth test mode
bool mPremultipliedAlphaEnabled : 1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
bool mShaderChanged : 1; ///< Flag indicating the shader changed and uniform maps have to be updated
- bool mUpdated : 1;
std::vector<Dali::DevelRenderer::DrawCommand> mDrawCommands; // Devel stuff
RenderCallback* mRenderCallback{nullptr};
mWidth(size.GetWidth()),
mHeight(size.GetHeight()),
mType(type),
- mHasAlpha(HasAlpha(format))
+ mHasAlpha(HasAlpha(format)),
+ mUpdated(true)
{
}
mWidth(static_cast<uint16_t>(nativeImageInterface->GetWidth())), // ignoring overflow, not happening in practice
mHeight(static_cast<uint16_t>(nativeImageInterface->GetHeight())), // ignoring overflow, not happening in practice
mType(TextureType::TEXTURE_2D),
- mHasAlpha(nativeImageInterface->RequiresBlending())
+ mHasAlpha(nativeImageInterface->RequiresBlending()),
+ mUpdated(true)
{
}
updateSourceInfo.memorySource.memory = pixelData->GetBuffer();
mGraphicsController->UpdateTextures({info}, {updateSourceInfo});
+
+ SetUpdated(true);
}
bool Texture::HasAlphaChannel() const
mGraphicsController->GenerateTextureMipmaps(*mGraphicsTexture.get());
}
+void Texture::OnRenderFinished()
+{
+ SetUpdated(false);
+}
+
} // namespace Render
} // namespace Internal
return static_cast<bool>(mNativeImage);
}
+ /**
+ * Called from RenderManager to notify the texture that current rendering pass has finished.
+ */
+ void OnRenderFinished();
+
+ /**
+ * Set the updated flag.
+ * @param[in] updated The updated flag
+ */
+ void SetUpdated(bool updated)
+ {
+ mUpdated = updated;
+ }
+
+ /**
+ * Check if the texture is updated
+ * @return True if the texture is updated
+ */
+ [[nodiscard]] bool Updated()
+ {
+ if(mUpdated || IsNativeImage())
+ {
+ return true;
+ }
+ return false;
+ }
+
private:
/**
* Helper method to apply a sampler to the texture
uint16_t mHeight; ///< Height of the texture
Type mType : 3; ///< Type of the texture
bool mHasAlpha : 1; ///< Whether the format has an alpha channel
+ bool mUpdated : 1; ///< Whether the texture is updated
};
} // namespace Render
#define DALI_INTERNAL_SCENEGRAPH_NODE_RESETTER_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
mNode->mVisible.ResetToBaseValue(updateBufferIndex);
mNode->mColor.ResetToBaseValue(updateBufferIndex);
+ mNode->mUpdateAreaHint.ResetToBaseValue(updateBufferIndex);
}
};
mNode->mVisible.MarkAsDirty();
mNode->mColor.MarkAsDirty();
+ mNode->mUpdateAreaHint.MarkAsDirty();
}
/**
{
mNode->mVisible.MarkAsDirty();
mNode->mColor.MarkAsDirty();
+ mNode->mUpdateAreaHint.MarkAsDirty();
}
Node* mNode; ///< The node that owns the properties
Vector3 nodeSize;
Vector4 nodeUpdateArea;
bool nodeUpdateAreaSet(false);
- bool nodeUpdateAreaUseHint(false);
Matrix nodeModelViewMatrix(false);
bool nodeModelViewMatrixSet(false);
// Don't cull items which have render callback
bool hasRenderCallback = (renderable.mRenderer && renderable.mRenderer->GetRenderCallback());
- if(cull && renderable.mRenderer && (hasRenderCallback || (!renderable.mRenderer->GetShader().HintEnabled(Dali::Shader::Hint::MODIFIES_GEOMETRY) && node->GetClippingMode() == ClippingMode::DISABLED)))
+ if(cull && renderable.mRenderer && !hasRenderCallback && !renderable.mRenderer->GetShader().HintEnabled(Dali::Shader::Hint::MODIFIES_GEOMETRY) && node->GetClippingMode() == ClippingMode::DISABLED)
{
const Vector4& boundingSphere = node->GetBoundingSphere();
inside = (boundingSphere.w > Math::MACHINE_EPSILON_1000) &&
if(inside && !isLayer3d && viewportSet)
{
- nodeUpdateAreaUseHint = SetNodeUpdateArea(node, isLayer3d, nodeWorldMatrix, nodeSize, nodeUpdateArea);
- nodeUpdateAreaSet = true;
+ SetNodeUpdateArea(node, isLayer3d, nodeWorldMatrix, nodeSize, nodeUpdateArea);
+ nodeUpdateAreaSet = true;
const Vector3& scale = node->GetWorldScale(updateBufferIndex);
const Vector3& size = Vector3(nodeUpdateArea.z, nodeUpdateArea.w, 1.0f) * scale;
// Get the next free RenderItem.
RenderItem& item = renderList.GetNextFreeItem();
- PartialRenderingData partialRenderingData;
-
- partialRenderingData.node = node;
- partialRenderingData.renderer = renderable.mRenderer;
- partialRenderingData.color = node->GetWorldColor(updateBufferIndex);
- partialRenderingData.depthIndex = node->GetDepthIndex();
- partialRenderingData.isOpaque = isOpaque;
-
- partialRenderingData.textureSet = nullptr;
- if(DALI_LIKELY(renderable.mRenderer))
- {
- partialRenderingData.color.a *= renderable.mRenderer->GetOpacity(updateBufferIndex);
- partialRenderingData.textureSet = renderable.mRenderer->GetTextureSet();
- }
-
item.mNode = node;
item.mIsOpaque = isOpaque;
item.mColor = node->GetColor(updateBufferIndex);
item.mRenderer = &renderable.mRenderer->GetRenderer();
item.mTextureSet = renderable.mRenderer->GetTextureSet();
item.mDepthIndex += renderable.mRenderer->GetDepthIndex();
-
- // Get whether collected map is up to date
- item.mIsUpdated |= renderable.mRenderer->UniformMapUpdated();
}
else
{
if(!nodeUpdateAreaSet)
{
- nodeUpdateAreaUseHint = SetNodeUpdateArea(node, isLayer3d, nodeWorldMatrix, nodeSize, nodeUpdateArea);
+ SetNodeUpdateArea(node, isLayer3d, nodeWorldMatrix, nodeSize, nodeUpdateArea);
}
item.mSize = nodeSize;
item.mUpdateArea = nodeUpdateArea;
item.mModelMatrix = nodeWorldMatrix;
- // Apply transform informations if node doesn't have update size hint and use VisualRenderer.
- if(!nodeUpdateAreaUseHint && renderable.mRenderer && renderable.mRenderer->GetVisualProperties())
- {
- Vector3 updateSize = renderable.mRenderer->CalculateVisualTransformedUpdateSize(updateBufferIndex, Vector3(item.mUpdateArea.z, item.mUpdateArea.w, 0.0f));
- item.mUpdateArea.z = updateSize.x;
- item.mUpdateArea.w = updateSize.y;
- }
-
if(!nodeModelViewMatrixSet)
{
MatrixUtils::Multiply(nodeModelViewMatrix, nodeWorldMatrix, viewMatrix);
}
item.mModelViewMatrix = nodeModelViewMatrix;
+ PartialRenderingData partialRenderingData;
+ partialRenderingData.color = node->GetWorldColor(updateBufferIndex);
+ partialRenderingData.depthIndex = node->GetDepthIndex();
partialRenderingData.matrix = item.mModelViewMatrix;
partialRenderingData.updatedPositionSize = item.mUpdateArea;
partialRenderingData.size = item.mSize;
// List of zValue calculating functions.
const Dali::Layer::SortFunctionType zValueFunctionFromVector3[] = {
- [](const Vector3& position)
- { return position.z; },
- [](const Vector3& position)
- { return position.LengthSquared(); },
+ [](const Vector3& position) { return position.z; },
+ [](const Vector3& position) { return position.LengthSquared(); },
layer.GetSortFunction(),
};
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
UpdateNodeOpacity(node, nodeDirtyFlags, updateBufferIndex);
-
+ node.UpdateUniformHash(updateBufferIndex);
// For partial update, mark all children of an animating node as updated.
if(updated) // Only set to updated if parent was updated.
{
layer->SetReuseRenderers(updateBufferIndex, false);
}
+ else
+ {
+ // If the node is not dirty, then check renderers
+ const uint32_t count = node.GetRendererCount();
+ for(uint32_t i = 0; i < count; ++i)
+ {
+ SceneGraph::Renderer* renderer = node.GetRendererAt(i);
+ if(renderer->IsDirty())
+ {
+ layer->SetReuseRenderers(updateBufferIndex, false);
+ break;
+ }
+ }
+ }
// recurse children
NodeContainer& children = node.GetChildren();
NodePropertyFlags nodeDirtyFlags = layer.GetDirtyFlags();
nodeDirtyFlags |= (layer.IsLocalMatrixDirty() ? NodePropertyFlags::TRANSFORM : NodePropertyFlags::NOTHING);
+ layer.SetReuseRenderers(updateBufferIndex, nodeDirtyFlags == NodePropertyFlags::NOTHING);
+
// recurse children
NodeContainer& children = layer.GetChildren();
const NodeIter endIter = children.End();
return keepUpdating;
}
+void UpdateManager::PostRender()
+{
+ // Reset dirty flag
+ for(auto&& renderer : mImpl->renderers)
+ {
+ renderer->ResetDirtyFlag();
+ }
+
+ for(auto&& scene : mImpl->scenes)
+ {
+ scene->root->SetUpdatedTree(false);
+ }
+}
+
uint32_t UpdateManager::KeepUpdatingCheck(float elapsedSeconds) const
{
// Update the duration set via Stage::KeepRendering()
bool uploadOnly);
/**
+ * This is called after rendering all the scenes in the next frame.
+ */
+ void PostRender();
+
+ /**
* @copydoc Dali::Stage::KeepRendering()
*/
void KeepRendering(float durationSeconds);
flags |= NodePropertyFlags::COLOR;
}
+ // Check whether the update area property has changed
+ if(!mUpdateAreaHint.IsClean())
+ {
+ flags |= NodePropertyFlags::TRANSFORM;
+ }
+
return flags;
}
mDirtyFlags = NodePropertyFlags::NOTHING;
}
+void Node::UpdateUniformHash(BufferIndex bufferIndex)
+{
+ uint64_t hash = 0xc70f6907UL;
+ for(uint32_t i = 0u, count = mUniformMaps.Count(); i < count; ++i)
+ {
+ hash = mUniformMaps[i].propertyPtr->Hash(bufferIndex, hash);
+ }
+ if(mUniformsHash != hash)
+ {
+ mUniformsHash = hash;
+ SetUpdated(true);
+ }
+}
+
void Node::SetParent(Node& parentNode)
{
DALI_ASSERT_ALWAYS(this != &parentNode);
void SetClippingMode(const ClippingMode::Type clippingMode)
{
mClippingMode = clippingMode;
+ SetDirtyFlag(NodePropertyFlags::TRANSFORM);
}
/**
*/
void ResetDirtyFlags(BufferIndex updateBufferIndex);
+ /**
+ * Update uniform hash
+ * @param[in] bufferIndex The buffer to read from.
+ */
+ void UpdateUniformHash(BufferIndex bufferIndex);
+
protected:
/**
* Set the parent of a Node.
private:
// Delete copy and move
- Node(const Node&) = delete;
- Node(Node&&) = delete;
+ Node(const Node&) = delete;
+ Node(Node&&) = delete;
Node& operator=(const Node& rhs) = delete;
- Node& operator=(Node&& rhs) = delete;
+ Node& operator=(Node&& rhs) = delete;
/**
* Recursive helper to disconnect a Node and its children.
TransformManagerMatrixInput mWorldMatrix; ///< Full inherited world matrix
InheritedColor mWorldColor; ///< Full inherited color
+ uint64_t mUniformsHash{0u}; ///< Hash of uniform map property values
uint32_t mClippingSortModifier; ///< Contains bit-packed clipping information for quick access when sorting
const uint32_t mId; ///< The Unique ID of the node.
*/
struct PartialRenderingData
{
- Node* node{nullptr}; /// Node associated with the entry
- Renderer* renderer{nullptr}; /// Renderer object
- const TextureSet* textureSet{nullptr}; /// TextureSet object
- Matrix matrix{}; /// Model-view matrix
- Vector4 color{}; /// Color
- Vector4 updatedPositionSize{}; /// Updated position/size (x, y, width, height)
- Vector3 size{}; /// Size
- uint32_t depthIndex{0u}; /// Depth index
- uint32_t hash; /// Last frame's hash
- bool isOpaque{}; /// Opacity state
+ Matrix matrix{}; /// Model-view matrix
+ Vector4 color{}; /// Color
+ Vector4 updatedPositionSize{}; /// Updated position/size (x, y, width, height)
+ Vector3 size{}; /// Size
+ uint32_t depthIndex{0u}; /// Depth index
+ uint32_t hash; /// Last frame's hash
bool mVisible{true}; /// Visible state (Not hashed)
bool mRendered{false}; /// Rendering state (Not hashed)
void CalculateHash()
{
hash = Dali::INITIAL_HASH_VALUE;
- AddToHash(hash, &node, sizeof(decltype(node)));
- AddToHash(hash, &renderer, sizeof(decltype(renderer)));
- AddToHash(hash, &textureSet, sizeof(decltype(textureSet)));
AddToHash(hash, &matrix, sizeof(decltype(matrix)));
AddToHash(hash, &color, sizeof(decltype(color)));
AddToHash(hash, &updatedPositionSize, sizeof(decltype(updatedPositionSize)));
AddToHash(hash, &size, sizeof(decltype(size)));
AddToHash(hash, &depthIndex, sizeof(decltype(depthIndex)));
- AddToHash(hash, &isOpaque, sizeof(decltype(isOpaque)));
}
/**
frameCache.CalculateHash();
return hash != frameCache.hash ||
- node != frameCache.node ||
- renderer != frameCache.renderer ||
- textureSet != frameCache.textureSet ||
matrix != frameCache.matrix ||
color != frameCache.color ||
updatedPositionSize != frameCache.updatedPositionSize ||
size != frameCache.size ||
depthIndex != frameCache.depthIndex ||
- isOpaque != frameCache.isOpaque ||
-
!mRendered; // If everything is the same, check if we didn't render last frame.
}
void Update(const PartialRenderingData& frameCache)
{
- node = frameCache.node;
- renderer = frameCache.renderer;
- textureSet = frameCache.textureSet;
matrix = frameCache.matrix;
color = frameCache.color;
updatedPositionSize = frameCache.updatedPositionSize;
size = frameCache.size;
depthIndex = frameCache.depthIndex;
- isOpaque = frameCache.isOpaque;
hash = frameCache.hash;
mRendered = true;
mRenderingBehavior(DevelRenderer::Rendering::IF_REQUIRED),
mUpdateDecay(Renderer::Decay::INITIAL),
mRegenerateUniformMap(false),
- mUniformMapUpdated(false),
mPremultipledAlphaEnabled(false),
+ mDirtyFlag(true),
mOpacity(1.0f),
mDepthIndex(0)
{
new(slot) DerivedType(mRenderer, &Render::Renderer::SetRenderCallback, mRenderCallback);
}
+ SetUpdated(true);
+
mResendFlag = 0;
}
// Ensure collected map is up to date
- UpdateUniformMap();
+ UpdateUniformMap(updateBufferIndex);
return rendererUpdated;
}
DALI_ASSERT_DEBUG(textureSet != NULL && "Texture set pointer is NULL");
mTextureSet = textureSet;
+
+ mDirtyFlag = true;
+ SetUpdated(true);
}
const Vector<Render::Texture*>* Renderer::GetTextures() const
mShader->AddUniformMapObserver(*this);
mRegenerateUniformMap = true;
mResendFlag |= RESEND_GEOMETRY | RESEND_SHADER;
+ mDirtyFlag = true;
}
void Renderer::SetGeometry(Render::Geometry* geometry)
void Renderer::SetDepthIndex(int depthIndex)
{
mDepthIndex = depthIndex;
+
+ mDirtyFlag = true;
+ SetUpdated(true);
}
void Renderer::SetFaceCullingMode(FaceCullingMode::Type faceCullingMode)
void Renderer::SetBlendMode(BlendMode::Type blendingMode)
{
mBlendMode = blendingMode;
+
+ mDirtyFlag = true;
+ SetUpdated(true);
}
BlendMode::Type Renderer::GetBlendMode() const
{
mBlendBitmask = options;
mResendFlag |= RESEND_BLEND_BIT_MASK;
+ mDirtyFlag = true;
}
}
{
mRenderCallback = callback;
mResendFlag |= RESEND_SET_RENDER_CALLBACK;
+ mDirtyFlag = true;
}
const Render::Renderer::StencilParameters& Renderer::GetStencilParameters() const
void Renderer::BakeOpacity(BufferIndex updateBufferIndex, float opacity)
{
mOpacity.Bake(updateBufferIndex, opacity);
+
+ mDirtyFlag = true;
+ SetUpdated(true);
}
float Renderer::GetOpacity(BufferIndex updateBufferIndex) const
void Renderer::SetRenderingBehavior(DevelRenderer::Rendering::Type renderingBehavior)
{
mRenderingBehavior = renderingBehavior;
+ SetUpdated(true);
}
DevelRenderer::Rendering::Type Renderer::GetRenderingBehavior() const
return opacityType;
}
-void Renderer::UpdateUniformMap()
+void Renderer::UpdateUniformMap(BufferIndex updateBufferIndex)
{
if(mRegenerateUniformMap)
{
}
localMap.UpdateChangeCounter();
mRegenerateUniformMap = false;
- mUniformMapUpdated = true;
+ SetUpdated(true);
+ }
+
+ uint64_t hash = 0xc70f6907UL;
+ const SceneGraph::UniformMapDataProvider& uniformMapDataProvider = GetUniformMapDataProvider();
+ const SceneGraph::CollectedUniformMap& collectedUniformMap = uniformMapDataProvider.GetCollectedUniformMap();
+ for(uint32_t i = 0u, count = collectedUniformMap.Count(); i < count; ++i)
+ {
+ hash = collectedUniformMap.mUniformMap[i].propertyPtr->Hash(updateBufferIndex, hash);
+ }
+ if(mUniformsHash != hash)
+ {
+ mUniformsHash = hash;
+ SetUpdated(true);
}
}
mResendFlag |= RESEND_DRAW_COMMANDS;
}
+bool Renderer::IsDirty() const
+{
+ // Check whether the opacity property has changed
+ return (mDirtyFlag || !mOpacity.IsClean());
+}
+
+void Renderer::ResetDirtyFlag()
+{
+ mDirtyFlag = false;
+
+ SetUpdated(false);
+}
+
void Renderer::UniformMappingsChanged(const UniformMap& mappings)
{
// The mappings are either from PropertyOwner base class, or the Shader
return mCollectedUniformMap;
}
-Vector3 Renderer::CalculateVisualTransformedUpdateSize(BufferIndex updateBufferIndex, const Vector3& originalSize)
+Vector4 Renderer::GetVisualTransformedUpdateArea(BufferIndex updateBufferIndex, const Vector4& originalUpdateArea) noexcept
{
if(mVisualProperties)
{
// = scaleVertexPosition + 2.0f * abs(basicVertexPosition)
// Cause transform matrix will think center of vertex is (0, 0)
- const Vector2 basicVertexPosition = mVisualPropertiesCoefficient.coefXB * originalSize.GetVectorXY() + mVisualPropertiesCoefficient.coefCB;
- const Vector2 scaleVertexPosition = mVisualPropertiesCoefficient.coefXA * originalSize.GetVectorXY() + mVisualPropertiesCoefficient.coefCA;
+ const Vector2 originalXY = Vector2(originalUpdateArea.x, originalUpdateArea.y);
+ const Vector2 originalWH = Vector2(originalUpdateArea.z, originalUpdateArea.w);
+
+ const Vector2 basicVertexPosition = mVisualPropertiesCoefficient.coefXB * originalWH + mVisualPropertiesCoefficient.coefCB;
+ const Vector2 scaleVertexPosition = mVisualPropertiesCoefficient.coefXA * originalWH + mVisualPropertiesCoefficient.coefCA;
- // VisualTransform don't set z value. Just copy from original z size
- const Vector3 resultSize = Vector3(scaleVertexPosition.x + 2.0f * abs(basicVertexPosition.x) + mVisualPropertiesCoefficient.coefD,
- scaleVertexPosition.y + 2.0f * abs(basicVertexPosition.y) + mVisualPropertiesCoefficient.coefD,
- originalSize.z);
+ // TODO : We need to re-generate coefficient to consitder area width/height
+ const Vector4 resultArea = Vector4(originalXY.x,
+ originalXY.y,
+ scaleVertexPosition.x + 2.0f * abs(basicVertexPosition.x) + mVisualPropertiesCoefficient.coefD,
+ scaleVertexPosition.y + 2.0f * abs(basicVertexPosition.y) + mVisualPropertiesCoefficient.coefD);
- DALI_LOG_INFO(gSceneGraphRendererLogFilter, Debug::Verbose, "%f %f --> %f %f\n", originalSize.x, originalSize.y, resultSize.x, resultSize.y);
+ DALI_LOG_INFO(gSceneGraphRendererLogFilter, Debug::Verbose, "%f %f %f %f--> %f %f %f %f\n", originalUpdateArea.x, originalUpdateArea.y, originalUpdateArea.z, originalUpdateArea.w, resultArea.x, resultArea.y, resultArea.z, resultArea.w);
- return resultSize;
+ return resultArea;
}
- return originalSize;
+ return originalUpdateArea;
}
} // namespace SceneGraph
};
/**
+ * @copydoc RenderDataProvider::IsUpdated()
+ */
+ bool IsUpdated() const override
+ {
+ return Updated();
+ }
+
+ /**
+ * @copydoc RenderDataProvider::GetVisualTransformedUpdateArea()
+ */
+ Vector4 GetVisualTransformedUpdateArea(BufferIndex updateBufferIndex, const Vector4& originalUpdateArea) noexcept override;
+
+ /**
* Sets RenderCallback object
*
* @param[in] callback Valid pointer to RenderCallback object
* Merge shader uniform map into renderer uniform map if any of the
* maps have changed. Only update uniform map if added to render
* instructions.
+ * @param[in] updateBufferIndex The current update buffer index.
*/
- void UpdateUniformMap();
+ void UpdateUniformMap(BufferIndex updateBufferIndex);
/**
- * @brief CHeck if the uniformMap regenerated
- * @return True if the uniformMap changed after latest checkup.
- * @note The uniform map updated flag is reset after calling this.
+ * Set the given external draw commands on this renderer.
*/
- [[nodiscard]] inline bool UniformMapUpdated() noexcept
- {
- if(mUniformMapUpdated)
- {
- mUniformMapUpdated = false;
- return true;
- }
- return false;
- }
+ void SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size);
/**
- * Set the given external draw commands on this renderer.
+ * Query whether a renderer is dirty.
+ * @return true if the renderer is dirty.
+ * @note It is used to decide whether to reuse the RenderList. We can't reuse the RenderList if this is dirty.
*/
- void SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size);
+ bool IsDirty() const;
+
+ /**
+ * Reset both dirty flag and updated flag.
+ * @note This is called after rendering has completed.
+ */
+ void ResetDirtyFlag();
public: // UniformMap::Observer
/**
return mVisualProperties.Get();
}
- /**
- * @brief Recalculate size after visual properties applied.
- *
- * @param[in] updateBufferIndex The current update buffer index.
- * @param[in] originalSize The original size before apply the visual properties.
- *
- * @return The recalculated size after visual properties applied.
- */
- Vector3 CalculateVisualTransformedUpdateSize(BufferIndex updateBufferIndex, const Vector3& originalSize);
-
private:
/**
* Protected constructor; See also Renderer::New()
Dali::Internal::Render::Renderer::StencilParameters mStencilParameters; ///< Struct containing all stencil related options
+ uint64_t mUniformsHash{0}; ///< Hash of uniform map property values
uint32_t mIndexedDrawFirstElement; ///< first element index to be drawn using indexed draw
uint32_t mIndexedDrawElementsCount; ///< number of elements to be drawn using indexed draw
uint32_t mBlendBitmask; ///< The bitmask of blending options
DevelRenderer::Rendering::Type mRenderingBehavior : 2; ///< The rendering behavior
Decay mUpdateDecay : 2; ///< Update decay (aging)
- bool mRegenerateUniformMap : 1; ///< true if the map should be regenerated
- bool mUniformMapUpdated : 1; ///< true if the map regenerated recently.
- bool mPremultipledAlphaEnabled : 1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
+ bool mRegenerateUniformMap : 1; ///< true if the map should be regenerated
+ bool mPremultipledAlphaEnabled : 1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
+ bool mDirtyFlag : 1; ///< Flag indicating whether the properties are changed
+
std::vector<Dali::DevelRenderer::DrawCommand> mDrawCommands;
Dali::RenderCallback* mRenderCallback{nullptr};
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
}
mSamplers[index] = sampler;
+
+ if(index < static_cast<uint32_t>(mTextures.Size()))
+ {
+ mTextures[index]->SetUpdated(true);
+ }
}
void TextureSet::SetTexture(uint32_t index, Render::Texture* texture)
if(texture)
{
mHasAlpha |= texture->HasAlphaChannel();
+ texture->SetUpdated(true);
}
}