int UtcTextureManagerExternalTexture(void)
{
ToolkitTestApplication application;
- tet_infoline("UtcTextureManagerExternalTexture check TextureManager using external texture works well");
+ tet_infoline("UtcTextureManagerExternalTexture check TextureManager using external texture as image, or masking, or both works well");
auto visualFactory = Toolkit::VisualFactory::Get();
auto& textureManager = GetImplementation(visualFactory).GetTextureManager(); // Use VisualFactory's texture manager
- TestObserver observer1;
- TestObserver observer2;
-
- auto textureId1(TextureManager::INVALID_TEXTURE_ID);
- auto textureId2(TextureManager::INVALID_TEXTURE_ID);
- std::string maskname(TEST_MASK_FILE_NAME);
- TextureManager::MaskingDataPointer maskInfo = nullptr;
- maskInfo.reset(new TextureManager::MaskingData());
- maskInfo->mAlphaMaskUrl = maskname;
- maskInfo->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
- maskInfo->mCropToMask = true;
- maskInfo->mContentScaleFactor = 1.0f;
- Vector4 atlasRect(0.f, 0.f, 1.f, 1.f);
- Dali::ImageDimensions atlasRectSize(0, 0);
- bool synchronousLoading(false);
- bool atlasingStatus(false);
- bool loadingStatus(false);
- auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
- ImageAtlasManagerPtr atlasManager = nullptr;
- Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
-
uint32_t width(64);
uint32_t height(64);
uint32_t bufferSize = width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888);
DALI_TEST_CHECK(pixelData);
- Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData, true);
- std::string url = imageUrl.GetUrl();
+ Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData, true);
+ std::string externalImageUrl = imageUrl.GetUrl();
+ Dali::Toolkit::ImageUrl imageUrl2 = Dali::Toolkit::Image::GenerateUrl(pixelData, false);
+ std::string externalImageUrl2 = imageUrl2.GetUrl();
- TextureSet texture1 = textureManager.LoadTexture(
- url,
- ImageDimensions(),
- FittingMode::SCALE_TO_FILL,
- SamplingMode::BOX_THEN_LINEAR,
- maskInfo,
- synchronousLoading,
- textureId1,
- atlasRect,
- atlasRectSize,
- atlasingStatus,
- loadingStatus,
- &observer1,
- atlasUploadObserver,
- atlasManager,
- true,
- TextureManager::ReloadPolicy::CACHED,
- preMultiply);
+ for(int testCase = 0; testCase < 6; testCase++)
+ {
+ // Test case config
+ // Note tat we don't need to test (!testExternalTexture && !testExternalMask) case.
+ const bool testSyncLoad = ((testCase & 0x01) == 0);
+ const bool testExternalTexture = ((testCase & 0x02) == 0);
+ const bool testExternalMask = ((testCase & 0x04) == 0);
- TextureSet texture2 = textureManager.LoadTexture(
- url,
- ImageDimensions(),
- FittingMode::SCALE_TO_FILL,
- SamplingMode::BOX_THEN_LINEAR,
- maskInfo,
- synchronousLoading,
- textureId2,
- atlasRect,
- atlasRectSize,
- atlasingStatus,
- loadingStatus,
- &observer2,
- atlasUploadObserver,
- atlasManager,
- true,
- TextureManager::ReloadPolicy::CACHED,
- preMultiply);
+ tet_printf("Testcase, syncload : %d, externalTexture : %d, externalMask : %d\n", testSyncLoad, testExternalTexture, testExternalMask);
- DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
- DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
- DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
- DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
+ // texture loaded only if it is syncload, or both of textures are external.
+ const bool expectTextureLoadedResult = testSyncLoad || (testExternalTexture && testExternalMask);
+ const bool expectObserverNotified = !testSyncLoad && (testExternalTexture && testExternalMask);
- application.SendNotification();
- application.Render();
+ auto textureId1(TextureManager::INVALID_TEXTURE_ID);
+ auto textureId2(TextureManager::INVALID_TEXTURE_ID);
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ TestObserver observer1;
+ TestObserver observer2;
- DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
- DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
- DALI_TEST_EQUALS(observer1.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
+ std::string maskname(testExternalMask ? externalImageUrl2 : TEST_MASK_FILE_NAME);
+ TextureManager::MaskingDataPointer maskInfo = nullptr;
+ maskInfo.reset(new TextureManager::MaskingData());
+ maskInfo->mAlphaMaskUrl = maskname;
+ maskInfo->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
+ maskInfo->mCropToMask = true;
+ maskInfo->mContentScaleFactor = 1.0f;
+ maskInfo->mPreappliedMasking = false;
- DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
- DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
- DALI_TEST_EQUALS(observer2.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
+ Vector4 atlasRect(0.f, 0.f, 1.f, 1.f);
+ Dali::ImageDimensions atlasRectSize(0, 0);
+ bool synchronousLoading(testSyncLoad);
+ bool atlasingStatus(false);
+ bool loadingStatus(false);
+ auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+ ImageAtlasManagerPtr atlasManager = nullptr;
+ Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
- DALI_TEST_EQUALS(textureId1 == textureId2, true, TEST_LOCATION);
+ std::string url(testExternalTexture ? externalImageUrl : TEST_IMAGE_FILE_NAME);
- texture1 = textureManager.LoadTexture(
- url,
- ImageDimensions(),
- FittingMode::SCALE_TO_FILL,
- SamplingMode::BOX_THEN_LINEAR,
- maskInfo,
- synchronousLoading,
- textureId1,
- atlasRect,
- atlasRectSize,
- atlasingStatus,
- loadingStatus,
- &observer1,
- atlasUploadObserver,
- atlasManager,
- true,
- TextureManager::ReloadPolicy::CACHED,
- preMultiply);
+ TextureSet texture1 = textureManager.LoadTexture(
+ url,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo,
+ synchronousLoading,
+ textureId1,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer1,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
- texture2 = textureManager.LoadTexture(
- url,
- ImageDimensions(),
- FittingMode::SCALE_TO_FILL,
- SamplingMode::BOX_THEN_LINEAR,
- maskInfo,
- synchronousLoading,
- textureId2,
- atlasRect,
- atlasRectSize,
- atlasingStatus,
- loadingStatus,
- &observer2,
- atlasUploadObserver,
- atlasManager,
- true,
- TextureManager::ReloadPolicy::CACHED,
- preMultiply);
+ DALI_TEST_EQUALS(!!texture1, expectTextureLoadedResult, TEST_LOCATION);
- application.SendNotification();
- application.Render();
+ TextureSet texture2 = textureManager.LoadTexture(
+ url,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo,
+ synchronousLoading,
+ textureId2,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer2,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
- DALI_TEST_EQUALS(textureId1 == textureId2, true, TEST_LOCATION);
- DALI_TEST_EQUALS(texture1 != texture2, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(!!texture2, expectTextureLoadedResult, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(observer1.mLoaded, expectObserverNotified, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mObserverCalled, expectObserverNotified, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mLoaded, expectObserverNotified, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mObserverCalled, expectObserverNotified, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(textureId1 == textureId2, true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ if(!expectTextureLoadedResult)
+ {
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ }
+
+ if(!testSyncLoad)
+ {
+ DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
+ }
+
+ application.SendNotification();
+ application.Render();
+
+ texture1 = textureManager.LoadTexture(
+ url,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo,
+ synchronousLoading,
+ textureId1,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer1,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ DALI_TEST_CHECK(texture1); // texture is loaded.
+
+ texture2 = textureManager.LoadTexture(
+ url,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo,
+ synchronousLoading,
+ textureId2,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer2,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ DALI_TEST_CHECK(texture2); // texture is loaded.
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(textureId1 == textureId2, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(texture1 != texture2, true, TEST_LOCATION);
+
+ // Ensure to remove cache.
+ textureManager.RequestRemove(textureId1, nullptr);
+ textureManager.RequestRemove(textureId1, nullptr);
+ textureManager.RequestRemove(textureId1, nullptr);
+ textureManager.RequestRemove(textureId1, nullptr);
+
+ application.SendNotification();
+ application.Render();
+ application.SendNotification();
+ application.Render();
+ }
END_TEST;
}
DALI_TEST_CHECK(textureId1 != TextureManager::INVALID_TEXTURE_ID);
+ // Note that ExernalTexture will notify observer.
+ DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
+
+ // Reset flags for observer1.
+ observer1.mLoaded = false;
+ observer1.mObserverCalled = false;
+
// Step 2 : Request remove for external url
textureManager.RequestRemove(textureId1, &observer1);
END_TEST;
}
+
+int UtcTextureManagerMaskByExternalTexture01(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcTextureManagerMaskByExternalTexture01 check TextureManager masking by external texture works well");
+
+ auto visualFactory = Toolkit::VisualFactory::Get();
+ auto& textureManager = GetImplementation(visualFactory).GetTextureManager(); // Use VisualFactory's texture manager
+
+ uint32_t width(64);
+ uint32_t height(64);
+ uint32_t bufferSize = width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888);
+
+ uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+ PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE);
+ Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData, true);
+
+ TestObserver observer1;
+ TestObserver observer2;
+
+ auto textureId1(TextureManager::INVALID_TEXTURE_ID);
+ auto textureId2(TextureManager::INVALID_TEXTURE_ID);
+ TextureManager::MaskingDataPointer maskInfo = nullptr;
+
+ maskInfo.reset(new TextureManager::MaskingData());
+ maskInfo->mAlphaMaskUrl = imageUrl.GetUrl();
+ maskInfo->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
+ maskInfo->mCropToMask = true;
+ maskInfo->mContentScaleFactor = 1.0f;
+ maskInfo->mPreappliedMasking = false;
+
+ Vector4 atlasRect(0.f, 0.f, 1.f, 1.f);
+ Dali::ImageDimensions atlasRectSize(0, 0);
+ bool synchronousLoading(false);
+ bool atlasingStatus(false);
+ bool loadingStatus(false);
+ auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+ ImageAtlasManagerPtr atlasManager = nullptr;
+ Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
+
+ DALI_TEST_CHECK(pixelData);
+
+ std::string url = TEST_IMAGE_FILE_NAME;
+
+ TextureSet texture1 = textureManager.LoadTexture(
+ url,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo,
+ synchronousLoading,
+ textureId1,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer1,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ TextureSet texture2 = textureManager.LoadTexture(
+ url,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo,
+ synchronousLoading,
+ textureId2,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer2,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ DALI_TEST_EQUALS(observer1.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mObserverCalled, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mLoaded, false, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mObserverCalled, false, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(textureId1 == textureId2, true, TEST_LOCATION);
+
+ texture1 = textureManager.LoadTexture(
+ url,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo,
+ synchronousLoading,
+ textureId1,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer1,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ texture2 = textureManager.LoadTexture(
+ url,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo,
+ synchronousLoading,
+ textureId2,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer2,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(textureId1 == textureId2, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(texture1 != texture2, true, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcTextureManagerMaskByExternalTexture02(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcTextureManagerMaskByExternalTexture02 check TextureManager masking external texture by external texture works well");
+
+ auto visualFactory = Toolkit::VisualFactory::Get();
+ auto& textureManager = GetImplementation(visualFactory).GetTextureManager(); // Use VisualFactory's texture manager
+
+ uint32_t width(64);
+ uint32_t height(64);
+ uint32_t bufferSize = width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888);
+
+ uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+ PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE);
+ Dali::Toolkit::ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData, true);
+ Dali::Toolkit::ImageUrl imageUrl2 = Dali::Toolkit::Image::GenerateUrl(pixelData, true);
+
+ TestObserver observer1;
+ TestObserver observer2;
+
+ auto textureId1(TextureManager::INVALID_TEXTURE_ID);
+ auto textureId2(TextureManager::INVALID_TEXTURE_ID);
+ TextureManager::MaskingDataPointer maskInfo = nullptr;
+
+ maskInfo.reset(new TextureManager::MaskingData());
+ maskInfo->mAlphaMaskUrl = imageUrl.GetUrl();
+ maskInfo->mAlphaMaskId = TextureManager::INVALID_TEXTURE_ID;
+ maskInfo->mCropToMask = true;
+ maskInfo->mContentScaleFactor = 1.0f;
+ maskInfo->mPreappliedMasking = false;
+
+ Vector4 atlasRect(0.f, 0.f, 1.f, 1.f);
+ Dali::ImageDimensions atlasRectSize(0, 0);
+ bool synchronousLoading(false);
+ bool atlasingStatus(false);
+ bool loadingStatus(false);
+ auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+ ImageAtlasManagerPtr atlasManager = nullptr;
+ Toolkit::AtlasUploadObserver* atlasUploadObserver = nullptr;
+
+ DALI_TEST_CHECK(pixelData);
+
+ std::string url = imageUrl2.GetUrl();
+
+ TextureSet texture1 = textureManager.LoadTexture(
+ url,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo,
+ synchronousLoading,
+ textureId1,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer1,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ TextureSet texture2 = textureManager.LoadTexture(
+ url,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo,
+ synchronousLoading,
+ textureId2,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer2,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ tet_printf("url : %s, mask url : %s, textureid : %d %d\n", url.c_str(), maskInfo->mAlphaMaskUrl.GetUrl().c_str(), textureId1, textureId2);
+
+ // observer called synchronously. (Since external textures are already uploaded)
+ DALI_TEST_EQUALS(observer1.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mObserverCalled, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer1.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(observer2.mLoaded, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mObserverCalled, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(observer2.mCompleteType, TestObserver::CompleteType::UPLOAD_COMPLETE, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(textureId1 == textureId2, true, TEST_LOCATION);
+
+ texture1 = textureManager.LoadTexture(
+ url,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo,
+ synchronousLoading,
+ textureId1,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer1,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ texture2 = textureManager.LoadTexture(
+ url,
+ ImageDimensions(),
+ FittingMode::SCALE_TO_FILL,
+ SamplingMode::BOX_THEN_LINEAR,
+ maskInfo,
+ synchronousLoading,
+ textureId2,
+ atlasRect,
+ atlasRectSize,
+ atlasingStatus,
+ loadingStatus,
+ &observer2,
+ atlasUploadObserver,
+ atlasManager,
+ true,
+ TextureManager::ReloadPolicy::CACHED,
+ preMultiply);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(textureId1 == textureId2, true, TEST_LOCATION);
+ DALI_TEST_EQUALS(texture1 != texture2, true, TEST_LOCATION);
+
+ END_TEST;
+}
namespace
{
constexpr uint32_t URL_ELLIPSED_LENGTH = 20u;
+
+void TestLocationAsInteger(const char* url, int32_t expectValue, bool expectResult, const char* testLocation)
+{
+ int32_t result = 0;
+ bool successed = VisualUrl(url).GetLocationAsInteger(result);
+ DALI_TEST_EQUALS(successed, expectResult, testLocation);
+ if(successed)
+ {
+ DALI_TEST_EQUALS(result, expectValue, testLocation);
+ }
}
+} // namespace
int UtcDaliVisualUrlConstructor(void)
{
DALI_TEST_EQUAL("", VisualUrl("ftp://.png").GetLocationWithoutExtension());
DALI_TEST_EQUAL("http://a.jpg", VisualUrl("http://http://a.jpg.jpg").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("a", VisualUrl("a.jpg").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("12", VisualUrl("12.png").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("/usr/bin/hello", VisualUrl("/usr/bin/hello.txt").GetLocationWithoutExtension());
+
+ END_TEST;
+}
+
+int UtcDaliVisualUrlGetLocationAsIntegerP(void)
+{
+ tet_infoline("UtcDaliVisualUrl GetLocationAsInteger Positive");
+
+ TestLocationAsInteger("http://1.png", 1, true, TEST_LOCATION);
+ TestLocationAsInteger("dali://2", 2, true, TEST_LOCATION);
+ TestLocationAsInteger("enbuf://4.svg", 4, true, TEST_LOCATION);
+ TestLocationAsInteger("ftp://-2", -2, true, TEST_LOCATION);
+ TestLocationAsInteger("9.png", 9, true, TEST_LOCATION);
+ TestLocationAsInteger("2147483647", 2147483647, true, TEST_LOCATION);
+ TestLocationAsInteger("-2147483648.jpg", -2147483648, true, TEST_LOCATION);
+
END_TEST;
}
DALI_TEST_EQUAL("", VisualUrl("").GetLocationWithoutExtension());
DALI_TEST_EQUAL("a", VisualUrl("a").GetLocationWithoutExtension());
- DALI_TEST_EQUAL("dali:/1.jpg", VisualUrl("dali:/1.jpg").GetLocationWithoutExtension());
- DALI_TEST_EQUAL("dali//1.jpg", VisualUrl("dali//1.jpg").GetLocationWithoutExtension());
- DALI_TEST_EQUAL("enbuf:/2.png", VisualUrl("enbuf:/2.png").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("dali:/1", VisualUrl("dali:/1").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("dali//1", VisualUrl("dali//1").GetLocationWithoutExtension());
+ DALI_TEST_EQUAL("enbuf:/2", VisualUrl("enbuf:/2.png").GetLocationWithoutExtension());
DALI_TEST_EQUAL("a.jpg", VisualUrl("http:/http://a.jpg.jpngif").GetLocationWithoutExtension());
END_TEST;
}
+int UtcDaliVisualUrlGetLocationAsIntegerN(void)
+{
+ tet_infoline("UtcDaliVisualUrl GetLocationAsInteger Positive");
+
+ TestLocationAsInteger("http://abc.png", 0, false, TEST_LOCATION);
+ TestLocationAsInteger("dali://.png.png", 0, false, TEST_LOCATION);
+ TestLocationAsInteger("enbuf://.svg", 0, false, TEST_LOCATION);
+ TestLocationAsInteger("ftp://", 0, false, TEST_LOCATION);
+
+ TestLocationAsInteger("2147483648", 0, false, TEST_LOCATION);
+ TestLocationAsInteger("-2147483649", 0, false, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliVisualUrlCreateTextureUrl(void)
{
tet_infoline("UtcDaliVisualUrl CreateTextureUrl");
#include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+#include <dali/devel-api/adaptor-framework/image-loading.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
#include <dali/devel-api/adaptor-framework/window-devel.h>
#include "dummy-control.h"
+#include "test-encoded-image-buffer.h"
using namespace Dali;
using namespace Dali::Toolkit;
const char* TEST_SVG_FILE_NAME = TEST_RESOURCE_DIR "/svg1.svg";
const char* TEST_ANIMATED_VECTOR_IMAGE_FILE_NAME = TEST_RESOURCE_DIR "/insta_camera.json";
-} // namespace
-
void CopyUrlsIntoArray(Property::Array& urls, int startIndex = 0)
{
for(int i = 20 + startIndex; i <= 30; ++i)
}
}
+enum ExternalUrlType
+{
+ EXTERNAL_TEXTURE,
+ ENCODED_IMAGE_BUFFER,
+ MIXED,
+};
+
+ImageUrl ConvertFileToImageUrl(const char* url, ExternalUrlType type)
+{
+ DALI_ASSERT_ALWAYS(type == ExternalUrlType::EXTERNAL_TEXTURE || type == ExternalUrlType::ENCODED_IMAGE_BUFFER);
+
+ ImageUrl imageUrl;
+
+ if(type == ExternalUrlType::EXTERNAL_TEXTURE)
+ {
+ Devel::PixelBuffer pixelBuffer = LoadImageFromFile(url);
+ PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer);
+
+ imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData);
+ }
+ else // ENCODED_IMAGE_BUFFER
+ {
+ EncodedImageBuffer rawBuffer = ConvertFileToEncodedImageBuffer(url);
+
+ imageUrl = Dali::Toolkit::Image::GenerateUrl(rawBuffer);
+ }
+
+ return imageUrl;
+}
+
+void CopyExternalUrlsIntoArray(Property::Array& urls, std::vector<ImageUrl>& imageUrlContainer, int startIndex, ExternalUrlType generationType)
+{
+ for(int i = 20 + startIndex; i <= 30; ++i)
+ {
+ char* url;
+ if(asprintf(&url, TEST_IMAGE_FILE_NAME, i) > 0)
+ {
+ ImageUrl imageUrl;
+ if(generationType == ExternalUrlType::EXTERNAL_TEXTURE ||
+ (generationType == ExternalUrlType::MIXED && (i % 2 == 0)))
+ {
+ imageUrl = ConvertFileToImageUrl(url, ExternalUrlType::EXTERNAL_TEXTURE);
+ }
+ else // ENCODED_IMAGE_BUFFER
+ {
+ imageUrl = ConvertFileToImageUrl(url, ExternalUrlType::ENCODED_IMAGE_BUFFER);
+ }
+
+ DALI_TEST_CHECK(imageUrl);
+
+ imageUrlContainer.push_back(imageUrl); ///< To keep reference count of external textures.
+
+ Property::Value value(imageUrl.GetUrl());
+ urls.Add(value);
+ free(url);
+ }
+ }
+}
+
+} // namespace
+
int UtcDaliAnimatedImageVisualGetPropertyMap01(void)
{
ToolkitTestApplication application;
dummyControl.Unparent();
}
tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ application.RunIdles();
application.SendNotification();
application.Render(16);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
application.SendNotification();
application.Render(20);
- // The first frame is loaded synchronously and load next batch with masking
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+ // The first frame is loaded synchronously and load next batch with masking (1 for load, 1 for apply masking)
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
application.SendNotification();
application.Render();
dummyControl.Unparent();
}
tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ application.RunIdles();
application.SendNotification();
application.Render(16);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
application.SendNotification();
application.Render(20);
- // The first frame is loaded synchronously and load next batch with masking
- DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+ // The first frame is loaded synchronously and load next batch
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
application.SendNotification();
application.Render();
DALI_TEST_EQUALS(Test::GetTimerCount(), 1, TEST_LOCATION);
- DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 4, TEST_LOCATION);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 3, TEST_LOCATION);
dummyControl.Unparent();
}
tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
application.SendNotification();
application.Render(16);
- DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+
+ // TODO : It will be failed due to we don't cache SyncLoading case. fix it soon
+ //DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
END_TEST;
}
dummyControl.Unparent();
}
tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ application.RunIdles();
application.SendNotification();
application.Render(16);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
dummyControl.Unparent();
}
tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ application.RunIdles();
application.SendNotification();
application.Render(16);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
dummyControl.Unparent();
}
tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ application.RunIdles();
application.SendNotification();
application.Render(16);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
dummyControl2.Unparent();
}
tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(20);
+ application.RunIdles();
application.SendNotification();
application.Render(20);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
dummyControl.Unparent();
}
tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(20);
+ application.RunIdles();
application.SendNotification();
application.Render(20);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
application.SendNotification();
application.Render();
- // load two frame(batch size), load mask image, and request two masking
+ // load two frame(batch size), load mask image, and do not request two masking
DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
application.SendNotification();
dummyControl.Unparent();
}
tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(20);
+ application.RunIdles();
application.SendNotification();
application.Render(20);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
int UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask03(void)
{
ToolkitTestApplication application;
- tet_infoline("UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask03 for GPU Alpha Masking with broken mask texture");
+ tet_infoline("UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask03 for CPU Alpha Masking with broken mask texture");
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ {
+ Property::Map propertyMap;
+ propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, TEST_GIF_FILE_NAME);
+ propertyMap.Insert(ImageVisual::Property::BATCH_SIZE, 2);
+ propertyMap.Insert(ImageVisual::Property::CACHE_SIZE, 4);
+ propertyMap.Insert(ImageVisual::Property::FRAME_DELAY, 20);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, "invalid.jpg");
+
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+ dummyControl.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(dummyControl);
+
+ application.SendNotification();
+ application.Render();
+
+ // load two frame(batch size), load mask image, and do not request two masking
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(20);
+
+ DALI_TEST_EQUALS(gl.GetLastGenTextureId(), 2, TEST_LOCATION);
+
+ dummyControl.Unparent();
+ }
+ tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(20);
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(20);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask04(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask04 for GPU Alpha Masking with broken mask texture");
TestGlAbstraction& gl = application.GetGlAbstraction();
{
propertyMap.Insert(ImageVisual::Property::BATCH_SIZE, 2);
propertyMap.Insert(ImageVisual::Property::CACHE_SIZE, 4);
propertyMap.Insert(ImageVisual::Property::FRAME_DELAY, 20);
- propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, "");
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, "invalid.jpg");
propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
VisualFactory factory = VisualFactory::Get();
application.SendNotification();
application.Render();
+ // load two frame(batch size), load mask image, and do not request two masking
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(20);
+
+ DALI_TEST_EQUALS(gl.GetLastGenTextureId(), 2, TEST_LOCATION);
+
+ dummyControl.Unparent();
+ }
+ tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(20);
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(20);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask05(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask05 for CPU Alpha Masking with encoded image buffer");
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ {
+ EncodedImageBuffer rawBuffer = ConvertFileToEncodedImageBuffer(TEST_MASK_IMAGE_FILE_NAME);
+ ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(rawBuffer);
+ std::string url = imageUrl.GetUrl();
+
+ Property::Map propertyMap;
+ propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, TEST_GIF_FILE_NAME);
+ propertyMap.Insert(ImageVisual::Property::BATCH_SIZE, 2);
+ propertyMap.Insert(ImageVisual::Property::CACHE_SIZE, 4);
+ propertyMap.Insert(ImageVisual::Property::FRAME_DELAY, 20);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, url);
+
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+ dummyControl.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(dummyControl);
+
+ application.SendNotification();
+ application.Render();
+
// load two frame(batch size), load mask image, and request two masking
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(5), true, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render(20);
+
+ DALI_TEST_EQUALS(gl.GetLastGenTextureId(), 2, TEST_LOCATION);
+
+ dummyControl.Unparent();
+ }
+ tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(20);
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(20);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask06(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("UtcDaliAnimatedImageVisualAnimatedImageWithAlphaMask06 for GPU Alpha Masking with encoded image buffer");
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ {
+ EncodedImageBuffer rawBuffer = ConvertFileToEncodedImageBuffer(TEST_MASK_IMAGE_FILE_NAME);
+ ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(rawBuffer);
+ std::string url = imageUrl.GetUrl();
+
+ Property::Map propertyMap;
+ propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, TEST_GIF_FILE_NAME);
+ propertyMap.Insert(ImageVisual::Property::BATCH_SIZE, 2);
+ propertyMap.Insert(ImageVisual::Property::CACHE_SIZE, 4);
+ propertyMap.Insert(ImageVisual::Property::FRAME_DELAY, 20);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, url);
+ propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+ dummyControl.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(dummyControl);
+
+ application.SendNotification();
+ application.Render();
+
+ // load two frame(batch size), load mask image, and do not request two masking
DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
application.SendNotification();
dummyControl.Unparent();
}
tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(20);
+ application.RunIdles();
application.SendNotification();
application.Render(20);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
dummyControl.Unparent();
}
tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ application.RunIdles();
application.SendNotification();
application.Render(16);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
dummyControl.Unparent();
}
tet_infoline("Test that removing the visual from window deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ application.RunIdles();
application.SendNotification();
application.Render(16);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
dummyControl2.Unparent();
}
tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ application.RunIdles();
application.SendNotification();
application.Render(16);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
}
tet_infoline("Test that removing the visual from stage deletes all textures");
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ application.RunIdles();
application.SendNotification();
application.Render(16);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
dummyControl.Unparent();
}
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ application.RunIdles();
application.SendNotification();
application.Render(16);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
tet_infoline("Test that pending batch of image loads are cancelled instead of uploaded");
DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(4), true, TEST_LOCATION);
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ application.RunIdles();
application.SendNotification();
application.Render(16);
DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
END_TEST;
}
+int UtcDaliAnimatedImageVisualExternalImage01(void)
+{
+ ToolkitTestApplication application;
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ tet_infoline("Test various cases of url with external image");
+
+ for(int testCase = 0; testCase < 6; testCase++)
+ {
+ ExternalUrlType type = static_cast<ExternalUrlType>(testCase % 2);
+ ExternalUrlType maskType = static_cast<ExternalUrlType>(testCase / 3);
+
+ const bool useMask = (maskType == ExternalUrlType::EXTERNAL_TEXTURE || maskType == ExternalUrlType::ENCODED_IMAGE_BUFFER);
+
+ ImageUrl imageUrl = ConvertFileToImageUrl(TEST_GIF_FILE_NAME, type);
+ ImageUrl maskImageUrl;
+
+ int preCreatedTextureCount = 0;
+ if(imageUrl.GetUrl()[0] == 'd')
+ {
+ ++preCreatedTextureCount;
+ }
+
+ if(useMask)
+ {
+ maskImageUrl = ConvertFileToImageUrl(TEST_MASK_IMAGE_FILE_NAME, maskType);
+ if(maskImageUrl.GetUrl()[0] == 'd')
+ {
+ ++preCreatedTextureCount;
+ }
+ }
+
+ tet_printf("Test case : %d, image type : %d, mask type : %d. pre-created texture count : %d\n", testCase, type, maskType, preCreatedTextureCount);
+
+ // TODO : Need to fix this UTC
+
+ {
+ Property::Map propertyMap;
+ propertyMap.Insert(Visual::Property::TYPE, Visual::ANIMATED_IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, imageUrl.GetUrl());
+ propertyMap.Insert(ImageVisual::Property::BATCH_SIZE, 4);
+ propertyMap.Insert(ImageVisual::Property::CACHE_SIZE, 8);
+ propertyMap.Insert(ImageVisual::Property::FRAME_DELAY, 100);
+ propertyMap.Insert(DevelImageVisual::Property::FRAME_SPEED_FACTOR, 1.5f);
+ if(useMask)
+ {
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, maskImageUrl.GetUrl());
+ propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+ }
+
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+
+ // Expect that a batch of 4 textures has been requested. These will be serially loaded
+ // below.
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+ dummyControl.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(dummyControl);
+ application.SendNotification();
+ application.Render(16);
+
+ int expectTriggerCount = 0;
+ int expectTextureCount = preCreatedTextureCount;
+ if(imageUrl.GetUrl()[0] == 'e')
+ {
+ ++expectTriggerCount;
+ ++expectTextureCount;
+ }
+
+ if(useMask && maskImageUrl.GetUrl()[0] == 'e')
+ {
+ ++expectTriggerCount;
+ ++expectTextureCount;
+ }
+
+ tet_printf("Ready the visual after the visual is on stage (trigger count : %d, texture count : %d)\n", expectTriggerCount, expectTextureCount);
+ if(expectTriggerCount)
+ {
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(expectTriggerCount), true, TEST_LOCATION);
+ }
+
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ application.SendNotification();
+ application.Render(16);
+
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), expectTextureCount, TEST_LOCATION);
+ DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+
+ dummyControl.Unparent();
+ }
+ tet_infoline("Test that removing the visual from stage deletes all textures");
+ imageUrl.Reset();
+ maskImageUrl.Reset();
+
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliAnimatedImageVisualExternalMultiImage01(void)
+{
+ ToolkitTestApplication application;
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ tet_infoline("Test various cases of urls with external images");
+
+ for(int testCase = 0; testCase < 9; testCase++)
+ {
+ ExternalUrlType type = static_cast<ExternalUrlType>(testCase % 3);
+ ExternalUrlType maskType = static_cast<ExternalUrlType>(testCase / 3);
+
+ const bool useMask = (maskType == ExternalUrlType::EXTERNAL_TEXTURE || maskType == ExternalUrlType::ENCODED_IMAGE_BUFFER);
+
+ Property::Array urls;
+ std::vector<ImageUrl> imageUrlHolder;
+ CopyExternalUrlsIntoArray(urls, imageUrlHolder, 0, type);
+ int preCreatedTextureCount = 0;
+ for(size_t i = 0u; i < imageUrlHolder.size(); i++)
+ {
+ if(imageUrlHolder[i].GetUrl()[0] == 'd')
+ {
+ ++preCreatedTextureCount;
+ }
+ }
+
+ ImageUrl maskImageUrl;
+ if(useMask)
+ {
+ maskImageUrl = ConvertFileToImageUrl(TEST_MASK_IMAGE_FILE_NAME, maskType);
+ if(maskImageUrl.GetUrl()[0] == 'd')
+ {
+ ++preCreatedTextureCount;
+ }
+ }
+
+ tet_printf("Test case : %d, image type : %d, mask type : %d. pre-created texture count : %d\n", testCase, type, maskType, preCreatedTextureCount);
+
+ // TODO : Need to fix this UTC
+
+ {
+ Property::Map propertyMap;
+ propertyMap.Insert(Visual::Property::TYPE, Visual::IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, Property::Value(urls));
+ propertyMap.Insert(ImageVisual::Property::BATCH_SIZE, 4);
+ propertyMap.Insert(ImageVisual::Property::CACHE_SIZE, 8);
+ propertyMap.Insert(ImageVisual::Property::FRAME_DELAY, 100);
+ propertyMap.Insert(DevelImageVisual::Property::FRAME_SPEED_FACTOR, 1.5f);
+ if(useMask)
+ {
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, maskImageUrl.GetUrl());
+ propertyMap.Insert(DevelImageVisual::Property::MASKING_TYPE, DevelImageVisual::MaskingType::MASKING_ON_RENDERING);
+ }
+
+ VisualFactory factory = VisualFactory::Get();
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+
+ // Expect that a batch of 4 textures has been requested. These will be serially loaded
+ // below.
+
+ DummyControl dummyControl = DummyControl::New(true);
+ Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(dummyControl.GetImplementation());
+ dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, visual);
+
+ dummyControl.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
+ application.GetScene().Add(dummyControl);
+ application.SendNotification();
+ application.Render(16);
+
+ int expectTriggerCount = 0;
+ int expectTextureCount = preCreatedTextureCount;
+ for(int i = 0; i < 4; i++)
+ {
+ if(imageUrlHolder[(i % imageUrlHolder.size())].GetUrl()[0] == 'e')
+ {
+ ++expectTriggerCount;
+ ++expectTextureCount;
+ }
+ }
+
+ if(useMask && maskImageUrl.GetUrl()[0] == 'e')
+ {
+ ++expectTriggerCount;
+ ++expectTextureCount;
+ }
+
+ tet_printf("Ready the visual after the visual is on stage (trigger count : %d, texture count : %d)\n", expectTriggerCount, expectTextureCount);
+ if(expectTriggerCount)
+ {
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(expectTriggerCount), true, TEST_LOCATION);
+ }
+
+ tet_printf("Test that a timer has been started\n");
+ DALI_TEST_EQUALS(Test::GetTimerCount(), 1, TEST_LOCATION);
+
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ application.SendNotification();
+ application.Render(16);
+
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), expectTextureCount, TEST_LOCATION);
+ DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+
+ tet_printf("Test that after 1 tick, and file loads completed, that we have 7 textures\n");
+ Test::EmitGlobalTimerSignal();
+
+ expectTriggerCount = 0;
+ for(int i = 0; i < 1; i++)
+ {
+ if(imageUrlHolder[(i % imageUrlHolder.size())].GetUrl()[0] == 'e')
+ {
+ --expectTextureCount;
+ }
+ }
+ for(int i = 4; i < 8; i++)
+ {
+ if(imageUrlHolder[(i % imageUrlHolder.size())].GetUrl()[0] == 'e')
+ {
+ ++expectTriggerCount;
+ ++expectTextureCount;
+ }
+ }
+
+ // Expect the second batch has been requested
+ tet_printf("Expect the second batch has been requested (trigger count : %d, texture count : %d)\n", expectTriggerCount, expectTextureCount);
+ if(expectTriggerCount)
+ {
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(expectTriggerCount), true, TEST_LOCATION);
+ }
+
+ application.SendNotification();
+ application.Render(16);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), expectTextureCount, TEST_LOCATION);
+
+ for(int i = 1; i < 2; i++)
+ {
+ if(imageUrlHolder[(i % imageUrlHolder.size())].GetUrl()[0] == 'e')
+ {
+ --expectTextureCount;
+ }
+ }
+ tet_printf("Test that after 2 ticks that we have 6 textures (texture count : %d)\n", expectTextureCount);
+
+ Test::EmitGlobalTimerSignal();
+ application.SendNotification();
+ application.Render(16);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), expectTextureCount, TEST_LOCATION);
+
+ expectTriggerCount = 0;
+ for(int i = 8; i < 10; i++)
+ {
+ if(imageUrlHolder[(i % imageUrlHolder.size())].GetUrl()[0] == 'e')
+ {
+ ++expectTriggerCount;
+ ++expectTextureCount;
+ }
+ }
+ tet_printf("And that at least 2 textures were requested (trigger count : %d, texture count : %d)\n", expectTriggerCount, expectTextureCount);
+ if(expectTriggerCount)
+ {
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(expectTriggerCount), true, TEST_LOCATION);
+ }
+ application.SendNotification();
+ application.Render(16);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), expectTextureCount, TEST_LOCATION);
+
+ for(int i = 2; i < 3; i++)
+ {
+ if(imageUrlHolder[(i % imageUrlHolder.size())].GetUrl()[0] == 'e')
+ {
+ --expectTextureCount;
+ }
+ }
+ tet_printf("Test that after 3rd tick that we have 7 textures and 1 request (texture count : %d)\n", expectTextureCount);
+ Test::EmitGlobalTimerSignal();
+ application.SendNotification();
+ application.Render(16);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), expectTextureCount, TEST_LOCATION);
+
+ expectTriggerCount = 0;
+ for(int i = 10; i < 11; i++)
+ {
+ if(imageUrlHolder[(i % imageUrlHolder.size())].GetUrl()[0] == 'e')
+ {
+ ++expectTriggerCount;
+ ++expectTextureCount;
+ }
+ }
+ if(expectTriggerCount)
+ {
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(expectTriggerCount), true, TEST_LOCATION);
+ }
+ application.SendNotification();
+ application.Render(16);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), expectTextureCount, TEST_LOCATION);
+
+ dummyControl.Unparent();
+ }
+ tet_infoline("Test that removing the visual from stage deletes all textures");
+ imageUrlHolder.clear();
+ maskImageUrl.Reset();
+
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ application.RunIdles();
+ application.SendNotification();
+ application.Render(16);
+ DALI_TEST_EQUALS(gl.GetNumGeneratedTextures(), 0, TEST_LOCATION);
+ }
+
+ END_TEST;
+}
+
namespace
{
void TestLoopCount(ToolkitTestApplication& application, DummyControl& dummyControl, uint16_t frameCount, uint16_t loopCount, const char* location)
END_TEST;
}
-int UtcDaliImageVisualWithPixelDataMasking(void)
+int UtcDaliImageVisualWithPixelDataMasking01(void)
{
ToolkitTestApplication application;
tet_infoline("Load external texture with mask");
DALI_TEST_CHECK(pixelData);
- ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData, true);
+ ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData);
std::string url = imageUrl.GetUrl();
VisualFactory factory = VisualFactory::Get();
DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+ // Update result map after load completed.
+ visual.CreatePropertyMap(testMap);
+
+ Renderer renderer = actor.GetRendererAt(0);
+
+ //Check visual property
+ DALI_TEST_EQUALS(*testMap.Find(Visual::Property::PREMULTIPLIED_ALPHA), Property::Value(false), TEST_LOCATION);
+
+ // Check whether preMultipliedAlpha is false.
+ auto preMultipliedAlpha = renderer.GetProperty<bool>(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA);
+ DALI_TEST_EQUALS(preMultipliedAlpha, false, TEST_LOCATION);
+
dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1);
DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+ // Update result map after load completed.
+ visual.CreatePropertyMap(testMap);
+
Renderer renderer = actor.GetRendererAt(0);
//Check visual property
END_TEST;
}
+int UtcDaliImageVisualWithPixelDataMasking03(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("Load external texture with invalid mask file");
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ uint32_t width(64);
+ uint32_t height(64);
+ uint32_t bufferSize = width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888);
+
+ uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+ PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE);
+
+ DALI_TEST_CHECK(pixelData);
+
+ ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData);
+ std::string url = imageUrl.GetUrl();
+
+ VisualFactory factory = VisualFactory::Get();
+ DALI_TEST_CHECK(factory);
+
+ Property::Map propertyMap;
+ propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, url);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, TEST_INVALID_FILE_NAME);
+
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+ DALI_TEST_CHECK(visual);
+
+ Property::Map testMap;
+ visual.CreatePropertyMap(testMap);
+ DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(TEST_INVALID_FILE_NAME), TEST_LOCATION);
+
+ DummyControl actor = DummyControl::New();
+ DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+ dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual);
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+
+ application.GetScene().Add(actor);
+ application.SendNotification();
+ application.Render(16);
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+
+ // Update result map after load completed.
+ visual.CreatePropertyMap(testMap);
+
+ Renderer renderer = actor.GetRendererAt(0);
+
+ //Check visual property
+ DALI_TEST_EQUALS(*testMap.Find(Visual::Property::PREMULTIPLIED_ALPHA), Property::Value(false), TEST_LOCATION);
+
+ // Check whether preMultipliedAlpha is false.
+ auto preMultipliedAlpha = renderer.GetProperty<bool>(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA);
+ DALI_TEST_EQUALS(preMultipliedAlpha, false, TEST_LOCATION);
+
+ dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1);
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliImageVisualWithPixelDataMasking04(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("Load external texture with external texture mask");
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ uint32_t width(64);
+ uint32_t height(64);
+ uint32_t bufferSize = width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888);
+
+ uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+ PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE);
+
+ DALI_TEST_CHECK(pixelData);
+
+ ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData);
+ std::string url = imageUrl.GetUrl();
+
+ uint8_t* anotherBuffer = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+ PixelData maskPixelData = PixelData::New(anotherBuffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE);
+ ImageUrl maskImageUrl = Dali::Toolkit::Image::GenerateUrl(maskPixelData);
+ std::string maskUrl = maskImageUrl.GetUrl();
+
+ VisualFactory factory = VisualFactory::Get();
+ DALI_TEST_CHECK(factory);
+
+ Property::Map propertyMap;
+ propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, url);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, maskUrl);
+
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+ DALI_TEST_CHECK(visual);
+
+ Property::Map testMap;
+ visual.CreatePropertyMap(testMap);
+ DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(maskUrl), TEST_LOCATION);
+
+ DummyControl actor = DummyControl::New();
+ DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+ dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual);
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+
+ application.GetScene().Add(actor);
+ application.SendNotification();
+ application.Render(16);
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+
+ // Update result map after load completed.
+ visual.CreatePropertyMap(testMap);
+
+ Renderer renderer = actor.GetRendererAt(0);
+
+ //Check visual property
+ DALI_TEST_EQUALS(*testMap.Find(Visual::Property::PREMULTIPLIED_ALPHA), Property::Value(false), TEST_LOCATION);
+
+ // Check whether preMultipliedAlpha is false.
+ auto preMultipliedAlpha = renderer.GetProperty<bool>(Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA);
+ DALI_TEST_EQUALS(preMultipliedAlpha, false, TEST_LOCATION);
+
+ dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1);
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+
+ END_TEST;
+}
+
+int UtcDaliImageVisualWithPixelDataMasking05(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("Load image with external texture mask");
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ uint32_t width(64);
+ uint32_t height(64);
+ uint32_t bufferSize = width * height * Pixel::GetBytesPerPixel(Pixel::RGBA8888);
+
+ uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+ PixelData pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE);
+
+ DALI_TEST_CHECK(pixelData);
+
+ ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData);
+ std::string url = imageUrl.GetUrl();
+
+ VisualFactory factory = VisualFactory::Get();
+ DALI_TEST_CHECK(factory);
+
+ Property::Map propertyMap;
+ propertyMap.Insert(Toolkit::Visual::Property::TYPE, Visual::IMAGE);
+ propertyMap.Insert(ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME);
+ propertyMap.Insert(ImageVisual::Property::ALPHA_MASK_URL, url);
+
+ Visual::Base visual = factory.CreateVisual(propertyMap);
+ DALI_TEST_CHECK(visual);
+
+ Property::Map testMap;
+ visual.CreatePropertyMap(testMap);
+ DALI_TEST_EQUALS(*testMap.Find(ImageVisual::Property::ALPHA_MASK_URL), Property::Value(url), TEST_LOCATION);
+
+ DummyControl actor = DummyControl::New();
+ DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+ dummyImpl.RegisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1, visual);
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+
+ application.GetScene().Add(actor);
+ application.SendNotification();
+ application.Render(16);
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+ DALI_TEST_EQUALS(textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION);
+ DALI_TEST_EQUALS(actor.IsResourceReady(), true, TEST_LOCATION);
+
+ dummyImpl.UnregisterVisual(Control::CONTROL_PROPERTY_END_INDEX + 1);
+ DALI_TEST_EQUALS(actor.GetRendererCount(), 0u, TEST_LOCATION);
+
+ END_TEST;
+}
+
int UtcDaliImageVisualWithPixelDataMaskingSynchronously(void)
{
ToolkitTestApplication application;
DALI_TEST_CHECK(pixelData);
- ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData, true);
+ ImageUrl imageUrl = Dali::Toolkit::Image::GenerateUrl(pixelData);
std::string url = imageUrl.GetUrl();
VisualFactory factory = VisualFactory::Get();
VisualUrl TextureCacheManager::GetVisualUrl(const TextureCacheManager::TextureId textureId)
{
- VisualUrl visualUrl("");
+ VisualUrl visualUrl("");
+ if(textureId == INVALID_TEXTURE_ID)
+ {
+ return visualUrl;
+ }
+
TextureCacheIndex cacheIndex = static_cast<TextureCacheIndex>(mTextureIdConverter[static_cast<uint32_t>(textureId)]);
switch(static_cast<TextureCacheIndexType>(cacheIndex.detailValue.type))
TextureCacheManager::LoadState TextureCacheManager::GetTextureState(const TextureCacheManager::TextureId textureId)
{
- LoadState loadState = TextureCacheManager::LoadState::NOT_STARTED;
+ LoadState loadState = TextureCacheManager::LoadState::NOT_STARTED;
+ if(textureId == INVALID_TEXTURE_ID)
+ {
+ return loadState;
+ }
+
TextureCacheIndex cacheIndex = static_cast<TextureCacheIndex>(mTextureIdConverter[static_cast<uint32_t>(textureId)]);
switch(static_cast<TextureCacheIndexType>(cacheIndex.detailValue.type))
}
case TextureCacheIndexType::TEXTURE_CACHE_INDEX_TYPE_TEXTURE:
{
- loadState = LoadState::UPLOADED;
+ ExternalTextureInfo& cachedExternalTextureInfo(mExternalTextures[cacheIndex.GetIndex()]);
+ loadState = cachedExternalTextureInfo.textureSet ? LoadState::UPLOADED : LoadState::LOAD_FAILED;
break;
}
default:
return loadState;
}
-TextureCacheManager::LoadState TextureCacheManager::GetTextureStateInternal(const TextureCacheManager::TextureId textureId)
+Texture TextureCacheManager::GetTexture(const TextureCacheManager::TextureId textureId, const uint32_t textureIndex)
{
- LoadState loadState = TextureCacheManager::LoadState::NOT_STARTED;
- TextureCacheIndex cacheIndex = GetCacheIndexFromId(textureId);
- if(cacheIndex != INVALID_CACHE_INDEX)
+ Texture texture; // empty handle
+ if(textureId == INVALID_TEXTURE_ID)
{
- TextureInfo& cachedTextureInfo(mTextureInfoContainer[cacheIndex.GetIndex()]);
- loadState = cachedTextureInfo.loadState;
+ return texture;
}
- return loadState;
-}
-
-Texture TextureCacheManager::GetTexture(const TextureCacheManager::TextureId textureId, const uint32_t textureIndex)
-{
- Texture texture; // empty handle
- TextureCacheIndex cacheIndex = GetCacheIndexFromId(textureId);
+ TextureCacheIndex cacheIndex = static_cast<TextureCacheIndex>(mTextureIdConverter[static_cast<uint32_t>(textureId)]);
switch(static_cast<TextureCacheIndexType>(cacheIndex.detailValue.type))
{
}
break;
}
+ case TextureCacheIndexType::TEXTURE_CACHE_INDEX_TYPE_TEXTURE:
+ {
+ ExternalTextureInfo& cachedExternalTextureInfo(mExternalTextures[cacheIndex.GetIndex()]);
+ if(cachedExternalTextureInfo.textureSet && textureIndex < static_cast<uint32_t>(cachedExternalTextureInfo.textureSet.GetTextureCount()))
+ {
+ texture = cachedExternalTextureInfo.textureSet.GetTexture(textureIndex);
+ }
+ break;
+ }
default:
{
break;
EncodedImageBuffer encodedImageBuffer; // empty handle
if(url.IsValid() && VisualUrl::BUFFER == url.GetProtocolType())
{
- std::string location = url.GetLocationWithoutExtension();
- if(location.size() > 0u)
+ TextureId bufferId = INVALID_TEXTURE_ID;
+ if(url.GetLocationAsInteger(bufferId) && bufferId != INVALID_TEXTURE_ID)
{
- TextureId bufferId = std::stoi(location);
return GetEncodedImageBuffer(bufferId);
}
}
if(VisualUrl::TEXTURE == url.GetProtocolType())
{
// get the location from the Url
- std::string location = url.GetLocation();
- if(location.size() > 0u)
+ TextureId externalTextureId = INVALID_TEXTURE_ID;
+ if(url.GetLocationAsInteger(externalTextureId) && externalTextureId != INVALID_TEXTURE_ID)
{
- TextureId textureId = std::stoi(location);
- removeTextureIndex = GetCacheIndexFromExternalTextureId(textureId);
+ removeTextureIndex = GetCacheIndexFromExternalTextureId(externalTextureId);
if(removeTextureIndex != INVALID_CACHE_INDEX)
{
ExternalTextureInfo& textureInfo(mExternalTextures[removeTextureIndex.GetIndex()]);
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureCacheManager::RemoveExternalTexture(url:%s) textureId:%d reference:%d\n", url.GetUrl().c_str(), textureId, static_cast<int>(textureInfo.referenceCount));
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureCacheManager::RemoveExternalTexture(url:%s) textureId:%d reference:%d\n", url.GetUrl().c_str(), externalTextureId, static_cast<int>(textureInfo.referenceCount));
textureSet = textureInfo.textureSet;
if(--(textureInfo.referenceCount) <= 0)
{
removeTextureInfo = true;
// id life is finished. Remove it at converter
- mTextureIdConverter.Remove(textureId);
+ mTextureIdConverter.Remove(externalTextureId);
}
}
}
if(VisualUrl::BUFFER == url.GetProtocolType())
{
// get the location from the Url
- std::string location = url.GetLocationWithoutExtension();
- if(location.size() > 0u)
+ TextureId bufferId = INVALID_TEXTURE_ID;
+ if(url.GetLocationAsInteger(bufferId) && bufferId != INVALID_TEXTURE_ID)
{
- TextureId bufferId = std::stoi(location);
- removeBufferIndex = GetCacheIndexFromEncodedImageBufferId(bufferId);
+ removeBufferIndex = GetCacheIndexFromEncodedImageBufferId(bufferId);
if(removeBufferIndex != INVALID_CACHE_INDEX)
{
{
if(VisualUrl::TEXTURE == url.GetProtocolType())
{
- std::string location = url.GetLocation();
- if(location.size() > 0u)
+ TextureId externalTextureId = INVALID_TEXTURE_ID;
+ if(url.GetLocationAsInteger(externalTextureId) && externalTextureId != INVALID_TEXTURE_ID)
{
- TextureId id = std::stoi(location);
- TextureCacheIndex cacheIndex = GetCacheIndexFromExternalTextureId(id);
+ TextureCacheIndex cacheIndex = GetCacheIndexFromExternalTextureId(externalTextureId);
if(cacheIndex != INVALID_CACHE_INDEX)
{
ExternalTextureInfo& textureInfo(mExternalTextures[cacheIndex.GetIndex()]);
}
else if(VisualUrl::BUFFER == url.GetProtocolType())
{
- std::string location = url.GetLocationWithoutExtension();
- if(location.size() > 0u)
+ TextureId encodedImageBufferId = INVALID_TEXTURE_ID;
+ if(url.GetLocationAsInteger(encodedImageBufferId) && encodedImageBufferId != INVALID_TEXTURE_ID)
{
- TextureId id = std::stoi(location);
- TextureCacheIndex cacheIndex = GetCacheIndexFromEncodedImageBufferId(id);
+ TextureCacheIndex cacheIndex = GetCacheIndexFromEncodedImageBufferId(encodedImageBufferId);
if(cacheIndex != INVALID_CACHE_INDEX)
{
EncodedImageBufferInfo& bufferInfo(mEncodedImageBuffers[cacheIndex.GetIndex()]);
*/
TextureCacheManager::LoadState GetTextureState(const TextureCacheManager::TextureId textureId);
- /**
- * @brief Get the current state of a texture
- * @note This API doesn't consider external & encodedimagebuffer.
- * @param[in] textureId The texture id to query
- * @return The loading state if the texture is valid, or NOT_STARTED if the textureId
- * is not valid.
- */
- TextureCacheManager::LoadState GetTextureStateInternal(const TextureCacheManager::TextureId textureId);
-
/**
* @brief Get the associated texture set if the texture id is valid
* @param[in] textureId The texture Id to look up
loadState == TextureManagerType::LoadState::MASK_CANCELLED ? "MASK_CANCELLED" : \
loadState == TextureManagerType::LoadState::LOAD_FAILED ? "LOAD_FAILED" : \
"Unknown"
+
+#define GET_STORAGE_TYPE_STRING(storageType) \
+ storageType == TextureManagerType::StorageType::KEEP_PIXEL_BUFFER ? "KEEP_PIXEL_BUFFER" : \
+ storageType == TextureManagerType::StorageType::RETURN_PIXEL_BUFFER ? "RETURN_PIXEL_BUFFER" : \
+ storageType == TextureManagerType::StorageType::KEEP_TEXTURE ? "KEEP_TEXTURE" : \
+ storageType == TextureManagerType::StorageType::UPLOAD_TO_TEXTURE ? "UPLOAD_TO_TEXTURE" : \
+ "Unknown"
// clang-format on
#endif
{
TextureSet textureSet;
+ TextureId alphaMaskId = INVALID_TEXTURE_ID;
+ float contentScaleFactor = 1.0f;
+ bool cropToMask = false;
+ if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
+ {
+ const bool preappliedMasking = maskInfo->mPreappliedMasking && (VisualUrl::TEXTURE != url.GetProtocolType());
+ maskInfo->mPreappliedMasking = preappliedMasking;
+
+ maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl, preappliedMasking ? TextureManager::StorageType::KEEP_PIXEL_BUFFER : TextureManager::StorageType::KEEP_TEXTURE, synchronousLoading);
+ alphaMaskId = maskInfo->mAlphaMaskId;
+ if(maskInfo && preappliedMasking)
+ {
+ contentScaleFactor = maskInfo->mContentScaleFactor;
+ cropToMask = maskInfo->mCropToMask;
+ }
+ }
+
if(synchronousLoading)
{
+ // TODO : Please remove this duplicated codes.
+ // Since we don't cache sync loaded texture.
+ // But cannot remove it since AnimatedImageVisual didn't consider sync load cached case.
+ // It should be fixed soon.
Devel::PixelBuffer pixelBuffer;
if(animatedImageLoading)
{
else
{
Texture maskTexture;
- if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
+ if(alphaMaskId != INVALID_TEXTURE_ID)
{
- Devel::PixelBuffer maskPixelBuffer = LoadImageFromFile(maskInfo->mAlphaMaskUrl.GetUrl(), desiredSize, fittingMode, samplingMode, true);
- if(maskPixelBuffer)
+ TextureCacheIndex maskCacheIndex = mTextureCacheManager.GetCacheIndexFromId(alphaMaskId);
+ if(maskCacheIndex != INVALID_CACHE_INDEX)
{
- if(!maskInfo->mPreappliedMasking)
+ TextureInfo& maskTextureInfo(mTextureCacheManager[maskCacheIndex]);
+ if(maskTextureInfo.storageType == TextureManager::StorageType::UPLOAD_TO_TEXTURE ||
+ maskTextureInfo.storageType == TextureManager::StorageType::KEEP_TEXTURE)
{
- PixelData maskPixelData = Devel::PixelBuffer::Convert(maskPixelBuffer); // takes ownership of buffer
- maskTexture = Texture::New(Dali::TextureType::TEXTURE_2D, maskPixelData.GetPixelFormat(), maskPixelData.GetWidth(), maskPixelData.GetHeight());
- maskTexture.Upload(maskPixelData);
+ if(maskTextureInfo.textures.size() > TEXTURE_INDEX)
+ {
+ maskTexture = maskTextureInfo.textures[TEXTURE_INDEX];
+ }
+ else
+ {
+ DALI_LOG_ERROR("TextureManager::LoadAnimatedImageTexture: Synchronous mask image loading is failed\n");
+ }
}
- else
+ else if(maskTextureInfo.storageType == TextureManager::StorageType::KEEP_PIXEL_BUFFER)
{
- pixelBuffer.ApplyMask(maskPixelBuffer, maskInfo->mContentScaleFactor, maskInfo->mCropToMask);
+ Devel::PixelBuffer maskPixelBuffer = maskTextureInfo.pixelBuffer;
+ if(maskPixelBuffer)
+ {
+ if(!maskInfo->mPreappliedMasking)
+ {
+ PixelData maskPixelData = Devel::PixelBuffer::Convert(maskPixelBuffer); // takes ownership of buffer
+ maskTexture = Texture::New(Dali::TextureType::TEXTURE_2D, maskPixelData.GetPixelFormat(), maskPixelData.GetWidth(), maskPixelData.GetHeight());
+ maskTexture.Upload(maskPixelData);
+ }
+ else
+ {
+ pixelBuffer.ApplyMask(maskPixelBuffer, maskInfo->mContentScaleFactor, maskInfo->mCropToMask);
+ }
+ }
+ else
+ {
+ DALI_LOG_ERROR("TextureManager::LoadAnimatedImageTexture: Synchronous mask image loading is failed\n");
+ }
}
}
- else
- {
- DALI_LOG_ERROR("TextureManager::LoadAnimatedImageTexture: Synchronous mask image loading is failed\n");
- }
}
if(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD)
}
PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer); // takes ownership of buffer
- if(!textureSet)
+ Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight());
+ texture.Upload(pixelData);
+ textureSet = TextureSet::New();
+ textureSet.SetTexture(TEXTURE_INDEX, texture);
+ if(maskTexture)
{
- Texture texture = Texture::New(Dali::TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight());
- texture.Upload(pixelData);
- textureSet = TextureSet::New();
- textureSet.SetTexture(TEXTURE_INDEX, texture);
- if(maskTexture)
- {
- textureSet.SetTexture(MASK_TEXTURE_INDEX, maskTexture);
- }
+ textureSet.SetTexture(MASK_TEXTURE_INDEX, maskTexture);
}
}
}
else
{
- TextureId alphaMaskId = INVALID_TEXTURE_ID;
- float contentScaleFactor = 1.0f;
- bool cropToMask = false;
- if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
- {
- maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl, maskInfo->mPreappliedMasking ? TextureManager::StorageType::KEEP_PIXEL_BUFFER : TextureManager::StorageType::KEEP_TEXTURE);
- alphaMaskId = maskInfo->mAlphaMaskId;
- if(maskInfo->mPreappliedMasking)
- {
- contentScaleFactor = maskInfo->mContentScaleFactor;
- cropToMask = maskInfo->mCropToMask;
- }
- }
-
textureId = RequestLoadInternal(url, alphaMaskId, textureId, contentScaleFactor, desiredSize, fittingMode, samplingMode, cropToMask, TextureManager::StorageType::UPLOAD_TO_TEXTURE, textureObserver, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad, animatedImageLoading, frameIndex, false);
- TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
+ TextureManager::LoadState loadState = mTextureCacheManager.GetTextureState(textureId);
if(loadState == TextureManager::LoadState::UPLOADED)
{
// LoadComplete has already been called - keep the same texture set
if(VisualUrl::TEXTURE == url.GetProtocolType())
{
- std::string location = url.GetLocation();
- if(location.size() > 0u)
+ // Ensure that external texture don't allow atlasing.
+ atlasingStatus = false;
+ }
+
+ // For Atlas
+ if(synchronousLoading && atlasingStatus)
+ {
+ const bool synchronousAtlasAvaliable = (desiredSize != ImageDimensions() || url.IsLocalResource()) ? imageAtlasManager->CheckAtlasAvailable(url, desiredSize)
+ : false;
+ if(synchronousAtlasAvaliable)
{
- TextureId id = std::stoi(location);
- auto externalTextureInfo = mTextureCacheManager.GetExternalTextureInfo(id);
- if(externalTextureInfo.textureSet)
+ std::vector<Devel::PixelBuffer> pixelBuffers;
+ LoadImageSynchronously(url, desiredSize, fittingMode, samplingMode, orientationCorrection, false, pixelBuffers);
+
+ if(!pixelBuffers.empty() && maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
{
- if(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD)
+ std::vector<Devel::PixelBuffer> maskPixelBuffers;
+ LoadImageSynchronously(maskInfo->mAlphaMaskUrl, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, true, false, maskPixelBuffers);
+ if(!maskPixelBuffers.empty())
{
- // Change preMultiplyOnLoad value so make caller determine to preMultiplyAlpha or not.
- // TODO : Should we seperate input and output value?
- preMultiplyOnLoad = externalTextureInfo.preMultiplied ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+ pixelBuffers[0].ApplyMask(maskPixelBuffers[0], maskInfo->mContentScaleFactor, maskInfo->mCropToMask);
}
+ }
- TextureId alphaMaskId = INVALID_TEXTURE_ID;
- if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
- {
- maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl, TextureManager::StorageType::KEEP_TEXTURE, synchronousLoading);
- alphaMaskId = maskInfo->mAlphaMaskId;
-
- // Create new textureId. this textureId is not same as location
- textureId = RequestLoad(url, alphaMaskId, textureId, 1.0f, desiredSize, fittingMode, samplingMode, false, textureObserver, orientationCorrection, reloadPolicy, preMultiplyOnLoad, synchronousLoading);
+ PixelData data;
+ if(!pixelBuffers.empty())
+ {
+ PreMultiply(pixelBuffers[0], preMultiplyOnLoad);
+ data = Devel::PixelBuffer::Convert(pixelBuffers[0]); // takes ownership of buffer
- TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
- if(loadState == TextureManager::LoadState::UPLOADED)
+ if(data)
+ {
+ textureSet = imageAtlasManager->Add(textureRect, data);
+ if(textureSet)
{
- textureSet = GetTextureSet(textureId);
+ textureRectSize.SetWidth(data.GetWidth());
+ textureRectSize.SetHeight(data.GetHeight());
}
}
else
{
- // TextureId is same as location
- textureId = id;
-
- textureSet = TextureSet::New();
- textureSet.SetTexture(TEXTURE_INDEX, externalTextureInfo.textureSet.GetTexture(TEXTURE_INDEX));
+ DALI_LOG_ERROR("TextureManager::LoadTexture: Synchronous Texture loading with atlasing is failed.\n");
}
}
- }
- }
- else
- {
- // For Atlas
- if(synchronousLoading && atlasingStatus)
- {
- const bool synchronousAtlasAvaliable = (desiredSize != ImageDimensions() || url.IsLocalResource()) ? imageAtlasManager->CheckAtlasAvailable(url, desiredSize)
- : false;
- if(synchronousAtlasAvaliable)
+ if(!textureSet)
{
- std::vector<Devel::PixelBuffer> pixelBuffers;
- LoadImageSynchronously(url, desiredSize, fittingMode, samplingMode, orientationCorrection, false, pixelBuffers);
-
- if(!pixelBuffers.empty() && maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
- {
- std::vector<Devel::PixelBuffer> maskPixelBuffers;
- LoadImageSynchronously(maskInfo->mAlphaMaskUrl, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, true, false, maskPixelBuffers);
- if(!maskPixelBuffers.empty())
- {
- pixelBuffers[0].ApplyMask(maskPixelBuffers[0], maskInfo->mContentScaleFactor, maskInfo->mCropToMask);
- }
- }
-
- PixelData data;
- if(!pixelBuffers.empty())
- {
- PreMultiply(pixelBuffers[0], preMultiplyOnLoad);
- data = Devel::PixelBuffer::Convert(pixelBuffers[0]); // takes ownership of buffer
-
- if(data)
- {
- textureSet = imageAtlasManager->Add(textureRect, data);
- if(textureSet)
- {
- textureRectSize.SetWidth(data.GetWidth());
- textureRectSize.SetHeight(data.GetHeight());
- }
- }
- else
- {
- DALI_LOG_ERROR("TextureManager::LoadTexture: Synchronous Texture loading with atlasing is failed.\n");
- }
- }
- if(!textureSet)
- {
- atlasingStatus = false;
- }
+ atlasingStatus = false;
}
}
+ }
- if(!textureSet)
+ if(!textureSet)
+ {
+ loadingStatus = true;
+ // Atlas manager can chage desired size when it is set by 0,0.
+ // We should store into textureRectSize only if atlasing successed.
+ // So copy inputed desiredSize, and replace value into textureRectSize only if atlasing success.
+ Dali::ImageDimensions atlasDesiredSize = desiredSize;
+ if(atlasingStatus)
{
- loadingStatus = true;
- // Atlas manager can chage desired size when it is set by 0,0.
- // We should store into textureRectSize only if atlasing successed.
- // So copy inputed desiredSize, and replace value into textureRectSize only if atlasing success.
- Dali::ImageDimensions atlasDesiredSize = desiredSize;
- if(atlasingStatus)
+ if(url.IsBufferResource())
{
- if(url.IsBufferResource())
- {
- const EncodedImageBuffer& encodedImageBuffer = GetEncodedImageBuffer(url.GetUrl());
- if(encodedImageBuffer)
- {
- textureSet = imageAtlasManager->Add(textureRect, encodedImageBuffer, desiredSize, fittingMode, true, atlasObserver);
- }
- }
- else
+ const EncodedImageBuffer& encodedImageBuffer = GetEncodedImageBuffer(url.GetUrl());
+ if(encodedImageBuffer)
{
- textureSet = imageAtlasManager->Add(textureRect, url, atlasDesiredSize, fittingMode, true, atlasObserver);
+ textureSet = imageAtlasManager->Add(textureRect, encodedImageBuffer, desiredSize, fittingMode, true, atlasObserver);
}
}
- if(!textureSet) // big image, no atlasing or atlasing failed
+ else
{
- atlasingStatus = false;
+ textureSet = imageAtlasManager->Add(textureRect, url, atlasDesiredSize, fittingMode, true, atlasObserver);
+ }
+ }
+ if(!textureSet) // big image, no atlasing or atlasing failed
+ {
+ atlasingStatus = false;
- TextureId alphaMaskId = INVALID_TEXTURE_ID;
- float contentScaleFactor = 1.0f;
- bool cropToMask = false;
- if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
- {
- maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl, maskInfo->mPreappliedMasking ? TextureManager::StorageType::KEEP_PIXEL_BUFFER : TextureManager::StorageType::KEEP_TEXTURE, synchronousLoading);
- alphaMaskId = maskInfo->mAlphaMaskId;
- if(maskInfo && maskInfo->mPreappliedMasking)
- {
- contentScaleFactor = maskInfo->mContentScaleFactor;
- cropToMask = maskInfo->mCropToMask;
- }
- }
+ TextureId alphaMaskId = INVALID_TEXTURE_ID;
+ float contentScaleFactor = 1.0f;
+ bool cropToMask = false;
+ if(maskInfo && maskInfo->mAlphaMaskUrl.IsValid())
+ {
+ const bool preappliedMasking = maskInfo->mPreappliedMasking && (VisualUrl::TEXTURE != url.GetProtocolType());
+ maskInfo->mPreappliedMasking = preappliedMasking;
- textureId = RequestLoad(
- url,
- alphaMaskId,
- textureId,
- contentScaleFactor,
- desiredSize,
- fittingMode,
- samplingMode,
- cropToMask,
- textureObserver,
- orientationCorrection,
- reloadPolicy,
- preMultiplyOnLoad,
- synchronousLoading);
-
- TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
- if(loadState == TextureManager::LoadState::UPLOADED)
+ maskInfo->mAlphaMaskId = RequestMaskLoad(maskInfo->mAlphaMaskUrl, preappliedMasking ? TextureManager::StorageType::KEEP_PIXEL_BUFFER : TextureManager::StorageType::KEEP_TEXTURE, synchronousLoading);
+ alphaMaskId = maskInfo->mAlphaMaskId;
+ if(maskInfo && preappliedMasking)
{
- // LoadComplete has already been called - keep the same texture set
- textureSet = GetTextureSet(textureId);
+ contentScaleFactor = maskInfo->mContentScaleFactor;
+ cropToMask = maskInfo->mCropToMask;
}
-
- // If we are loading the texture, or waiting for the ready signal handler to complete, inform
- // caller that they need to wait.
- loadingStatus = (loadState == TextureManager::LoadState::LOADING ||
- loadState == TextureManager::LoadState::WAITING_FOR_MASK ||
- loadState == TextureManager::LoadState::MASK_APPLYING ||
- loadState == TextureManager::LoadState::MASK_APPLIED ||
- loadState == TextureManager::LoadState::NOT_STARTED ||
- mLoadingQueueTextureId != INVALID_TEXTURE_ID);
}
- else
+
+ textureId = RequestLoad(
+ url,
+ alphaMaskId,
+ textureId,
+ contentScaleFactor,
+ desiredSize,
+ fittingMode,
+ samplingMode,
+ cropToMask,
+ textureObserver,
+ orientationCorrection,
+ reloadPolicy,
+ preMultiplyOnLoad,
+ synchronousLoading);
+
+ TextureManager::LoadState loadState = mTextureCacheManager.GetTextureState(textureId);
+ if(loadState == TextureManager::LoadState::UPLOADED)
{
- textureRectSize = atlasDesiredSize;
+ // LoadComplete has already been called - keep the same texture set
+ textureSet = GetTextureSet(textureId);
}
+
+ // If we are loading the texture, or waiting for the ready signal handler to complete, inform
+ // caller that they need to wait.
+ loadingStatus = (loadState == TextureManager::LoadState::LOADING ||
+ loadState == TextureManager::LoadState::WAITING_FOR_MASK ||
+ loadState == TextureManager::LoadState::MASK_APPLYING ||
+ loadState == TextureManager::LoadState::MASK_APPLIED ||
+ loadState == TextureManager::LoadState::NOT_STARTED ||
+ mLoadingQueueTextureId != INVALID_TEXTURE_ID);
+ }
+ else
+ {
+ textureRectSize = atlasDesiredSize;
}
}
const bool synchronousLoading)
{
// Use the normal load procedure to get the alpha mask.
+ // TODO : Is their any case to pre multiply required case?
auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
return RequestLoadInternal(maskUrl, INVALID_TEXTURE_ID, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), Dali::FittingMode::SCALE_TO_FILL, Dali::SamplingMode::NO_FILTER, false, storageType, NULL, true, TextureManager::ReloadPolicy::CACHED, preMultiply, Dali::AnimatedImageLoading(), 0u, synchronousLoading);
}
// Check if the requested Texture exists in the cache.
if(cacheIndex != INVALID_CACHE_INDEX)
{
- if(TextureManager::ReloadPolicy::CACHED == reloadPolicy || TextureManager::INVALID_TEXTURE_ID == previousTextureId)
+ if(TextureManager::ReloadPolicy::CACHED == reloadPolicy || INVALID_TEXTURE_ID == previousTextureId)
{
// Mark this texture being used by another client resource, or Reload forced without request load before.
// Forced reload which have current texture before, would replace the current texture.
textureId = mTextureCacheManager[cacheIndex].textureId;
// Update preMultiplyOnLoad value. It should be changed according to preMultiplied value of the cached info.
- preMultiplyOnLoad = mTextureCacheManager[cacheIndex].preMultiplied ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s size=%hux%hu observer=%p ) Using cached texture id@%d, textureId=%d, maskTextureId=%d, prevTextureId=%d, frameindex=%d, premultiplied=%d, refCount=%d\n", url.GetUrl().c_str(), desiredSize.GetWidth(), desiredSize.GetHeight(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, previousTextureId, frameIndex, mTextureCacheManager[cacheIndex].preMultiplied ? 1 : 0, static_cast<int>(mTextureCacheManager[cacheIndex].referenceCount));
+ if(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD)
+ {
+ // Change preMultiplyOnLoad value so make caller determine to preMultiplyAlpha or not.
+ // TODO : Should we seperate input and output value?
+ preMultiplyOnLoad = mTextureCacheManager[cacheIndex].preMultiplied ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+ }
+
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s size=%hux%hu observer=%p ) Using cached texture id@%d, textureId=%d, maskTextureId=%d, prevTextureId=%d, frameindex=%d, orientCorrect=%d, premultiplied=%d, refCount=%d\n", url.GetUrl().c_str(), desiredSize.GetWidth(), desiredSize.GetHeight(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, previousTextureId, frameIndex, orientationCorrection, mTextureCacheManager[cacheIndex].preMultiplied ? 1 : 0, static_cast<int>(mTextureCacheManager[cacheIndex].referenceCount));
}
if(textureId == INVALID_TEXTURE_ID) // There was no caching, or caching not required
// Cache new texutre, and get cacheIndex.
cacheIndex = mTextureCacheManager.AppendCache(TextureInfo(textureId, maskTextureId, url, desiredSize, contentScale, fittingMode, samplingMode, false, cropToMask, textureHash, orientationCorrection, preMultiply, animatedImageLoading, frameIndex, loadYuvPlanes));
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s size=%hux%hu observer=%p ) New texture, cacheIndex:%d, textureId=%d, maskTextureId=%d, frameindex=%d premultiply=%d\n", url.GetUrl().c_str(), desiredSize.GetWidth(), desiredSize.GetHeight(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, frameIndex, preMultiply);
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s size=%hux%hu observer=%p ) New texture, cacheIndex:%d, textureId=%d, maskTextureId=%d, frameindex=%d orientCorrect=%d premultiply=%d\n", url.GetUrl().c_str(), desiredSize.GetWidth(), desiredSize.GetHeight(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, frameIndex, orientationCorrection, preMultiply);
}
// The below code path is common whether we are using the cache or not.
textureInfo.storageType = storageType;
textureInfo.orientationCorrection = orientationCorrection;
- // the case using external texture has already been loaded texture, so change its status to WAITING_FOR_MASK.
+ // the case using external texture has already been loaded texture, so change its status to UPLOADED or WAITING_FOR_MASK.
if(url.GetProtocolType() == VisualUrl::TEXTURE)
{
- if(textureInfo.loadState != TextureManager::LoadState::UPLOADED)
- {
- textureInfo.preMultiplied = (preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD);
- textureInfo.loadState = TextureManager::LoadState::WAITING_FOR_MASK;
- }
+ UpdateExternalTextureInfo(textureInfo, preMultiplyOnLoad);
}
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureInfo loadState:%s\n", GET_LOAD_STATE_STRING(textureInfo.loadState));
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureInfo loadState:%s, storageType:%s preMultiplyOnLoad:%d\n", GET_LOAD_STATE_STRING(textureInfo.loadState), GET_STORAGE_TYPE_STRING(textureInfo.storageType), (preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD));
// Force reloading of texture by setting loadState unless already loading or cancelled.
if(TextureManager::ReloadPolicy::FORCED == reloadPolicy &&
TextureManager::LoadState::MASK_APPLYING != textureInfo.loadState &&
TextureManager::LoadState::MASK_APPLIED != textureInfo.loadState &&
TextureManager::LoadState::CANCELLED != textureInfo.loadState &&
- TextureManager::LoadState::MASK_CANCELLED != textureInfo.loadState)
+ TextureManager::LoadState::MASK_CANCELLED != textureInfo.loadState &&
+ url.GetProtocolType() != VisualUrl::TEXTURE)
{
DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "TextureManager::RequestLoad( url=%s size=%hux%hu observer=%p ) ForcedReload cacheIndex:%d, textureId=%d, maskTextureId=%d, prevTextureId=%d\n", url.GetUrl().c_str(), desiredSize.GetWidth(), desiredSize.GetHeight(), observer, cacheIndex.GetIndex(), textureId, maskTextureId, previousTextureId);
textureInfo.loadState = TextureManager::LoadState::NOT_STARTED;
case TextureManager::LoadState::MASK_APPLIED:
{
// Do not observe even we reload forced when texture is already loading state.
- if(TextureManager::ReloadPolicy::CACHED == reloadPolicy || TextureManager::INVALID_TEXTURE_ID == previousTextureId)
+ if(TextureManager::ReloadPolicy::CACHED == reloadPolicy || INVALID_TEXTURE_ID == previousTextureId)
{
ObserveTexture(textureInfo, observer);
}
{
if(url.GetProtocolType() == VisualUrl::TEXTURE)
{
- // Get external textureSet from cacheManager.
- std::string location = textureInfo.url.GetLocation();
- if(!location.empty())
- {
- TextureId id = std::stoi(location);
- auto externalTextureInfo = mTextureCacheManager.GetExternalTextureInfo(id);
- textureInfo.textures.push_back(externalTextureInfo.textureSet.GetTexture(0));
- textureInfo.loadState = TextureManager::LoadState::UPLOADED;
- }
+ UpdateExternalTextureInfo(textureInfo, preMultiplyOnLoad);
}
else
{
}
else // For the image loading.
{
- Texture maskTexture;
if(maskTextureId != INVALID_TEXTURE_ID)
{
TextureCacheIndex maskCacheIndex = mTextureCacheManager.GetCacheIndexFromId(maskTextureId);
DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::ProcessLoadQueue() textureId=%d, observer=%p, cacheIndex=@%d, loadState:%s\n", element.mTextureId, element.mObserver, cacheIndex.GetIndex(), GET_LOAD_STATE_STRING(textureInfo.loadState));
if((textureInfo.loadState == TextureManager::LoadState::UPLOADED) ||
+ (textureInfo.loadState == TextureManager::LoadState::LOAD_FAILED) ||
(textureInfo.loadState == TextureManager::LoadState::LOAD_FINISHED &&
textureInfo.storageType == TextureManager::StorageType::RETURN_PIXEL_BUFFER))
{
DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, " Disconnect DestructionSignal to observer:%p\n", element.mObserver);
element.mObserver->DestructionSignal().Disconnect(this, &TextureManager::ObserverDestroyed);
- EmitLoadComplete(element.mObserver, textureInfo, true);
+ EmitLoadComplete(element.mObserver, textureInfo, (textureInfo.loadState != TextureManager::LoadState::LOAD_FAILED));
}
}
else if(textureInfo.loadState == TextureManager::LoadState::LOADING)
}
else
{
- LoadState maskLoadState = mTextureCacheManager.GetTextureStateInternal(textureInfo.maskTextureId);
+ LoadState maskLoadState = mTextureCacheManager.GetTextureState(textureInfo.maskTextureId);
textureInfo.pixelBuffer = pixelBuffer; // Store the pixel buffer temporarily
+
if(maskLoadState == TextureManager::LoadState::LOADING)
{
textureInfo.loadState = TextureManager::LoadState::WAITING_FOR_MASK;
if(maskTextureInfo.loadState == TextureManager::LoadState::LOAD_FINISHED)
{
- if(maskTextureInfo.storageType == TextureManager::StorageType::KEEP_PIXEL_BUFFER)
- {
- ApplyMask(textureInfo, maskTextureInfo.textureId);
- }
+ DALI_ASSERT_ALWAYS(maskTextureInfo.storageType == TextureManager::StorageType::KEEP_PIXEL_BUFFER && "Only KEEP_PIXEL_BUFFER storage type could be LOAD_FINISHED!");
+ ApplyMask(textureInfo, maskTextureInfo.textureId);
}
else if(maskTextureInfo.loadState == TextureManager::LoadState::UPLOADED)
{
- if(maskTextureInfo.storageType == TextureManager::StorageType::KEEP_TEXTURE)
+ DALI_ASSERT_ALWAYS(maskTextureInfo.storageType == TextureManager::StorageType::KEEP_TEXTURE && "Only KEEP_TEXTURE storage type could be UPLOADED!");
+ if(textureInfo.url.GetProtocolType() == VisualUrl::TEXTURE)
{
- if(textureInfo.url.GetProtocolType() == VisualUrl::TEXTURE)
- {
- // Get external textureSet from cacheManager.
- std::string location = textureInfo.url.GetLocation();
- if(!location.empty())
- {
- TextureId id = std::stoi(location);
- auto externalTextureInfo = mTextureCacheManager.GetExternalTextureInfo(id);
- textureInfo.textures.push_back(externalTextureInfo.textureSet.GetTexture(0));
- textureInfo.loadState = TextureManager::LoadState::UPLOADED;
- }
- }
- else
+ // Just change load state WAITING_FOR_MASK to UPLOADED (Since we already upload texture)
+ if(textureInfo.loadState == TextureManager::LoadState::WAITING_FOR_MASK)
{
- // Upload image texture. textureInfo.loadState will be UPLOADED.
- std::vector<Devel::PixelBuffer> pixelBuffers;
- pixelBuffers.push_back(textureInfo.pixelBuffer);
- UploadTextures(pixelBuffers, textureInfo);
+ textureInfo.loadState = TextureManager::LoadState::UPLOADED;
}
+ }
+ else
+ {
+ // Upload image texture. textureInfo.loadState will be UPLOADED.
+ std::vector<Devel::PixelBuffer> pixelBuffers;
+ pixelBuffers.push_back(textureInfo.pixelBuffer);
+ UploadTextures(pixelBuffers, textureInfo);
+ }
- // Increase reference counts for notify required textureId.
- // Now we can assume that we don't remove & re-assign this textureId
- // during NotifyObserver signal emit.
- maskTextureInfo.referenceCount++;
- textureInfo.referenceCount++;
+ // Increase reference counts for notify required textureId.
+ // Now we can assume that we don't remove & re-assign this textureId
+ // during NotifyObserver signal emit.
+ maskTextureInfo.referenceCount++;
+ textureInfo.referenceCount++;
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): Ready to notify textureId=%d\n", textureInfo.textureId);
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::CheckForWaitingTexture(): Ready to notify textureId=%d\n", textureInfo.textureId);
- notifyRequiredTextureIds.push_back(textureInfo.textureId);
- }
+ notifyRequiredTextureIds.push_back(textureInfo.textureId);
}
else // maskTextureInfo.loadState == TextureManager::LoadState::LOAD_FAILED
{
// Url texture load success, But alpha mask texture load failed. Run as normal image upload.
DALI_LOG_ERROR("Alpha mask image loading failed! Image will not be masked\n");
- std::vector<Devel::PixelBuffer> pixelBuffers;
- pixelBuffers.push_back(textureInfo.pixelBuffer);
- UploadTextures(pixelBuffers, textureInfo);
+ if(maskTextureInfo.storageType == TextureManager::StorageType::KEEP_TEXTURE && textureInfo.url.GetProtocolType() == VisualUrl::TEXTURE)
+ {
+ // Just change load state WAITING_FOR_MASK to UPLOADED (Since we already upload texture)
+ if(textureInfo.loadState == TextureManager::LoadState::WAITING_FOR_MASK)
+ {
+ textureInfo.loadState = TextureManager::LoadState::UPLOADED;
+ }
+ }
+ else
+ {
+ std::vector<Devel::PixelBuffer> pixelBuffers;
+ pixelBuffers.push_back(textureInfo.pixelBuffer);
+ UploadTextures(pixelBuffers, textureInfo);
+ }
// Increase reference counts for notify required textureId.
// Now we can assume that we don't remove & re-assign this textureId
// invalidating the reference to the textureInfo struct.
// Texture load requests for the same URL are deferred until the end of this
// method.
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::NotifyObservers() observer:%p textureId:%d size:%hux%hu url:%s loadState:%s\n", observer, textureId, info->desiredSize.GetWidth(), info->desiredSize.GetHeight(), info->url.GetUrl().c_str(), GET_LOAD_STATE_STRING(info->loadState));
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Concise, "TextureManager::NotifyObservers() observer:%p textureId:%d size:%hux%hu url:%s loadState:%s premultiplied:%d\n", observer, textureId, info->desiredSize.GetWidth(), info->desiredSize.GetHeight(), info->url.GetUrl().c_str(), GET_LOAD_STATE_STRING(info->loadState), info->preMultiplied);
// It is possible for the observer to be deleted.
// Disconnect and remove the observer first.
DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, " Disconnect DestructionSignal to observer:%p\n", observer);
}
else
{
- TextureSet textureSet = GetTextureSet(textureInfo);
+ TextureSet textureSet = GetTextureSetInternal(textureInfo);
if(textureInfo.isAnimatedImageFormat)
{
observer->LoadComplete(success, TextureUploadObserver::TextureInformation(TextureUploadObserver::ReturnType::ANIMATED_IMAGE_TEXTURE, textureInfo.textureId, textureSet, textureInfo.frameCount, textureInfo.frameInterval, textureInfo.preMultiplied));
TextureSet TextureManager::GetTextureSet(const TextureManager::TextureId textureId)
{
TextureSet textureSet;
- TextureManager::LoadState loadState = mTextureCacheManager.GetTextureStateInternal(textureId);
+ TextureManager::LoadState loadState = mTextureCacheManager.GetTextureState(textureId);
if(loadState == TextureManager::LoadState::UPLOADED)
{
TextureCacheIndex textureCacheIndex = mTextureCacheManager.GetCacheIndexFromId(textureId);
if(textureCacheIndex != INVALID_CACHE_INDEX)
{
TextureInfo& textureInfo(mTextureCacheManager[textureCacheIndex]);
- textureSet = GetTextureSet(textureInfo);
+ textureSet = GetTextureSetInternal(textureInfo);
}
}
- else
+
+ if(!textureSet)
{
- DALI_LOG_ERROR("GetTextureSet is failed. texture is not uploaded \n");
+ DALI_LOG_ERROR("GetTextureSet(%d) is failed. texture is not uploaded \n", textureId);
}
return textureSet;
}
-TextureSet TextureManager::GetTextureSet(const TextureManager::TextureInfo& textureInfo)
+void TextureManager::RemoveTextureObserver(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer)
+{
+ if(observer)
+ {
+ const auto iterEnd = textureInfo.observerList.End();
+ const auto iter = std::find(textureInfo.observerList.Begin(), iterEnd, observer);
+ if(iter != iterEnd)
+ {
+ // Disconnect and remove the observer.
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, " Disconnect DestructionSignal to observer:%p\n", observer);
+ observer->DestructionSignal().Disconnect(this, &TextureManager::ObserverDestroyed);
+ textureInfo.observerList.Erase(iter);
+ }
+ else
+ {
+ // Given textureId might exist at load queue.
+ // Remove observer from the LoadQueue
+ for(auto&& element : mLoadQueue)
+ {
+ if(element.mTextureId == textureInfo.textureId && element.mObserver == observer)
+ {
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "Remove observer from observer queue (textureId:%d, observer:%p)\n", element.mTextureId, element.mObserver);
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, " Disconnect DestructionSignal to observer:%p\n", observer);
+ observer->DestructionSignal().Disconnect(this, &TextureManager::ObserverDestroyed);
+ element.mObserver = nullptr;
+ break;
+ }
+ }
+ }
+ }
+}
+
+// Internal methods
+TextureSet TextureManager::GetTextureSetInternal(const TextureManager::TextureInfo& textureInfo)
{
TextureSet textureSet;
textureSet.SetTexture(index++, texture);
}
}
- else
+ else if(textureInfo.textures.size() > TEXTURE_INDEX)
{
- textureSet.SetTexture(TEXTURE_INDEX, textureInfo.textures[0]);
- TextureCacheIndex maskCacheIndex = mTextureCacheManager.GetCacheIndexFromId(textureInfo.maskTextureId);
- if(maskCacheIndex != INVALID_CACHE_INDEX)
+ textureSet.SetTexture(TEXTURE_INDEX, textureInfo.textures[TEXTURE_INDEX]);
+ if(textureInfo.maskTextureId != INVALID_TEXTURE_ID)
{
- TextureInfo& maskTextureInfo(mTextureCacheManager[maskCacheIndex]);
- if(maskTextureInfo.storageType == TextureManager::StorageType::UPLOAD_TO_TEXTURE || maskTextureInfo.storageType == TextureManager::StorageType::KEEP_TEXTURE)
+ TextureCacheIndex maskCacheIndex = mTextureCacheManager.GetCacheIndexFromId(textureInfo.maskTextureId);
+ if(maskCacheIndex != INVALID_CACHE_INDEX)
{
- if(!maskTextureInfo.textures.empty())
+ TextureInfo& maskTextureInfo(mTextureCacheManager[maskCacheIndex]);
+ if(maskTextureInfo.storageType == TextureManager::StorageType::UPLOAD_TO_TEXTURE ||
+ maskTextureInfo.storageType == TextureManager::StorageType::KEEP_TEXTURE)
{
- textureSet.SetTexture(MASK_TEXTURE_INDEX, maskTextureInfo.textures[0]);
+ if(maskTextureInfo.textures.size() > TEXTURE_INDEX)
+ {
+ textureSet.SetTexture(MASK_TEXTURE_INDEX, maskTextureInfo.textures[TEXTURE_INDEX]);
+ }
}
}
}
return textureSet;
}
-void TextureManager::RemoveTextureObserver(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer)
+void TextureManager::UpdateExternalTextureInfo(TextureManager::TextureInfo& textureInfo, TextureManager::MultiplyOnLoad& preMultiplyOnLoad)
{
- if(observer)
+ DALI_ASSERT_DEBUG(textureInfo.url.GetProtocolType() == VisualUrl::TEXTURE);
+
+ if(textureInfo.loadState == TextureManager::LoadState::UPLOADED ||
+ textureInfo.loadState == TextureManager::LoadState::WAITING_FOR_MASK ||
+ textureInfo.loadState == TextureManager::LoadState::LOAD_FAILED)
{
- const auto iterEnd = textureInfo.observerList.End();
- const auto iter = std::find(textureInfo.observerList.Begin(), iterEnd, observer);
- if(iter != iterEnd)
- {
- // Disconnect and remove the observer.
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, " Disconnect DestructionSignal to observer:%p\n", observer);
- observer->DestructionSignal().Disconnect(this, &TextureManager::ObserverDestroyed);
- textureInfo.observerList.Erase(iter);
- }
- else
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::GetInfo already called before. (textureId=%d url:%s premultiplied=%d, loadState:%s)\n", textureInfo.textureId, textureInfo.url.GetUrl().c_str(), textureInfo.preMultiplied, GET_LOAD_STATE_STRING(textureInfo.loadState));
+ return;
+ }
+
+ // To reduce duplicated failed case branch out, set loadState to LOAD_FAILED first.
+ textureInfo.loadState = TextureManager::LoadState::LOAD_FAILED;
+
+ // Get Texture from external textureset
+ TextureId externalTextureId = INVALID_TEXTURE_ID;
+ if(textureInfo.url.GetLocationAsInteger(externalTextureId) && externalTextureId != INVALID_TEXTURE_ID)
+ {
+ const auto& externalTextureInfo = mTextureCacheManager.GetExternalTextureInfo(externalTextureId);
+
+ if(externalTextureInfo.textureSet && externalTextureInfo.textureSet.GetTextureCount() > TEXTURE_INDEX)
{
- // Given textureId might exist at load queue.
- // Remove observer from the LoadQueue
- for(auto&& element : mLoadQueue)
+ auto externalTexture = externalTextureInfo.textureSet.GetTexture(TEXTURE_INDEX);
+ if(externalTexture)
{
- if(element.mTextureId == textureInfo.textureId && element.mObserver == observer)
+ textureInfo.textures.push_back(externalTexture);
+
+ if(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD)
{
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, "Remove observer from observer queue (textureId:%d, observer:%p)\n", element.mTextureId, element.mObserver);
- DALI_LOG_INFO(gTextureManagerLogFilter, Debug::Verbose, " Disconnect DestructionSignal to observer:%p\n", observer);
- observer->DestructionSignal().Disconnect(this, &TextureManager::ObserverDestroyed);
- element.mObserver = nullptr;
- break;
+ // TODO : Shouldn't we check preMultiplied value of external texture when TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY??
+ textureInfo.preMultiplied = externalTextureInfo.preMultiplied;
+
+ // Change preMultiplyOnLoad value so make caller determine to preMultiplyAlpha or not.
+ // TODO : Should we seperate input and output value?
+ preMultiplyOnLoad = textureInfo.preMultiplied ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+ }
+
+ if(textureInfo.maskTextureId != INVALID_TEXTURE_ID)
+ {
+ textureInfo.loadState = TextureManager::LoadState::WAITING_FOR_MASK;
+
+ // Check if mask texutre is already uploaded or not.
+ TextureManager::LoadState maskLoadState = mTextureCacheManager.GetTextureState(textureInfo.maskTextureId);
+ if(maskLoadState == TextureManager::LoadState::UPLOADED ||
+ maskLoadState == TextureManager::LoadState::LOAD_FAILED)
+ {
+ textureInfo.loadState = TextureManager::LoadState::UPLOADED;
+ }
+ }
+ else
+ {
+ textureInfo.loadState = TextureManager::LoadState::UPLOADED;
}
}
}
}
+ DALI_LOG_INFO(gTextureManagerLogFilter, Debug::General, "TextureManager::GetInfo from external. (textureId=%d url:%s exernalTextureId=%d premultiplied=%d, loadState:%s)\n", textureInfo.textureId, textureInfo.url.GetUrl().c_str(), externalTextureId, textureInfo.preMultiplied, GET_LOAD_STATE_STRING(textureInfo.loadState));
}
} // namespace Internal
*/
TextureSet GetTextureSet(const TextureManager::TextureId textureId);
- /**
- * @brief Returns the textureSet in texture manager.
- * @param[in] textureInfo the information of the texture
- * @return The textureSet in texture manager. These textures include YUV textures or images and masks.
- */
- TextureSet GetTextureSet(const TextureManager::TextureInfo& textureInfo);
-
public:
// API list that need to access TextureCacheManager.
*/
void RemoveTextureObserver(TextureManager::TextureInfo& textureInfo, TextureUploadObserver* observer);
+private: // Internal methods
+ /**
+ * @brief Returns the textureSet in texture manager.
+ * @param[in] textureInfo the information of the texture
+ * @return The textureSet in texture manager. These textures include YUV textures or images and masks.
+ */
+ TextureSet GetTextureSetInternal(const TextureManager::TextureInfo& textureInfo);
+
+ /**
+ * @brief Update texture info from external texture info if url is external texture.
+ * @param[in,out] textureInfo the information of the texture
+ * @param[in,out] preMultiplyOnLoad True if the image color should be multiplied by it's alpha. Set to false if the image has no alpha channel
+ */
+ void UpdateExternalTextureInfo(TextureManager::TextureInfo& textureInfo, TextureManager::MultiplyOnLoad& preMultiplyOnLoad);
+
public:
/**
* @brief Common method to handle loading completion.
// EXTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/image-loading.h>
#include <dali/devel-api/adaptor-framework/window-devel.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
#include <dali/integration-api/debug.h>
#include <dali/public-api/rendering/decorated-visual-renderer.h>
#include <memory>
ImageCache::UrlStore urlStore;
urlStore.mTextureId = TextureManager::INVALID_TEXTURE_ID;
urlStore.mUrl = imageUrls[i].Get<std::string>();
- visual->mImageUrls->push_back(urlStore);
+ if(DALI_LIKELY(Dali::Adaptor::IsAvailable()))
+ {
+ // Increase reference count of External Resources :
+ // EncodedImageBuffer or ExternalTextures.
+ // Reference count will be decreased at destructor of the visual.
+ urlStore.mUrl.IncreaseExternalResourceReference(factoryCache.GetTextureManager());
+ }
+ visual->mImageUrls->push_back(std::move(urlStore));
}
visual->mFrameCount = imageUrls.Count();
visual->SetProperties(properties);
ImageCache::UrlStore urlStore;
urlStore.mTextureId = TextureManager::INVALID_TEXTURE_ID;
urlStore.mUrl = imageUrl;
- mImageUrls->push_back(urlStore);
+ if(DALI_LIKELY(Dali::Adaptor::IsAvailable()))
+ {
+ // Increase reference count of External Resources :
+ // EncodedImageBuffer or ExternalTextures.
+ // Reference count will be decreased at destructor of the visual.
+ urlStore.mUrl.IncreaseExternalResourceReference(mFactoryCache.GetTextureManager());
+ }
+ mImageUrls->push_back(std::move(urlStore));
}
mFrameCount = SINGLE_IMAGE_COUNT;
}
uint16_t numUrls = mImageUrls->size();
uint16_t batchSize = std::max(std::min(mBatchSize, numUrls), MINIMUM_CACHESIZE);
uint16_t cacheSize = std::max(std::min(std::max(batchSize, mCacheSize), numUrls), MINIMUM_CACHESIZE);
+
if(cacheSize < numUrls)
{
mImageCache = new RollingImageCache(textureManager, mDesiredSize, mFittingMode, mSamplingMode, *mImageUrls, mMaskingData, *this, cacheSize, batchSize, mFrameDelay, IsPreMultipliedAlphaEnabled());
mAnimatedImageLoading(),
mFrameIndexForJumpTo(0),
mCurrentFrameIndex(FIRST_FRAME_INDEX),
- mImageUrls(NULL),
- mImageCache(NULL),
+ mImageUrls(nullptr),
+ mImageCache(nullptr),
mCacheSize(2),
mBatchSize(2),
mFrameDelay(100),
mImageCache->ClearCache();
}
}
+
+ if(DALI_LIKELY(Dali::Adaptor::IsAvailable()))
+ {
+ TextureManager& textureManager = mFactoryCache.GetTextureManager();
+
+ if(mImageUrls != nullptr && !mImageUrls->empty())
+ {
+ for(const auto& urlStore : *mImageUrls)
+ {
+ urlStore.mUrl.DecreaseExternalResourceReference(textureManager);
+ }
+ }
+
+ if(mMaskingData)
+ {
+ mMaskingData->mAlphaMaskUrl.DecreaseExternalResourceReference(textureManager);
+ }
+ }
delete mImageCache;
delete mImageUrls;
}
{
map.Insert(Toolkit::ImageVisual::Property::URL, mImageUrl.GetUrl());
}
- if(mImageUrls != NULL && !mImageUrls->empty())
+ if(mImageUrls != nullptr && !mImageUrls->empty())
{
Property::Array urls;
for(unsigned int i = 0; i < mImageUrls->size(); ++i)
{
AllocateMaskData();
mMaskingData->mAlphaMaskUrl = alphaUrl;
+ if(mMaskingData->mAlphaMaskUrl.IsValid())
+ {
+ if(DALI_LIKELY(Dali::Adaptor::IsAvailable()))
+ {
+ // Increase reference count of External Resources :
+ // EncodedImageBuffer or ExternalTextures.
+ // Reference count will be decreased at destructor of the visual.
+ mMaskingData->mAlphaMaskUrl.IncreaseExternalResourceReference(mFactoryCache.GetTextureManager());
+ }
+ if(mMaskingData->mAlphaMaskUrl.GetProtocolType() == VisualUrl::TEXTURE)
+ {
+ mMaskingData->mPreappliedMasking = false;
+ }
+ }
}
break;
}
if(value.Get(maskingType))
{
AllocateMaskData();
- mMaskingData->mPreappliedMasking = Toolkit::DevelImageVisual::MaskingType::Type(maskingType) == Toolkit::DevelImageVisual::MaskingType::MASKING_ON_LOADING ? true : false;
+
+ bool externalTextureUsed = false;
+ if(mMaskingData->mAlphaMaskUrl.IsValid() && mMaskingData->mAlphaMaskUrl.GetProtocolType() == VisualUrl::TEXTURE)
+ {
+ externalTextureUsed = true;
+ }
+ else if(mImageUrls != nullptr && !mImageUrls->empty())
+ {
+ for(const auto& urlStore : *mImageUrls)
+ {
+ const auto& imageUrl = urlStore.mUrl;
+ if(imageUrl.IsValid() && imageUrl.GetProtocolType() == VisualUrl::TEXTURE)
+ {
+ externalTextureUsed = true;
+ break;
+ }
+ }
+ }
+
+ if(externalTextureUsed)
+ {
+ // For external textures, only gpu masking is available.
+ // Therefore, MASKING_TYPE is set to MASKING_ON_RENDERING forcelly.
+ mMaskingData->mPreappliedMasking = false;
+ }
+ else
+ {
+ mMaskingData->mPreappliedMasking = (Toolkit::DevelImageVisual::MaskingType::Type(maskingType) == Toolkit::DevelImageVisual::MaskingType::MASKING_ON_LOADING);
+ }
}
break;
}
mPixelAreaIndex = mImpl->mRenderer.RegisterUniqueProperty(Toolkit::ImageVisual::Property::PIXEL_AREA, PIXEL_AREA_UNIFORM_NAME, mPixelArea);
}
- if(mMaskingData)
- {
- mImpl->mRenderer.RegisterUniqueProperty(Toolkit::ImageVisual::Property::CROP_TO_MASK, CROP_TO_MASK_NAME, static_cast<float>(mMaskingData->mCropToMask));
- }
-
// Enable PreMultipliedAlpha if it need.
auto preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader
? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
: TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
EnablePreMultipliedAlpha(preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD);
+
+ if(mMaskingData)
+ {
+ mImpl->mRenderer.RegisterUniqueProperty(Toolkit::ImageVisual::Property::CROP_TO_MASK, CROP_TO_MASK_NAME, static_cast<float>(mMaskingData->mCropToMask));
+ }
}
void AnimatedImageVisual::StartFirstFrame(TextureSet& textureSet, uint32_t firstInterval)
if(!mMaskingData)
{
mMaskingData.reset(new TextureManager::MaskingData());
+
+ // Note : If input url was TEXTURE protocol, it will fail to create AnimatedImageLoading.
+ // So it should be added at mImageUrls.
+ if(mImageUrls != nullptr && !mImageUrls->empty())
+ {
+ for(const auto& urlStore : *mImageUrls)
+ {
+ const auto& imageUrl = urlStore.mUrl;
+ if(imageUrl.IsValid() && imageUrl.GetProtocolType() == VisualUrl::TEXTURE)
+ {
+ mMaskingData->mPreappliedMasking = false;
+ break;
+ }
+ }
+ }
}
}
{
if(DALI_LIKELY(Dali::Adaptor::IsAvailable()))
{
- if(mImageUrl.IsValid())
{
- // Decrease reference count of External Resources :
- // EncodedImageBuffer or ExternalTextures.
- // Ensure the stage is still valid before accessing texture manager.
- if(mImageUrl.GetProtocolType() == VisualUrl::TEXTURE)
- {
- TextureManager& textureManager = mFactoryCache.GetTextureManager();
- textureManager.RemoveExternalTexture(mImageUrl);
- }
- else if(mImageUrl.IsBufferResource())
+ TextureManager& textureManager = mFactoryCache.GetTextureManager();
+
+ mImageUrl.DecreaseExternalResourceReference(textureManager);
+ if(mMaskingData)
{
- TextureManager& textureManager = mFactoryCache.GetTextureManager();
- textureManager.RemoveEncodedImageBuffer(mImageUrl);
+ mMaskingData->mAlphaMaskUrl.DecreaseExternalResourceReference(textureManager);
}
}
{
AllocateMaskData();
mMaskingData->mAlphaMaskUrl = alphaUrl;
+ if(mMaskingData->mAlphaMaskUrl.IsValid())
+ {
+ if(DALI_LIKELY(Dali::Adaptor::IsAvailable()))
+ {
+ // Increase reference count of External Resources :
+ // EncodedImageBuffer or ExternalTextures.
+ // Reference count will be decreased at destructor of the visual.
+ mMaskingData->mAlphaMaskUrl.IncreaseExternalResourceReference(mFactoryCache.GetTextureManager());
+ }
+ if(mMaskingData->mAlphaMaskUrl.GetProtocolType() == VisualUrl::TEXTURE)
+ {
+ mMaskingData->mPreappliedMasking = false;
+ }
+ }
}
break;
}
if(value.Get(maskingType))
{
AllocateMaskData();
+
+ bool externalTextureUsed = false;
if(mImageUrl.IsValid() && mImageUrl.GetProtocolType() == VisualUrl::TEXTURE)
+ {
+ externalTextureUsed = true;
+ }
+ else if(mMaskingData->mAlphaMaskUrl.IsValid() && mMaskingData->mAlphaMaskUrl.GetProtocolType() == VisualUrl::TEXTURE)
+ {
+ externalTextureUsed = true;
+ }
+
+ if(externalTextureUsed)
{
// For external textures, only gpu masking is available.
// Therefore, MASKING_TYPE is set to MASKING_ON_RENDERING forcelly.
void ImageVisual::OnInitialize()
{
- // Increase reference count of External Resources :
- // EncodedImageBuffer or ExternalTextures.
- // Reference count will be decreased at destructor of the visual.
- if(mImageUrl.IsValid() && (mImageUrl.IsBufferResource() || mImageUrl.GetProtocolType() == VisualUrl::TEXTURE))
+ if(DALI_LIKELY(Dali::Adaptor::IsAvailable()))
{
- TextureManager& textureManager = mFactoryCache.GetTextureManager();
- textureManager.UseExternalResource(mImageUrl);
+ // Increase reference count of External Resources :
+ // EncodedImageBuffer or ExternalTextures.
+ // Reference count will be decreased at destructor of the visual.
+ mImageUrl.IncreaseExternalResourceReference(mFactoryCache.GetTextureManager());
}
// Generate geometry and shader. Note that we should check AddOn when generate geometry, due to LoadPolicy::IMMEDIATE case
}
}
- DALI_LOG_INFO(gLogFilter, Debug::Concise, "VisualFactory::CreateVisual( VisualType:%s %s%s)\n", Scripting::GetEnumerationName<Toolkit::DevelVisual::Type>(visualType, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT), (visualType == Toolkit::DevelVisual::IMAGE) ? "url:" : "", (visualType == Toolkit::DevelVisual::IMAGE) ? (([&]() {
- // Return URL if present in PropertyMap else return "not found message"
- Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
- return (imageURLValue) ? imageURLValue->Get<std::string>().c_str() : "url not found in PropertyMap";
- })())
- : "");
+ DALI_LOG_INFO(gLogFilter, Debug::Concise, "VisualFactory::CreateVisual( VisualType:%s %s%s)\n", Scripting::GetEnumerationName<Toolkit::DevelVisual::Type>(visualType, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT), (visualType == Toolkit::DevelVisual::IMAGE) ? "url:" : "", ((visualType == Toolkit::DevelVisual::IMAGE) ? (([&]() {
+ // Return URL if present in PropertyMap else return "not found message"
+ Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
+ return (imageURLValue) ? imageURLValue->Get<std::string>() : std::string("url not found in PropertyMap");
+ })())
+ : std::string(""))
+ .c_str());
if(!visualPtr)
{
#include <dali/devel-api/common/hash.h>
#include <cstring> // for toupper()
+// INTERNAL HEADERS
+#include <dali-toolkit/internal/texture-manager/texture-manager-impl.h>
+
namespace Dali
{
namespace Toolkit
return GetLocationWithoutExtension(mUrl);
}
+bool VisualUrl::GetLocationAsInteger(int32_t& integerLocation) const
+{
+ const auto& location = GetLocationWithoutExtension(mUrl);
+ if(!location.empty())
+ {
+ try
+ {
+ integerLocation = std::stoi(location);
+ return true;
+ }
+ catch(...)
+ {
+ return false;
+ }
+ }
+ return false;
+}
+
+void VisualUrl::IncreaseExternalResourceReference(TextureManager& textureManager) const
+{
+ if(IsValid() && (mLocation == VisualUrl::TEXTURE || mLocation == VisualUrl::BUFFER))
+ {
+ textureManager.UseExternalResource(*this);
+ }
+}
+
+void VisualUrl::DecreaseExternalResourceReference(TextureManager& textureManager) const
+{
+ if(IsValid() && (mLocation == VisualUrl::TEXTURE || mLocation == VisualUrl::BUFFER))
+ {
+ switch(mLocation)
+ {
+ case VisualUrl::TEXTURE:
+ {
+ textureManager.RemoveExternalTexture(*this);
+ break;
+ }
+ case VisualUrl::BUFFER:
+ {
+ textureManager.RemoveEncodedImageBuffer(*this);
+ break;
+ }
+ }
+ }
+}
+
std::string VisualUrl::CreateTextureUrl(const std::string& location)
{
return "dali://" + location;
std::string VisualUrl::GetLocationWithoutExtension(const std::string& url)
{
- const auto location = url.find("://");
- if(std::string::npos != location)
- {
- const auto extension = url.find_last_of("."); // Find last position of '.' keyword.
- const auto locationLength = extension != std::string::npos ? extension - (location + 3u) : std::string::npos;
- return url.substr(location + 3u, locationLength); // 3 characters forwards from the start of ://, and end of last '.' keyword.
- }
- return url;
+ const auto location = url.find("://");
+ const auto extension = url.find_last_of("."); // Find last position of '.' keyword.
+
+ const auto locationOffset = location != std::string::npos ? location + 3u : 0u;
+ const auto locationLength = extension != std::string::npos ? extension - (locationOffset) : std::string::npos;
+
+ return url.substr(locationOffset, locationLength);
}
} // namespace Internal
{
namespace Internal
{
+class TextureManager;
+
class VisualUrl
{
public:
*/
std::string GetLocationWithoutExtension() const;
+ /**
+ * @brief Convert the location part of the url as single integer
+ *
+ * @param[out] integerLocation The result of conversion.
+ * @return True if the location can be converted to integer. Otherwise false.
+ */
+ bool GetLocationAsInteger(int32_t& integerLocation) const;
+
+ /**
+ * @brief Increase the external resource reference count.
+ * Only have effort if ProtocolType is TEXTURE or BUFFER.
+ *
+ * @post DecreaseExternalResourceReference Should be called when the resource is no longer needed.
+ *
+ * @param[in] textureManager The texture manager who owns the external texture.
+ */
+ void IncreaseExternalResourceReference(TextureManager& textureManager) const;
+
+ /**
+ * @brief Decrease the external resource reference count.
+ * Only have effort if ProtocolType is TEXTURE or BUFFER.
+ *
+ * @pre IncreaseExternalResourceReference Should be called before calling this function.
+ *
+ * @param[in] textureManager The texture manager who owns the external texture.
+ */
+ void DecreaseExternalResourceReference(TextureManager& textureManager) const;
+
/**
* Helper to create a URL of type TEXTURE
* @param location the location of the texture