utc-Dali-CustomActor.cpp
utc-Dali-Degree.cpp
utc-Dali-DistanceField.cpp
+ utc-Dali-DrawableActor.cpp
utc-Dali-Extents.cpp
utc-Dali-FrameBuffer.cpp
utc-Dali-FrameCallbackInterface.cpp
SET_DEPTH_COMPARE_OP = 1 << 24,
SET_DEPTH_TEST_ENABLE = 1 << 25,
SET_DEPTH_WRITE_ENABLE = 1 << 26,
+ DRAW_NATIVE = 1 << 27,
};
std::ostream& operator<<(std::ostream& os, Graphics::StencilOp op);
{
DRAW,
DRAW_INDEXED,
- DRAW_INDEXED_INDIRECT
+ DRAW_INDEXED_INDIRECT,
+ DRAW_NATIVE
};
Type type{}; ///< Type of the draw call
uint32_t drawCount;
uint32_t stride;
} drawIndexedIndirect;
+
+ struct
+ {
+ Graphics::DrawNativeInfo drawNativeInfo;
+ } drawNative;
};
};
data.bindUniformBuffers = rhs.data.bindUniformBuffers;
break;
}
+ case CommandType::DRAW_NATIVE:
+ {
+ data.draw.type = rhs.data.draw.type;
+ data.draw.drawNative = rhs.data.draw.drawNative;
+ break;
+ }
case CommandType::DRAW:
{
data.draw.type = rhs.data.draw.type;
data.bindPipeline = rhs.data.bindPipeline;
break;
}
+ case CommandType::DRAW_NATIVE:
+ {
+ data.draw.type = rhs.data.draw.type;
+ data.draw.drawNative = rhs.data.draw.drawNative;
+ break;
+ }
case CommandType::DRAW:
{
data.draw.type = rhs.data.draw.type;
mCallStack.PushCall("ExecuteCommandBuffers", "");
}
+ void DrawNative(const Graphics::DrawNativeInfo* drawInfo)
+ {
+ mCommands.emplace_back();
+ mCommands.back().type = CommandType::DRAW_NATIVE;
+ auto& cmd = mCommands.back().data.draw;
+ cmd.type = DrawCallDescriptor::Type::DRAW_NATIVE;
+ cmd.drawNative.drawNativeInfo = *drawInfo;
+ mCallStack.PushCall("DrawNative", "");
+ }
+
void Draw(
uint32_t vertexCount,
uint32_t instanceCount,
BindPipeline(currentPipeline);
break;
}
+ case CommandType::DRAW_NATIVE:
+ {
+ auto info = &cmd.data.draw.drawNative.drawNativeInfo;
+ CallbackBase::ExecuteReturn<bool>(*info->callback, info->userData);
+ break;
+ }
case CommandType::DRAW:
{
if(currentPipeline)
--- /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.
+ *
+ */
+
+#include <dali-test-suite-utils.h>
+#include <dali/public-api/actors/drawable-actor.h>
+
+struct DrawableObject
+{
+ bool Render(const RenderCallbackInput& inputData)
+ {
+ // Store the size of rendered area
+ size = inputData.size;
+
+ return false;
+ }
+
+ Size size;
+};
+
+int UtcDaliDrawableActor1P(void)
+{
+ tet_infoline("Testing DrawableActor");
+ TestApplication application;
+
+ DrawableObject drawable{};
+
+ auto callback = RenderCallback::New<DrawableObject>(&drawable, &DrawableObject::Render);
+
+ DrawableActor drawableActor = DrawableActor::New(*callback);
+ application.GetScene().Add(drawableActor);
+
+ drawableActor.SetProperty(Actor::Property::SIZE, Vector2(100, 100));
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ // Check the size (whether callback has been called)
+ auto size(drawable.size);
+ DALI_TEST_EQUALS(drawable.size, Size(100, 100), TEST_LOCATION);
+
+ END_TEST;
+}
\ No newline at end of file
};
};
+// Native rendering (using native APIs)
+
+enum class DrawNativeAPI
+{
+ GLES,
+ UNDEFINED
+};
+
+struct DrawNativeInfo
+{
+ DrawNativeAPI api; //< API used by the callback
+ Dali::CallbackBase* callback; //< Callback pointer
+ void* userData; //< Data passed into the callback (unspecified type, callback should decode it)
+ void* reserved; //< Reserved for internal use
+};
+
/**
* @brief CommandBuffer contains a stream of commands to be executed
* by the controller.
uint32_t stride) = 0;
/**
+ * @brief Draws using native API (via callback)
+ *
+ * DrawNative should be use in order to acquire direct access to the
+ * graphics API like GL. Upon command execution, the backend will
+ * invoke given callback and pass API-specific arguments (for example,
+ * the GL callback will receive EGL context used for rendering).
+ *
+ * The client side must make sure the callback is valid for the
+ * time of execution.
+ *
+ * @param[in] drawInfo NativeDrawInfo structure
+ */
+ virtual void DrawNative(const DrawNativeInfo* drawInfo) = 0;
+
+ /**
* @brief Resets CommandBuffer
*
* This function resets the command buffer and discards all previously
#include <utility>
#include <vector>
+#include <dali/public-api/signals/callback.h>
+
namespace Dali
{
namespace Graphics
--- /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.
+ *
+ */
+
+#include "drawable-actor-impl.h"
+#include <dali/internal/event/rendering/renderer-impl.h>
+#include <dali/internal/update/nodes/node.h>
+
+namespace Dali::Internal
+{
+DrawableActorPtr DrawableActor::New(RenderCallback* renderCallback)
+{
+ return DrawableActorPtr(new DrawableActor(*CreateNode(), renderCallback));
+}
+
+DrawableActor::DrawableActor(const Internal::SceneGraph::Node& node, RenderCallback* renderCallback)
+: Actor(Actor::BASIC, node)
+{
+ auto rendererImpl = Internal::Renderer::New();
+
+ rendererImpl->SetProperty(DevelRenderer::Property::RENDERING_BEHAVIOR, DevelRenderer::Rendering::CONTINUOUSLY);
+
+ mRenderer = Dali::Renderer(rendererImpl.Get());
+ mRenderer.SetRenderCallback(renderCallback);
+ AddRenderer(*rendererImpl.Get());
+}
+
+} // namespace Dali::Internal
\ No newline at end of file
--- /dev/null
+#ifndef DALI_INTERNAL_DRAWABLE_ACTOR_H
+#define DALI_INTERNAL_DRAWABLE_ACTOR_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.
+ *
+ */
+
+#include <dali/internal/event/actors/actor-impl.h>
+#include <dali/public-api/rendering/renderer.h>
+
+namespace Dali::Internal
+{
+namespace SceneGraph
+{
+class Node;
+}
+
+class DrawableActor;
+using DrawableActorPtr = IntrusivePtr<DrawableActor>;
+
+class DrawableActor : public Actor
+{
+public:
+ /**
+ * @brief Constructor of DrawableActor
+ *
+ * @param[in] node the scenegraph Node object
+ * @param[in] renderCallback the pointer to the CallbackBase object
+ */
+ explicit DrawableActor(const Internal::SceneGraph::Node& node, RenderCallback* renderCallback);
+
+ /**
+ * @brief Creates new instance of the DrawableActor implementation
+ *
+ * @param[in] renderCallback Pointer to a valid CallbackBase object
+ * @return managed pointer to the DrawableActor implementation
+ */
+ static DrawableActorPtr New(RenderCallback* renderCallback);
+
+private:
+ Dali::Renderer mRenderer; //< Drawable renderer with callback attached
+};
+
+} // namespace Dali::Internal
+
+#endif // DALI_INTERNAL_DRAWABLE_ACTOR_H
return Color::TRANSPARENT; // GL default
}
+void Renderer::SetRenderCallback(RenderCallback* callback)
+{
+ Dali::Internal::SceneGraph::SetRenderCallbackMessage(GetEventThreadServices(),
+ GetRendererSceneObject(),
+ callback);
+}
+
} // namespace Internal
} // namespace Dali
*/
void AddDrawCommand(const Dali::DevelRenderer::DrawCommand& command);
+ /**
+ * @copydoc Dali::Renderer::SetRenderCallback()
+ */
+ void SetRenderCallback(RenderCallback* callback);
+
protected: // implementation
/**
* @brief Constructor.
${internal_src_dir}/event/actors/actor-parent-impl.cpp
${internal_src_dir}/event/actors/actor-sizer.cpp
${internal_src_dir}/event/actors/custom-actor-internal.cpp
+ ${internal_src_dir}/event/actors/drawable-actor-impl.cpp
${internal_src_dir}/event/actors/layer-impl.cpp
${internal_src_dir}/event/actors/layer-list.cpp
${internal_src_dir}/event/actors/camera-actor-impl.cpp
#include <dali/internal/render/shaders/program.h>
#include <dali/internal/render/shaders/render-shader.h>
#include <dali/internal/update/common/uniform-map.h>
+#include <dali/public-api/signals/render-callback.h>
namespace Dali::Internal
{
return false;
}
+ // Check if there is render callback
+ if(mRenderCallback)
+ {
+ Graphics::DrawNativeInfo info{};
+ info.api = Graphics::DrawNativeAPI::GLES;
+ info.callback = &static_cast<Dali::CallbackBase&>(*mRenderCallback);
+ info.userData = &mRenderCallbackInput;
+ info.reserved = nullptr;
+
+ // pass render callback input
+ mRenderCallbackInput.size = size;
+ mRenderCallbackInput.projection = projectionMatrix;
+ Matrix::Multiply(mRenderCallbackInput.mvp, modelViewMatrix, projectionMatrix);
+
+ // submit draw
+ commandBuffer.DrawNative(&info);
+ return true;
+ }
+
// Prepare commands
std::vector<DevelRenderer::DrawCommand*> commands;
for(auto& cmd : mDrawCommands)
return true;
}
- if(mShaderChanged || mGeometry->AttributesChanged())
+ if(mRenderCallback || mShaderChanged || mGeometry->AttributesChanged())
{
return true;
}
return *pipelineResult.pipeline;
}
+void Renderer::SetRenderCallback(RenderCallback* callback)
+{
+ mRenderCallback = callback;
+}
+
} // namespace Render
} // namespace Dali::Internal
#define DALI_INTERNAL_RENDER_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/public-api/math/matrix.h>
#include <dali/public-api/math/vector4.h>
#include <dali/public-api/rendering/texture-set.h>
+#include <dali/public-api/signals/render-callback.h>
#include <dali/graphics-api/graphics-controller.h>
#include <dali/integration-api/debug.h>
uint32_t queueIndex);
/**
+ * Sets RenderCallback object
+ *
+ * @param[in] callback Valid pointer to RenderCallback object
+ */
+ void SetRenderCallback(RenderCallback* callback);
+
+ /**
+ * Returns currently set RenderCallback object
+ *
+ * @return Valid pointer to RenderCallback object or nullptr
+ */
+ RenderCallback* GetRenderCallback()
+ {
+ return mRenderCallback;
+ }
+
+ /**
* Write the renderer's sort attributes to the passed in reference
*
* @param[out] sortAttributes
bool mUpdated : 1;
std::vector<Dali::DevelRenderer::DrawCommand> mDrawCommands; // Devel stuff
+ RenderCallback* mRenderCallback{nullptr};
+ RenderCallbackInput mRenderCallbackInput{};
};
} // namespace Render
Matrix nodeModelViewMatrix(false);
bool nodeModelViewMatrixSet(false);
- if(cull && renderable.mRenderer && !renderable.mRenderer->GetShader().HintEnabled(Dali::Shader::Hint::MODIFIES_GEOMETRY) && node->GetClippingMode() == ClippingMode::DISABLED)
+ // Don't cull items which have render callback
+ bool hasRenderCallback = (renderable.mRenderer && renderable.mRenderer->GetRenderCallback());
+
+ if(cull && renderable.mRenderer && (hasRenderCallback || (!renderable.mRenderer->GetShader().HintEnabled(Dali::Shader::Hint::MODIFIES_GEOMETRY) && node->GetClippingMode() == ClippingMode::DISABLED)))
{
const Vector4& boundingSphere = node->GetBoundingSphere();
inside = (boundingSphere.w > Math::MACHINE_EPSILON_1000) &&
if(inside)
{
- Renderer::OpacityType opacityType = renderable.mRenderer ? renderable.mRenderer->GetOpacityType(updateBufferIndex, *node) : Renderer::OPAQUE;
+ bool skipRender(false);
+ bool isOpaque = true;
+ if(!hasRenderCallback)
+ {
+ Renderer::OpacityType opacityType = renderable.mRenderer ? renderable.mRenderer->GetOpacityType(updateBufferIndex, *node) : Renderer::OPAQUE;
+
+ // We can skip render when node is not clipping and transparent
+ skipRender = (opacityType == Renderer::TRANSPARENT && node->GetClippingMode() == ClippingMode::DISABLED);
+
+ isOpaque = (opacityType == Renderer::OPAQUE);
+ }
- // We can skip render when node is not clipping and transparent
- const bool skipRender(opacityType == Renderer::TRANSPARENT && node->GetClippingMode() == ClippingMode::DISABLED);
if(!skipRender)
{
// Get the next free RenderItem.
auto& partialRenderingCacheInfo = node->GetPartialRenderingData().GetCurrentCacheInfo();
partialRenderingCacheInfo.node = node;
- partialRenderingCacheInfo.isOpaque = (opacityType == Renderer::OPAQUE);
+ partialRenderingCacheInfo.isOpaque = isOpaque;
partialRenderingCacheInfo.renderer = renderable.mRenderer;
partialRenderingCacheInfo.color = node->GetWorldColor(updateBufferIndex);
partialRenderingCacheInfo.depthIndex = node->GetDepthIndex();
}
item.mNode = node;
- item.mIsOpaque = (opacityType == Renderer::OPAQUE);
+ item.mIsOpaque = isOpaque;
item.mColor = node->GetColor(updateBufferIndex);
item.mDepthIndex = 0;
/*
- * 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.
RESEND_STENCIL_OPERATION_ON_Z_PASS = 1 << 17,
RESEND_WRITE_TO_COLOR_BUFFER = 1 << 18,
RESEND_SHADER = 1 << 19,
- RESEND_DRAW_COMMANDS = 1 << 20
+ RESEND_DRAW_COMMANDS = 1 << 20,
+ RESEND_SET_RENDER_CALLBACK = 1 << 21
};
} // Anonymous namespace
new(slot) DerivedType(mRenderer, &Render::Renderer::SetShaderChanged, true);
}
+ if(mResendFlag & RESEND_SET_RENDER_CALLBACK)
+ {
+ using DerivedType = MessageValue1<Render::Renderer, Dali::RenderCallback*>;
+ uint32_t* slot = mSceneController->GetRenderQueue().ReserveMessageSlot(updateBufferIndex, sizeof(DerivedType));
+ new(slot) DerivedType(mRenderer, &Render::Renderer::SetRenderCallback, mRenderCallback);
+ }
+
mResendFlag = 0;
}
mResendFlag |= RESEND_STENCIL_OPERATION_ON_Z_PASS;
}
+void Renderer::SetRenderCallback(RenderCallback* callback)
+{
+ mRenderCallback = callback;
+ mResendFlag |= RESEND_SET_RENDER_CALLBACK;
+}
+
const Render::Renderer::StencilParameters& Renderer::GetStencilParameters() const
{
return mStencilParameters;
return *this;
};
+ /**
+ * Sets RenderCallback object
+ *
+ * @param[in] callback Valid pointer to RenderCallback object
+ */
+ void SetRenderCallback(RenderCallback* callback);
+
+ /**
+ * Returns currently set RenderCallback pointer
+ *
+ * @return RenderCallback pointer or nullptr
+ */
+ RenderCallback* GetRenderCallback()
+ {
+ return mRenderCallback;
+ }
+
public: // Implementation of ConnectionChangePropagator
/**
* @copydoc ConnectionChangePropagator::AddObserver
bool mPremultipledAlphaEnabled : 1; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
std::vector<Dali::DevelRenderer::DrawCommand> mDrawCommands;
+ Dali::RenderCallback* mRenderCallback{nullptr};
public:
AnimatableProperty<float> mOpacity; ///< The opacity value
new(slot) LocalType(&renderer, &Renderer::SetDrawCommands, pDrawCommands, size);
}
+inline void SetRenderCallbackMessage(EventThreadServices& eventThreadServices, const Renderer& renderer, Dali::RenderCallback* callback)
+{
+ using LocalType = MessageValue1<Renderer, Dali::RenderCallback*>;
+
+ // Reserve some memory inside the message queue
+ uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
+
+ new(slot) LocalType(&renderer, &Renderer::SetRenderCallback, callback);
+}
+
} // namespace SceneGraph
} // namespace Internal
} // namespace Dali
--- /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/actors/drawable-actor.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/actors/drawable-actor-impl.h>
+
+using DrawableActorImpl = Dali::Internal::DrawableActor;
+
+namespace Dali
+{
+DrawableActor DrawableActor::New(RenderCallback& callback)
+{
+ auto internal = Internal::DrawableActor::New(&callback);
+ return DrawableActor(internal.Get());
+}
+
+DrawableActor::DrawableActor(Internal::DrawableActor* internal)
+: Actor(internal)
+{
+}
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_DRAWABLE_ACTOR_H
+#define DALI_DRAWABLE_ACTOR_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/actors/actor.h>
+#include <dali/public-api/signals/render-callback.h>
+
+// EXTERNAL INCLUDES
+#include <memory>
+
+namespace Dali
+{
+namespace Internal
+{
+class DrawableActor;
+}
+
+/**
+ * @class DrawableActor
+ *
+ * DrawableActor is a special type of Actor that allows attaching
+ * DrawableCallback in order to pass custom native graphics API
+ * calls (like GLES).
+ *
+ * @SINCE_2_1.15
+ */
+class DALI_CORE_API DrawableActor : public Actor
+{
+public:
+ /**
+ * @brief Creates new DrawableActor instance
+ *
+ * @SINCE_2_1.15
+ * @param[in] callback Reference to the valid DrawableCallback object
+ * @return Handle to the new DrawableActor
+ */
+ static DrawableActor New(RenderCallback& callback);
+
+ /**
+ * @brief Constructor
+ *
+ * @SINCE_2_1.15
+ */
+ DrawableActor() = default;
+
+private:
+ explicit DrawableActor(Internal::DrawableActor* internal);
+};
+} // namespace Dali
+
+#endif // DALI_DRAWABLE_ACTOR_H
${public_api_src_dir}/actors/camera-actor.cpp
${public_api_src_dir}/actors/custom-actor.cpp
${public_api_src_dir}/actors/custom-actor-impl.cpp
+ ${public_api_src_dir}/actors/drawable-actor.cpp
${public_api_src_dir}/actors/layer.cpp
${public_api_src_dir}/animation/animation.cpp
${public_api_src_dir}/animation/alpha-function.cpp
${public_api_src_dir}/signals/signal-slot-observers.cpp
${public_api_src_dir}/signals/base-signal.cpp
${public_api_src_dir}/signals/functor-delegate.cpp
+ ${public_api_src_dir}/signals/render-callback.cpp
${public_api_src_dir}/object/type-info.cpp
${public_api_src_dir}/object/type-registry.cpp
${public_api_src_dir}/object/weak-handle.cpp
${public_api_src_dir}/actors/camera-actor.h
${public_api_src_dir}/actors/custom-actor.h
${public_api_src_dir}/actors/custom-actor-impl.h
+ ${public_api_src_dir}/actors/drawable-actor.h
${public_api_src_dir}/actors/draw-mode.h
${public_api_src_dir}/actors/layer.h
${public_api_src_dir}/actors/sampling.h
${public_api_src_dir}/signals/signal-slot-connections.h
${public_api_src_dir}/signals/signal-slot-observers.h
${public_api_src_dir}/signals/slot-delegate.h
+ ${public_api_src_dir}/signals/render-callback.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.
GetImplementation(*this).SetShader(GetImplementation(shader));
}
+void Renderer::SetRenderCallback(RenderCallback* callback)
+{
+ GetImplementation(*this).SetRenderCallback(callback);
+}
+
Shader Renderer::GetShader() const
{
return Dali::Shader(GetImplementation(*this).GetShader().Get());
namespace Dali
{
+class RenderCallback;
+
/**
* @addtogroup dali_core_rendering_effects
* @{
*/
Shader GetShader() const;
+ /**
+ * @brief Sets RenderCallback to be used for native rendering
+ *
+ * @SINCE_2_1.15
+ * @param[in] callback Pointer to a valid RenderCallback object
+ */
+ void SetRenderCallback(RenderCallback* callback);
+
public:
/// @cond internal
/**
--- /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.
+*
+*/
+
+#include <dali/public-api/signals/render-callback.h>
--- /dev/null
+#ifndef DALI_RENDER_CALLBACK_H
+#define DALI_RENDER_CALLBACK_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/math/matrix.h>
+#include <dali/public-api/math/vector2.h>
+#include <dali/public-api/signals/callback.h>
+
+// EXTERNAL INCLUDES
+#include <memory>
+
+namespace Dali
+{
+/**
+ * @class RenderCallbackInput
+ *
+ * This structure contains data to be passed into the RenderCallback
+ * functor.
+ *
+ * RenderCallbackInput inherits from Graphics::NativeDrawInput
+ *
+ * @SINCE_2_1.14
+ */
+struct RenderCallbackInput
+{
+ Matrix mvp;
+ Matrix projection;
+ Size size;
+};
+
+/**
+ * @class DrawableCallback
+ *
+ * The class wraps CallbackBase object ensuring its type-safe assignment
+ *
+ * @SINCE_2_1.14
+ */
+class RenderCallback
+{
+public:
+ /**
+ * Templated member function type
+ */
+ template<class T>
+ using FuncType = bool (T::*)(const RenderCallbackInput&);
+
+ /**
+ * @brief Constructor of RenderCallback
+ *
+ * @param[in] object Object to invoke
+ * @param[in] func Member function to invoke
+ *
+ * @SINCE_2_1.14
+ */
+ template<class T>
+ RenderCallback(T* object, FuncType<T> func)
+ : mCallback(MakeCallback(object, func))
+ {
+ }
+
+ /**
+ * @brief Creates new instance of RenderCallback
+ *
+ * @SINCE_2_1.14
+ * @param[in] object Object to invoke
+ * @param[in] func Member function to invoke
+ * @return Unique pointer to the RenderCallback instance
+ */
+ template<class T>
+ static std::unique_ptr<RenderCallback> New(T* object, FuncType<T> func)
+ {
+ return std::make_unique<RenderCallback>(object, func);
+ }
+
+ /**
+ * @brief Explicit cast operator
+ *
+ * @SINCE_2_1.14
+ * @return casts RenderCallback to CallbackBase object
+ */
+ explicit operator CallbackBase*()
+ {
+ return mCallback.get();
+ }
+
+ /**
+ * @brief Explicit cast operator
+ *
+ * @SINCE_2_1.14
+ * @return casts RenderCallback to CallbackBase object
+ */
+ explicit operator CallbackBase&()
+ {
+ return *mCallback;
+ }
+
+private:
+ std::unique_ptr<CallbackBase> mCallback; //< Callback base object
+};
+} // namespace Dali
+
+#endif // DALI_RENDER_CALLBACK_H