END_TEST;
}
+
+int utcDaliRendererDoNotSkipRenderIfTextureSetChanged(void)
+{
+ TestApplication application;
+ tet_infoline("Check to not skip rendering in case of the TextureSet Changed");
+
+ TraceCallStack& drawTrace = application.GetGlAbstraction().GetDrawTrace();
+ drawTrace.Enable(true);
+ drawTrace.Reset();
+
+ Actor actor = CreateRenderableActor();
+ actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ actor.SetProperty(Actor::Property::SIZE, Vector3(80.0f, 80.0f, 0.0f));
+ application.GetScene().Add(actor);
+
+ // Make any animation to skip rendering.
+ // Delay duration must be bigger than 0.0f
+ Animation animation = Animation::New(2.0f);
+ animation.AnimateTo(Property(actor, Actor::Property::POSITION_X), 1.0f, TimePeriod(1.0f, 1.0f));
+ animation.Play();
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+
+ Renderer renderer = actor.GetRendererAt(0u);
+
+ Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGB888, 64, 64);
+ TextureSet textureSet = CreateTextureSet(image);
+
+ // Render at least 2 frames
+ application.SendNotification();
+ application.Render();
+ application.SendNotification();
+ application.Render();
+
+ drawTrace.Reset();
+
+ application.SendNotification();
+ application.Render();
+
+ // Skip rendering
+ DALI_TEST_EQUALS(drawTrace.CountMethod("DrawElements"), 0, TEST_LOCATION);
+
+ // Change TextureSet
+ renderer.SetTextures(textureSet);
+
+ application.SendNotification();
+ application.Render(16u);
+
+ // Should not Skip rendering!
+ DALI_TEST_GREATER(drawTrace.CountMethod("DrawElements"), 0, TEST_LOCATION);
+
+ END_TEST;
+}
\ No newline at end of file
Stage& Stage::operator=(const Stage& rhs) = default;
-Stage::Stage(Stage&& handle) = default;
+Stage::Stage(Stage&& handle) noexcept = default;
-Stage& Stage::operator=(Stage&& rhs) = default;
+Stage& Stage::operator=(Stage&& rhs) noexcept = default;
Stage::Stage(Internal::Stage* internal)
: BaseHandle(internal)
*
* @param[in] handle A reference to the moved handle
*/
- Stage(Stage&& handle);
+ Stage(Stage&& handle) noexcept;
/**
* @brief This move assignment operator is required for (smart) pointer semantics.
* @param[in] rhs A reference to the moved handle
* @return A reference to this
*/
- Stage& operator=(Stage&& rhs);
+ Stage& operator=(Stage&& rhs) noexcept;
// Containment
* Move constructor. Passes the ownership of a pointer to another.
* @param[in] other The pointer that gives away the ownership.
*/
- OwnerPointer(OwnerPointer&& other)
+ OwnerPointer(OwnerPointer&& other) noexcept
: mObject(nullptr)
{
Swap(other);
* Move assignment operator. Passes the ownership of a pointer to another.
* @param[in] other The pointer that gives away the ownership.
*/
- OwnerPointer& operator=(OwnerPointer&& other)
+ OwnerPointer& operator=(OwnerPointer&& other) noexcept
{
// Reuse operator=
return operator=(other);
delete mRemoveCallback;
}
-ActorObserver::ActorObserver(ActorObserver&& other)
+ActorObserver::ActorObserver(ActorObserver&& other) noexcept
: ActorObserver(nullptr)
{
operator=(std::move(other));
}
-ActorObserver& ActorObserver::operator=(ActorObserver&& other)
+ActorObserver& ActorObserver::operator=(ActorObserver&& other) noexcept
{
if(this != &other)
{
* @note The other's actor is appropriately disconnected.
* @note Ownership of callback is passed onto this class.
*/
- ActorObserver(ActorObserver&& other);
+ ActorObserver(ActorObserver&& other) noexcept;
/**
* Move assignment operator.
* @note The other's actor is appropriately disconnected.
* @note Ownership of callback is passed onto this class.
*/
- ActorObserver& operator=(ActorObserver&& other);
+ ActorObserver& operator=(ActorObserver&& other) noexcept;
// Not copyable
std::unique_ptr<Dali::ThreadPool> threadPool; ///< The thread pool
Vector<Graphics::Texture*> boundTextures; ///< The textures bound for rendering
Vector<Graphics::Texture*> textureDependencyList; ///< The dependency list of bound textures
+ Vector<Render::TextureKey> updatedTextures{}; ///< The updated texture list
uint32_t frameCount{0u}; ///< The current frame count
BufferIndex renderBufferIndex{SceneGraphBuffers::INITIAL_UPDATE_BUFFER_INDEX}; ///< The index of the buffer to read from; this is opposite of the "update" buffer
textureKey->Initialize(mImpl->graphicsController);
mImpl->textureContainer.PushBack(textureKey);
+ mImpl->updatedTextures.PushBack(textureKey);
}
void RenderManager::RemoveTexture(const Render::TextureKey& textureKey)
{
DALI_ASSERT_DEBUG(textureKey && "Trying to upload to empty texture key");
textureKey->Upload(pixelData, params);
+
+ mImpl->updatedTextures.PushBack(textureKey);
}
void RenderManager::GenerateMipmaps(const Render::TextureKey& textureKey)
{
DALI_ASSERT_DEBUG(textureKey && "Trying to generate mipmaps on empty texture key");
textureKey->GenerateMipmaps();
+
+ mImpl->updatedTextures.PushBack(textureKey);
+}
+
+void RenderManager::SetTextureUpdated(const Render::TextureKey& textureKey)
+{
+ DALI_ASSERT_DEBUG(textureKey && "Trying to set updated on empty texture key");
+ textureKey->SetUpdated(true);
+
+ mImpl->updatedTextures.PushBack(textureKey);
}
void RenderManager::SetFilterMode(Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode)
iter->OnRenderFinished();
}
- // Notify RenderTexture that rendering has finished
- for(auto&& iter : mImpl->textureContainer)
+ // Notify updated RenderTexture that rendering has finished
+ for(auto&& iter : mImpl->updatedTextures)
{
iter->OnRenderFinished();
}
+ mImpl->updatedTextures.Clear();
mImpl->UpdateTrackers();
void GenerateMipmaps(const Render::TextureKey& texture);
/**
+ * Sets the updated flag of a texture
+ * @param[in] texture The updated texture
+ */
+ void SetTextureUpdated(const Render::TextureKey& textureKey);
+
+ /**
* Adds a framebuffer to the render manager
* @param[in] frameBuffer The framebuffer to add
*/
new(slot) DerivedType(&mRenderManager, &RenderManager::RemoveRenderTracker, &renderTracker);
}
+RenderManager& RenderMessageDispatcher::GetRenderManager()
+{
+ return mRenderManager;
+}
+
+uint32_t* RenderMessageDispatcher::ReserveMessageSlot(std::size_t size)
+{
+ return mRenderQueue.ReserveMessageSlot(mBuffers.GetUpdateBufferIndex(), size);
+}
+
} // namespace SceneGraph
} // namespace Internal
*/
void RemoveRenderTracker(Render::RenderTracker& renderTracker);
+ /**
+ * Return the render manager.
+ * @return A reference to the render manager.
+ */
+ RenderManager& GetRenderManager();
+
+ /**
+ * Reserve space for another message in the queue.
+ * @param[in] size The message size with respect to the size of type "char".
+ * @return A pointer to the first char allocated for the message.
+ */
+ uint32_t* ReserveMessageSlot(std::size_t size);
+
private:
RenderManager& mRenderManager;
RenderQueue& mRenderQueue;
void UpdateManager::AddTextureSet(OwnerPointer<TextureSet>& textureSet)
{
+ textureSet->SetRenderMessageDispatcher(&mImpl->renderMessageDispatcher);
mImpl->textureSets.PushBack(textureSet.Release());
}
bool Renderer::PrepareRender(BufferIndex updateBufferIndex)
{
- bool rendererUpdated = mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY || mUpdateDecay > 0;
+ bool rendererUpdated = mDirtyFlag || mResendFlag || mRenderingBehavior == DevelRenderer::Rendering::CONTINUOUSLY || mUpdateDecay > 0;
auto shaderMapChangeCounter = mShader ? mShader->GetUniformMap().GetChangeCounter() : 0u;
bool shaderMapChanged = mShader && (mShaderMapChangeCounter != shaderMapChangeCounter);
if(shaderMapChanged)
DALI_ASSERT_DEBUG(geometry != NULL && "Geometry pointer is NULL");
mGeometry = geometry;
+ mDirtyFlag = true;
if(mRenderer)
{
mResendFlag |= RESEND_GEOMETRY;
void Renderer::SetRenderingBehavior(DevelRenderer::Rendering::Type renderingBehavior)
{
mRenderingBehavior = renderingBehavior;
+
+ mDirtyFlag = true;
SetUpdated(true);
}
// INTERNAL HEADERS
#include <dali/internal/common/internal-constants.h>
#include <dali/internal/common/memory-pool-object-allocator.h>
+#include <dali/internal/render/common/render-manager.h>
#include <dali/internal/render/renderers/render-texture.h>
+#include <dali/internal/update/controllers/render-message-dispatcher.h>
#include <dali/internal/update/rendering/scene-graph-renderer.h>
namespace //Unnamed namespace
if(index < static_cast<uint32_t>(mTextures.Size()))
{
- mTextures[index]->SetUpdated(true);
+ // Send a message to the RenderManagerReserveMessageSlot
+ using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
+
+ // Reserve some memory inside the render queue
+ uint32_t* slot = mRenderMessageDispatcher->ReserveMessageSlot(sizeof(DerivedType));
+
+ // Construct message in the render queue memory; note that delete should not be called on the return value
+ new(slot) DerivedType(&mRenderMessageDispatcher->GetRenderManager(), &RenderManager::SetTextureUpdated, mTextures[index]);
}
}
if(texture)
{
mHasAlpha |= texture->HasAlphaChannel();
- texture->SetUpdated(true);
+
+ // Send a message to the RenderManagerReserveMessageSlot
+ using DerivedType = MessageValue1<RenderManager, Render::TextureKey>;
+
+ // Reserve some memory inside the render queue
+ uint32_t* slot = mRenderMessageDispatcher->ReserveMessageSlot(sizeof(DerivedType));
+
+ // Construct message in the render queue memory; note that delete should not be called on the return value
+ new(slot) DerivedType(&mRenderMessageDispatcher->GetRenderManager(), &RenderManager::SetTextureUpdated, texture);
}
}
return mHasAlpha;
}
+void TextureSet::SetRenderMessageDispatcher(RenderMessageDispatcher* renderMessageDispatcher)
+{
+ mRenderMessageDispatcher = renderMessageDispatcher;
+}
+
uint32_t TextureSet::GetMemoryPoolCapacity()
{
return GetTextureSetMemoryPool().GetCapacity();
namespace SceneGraph
{
class Renderer;
+class RenderMessageDispatcher;
class TextureSet
{
}
/**
+ * Set the renderMessageDispatcher to send message.
+ * @param[in] renderMessageDispatcher The renderMessageDispatcher to send messages.
+ */
+ void SetRenderMessageDispatcher(RenderMessageDispatcher* renderMessageDispatcher);
+
+ /**
* Get the capacity of the memory pools
* @return the capacity of the memory pools
*/
TextureSet();
private:
- Vector<Render::Sampler*> mSamplers; ///< List of samplers used by each texture. Not owned
- Vector<Render::TextureKey> mTextures; ///< List of Textures. Not owned
- bool mHasAlpha; ///< if any of the textures has an alpha channel
+ Vector<Render::Sampler*> mSamplers; ///< List of samplers used by each texture. Not owned
+ Vector<Render::TextureKey> mTextures; ///< List of Textures. Not owned
+ RenderMessageDispatcher* mRenderMessageDispatcher{nullptr}; ///< for sending messages to render thread. Not owned
+ bool mHasAlpha; ///< if any of the textures has an alpha channel
};
inline void SetTextureMessage(EventThreadServices& eventThreadServices, const TextureSet& textureSet, uint32_t index, const Render::TextureKey& textureKey)
{
const uint32_t CORE_MAJOR_VERSION = 2;
const uint32_t CORE_MINOR_VERSION = 2;
-const uint32_t CORE_MICRO_VERSION = 18;
+const uint32_t CORE_MICRO_VERSION = 19;
const char* const CORE_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2
Summary: DALi 3D Engine
-Version: 2.2.18
+Version: 2.2.19
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT