/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
mObserverCalled = true;
}
+ virtual void LoadComplete( bool loadSuccess, Devel::PixelBuffer pixelBuffer, const VisualUrl& url, bool preMultiplied ) override
+ {
+ mLoaded = loadSuccess;
+ mObserverCalled = true;
+ }
+
bool mLoaded;
bool mObserverCalled;
};
/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
tet_infoline( "UtcDaliVisualSetTransform: NPatch visual" );
VisualFactory factory = VisualFactory::Get();
- Image image = ResourceImage::New(TEST_NPATCH_FILE_NAME, ImageDimensions(100, 200));
- Visual::Base visual = factory.CreateVisual(image);
+ Property::Map propertyMap;
+ propertyMap[Toolkit::Visual::Property::TYPE] = Toolkit::Visual::IMAGE;
+ propertyMap[Toolkit::ImageVisual::Property::URL] = TEST_NPATCH_FILE_NAME;
+ propertyMap[Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING] = true;
+ Visual::Base visual = factory.CreateVisual(propertyMap);
TestTransform( application, visual );
TestMixColor( visual, Visual::Property::MIX_COLOR, Color::WHITE );
properties[Visual::Property::MIX_COLOR] = Color::BLUE;
properties[Visual::Property::SHADER]=shader;
properties[ImageVisual::Property::URL] = TEST_NPATCH_FILE_NAME;
+ properties[ImageVisual::Property::SYNCHRONOUS_LOADING] = true;
Visual::Base visual = factory.CreateVisual( properties );
TestMixColor( visual, Visual::Property::MIX_COLOR, Color::BLUE );
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/devel-api/adaptor-framework/image-loading.h>
#include "dummy-control.h"
+#include <dali/integration-api/debug.h>
+
using namespace Dali;
using namespace Dali::Toolkit;
DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
}
+void TestVisualAsynchronousRender( ToolkitTestApplication& application,
+ DummyControl& actor,
+ Visual::Base& visual )
+{
+ DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+ dummyImpl.RegisterVisual( DummyControl::Property::TEST_VISUAL, visual );
+
+ actor.SetSize( 200.f, 200.f );
+ DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
+
+ Stage::GetCurrent().Add( actor );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
+}
+
} // namespace
END_TEST;
}
-int UtcDaliVisualFactoryGetNPatchVisual1(void)
+int UtcDaliVisualFactoryGetNPatchVisualSynchronousLoad1(void)
{
ToolkitTestApplication application;
- tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual1: Request 9-patch visual with a Property::Map" );
+ tet_infoline( "UtcDaliVisualFactoryGetNPatchVisualSynchronousLoad1: Request 9-patch visual with a Property::Map" );
VisualFactory factory = VisualFactory::Get();
DALI_TEST_CHECK( factory );
Property::Map propertyMap;
propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
propertyMap.Insert( ImageVisual::Property::URL, TEST_9_PATCH_FILE_NAME );
+ propertyMap.Insert( ImageVisual::Property::SYNCHRONOUS_LOADING, true );
{
tet_infoline( "whole grid" );
Visual::Base visual = factory.CreateVisual( propertyMap );
END_TEST;
}
-int UtcDaliVisualFactoryGetNPatchVisual2(void)
+int UtcDaliVisualFactoryGetNPatchVisualSynchronousLoad2(void)
{
ToolkitTestApplication application;
- tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual1: Request 9-patch visual with a Property::Map including border" );
+ tet_infoline( "UtcDaliVisualFactoryGetNPatchVisualSynchronousLoad2: Request 9-patch visual with a Property::Map including border" );
VisualFactory factory = VisualFactory::Get();
DALI_TEST_CHECK( factory );
propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
propertyMap.Insert( ImageVisual::Property::URL, gImage_34_RGBA );
propertyMap.Insert( ImageVisual::Property::BORDER, Rect< int >( 2, 2, 2, 2 ) );
+ propertyMap.Insert( ImageVisual::Property::SYNCHRONOUS_LOADING, true );
{
tet_infoline( "whole grid" );
Visual::Base visual = factory.CreateVisual( propertyMap );
propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
propertyMap.Insert( ImageVisual::Property::URL, gImage_34_RGBA );
propertyMap.Insert( ImageVisual::Property::BORDER, Rect< int >( 1, 1, 1, 1 ) );
+ propertyMap.Insert( ImageVisual::Property::SYNCHRONOUS_LOADING, true );
+ {
+ tet_infoline( "whole grid" );
+ Visual::Base visual = factory.CreateVisual( propertyMap );
+ DALI_TEST_CHECK( visual );
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ DummyControl actor = DummyControl::New(true);
+ TestVisualRender( application, actor, visual );
+
+ DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+ Vector2 naturalSize( 0.0f, 0.0f );
+ visual.GetNaturalSize( naturalSize );
+ DALI_TEST_EQUALS( naturalSize, Vector2( imageSize.GetWidth(), imageSize.GetHeight() ), TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int UtcDaliVisualFactoryGetNPatchVisual1(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual1: Request 9-patch visual with a Property::Map" );
+
+ VisualFactory factory = VisualFactory::Get();
+ DALI_TEST_CHECK( factory );
+
+ // Get actual size of test image
+ ImageDimensions imageSize = Dali::GetClosestImageSize( TEST_9_PATCH_FILE_NAME );
+
+ Property::Map propertyMap;
+ propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
+ propertyMap.Insert( ImageVisual::Property::URL, TEST_9_PATCH_FILE_NAME );
+ propertyMap.Insert( ImageVisual::Property::SYNCHRONOUS_LOADING, false );
+ {
+ tet_infoline( "whole grid" );
+ Visual::Base visual = factory.CreateVisual( propertyMap );
+ DALI_TEST_CHECK( visual );
+
+ Vector2 naturalSize( 0.0f, 0.0f );
+ visual.GetNaturalSize( naturalSize );
+ DALI_TEST_EQUALS( naturalSize, Vector2( imageSize.GetWidth(), imageSize.GetHeight() ), TEST_LOCATION );
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ DummyControl actor = DummyControl::New(true);
+ TestVisualAsynchronousRender( application, actor, visual );
+
+ DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+ visual.GetNaturalSize( naturalSize );
+ DALI_TEST_EQUALS( naturalSize, Vector2( imageSize.GetWidth() - 2.0f, imageSize.GetHeight() - 2.0f ), TEST_LOCATION );
+ }
+
+ propertyMap.Insert( ImageVisual::Property::BORDER_ONLY, true );
+ {
+ tet_infoline( "border only" );
+ Visual::Base visual = factory.CreateVisual( propertyMap );
+ DALI_TEST_CHECK( visual );
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ DummyControl actor = DummyControl::New(true);
+ TestVisualRender( application, actor, visual );
+
+ DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+ Vector2 naturalSize( 0.0f, 0.0f );
+ visual.GetNaturalSize( naturalSize );
+ DALI_TEST_EQUALS( naturalSize, Vector2( imageSize.GetWidth() - 2.0f, imageSize.GetHeight() - 2.0f ), TEST_LOCATION );
+ }
+
+ END_TEST;
+}
+
+int UtcDaliVisualFactoryGetNPatchVisual2(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline( "UtcDaliVisualFactoryGetNPatchVisual2: Request 9-patch visual with a Property::Map including border" );
+
+ VisualFactory factory = VisualFactory::Get();
+ DALI_TEST_CHECK( factory );
+
+ // Get actual size of test image
+ ImageDimensions imageSize = Dali::GetClosestImageSize( gImage_34_RGBA );
+
+ Property::Map propertyMap;
+ propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
+ propertyMap.Insert( ImageVisual::Property::URL, gImage_34_RGBA );
+ propertyMap.Insert( ImageVisual::Property::BORDER, Rect< int >( 2, 2, 2, 2 ) );
+ {
+ tet_infoline( "whole grid" );
+ Visual::Base visual = factory.CreateVisual( propertyMap );
+ DALI_TEST_CHECK( visual );
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ DummyControl actor = DummyControl::New(true);
+ TestVisualAsynchronousRender( application, actor, visual );
+
+ DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+ Vector2 naturalSize( 0.0f, 0.0f );
+ visual.GetNaturalSize( naturalSize );
+ DALI_TEST_EQUALS( naturalSize, Vector2( imageSize.GetWidth(), imageSize.GetHeight() ), TEST_LOCATION );
+ }
+
+ propertyMap.Insert( ImageVisual::Property::BORDER_ONLY, true );
+ {
+ tet_infoline( "border only" );
+ Visual::Base visual = factory.CreateVisual( propertyMap );
+ DALI_TEST_CHECK( visual );
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+ TraceCallStack& textureTrace = gl.GetTextureTrace();
+ textureTrace.Enable(true);
+
+ DummyControl actor = DummyControl::New(true);
+ TestVisualRender( application, actor, visual );
+
+ DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+ Vector2 naturalSize( 0.0f, 0.0f );
+ visual.GetNaturalSize( naturalSize );
+ DALI_TEST_EQUALS( naturalSize, Vector2( imageSize.GetWidth(), imageSize.GetHeight() ), TEST_LOCATION );
+ }
+
+ propertyMap.Clear();
+ propertyMap.Insert( Toolkit::Visual::Property::TYPE, Visual::N_PATCH );
+ propertyMap.Insert( ImageVisual::Property::URL, gImage_34_RGBA );
+ propertyMap.Insert( ImageVisual::Property::BORDER, Rect< int >( 1, 1, 1, 1 ) );
{
tet_infoline( "whole grid" );
Visual::Base visual = factory.CreateVisual( propertyMap );
textureTrace.Enable(true);
DummyControl actor = DummyControl::New(true);
- TestVisualRender( application, actor, visual );
+ TestVisualAsynchronousRender( application, actor, visual );
DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
TestGlAbstraction& gl = application.GetGlAbstraction();
TraceCallStack& textureTrace = gl.GetTextureTrace();
textureTrace.Enable(true);
-
DummyControl actor = DummyControl::New(true);
- TestVisualRender( application, actor, visual );
+ TestVisualAsynchronousRender( application, actor, visual );
DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
textureTrace.Enable(true);
DummyControl actor = DummyControl::New(true);
- TestVisualRender( application, actor, visual );
+ TestVisualAsynchronousRender( application, actor, visual );
DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
textureTrace.Enable(true);
DummyControl actor = DummyControl::New(true);
- TestVisualRender( application, actor, visual );
+ TestVisualAsynchronousRender( application, actor, visual );
DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
textureTrace.Enable(true);
DummyControl actor = DummyControl::New(true);
- TestVisualRender( application, actor, visual );
+ TestVisualAsynchronousRender( application, actor, visual );
DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
dummy.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
dummy.SetParentOrigin(ParentOrigin::CENTER);
Stage::GetCurrent().Add(dummy);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 2 ), true, TEST_LOCATION );
+
application.SendNotification();
application.Render();
textureTrace.Enable(true);
DummyControl actor = DummyControl::New(true);
- TestVisualRender( application, actor, visual );
+ TestVisualAsynchronousRender( application, actor, visual );
DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
drawTrace.Enable(true);
DummyControl actor = DummyControl::New(true);
- TestVisualRender( application, actor, visual );
+ TestVisualAsynchronousRender( application, actor, visual );
DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
}
}
+void FixedImageCache::LoadComplete(
+ bool loadSuccess,
+ Devel::PixelBuffer pixelBuffer,
+ const VisualUrl& url,
+ bool preMultiplied )
+{
+ // LoadComplete is called if this TextureUploadObserver requested to load
+ // an image that will be returned as a type of PixelBuffer by using a method
+ // TextureManager::LoadPixelBuffer.
+}
+
} //namespace Internal
} //namespace Toolkit
-} //namespace Dali
+} //namespace Dali
\ No newline at end of file
#define DALI_TOOLKIT_INTERNAL_FIXED_IMAGE_CACHE_H
/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
TextureSet textureSet,
bool useAtlasing,
const Vector4& atlasRect,
- bool premultiplied) override;
+ bool premultiplied ) override;
+
+ void LoadComplete(
+ bool loadSuccess,
+ Devel::PixelBuffer pixelBuffer,
+ const VisualUrl& url,
+ bool preMultiplied ) override;
private:
std::vector<UrlStore>& mImageUrls;
/*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
LOG_CACHE;
}
+void RollingImageCache::LoadComplete(
+ bool loadSuccess,
+ Devel::PixelBuffer pixelBuffer,
+ const VisualUrl& url,
+ bool preMultiplied )
+{
+ // LoadComplete is called if this TextureUploadObserver requested to load
+ // an image that will be returned as a type of PixelBuffer by using a method
+ // TextureManager::LoadPixelBuffer.
+}
+
} //namespace Internal
} //namespace Toolkit
} //namespace Dali
#define DALI_TOOLKIT_INTERNAL_ROLLING_IMAGE_CACHE_H
/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
const Vector4& atlasRect,
bool preMultiplied ) override;
+ void LoadComplete(
+ bool loadSuccess,
+ Devel::PixelBuffer pixelBuffer,
+ const VisualUrl& url,
+ bool preMultiplied ) override;
+
private:
/**
* Secondary class to hold readiness and index into url
#define DALI_TOOLKIT_INTERNAL_IMAGE_VISUAL_H
/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
private:
/**
+ * @copydoc TextureUploadObserver::LoadComplete
+ *
+ * To avoid rendering garbage pixels, renderer should be added to actor after the resources are ready.
+ * This callback is the place to add the renderer as it would be called once the PixelBuffer loading is finished.
+ */
+ void LoadComplete( bool loadSuccess, Devel::PixelBuffer pixelBuffer, const VisualUrl& url, bool preMultiplied ) override {}
+
+ /**
* Allocate the mask data when a masking property is defined in the property map
*/
void AllocateMaskData();
/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// EXTERNAL HEADER
#include <dali/devel-api/adaptor-framework/image-loading.h>
-#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
#include <dali/devel-api/common/hash.h>
#include <dali/integration-api/debug.h>
}
}
+void SetLoadedNPatchData( NPatchLoader::Data* data, Devel::PixelBuffer& pixelBuffer )
+{
+ if( data->border == Rect< int >( 0, 0, 0, 0 ) )
+ {
+ NPatchBuffer::ParseBorders( pixelBuffer, data );
+
+ // Crop the image
+ pixelBuffer.Crop( 1, 1, pixelBuffer.GetWidth() - 2, pixelBuffer.GetHeight() - 2 );
+ }
+ else
+ {
+ data->stretchPixelsX.PushBack( Uint16Pair( data->border.left, ( (pixelBuffer.GetWidth() >= static_cast< unsigned int >( data->border.right )) ? pixelBuffer.GetWidth() - data->border.right : 0 ) ) );
+ data->stretchPixelsY.PushBack( Uint16Pair( data->border.top, ( (pixelBuffer.GetHeight() >= static_cast< unsigned int >( data->border.bottom )) ? pixelBuffer.GetHeight() - data->border.bottom : 0 ) ) );
+ }
+
+ data->croppedWidth = pixelBuffer.GetWidth();
+ data->croppedHeight = pixelBuffer.GetHeight();
+
+ PixelData pixels = Devel::PixelBuffer::Convert( pixelBuffer ); // takes ownership of buffer
+
+ Texture texture = Texture::New( TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight() );
+ texture.Upload( pixels );
+
+ data->textureSet = TextureSet::New();
+ data->textureSet.SetTexture( 0u, texture );
+
+ data->loadCompleted = true;
+}
+
} // namespace NPatchBuffer
NPatchLoader::NPatchLoader()
{
}
-std::size_t NPatchLoader::Load( const std::string& url, const Rect< int >& border, bool& preMultiplyOnLoad )
+std::size_t NPatchLoader::Load( TextureManager& textureManager, TextureUploadObserver* textureObserver, const std::string& url, const Rect< int >& border, bool& preMultiplyOnLoad, bool synchronousLoading )
{
std::size_t hash = CalculateHash( url );
OwnerContainer< Data* >::SizeType index = UNINITIALIZED_ID;
const OwnerContainer< Data* >::SizeType count = mCache.Count();
int cachedIndex = -1;
+ Data* data;
for( ; index < count; ++index )
{
// Use cached data
if( mCache[ index ]->border == border )
{
- return index+1u; // valid indices are from 1 onwards
+ if( mCache[ index ]->loadCompleted )
+ {
+ return index + 1u; // valid indices are from 1 onwards
+ }
+ data = mCache[ index ];
+ cachedIndex = index + 1u; // valid indices are from 1 onwards
+ break;
}
else
{
- cachedIndex = index;
- }
- }
- }
- }
+ if( mCache[ index ]->loadCompleted )
+ {
+ // Same url but border is different - use the existing texture
+ Data* data = new Data();
+ data->hash = hash;
+ data->url = url;
+ data->croppedWidth = mCache[ index ]->croppedWidth;
+ data->croppedHeight = mCache[ index ]->croppedHeight;
- if( cachedIndex != -1 )
- {
- // Same url but border is different - use the existing texture
- Data* data = new Data();
- data->hash = hash;
- data->url = url;
- data->croppedWidth = mCache[ cachedIndex ]->croppedWidth;
- data->croppedHeight = mCache[ cachedIndex ]->croppedHeight;
+ data->textureSet = mCache[ index ]->textureSet;
- data->textureSet = mCache[ cachedIndex ]->textureSet;
+ StretchRanges stretchRangesX;
+ stretchRangesX.PushBack( Uint16Pair( border.left, ( (data->croppedWidth >= static_cast< unsigned int >( border.right )) ? data->croppedWidth - border.right : 0 ) ) );
- StretchRanges stretchRangesX;
- stretchRangesX.PushBack( Uint16Pair( border.left, ( (data->croppedWidth >= static_cast< unsigned int >( border.right )) ? data->croppedWidth - border.right : 0 ) ) );
+ StretchRanges stretchRangesY;
+ stretchRangesY.PushBack( Uint16Pair( border.top, ( (data->croppedHeight >= static_cast< unsigned int >( border.bottom )) ? data->croppedHeight - border.bottom : 0 ) ) );
- StretchRanges stretchRangesY;
- stretchRangesY.PushBack( Uint16Pair( border.top, ( (data->croppedHeight >= static_cast< unsigned int >( border.bottom )) ? data->croppedHeight - border.bottom : 0 ) ) );
+ data->stretchPixelsX = stretchRangesX;
+ data->stretchPixelsY = stretchRangesY;
+ data->border = border;
- data->stretchPixelsX = stretchRangesX;
- data->stretchPixelsY = stretchRangesY;
- data->border = border;
+ data->loadCompleted = mCache[ index ]->loadCompleted;
- mCache.PushBack( data );
+ mCache.PushBack( data );
- return mCache.Count(); // valid ids start from 1u
+ return mCache.Count(); // valid ids start from 1u
+ }
+ }
+ }
+ }
}
- // got to the end so no match, decode N patch and append new item to cache
- Devel::PixelBuffer pixelBuffer = Dali::LoadImageFromFile( url, ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true );
- if( pixelBuffer )
+ if( cachedIndex == -1 )
{
- Data* data = new Data();
+ data = new Data();
+ data->loadCompleted = false;
data->hash = hash;
data->url = url;
+ data->border = border;
- if( border == Rect< int >( 0, 0, 0, 0 ) )
- {
- NPatchBuffer::ParseBorders( pixelBuffer, data );
-
- data->border = Rect< int >( 0, 0, 0, 0 );
-
- // Crop the image
- pixelBuffer.Crop( 1, 1, pixelBuffer.GetWidth() - 2, pixelBuffer.GetHeight() - 2 );
- }
- else
- {
- data->stretchPixelsX.PushBack( Uint16Pair( border.left, ( (pixelBuffer.GetWidth() >= static_cast< unsigned int >( border.right )) ? pixelBuffer.GetWidth() - border.right : 0 ) ) );
- data->stretchPixelsY.PushBack( Uint16Pair( border.top, ( (pixelBuffer.GetHeight() >= static_cast< unsigned int >( border.bottom )) ? pixelBuffer.GetHeight() - border.bottom : 0 ) ) );
- data->border = border;
- }
-
- data->croppedWidth = pixelBuffer.GetWidth();
- data->croppedHeight = pixelBuffer.GetHeight();
+ mCache.PushBack( data );
- if( preMultiplyOnLoad && Pixel::HasAlpha( pixelBuffer.GetPixelFormat() ) )
- {
- pixelBuffer.MultiplyColorByAlpha();
- }
- else
- {
- preMultiplyOnLoad = false;
- }
+ cachedIndex = mCache.Count();
+ }
- PixelData pixels = Devel::PixelBuffer::Convert( pixelBuffer ); // takes ownership of buffer
+ auto preMultiplyOnLoading = preMultiplyOnLoad ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
+ : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+ Devel::PixelBuffer pixelBuffer = textureManager.LoadPixelBuffer( url, Dali::ImageDimensions(), FittingMode::DEFAULT,
+ SamplingMode::BOX_THEN_LINEAR, synchronousLoading,
+ textureObserver, true, preMultiplyOnLoading );
- Texture texture = Texture::New( TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight() );
- texture.Upload( pixels );
+ if( pixelBuffer )
+ {
+ NPatchBuffer::SetLoadedNPatchData( data, pixelBuffer );
+ preMultiplyOnLoad = ( preMultiplyOnLoading == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD ) ? true : false;
+ }
- data->textureSet = TextureSet::New();
- data->textureSet.SetTexture( 0u, texture );
+ return cachedIndex;
+}
- mCache.PushBack( data );
+void NPatchLoader::SetNPatchData( std::size_t id, Devel::PixelBuffer& pixelBuffer )
+{
+ Data* data;
+ data = mCache[ id - 1u ];
- return mCache.Count(); // valid ids start from 1u
+ if( !data->loadCompleted )
+ {
+ NPatchBuffer::SetLoadedNPatchData( data, pixelBuffer );
}
-
- return 0u;
}
bool NPatchLoader::GetNPatchData( std::size_t id, const Data*& data )
#define DALI_TOOLKIT_NPATCH_LOADER_H
/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/public-api/rendering/texture-set.h>
#include <dali/public-api/math/uint-16-pair.h>
#include <dali/devel-api/common/owner-container.h>
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
+
+// INTERNAL HEADERS
+#include <dali-toolkit/internal/visuals/texture-manager-impl.h>
namespace Dali
{
struct Data
{
+ Data()
+ : loadCompleted( false )
+ {}
+
std::string url; ///< Url of the N-Patch
TextureSet textureSet; ///< Texture containing the cropped image
StretchRanges stretchPixelsX; ///< X stretch pixels
uint32_t croppedWidth; ///< Width of the cropped middle part of N-patch
uint32_t croppedHeight; ///< Height of the cropped middle part of N-patch
Rect< int > border; ///< The size of the border
+ bool loadCompleted; ///< True if the data loading is completed
};
public:
/**
* @brief Retrieve a texture matching the n-patch url.
*
+ * @param [in] textureManager that will be used to loading image
+ * @param [in] textureObserver The NPatchVisual that requested loading.
* @param [in] url to retrieve
* @param [in] border The border size of the image
* @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
+ * @param [in] synchronousLoading True if the image will be loaded in synchronous time.
* @return id of the texture.
*/
- std::size_t Load( const std::string& url, const Rect< int >& border, bool& preMultiplyOnLoad );
+ std::size_t Load( TextureManager& textureManager, TextureUploadObserver* textureObserver, const std::string& url, const Rect< int >& border, bool& preMultiplyOnLoad, bool synchronousLoading );
+
+ /**
+ * @brief Set loaded PixelBuffer and its information
+ *
+ * @param [in] id cache data id
+ * @param [in] pixelBuffer of loaded image
+ */
+ void SetNPatchData( std::size_t id, Devel::PixelBuffer& pixelBuffer );
/**
* @brief Retrieve N patch data matching to an id
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
const char * const BORDER( "border" );
const char * const AUXILIARY_IMAGE_NAME( "auxiliaryImage" );
const char * const AUXILIARY_IMAGE_ALPHA_NAME( "auxiliaryImageAlpha" );
+const char * const SYNCHRONOUS_LOADING( "synchronousLoading" );
const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
attribute mediump vec2 aPosition;\n
void NPatchVisual::LoadImages()
{
+ TextureManager& textureManager = mFactoryCache.GetTextureManager();
+ bool synchronousLoading = mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
+
if( NPatchLoader::UNINITIALIZED_ID == mId && mImageUrl.IsLocalResource() )
{
bool preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader ? true : false;
+ mId = mLoader.Load( textureManager, this, mImageUrl.GetUrl(), mBorder, preMultiplyOnLoad, synchronousLoading );
- mId = mLoader.Load( mImageUrl.GetUrl(), mBorder, preMultiplyOnLoad );
-
- EnablePreMultipliedAlpha( preMultiplyOnLoad );
+ const NPatchLoader::Data* data;
+ if( mLoader.GetNPatchData( mId, data ) && data->loadCompleted )
+ {
+ EnablePreMultipliedAlpha( preMultiplyOnLoad );
+ }
}
- if( ! mAuxiliaryPixelBuffer && mAuxiliaryUrl.IsValid() && mAuxiliaryUrl.IsLocalResource() )
+ if( !mAuxiliaryPixelBuffer && mAuxiliaryUrl.IsValid() && mAuxiliaryUrl.IsLocalResource() )
{
- // Load the auxiliary image synchronously
- mAuxiliaryPixelBuffer = Dali::LoadImageFromFile( mAuxiliaryUrl.GetUrl(), ImageDimensions(),
- FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, true );
+ // Load the auxiliary image
+ auto preMultiplyOnLoading = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+ mAuxiliaryPixelBuffer = textureManager.LoadPixelBuffer( mAuxiliaryUrl, Dali::ImageDimensions(), FittingMode::DEFAULT,
+ SamplingMode::BOX_THEN_LINEAR, synchronousLoading,
+ this, true, preMultiplyOnLoading );
}
}
naturalSize.y = 0u;
// load now if not already loaded
- LoadImages();
-
const NPatchLoader::Data* data;
- if( mLoader.GetNPatchData( mId, data ) )
+ if( mLoader.GetNPatchData( mId, data ) && data->loadCompleted )
{
naturalSize.x = data->croppedWidth;
naturalSize.y = data->croppedHeight;
}
+ else
+ {
+ if( mImageUrl.IsValid() )
+ {
+ ImageDimensions dimensions = Dali::GetOriginalImageSize( mImageUrl.GetUrl() );
+ if( dimensions != ImageDimensions( 0, 0 ) )
+ {
+ naturalSize.x = dimensions.GetWidth();
+ naturalSize.y = dimensions.GetHeight();
+ }
+ }
+ }
if( mAuxiliaryPixelBuffer )
{
{
auxImageAlpha->Get( mAuxiliaryImageAlpha );
}
+
+ Property::Value* synchronousLoading = propertyMap.Find( Toolkit::ImageVisual::Property::SYNCHRONOUS_LOADING, SYNCHRONOUS_LOADING );
+ if( synchronousLoading )
+ {
+ bool sync = false;
+ synchronousLoading->Get( sync );
+ if( sync )
+ {
+ mImpl->mFlags |= Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
+ }
+ else
+ {
+ mImpl->mFlags &= ~Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
+ }
+ }
}
void NPatchVisual::DoSetOnStage( Actor& actor )
// load when first go on stage
LoadImages();
- Geometry geometry = CreateGeometry();
- Shader shader = CreateShader();
- mImpl->mRenderer = Renderer::New( geometry, shader );
+ const NPatchLoader::Data* data;
+ if( mLoader.GetNPatchData( mId, data ) )
+ {
+ Geometry geometry = CreateGeometry();
+ Shader shader = CreateShader();
- ApplyTextureAndUniforms();
+ mImpl->mRenderer = Renderer::New( geometry, shader );
- actor.AddRenderer( mImpl->mRenderer );
+ mPlacementActor = actor;
+ if( data->loadCompleted )
+ {
+ ApplyTextureAndUniforms();
+ actor.AddRenderer( mImpl->mRenderer );
+ mPlacementActor.Reset();
- // npatch loaded and ready to display
- ResourceReady( Toolkit::Visual::ResourceStatus::READY );
+ // npatch loaded and ready to display
+ ResourceReady( Toolkit::Visual::ResourceStatus::READY );
+ }
+ }
}
void NPatchVisual::DoSetOffStage( Actor& actor )
{
actor.RemoveRenderer( mImpl->mRenderer );
mImpl->mRenderer.Reset();
+ mPlacementActor.Reset();
}
void NPatchVisual::OnSetTransform()
NPatchVisual::NPatchVisual( VisualFactoryCache& factoryCache )
: Visual::Base( factoryCache, Visual::FittingMode::FILL ),
+ mPlacementActor(),
mLoader( factoryCache.GetNPatchLoader() ),
mImageUrl(),
mAuxiliaryUrl(),
{
Geometry geometry;
const NPatchLoader::Data* data;
- if( mLoader.GetNPatchData( mId, data ) )
+ if( mLoader.GetNPatchData( mId, data ) && data->loadCompleted )
{
if( data->stretchPixelsX.Size() == 1 && data->stretchPixelsY.Size() == 1 )
{
const NPatchLoader::Data* data;
TextureSet textureSet;
- if( mLoader.GetNPatchData( mId, data ) )
+ if( mLoader.GetNPatchData( mId, data ) && data->loadCompleted )
{
textureSet = data->textureSet;
return GenerateGeometry( vertices, indices );
}
+void NPatchVisual::SetResource()
+{
+ const NPatchLoader::Data* data;
+ if( mLoader.GetNPatchData( mId, data ) )
+ {
+ Geometry geometry = CreateGeometry();
+ Shader shader = CreateShader();
+
+ mImpl->mRenderer.SetGeometry( geometry );
+ mImpl->mRenderer.SetShader( shader );
+
+ Actor actor = mPlacementActor.GetHandle();
+ if( actor )
+ {
+ ApplyTextureAndUniforms();
+ actor.AddRenderer( mImpl->mRenderer );
+ mPlacementActor.Reset();
+
+ // npatch loaded and ready to display
+ ResourceReady( Toolkit::Visual::ResourceStatus::READY );
+ }
+ }
+}
+
+void NPatchVisual::LoadComplete( bool loadSuccess, Devel::PixelBuffer pixelBuffer, const VisualUrl& url, bool preMultiplied )
+{
+ if( url.GetUrl() == mAuxiliaryUrl.GetUrl() )
+ {
+ mAuxiliaryPixelBuffer = pixelBuffer;
+ const NPatchLoader::Data* data;
+ if( mLoader.GetNPatchData( mId, data ) && data->loadCompleted )
+ {
+ SetResource();
+ }
+ }
+ else
+ {
+ if( loadSuccess )
+ {
+ mLoader.SetNPatchData( mId, pixelBuffer );
+ EnablePreMultipliedAlpha( preMultiplied );
+ }
+
+ if( mAuxiliaryPixelBuffer || !mAuxiliaryUrl.IsValid() )
+ {
+ SetResource();
+ }
+ }
+}
+
} // namespace Internal
} // namespace Toolkit
#define DALI_TOOLKIT_INTERNAL_N_PATCH_VISUAL_H
/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/public-api/rendering/geometry.h>
#include <dali/public-api/rendering/sampler.h>
#include <dali/public-api/rendering/shader.h>
+#include <dali/public-api/object/weak-handle.h>
// INTERNAL INCLUDES
+#include <dali-toolkit/internal/visuals/texture-upload-observer.h>
#include <dali-toolkit/internal/visuals/visual-base-impl.h>
#include <dali-toolkit/internal/visuals/visual-url.h>
* | auxiliaryImage | STRING |
* | auxiliaryImageAlpha | FLOAT |
*/
-class NPatchVisual: public Visual::Base
+class NPatchVisual: public Visual::Base, public TextureUploadObserver
{
public:
*/
Geometry CreateBorderGeometry( Uint16Pair gridSize );
+ /**
+ * @brief Creates a renderer by using loaded resource.
+ */
+ void SetResource();
+
+private:
+
+ /**
+ * @copydoc TextureUploadObserver::UploadCompleted
+ *
+ * To avoid rendering garbage pixels, renderer should be added to actor after the resources are ready.
+ * This callback is the place to add the renderer as it would be called once the loading is finished.
+ */
+ void UploadComplete( bool loadSuccess, int32_t textureId, TextureSet textureSet, bool useAtlasing, const Vector4& atlasRect, bool preMultiplied ) override {}
+
+ /**
+ * @copydoc TextureUploadObserver::LoadComplete
+ *
+ * To avoid rendering garbage pixels, renderer should be added to actor after the resources are ready.
+ * This callback is the place to add the renderer as it would be called once the loading is finished.
+ */
+ void LoadComplete( bool loadSuccess, Devel::PixelBuffer pixelBuffer, const VisualUrl& url, bool preMultiplied ) override;
+
private:
+ WeakHandle<Actor> mPlacementActor; ///< Weakhandle to contain Actor during texture loading
NPatchLoader& mLoader; ///< reference to N patch loader for fast access
VisualUrl mImageUrl; ///< The url to the N patch to load
VisualUrl mAuxiliaryUrl; ///< An auxiliary image that can be displayed on top of the N-Patch
}
}
+Devel::PixelBuffer TextureManager::LoadPixelBuffer(
+ const VisualUrl& url, Dali::ImageDimensions desiredSize, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode, bool synchronousLoading, TextureUploadObserver* textureObserver, bool orientationCorrection, TextureManager::MultiplyOnLoad& preMultiplyOnLoad )
+{
+ Devel::PixelBuffer pixelBuffer;
+ if( synchronousLoading )
+ {
+ if( url.IsValid() )
+ {
+ pixelBuffer = LoadImageFromFile( url.GetUrl(), desiredSize, fittingMode, samplingMode,
+ orientationCorrection );
+ if( pixelBuffer && preMultiplyOnLoad == TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD )
+ {
+ PreMultiply( pixelBuffer, preMultiplyOnLoad );
+ }
+ }
+ }
+ else
+ {
+ RequestLoadInternal( url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, TextureManager::NO_ATLAS,
+ false, KEEP_PIXEL_BUFFER, textureObserver, orientationCorrection, TextureManager::ReloadPolicy::FORCED,
+ preMultiplyOnLoad, true );
+ }
+
+ return pixelBuffer;
+}
+
TextureSet TextureManager::LoadTexture(
const VisualUrl& url, Dali::ImageDimensions desiredSize, Dali::FittingMode::Type fittingMode,
Dali::SamplingMode::Type samplingMode, MaskingDataPointer& maskInfo,
{
return RequestLoadInternal( url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, useAtlas,
false, UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy,
- preMultiplyOnLoad );
+ preMultiplyOnLoad, false );
}
TextureManager::TextureId TextureManager::RequestLoad(
{
return RequestLoadInternal( url, maskTextureId, contentScale, desiredSize, fittingMode, samplingMode, useAtlas,
cropToMask, UPLOAD_TO_TEXTURE, observer, orientationCorrection, reloadPolicy,
- preMultiplyOnLoad );
+ preMultiplyOnLoad, false );
}
TextureManager::TextureId TextureManager::RequestMaskLoad( const VisualUrl& maskUrl )
auto preMultiply = TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
return RequestLoadInternal( maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL,
SamplingMode::NO_FILTER, NO_ATLAS, false, KEEP_PIXEL_BUFFER, NULL, true,
- TextureManager::ReloadPolicy::CACHED, preMultiply );
+ TextureManager::ReloadPolicy::CACHED, preMultiply, false );
}
TextureManager::TextureId TextureManager::RequestLoadInternal(
TextureUploadObserver* observer,
bool orientationCorrection,
TextureManager::ReloadPolicy reloadPolicy,
- TextureManager::MultiplyOnLoad& preMultiplyOnLoad)
+ TextureManager::MultiplyOnLoad& preMultiplyOnLoad,
+ bool loadPixelBuffer )
{
// First check if the requested Texture is cached.
const TextureHash textureHash = GenerateHash( url.GetUrl(), desiredSize, fittingMode, samplingMode, useAtlas,
mTextureInfoContainer.push_back( TextureInfo( textureId, maskTextureId, url.GetUrl(),
desiredSize, contentScale, fittingMode, samplingMode,
false, cropToMask, useAtlas, textureHash, orientationCorrection,
- preMultiply ) );
+ preMultiply, loadPixelBuffer ) );
cacheIndex = mTextureInfoContainer.size() - 1u;
DALI_LOG_INFO( gTextureManagerLogFilter, Debug::General, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d\n",
break;
}
case TextureManager::LOAD_FINISHED:
- // Loading has already completed. Do nothing.
+ // Loading has already completed.
+ if( observer && textureInfo.loadPixelBuffer )
+ {
+ LoadOrQueueTexture( textureInfo, observer );
+ }
break;
}
textureInfo.useAtlas, textureInfo.atlasRect,
textureInfo.preMultiplied );
}
+ else if ( textureInfo.loadState == LOAD_FINISHED && textureInfo.loadPixelBuffer )
+ {
+ element.mObserver->LoadComplete( true, textureInfo.pixelBuffer, textureInfo.url, textureInfo.preMultiplied );
+ }
else
{
LoadTexture( textureInfo, element.mObserver );
{
// No atlas support for now
textureInfo.useAtlas = NO_ATLAS;
+ textureInfo.preMultiplied = pixelBuffer.IsAlphaPreMultiplied();
if( textureInfo.storageType == UPLOAD_TO_TEXTURE )
{
textureInfo.pixelBuffer = pixelBuffer; // Store the pixel data
textureInfo.loadState = LOAD_FINISHED;
+ if( textureInfo.loadPixelBuffer )
+ {
+ NotifyObservers( textureInfo, true );
+ }
// Check if there was another texture waiting for this load to complete
// (e.g. if this was an image mask, and its load is on a different thread)
CheckForWaitingTexture( textureInfo );
DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "NotifyObservers() url:%s loadState:%s\n",
textureInfo.url.GetUrl().c_str(), GET_LOAD_STATE_STRING(textureInfo.loadState ) );
- observer->UploadComplete( success, info->textureId, info->textureSet, info->useAtlas, info->atlasRect,
- info->preMultiplied );
+ if( info->loadPixelBuffer )
+ {
+ observer->LoadComplete( success, info->pixelBuffer, info->url, info->preMultiplied );
+ }
+ else
+ {
+ observer->UploadComplete( success, info->textureId, info->textureSet, info->useAtlas, info->atlasRect,
+ info->preMultiplied );
+ }
+
observer->DestructionSignal().Disconnect( this, &TextureManager::ObserverDestroyed );
// Get the textureInfo from the container again as it may have been invalidated.
mQueueLoadFlag = false;
ProcessQueuedTextures();
+
+ if( info->loadPixelBuffer && info->observerList.Count() == 0 )
+ {
+ Remove( info->textureId, nullptr );
+ }
}
TextureManager::TextureId TextureManager::GenerateUniqueTextureId()
#define DALI_TOOLKIT_TEXTURE_MANAGER_IMPL_H
/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// TextureManager Main API:
/**
+ * @brief Requests an image load of the given URL to get PixelBuffer.
+ *
+ * The parameters are used to specify how the image is loaded.
+ * The observer has the LoadComplete method called when the load is ready.
+ *
+ * @param[in] url The URL of the image to load
+ * @param[in] desiredSize The size the image is likely to appear at. This can be set to 0,0 for automatic
+ * @param[in] fittingMode The FittingMode to use
+ * @param[in] samplingMode The SamplingMode to use
+ * @param[in] synchronousLoading true if the URL should be loaded synchronously
+ * @param[in] textureObserver The client object should inherit from this and provide the "UploadCompleted" virtual.
+ * This is called when an image load completes (or fails).
+ * @param[in] orientationCorrection Whether to rotate image to match embedded orientation data
+ * @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
+ *
+ * @return The pixel buffer containing the image, or empty if still loading.
+ */
+
+ Devel::PixelBuffer LoadPixelBuffer( const VisualUrl& url,
+ Dali::ImageDimensions desiredSize,
+ Dali::FittingMode::Type fittingMode,
+ Dali::SamplingMode::Type samplingMode,
+ bool synchronousLoading,
+ TextureUploadObserver* textureObserver,
+ bool orientationCorrection,
+ TextureManager::MultiplyOnLoad& preMultiplyOnLoad );
+
+
+ /**
* @brief Requests an image load of the given URL.
*
* The parameters are used to specify how the image is loaded.
TextureUploadObserver* observer,
bool orientationCorrection,
TextureManager::ReloadPolicy reloadPolicy,
- MultiplyOnLoad& preMultiplyOnLoad );
+ MultiplyOnLoad& preMultiplyOnLoad,
+ bool loadPixelBuffer );
/**
* @brief Get the current state of a texture
UseAtlas useAtlas,
TextureManager::TextureHash hash,
bool orientationCorrection,
- bool preMultiplyOnLoad )
+ bool preMultiplyOnLoad,
+ bool loadPixelBuffer )
: url( url ),
desiredSize( desiredSize ),
useSize( desiredSize ),
cropToMask( cropToMask ),
orientationCorrection( true ),
preMultiplyOnLoad( preMultiplyOnLoad ),
- preMultiplied( false )
+ preMultiplied( false ),
+ loadPixelBuffer( loadPixelBuffer )
{
}
bool orientationCorrection:1; ///< true if the image should be rotated to match exif orientation data
bool preMultiplyOnLoad:1; ///< true if the image's color should be multiplied by it's alpha
bool preMultiplied:1; ///< true if the image's color was multiplied by it's alpha
+ bool loadPixelBuffer:1; ///< true if the image is needed to be returned as PixelBuffer
};
/**
#define DALI_TOOLKIT_INTERNAL_TEXTURE_UPLOAD_OBSERVER_H
/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
*/
-#include <dali-toolkit/public-api/dali-toolkit-common.h>
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/pixel-buffer.h>
#include <dali/public-api/signals/dali-signal.h>
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/dali-toolkit-common.h>
+#include <dali-toolkit/internal/visuals/visual-url.h>
+
namespace Dali
{
const Vector4& atlasRect, bool preMultiplied ) = 0;
/**
+ * The action to be taken once the async load has finished.
+ * This should be overridden by the deriving class.
+ *
+ * @param[in] loadSuccess True if the image load was successful (i.e. the resource is available). If false, then the resource failed to load.
+ * @param[in] pixelBuffer The PixelBuffer of the loaded image.
+ * @param[in] url The url address of the loaded image.
+ * @param[in] preMultiplied True if the image had pre-multiplied alpha applied
+ */
+ virtual void LoadComplete( bool loadSuccess, Devel::PixelBuffer pixelBuffer, const Internal::VisualUrl& url, bool preMultiplied ) = 0;
+
+ /**
* @brief Returns the destruction signal.
* This is emitted when the observer is destroyed.
* This is used by the observer notifier to mark this observer as destroyed (IE. It no longer needs notifying).