utc-Dali-ConstraintFunction.cpp
utc-Dali-Constraints.cpp
utc-Dali-ConstraintSource.cpp
- utc-Dali-Context.cpp
utc-Dali-Core.cpp
utc-Dali-CustomActor.cpp
utc-Dali-Degree.cpp
utc-Dali-Random.cpp
utc-Dali-Rect.cpp
utc-Dali-Renderer.cpp
+ utc-Dali-VisualRenderer.cpp
utc-Dali-RenderTask.cpp
utc-Dali-RenderTaskList.cpp
utc-Dali-RotationGestureDetector.cpp
/*
- * 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.
{"uViewMatrix", GL_FLOAT_MAT4, 1},
{"uLightCameraProjectionMatrix", GL_FLOAT_MAT4, 1},
{"uLightCameraViewMatrix", GL_FLOAT_MAT4, 1}};
+
+ // WARNING: IF YOU CHANGE THIS LIST, ALSO CHANGE UNIFORMS IN test-graphics-reflection.cpp
}
void TestGlAbstraction::PreRender()
#define TEST_GL_ABSTRACTION_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.
if(it2 == uniformIDs.end())
{
// Uniform not found, so add it...
- uniformIDs[name] = mLastUniformIdUsed++;
- return mLastUniformIdUsed;
+ uniformIDs[name] = ++mLastUniformIdUsed;
+ return uniformIDs[name];
}
return it2->second;
for(const auto& uniform : mCustomUniformData)
{
- GetUniformLocation(program, uniform.name.c_str());
+ auto iter = uniform.name.find("[");
+ auto name = uniform.name;
+ if(iter != std::string::npos)
+ {
+ name = uniform.name.substr(0, iter);
+ auto arrayCount = std::stoi(uniform.name.substr(iter + 1));
+ for(int i = 0; i < arrayCount; ++i)
+ {
+ std::stringstream nss;
+ nss << name << "[" << i << "]";
+ GetUniformLocation(program, nss.str().c_str()); // Generate a GL loc per element
+ }
+ }
+ else
+ {
+ GetUniformLocation(program, name.c_str());
+ }
}
}
/*
- * 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.
mUsage(usage)
{
memory.resize(size);
- mGl.GetBufferTrace().EnableLogging(true);
+ mGl.GetBufferTrace().EnableLogging(false);
}
void TestGraphicsBuffer::Bind()
void TestGraphicsBuffer::BindAsUniformBuffer(const TestGraphicsProgram* program, const Dali::UniformBufferBindingDescriptor& uboBinding) const
{
- auto* reflection = static_cast<const TestGraphicsReflection*>(&program->GetReflection());
-
- Graphics::UniformBlockInfo uboInfo{};
- reflection->GetUniformBlock(0, uboInfo);
+ auto* reflection = static_cast<const TestGraphicsReflection*>(&program->GetReflection());
+ const auto& uboInfo = reflection->GetTestUniformBlock(0u);
auto offset = uboBinding.offset;
auto* data = memory.data() + offset;
for(const auto& member : uboInfo.members)
{
- auto type = reflection->GetMemberType(0, member.location);
- switch(type)
+ uint32_t numElements = member.numElements > 0 ? member.numElements : 1;
+
+ for(uint32_t i = 0; i < numElements; ++i)
{
- case Property::VECTOR4:
- {
- auto value = *reinterpret_cast<const Dali::Vector4*>(data + member.offset);
- mGl.Uniform4f(member.location, value.x, value.y, value.z, value.w);
- break;
- }
- case Property::VECTOR3:
- {
- auto value = *reinterpret_cast<const Dali::Vector3*>(data + member.offset);
- mGl.Uniform3f(member.location, value.x, value.y, value.z);
- break;
- }
- case Property::VECTOR2:
- {
- auto value = *reinterpret_cast<const Dali::Vector2*>(data + member.offset);
- mGl.Uniform2f(member.location, value.x, value.y);
- break;
- }
- case Property::FLOAT:
- {
- auto value = *reinterpret_cast<const float*>(data + member.offset);
- mGl.Uniform1f(member.location, value);
- break;
- }
- case Property::INTEGER:
- {
- auto ptr = reinterpret_cast<const GLint*>(data + member.offset);
- auto value = *ptr;
- mGl.Uniform1i(member.location, value);
- break;
- }
- case Property::MATRIX:
- {
- auto value = reinterpret_cast<const float*>(data + member.offset);
- mGl.UniformMatrix4fv(member.location, 1, GL_FALSE, value);
- break;
- }
- case Property::MATRIX3:
- {
- auto value = reinterpret_cast<const float*>(data + member.offset);
- mGl.UniformMatrix3fv(member.location, 1, GL_FALSE, value);
- break;
- }
- default:
+ switch(member.type)
{
- fprintf(stderr, "\n%s type not found\n", member.name.c_str());
+ case Property::VECTOR4:
+ {
+ auto value = *reinterpret_cast<const Dali::Vector4*>(data + member.offsets[i]);
+ mGl.Uniform4f(member.locations[i], value.x, value.y, value.z, value.w);
+ break;
+ }
+ case Property::VECTOR3:
+ {
+ auto value = *reinterpret_cast<const Dali::Vector3*>(data + member.offsets[i]);
+ mGl.Uniform3f(member.locations[i], value.x, value.y, value.z);
+ break;
+ }
+ case Property::VECTOR2:
+ {
+ auto value = *reinterpret_cast<const Dali::Vector2*>(data + member.offsets[i]);
+ mGl.Uniform2f(member.locations[i], value.x, value.y);
+ break;
+ }
+ case Property::FLOAT:
+ {
+ auto value = *reinterpret_cast<const float*>(data + member.offsets[i]);
+ mGl.Uniform1f(member.locations[i], value);
+ break;
+ }
+ case Property::INTEGER:
+ {
+ auto ptr = reinterpret_cast<const GLint*>(data + member.offsets[i]);
+ auto value = *ptr;
+ mGl.Uniform1i(member.locations[i], value);
+ break;
+ }
+ case Property::MATRIX:
+ {
+ auto value = reinterpret_cast<const float*>(data + member.offsets[i]);
+ mGl.UniformMatrix4fv(member.locations[i], 1, GL_FALSE, value);
+ break;
+ }
+ case Property::MATRIX3:
+ {
+ auto value = reinterpret_cast<const float*>(data + member.offsets[i]);
+ mGl.UniformMatrix3fv(member.locations[i], 1, GL_FALSE, value);
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "\n%s type not found\n", member.name.c_str());
+ }
}
}
}
};
TestGraphicsController::TestGraphicsController()
-: mCallStack(true, "TestGraphicsController."),
- mCommandBufferCallStack(true, "TestCommandBuffer."),
- mFrameBufferCallStack(true, "TestFrameBuffer.")
+: mCallStack(false, "TestGraphicsController."),
+ mCommandBufferCallStack(false, "TestCommandBuffer."),
+ mFrameBufferCallStack(false, "TestFrameBuffer.")
{
mCallStack.Enable(true);
mCommandBufferCallStack.Enable(true);
auto& trace = mGl.GetTextureTrace();
trace.Enable(true);
- trace.EnableLogging(true);
+ trace.EnableLogging(false);
}
void TestGraphicsController::SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo)
/*
- * 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.
{
TestGraphicsProgramImpl::TestGraphicsProgramImpl(TestGlAbstraction& gl, const Graphics::ProgramCreateInfo& createInfo, Property::Array& vertexFormats, std::vector<UniformData>& customUniforms)
: mGl(gl),
+ mId(gl.CreateProgram()),
mCreateInfo(createInfo),
- mReflection(gl, vertexFormats, createInfo, customUniforms)
+ mReflection(gl, mId, vertexFormats, createInfo, customUniforms)
{
- mId = mGl.CreateProgram();
-
// Ensure active sampler uniforms are set
mGl.SetCustomUniforms(customUniforms);
- mGl.LinkProgram(mId);
+
+ // Don't need to re-register uniforms in GL side - now done in creation of mReflection.
+ // Was previously done in mGl.LinkProgram(mId);
}
bool TestGraphicsProgramImpl::GetParameter(uint32_t parameterId, void* outData)
/*
- * 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.
UniformData("uViewMatrix", Property::Type::MATRIX),
UniformData("uLightCameraProjectionMatrix", Property::Type::MATRIX),
UniformData("uLightCameraViewMatrix", Property::Type::MATRIX),
+
+ // WARNING: IF YOU CHANGE THIS LIST, ALSO CHANGE mActiveUniforms IN test-gl-abstraction, Initialize
};
+
+/**
+ * Helper function that returns size of uniform datatypes based
+ * on property type.
+ */
+constexpr int GetSizeForType(Property::Type type)
+{
+ switch(type)
+ {
+ case Property::Type::BOOLEAN:
+ {
+ return sizeof(bool);
+ }
+ case Property::Type::FLOAT:
+ {
+ return sizeof(float);
+ }
+ case Property::Type::INTEGER:
+ {
+ return sizeof(int);
+ }
+ case Property::Type::VECTOR2:
+ {
+ return sizeof(Vector2);
+ }
+ case Property::Type::VECTOR3:
+ {
+ return sizeof(Vector3);
+ }
+ case Property::Type::VECTOR4:
+ {
+ return sizeof(Vector4);
+ }
+ case Property::Type::MATRIX3:
+ {
+ return sizeof(Matrix3);
+ }
+ case Property::Type::MATRIX:
+ {
+ return sizeof(Matrix);
+ }
+ default:
+ {
+ return 0;
+ }
+ };
}
-TestGraphicsReflection::TestGraphicsReflection(TestGlAbstraction& gl, Property::Array& vfs, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms)
+} // namespace
+
+TestGraphicsReflection::TestGraphicsReflection(TestGlAbstraction& gl, uint32_t programId, Property::Array& vfs, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms)
: mGl(gl),
mCustomUniforms(customUniforms)
{
mDefaultUniformBlock.name = "";
mDefaultUniformBlock.members = {};
mDefaultUniformBlock.binding = 0;
- mDefaultUniformBlock.size = 64 * (UNIFORMS.size() + mCustomUniforms.size());
mDefaultUniformBlock.descriptorSet = 0;
mDefaultUniformBlock.members.clear();
- int loc = 0;
+
+ int offset = 0;
for(const auto& data : UNIFORMS)
{
mDefaultUniformBlock.members.emplace_back();
- auto& item = mDefaultUniformBlock.members.back();
- item.name = data.name;
- item.binding = 0;
- item.offset = loc * 64;
- item.location = loc++;
+ auto& item = mDefaultUniformBlock.members.back();
+ item.name = data.name;
+ item.binding = 0;
+ item.offsets.push_back(offset);
+ item.locations.push_back(gl.GetUniformLocation(programId, data.name.c_str()));
item.bufferIndex = 0;
item.uniformClass = Graphics::UniformClass::UNIFORM;
+ item.type = data.type;
+ offset += GetSizeForType(data.type);
}
for(const auto& data : mCustomUniforms)
{
fprintf(stderr, "\ncustom uniforms: %s\n", data.name.c_str());
mDefaultUniformBlock.members.emplace_back();
- auto& item = mDefaultUniformBlock.members.back();
- item.name = data.name;
- item.binding = 0;
- item.offset = loc * 64;
- item.location = loc++;
- item.bufferIndex = 0;
- item.uniformClass = Graphics::UniformClass::UNIFORM;
+ auto& item = mDefaultUniformBlock.members.back();
+
+ auto iter = data.name.find("[", 0);
+ int numElements = 1;
+ if(iter != std::string::npos)
+ {
+ auto baseName = data.name.substr(0, iter);
+ iter++;
+ numElements = std::stoi(data.name.substr(iter));
+ if(numElements == 0)
+ {
+ numElements = 1;
+ }
+
+ item.name = baseName;
+ item.binding = 0;
+ item.bufferIndex = 0;
+ item.uniformClass = Graphics::UniformClass::UNIFORM;
+ item.type = data.type;
+ item.numElements = numElements;
+
+ for(int i = 0; i < numElements; ++i)
+ {
+ std::stringstream elementNameStream;
+ elementNameStream << baseName << "[" << i << "]";
+
+ item.locations.push_back(gl.GetUniformLocation(programId, elementNameStream.str().c_str()));
+ item.offsets.push_back(offset);
+ offset += GetSizeForType(data.type);
+ }
+ }
+ else
+ {
+ item.name = data.name;
+ item.binding = 0;
+ item.offsets.push_back(offset);
+ item.locations.push_back(gl.GetUniformLocation(programId, item.name.c_str()));
+ item.bufferIndex = 0;
+ item.uniformClass = Graphics::UniformClass::UNIFORM;
+ item.type = data.type;
+ offset += GetSizeForType(data.type);
+ }
}
+ mDefaultUniformBlock.size = offset;
mUniformBlocks.push_back(mDefaultUniformBlock);
}
uint32_t TestGraphicsReflection::GetUniformBlockSize(uint32_t index) const
{
- // 64 bytes per uniform (64 = 4x4 matrix)
- // TODO: fix if array will be used
- return 64 * (UNIFORMS.size() + mCustomUniforms.size());
+ if(index >= mUniformBlocks.size())
+ {
+ return 0;
+ }
+
+ const auto& block = mUniformBlocks[index];
+ return block.size;
}
bool TestGraphicsReflection::GetUniformBlock(uint32_t index, Dali::Graphics::UniformBlockInfo& out) const
out.members[i].name = memberUniform.name;
out.members[i].binding = block.binding;
out.members[i].uniformClass = Graphics::UniformClass::UNIFORM;
- out.members[i].offset = memberUniform.offset;
- out.members[i].location = memberUniform.location;
+ out.members[i].offset = memberUniform.offsets[0];
+ out.members[i].location = memberUniform.locations[0];
}
return true;
{
if(blockIndex < mUniformBlocks.size() && memberLocation < mUniformBlocks[blockIndex].members.size())
{
- return mUniformBlocks[blockIndex].members[memberLocation].offset;
+ return mUniformBlocks[blockIndex].members[memberLocation].offsets[0];
}
else
{
return Graphics::ShaderLanguage::GLSL_3_1;
}
-Dali::Property::Type TestGraphicsReflection::GetMemberType(int blockIndex, int location) const
-{
- return location < static_cast<int>(UNIFORMS.size()) ? UNIFORMS[location].type : mCustomUniforms[location - UNIFORMS.size()].type;
-}
-
} // namespace Dali
#define DALI_TEST_GRAPHICS_REFLECTION_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.
class TestGraphicsReflection : public Graphics::Reflection
{
public:
- TestGraphicsReflection(TestGlAbstraction& gl, Property::Array& vertexFormats, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms);
+ TestGraphicsReflection(TestGlAbstraction& gl, uint32_t program_id, Property::Array& vertexFormats, const Graphics::ProgramCreateInfo& createInfo, std::vector<UniformData>& customUniforms);
uint32_t GetVertexAttributeLocation(const std::string& name) const override;
Dali::Graphics::VertexInputAttributeFormat GetVertexAttributeFormat(uint32_t location) const override;
Graphics::ShaderLanguage GetLanguage() const override;
public: // Test methods
+ struct TestUniformInfo
+ {
+ std::string name{""}; // baseName in the case of arrays
+ Graphics::UniformClass uniformClass{Graphics::UniformClass::UNDEFINED};
+ uint32_t binding{0u};
+ uint32_t bufferIndex{0u};
+ std::vector<uint32_t> offsets{};
+ std::vector<uint32_t> locations{};
+ uint32_t numElements{0u}; // 0 elements means this isn't an array; 1 element means this is an array of size 1
+ Property::Type type;
+ };
+
+ struct TestUniformBlockInfo
+ {
+ std::string name{""};
+ uint32_t descriptorSet{0u};
+ uint32_t binding{0u};
+ uint32_t size{0u};
+ std::vector<TestUniformInfo> members{};
+ };
+
void SetAttributes(std::vector<std::string> locations)
{
mAttributes.clear();
}
}
- Dali::Property::Type GetMemberType(int blockIndex, int location) const;
+ const TestUniformBlockInfo& GetTestUniformBlock(uint32_t index) const
+ {
+ return mUniformBlocks[index];
+ }
TestGlAbstraction& mGl;
mutable std::vector<std::string> mAttributes;
std::vector<UniformData> mCustomUniforms;
- Graphics::UniformBlockInfo mDefaultUniformBlock{}; ///< The emulated UBO containing all the standalone uniforms
- std::vector<Graphics::UniformBlockInfo> mUniformBlocks{}; ///< List of uniform blocks
+ TestUniformBlockInfo mDefaultUniformBlock{}; ///< The emulated UBO containing all the standalone uniforms
+ std::vector<TestUniformBlockInfo> mUniformBlocks{}; ///< List of uniform blocks
};
} // namespace Dali
/*
- * 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.
}
if(!found)
{
- fprintf(stderr, "Search for %s(%s) failed\n", method.c_str(), params.c_str());
+ fprintf(stderr, "Search for %s() failed\n", method.c_str());
+ }
+ return found;
+}
+
+bool TraceCallStack::FindMethodAndGetParameters(std::string method, NamedParams& params) const
+{
+ bool found = false;
+ for(size_t i = 0; i < mCallStack.size(); i++)
+ {
+ if(0 == mCallStack[i].method.compare(method))
+ {
+ found = true;
+ params = mCallStack[i].namedParams;
+ break;
+ }
+ }
+ if(!found)
+ {
+ fprintf(stderr, "Search for %s() failed\n", method.c_str());
}
return found;
}
bool FindMethodAndGetParameters(std::string method, std::string& params) const;
/**
+ * Search for a method in the stack and return its parameters if found
+ * @param[in] method The name of the method
+ * @param[out] params of the method
+ * @return true if the method was in the stack
+ */
+ bool FindMethodAndGetParameters(std::string method, NamedParams& params) const;
+
+ /**
* Count how many times a method was called
* @param[in] method The name of the method
* @return The number of times it was called
bool gTouchCallBackCalled = false;
bool gTouchCallBackCalled2 = false;
bool gTouchCallBackCalled3 = false;
+bool gHitTestTouchCallBackCalled = false;
bool gHoverCallBackCalled = false;
END_TEST;
}
+static bool TestHitTestTouchCallback(Actor, const TouchEvent&)
+{
+ gHitTestTouchCallBackCalled = true;
+ return false;
+ END_TEST;
+}
+
static void ResetTouchCallbacks()
{
gTouchCallBackCalled = false;
// Check stencil functions are not called.
DALI_TEST_CHECK(!stencilTrace.FindMethod("StencilFunc"));
- // TODO: Temporarily commented out the line below when caching is disabled. Will need to add it back.
- // DALI_TEST_CHECK(!stencilTrace.FindMethod("StencilMask"));
DALI_TEST_CHECK(!stencilTrace.FindMethod("StencilOp"));
// Check that scissor clipping is overriden by the renderer properties.
END_TEST;
}
+
+int UtcDaliActorDoesWantedHitTest(void)
+{
+ struct HitTestData
+ {
+ public:
+ HitTestData(const Vector3& scale, const Vector2& touchPoint, bool result)
+ : mScale(scale),
+ mTouchPoint(touchPoint),
+ mResult(result)
+ {
+ }
+
+ Vector3 mScale;
+ Vector2 mTouchPoint;
+ bool mResult;
+ };
+
+ TestApplication application;
+ tet_infoline(" UtcDaliActorDoesWantedHitTest");
+
+ // Fill a vector with different hit tests.
+ struct HitTestData* hitTestData[] = {
+ // scale touch point result
+ new HitTestData(Vector3(100.f, 100.f, 1.f), Vector2(289.f, 400.f), true), // touch point close to the right edge (inside)
+ new HitTestData(Vector3(100.f, 100.f, 1.f), Vector2(291.f, 400.f), false), // touch point close to the right edge (outside)
+ new HitTestData(Vector3(110.f, 100.f, 1.f), Vector2(291.f, 400.f), true), // same point as above with a wider scale. Should be inside.
+ new HitTestData(Vector3(100.f, 100.f, 1.f), Vector2(200.f, 451.f), false), // touch point close to the down edge (outside)
+ new HitTestData(Vector3(100.f, 110.f, 1.f), Vector2(200.f, 451.f), true), // same point as above with a wider scale. Should be inside.
+ NULL,
+ };
+
+ // get the root layer
+ Actor actor = Actor::New();
+ actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+
+ Actor lowerActor = Actor::New();
+ lowerActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ lowerActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+
+ // actor and lowerActor have no relationship.
+ application.GetScene().Add(lowerActor);
+ application.GetScene().Add(actor);
+
+ ResetTouchCallbacks();
+ gHitTestTouchCallBackCalled = false;
+
+ unsigned int index = 0;
+ while(NULL != hitTestData[index])
+ {
+ actor.SetProperty(Actor::Property::SIZE, Vector2(1.f, 1.f));
+ actor.SetProperty(Actor::Property::SCALE, Vector3(hitTestData[index]->mScale.x, hitTestData[index]->mScale.y, hitTestData[index]->mScale.z));
+
+ lowerActor.SetProperty(Actor::Property::SIZE, Vector2(1.f, 1.f));
+ lowerActor.SetProperty(Actor::Property::SCALE, Vector3(hitTestData[index]->mScale.x, hitTestData[index]->mScale.y, hitTestData[index]->mScale.z));
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(!gTouchCallBackCalled);
+ DALI_TEST_CHECK(!gTouchCallBackCalled2);
+ DALI_TEST_CHECK(!gHitTestTouchCallBackCalled);
+
+ // connect to its touch signal
+ actor.TouchedSignal().Connect(TestTouchCallback);
+ lowerActor.TouchedSignal().Connect(TestTouchCallback2);
+
+ // connect to its hit-test signal
+ Dali::DevelActor::HitTestResultSignal(actor).Connect(TestHitTestTouchCallback);
+
+ Dali::Integration::Point point;
+ point.SetState(PointState::DOWN);
+ point.SetScreenPosition(Vector2(hitTestData[index]->mTouchPoint.x, hitTestData[index]->mTouchPoint.y));
+ Dali::Integration::TouchEvent event;
+ event.AddPoint(point);
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+ application.ProcessEvent(event);
+
+ // check hit-test events
+ DALI_TEST_CHECK(gHitTestTouchCallBackCalled == hitTestData[index]->mResult);
+ // Passed all hit-tests of actor.
+ DALI_TEST_CHECK(gTouchCallBackCalled == false);
+ // The lowerActor was hit-tested.
+ DALI_TEST_CHECK(gTouchCallBackCalled2 == hitTestData[index]->mResult);
+
+ if(gTouchCallBackCalled2 != hitTestData[index]->mResult)
+ tet_printf("Test failed:\nScale %f %f %f\nTouchPoint %f, %f\nResult %d\n",
+ hitTestData[index]->mScale.x,
+ hitTestData[index]->mScale.y,
+ hitTestData[index]->mScale.z,
+ hitTestData[index]->mTouchPoint.x,
+ hitTestData[index]->mTouchPoint.y,
+ hitTestData[index]->mResult);
+
+ ResetTouchCallbacks();
+ gHitTestTouchCallBackCalled = false;
+ ++index;
+ }
+ END_TEST;
+}
/*
- * Copyright (c) 2020 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.
END_TEST;
}
+int UtcDaliBaseHandleInequalityWithNullptr(void)
+{
+ TestApplication application;
+ tet_infoline("Test for Dali::BaseHandle::operator == nullptr");
+
+ BaseHandle object;
+
+ // object is nullptr.
+ DALI_TEST_CHECK(object == nullptr);
+ DALI_TEST_CHECK(nullptr == object);
+ DALI_TEST_CHECK(!(object != nullptr));
+ DALI_TEST_CHECK(!(nullptr != object));
+
+ object = Actor::New();
+
+ // object is not nullptr.
+ DALI_TEST_CHECK(!(object == nullptr));
+ DALI_TEST_CHECK(!(nullptr == object));
+ DALI_TEST_CHECK(object != nullptr);
+ DALI_TEST_CHECK(nullptr != object);
+
+ END_TEST;
+}
+
int UtcDaliBaseHandleStlVector(void)
{
TestApplication application;
+++ /dev/null
-/*
- * 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 <dali-test-suite-utils.h>
-#include <dali/public-api/dali-core.h>
-#include <stdlib.h>
-
-#include <iostream>
-
-using namespace Dali;
-
-namespace
-{
-// Size of the VertexAttributeArray enables
-// GLES specification states that there's a minimum of 8
-const unsigned int TEST_MAX_ATTRIBUTE_CACHE_SIZE = 8;
-
-enum TestAttribType
-{
- ATTRIB_UNKNOWN = -1,
- ATTRIB_POSITION,
- ATTRIB_NORMAL,
- ATTRIB_TEXCOORD,
- ATTRIB_COLOR,
- ATTRIB_BONE_WEIGHTS,
- ATTRIB_BONE_INDICES,
- ATTRIB_TYPE_LAST
-};
-
-// Create bitmap actor
-static Actor CreateBitmapActor()
-{
- Actor actor = CreateRenderableActor();
- actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
- actor.SetProperty(Actor::Property::NAME, "Test Image Rendering Actor");
- return actor;
-}
-
-} // anonymous namespace
-
-// Positive test case for a method
-int UtcDaliContextVertexAttribStartup(void)
-{
- tet_infoline("Testing vertex attrib initial state in context");
-
- TestApplication application;
-
- // start up
- application.SendNotification();
- application.Render();
- application.Render();
-
- // check the locations
- for(unsigned int i = 0; i < TEST_MAX_ATTRIBUTE_CACHE_SIZE; i++)
- {
- DALI_TEST_CHECK(application.GetGlAbstraction().GetVertexAttribArrayState(i) == false);
- }
-
- tet_result(TET_PASS);
- END_TEST;
-}
-
-// Tests to make the attribs only get set once when continually rendering an image actor
-int UtcDaliContextVertexAttribImageRendering(void)
-{
- tet_infoline("Testing vertex attrib rendering state in context with images");
-
- TestApplication application;
-
- // start up
- application.SendNotification();
- application.Render();
- application.Render();
-
- // the vertex attribs get modified on startup to set them to disabled
- // clear the flag to say they've changed
- application.GetGlAbstraction().ClearVertexAttribArrayChanged();
-
- // create a test bitmap actor
- Actor actor(CreateBitmapActor());
- application.GetScene().Add(actor);
-
- application.SendNotification();
- application.Render();
- application.Render();
-
- // check to make sure the state has changed (the image renderer will enable some
- // locations).
- DALI_TEST_CHECK(application.GetGlAbstraction().GetVertexAttribArrayChanged());
-
-#ifdef REMOVE_CACHE_TESTING_TEMPORARILY
- // Now check to make sure the state is cached, and isn't being set each frame.
- application.GetGlAbstraction().ClearVertexAttribArrayChanged();
-
- application.Render();
- application.Render();
- application.Render();
-
- // if it has changed then the caching has failed
- DALI_TEST_CHECK(application.GetGlAbstraction().GetVertexAttribArrayChanged() == false);
-
- //tet_result(TET_PASS);
-#endif
-
- END_TEST;
-}
/*
- * Copyright (c) 2020 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.
*/
#include <dali-test-suite-utils.h>
+#include <dali/devel-api/actors/actor-devel.h>
#include <dali/devel-api/events/hit-test-algorithm.h>
#include <dali/integration-api/events/touch-event-integ.h>
#include <dali/public-api/dali-core.h>
namespace
{
+bool gHitTestTouchCallBackCalled = false;
+static bool TestHitTestTouchCallback(Actor, const TouchEvent&)
+{
+ gHitTestTouchCallBackCalled = true;
+ return false;
+ END_TEST;
+}
+
/**
* The functor to be used in the hit-test algorithm to check whether the actor is hittable.
*/
DALI_TEST_EQUALS(results.actorCoordinates, actorSize * 0.5f, TEST_LOCATION);
END_TEST;
}
+
+int UtcDaliHitTestAlgorithmDoesWantedHitTest(void)
+{
+ TestApplication application;
+ tet_infoline("Testing Dali::HitTestAlgorithm with does wanted to HitTest");
+
+ Stage stage = Stage::GetCurrent();
+ RenderTaskList renderTaskList = stage.GetRenderTaskList();
+ RenderTask defaultRenderTask = renderTaskList.GetTask(0u);
+ Dali::CameraActor cameraActor = defaultRenderTask.GetCameraActor();
+
+ Vector2 stageSize(stage.GetSize());
+ cameraActor.SetOrthographicProjection(stageSize);
+ cameraActor.SetProperty(Actor::Property::POSITION, Vector3(0.0f, 0.0f, 1600.0f));
+
+ Vector2 actorSize(stageSize * 0.5f);
+ // Create two actors with half the size of the stage and set them to be overlapping
+ Actor blue = Actor::New();
+ blue.SetProperty(Actor::Property::NAME, "Blue");
+ blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ blue.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER);
+ blue.SetProperty(Actor::Property::SIZE, actorSize);
+
+ Actor green = Actor::New();
+ green.SetProperty(Actor::Property::NAME, "Green");
+ green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ green.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER);
+ green.SetProperty(Actor::Property::SIZE, actorSize);
+
+ // Add the actors to the view
+ stage.Add(blue);
+ stage.Add(green);
+
+ // connect to its hit-test signal
+ Dali::DevelActor::HitTestResultSignal(green).Connect(TestHitTestTouchCallback);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render(0);
+ application.Render(10);
+
+ gHitTestTouchCallBackCalled = false;
+
+ HitTestAlgorithm::Results results;
+ HitTest(stage, stageSize / 2.0f, results, &DefaultIsActorTouchableFunction);
+
+ // check hit-test events
+ // The green actor received an event that the green actor was hit.
+ DALI_TEST_CHECK(gHitTestTouchCallBackCalled == true);
+ // The green actor passed the hit-test. So blue was the final hit.
+ DALI_TEST_CHECK(results.actor == blue);
+
+ END_TEST;
+}
/*
- * Copyright (c) 2020 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.
END_TEST;
}
+
+/** Equality with nullptr */
+int UtcDaliIntrusivePtrOperatorEqualWithNullptr(void)
+{
+ tet_infoline("Test for Dali::IntrusivePtr::operator == nullptr");
+
+ IntrusivePtr<Counted> counted1(new Counted);
+
+ // counted1 is not nullptr.
+ DALI_TEST_CHECK(!(counted1 == nullptr));
+ DALI_TEST_CHECK(!(nullptr == counted1));
+ DALI_TEST_CHECK(counted1 != nullptr);
+ DALI_TEST_CHECK(nullptr != counted1);
+
+ counted1 = nullptr;
+
+ // counted1 is nullptr.
+ DALI_TEST_CHECK(counted1 == nullptr);
+ DALI_TEST_CHECK(nullptr == counted1);
+ DALI_TEST_CHECK(!(counted1 != nullptr));
+ DALI_TEST_CHECK(!(nullptr != counted1));
+
+ END_TEST;
+}
/*
- * Copyright (c) 2020 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.
GestureReceivedFunctor functor(data);
detector.DetectedSignal().Connect(&application, functor);
- // application.ProcessEvent( GenerateSingleTouch( PointState::DOWN, Vector2( 20.0f, 20.0f ), 150 ) );
- // application.ProcessEvent( GenerateSingleTouch( PointState::MOTION, Vector2( 20.0f, 25.0f ), 151 ) );
application.ProcessEvent(GenerateSingleTouch(PointState::INTERRUPTED, Vector2(20.0f, 30.0f), 152));
application.SendNotification();
/*
- * 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.
///////////////////////////////////////////////////////////////////////////////
namespace
{
+bool gHitTestTouchCallBackCalled = false;
+static bool TestHitTestTouchCallback(Actor, const TouchEvent&)
+{
+ gHitTestTouchCallBackCalled = true;
+ return false;
+ END_TEST;
+}
// Stores data that is populated in the callback and will be read by the TET cases
struct SignalData
{
data.Reset();
END_TEST;
+}
+
+int UtcDaliTapGestureDoesWantedHitTest(void)
+{
+ TestApplication application;
+
+ Actor blue = Actor::New();
+ blue.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ blue.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ Actor green = Actor::New();
+ green.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ green.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ application.GetScene().Add(blue);
+ application.GetScene().Add(green);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ SignalData blueData;
+ GestureReceivedFunctor blueFunctor(blueData);
+
+ TapGestureDetector blueDetector = TapGestureDetector::New();
+ blueDetector.Attach(blue);
+ blueDetector.DetectedSignal().Connect(&application, blueFunctor);
+
+ SignalData greenData;
+ GestureReceivedFunctor greenFunctor(greenData);
+
+ TapGestureDetector greenDetector = TapGestureDetector::New();
+ greenDetector.Attach(green);
+ greenDetector.DetectedSignal().Connect(&application, greenFunctor);
+
+ // connect to its hit-test signal
+ gHitTestTouchCallBackCalled = false;
+ Dali::DevelActor::HitTestResultSignal(green).Connect(TestHitTestTouchCallback);
+
+ // Emit a down signal
+ application.ProcessEvent(GenerateSingleTouch(PointState::DOWN, Vector2(20.0f, 20.0f), 0, 100));
+ application.ProcessEvent(GenerateSingleTouch(PointState::UP, Vector2(20.0f, 20.0f), 0, 120));
+ application.SendNotification();
+
+ // check hit-test events
+ // The green actor received an event that the green actor was hit.
+ DALI_TEST_EQUALS(true, gHitTestTouchCallBackCalled, TEST_LOCATION);
+
+ // The green actor passed the hit-test. So blue was the final hit.
+ DALI_TEST_EQUALS(false, greenData.functorCalled, TEST_LOCATION);
+ DALI_TEST_EQUALS(true, blueData.functorCalled, TEST_LOCATION);
+
+ blueData.Reset();
+ greenData.Reset();
+
+ END_TEST;
}
\ No newline at end of file
--- /dev/null
+/*
+ * 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.
+ * 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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/actors/actor-devel.h>
+#include <dali/devel-api/common/capabilities.h>
+#include <dali/devel-api/common/stage.h>
+#include <dali/devel-api/rendering/renderer-devel.h>
+#include <dali/integration-api/render-task-list-integ.h>
+#include <dali/public-api/dali-core.h>
+#include <cstdio>
+#include <string>
+
+// INTERNAL INCLUDES
+#include <dali-test-suite-utils.h>
+#include <mesh-builder.h>
+#include <test-trace-call-stack.h>
+#include "test-graphics-command-buffer.h"
+
+using namespace Dali;
+
+void visual_renderer_test_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void visual_renderer_test_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+int UtcDaliVisualRendererNew01(void)
+{
+ TestApplication application;
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = CreateShader();
+ VisualRenderer renderer = VisualRenderer::New(geometry, shader);
+
+ DALI_TEST_EQUALS((bool)renderer, true, TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliVisualRendererNew02(void)
+{
+ TestApplication application;
+ VisualRenderer renderer;
+ DALI_TEST_EQUALS((bool)renderer, false, TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliVisualRendererCopyConstructor(void)
+{
+ TestApplication application;
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = CreateShader();
+ VisualRenderer renderer = VisualRenderer::New(geometry, shader);
+
+ VisualRenderer rendererCopy(renderer);
+ DALI_TEST_EQUALS((bool)rendererCopy, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliVisualRendererAssignmentOperator(void)
+{
+ TestApplication application;
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = CreateShader();
+ VisualRenderer renderer = VisualRenderer::New(geometry, shader);
+
+ VisualRenderer renderer2;
+ DALI_TEST_EQUALS((bool)renderer2, false, TEST_LOCATION);
+
+ renderer2 = renderer;
+ DALI_TEST_EQUALS((bool)renderer2, true, TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliVisualRendererMoveConstructor(void)
+{
+ TestApplication application;
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = Shader::New("vertexSrc", "fragmentSrc");
+ VisualRenderer renderer = VisualRenderer::New(geometry, shader);
+ DALI_TEST_CHECK(renderer);
+ DALI_TEST_EQUALS(1, renderer.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetProperty<Vector3>(VisualRenderer::Property::VISUAL_MIX_COLOR), Vector3::ONE, TEST_LOCATION);
+
+ auto testColor = Vector3(1.0f, 0.0f, 1.0f);
+ renderer.SetProperty(VisualRenderer::Property::VISUAL_MIX_COLOR, testColor);
+ application.SendNotification();
+ application.Render();
+ DALI_TEST_EQUALS(renderer.GetProperty<Vector3>(VisualRenderer::Property::VISUAL_MIX_COLOR), testColor, TEST_LOCATION);
+
+ VisualRenderer move = std::move(renderer);
+ DALI_TEST_CHECK(move);
+ DALI_TEST_EQUALS(1, move.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_EQUALS(move.GetProperty<Vector3>(VisualRenderer::Property::VISUAL_MIX_COLOR), testColor, TEST_LOCATION);
+ DALI_TEST_CHECK(!renderer);
+
+ END_TEST;
+}
+
+int UtcDaliVisualRendererMoveAssignment(void)
+{
+ TestApplication application;
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = Shader::New("vertexSrc", "fragmentSrc");
+ VisualRenderer renderer = VisualRenderer::New(geometry, shader);
+ DALI_TEST_CHECK(renderer);
+ DALI_TEST_EQUALS(1, renderer.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetProperty<Vector3>(VisualRenderer::Property::VISUAL_MIX_COLOR), Vector3::ONE, TEST_LOCATION);
+
+ renderer.SetProperty(VisualRenderer::Property::VISUAL_MIX_COLOR, Vector3(1.0f, 0.0f, 1.0f));
+ application.SendNotification();
+ application.Render();
+ DALI_TEST_EQUALS(renderer.GetProperty<Vector3>(VisualRenderer::Property::VISUAL_MIX_COLOR), Vector3(1.0f, 0.0f, 1.0f), TEST_LOCATION);
+
+ VisualRenderer move;
+ move = std::move(renderer);
+ DALI_TEST_CHECK(move);
+ DALI_TEST_EQUALS(1, move.GetBaseObject().ReferenceCount(), TEST_LOCATION);
+ DALI_TEST_EQUALS(move.GetProperty<Vector3>(VisualRenderer::Property::VISUAL_MIX_COLOR), Vector3(1.0f, 0.0f, 1.0f), TEST_LOCATION);
+ DALI_TEST_CHECK(!renderer);
+
+ END_TEST;
+}
+
+int UtcDaliVisualRendererDownCast01(void)
+{
+ TestApplication application;
+
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = CreateShader();
+ VisualRenderer renderer = VisualRenderer::New(geometry, shader);
+
+ BaseHandle handle(renderer);
+ VisualRenderer renderer2 = VisualRenderer::DownCast(handle);
+ DALI_TEST_EQUALS((bool)renderer2, true, TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliVisualRendererDownCast02(void)
+{
+ TestApplication application;
+
+ Handle handle = Handle::New(); // Create a custom object
+ VisualRenderer renderer = VisualRenderer::DownCast(handle);
+ DALI_TEST_EQUALS((bool)renderer, false, TEST_LOCATION);
+ END_TEST;
+}
+
+// using a template to auto deduce the parameter types
+template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
+void TEST_RENDERER_PROPERTY(P1 renderer, P2 stringName, P3 type, P4 isWriteable, P5 isAnimateable, P6 isConstraintInput, P7 enumName, P8 LOCATION)
+{
+ DALI_TEST_EQUALS(renderer.GetPropertyName(enumName), stringName, LOCATION);
+ DALI_TEST_EQUALS(renderer.GetPropertyIndex(stringName), static_cast<Property::Index>(enumName), LOCATION);
+ DALI_TEST_EQUALS(renderer.GetPropertyType(enumName), type, LOCATION);
+ DALI_TEST_EQUALS(renderer.IsPropertyWritable(enumName), isWriteable, LOCATION);
+ DALI_TEST_EQUALS(renderer.IsPropertyAnimatable(enumName), isAnimateable, LOCATION);
+ DALI_TEST_EQUALS(renderer.IsPropertyAConstraintInput(enumName), isConstraintInput, LOCATION);
+}
+
+int UtcDaliVisualRendererDefaultProperties(void)
+{
+ TestApplication application;
+ Geometry geometry = CreateQuadGeometry();
+ Shader shader = CreateShader();
+ VisualRenderer renderer = VisualRenderer::New(geometry, shader);
+ Renderer baseRenderer = Renderer::New(geometry, shader);
+
+ DALI_TEST_EQUALS(baseRenderer.GetPropertyCount(), 27, TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetPropertyCount(), 27 + 8, TEST_LOCATION);
+
+ TEST_RENDERER_PROPERTY(renderer, "transformOffset", Property::VECTOR2, true, true, true, VisualRenderer::Property::TRANSFORM_OFFSET, TEST_LOCATION);
+ TEST_RENDERER_PROPERTY(renderer, "transformSize", Property::VECTOR2, true, true, true, VisualRenderer::Property::TRANSFORM_SIZE, TEST_LOCATION);
+ TEST_RENDERER_PROPERTY(renderer, "transformOrigin", Property::VECTOR2, true, false, false, VisualRenderer::Property::TRANSFORM_ORIGIN, TEST_LOCATION);
+ TEST_RENDERER_PROPERTY(renderer, "transformAnchorPoint", Property::VECTOR2, true, false, false, VisualRenderer::Property::TRANSFORM_ANCHOR_POINT, TEST_LOCATION);
+ TEST_RENDERER_PROPERTY(renderer, "transformOffsetSizeMode", Property::VECTOR4, true, false, false, VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE, TEST_LOCATION);
+ TEST_RENDERER_PROPERTY(renderer, "extraSize", Property::VECTOR2, true, true, true, VisualRenderer::Property::EXTRA_SIZE, TEST_LOCATION);
+
+ TEST_RENDERER_PROPERTY(renderer, "visualMixColor", Property::VECTOR3, true, true, true, VisualRenderer::Property::VISUAL_MIX_COLOR, TEST_LOCATION);
+ TEST_RENDERER_PROPERTY(renderer, "preMultipliedAlpha", Property::FLOAT, true, false, false, VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliVisualRendererAnimatedProperty01(void)
+{
+ TestApplication application;
+
+ tet_infoline("Test that a visual renderer property can be animated");
+
+ Shader shader = Shader::New("VertexSource", "FragmentSource");
+ Geometry geometry = CreateQuadGeometry();
+ VisualRenderer renderer = VisualRenderer::New(geometry, shader);
+
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+ actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+ application.GetScene().Add(actor);
+
+ Property::Index colorIndex = VisualRenderer::Property::VISUAL_MIX_COLOR;
+ renderer.SetProperty(colorIndex, Vector3(1.0f, 1.0f, 1.0f));
+
+ application.SendNotification();
+ application.Render(0);
+ DALI_TEST_EQUALS(renderer.GetProperty<Vector3>(colorIndex), Vector3(1.0f, 1.0f, 1.0f), 0.001f, TEST_LOCATION);
+
+ Animation animation = Animation::New(1.0f);
+ KeyFrames keyFrames = KeyFrames::New();
+ keyFrames.Add(0.0f, Vector3(1.0f, 0.0f, 1.0f));
+ keyFrames.Add(1.0f, Vector3(0.0f, 0.0f, 0.0f));
+ animation.AnimateBetween(Property(renderer, colorIndex), keyFrames);
+ animation.Play();
+
+ application.SendNotification();
+ application.Render(500);
+
+ DALI_TEST_EQUALS(renderer.GetCurrentProperty<Vector3>(colorIndex), Vector3(0.5f, 0.f, 0.5f), TEST_LOCATION);
+
+ application.Render(400);
+ DALI_TEST_EQUALS(renderer.GetCurrentProperty<Vector3>(colorIndex), Vector3(0.1f, 0.f, 0.1f), TEST_LOCATION);
+
+ application.Render(100);
+ DALI_TEST_EQUALS(renderer.GetCurrentProperty<Vector3>(colorIndex), Vector3(0.f, 0.f, 0.f), TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetProperty<Vector3>(colorIndex), Vector3(0.f, 0.f, 0.f), TEST_LOCATION);
+
+ // Can we test to see if the actor has stopped being drawn?
+ END_TEST;
+}
+
+int UtcDaliVisualRendererAnimatedProperty02(void)
+{
+ TestApplication application;
+
+ tet_infoline("Test that a visual renderer property can be animated");
+
+ Shader shader = Shader::New("VertexSource", "FragmentSource");
+ Geometry geometry = CreateQuadGeometry();
+ VisualRenderer renderer = VisualRenderer::New(geometry, shader);
+
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+ actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+ application.GetScene().Add(actor);
+
+ Property::Index index = VisualRenderer::Property::TRANSFORM_OFFSET;
+ renderer.SetProperty(index, Vector2(1.0f, 0.0f));
+
+ application.SendNotification();
+ application.Render(0);
+ application.SendNotification();
+ application.Render(0);
+ DALI_TEST_EQUALS(renderer.GetProperty<Vector2>(index), Vector2(1.0f, 0.0f), 0.001f, TEST_LOCATION);
+
+ Animation animation = Animation::New(1.0f);
+ KeyFrames keyFrames = KeyFrames::New();
+ keyFrames.Add(0.0f, Vector2(1.0f, 0.0f));
+ keyFrames.Add(1.0f, Vector2(0.0f, 1.0f));
+ animation.AnimateBetween(Property(renderer, index), keyFrames);
+ animation.Play();
+
+ application.SendNotification();
+ application.Render(500);
+
+ DALI_TEST_EQUALS(renderer.GetCurrentProperty<Vector2>(index), Vector2(0.5f, 0.5f), TEST_LOCATION);
+
+ application.Render(400);
+ DALI_TEST_EQUALS(renderer.GetCurrentProperty<Vector2>(index), Vector2(0.1f, 0.9f), TEST_LOCATION);
+
+ application.Render(100);
+ DALI_TEST_EQUALS(renderer.GetCurrentProperty<Vector2>(index), Vector2(0.f, 1.0f), TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetProperty<Vector2>(index), Vector2(0.f, 1.f), TEST_LOCATION);
+
+ END_TEST;
+}
+
+struct VisualProperties
+{
+ VisualProperties() = default;
+
+ VisualProperties(Vector2 offset, Vector2 size, Vector2 origin, Vector2 pivot, Vector4 modes, Vector2 extraSize, Vector3 mixColor)
+ : mTransformOffset(offset),
+ mTransformSize(size),
+ mTransformOrigin(origin),
+ mTransformAnchorPoint(pivot),
+ mTransformOffsetSizeMode(modes),
+ mExtraSize(extraSize),
+ mMixColor(mixColor)
+ {
+ }
+
+ Vector2 mTransformOffset{Vector2::ZERO};
+ Vector2 mTransformSize{Vector2::ZERO};
+ Vector2 mTransformOrigin{Vector2::ZERO};
+ Vector2 mTransformAnchorPoint{Vector2::ZERO};
+ Vector4 mTransformOffsetSizeMode{Vector2::ZERO};
+ Vector2 mExtraSize{Vector2::ZERO};
+ Vector3 mMixColor{Vector3::ONE};
+
+ static VisualProperties GetPropsAt(float alpha, const VisualProperties& start, const VisualProperties& end)
+ {
+ VisualProperties progress;
+ progress.mTransformOffset = start.mTransformOffset + (end.mTransformOffset - start.mTransformOffset) * alpha;
+ progress.mTransformSize = start.mTransformSize + (end.mTransformSize - start.mTransformSize) * alpha;
+ progress.mExtraSize = start.mExtraSize + (end.mExtraSize - start.mExtraSize) * alpha;
+ progress.mMixColor = start.mMixColor + (end.mMixColor - start.mMixColor) * alpha;
+ progress.mTransformOffsetSizeMode = end.mTransformOffsetSizeMode;
+ progress.mTransformOrigin = end.mTransformOrigin;
+ progress.mTransformAnchorPoint = end.mTransformAnchorPoint;
+ return progress;
+ }
+};
+
+void PrintVisualProperties(const VisualProperties& props, const std::string& prefix)
+{
+ tet_printf(
+ "%s: offset:(%5.3f, %5.3f)\n"
+ "%*c size:(%5.3f, %5.3f)\n"
+ "%*c origin:(%5.3f, %5.3f)\n"
+ "%*c anchorPoint:(%5.3f, %5.3f)\n"
+ "%*c offsetSizeMode:(%5.3f, %5.3f, %5.3f, %5.3f)\n"
+ "%*c extraSize:(%5.3f, %5.3f)\n"
+ "%*c mixColor:(%5.3f, %5.3f, %5.3f, %5.3f)\n",
+ prefix.c_str(),
+ props.mTransformOffset.x,
+ props.mTransformOffset.y,
+ prefix.length(),
+ ' ',
+ props.mTransformSize.x,
+ props.mTransformSize.y,
+ prefix.length(),
+ ' ',
+ props.mTransformOrigin.x,
+ props.mTransformOrigin.y,
+ prefix.length(),
+ ' ',
+ props.mTransformAnchorPoint.x,
+ props.mTransformAnchorPoint.y,
+ prefix.length(),
+ ' ',
+ props.mTransformOffsetSizeMode.x,
+ props.mTransformOffsetSizeMode.y,
+ props.mTransformOffsetSizeMode.z,
+ props.mTransformOffsetSizeMode.w,
+ prefix.length(),
+ ' ',
+ props.mExtraSize.x,
+ props.mExtraSize.y,
+ prefix.length(),
+ ' ',
+ props.mMixColor.x,
+ props.mMixColor.y,
+ props.mMixColor.z);
+}
+
+void SetVisualProperties(VisualRenderer renderer, VisualProperties props)
+{
+ renderer.SetProperty(VisualRenderer::Property::TRANSFORM_OFFSET, props.mTransformOffset);
+ renderer.SetProperty(VisualRenderer::Property::TRANSFORM_SIZE, props.mTransformSize);
+ renderer.SetProperty(VisualRenderer::Property::TRANSFORM_ORIGIN, props.mTransformOrigin);
+ renderer.SetProperty(VisualRenderer::Property::TRANSFORM_ANCHOR_POINT, props.mTransformAnchorPoint);
+ renderer.SetProperty(VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE, props.mTransformOffsetSizeMode);
+ renderer.SetProperty(VisualRenderer::Property::EXTRA_SIZE, props.mExtraSize);
+ renderer.SetProperty(VisualRenderer::Property::VISUAL_MIX_COLOR, props.mMixColor);
+}
+
+void CheckEventVisualProperties(VisualRenderer renderer, VisualProperties expectedProps)
+{
+ tet_infoline("CheckEventVisualProperties\n");
+
+ VisualProperties actualProps;
+ actualProps.mTransformOffset = renderer.GetProperty<Vector2>(VisualRenderer::Property::TRANSFORM_OFFSET);
+ actualProps.mTransformSize = renderer.GetProperty<Vector2>(VisualRenderer::Property::TRANSFORM_SIZE);
+ actualProps.mTransformOrigin = renderer.GetProperty<Vector2>(VisualRenderer::Property::TRANSFORM_ORIGIN);
+ actualProps.mTransformAnchorPoint = renderer.GetProperty<Vector2>(VisualRenderer::Property::TRANSFORM_ANCHOR_POINT);
+ actualProps.mTransformOffsetSizeMode = renderer.GetProperty<Vector4>(VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE);
+ actualProps.mExtraSize = renderer.GetProperty<Vector2>(VisualRenderer::Property::EXTRA_SIZE);
+ actualProps.mMixColor = renderer.GetProperty<Vector3>(VisualRenderer::Property::VISUAL_MIX_COLOR);
+
+ PrintVisualProperties(actualProps, "Actual event props");
+
+ DALI_TEST_EQUALS(actualProps.mTransformOffset, expectedProps.mTransformOffset, TEST_LOCATION);
+ DALI_TEST_EQUALS(actualProps.mTransformSize, expectedProps.mTransformSize, TEST_LOCATION);
+ DALI_TEST_EQUALS(actualProps.mTransformOrigin, expectedProps.mTransformOrigin, TEST_LOCATION);
+ DALI_TEST_EQUALS(actualProps.mTransformAnchorPoint, expectedProps.mTransformAnchorPoint, TEST_LOCATION);
+ DALI_TEST_EQUALS(actualProps.mTransformOffsetSizeMode, expectedProps.mTransformOffsetSizeMode, TEST_LOCATION);
+ DALI_TEST_EQUALS(actualProps.mExtraSize, expectedProps.mExtraSize, TEST_LOCATION);
+ DALI_TEST_EQUALS(actualProps.mMixColor, expectedProps.mMixColor, TEST_LOCATION);
+}
+
+void CheckSceneGraphVisualProperties(VisualRenderer renderer, VisualProperties expectedProps)
+{
+ tet_infoline("CheckSceneGraphVisualProperties\n");
+
+ VisualProperties actualProps;
+
+ actualProps.mTransformOffset = renderer.GetCurrentProperty<Vector2>(VisualRenderer::Property::TRANSFORM_OFFSET);
+ actualProps.mTransformSize = renderer.GetCurrentProperty<Vector2>(VisualRenderer::Property::TRANSFORM_SIZE);
+ actualProps.mTransformOrigin = renderer.GetCurrentProperty<Vector2>(VisualRenderer::Property::TRANSFORM_ORIGIN);
+ actualProps.mTransformAnchorPoint = renderer.GetCurrentProperty<Vector2>(VisualRenderer::Property::TRANSFORM_ANCHOR_POINT);
+ actualProps.mTransformOffsetSizeMode = renderer.GetCurrentProperty<Vector4>(VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE);
+ actualProps.mExtraSize = renderer.GetCurrentProperty<Vector2>(VisualRenderer::Property::EXTRA_SIZE);
+ actualProps.mMixColor = renderer.GetCurrentProperty<Vector3>(VisualRenderer::Property::VISUAL_MIX_COLOR);
+
+ PrintVisualProperties(actualProps, "Actual update props");
+
+ DALI_TEST_EQUALS(actualProps.mTransformOffset, expectedProps.mTransformOffset, TEST_LOCATION);
+ DALI_TEST_EQUALS(actualProps.mTransformSize, expectedProps.mTransformSize, TEST_LOCATION);
+ DALI_TEST_EQUALS(actualProps.mTransformOrigin, expectedProps.mTransformOrigin, TEST_LOCATION);
+ DALI_TEST_EQUALS(actualProps.mTransformAnchorPoint, expectedProps.mTransformAnchorPoint, TEST_LOCATION);
+ DALI_TEST_EQUALS(actualProps.mTransformOffsetSizeMode, expectedProps.mTransformOffsetSizeMode, TEST_LOCATION);
+ DALI_TEST_EQUALS(actualProps.mExtraSize, expectedProps.mExtraSize, TEST_LOCATION);
+ DALI_TEST_EQUALS(actualProps.mMixColor, expectedProps.mMixColor, TEST_LOCATION);
+}
+
+void CheckUniforms(VisualRenderer renderer, VisualProperties props, std::vector<UniformData>& uniforms, TraceCallStack& callStack, TestGlAbstraction& gl)
+{
+ tet_infoline("CheckUniforms\n");
+
+ TraceCallStack::NamedParams params;
+
+ tet_printf("Callback trace: \n%s\n", callStack.GetTraceString().c_str());
+
+ DALI_TEST_CHECK(callStack.FindMethodAndGetParameters(uniforms[0].name, params));
+ DALI_TEST_CHECK(gl.GetUniformValue<Vector2>(uniforms[0].name.c_str(), props.mTransformOffset));
+
+ DALI_TEST_CHECK(callStack.FindMethodAndGetParameters(uniforms[1].name, params));
+ DALI_TEST_CHECK(gl.GetUniformValue<Vector2>(uniforms[1].name.c_str(), props.mTransformSize));
+
+ DALI_TEST_CHECK(callStack.FindMethodAndGetParameters(uniforms[2].name, params));
+ DALI_TEST_CHECK(gl.GetUniformValue<Vector2>(uniforms[2].name.c_str(), props.mTransformOrigin));
+
+ DALI_TEST_CHECK(callStack.FindMethodAndGetParameters(uniforms[3].name, params));
+ DALI_TEST_CHECK(gl.GetUniformValue<Vector2>(uniforms[3].name.c_str(), props.mTransformAnchorPoint));
+
+ DALI_TEST_CHECK(callStack.FindMethodAndGetParameters(uniforms[4].name, params));
+ DALI_TEST_CHECK(gl.GetUniformValue<Vector4>(uniforms[4].name.c_str(), props.mTransformOffsetSizeMode));
+
+ DALI_TEST_CHECK(callStack.FindMethodAndGetParameters(uniforms[5].name, params));
+ DALI_TEST_CHECK(gl.GetUniformValue<Vector2>(uniforms[5].name.c_str(), props.mExtraSize));
+
+ DALI_TEST_CHECK(callStack.FindMethodAndGetParameters(uniforms[6].name, params));
+ DALI_TEST_CHECK(gl.GetUniformValue<Vector3>(uniforms[6].name.c_str(), props.mMixColor));
+}
+
+int UtcDaliVisualRendererAnimatedProperty03(void)
+{
+ TestApplication application;
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& callStack = gl.GetSetUniformTrace();
+ gl.EnableSetUniformCallTrace(true);
+
+ tet_infoline("Test that a visual renderer property can be animated and that the uniforms are set");
+
+ std::vector<UniformData> customUniforms{{"offset", Property::VECTOR2},
+ {"size", Property::VECTOR2},
+ {"origin", Property::VECTOR2},
+ {"anchorPoint", Property::VECTOR2},
+ {"offsetSizeMode", Property::VECTOR4},
+ {"extraSize", Property::VECTOR2},
+ {"mixColor", Property::VECTOR3}};
+
+ application.GetGraphicsController().AddCustomUniforms(customUniforms);
+
+ Shader shader = Shader::New("VertexSource", "FragmentSource");
+ Geometry geometry = CreateQuadGeometry();
+ VisualRenderer renderer = VisualRenderer::New(geometry, shader);
+
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+ actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+ application.GetScene().Add(actor);
+
+ VisualProperties props{Vector2(10.f, 10.f), Vector2(200.f, 100.f), Vector2(0.5f, 0.5f), Vector2(0.5f, 0.5f), Vector4::ZERO, Vector2(0.0f, 0.0f), Vector3(Color::SEA_GREEN)};
+ VisualProperties targetProps{Vector2(40.f, 40.f), Vector2(100.f, 200.f), Vector2(0.5f, 0.5f), Vector2(0.5f, 0.5f), Vector4::ZERO, Vector2(25.0f, 25.0f), Vector3(Color::MEDIUM_PURPLE)};
+
+ SetVisualProperties(renderer, props);
+ CheckEventVisualProperties(renderer, props);
+ application.SendNotification();
+ application.Render(0);
+ CheckSceneGraphVisualProperties(renderer, props);
+ CheckUniforms(renderer, props, customUniforms, callStack, gl);
+
+ // Set up a 1 second anim.
+ Animation animation = Animation::New(1.0f);
+
+ animation.AnimateTo(Property(renderer, VisualRenderer::Property::TRANSFORM_OFFSET), targetProps.mTransformOffset);
+ animation.AnimateTo(Property(renderer, VisualRenderer::Property::TRANSFORM_SIZE), targetProps.mTransformSize);
+ animation.AnimateTo(Property(renderer, VisualRenderer::Property::EXTRA_SIZE), targetProps.mExtraSize);
+ animation.AnimateTo(Property(renderer, VisualRenderer::Property::VISUAL_MIX_COLOR), targetProps.mMixColor);
+ animation.Play();
+
+ CheckEventVisualProperties(renderer, targetProps);
+
+ for(int i = 0; i <= 10; ++i)
+ {
+ tet_printf("\n########### Animation progress: %d%%\n\n", i * 10);
+ VisualProperties propsProgress = VisualProperties::GetPropsAt(0.1f * i, props, targetProps);
+ PrintVisualProperties(propsProgress, "Expected values");
+
+ callStack.Reset();
+ application.SendNotification();
+ application.Render((i == 0 ? 0 : 100));
+
+ CheckEventVisualProperties(renderer, targetProps);
+
+ CheckSceneGraphVisualProperties(renderer, propsProgress);
+ CheckUniforms(renderer, propsProgress, customUniforms, callStack, gl);
+ }
+
+ // Ensure animation finishes
+ application.SendNotification();
+ application.Render(100);
+ CheckSceneGraphVisualProperties(renderer, targetProps);
+ CheckUniforms(renderer, targetProps, customUniforms, callStack, gl);
+
+ END_TEST;
+}
+
+int UtcDaliVisualRendererAnimatedProperty04(void)
+{
+ TestApplication application;
+
+ tet_infoline("Test that a visual renderer property can't be animated");
+
+ Shader shader = Shader::New("VertexSource", "FragmentSource");
+ Geometry geometry = CreateQuadGeometry();
+ VisualRenderer renderer = VisualRenderer::New(geometry, shader);
+
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+ actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+ application.GetScene().Add(actor);
+
+ Property::Index index = VisualRenderer::Property::TRANSFORM_ANCHOR_POINT;
+ renderer.SetProperty(index, Vector2(AnchorPoint::TOP_RIGHT));
+
+ application.SendNotification();
+ application.Render(0);
+ DALI_TEST_EQUALS(renderer.GetProperty<Vector2>(index), Vector2(AnchorPoint::TOP_RIGHT), 0.001f, TEST_LOCATION);
+
+ Animation animation = Animation::New(1.0f);
+ KeyFrames keyFrames = KeyFrames::New();
+ keyFrames.Add(0.0f, Vector2::ZERO);
+ keyFrames.Add(1.0f, Vector2(10.0f, 10.0f));
+ try
+ {
+ animation.AnimateBetween(Property(renderer, index), keyFrames);
+ tet_result(TET_FAIL);
+ }
+ catch(DaliException& e)
+ {
+ DALI_TEST_ASSERT(e, "baseProperty && \"Property is not animatable\"", TEST_LOCATION);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliVisualRendererAnimatedProperty05(void)
+{
+ TestApplication application;
+
+ tet_infoline("Test that a visual renderer property can't be animated");
+
+ Shader shader = Shader::New("VertexSource", "FragmentSource");
+ Geometry geometry = CreateQuadGeometry();
+ VisualRenderer renderer = VisualRenderer::New(geometry, shader);
+
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+ actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+ application.GetScene().Add(actor);
+
+ Property::Index index = VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA;
+ renderer.SetProperty(index, 1.0f);
+
+ application.SendNotification();
+ application.Render(0);
+ DALI_TEST_EQUALS(renderer.GetProperty<float>(index), 1.0f, 0.001f, TEST_LOCATION);
+
+ Animation animation = Animation::New(1.0f);
+ KeyFrames keyFrames = KeyFrames::New();
+ keyFrames.Add(0.0f, 0.5f);
+ keyFrames.Add(1.0f, 1.0f);
+ try
+ {
+ animation.AnimateBetween(Property(renderer, index), keyFrames);
+ tet_result(TET_FAIL);
+ }
+ catch(DaliException& e)
+ {
+ DALI_TEST_ASSERT(e, "baseProperty && \"Property is not animatable\"", TEST_LOCATION);
+ }
+
+ DALI_TEST_EQUALS(renderer.GetProperty<float>(index), 1.0f, 0.0001f, TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetCurrentProperty<float>(index), 1.0f, 0.0001f, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliVisualRendererAnimatedProperty06(void)
+{
+ TestApplication application;
+
+ tet_infoline("Test that a parent renderer property can still be animated");
+
+ Shader shader = Shader::New("VertexSource", "FragmentSource");
+ Geometry geometry = CreateQuadGeometry();
+ VisualRenderer renderer = VisualRenderer::New(geometry, shader);
+
+ Actor actor = Actor::New();
+ actor.AddRenderer(renderer);
+ actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+ application.GetScene().Add(actor);
+
+ Property::Index index = DevelRenderer::Property::OPACITY;
+ renderer.SetProperty(index, 1.0f);
+
+ application.SendNotification();
+ application.Render(0);
+ DALI_TEST_EQUALS(renderer.GetProperty<float>(index), 1.0f, 0.001f, TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetCurrentProperty<float>(DevelRenderer::Property::OPACITY), 1.0f, 0.0001f, TEST_LOCATION);
+
+ Animation animation = Animation::New(1.0f);
+ KeyFrames keyFrames = KeyFrames::New();
+ keyFrames.Add(0.0f, float(0.5f));
+ keyFrames.Add(1.0f, float(0.0f));
+ animation.AnimateBetween(Property(renderer, index), keyFrames);
+ animation.Play();
+
+ application.SendNotification();
+
+ // Test that the event side properties are set to target value of 0
+ DALI_TEST_EQUALS(renderer.GetProperty<float>(DevelRenderer::Property::OPACITY), 0.0f, 0.0001f, TEST_LOCATION);
+
+ application.Render(500);
+
+ DALI_TEST_EQUALS(renderer.GetCurrentProperty<float>(index), 0.25f, 0.0001f, TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetCurrentProperty<float>(DevelRenderer::Property::OPACITY), 0.25f, 0.0001f, TEST_LOCATION);
+
+ // Test that the event side properties are set to target value 0f 0
+ DALI_TEST_EQUALS(renderer.GetProperty<float>(DevelRenderer::Property::OPACITY), 0.0f, 0.0001f, TEST_LOCATION);
+
+ // Complete the animation
+ application.Render(500);
+
+ DALI_TEST_EQUALS(renderer.GetCurrentProperty<float>(index), 0.0f, 0.0001f, TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetCurrentProperty<float>(DevelRenderer::Property::OPACITY), 0.0f, 0.0001f, TEST_LOCATION);
+ DALI_TEST_EQUALS(renderer.GetProperty<float>(DevelRenderer::Property::OPACITY), 0.0f, 0.0001f, TEST_LOCATION);
+ END_TEST;
+}
/*
- * 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.
return GetImplementation(actor).SwitchParent(GetImplementation(newParent));
}
+Actor::TouchEventSignalType& HitTestResultSignal(Actor actor)
+{
+ return GetImplementation(actor).HitTestResultSignal();
+}
+
} // namespace DevelActor
} // namespace Dali
#define DALI_ACTOR_DEVEL_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.
*/
DALI_CORE_API void SwitchParent(Actor actor, Actor newParent);
+/**
+ * @brief This signal is emitted when an actor is hit through hit-test.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ * void MyCallbackName( Actor actor );
+ * @endcode
+ * actor The actor to intercept
+ *
+ * @note This callback is called when the actor is hit.
+ * If true is returned, TouchEvent is called from the this actor.
+ * If false is returned, the hit test starts again from the next lower actor.
+ *
+ * @note example
+ * Actor topActor = Actor::New();
+ * Actor bottomActor = Actor::New();
+ * topActor.TouchedSignal().Connect(&application, topActorFunctor);
+ * bottomActor.TouchedSignal().Connect(&application, bottomActorFunctor);
+ * The two actors have no relationship.
+ * So when the topActor is touched, the event cannot be propagated to the bottomActor.
+ *
+ * If you connect HitTestResultSignal to topActor.
+ * Dali::DevelActor::HitTestResultSignal(topActor).Connect(&application, hitTestResultFunctor);
+ *
+ * If the hitTestResult Functor returns false, it passes the hit-test and starts the hit-test again from the next lower actor.
+ * So the bottomActor can be hit and receive touch events.
+ * If hitTestResult returns true, it means that it has been hit. So it receives a TouchEvent from itself.
+ *
+ * @return The signal to connect to
+ * @pre The Actor has been initialized
+ */
+DALI_CORE_API Actor::TouchEventSignalType& HitTestResultSignal(Actor actor);
+
} // namespace DevelActor
} // namespace Dali
/*
- * 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.
#include <dali/devel-api/common/capabilities.h>
#include <dali/integration-api/debug.h>
+#include <dali/integration-api/events/touch-integ.h>
#include <dali/internal/event/actors/actor-coords.h>
#include <dali/internal/event/actors/actor-parent.h>
EmitSignal(*this, mLayoutDirectionChangedSignal, type);
}
+bool Actor::EmitHitTestResultSignal(Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp)
+{
+ bool hit = true;
+
+ if(IsHitTestResultRequired())
+ {
+ Dali::Actor handle(this);
+ Integration::Point newPoint(point);
+ newPoint.SetHitActor(handle);
+ newPoint.SetLocalPosition(hitPointLocal);
+ Dali::TouchEvent touchEvent = Dali::Integration::NewTouchEvent(timeStamp, newPoint);
+ hit = mHitTestResultSignal.Emit(handle, touchEvent);
+ }
+ return hit;
+}
+
DevelActor::ChildChangedSignalType& Actor::ChildAddedSignal()
{
return mParentImpl.ChildAddedSignal();
mOnRelayoutSignal(),
mVisibilityChangedSignal(),
mLayoutDirectionChangedSignal(),
+ mHitTestResultSignal(),
mTargetOrientation(Quaternion::IDENTITY),
mTargetColor(Color::WHITE),
mTargetPosition(Vector3::ZERO),
#define DALI_INTERNAL_ACTOR_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.
#include <dali/devel-api/actors/actor-devel.h>
#include <dali/devel-api/rendering/renderer-devel.h>
+#include <dali/integration-api/events/touch-event-integ.h>
+
#include <dali/internal/common/const-string.h>
#include <dali/internal/common/internal-constants.h>
#include <dali/internal/common/memory-pool-object-allocator.h>
}
/**
+ * Query whether the application or derived actor type requires hit-test result events.
+ * @return True if hit-test result events are required.
+ */
+ bool IsHitTestResultRequired() const
+ {
+ return !mHitTestResultSignal.Empty();
+ }
+
+ /**
* Query whether the application or derived actor type requires intercept touch events.
* @return True if intercept touch events are required.
*/
void EmitLayoutDirectionChangedSignal(LayoutDirection::Type type);
/**
+ * Used by the EventProcessor to emit hit-test result touch event signals.
+ * @param[in] point The point of event touched.
+ * @param[in] hitPointLocal The hit point in the Actor's local reference system.
+ * @param[in] timeStamp The time the event occurred.
+ * @return True if the event was consumed.
+ */
+ bool EmitHitTestResultSignal(Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp);
+
+ /**
+ * @copydoc DevelActor::HitTestResultSignal()
+ */
+ Dali::Actor::TouchEventSignalType& HitTestResultSignal()
+ {
+ return mHitTestResultSignal;
+ }
+
+ /**
* @copydoc DevelActor::InterceptTouchedSignal()
*/
Dali::Actor::TouchEventSignalType& InterceptTouchedSignal()
Dali::Actor::OnRelayoutSignalType mOnRelayoutSignal;
DevelActor::VisibilityChangedSignalType mVisibilityChangedSignal;
Dali::Actor::LayoutDirectionChangedSignalType mLayoutDirectionChangedSignal;
+ Dali::Actor::TouchEventSignalType mHitTestResultSignal;
Quaternion mTargetOrientation; ///< Event-side storage for orientation
Vector4 mTargetColor; ///< Event-side storage for color
/*
- * 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.
return layer->IsTouchConsumed();
}
+ bool ActorRequiresHitResultCheck(Actor* actor, Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp) override
+ {
+ return actor->EmitHitTestResultSignal(point, hitPointLocal, timeStamp);
+ }
+
GestureType::Value mType;
};
mNeedsUpdate(false),
mType(type),
mCurrentGesturedActor(nullptr),
+ mPoint(),
+ mEventTime(0u),
mGesturedActorDisconnected(false)
{
}
{
if(mGestureRecognizer)
{
+ if(!event.points.empty())
+ {
+ mPoint = event.points[0];
+ mEventTime = event.time;
+ }
mGestureRecognizer->SendEvent(scene, event);
}
}
bool GestureProcessor::HitTest(Scene& scene, Vector2 screenCoordinates, HitTestAlgorithm::Results& hitTestResults)
{
GestureHitTestCheck hitCheck(mType);
+ hitTestResults.point = mPoint;
+ hitTestResults.eventTime = mEventTime;
HitTestAlgorithm::HitTest(scene.GetSize(), scene.GetRenderTaskList(), scene.GetLayerList(), screenCoordinates, hitTestResults, hitCheck);
return hitTestResults.renderTask && hitTestResults.actor;
}
private: // Data
GestureType::Value mType; ///< Type of GestureProcessor
Actor* mCurrentGesturedActor; ///< The current actor that has been gestured.
+ Integration::Point mPoint; ///< The point of event touched.
+ uint32_t mEventTime; ///< The time the event occurred.
bool mGesturedActorDisconnected : 1; ///< Indicates whether the gestured actor has been disconnected from the scene
};
/*
- * 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.
return false;
}
+ bool ActorRequiresHitResultCheck(Actor* actor, Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp) override
+ {
+ return actor->EmitHitTestResultSignal(point, hitPointLocal, timeStamp);
+ }
+
Dali::HitTestAlgorithm::HitTestFunction mFunc;
};
{
return layer->IsTouchConsumed();
}
+
+ bool ActorRequiresHitResultCheck(Actor* actor, Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp) override
+ {
+ return actor->EmitHitTestResultSignal(point, hitPointLocal, timeStamp);
+ }
};
/**
bool layerIs3d,
uint32_t clippingDepth,
uint32_t clippingBitPlaneMask,
- const RayTest& rayTest)
+ const RayTest& rayTest,
+ const Integration::Point& point,
+ const uint32_t eventTime)
{
HitActor hit;
}
}
- if(haveHitActor)
+ // If the hit actor does not want to hit, the hit-test continues.
+ if(haveHitActor && hitCheck.ActorRequiresHitResultCheck(&actor, point, hitPointLocal, eventTime))
{
hit.actor = &actor;
hit.hitPosition = hitPointLocal;
layerIs3d,
newClippingDepth,
clippingBitPlaneMask,
- rayTest));
+ rayTest,
+ point,
+ eventTime));
// Make sure the set hit actor is actually hittable. This is usually required when we have some
// clipping as we need to hit-test all actors as we descend the tree regardless of whether they
// are hittable or not.
- if(currentHit.actor && !hitCheck.IsActorHittable(currentHit.actor))
+ if(currentHit.actor && (!hitCheck.IsActorHittable(currentHit.actor)))
{
continue;
}
layer->GetBehavior() == Dali::Layer::LAYER_3D,
0u,
0u,
- rayTest);
+ rayTest,
+ results.point,
+ results.eventTime);
}
else if(IsWithinSourceActors(*sourceActor, *layer))
{
layer->GetBehavior() == Dali::Layer::LAYER_3D,
0u,
0u,
- rayTest);
+ rayTest,
+ results.point,
+ results.eventTime);
}
// If this layer is set to consume the hit, then do not check any layers behind it
// Skip to next task
continue;
}
-
if(HitTestRenderTask(exclusives, sceneSize, layers, renderTask, screenCoordinates, results, hitCheck, rayTest))
{
// Return true when an actor is hit (or layer in our render-task consumes the hit)
#define DALI_INTERNAL_HIT_TEST_ALGORITHM_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.
// INTERNAL INCLUDES
#include <dali/devel-api/events/hit-test-algorithm.h>
+#include <dali/integration-api/events/touch-event-integ.h>
#include <dali/internal/event/render-tasks/render-task-impl.h>
#include <dali/public-api/actors/actor.h>
{
struct Results
{
- RenderTaskPtr renderTask; ///< The render-task displaying the actor.
- Dali::Actor actor; ///< The hit actor.
- Vector2 actorCoordinates; ///< The actor coordinates.
- Vector4 rayOrigin; ///< The point of origin of the ray.
- Vector4 rayDirection; ///< The direction vector of the ray.
+ RenderTaskPtr renderTask; ///< The render-task displaying the actor.
+ Dali::Actor actor; ///< The hit actor.
+ Vector2 actorCoordinates; ///< The actor coordinates.
+ Vector4 rayOrigin; ///< The point of origin of the ray.
+ Vector4 rayDirection; ///< The direction vector of the ray.
+ Integration::Point point; ///< The point of event touched.
+ uint32_t eventTime; ///< The time the event occurred.
};
/**
*/
virtual bool DoesLayerConsumeHit(Layer* layer) = 0;
+ /**
+ * Called by the hit-test algorithm to determine whether the actor will be hit or not.
+ *
+ * @note If true is returned, then this actor will be hit.
+ * If false is returend, then this actor passes the hit-test and the next actor performs the hit-test.
+ *
+ * @param[in] actor The hit actor.
+ * @param[in] point The point of event touched.
+ * @param[in] hitPointLocal The hit point in the Actor's local reference system.
+ * @param[in] timeStamp The time the event occurred.
+ *
+ * @return true if the actor should be the hit, false otherwise.
+ */
+ virtual bool ActorRequiresHitResultCheck(Actor* actor, Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp) = 0;
+
protected:
/**
* Virtual destructor, no deletion through this interface
/*
- * 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.
{
return layer->IsHoverConsumed();
}
+
+ bool ActorRequiresHitResultCheck(Actor* actor, Integration::Point point, Vector2 hitPointLocal, uint32_t timeStamp) override
+ {
+ // Hover event is always hit.
+ return true;
+ }
};
} // unnamed namespace
for(auto&& currentPoint : event.points)
{
HitTestAlgorithm::Results hitTestResults;
+ hitTestResults.point = currentPoint;
+ hitTestResults.eventTime = event.time;
if(!firstPointParsed)
{
firstPointParsed = true;
/*
- * 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.
return GetSceneObjectAnimatableProperty(index);
}
+void Renderer::AddDrawCommand(const Dali::DevelRenderer::DrawCommand& command)
+{
+ if(!mDrawCommands.capacity())
+ {
+ mDrawCommands.reserve(8);
+ }
+
+ mDrawCommands.emplace_back(command);
+
+ Dali::Internal::SceneGraph::SetDrawCommandsMessage(GetEventThreadServices(),
+ GetRendererSceneObject(),
+ mDrawCommands.data(),
+ uint32_t(mDrawCommands.size())
+
+ );
+}
+
Renderer::Renderer(const SceneGraph::Renderer* sceneObject)
: Object(sceneObject),
mDepthIndex(0),
{
}
-void Renderer::SetBlendColor(const Vector4& blendColor)
-{
- mBlendingOptions.SetBlendColor(blendColor);
- SetBlendColorMessage(GetEventThreadServices(), GetRendererSceneObject(), GetBlendColor());
-}
-
-const Vector4& Renderer::GetBlendColor() const
-{
- const Vector4* blendColor = mBlendingOptions.GetBlendColor();
- if(blendColor)
- {
- return *blendColor;
- }
- return Color::TRANSPARENT; // GL default
-}
-
Renderer::~Renderer()
{
if(EventThreadServices::IsCoreRunning())
return valueSet;
}
-void Renderer::AddDrawCommand(const Dali::DevelRenderer::DrawCommand& command)
+void Renderer::SetBlendColor(const Vector4& blendColor)
{
- if(!mDrawCommands.capacity())
+ mBlendingOptions.SetBlendColor(blendColor);
+ SetBlendColorMessage(GetEventThreadServices(), GetRendererSceneObject(), GetBlendColor());
+}
+
+const Vector4& Renderer::GetBlendColor() const
+{
+ const Vector4* blendColor = mBlendingOptions.GetBlendColor();
+ if(blendColor)
{
- mDrawCommands.reserve(8);
+ return *blendColor;
}
-
- mDrawCommands.emplace_back(command);
-
- Dali::Internal::SceneGraph::SetDrawCommandsMessage(GetEventThreadServices(),
- GetRendererSceneObject(),
- mDrawCommands.data(),
- uint32_t(mDrawCommands.size())
-
- );
+ return Color::TRANSPARENT; // GL default
}
} // namespace Internal
#define DALI_INTERNAL_RENDERER_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.
*/
void AddDrawCommand(const Dali::DevelRenderer::DrawCommand& command);
-private: // implementation
+protected: // implementation
/**
* @brief Constructor.
*
Renderer(const SceneGraph::Renderer* sceneObject);
/**
- * @brief Sets the blend color.
- * @param[in] blendColor The blend color to set.
+ * A reference counted object may only be deleted by calling Unreference()
*/
- void SetBlendColor(const Vector4& blendColor);
+ ~Renderer() override;
- /**
- * @brief Retrieves the blend-color.
- * @return A const reference to the blend-color
- */
- const Vector4& GetBlendColor() const;
+private:
+ Renderer(const Renderer&) = delete; ///< Deleted copy constructor
+ Renderer& operator=(const Renderer&) = delete; ///< Deleted assignment operator
/**
* @brief Retrieves the cached event side value of a default property.
*/
bool GetCurrentPropertyValue(Property::Index index, Property::Value& value) const;
-protected:
/**
- * A reference counted object may only be deleted by calling Unreference()
+ * @brief Sets the blend color.
+ * @param[in] blendColor The blend color to set.
*/
- ~Renderer() override;
+ void SetBlendColor(const Vector4& blendColor);
-private: // unimplemented methods
- Renderer(const Renderer&);
- Renderer& operator=(const Renderer&);
+ /**
+ * @brief Retrieves the blend-color.
+ * @return A const reference to the blend-color
+ */
+ const Vector4& GetBlendColor() const;
-private: // data
+protected:
GeometryPtr mGeometry; ///< Intrusive pointer to the geometry used by this renderer
TextureSetPtr mTextureSet; ///< Intrusive pointer to the texture set used by this renderer
ShaderPtr mShader; ///< Intrusive pointer to the shader used by this renderer
DevelRenderer::Rendering::Type mRenderingBehavior : 2; ///< The rendering behavior
bool mPremultipledAlphaEnabled : 1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
+private:
std::vector<Dali::DevelRenderer::DrawCommand> mDrawCommands; ///< list of draw commands
};
--- /dev/null
+/*
+ * 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.
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/event/rendering/visual-renderer-impl.h>
+
+// INTERNAL INCLUDES
+#include <dali/devel-api/rendering/renderer-devel.h>
+#include <dali/devel-api/scripting/scripting.h>
+#include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
+#include <dali/internal/event/common/property-input-impl.h>
+#include <dali/internal/update/manager/update-manager.h>
+#include <dali/internal/update/rendering/scene-graph-renderer.h>
+#include <dali/public-api/object/type-registry.h>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace
+{
+/**
+ * Properties: |name |type |writable|animatable|constraint-input|enum for index-checking|
+ */
+DALI_PROPERTY_TABLE_BEGIN
+DALI_PROPERTY("transformOffset", VECTOR2, true, true, true, Dali::VisualRenderer::Property::TRANSFORM_OFFSET)
+DALI_PROPERTY("transformSize", VECTOR2, true, true, true, Dali::VisualRenderer::Property::TRANSFORM_SIZE)
+DALI_PROPERTY("transformOrigin", VECTOR2, true, false, false, Dali::VisualRenderer::Property::TRANSFORM_ORIGIN)
+DALI_PROPERTY("transformAnchorPoint", VECTOR2, true, false, false, Dali::VisualRenderer::Property::TRANSFORM_ANCHOR_POINT)
+DALI_PROPERTY("transformOffsetSizeMode", VECTOR4, true, false, false, Dali::VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE)
+DALI_PROPERTY("extraSize", VECTOR2, true, true, true, Dali::VisualRenderer::Property::EXTRA_SIZE)
+DALI_PROPERTY("visualMixColor", VECTOR3, true, true, true, Dali::VisualRenderer::Property::VISUAL_MIX_COLOR)
+DALI_PROPERTY("preMultipliedAlpha", FLOAT, true, false, false, Dali::VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA)
+DALI_PROPERTY_TABLE_END(Dali::VisualRenderer::Property::DEFAULT_VISUAL_RENDERER_PROPERTY_START_INDEX, VisualRendererDefaultProperties)
+
+// Property string to enumeration tables:
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN(TRANSFORM_POLICY)
+ DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::VisualRenderer::TransformPolicy::Type, RELATIVE)
+ DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::VisualRenderer::TransformPolicy::Type, ABSOLUTE)
+DALI_ENUM_TO_STRING_TABLE_END(TRANSFORM_POLICY)
+
+BaseHandle Create()
+{
+ return Dali::BaseHandle();
+}
+
+TypeRegistration mType(typeid(Dali::VisualRenderer), typeid(Dali::Renderer), Create, VisualRendererDefaultProperties);
+
+} // unnamed namespace
+
+VisualRendererPtr VisualRenderer::New()
+{
+ // create scene object first so it's guaranteed to exist for the event side
+ auto sceneObject = SceneGraph::Renderer::New();
+
+ sceneObject->SetVisualProperties(new AnimatableVisualProperties());
+
+ OwnerPointer<SceneGraph::Renderer> transferOwnership(sceneObject);
+ // pass the pointer to base for message passing
+ VisualRendererPtr rendererPtr(new VisualRenderer(sceneObject));
+
+ rendererPtr->AddUniformMappings(); // Ensure properties are mapped to uniforms
+
+ // transfer scene object ownership to update manager
+ EventThreadServices& eventThreadServices = rendererPtr->GetEventThreadServices();
+ SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
+ AddRendererMessage(updateManager, transferOwnership);
+
+ eventThreadServices.RegisterObject(rendererPtr.Get());
+ return rendererPtr;
+}
+
+VisualRenderer::VisualRenderer(const SceneGraph::Renderer* sceneObject)
+: Renderer(sceneObject)
+{
+}
+
+VisualRenderer::~VisualRenderer()
+{
+ if(EventThreadServices::IsCoreRunning())
+ {
+ EventThreadServices& eventThreadServices = GetEventThreadServices();
+ SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
+ RemoveRendererMessage(updateManager, GetVisualRendererSceneObject());
+
+ eventThreadServices.UnregisterObject(this);
+ }
+}
+
+const SceneGraph::Renderer& VisualRenderer::GetVisualRendererSceneObject() const
+{
+ return static_cast<const SceneGraph::Renderer&>(GetSceneObject());
+}
+
+void VisualRenderer::SetDefaultProperty(Property::Index index,
+ const Property::Value& propertyValue)
+{
+ if(index < Dali::VisualRenderer::Property::DEFAULT_VISUAL_RENDERER_PROPERTY_START_INDEX)
+ {
+ Renderer::SetDefaultProperty(index, propertyValue);
+ }
+ else
+ {
+ switch(index)
+ {
+ case Dali::VisualRenderer::Property::TRANSFORM_OFFSET:
+ {
+ if(propertyValue.Get(mPropertyCache.mTransformOffset))
+ {
+ const SceneGraph::Renderer& sceneObject = GetVisualRendererSceneObject();
+ auto visualProperties = sceneObject.GetVisualProperties();
+
+ if(visualProperties)
+ {
+ BakeMessage<Vector2>(GetEventThreadServices(), visualProperties->mTransformOffset, mPropertyCache.mTransformOffset);
+ }
+ }
+ break;
+ }
+
+ case Dali::VisualRenderer::Property::TRANSFORM_SIZE:
+ {
+ if(propertyValue.Get(mPropertyCache.mTransformSize))
+ {
+ const SceneGraph::Renderer& sceneObject = GetVisualRendererSceneObject();
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ BakeMessage<Vector2>(GetEventThreadServices(), visualProperties->mTransformSize, mPropertyCache.mTransformSize);
+ }
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_ORIGIN:
+ {
+ if(propertyValue.Get(mPropertyCache.mTransformOrigin))
+ {
+ const SceneGraph::Renderer& sceneObject = GetVisualRendererSceneObject();
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ BakeMessage<Vector2>(GetEventThreadServices(), visualProperties->mTransformOrigin, mPropertyCache.mTransformOrigin);
+ }
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_ANCHOR_POINT:
+ {
+ if(propertyValue.Get(mPropertyCache.mTransformAnchorPoint))
+ {
+ const SceneGraph::Renderer& sceneObject = GetVisualRendererSceneObject();
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ BakeMessage<Vector2>(GetEventThreadServices(), visualProperties->mTransformAnchorPoint, mPropertyCache.mTransformAnchorPoint);
+ }
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE:
+ {
+ if(propertyValue.Get(mPropertyCache.mTransformOffsetSizeMode))
+ {
+ const SceneGraph::Renderer& sceneObject = GetVisualRendererSceneObject();
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ BakeMessage<Vector4>(GetEventThreadServices(), visualProperties->mTransformOffsetSizeMode, mPropertyCache.mTransformOffsetSizeMode);
+ }
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::EXTRA_SIZE:
+ {
+ if(propertyValue.Get(mPropertyCache.mExtraSize))
+ {
+ const SceneGraph::Renderer& sceneObject = GetVisualRendererSceneObject();
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ BakeMessage<Vector2>(GetEventThreadServices(), visualProperties->mExtraSize, mPropertyCache.mExtraSize);
+ }
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::VISUAL_MIX_COLOR:
+ {
+ if(propertyValue.Get(mPropertyCache.mMixColor))
+ {
+ const SceneGraph::Renderer& sceneObject = GetVisualRendererSceneObject();
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ BakeMessage<Vector3>(GetEventThreadServices(), visualProperties->mMixColor, mPropertyCache.mMixColor);
+ }
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA:
+ {
+ float preMultipliedAlpha;
+ if(propertyValue.Get(preMultipliedAlpha))
+ {
+ if(!Equals(mPropertyCache.mPreMultipliedAlpha, preMultipliedAlpha))
+ {
+ const SceneGraph::Renderer& sceneObject = GetVisualRendererSceneObject();
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ mPropertyCache.mPreMultipliedAlpha = preMultipliedAlpha;
+ BakeMessage<float>(GetEventThreadServices(), visualProperties->mPreMultipliedAlpha, preMultipliedAlpha);
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+Property::Value VisualRenderer::GetDefaultProperty(Property::Index index) const
+{
+ Property::Value value;
+
+ if(index < Dali::VisualRenderer::Property::DEFAULT_VISUAL_RENDERER_PROPERTY_START_INDEX)
+ {
+ value = Renderer::GetDefaultProperty(index);
+ }
+ else
+ {
+ switch(index)
+ {
+ case Dali::VisualRenderer::Property::TRANSFORM_OFFSET:
+ {
+ value = mPropertyCache.mTransformOffset;
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_SIZE:
+ {
+ value = mPropertyCache.mTransformSize;
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_ORIGIN:
+ {
+ value = mPropertyCache.mTransformOrigin;
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_ANCHOR_POINT:
+ {
+ value = mPropertyCache.mTransformAnchorPoint;
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE:
+ {
+ value = mPropertyCache.mTransformOffsetSizeMode;
+ break;
+ }
+ case Dali::VisualRenderer::Property::EXTRA_SIZE:
+ {
+ value = mPropertyCache.mExtraSize;
+ break;
+ }
+ case Dali::VisualRenderer::Property::VISUAL_MIX_COLOR:
+ {
+ value = mPropertyCache.mMixColor;
+ break;
+ }
+ case Dali::VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA:
+ {
+ value = mPropertyCache.mPreMultipliedAlpha;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ return value;
+}
+
+Property::Value VisualRenderer::GetDefaultPropertyCurrentValue(Property::Index index) const
+{
+ Property::Value value;
+
+ if(index < Dali::VisualRenderer::Property::DEFAULT_VISUAL_RENDERER_PROPERTY_START_INDEX)
+ {
+ value = Renderer::GetDefaultPropertyCurrentValue(index);
+ }
+ else
+ {
+ const SceneGraph::Renderer& sceneObject = GetVisualRendererSceneObject();
+
+ switch(index)
+ {
+ case Dali::VisualRenderer::Property::TRANSFORM_OFFSET:
+ {
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ value = visualProperties->mTransformOffset[GetEventThreadServices().GetEventBufferIndex()];
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_SIZE:
+ {
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ value = visualProperties->mTransformSize[GetEventThreadServices().GetEventBufferIndex()];
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_ORIGIN:
+ {
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ value = visualProperties->mTransformOrigin[GetEventThreadServices().GetEventBufferIndex()];
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_ANCHOR_POINT:
+ {
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ value = visualProperties->mTransformAnchorPoint[GetEventThreadServices().GetEventBufferIndex()];
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE:
+ {
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ value = visualProperties->mTransformOffsetSizeMode[GetEventThreadServices().GetEventBufferIndex()];
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::EXTRA_SIZE:
+ {
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ value = visualProperties->mExtraSize[GetEventThreadServices().GetEventBufferIndex()];
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::VISUAL_MIX_COLOR:
+ {
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ value = visualProperties->mMixColor[GetEventThreadServices().GetEventBufferIndex()];
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA:
+ {
+ auto visualProperties = sceneObject.GetVisualProperties();
+ if(visualProperties)
+ {
+ value = visualProperties->mPreMultipliedAlpha[GetEventThreadServices().GetEventBufferIndex()];
+ }
+ break;
+ }
+ }
+ }
+ return value;
+}
+
+void VisualRenderer::OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType)
+{
+ if(index < Dali::VisualRenderer::Property::DEFAULT_VISUAL_RENDERER_PROPERTY_START_INDEX)
+ {
+ Renderer::OnNotifyDefaultPropertyAnimation(animation, index, value, animationType);
+ }
+ else
+ {
+ switch(animationType)
+ {
+ case Animation::TO:
+ case Animation::BETWEEN:
+ {
+ switch(index)
+ {
+ case Dali::VisualRenderer::Property::TRANSFORM_OFFSET:
+ {
+ value.Get(mPropertyCache.mTransformOffset);
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_SIZE:
+ {
+ value.Get(mPropertyCache.mTransformSize);
+ break;
+ }
+ case Dali::VisualRenderer::Property::EXTRA_SIZE:
+ {
+ value.Get(mPropertyCache.mExtraSize);
+ break;
+ }
+ case Dali::VisualRenderer::Property::VISUAL_MIX_COLOR:
+ {
+ value.Get(mPropertyCache.mMixColor);
+ break;
+ }
+ }
+ break;
+ }
+
+ case Animation::BY:
+ {
+ switch(index)
+ {
+ case Dali::VisualRenderer::Property::TRANSFORM_OFFSET:
+ {
+ AdjustValue<Vector2>(mPropertyCache.mTransformOffset, value);
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_SIZE:
+ {
+ AdjustValue<Vector2>(mPropertyCache.mTransformSize, value);
+ break;
+ }
+ case Dali::VisualRenderer::Property::EXTRA_SIZE:
+ {
+ AdjustValue<Vector2>(mPropertyCache.mExtraSize, value);
+ break;
+ }
+ case Dali::VisualRenderer::Property::VISUAL_MIX_COLOR:
+ {
+ AdjustValue<Vector3>(mPropertyCache.mMixColor, value);
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+
+const SceneGraph::PropertyBase* VisualRenderer::GetSceneObjectAnimatableProperty(Property::Index index) const
+{
+ const SceneGraph::PropertyBase* property = nullptr;
+
+ switch(index)
+ {
+ case Dali::VisualRenderer::Property::TRANSFORM_OFFSET:
+ {
+ auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
+ if(visualProperties)
+ {
+ property = &visualProperties->mTransformOffset;
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_SIZE:
+ {
+ auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
+ if(visualProperties)
+ {
+ property = &visualProperties->mTransformSize;
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::EXTRA_SIZE:
+ {
+ auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
+ if(visualProperties)
+ {
+ property = &visualProperties->mExtraSize;
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::VISUAL_MIX_COLOR:
+ {
+ auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
+ if(visualProperties)
+ {
+ property = &visualProperties->mMixColor;
+ }
+ break;
+ }
+ }
+
+ if(!property)
+ {
+ // not our property, ask base
+ property = Renderer::GetSceneObjectAnimatableProperty(index);
+ }
+
+ return property;
+}
+
+const PropertyInputImpl* VisualRenderer::GetSceneObjectInputProperty(Property::Index index) const
+{
+ switch(index)
+ {
+ case Dali::VisualRenderer::Property::TRANSFORM_ORIGIN:
+ {
+ auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
+ if(visualProperties)
+ {
+ return &visualProperties->mTransformOrigin;
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_ANCHOR_POINT:
+ {
+ auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
+ if(visualProperties)
+ {
+ return &visualProperties->mTransformAnchorPoint;
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE:
+ {
+ auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
+ if(visualProperties)
+ {
+ return &visualProperties->mTransformOffsetSizeMode;
+ }
+ break;
+ }
+ case Dali::VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA:
+ {
+ auto visualProperties = GetVisualRendererSceneObject().GetVisualProperties();
+ if(visualProperties)
+ {
+ return &visualProperties->mPreMultipliedAlpha;
+ }
+ break;
+ }
+ default:
+ {
+ return GetSceneObjectAnimatableProperty(index);
+ }
+ }
+ return nullptr;
+}
+
+void VisualRenderer::AddUniformMappings()
+{
+ AddUniformMapping(Dali::VisualRenderer::Property::TRANSFORM_OFFSET, ConstString("offset"));
+ AddUniformMapping(Dali::VisualRenderer::Property::TRANSFORM_SIZE, ConstString("size"));
+ AddUniformMapping(Dali::VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE, ConstString("offsetSizeMode"));
+ AddUniformMapping(Dali::VisualRenderer::Property::TRANSFORM_ORIGIN, ConstString("origin"));
+ AddUniformMapping(Dali::VisualRenderer::Property::TRANSFORM_ANCHOR_POINT, ConstString("anchorPoint"));
+ AddUniformMapping(Dali::VisualRenderer::Property::EXTRA_SIZE, ConstString("extraSize"));
+ AddUniformMapping(Dali::VisualRenderer::Property::VISUAL_MIX_COLOR, ConstString("mixColor"));
+ AddUniformMapping(Dali::VisualRenderer::Property::VISUAL_PRE_MULTIPLIED_ALPHA, ConstString("preMultipliedAlpha"));
+}
+
+} // namespace Internal
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_INTERNAL_VISUAL_RENDERER_H
+#define DALI_INTERNAL_VISUAL_RENDERER_H
+
+/*
+ * 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.
+ * 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/rendering/renderer-impl.h> // Dali::Internal::Renderer
+#include <dali/internal/update/common/animatable-property.h>
+#include <dali/public-api/rendering/visual-renderer.h> // Dali::VisualRenderer
+
+namespace Dali
+{
+namespace Internal
+{
+namespace SceneGraph
+{
+class Renderer;
+}
+
+class VisualRenderer;
+using VisualRendererPtr = IntrusivePtr<VisualRenderer>;
+
+/**
+ * VisualRenderer is a Renderer that has additional default properties for toolkit
+ */
+class VisualRenderer : public Renderer
+{
+public:
+ /**
+ * Create a new VisualRenderer.
+ * @return A smart-pointer to the newly allocated VisualRenderer.
+ */
+ static VisualRendererPtr New();
+
+ /**
+ * @brief Get the scene graph object
+ *
+ * @return the scene object
+ */
+ const SceneGraph::Renderer& GetVisualRendererSceneObject() const;
+
+public: // Default property extensions from Object
+ /**
+ * @copydoc Dali::Internal::Object::SetDefaultProperty()
+ */
+ void SetDefaultProperty(Property::Index index, const Property::Value& propertyValue) override;
+
+ /**
+ * @copydoc Dali::Internal::Object::GetDefaultProperty()
+ */
+ Property::Value GetDefaultProperty(Property::Index index) const override;
+
+ /**
+ * @copydoc Dali::Internal::Object::GetDefaultPropertyCurrentValue()
+ */
+ Property::Value GetDefaultPropertyCurrentValue(Property::Index index) const override;
+
+ /**
+ * @copydoc Dali::Internal::Object::OnNotifyDefaultPropertyAnimation()
+ */
+ void OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType) override;
+
+ /**
+ * @copydoc Dali::Internal::Object::GetSceneObjectAnimatableProperty()
+ */
+ const SceneGraph::PropertyBase* GetSceneObjectAnimatableProperty(Property::Index index) const override;
+
+ /**
+ * @copydoc Dali::Internal::Object::GetSceneObjectInputProperty()
+ */
+ const PropertyInputImpl* GetSceneObjectInputProperty(Property::Index index) const override;
+
+private: // implementation
+ /**
+ * @brief Constructor.
+ *
+ * @param sceneObject the scene graph renderer
+ */
+ VisualRenderer(const SceneGraph::Renderer* sceneObject);
+
+ /**
+ * @brief Retrieves the current value of a default property from the scene-graph.
+ * @param[in] index The index of the property
+ * @param[out] value Is set with the current scene-graph value of the property
+ * @return True if value set, false otherwise.
+ */
+ bool GetCurrentPropertyValue(Property::Index index, Property::Value& value) const;
+
+protected:
+ /**
+ * A reference counted object may only be deleted by calling Unreference()
+ */
+ ~VisualRenderer() override;
+
+private:
+ VisualRenderer(const VisualRenderer&) = delete;
+ VisualRenderer& operator=(const VisualRenderer&) = delete;
+
+ /**
+ * @brief Ensure that properties are mapped to uniforms
+ */
+ void AddUniformMappings();
+
+public:
+ struct VisualPropertyCache
+ {
+ Vector2 mTransformOffset{Vector2::ZERO};
+ Vector2 mTransformSize{Vector2::ZERO};
+ Vector2 mTransformOrigin{Vector2::ZERO};
+ Vector2 mTransformAnchorPoint{Vector2::ZERO};
+ Vector4 mTransformOffsetSizeMode{Vector2::ZERO};
+ Vector2 mExtraSize{Vector2::ZERO};
+ Vector3 mMixColor{Vector3::ONE};
+ float mPreMultipliedAlpha{0.0f};
+ };
+
+ struct AnimatableVisualProperties
+ {
+ AnimatableVisualProperties()
+ : mTransformOffset(Vector2::ZERO),
+ mTransformSize(Vector2::ZERO),
+ mTransformOrigin(Vector2::ZERO),
+ mTransformAnchorPoint(Vector2::ZERO),
+ mTransformOffsetSizeMode(Vector4::ZERO),
+ mExtraSize(Vector2::ZERO),
+ mMixColor(Vector3::ONE),
+ mPreMultipliedAlpha(0.0f)
+ {
+ }
+ SceneGraph::AnimatableProperty<Vector2> mTransformOffset;
+ SceneGraph::AnimatableProperty<Vector2> mTransformSize;
+ SceneGraph::AnimatableProperty<Vector2> mTransformOrigin;
+ SceneGraph::AnimatableProperty<Vector2> mTransformAnchorPoint;
+ SceneGraph::AnimatableProperty<Vector4> mTransformOffsetSizeMode;
+ SceneGraph::AnimatableProperty<Vector2> mExtraSize;
+ SceneGraph::AnimatableProperty<Vector3> mMixColor;
+ SceneGraph::AnimatableProperty<float> mPreMultipliedAlpha;
+ void* mExtendedProperties{nullptr}; // Enable derived class to extend properties further
+ };
+
+private:
+ VisualPropertyCache mPropertyCache;
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+inline Internal::VisualRenderer& GetImplementation(Dali::VisualRenderer& handle)
+{
+ DALI_ASSERT_ALWAYS(handle && "VisualRenderer handle is empty");
+
+ BaseObject& object = handle.GetBaseObject();
+
+ return static_cast<Internal::VisualRenderer&>(object);
+}
+
+inline const Internal::VisualRenderer& GetImplementation(const Dali::VisualRenderer& handle)
+{
+ DALI_ASSERT_ALWAYS(handle && "VisualRenderer handle is empty");
+
+ const BaseObject& object = handle.GetBaseObject();
+
+ return static_cast<const Internal::VisualRenderer&>(object);
+}
+
+} // namespace Dali
+
+#endif // DALI_INTERNAL_RENDERER_H
${internal_src_dir}/event/rendering/texture-impl.cpp
${internal_src_dir}/event/rendering/texture-set-impl.cpp
${internal_src_dir}/event/rendering/renderer-impl.cpp
+ ${internal_src_dir}/event/rendering/visual-renderer-impl.cpp
${internal_src_dir}/event/rendering/sampler-impl.cpp
${internal_src_dir}/event/rendering/shader-impl.cpp
${internal_src_dir}/event/rendering/vertex-buffer-impl.cpp
#define DALI_INTERNAL_SCENE_GRAPH_RENDERER_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.
#include <dali/internal/common/blending-options.h>
#include <dali/internal/common/type-abstraction-enums.h>
#include <dali/internal/event/common/event-thread-services.h>
+#include <dali/internal/event/rendering/visual-renderer-impl.h>
#include <dali/internal/render/data-providers/render-data-provider.h>
#include <dali/internal/render/renderers/render-renderer.h>
#include <dali/internal/update/common/animatable-property.h>
void SetDrawCommands(Dali::DevelRenderer::DrawCommand* pDrawCommands, uint32_t size);
+public: // For VisualProperties
+ /**
+ * To be used only for 1st stage initialization in event thread.
+ */
+ void SetVisualProperties(Internal::VisualRenderer::AnimatableVisualProperties* visualProperties)
+ {
+ mVisualProperties = visualProperties;
+ }
+
+ /**
+ * May be accessed from event thread
+ */
+ const Internal::VisualRenderer::AnimatableVisualProperties* GetVisualProperties() const
+ {
+ return mVisualProperties;
+ }
+
private:
/**
* Protected constructor; See also Renderer::New()
private:
CollectedUniformMap mCollectedUniformMap[2]; ///< Uniform maps collected by the renderer
- SceneController* mSceneController; ///< Used for initializing renderers
- Render::Renderer* mRenderer; ///< Raw pointer to the renderer (that's owned by RenderManager)
- TextureSet* mTextureSet; ///< The texture set this renderer uses. (Not owned)
- Render::Geometry* mGeometry; ///< The geometry this renderer uses. (Not owned)
- Shader* mShader; ///< The shader this renderer uses. (Not owned)
- OwnerPointer<Vector4> mBlendColor; ///< The blend color for blending operation
+ SceneController* mSceneController; ///< Used for initializing renderers
+ Render::Renderer* mRenderer; ///< Raw pointer to the renderer (that's owned by RenderManager)
+ TextureSet* mTextureSet; ///< The texture set this renderer uses. (Not owned)
+ Render::Geometry* mGeometry; ///< The geometry this renderer uses. (Not owned)
+ Shader* mShader; ///< The shader this renderer uses. (Not owned)
+ VisualRenderer::AnimatableVisualProperties* mVisualProperties{nullptr}; ///< VisualProperties (optional/owned)
+ OwnerPointer<Vector4> mBlendColor; ///< The blend color for blending operation
Dali::Internal::Render::Renderer::StencilParameters mStencilParameters; ///< Struct containing all stencil related options
#define DALI_INTRUSIVE_PTR_H
/*
- * Copyright (c) 2020 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.
*
*/
+// EXTERNAL INCLUDES
+#include <cstddef> // for std::nullptr_t
+
// INTERNAL INCLUDES
#include <dali/public-api/common/dali-common.h>
}
/**
+ * @brief Comparison overrides of objects with nullptr_t.
+ *
+ * @SINCE_2_1.12
+ * @param[in] lhs Intrusive pointer to compare with
+ * @param[in] rhs nullptr
+ * @return True if the pointers is nullptr
+ */
+template<typename T>
+inline bool operator==(IntrusivePtr<T> const& lhs, std::nullptr_t rhs)
+{
+ return lhs.Get() == nullptr;
+}
+
+/**
+ * @brief Comparison overrides of objects with nullptr_t.
+ *
+ * @SINCE_2_1.12
+ * @param[in] lhs Intrusive pointer to compare with
+ * @param[in] rhs nullptr
+ * @return True if the pointers is not nullptr
+ */
+template<typename T>
+inline bool operator!=(IntrusivePtr<T> const& lhs, std::nullptr_t rhs)
+{
+ return lhs.Get() != nullptr;
+}
+
+/**
+ * @brief Comparison overrides of objects with nullptr_t.
+ *
+ * @SINCE_2_1.12
+ * @param[in] lhs nullptr
+ * @param[in] rhs Intrusive pointer to compare against
+ * @return True if the pointers is nullptr
+ */
+template<typename T>
+inline bool operator==(std::nullptr_t lhs, IntrusivePtr<T> const& rhs)
+{
+ return nullptr == rhs.Get();
+}
+
+/**
+ * @brief Comparison overrides of objects with nullptr_t.
+ *
+ * @SINCE_2_1.12
+ * @param[in] lhs nullptr
+ * @param[in] rhs Intrusive pointer to compare against
+ * @return True if the pointers is not nullptr
+ */
+template<typename T>
+inline bool operator!=(std::nullptr_t lhs, IntrusivePtr<T> const& rhs)
+{
+ return nullptr != rhs.Get();
+}
+
+/**
* @}
*/
} // namespace Dali
{
const uint32_t CORE_MAJOR_VERSION = 2;
const uint32_t CORE_MINOR_VERSION = 1;
-const uint32_t CORE_MICRO_VERSION = 12;
+const uint32_t CORE_MICRO_VERSION = 13;
const char* const CORE_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
#define DALI_CORE_H
/*
- * Copyright (c) 2020 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.
#include <dali/public-api/rendering/texture-set.h>
#include <dali/public-api/rendering/texture.h>
#include <dali/public-api/rendering/vertex-buffer.h>
+#include <dali/public-api/rendering/visual-renderer.h>
#include <dali/public-api/signals/base-signal.h>
#include <dali/public-api/signals/callback.h>
${public_api_src_dir}/rendering/texture.cpp
${public_api_src_dir}/rendering/texture-set.cpp
${public_api_src_dir}/rendering/renderer.cpp
+ ${public_api_src_dir}/rendering/visual-renderer.cpp
${public_api_src_dir}/rendering/sampler.cpp
${public_api_src_dir}/rendering/shader.cpp
${public_api_src_dir}/signals/callback.cpp
${public_api_src_dir}/rendering/texture.h
${public_api_src_dir}/rendering/texture-set.h
${public_api_src_dir}/rendering/renderer.h
+ ${public_api_src_dir}/rendering/visual-renderer.h
${public_api_src_dir}/rendering/sampler.h
${public_api_src_dir}/rendering/shader.h
)
#define DALI_PROPERTY_INDEX_RANGES_H
/*
- * Copyright (c) 2020 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.
DEFAULT_GESTURE_DETECTOR_PROPERTY_START_INDEX = DEFAULT_DERIVED_ACTOR_PROPERTY_START_INDEX, ///< Used by PanGestureDetector. @SINCE_1_0.0
DEFAULT_RENDERER_PROPERTY_START_INDEX = 9000000, ///< Start index for Renderer. @SINCE_1_1.44
- DEFAULT_RENDERER_PROPERTY_MAX_INDEX = DEFAULT_RENDERER_PROPERTY_START_INDEX + 100000, ///< Renderer range: 9000000 to 9100000 @SINCE_1_1.44
+ DEFAULT_RENDERER_PROPERTY_MAX_INDEX = DEFAULT_RENDERER_PROPERTY_START_INDEX + DEFAULT_PROPERTY_MAX_COUNT_PER_DERIVATION-1,///< Renderer range: 9,000,000 to 9,009,999 @SINCE_2_1.13
PROPERTY_REGISTRATION_START_INDEX = 10000000, ///< The index when registering a property should start from this number. @SINCE_1_0.0
DEFAULT_PROPERTY_MAX_COUNT = PROPERTY_REGISTRATION_START_INDEX, ///< Default Property Range: 0 to 9999999 @SINCE_1_0.0
#define DALI_RENDERER_H
/*
- * Copyright (c) 2020 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.
Shader GetShader() const;
public:
+ /// @cond internal
/**
* @brief The constructor.
* @note Not intended for application developers.
* @param[in] pointer A pointer to a newly allocated Renderer
*/
explicit DALI_INTERNAL Renderer(Internal::Renderer* pointer);
+ /// @endcond
};
/**
--- /dev/null
+/*
+ * 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.
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/public-api/rendering/visual-renderer.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/rendering/visual-renderer-impl.h>
+
+namespace Dali
+{
+VisualRenderer VisualRenderer::New(Geometry& geometry, Shader& shader)
+{
+ Internal::VisualRendererPtr renderer = Internal::VisualRenderer::New();
+ renderer->SetGeometry(GetImplementation(geometry));
+ renderer->SetShader(GetImplementation(shader));
+ return VisualRenderer(renderer.Get());
+}
+
+VisualRenderer::VisualRenderer() = default;
+
+VisualRenderer::~VisualRenderer() = default;
+
+VisualRenderer::VisualRenderer(const VisualRenderer& handle) = default;
+
+VisualRenderer VisualRenderer::DownCast(BaseHandle handle)
+{
+ return VisualRenderer(dynamic_cast<Dali::Internal::VisualRenderer*>(handle.GetObjectPtr()));
+}
+
+VisualRenderer& VisualRenderer::operator=(const VisualRenderer& handle) = default;
+
+VisualRenderer::VisualRenderer(VisualRenderer&& rhs) = default;
+
+VisualRenderer& VisualRenderer::operator=(VisualRenderer&& rhs) = default;
+
+VisualRenderer::VisualRenderer(Internal::VisualRenderer* pointer)
+: Dali::Renderer(pointer)
+{
+}
+
+} //namespace Dali
--- /dev/null
+#ifndef DALI_VISUAL_RENDERER_H
+#define DALI_VISUAL_RENDERER_H
+
+/*
+ * 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.
+ * 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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/public-api/rendering/renderer.h>
+
+namespace Dali
+{
+/**
+ * @addtogroup dali_core_rendering_effects
+ * @{
+ */
+
+namespace Internal DALI_INTERNAL
+{
+class VisualRenderer;
+}
+
+/**
+ * @brief VisualRenderer is a handle to a Renderer with extra properties for Toolkit::Visuals
+ *
+ * @SINCE_2_1.13
+ */
+class DALI_CORE_API VisualRenderer : public Renderer
+{
+public:
+ /**
+ * @brief Policies used by the transform for the offset or size.
+ * @SINCE_2_1.13
+ */
+ struct TransformPolicy
+ {
+ /**
+ * @brief Enumeration for the type of Transform Policy.
+ * @SINCE_2_1.13
+ */
+ enum Type
+ {
+ RELATIVE = 0, ///< Relative to the control (percentage [0.0f to 1.0f] of the control). @SINCE_2_1.13
+ ABSOLUTE = 1 ///< Absolute value in world units. @SINCE_2_1.13
+ };
+ };
+
+ /**
+ * @brief Enumeration for instances of properties belonging to the VisualRenderer class.
+ * @SINCE_2_1.13
+ */
+ struct Property
+ {
+ static constexpr Dali::Property::Index DEFAULT_VISUAL_RENDERER_PROPERTY_START_INDEX = DEFAULT_RENDERER_PROPERTY_START_INDEX + DEFAULT_PROPERTY_MAX_COUNT_PER_DERIVATION;
+
+ /**
+ * @brief Enumeration for instances of properties belonging to the VisualRenderer class.
+ * @SINCE_2_1.13
+ */
+ enum
+ {
+ /**
+ * @brief Name "transformOffset", type Property::Vector2, animatable.
+ * @SINCE_2_1.13
+ * @note The default value is (0,0).
+ */
+ TRANSFORM_OFFSET = DEFAULT_VISUAL_RENDERER_PROPERTY_START_INDEX,
+
+ /**
+ * @brief Size of the visual, which can be either relative (percentage [0.0f to 1.0f] of the parent) or absolute (in world units).
+ * @details Name "transformSize", type Property::VECTOR2, animatable.
+ * @SINCE_2_1.13
+ * @see TRANSFORM_SIZE_POLICY
+ */
+ TRANSFORM_SIZE,
+
+ /**
+ * @brief The origin of the visual renderer within its control area.
+ * @details Name "transformOrigin", type Property::VECTOR2
+ * @note This is relative to the size of the actor, where the origin is the center of the actor,
+ * and the range is -0.5 to +0.5 vertically and horizontally
+ * @note Toolkit may impose additional layout directions
+ * @SINCE_2_1.13
+ * @note The default is top left
+ */
+ TRANSFORM_ORIGIN,
+
+ /**
+ * @brief The anchor-point of the visual renderer
+ * @details Name "transformAnchorPoint", type Property::VECTOR2
+ * @note This is relative to the size of the actor; where the origin is the center of the actor,
+ * and the range is -0.5 to +0.5 vertically and horizontally
+ * @note Toolkit may impose additional layout directions
+ * @SINCE_2_1.13
+ * @note The default is top left.
+ */
+ TRANSFORM_ANCHOR_POINT,
+
+ /**
+ * @brief Whether the x or y OFFSET/SIZE values are relative (percentage [0.0f to 1.0f] of the control) or absolute (in world units).
+ * @details Name "transformOffsetSizeMode", type Property::VECTOR4
+ *
+ * @code
+ * visualRenderer.SetProperty( VisualRenderer::Property::TRANSFORM_OFFSET_SIZE_MODE,
+ * Vector4( Policy::ABSOLUTE, Policy::RELATIVE, Policy::ABSOLUTE, Policy::RELATIVE ));
+ * @endcode
+ * @see Policy::Type
+ * @SINCE_2_1.13
+ * @note By default, both the x and the y offset/size is RELATIVE.
+ */
+ TRANSFORM_OFFSET_SIZE_MODE,
+
+ /**
+ * @brief Any extra size the shader needs for drawing into.
+ * @details Name "extraSize", type Property::VECTOR2, animatable
+ * @SINCE_2_1.13
+ * @note the default is (0, 0)
+ */
+ EXTRA_SIZE,
+
+ /**
+ * @brief Mix color is a generic color for any visual.
+ * @details Name "visualMixColor", type Property::VECTOR3, animatable
+ * @SINCE_2_1.13
+ */
+ VISUAL_MIX_COLOR,
+
+ /**
+ * @brief PremultipliedAlpha is a float representing a bool, and is either 0.0f, or 1.0f
+ * @details Name "preMultipliedAlpha", type Property::FLOAT
+ * @SINCE_2_1.13
+ */
+ VISUAL_PRE_MULTIPLIED_ALPHA,
+ };
+ };
+
+ /**
+ * @brief Creates a new Renderer object.
+ *
+ * @SINCE_2_1.13
+ * @param[in] geometry Geometry to be used by this renderer
+ * @param[in] shader Shader to be used by this renderer
+ * @return A handle to the Renderer
+ */
+ static VisualRenderer New(Geometry& geometry, Shader& shader);
+
+ /**
+ * @brief Default constructor, creates an empty handle
+ *
+ * @SINCE_2_1.13
+ */
+ VisualRenderer();
+
+ /**
+ * @brief Destructor.
+ *
+ * @SINCE_2_1.13
+ */
+ ~VisualRenderer();
+
+ /**
+ * @brief Copy constructor, creates a new handle to the same object.
+ *
+ * @SINCE_2_1.13
+ * @param[in] handle Handle to an object
+ */
+ VisualRenderer(const VisualRenderer& handle);
+
+ /**
+ * @brief Downcasts to a visual renderer handle.
+ * If not, a renderer the returned visual renderer handle is left uninitialized.
+ *
+ * @SINCE_2_1.13
+ * @param[in] handle Handle to an object
+ * @return Renderer handle or an uninitialized handle
+ */
+ static VisualRenderer DownCast(BaseHandle handle);
+
+ /**
+ * @brief Assignment operator, changes this handle to point at the same object.
+ *
+ * @SINCE_2_1.13
+ * @param[in] handle Handle to an object
+ * @return Reference to the assigned object
+ */
+ VisualRenderer& operator=(const VisualRenderer& handle);
+
+ /**
+ * @brief Move constructor.
+ *
+ * @SINCE_2_1.13
+ * @param[in] rhs A reference to the moved handle
+ */
+ VisualRenderer(VisualRenderer&& rhs);
+
+ /**
+ * @brief Move assignment operator.
+ *
+ * @SINCE_2_1.13
+ * @param[in] rhs A reference to the moved handle
+ * @return A reference to this handle
+ */
+ VisualRenderer& operator=(VisualRenderer&& rhs);
+
+public:
+ /// @cond internal
+ /**
+ * @brief The constructor.
+ * @note Not intended for application developers.
+ * @SINCE_2_1.13
+ * @param[in] pointer A pointer to a newly allocated VisualRenderer
+ */
+ explicit DALI_INTERNAL VisualRenderer(Internal::VisualRenderer* pointer);
+ /// @endcond
+};
+
+/**
+ * @}
+ */
+} //namespace Dali
+
+#endif // DALI_VISUAL_RENDERER_H
Name: dali2
Summary: DALi 3D Engine
-Version: 2.1.12
+Version: 2.1.13
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT