/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
* These textures are based off version of Wave engine sample
* Take from https://github.com/WaveEngine/Samples
*
- * Copyright (c) 2023 Wave Coorporation
+ * Copyright (c) 2024 Wave Coorporation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
{
ToolkitTestApplication application;
- uint32_t renderTaskCount = application.GetScene().GetRenderTaskList().GetTaskCount();
- DALI_TEST_EQUALS(1u, renderTaskCount, TEST_LOCATION);
+ uint32_t baseRenderTaskCount = application.GetScene().GetRenderTaskList().GetTaskCount();
Scene3D::SceneView view = Scene3D::SceneView::New();
- renderTaskCount = application.GetScene().GetRenderTaskList().GetTaskCount();
- DALI_TEST_EQUALS(1u, renderTaskCount, TEST_LOCATION);
+ uint32_t renderTaskCount = application.GetScene().GetRenderTaskList().GetTaskCount();
+ DALI_TEST_EQUALS(baseRenderTaskCount, renderTaskCount, TEST_LOCATION);
application.GetScene().Add(view);
application.Render();
renderTaskCount = application.GetScene().GetRenderTaskList().GetTaskCount();
- DALI_TEST_EQUALS(3u, renderTaskCount, TEST_LOCATION);
+ DALI_TEST_EQUALS(baseRenderTaskCount + 2u, renderTaskCount, TEST_LOCATION);
- RenderTask renderTask = application.GetScene().GetRenderTaskList().GetTask(2u);
+ RenderTask renderTask = application.GetScene().GetRenderTaskList().GetTask(baseRenderTaskCount + 1u);
CameraActor camera = renderTask.GetCameraActor();
CameraActor defaultCamera = renderTask.GetCameraActor();
{
ToolkitTestApplication application;
+ uint32_t baseRenderTaskCount = application.GetScene().GetRenderTaskList().GetTaskCount();
+
Scene3D::SceneView view = Scene3D::SceneView::New();
view.SetProperty(Dali::Actor::Property::SIZE, Vector2(100, 100));
application.SendNotification();
application.Render();
- RenderTask renderTask = application.GetScene().GetRenderTaskList().GetTask(2u);
+ RenderTask renderTask = application.GetScene().GetRenderTaskList().GetTask(baseRenderTaskCount + 1u);
DALI_TEST_CHECK(!renderTask.GetFrameBuffer());
view.UseFramebuffer(true);
ToolkitTestApplication application;
RenderTaskList taskList = application.GetScene().GetRenderTaskList();
- uint32_t renderTaskCount = taskList.GetTaskCount();
+ uint32_t baseRenderTaskCount = taskList.GetTaskCount();
Scene3D::SceneView view = Scene3D::SceneView::New();
view.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
- DALI_TEST_EQUALS(renderTaskCount, application.GetScene().GetRenderTaskList().GetTaskCount(), TEST_LOCATION);
+ DALI_TEST_EQUALS(baseRenderTaskCount, application.GetScene().GetRenderTaskList().GetTaskCount(), TEST_LOCATION);
application.GetScene().Add(view);
- DALI_TEST_EQUALS(renderTaskCount + 2, application.GetScene().GetRenderTaskList().GetTaskCount(), TEST_LOCATION);
+ DALI_TEST_EQUALS(baseRenderTaskCount + 2, application.GetScene().GetRenderTaskList().GetTaskCount(), TEST_LOCATION);
view.Unparent();
- DALI_TEST_EQUALS(renderTaskCount, application.GetScene().GetRenderTaskList().GetTaskCount(), TEST_LOCATION);
+ DALI_TEST_EQUALS(baseRenderTaskCount, application.GetScene().GetRenderTaskList().GetTaskCount(), TEST_LOCATION);
END_TEST;
}
END_TEST;
}
+int UtcDaliSceneViewSetResolution02(void)
+{
+ tet_infoline("Test whether framebuffer created well base on inputed resolution");
+ ToolkitTestApplication application;
+ RenderTaskList renderTaskList = application.GetScene().GetRenderTaskList();
+
+ uint32_t baseRenderTaskCount = renderTaskList.GetTaskCount();
+
+ Scene3D::SceneView view = Scene3D::SceneView::New();
+ application.GetScene().Add(view);
+ view.SetProperty(Dali::Actor::Property::SIZE, Vector2(100, 100));
+
+ DALI_TEST_EQUALS(view.GetResolutionWidth(), 100u, TEST_LOCATION);
+ DALI_TEST_EQUALS(view.GetResolutionHeight(), 100u, TEST_LOCATION);
+
+ uint32_t expectWidth = 83u;
+ uint32_t expectHeight = 207u;
+
+ view.SetResolution(expectWidth, expectHeight);
+
+ DALI_TEST_EQUALS(view.GetResolutionWidth(), 100u, TEST_LOCATION);
+ DALI_TEST_EQUALS(view.GetResolutionHeight(), 100u, TEST_LOCATION);
+
+ tet_printf("Test Framebuffer result target created well\n");
+ view.UseFramebuffer(true);
+
+ RenderTask renderTask = renderTaskList.GetTask(baseRenderTaskCount + 1u);
+ DALI_TEST_CHECK(renderTask);
+
+ FrameBuffer frameBuffer = renderTask.GetFrameBuffer();
+ DALI_TEST_CHECK(frameBuffer);
+
+ DALI_TEST_EQUALS(view.GetResolutionWidth(), expectWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(view.GetResolutionHeight(), expectHeight, TEST_LOCATION);
+
+ Texture renderTargetTexture = frameBuffer.GetColorTexture();
+ DALI_TEST_CHECK(renderTargetTexture);
+ DALI_TEST_EQUALS(renderTargetTexture.GetWidth(), expectWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(renderTargetTexture.GetHeight(), expectHeight, TEST_LOCATION);
+
+ tet_printf("Test Framebuffer result target created well after create new FBO, by set multisampling level\n");
+ view.SetFramebufferMultiSamplingLevel(2u);
+
+ renderTask = renderTaskList.GetTask(baseRenderTaskCount + 1u);
+ DALI_TEST_CHECK(renderTask);
+
+ frameBuffer = renderTask.GetFrameBuffer();
+ DALI_TEST_CHECK(frameBuffer);
+
+ DALI_TEST_EQUALS(view.GetResolutionWidth(), expectWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(view.GetResolutionHeight(), expectHeight, TEST_LOCATION);
+
+ renderTargetTexture = frameBuffer.GetColorTexture();
+ DALI_TEST_CHECK(renderTargetTexture);
+
+ DALI_TEST_EQUALS(renderTargetTexture.GetWidth(), expectWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(renderTargetTexture.GetHeight(), expectHeight, TEST_LOCATION);
+
+ tet_printf("Test Framebuffer result target created well after change resolution\n");
+ expectWidth = 421u;
+ expectHeight = 103u;
+ view.SetResolution(expectWidth, expectHeight);
+
+ renderTask = renderTaskList.GetTask(baseRenderTaskCount + 1u);
+ DALI_TEST_CHECK(renderTask);
+
+ frameBuffer = renderTask.GetFrameBuffer();
+ DALI_TEST_CHECK(frameBuffer);
+
+ DALI_TEST_EQUALS(view.GetResolutionWidth(), expectWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(view.GetResolutionHeight(), expectHeight, TEST_LOCATION);
+
+ renderTargetTexture = frameBuffer.GetColorTexture();
+ DALI_TEST_CHECK(renderTargetTexture);
+
+ DALI_TEST_EQUALS(renderTargetTexture.GetWidth(), expectWidth, TEST_LOCATION);
+ DALI_TEST_EQUALS(renderTargetTexture.GetHeight(), expectHeight, TEST_LOCATION);
+
+ END_TEST;
+}
+
namespace
{
const char* TEST_MASK_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/mask.png";
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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 "test-graphics-texture.h"
+#include <dali/integration-api/pixel-data-integ.h>
#include <iostream>
#include <sstream>
updateInfo.srcExtent2D.width != (mCreateInfo.size.width / (1 << updateInfo.level)) ||
updateInfo.srcExtent2D.height != (mCreateInfo.size.height / (1 << updateInfo.level)));
+ uint8_t* pixels = nullptr;
+ bool releasePixels = false;
+
+ switch(source.sourceType)
+ {
+ case Graphics::TextureUpdateSourceInfo::Type::PIXEL_DATA:
+ {
+ auto pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(source.pixelDataSource.pixelData);
+
+ pixels = pixelDataBuffer.buffer;
+ releasePixels = Dali::Integration::IsPixelDataReleaseAfterUpload(source.pixelDataSource.pixelData) && updateInfo.srcOffset == 0u;
+ break;
+ }
+ case Graphics::TextureUpdateSourceInfo::Type::MEMORY:
+ {
+ pixels = reinterpret_cast<uint8_t*>(source.memorySource.memory);
+ releasePixels = true;
+ break;
+ }
+ default:
+ {
+ // TODO : Implement here
+ break;
+ }
+ }
+
if(!isSubImage)
{
if(!mIsCompressed)
{
- mGlAbstraction.TexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, mGlFormat, mPixelDataType, source.memorySource.memory);
+ mGlAbstraction.TexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, mGlFormat, mPixelDataType, pixels);
}
else
{
- mGlAbstraction.CompressedTexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, updateInfo.srcSize, source.memorySource.memory);
+ mGlAbstraction.CompressedTexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, updateInfo.srcSize, pixels);
}
}
else
{
if(!mIsCompressed)
{
- mGlAbstraction.TexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, mPixelDataType, source.memorySource.memory);
+ mGlAbstraction.TexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, mPixelDataType, pixels);
}
else
{
- mGlAbstraction.CompressedTexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, updateInfo.srcSize, source.memorySource.memory);
+ mGlAbstraction.CompressedTexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, updateInfo.srcSize, pixels);
+ }
+ }
+
+ if(releasePixels && pixels != nullptr)
+ {
+ switch(source.sourceType)
+ {
+ case Graphics::TextureUpdateSourceInfo::Type::PIXEL_DATA:
+ {
+ Dali::Integration::ReleasePixelDataBuffer(source.pixelDataSource.pixelData);
+ break;
+ }
+ case Graphics::TextureUpdateSourceInfo::Type::MEMORY:
+ {
+ free(reinterpret_cast<void*>(pixels));
+ break;
+ }
+ default:
+ {
+ // TODO : Implement here
+ break;
+ }
}
}
}
END_TEST;
}
+int UtcDaliToolkitTextlabelFastTextFitStressTest(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextlabelFastTextFitStressTest");
+ TextLabel label = TextLabel::New();
+ label.SetProperty(TextLabel::Property::TEXT, "Hello world");
+ label.SetProperty(TextLabel::Property::POINT_SIZE, 120.f);
+
+ // connect to the text git changed signal.
+ ConnectionTracker* testTracker = new ConnectionTracker();
+ DevelTextLabel::TextFitChangedSignal(label).Connect(&TestTextFitChangedCallback);
+ bool textFitChangedSignal = false;
+ label.ConnectSignal(testTracker, "textFitChanged", CallbackFunctor(&textFitChangedSignal));
+ gTextFitChangedCallBackCalled = false;
+
+ application.GetScene().Add(label);
+
+ // check text label width at range [100, 299]
+ for(int i=100; i<300; i++)
+ {
+ Vector2 size((float)i, 200.f);
+ label.SetProperty(Actor::Property::SIZE, size);
+
+ // check point size with veryvery big range
+ Property::Map textFitMapSet;
+ textFitMapSet["enable"] = true;
+ textFitMapSet["minSize"] = 10.f;
+ textFitMapSet["maxSize"] = 10000.f;
+ textFitMapSet["stepSize"] = -1.0f;
+ textFitMapSet["fontSizeType"] = "pointSize";
+
+ label.SetProperty(Toolkit::DevelTextLabel::Property::TEXT_FIT, textFitMapSet);
+
+ application.SendNotification();
+ application.Render();
+ }
+
+ DALI_TEST_CHECK(gTextFitChangedCallBackCalled);
+ DALI_TEST_CHECK(textFitChangedSignal);
+
+ END_TEST;
+}
+
+int UtcDaliToolkitTextlabelTextFitMultiLine(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextlabelTextFitMultiLine");
+ TextLabel label = TextLabel::New();
+ Vector2 size(500.0f, 100.0f);
+ label.SetProperty(Actor::Property::SIZE, size);
+ label.SetProperty(TextLabel::Property::TEXT, "Hello world\nHello world");
+ label.SetProperty(TextLabel::Property::MULTI_LINE, true);
+
+ // connect to the text git changed signal.
+ ConnectionTracker* testTracker = new ConnectionTracker();
+ DevelTextLabel::TextFitChangedSignal(label).Connect(&TestTextFitChangedCallback);
+ bool textFitChangedSignal = false;
+ label.ConnectSignal(testTracker, "textFitChanged", CallbackFunctor(&textFitChangedSignal));
+ gTextFitChangedCallBackCalled = false;
+
+ Property::Map textFitMapSet;
+ textFitMapSet["enable"] = true;
+ textFitMapSet["minSize"] = 10.f;
+ textFitMapSet["maxSize"] = 100.f;
+ textFitMapSet["stepSize"] = -1.0f;
+ textFitMapSet["fontSizeType"] = "pointSize";
+
+ label.SetProperty(Toolkit::DevelTextLabel::Property::TEXT_FIT, textFitMapSet);
+ label.SetProperty(TextLabel::Property::POINT_SIZE, 120.f);
+
+ application.GetScene().Add(label);
+
+ application.SendNotification();
+ application.Render();
+
+ float textFitFontSize = (label.GetProperty(Dali::Toolkit::DevelTextLabel::Property::TEXT_FIT).Get<Property::Map>())["fontSize"].Get<float>();
+ DALI_TEST_EQUALS(textFitFontSize, 14.f, TEST_LOCATION);
+
+ DALI_TEST_CHECK(gTextFitChangedCallBackCalled);
+ DALI_TEST_CHECK(textFitChangedSignal);
+
+ END_TEST;
+}
+
int UtcDaliToolkitTextlabelTextFitArray(void)
{
ToolkitTestApplication application;
// let each deformable body knows which solver body is in constact
void pairDeformableAndSolverBody(btCollisionObject** bodies, int numBodies, int numDeformableBodies, const btContactSolverInfo& infoGlobal);
+ // Modified by Samsung to compile under GCC13. 2024-01-10. eunkiki.hong@samsung.com
+ using btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIterations;
virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject * *bodies, int numBodies, btCollisionObject** deformableBodies, int numDeformableBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
virtual btScalar solveDeformableGroupIterations(btCollisionObject * *bodies, int numBodies, btCollisionObject** deformableBodies, int numDeformableBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
void positionCorrection(btScalar timeStep);
+ // Modified by Samsung to compile under GCC13. 2024-01-10. eunkiki.hong@samsung.com
+ using btMultiBodyDynamicsWorld::solveConstraints;
void solveConstraints(btScalar timeStep);
void updateActivationState(btScalar timeStep);
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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-scene3d/internal/common/image-resource-loader.h>
// EXTERNAL INCLUDES
-#include <dali-toolkit/public-api/image-loader/sync-image-loader.h>
+#include <dali/devel-api/adaptor-framework/image-loading.h>
#include <dali/devel-api/adaptor-framework/lifecycle-controller.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
#include <dali/devel-api/common/hash.h>
#include <dali/devel-api/common/map-wrapper.h>
#include <dali/devel-api/threading/mutex.h>
#include <dali/integration-api/adaptor-framework/adaptor.h>
#include <dali/integration-api/debug.h>
+#include <dali/integration-api/pixel-data-integ.h>
#include <dali/public-api/adaptor-framework/timer.h>
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/object/base-object.h>
Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_IMAGE_RESOURCE_LOADER");
#endif
+bool SupportPixelDataCache(Dali::PixelData pixelData)
+{
+ // Check given pixelData support to release data after upload.
+ // This is cause we need to reduce CPU memory usage.
+ if(Dali::Integration::IsPixelDataReleaseAfterUpload(pixelData))
+ {
+ return true;
+ }
+
+ // Check given pixelData is default pixelData.
+ if(pixelData == Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataWhiteRGB() ||
+ pixelData == Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataWhiteRGBA() ||
+ pixelData == Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataZAxisRGB() ||
+ pixelData == Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataZAxisAndAlphaRGBA())
+ {
+ return true;
+ }
+ return false;
+}
+
+bool SupportPixelDataListCache(const std::vector<std::vector<Dali::PixelData>>& pixelDataList)
+{
+ for(const auto& pixelDataListLevel0 : pixelDataList)
+ {
+ for(const auto& pixelData : pixelDataListLevel0)
+ {
+ if(!SupportPixelDataCache(pixelData))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
struct ImageInformation
{
ImageInformation(const std::string url,
// Item Creation functor list
-Dali::PixelData CreatePixelDataFromImageInfo(const ImageInformation& info, bool /* Not used */)
+Dali::PixelData CreatePixelDataFromImageInfo(const ImageInformation& info, bool releasePixelData)
{
- return Dali::Toolkit::SyncImageLoader::Load(info.mUrl, info.mDimensions, info.mFittingMode, info.mSamplingMode, info.mOrientationCorrection);
+ Dali::PixelData pixelData;
+
+ // Load the image synchronously (block the thread here).
+ Dali::Devel::PixelBuffer pixelBuffer = Dali::LoadImageFromFile(info.mUrl, info.mDimensions, info.mFittingMode, info.mSamplingMode, info.mOrientationCorrection);
+ if(pixelBuffer)
+ {
+ pixelData = Dali::Devel::PixelBuffer::Convert(pixelBuffer, releasePixelData);
+ }
+ return pixelData;
}
Dali::Texture CreateTextureFromPixelData(const Dali::PixelData& pixelData, bool mipmapRequired)
* @brief Try to get cached pixel data, or newly create if there is no pixel data that already cached.
*
* @param[in] info The informations of image to load.
+ * @param[in] releasePixelData Whether we need to release pixel data after upload, or not.
* @return Texture that has been cached. Or empty handle if we fail to found cached item.
*/
- Dali::PixelData GetOrCreateCachedPixelData(const ImageInformation& info)
+ Dali::PixelData GetOrCreateCachedPixelData(const ImageInformation& info, bool releasePixelData)
{
auto hashValue = GenerateHash(info);
- return GetOrCreateCachedItem<true, ImageInformation, Dali::PixelData, CreatePixelDataFromImageInfo>(mPixelDataCache, hashValue, info, false, mPixelDataContainerUpdated);
+ return GetOrCreateCachedItem<true, ImageInformation, Dali::PixelData, CreatePixelDataFromImageInfo>(mPixelDataCache, hashValue, info, releasePixelData, mPixelDataContainerUpdated);
}
private: // Called by main thread
namespace ImageResourceLoader
{
// Called by main thread..
-Dali::PixelData GetEmptyPixelDataWhiteRGB()
-{
- static Dali::PixelData emptyPixelData = PixelData::New(new uint8_t[3]{0xff, 0xff, 0xff}, 3, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY);
- return emptyPixelData;
-}
-
Dali::Texture GetEmptyTextureWhiteRGB()
{
if(!gEmptyTextureWhiteRGB)
Dali::Texture GetCachedTexture(Dali::PixelData pixelData, bool mipmapRequired)
{
- return GetCacheImpl()->GetOrCreateCachedTexture(pixelData, mipmapRequired);
+ if(SupportPixelDataCache(pixelData))
+ {
+ return GetCacheImpl()->GetOrCreateCachedTexture(pixelData, mipmapRequired);
+ }
+ else
+ {
+ return CreateTextureFromPixelData(pixelData, mipmapRequired);
+ }
}
Dali::Texture GetCachedCubeTexture(const std::vector<std::vector<Dali::PixelData>>& pixelDataList, bool mipmapRequired)
{
- return GetCacheImpl()->GetOrCreateCachedCubeTexture(pixelDataList, mipmapRequired);
+ if(SupportPixelDataListCache(pixelDataList))
+ {
+ return GetCacheImpl()->GetOrCreateCachedCubeTexture(pixelDataList, mipmapRequired);
+ }
+ else
+ {
+ return CreateCubeTextureFromPixelDataList(pixelDataList, mipmapRequired);
+ }
}
void RequestGarbageCollect(bool fullCollect)
}
// Can be called by worker thread.
+Dali::PixelData GetEmptyPixelDataWhiteRGB()
+{
+ static Dali::PixelData emptyPixelData = PixelData::New(new uint8_t[3]{0xff, 0xff, 0xff}, 3, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY);
+ return emptyPixelData;
+}
+
+Dali::PixelData GetEmptyPixelDataWhiteRGBA()
+{
+ static Dali::PixelData emptyPixelData = PixelData::New(new uint8_t[4]{0xff, 0xff, 0xff, 0xff}, 4, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY);
+ return emptyPixelData;
+}
+
+Dali::PixelData GetEmptyPixelDataZAxisRGB()
+{
+ static Dali::PixelData emptyPixelData = PixelData::New(new uint8_t[3]{0x7f, 0x7f, 0xff}, 3, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY);
+ return emptyPixelData;
+}
+
+Dali::PixelData GetEmptyPixelDataZAxisAndAlphaRGBA()
+{
+ static Dali::PixelData emptyPixelData = PixelData::New(new uint8_t[4]{0x7f, 0x7f, 0xff, 0xff}, 4, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY);
+ return emptyPixelData;
+}
+
Dali::PixelData GetCachedPixelData(const std::string& url)
{
return GetCachedPixelData(url, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true);
}
else
{
- return GetCacheImpl()->GetOrCreateCachedPixelData(info);
+ return GetCacheImpl()->GetOrCreateCachedPixelData(info, true);
}
}
} // namespace ImageResourceLoader
#define DALI_SCENE3D_IMAGE_RESOURCE_LOADER_H
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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::PixelData GetEmptyPixelDataWhiteRGB();
/**
+ * @brief Get cached pixelData handle filled as white with RGBA8888 format.
+ * @return A PixelData object containing the white RGBA8888 color.
+ */
+Dali::PixelData GetEmptyPixelDataWhiteRGBA();
+
+/**
+ * @brief Get cached pixelData handle that will be used for Z-Axis with RGB8888 format.
+ * @return A PixelData object containing the Z-Axis RGB8888 color.
+ */
+Dali::PixelData GetEmptyPixelDataZAxisRGB();
+
+/**
+ * @brief Get cached pixelData handle that will be used for Z-Axis and 1.0 alpha with RGBA8888 format.
+ * @return A PixelData object containing the Z-Axis and 1.0 alpha RGBA8888 color.
+ */
+Dali::PixelData GetEmptyPixelDataZAxisAndAlphaRGBA();
+
+/**
* @brief Get cached image, or loads an image synchronously.
* @note If cache handler is not created yet, or destroyed due to app terminated, it will load image synchronously without cache.
* @param[in] url The URL of the image file to load
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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 ResetResourceTask(IntrusivePtr<AsyncTask>&& asyncTask)
+{
+ if(!asyncTask)
+ {
+ return;
+ }
+ Dali::AsyncTaskManager::Get().RemoveTask(asyncTask);
+ asyncTask.Reset();
+}
+
} // anonymous namespace
Model::Model(const std::string& modelUrl, const std::string& resourceDirectoryUrl)
mDiffuseTexture.Reset();
mSpecularTexture.Reset();
UpdateImageBasedLightTexture();
+
+ // Request image resource GC
+ Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
}
else
{
mIblDiffuseLoadTask = new EnvironmentMapLoadTask(mDiffuseIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, MakeCallback(this, &Model::OnIblDiffuseLoadComplete));
Dali::AsyncTaskManager::Get().AddTask(mIblDiffuseLoadTask);
mIblDiffuseDirty = false;
+
+ // Request image resource GC
+ Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
}
if(isOnScene && mIblSpecularDirty)
mIblSpecularLoadTask = new EnvironmentMapLoadTask(mSpecularIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, MakeCallback(this, &Model::OnIblSpecularLoadComplete));
Dali::AsyncTaskManager::Get().AddTask(mIblSpecularLoadTask);
mIblSpecularDirty = false;
+
+ // Request image resource GC
+ Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
}
}
ResetResourceTask(mIblSpecularLoadTask);
}
-void Model::ResetResourceTask(IntrusivePtr<AsyncTask> asyncTask)
-{
- if(!asyncTask)
- {
- return;
- }
- Dali::AsyncTaskManager::Get().RemoveTask(asyncTask);
- asyncTask.Reset();
-}
-
void Model::NotifyResourceReady()
{
if(!IsResourceReady())
#define DALI_SCENE3D_INTERNAL_MODEL_H
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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 ResetResourceTasks();
/**
- * @brief Reset a Resource loading task.
- */
- void ResetResourceTask(IntrusivePtr<AsyncTask> asyncTask);
-
- /**
* @brief Notify Resource Ready signal.
*/
void NotifyResourceReady();
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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 <string_view>
// INTERNAL INCLUDES
+#include <dali-scene3d/internal/common/image-resource-loader.h>
#include <dali-scene3d/internal/controls/model/model-impl.h>
#include <dali-scene3d/internal/graphics/builtin-shader-extern-gen.h>
#include <dali-scene3d/internal/light/light-impl.h>
constexpr uint32_t MAXIMUM_SIZE_SHADOW_MAP = 2048;
static constexpr std::string_view SKYBOX_INTENSITY_STRING = "uIntensity";
-static constexpr std::string_view Y_FLIP_MASK_TEXTURE = "uYFlipMaskTexture";
-static constexpr float FLIP_MASK_TEXTURE = 1.0f;
+static constexpr std::string_view Y_FLIP_MASK_TEXTURE = "uYFlipMaskTexture";
+static constexpr float FLIP_MASK_TEXTURE = 1.0f;
Dali::Actor CreateSkybox()
{
Dali::AsyncTaskManager::Get().RemoveTask(mSkyboxLoadTask);
mSkyboxLoadTask.Reset();
}
+
+ // Request image resource GC
+ Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
}
}
mSpecularMipmapLevels = 1u;
NotifyImageBasedLightTextureChange();
+
+ // Request image resource GC
+ Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
}
else
{
{
Dali::AsyncTaskManager::Get().RemoveTask(mIblDiffuseLoadTask);
mIblDiffuseLoadTask.Reset();
+
+ // Request image resource GC
+ Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
}
mIblDiffuseLoadTask = new EnvironmentMapLoadTask(mDiffuseIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, MakeCallback(this, &SceneView::OnIblDiffuseLoadComplete));
Dali::AsyncTaskManager::Get().AddTask(mIblDiffuseLoadTask);
{
Dali::AsyncTaskManager::Get().RemoveTask(mIblSpecularLoadTask);
mIblSpecularLoadTask.Reset();
+
+ // Request image resource GC
+ Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
}
mIblSpecularLoadTask = new EnvironmentMapLoadTask(mSpecularIblUrl, Scene3D::EnvironmentMapType::CUBEMAP, MakeCallback(this, &SceneView::OnIblSpecularLoadComplete));
Dali::AsyncTaskManager::Get().AddTask(mIblSpecularLoadTask);
SetShadowLightConstraint(selectedCamera, lightCamera);
// make framebuffer for depth map and set it to render task.
- Vector3 size = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
- uint32_t shadowMapBufferSize = std::min(static_cast<uint32_t>(std::max(size.width, size.height)), MAXIMUM_SIZE_SHADOW_MAP);
+ uint32_t shadowMapBufferSize = std::min(std::max(GetResolutionWidth(), GetResolutionHeight()), MAXIMUM_SIZE_SHADOW_MAP);
UpdateShadowMapBuffer(shadowMapBufferSize);
// use lightCamera as a camera of shadow render task.
// Create new framebuffer with changed multiSamplingLevel.
if(mRenderTask && mFrameBuffer && mTexture)
{
- Vector3 size = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
-
- mFrameBuffer = FrameBuffer::New(size.width, size.height, FrameBuffer::Attachment::DEPTH_STENCIL);
+ mFrameBuffer = FrameBuffer::New(GetResolutionWidth(), GetResolutionHeight(), FrameBuffer::Attachment::DEPTH_STENCIL);
mFrameBuffer.AttachColorTexture(mTexture);
DevelFrameBuffer::SetMultiSamplingLevel(mFrameBuffer, mFrameBufferMultiSamplingLevel);
mRenderTask.SetFrameBuffer(mFrameBuffer);
{
if(mAlphaMaskUrl != alphaMaskUrl)
{
- mAlphaMaskUrl = alphaMaskUrl;
+ mAlphaMaskUrl = alphaMaskUrl;
mMaskingPropertyChanged = true;
UpdateRenderTask();
}
{
if(mCropToMask != enableCropToMask)
{
- mCropToMask = enableCropToMask;
+ mCropToMask = enableCropToMask;
mMaskingPropertyChanged = true;
UpdateRenderTask();
}
{
mRenderTask.SetCameraActor(mSelectedCamera);
}
+ uint32_t width = GetResolutionWidth();
+ uint32_t height = GetResolutionHeight();
- Vector3 size = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
- float aspectRatio = size.width / size.height;
-
- uint32_t shadowMapBufferSize = std::min(static_cast<uint32_t>(std::max(size.width, size.height)), MAXIMUM_SIZE_SHADOW_MAP);
+ uint32_t shadowMapBufferSize = std::min(std::max(width, height), MAXIMUM_SIZE_SHADOW_MAP);
UpdateShadowMapBuffer(shadowMapBufferSize);
if(mUseFrameBuffer)
{
- uint32_t width = (mWindowWidth == 0 || mWindowHeight == 0) ? static_cast<uint32_t>(size.width) : mWindowWidth;
- uint32_t height = (mWindowWidth == 0 || mWindowHeight == 0) ? static_cast<uint32_t>(size.height) : mWindowHeight;
- aspectRatio = static_cast<float>(width) / static_cast<float>(height);
-
Dali::FrameBuffer currentFrameBuffer = mRenderTask.GetFrameBuffer();
if(!currentFrameBuffer ||
- !Dali::Equals(currentFrameBuffer.GetColorTexture().GetWidth(), size.width) ||
- !Dali::Equals(currentFrameBuffer.GetColorTexture().GetHeight(), size.height) ||
+ !Dali::Equals(currentFrameBuffer.GetColorTexture().GetWidth(), width) ||
+ !Dali::Equals(currentFrameBuffer.GetColorTexture().GetHeight(), height) ||
mMaskingPropertyChanged ||
mWindowSizeChanged)
{
mRenderTask.SetClearColor(Color::TRANSPARENT);
mMaskingPropertyChanged = false;
- mWindowSizeChanged = false;
+ mWindowSizeChanged = false;
}
}
else
}
}
- mSelectedCamera.SetAspectRatio(aspectRatio);
+ if(width > 0u && height > 0u)
+ {
+ float aspectRatio = static_cast<float>(width) / static_cast<float>(height);
+ mSelectedCamera.SetAspectRatio(aspectRatio);
+ }
RotateCamera();
}
mSkyboxDirty = false;
mSkyboxResourceReady = true;
+
+ // Request image resource GC
+ Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
}
else
{
{
Dali::AsyncTaskManager::Get().RemoveTask(mSkyboxLoadTask);
mSkyboxLoadTask.Reset();
+
+ // Request image resource GC
+ Dali::Scene3D::Internal::ImageResourceLoader::RequestGarbageCollect();
}
mSkyboxLoadTask = new EnvironmentMapLoadTask(mSkyboxUrl, mSkyboxEnvironmentMapType, MakeCallback(this, &SceneView::OnSkyboxLoadComplete));
#define DALI_SCENE3D_INTERNAL_SCENE_VIEW_H
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
float mSkyboxIntensity{1.0f};
uint8_t mFrameBufferMultiSamplingLevel{0u};
- bool mWindowSizeChanged{false};
+ bool mWindowSizeChanged{false};
uint32_t mWindowWidth{0};
uint32_t mWindowHeight{0};
#endif
#ifdef MORPH
-#define MAX_BLEND_SHAPE_NUMBER 128
+#define MAX_BLEND_SHAPE_NUMBER 256
uniform int uNumberOfBlendShapes; ///< Total number of blend shapes loaded.
uniform highp float uBlendShapeWeight[MAX_BLEND_SHAPE_NUMBER]; ///< The weight of each blend shape.
#ifdef MORPH_VERSION_2_0
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
renderer.RegisterProperty("uOcclusionTextureTransformAvailable", 0.0f);
renderer.RegisterProperty("uEmissiveTextureTransformAvailable", 0.0f);
+ renderer.RegisterProperty("uBaseColorTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uNormalRoughnessTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uNormalTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uMetalRoughnessTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uOcclusionTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uEmissiveTextureTransform", Matrix3::IDENTITY);
+
float opaque = mIsOpaque ? 1.0f : 0.0f;
float mask = mIsMask ? 1.0f : 0.0f;
renderer.RegisterProperty("uOpaque", opaque);
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
environmentMapData.mPixelData.resize(6);
for(auto& face : environmentMapData.mPixelData)
{
- face.push_back(PixelData::New(new uint8_t[3]{0xff, 0xff, 0xff}, 3, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY));
+ face.push_back(Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataWhiteRGB());
}
environmentMapData.SetEnvironmentMapType(Dali::Scene3D::EnvironmentMapType::CUBEMAP);
Texture iblTexture = environmentMapData.GetTexture();
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
uint32_t finalFaceWidth = (xOffset + static_cast<uint32_t>(faceWidth) < imageWidth) ? static_cast<uint32_t>(faceWidth) : imageWidth - xOffset;
uint32_t finalFaceHeight = (yOffset + static_cast<uint32_t>(faceHeight) < imageHeight) ? static_cast<uint32_t>(faceHeight) : imageHeight - yOffset;
uint8_t* tempImageBuffer = GetCroppedBuffer(imageBuffer, bytesPerPixel, imageWidth, imageHeight, xOffset, yOffset, finalFaceWidth, finalFaceHeight);
- cubeFacePixelData = PixelData::New(tempImageBuffer, finalFaceWidth * finalFaceHeight * bytesPerPixel, finalFaceWidth, finalFaceHeight, imagePixelFormat, PixelData::FREE);
+
+ cubeFacePixelData = Dali::Integration::NewPixelDataWithReleaseAfterUpload(tempImageBuffer, finalFaceWidth * finalFaceHeight * bytesPerPixel, finalFaceWidth, finalFaceHeight, 0u, imagePixelFormat, PixelData::FREE);
}
}
return cubeFacePixelData;
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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-scene3d/public-api/loader/ktx-loader.h>
// EXTERNAL INCLUDES
+#include <dali/integration-api/pixel-data-integ.h>
#include <dali/public-api/rendering/texture.h>
#include <fstream>
#include <memory>
{
return false;
}
- environmentMapData.mPixelData[face][mipmapLevel] = PixelData::New(img.release(), byteSize, header.pixelWidth, header.pixelHeight, daliformat, PixelData::DELETE_ARRAY);
+ environmentMapData.mPixelData[face][mipmapLevel] = Dali::Integration::NewPixelDataWithReleaseAfterUpload(img.release(), byteSize, header.pixelWidth, header.pixelHeight, 0u, daliformat, PixelData::DELETE_ARRAY);
}
}
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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 <dali-toolkit/devel-api/builder/base64-encoding.h>
#include <dali/devel-api/adaptor-framework/image-loading.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+#include <dali/integration-api/pixel-data-integ.h>
// INTERNAL INCLUDES
#include <dali-scene3d/internal/common/image-resource-loader.h>
{
namespace Loader
{
-const Matrix3 TextureDefinition::DEFAULT_TRANSFORM = Matrix3(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
+const Matrix3 TextureDefinition::DEFAULT_TRANSFORM = Matrix3::IDENTITY;
namespace
{
Dali::Devel::PixelBuffer pixelBuffer = Dali::LoadImageFromBuffer(reinterpret_cast<uint8_t*>(buffer.data()), bufferSize, textureDefinition.mMinImageDimensions, fittingMode, textureDefinition.mSamplingMode, orientationCorrection);
if(pixelBuffer)
{
- pixelData = Devel::PixelBuffer::Convert(pixelBuffer);
+ pixelData = Dali::Devel::PixelBuffer::Convert(pixelBuffer, true);
}
}
}
}
else // single value normal-roughness
{
- const auto bufferSize = 4;
- uint8_t* buffer = new uint8_t[bufferSize]{0x7f, 0x7f, 0xff, 0xff}; // normal of (0, 0, 1), roughness of 1
- raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
+ raw.mTextures.push_back({Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataZAxisAndAlphaRGBA(), GetSingleValueSampler()});
}
}
else
buffer[0] = static_cast<uint8_t>(mColor.r * 255.f);
buffer[1] = static_cast<uint8_t>(mColor.g * 255.f);
buffer[2] = static_cast<uint8_t>(mColor.b * 255.f);
- raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, format, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
+ raw.mTextures.push_back({Dali::Integration::NewPixelDataWithReleaseAfterUpload(buffer, bufferSize, 1, 1, 0, format, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
}
// If we have transparency, or an image based albedo map, we will have to continue with separate metallicRoughness + normal.
{
// NOTE: we want to set both metallic and roughness to 1.0; dli uses the R & A channels,
// glTF2 uses B & G, so we might as well just set all components to 1.0.
- const auto bufferSize = 4;
- uint8_t* buffer = new uint8_t[bufferSize]{0xff, 0xff, 0xff, 0xff};
- raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
+ raw.mTextures.push_back({Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataWhiteRGBA(), GetSingleValueSampler()});
}
if(checkStage(NORMAL))
{
if(createMetallicRoughnessAndNormal)
{
- const auto bufferSize = 3;
- uint8_t* buffer = new uint8_t[bufferSize]{0x7f, 0x7f, 0xff}; // normal of (0, 0, 1)
- raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
+ raw.mTextures.push_back({Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataZAxisRGB(), GetSingleValueSampler()});
}
else // single-value normal-roughness
{
- const auto bufferSize = 4;
- uint8_t* buffer = new uint8_t[bufferSize]{0x7f, 0x7f, 0xff, 0xff}; // normal of (0, 0, 1), roughness of 1.0
- raw.mTextures.push_back({PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), GetSingleValueSampler()});
+ raw.mTextures.push_back({Dali::Scene3D::Internal::ImageResourceLoader::GetEmptyPixelDataZAxisAndAlphaRGBA(), GetSingleValueSampler()});
}
}
}
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
renderer.RegisterProperty("uOcclusionTextureTransformAvailable", 0.0f);
renderer.RegisterProperty("uEmissiveTextureTransformAvailable", 0.0f);
+ renderer.RegisterProperty("uBaseColorTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uNormalRoughnessTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uNormalTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uMetalRoughnessTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uOcclusionTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uEmissiveTextureTransform", Matrix3::IDENTITY);
+
auto iTexture = matDef.mTextureStages.begin();
auto checkStage = [&](uint32_t flags) {
return iTexture != matDef.mTextureStages.end() && MaskMatch(iTexture->mSemantic, flags);
if(checkStage(MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC))
{
- renderer.RegisterProperty("uBaseColorTextureTransformAvailable", 1.0f);
+ renderer.RegisterProperty("uBaseColorTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
renderer.RegisterProperty("uBaseColorTextureTransform", iTexture->mTexture.mTransform);
++iTexture;
if(checkStage(MaterialDefinition::NORMAL | MaterialDefinition::ROUGHNESS))
{
- renderer.RegisterProperty("uNormalRoughnessTextureTransformAvailable", 1.0f);
+ renderer.RegisterProperty("uNormalRoughnessTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
renderer.RegisterProperty("uNormalRoughnessTextureTransform", iTexture->mTexture.mTransform);
++iTexture;
}
}
else if(checkStage(MaterialDefinition::ALBEDO))
{
- renderer.RegisterProperty("uBaseColorTextureTransformAvailable", 1.0f);
+ renderer.RegisterProperty("uBaseColorTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
renderer.RegisterProperty("uBaseColorTextureTransform", iTexture->mTexture.mTransform);
++iTexture;
}
if(checkStage(MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS))
{
- renderer.RegisterProperty("uMetalRoughnessTextureTransformAvailable", 1.0f);
+ renderer.RegisterProperty("uMetalRoughnessTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
renderer.RegisterProperty("uMetalRoughnessTextureTransform", iTexture->mTexture.mTransform);
++iTexture;
}
if(checkStage(MaterialDefinition::NORMAL))
{
- renderer.RegisterProperty("uNormalTextureTransformAvailable", 1.0f);
+ renderer.RegisterProperty("uNormalTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
renderer.RegisterProperty("uNormalTextureTransform", iTexture->mTexture.mTransform);
++iTexture;
}
if(checkStage(MaterialDefinition::OCCLUSION))
{
- renderer.RegisterProperty("uOcclusionTextureTransformAvailable", 1.0f);
+ renderer.RegisterProperty("uOcclusionTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
renderer.RegisterProperty("uOcclusionTextureTransform", iTexture->mTexture.mTransform);
++iTexture;
}
if(checkStage(MaterialDefinition::EMISSIVE))
{
- renderer.RegisterProperty("uEmissiveTextureTransformAvailable", 1.0f);
+ renderer.RegisterProperty("uEmissiveTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
renderer.RegisterProperty("uEmissiveTextureTransform", iTexture->mTexture.mTransform);
++iTexture;
}
#include <dali-toolkit/internal/text/controller/text-controller-relayouter.h>
// EXTERNAL INCLUDES
+#include <cmath>
#include <dali/integration-api/debug.h>
#include <dali/integration-api/trace.h>
+#include <dali/public-api/common/constants.h>
#include <dali/public-api/math/math-utils.h>
#include <limits>
float pointInterval = impl.mTextFitStepSize;
float currentFitPointSize = impl.mFontDefaults->mFitPointSize;
float currentDefaultLineSize = impl.mLayoutEngine.GetDefaultLineSize();
+ bool isMultiLine = impl.mLayoutEngine.GetLayout() == Layout::Engine::MULTI_LINE_BOX;
// Instead of using the LineSize of the current TextLabel, the LineSize set in TextFit is used.
+
impl.SetDefaultLineSize(impl.mTextFitLineSize);
model->mElideEnabled = false;
+ float bestPointSize = minPointSize;
// check zero value
if(pointInterval < 1.f)
{
impl.mTextFitStepSize = pointInterval = 1.0f;
}
- uint32_t pointSizeRange = static_cast<uint32_t>(ceil((maxPointSize - minPointSize) / pointInterval));
- // Ensure minPointSize + pointSizeRange * pointInverval >= maxPointSize
- while(minPointSize + static_cast<float>(pointSizeRange) * pointInterval < maxPointSize)
- {
- ++pointSizeRange;
- }
+ uint32_t pointSizeRange = static_cast<uint32_t>(ceil((maxPointSize - minPointSize) / pointInterval));
- uint32_t bestSizeIndex = 0;
- uint32_t minIndex = bestSizeIndex + 1u;
- uint32_t maxIndex = pointSizeRange + 1u;
-
- bool bestSizeUpdatedLatest = false;
- // Find best size as binary search.
- // Range format as [l r). (left closed, right opened)
- // It mean, we already check all i < l is valid, and r <= i is invalid.
- // Below binary search will check m = (l+r)/2 point.
- // Search area sperate as [l m) or [m+1 r)
- //
- // Basically, we can assume that 0 (minPointSize) is always valid.
- // Now, we will check [1 pointSizeRange] range s.t. pointSizeRange mean the maxPointSize
- while(minIndex < maxIndex)
+ if(isMultiLine || pointSizeRange < 3)
{
- uint32_t testIndex = minIndex + ((maxIndex - minIndex) >> 1u);
- const float testPointSize = std::min(maxPointSize, minPointSize + static_cast<float>(testIndex) * pointInterval);
+ // Ensure minPointSize + pointSizeRange * pointInverval >= maxPointSize
+ while(minPointSize + static_cast<float>(pointSizeRange) * pointInterval < maxPointSize)
+ {
+ ++pointSizeRange;
+ }
- if(CheckForTextFit(controller, testPointSize, layoutSize))
+ uint32_t bestSizeIndex = 0;
+ uint32_t minIndex = bestSizeIndex + 1u;
+ uint32_t maxIndex = pointSizeRange + 1u;
+
+ bool bestSizeUpdatedLatest = false;
+ // Find best size as binary search.
+ // Range format as [l r). (left closed, right opened)
+ // It mean, we already check all i < l is valid, and r <= i is invalid.
+ // Below binary search will check m = (l+r)/2 point.
+ // Search area sperate as [l m) or [m+1 r)
+ //
+ // Basically, we can assume that 0 (minPointSize) is always valid.
+ // Now, we will check [1 pointSizeRange] range s.t. pointSizeRange mean the maxPointSize
+ while(minIndex < maxIndex)
{
- bestSizeUpdatedLatest = true;
+ uint32_t testIndex = minIndex + ((maxIndex - minIndex) >> 1u);
+ const float testPointSize = std::min(maxPointSize, minPointSize + static_cast<float>(testIndex) * pointInterval);
+
+ if(CheckForTextFit(controller, testPointSize, layoutSize))
+ {
+ bestSizeUpdatedLatest = true;
- bestSizeIndex = testIndex;
- minIndex = testIndex + 1u;
+ bestSizeIndex = testIndex;
+ minIndex = testIndex + 1u;
+ }
+ else
+ {
+ bestSizeUpdatedLatest = false;
+ maxIndex = testIndex;
+ }
}
- else
+ bestPointSize = std::min(maxPointSize, minPointSize + static_cast<float>(bestSizeIndex) * pointInterval);
+
+ // Best point size was not updated. re-run so the TextFit should be fitted really.
+ if(!bestSizeUpdatedLatest)
{
- bestSizeUpdatedLatest = false;
- maxIndex = testIndex;
+ CheckForTextFit(controller, bestPointSize, layoutSize);
}
}
- const float bestPointSize = std::min(maxPointSize, minPointSize + static_cast<float>(bestSizeIndex) * pointInterval);
-
- // Best point size was not updated. re-run so the TextFit should be fitted really.
- if(!bestSizeUpdatedLatest)
+ else
{
- CheckForTextFit(controller, bestPointSize, layoutSize);
+ // assume textSize = a * pointSize + b, finding a and b.
+ Size textSize;
+ TextUpdateInfo& textUpdateInfo = impl.mTextUpdateInfo;
+ const OperationsMask onlyOnceOperations = static_cast<OperationsMask>(CONVERT_TO_UTF32 |
+ GET_SCRIPTS |
+ VALIDATE_FONTS |
+ GET_LINE_BREAKS |
+ BIDI_INFO |
+ SHAPE_TEXT |
+ GET_GLYPH_METRICS);
+
+ float resultBasedX[2];
+ float resultBasedY[2];
+ float tmpPointSize[2] = {minPointSize, maxPointSize};
+
+ // Calculate a and b by creating simultaneous equations with two calculations.
+ for(int i=0;i<2;i++)
+ {
+ impl.mFontDefaults->mFitPointSize = tmpPointSize[i];
+ impl.mFontDefaults->sizeDefined = true;
+ impl.ClearFontData();
+
+ textUpdateInfo.mParagraphCharacterIndex = 0u;
+ textUpdateInfo.mRequestedNumberOfCharacters = impl.mModel->mLogicalModel->mText.Count();
+
+
+ // Make sure the model is up-to-date before layouting
+ impl.UpdateModel(onlyOnceOperations);
+
+ DoRelayout(impl,
+ Size(layoutSize.width, MAX_FLOAT),
+ static_cast<OperationsMask>(onlyOnceOperations | LAYOUT),
+ textSize);
+
+ // Clear the update info. This info will be set the next time the text is updated.
+ textUpdateInfo.Clear();
+ textUpdateInfo.mClearAll = true;
+
+ resultBasedX[i] = textSize.x;
+ resultBasedY[i] = textSize.y;
+ }
+
+ float aBasedX = (resultBasedX[1] - resultBasedX[0]) / (tmpPointSize[1] - tmpPointSize[0]);
+ float bBasedX = resultBasedX[1] - aBasedX * tmpPointSize[1];
+ aBasedX = std::max(aBasedX, Dali::Math::MACHINE_EPSILON_1000);
+
+ float aBasedY = (resultBasedY[1] - resultBasedY[0]) / (tmpPointSize[1] - tmpPointSize[0]);
+ float bBasedY = resultBasedY[1] - aBasedY * tmpPointSize[1];
+ aBasedY = std::max(aBasedY, Dali::Math::MACHINE_EPSILON_1000);
+
+ float bestPointSizeBasedX = (layoutSize.x - bBasedX) / aBasedX;
+ float bestPointSizeBasedY = (layoutSize.y - bBasedY) / aBasedY;
+
+ bestPointSize = std::min(bestPointSizeBasedX, bestPointSizeBasedY);
+ bestPointSize = std::min(std::max(bestPointSize, minPointSize), maxPointSize);
+ bestPointSize = std::floor((bestPointSize - minPointSize) / pointInterval) * pointInterval + minPointSize;
+
+ if(CheckForTextFit(controller, bestPointSize, layoutSize))
+ {
+ while(bestPointSize + pointInterval <= maxPointSize && CheckForTextFit(controller, bestPointSize + pointInterval, layoutSize))
+ {
+ bestPointSize += pointInterval;
+ }
+ }
+ else if(bestPointSize - pointInterval >= minPointSize)
+ {
+ do
+ {
+ bestPointSize -= pointInterval;
+ } while(bestPointSize - pointInterval >= minPointSize && !CheckForTextFit(controller, bestPointSize, layoutSize));
+ }
}
model->mElideEnabled = actualellipsis;
{
DALI_LOG_ERROR("VectorAnimationTask::Load: Load failed [%s]\n", mImageUrl.GetUrl().c_str());
mLoadRequest = false;
- if(!synchronousLoading && mLoadCompletedCallback)
{
- mVectorAnimationThread.AddEventTriggerCallback(mLoadCompletedCallback.get());
+ ConditionalWait::ScopedLock lock(mConditionalWait);
+ if(!synchronousLoading && mLoadCompletedCallback)
+ {
+ mVectorAnimationThread.AddEventTriggerCallback(mLoadCompletedCallback.get());
+ }
}
#ifdef TRACE_ENABLED
if(gTraceFilter && gTraceFilter->IsTraceEnabled())
mFrameDurationMicroSeconds = MICROSECONDS_PER_SECOND / mFrameRate;
mLoadRequest = false;
- if(!synchronousLoading && mLoadCompletedCallback)
{
- mVectorAnimationThread.AddEventTriggerCallback(mLoadCompletedCallback.get());
+ ConditionalWait::ScopedLock lock(mConditionalWait);
+ if(!synchronousLoading && mLoadCompletedCallback)
+ {
+ mVectorAnimationThread.AddEventTriggerCallback(mLoadCompletedCallback.get());
+ }
}
DALI_LOG_INFO(gVectorAnimationLogFilter, Debug::Verbose, "VectorAnimationTask::Load: file = %s [%d frames, %f fps] [%p]\n", mImageUrl.GetUrl().c_str(), mTotalFrame, mFrameRate, this);
for(std::size_t i = 0u; i < resultMap.Count(); ++i)
{
- auto key = resultMap.GetKeyAt(i);
- auto value = resultMap.GetValue(i);
+ auto key = resultMap.GetKeyAt(i);
+ const auto& value = resultMap.GetValue(i);
RedefineMacro(fragmentShader, std::move(key.stringKey), value.Get<std::string>());
}
Self().GetTypeInfo(type);
if(type)
{
- auto typeName = type.GetName();
+ const auto& typeName = type.GetName();
DevelControl::AppendAccessibilityAttribute(Toolkit::Control::DownCast(Self()), "class", typeName);
}
}
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 3;
-const unsigned int TOOLKIT_MICRO_VERSION = 5;
+const unsigned int TOOLKIT_MICRO_VERSION = 6;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 2.3.5
+Version: 2.3.6
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT