Merge "Fix npatch visual auxiliary bug" into devel/master
authorDavid Steele <david.steele@samsung.com>
Thu, 7 Jul 2022 10:14:51 +0000 (10:14 +0000)
committerGerrit Code Review <gerrit@review>
Thu, 7 Jul 2022 10:14:51 +0000 (10:14 +0000)
automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp
dali-toolkit/internal/graphics/shaders/npatch-visual-mask-shader.frag
dali-toolkit/internal/texture-manager/texture-upload-observer.cpp
dali-toolkit/internal/texture-manager/texture-upload-observer.h
dali-toolkit/internal/visuals/npatch-data.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.h

index c399993..ba39604 100644 (file)
@@ -62,6 +62,7 @@ const char* TEST_REMOTE_INVALID_FILE_NAME = "https://www.tizen.org/invalid.png";
 const char* TEST_MASK_IMAGE_FILE_NAME     = TEST_RESOURCE_DIR "/mask.png";
 const char* TEST_ROTATED_IMAGE            = TEST_RESOURCE_DIR "/keyboard-Landscape.jpg";
 const char* TEST_YUV420_IMAGE_FILE_NAME   = TEST_RESOURCE_DIR "/gallery-small-1-yuv420.jpg";
+const char* TEST_N_PATCH_IMAGE_FILE_NAME  = TEST_RESOURCE_DIR "/heartsframe.9.png";
 
 constexpr auto LOAD_IMAGE_YUV_PLANES_ENV = "DALI_LOAD_IMAGE_YUV_PLANES_ENV";
 
@@ -2441,6 +2442,65 @@ int UtcDaliImageVisualReleasePolicy08(void)
   END_TEST;
 }
 
+int UtcDaliImageVisualReleasePolicy09(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliImageVisualReleasePolicy09 Destroyed Policy with N-Patch, Texture should be deleted when visual destroyed");
+
+  Property::Map propertyMapNPatchReleasePolicy;
+  propertyMapNPatchReleasePolicy.Insert(Visual::Property::TYPE, Visual::N_PATCH);
+  propertyMapNPatchReleasePolicy.Insert(ImageVisual::Property::URL, TEST_N_PATCH_IMAGE_FILE_NAME);
+  propertyMapNPatchReleasePolicy.Insert(DevelImageVisual::Property::AUXILIARY_IMAGE, TEST_MASK_IMAGE_FILE_NAME);
+  propertyMapNPatchReleasePolicy.Insert(DevelImageVisual::Property::AUXILIARY_IMAGE_ALPHA, 0.9f);
+  propertyMapNPatchReleasePolicy.Insert(ImageVisual::Property::RELEASE_POLICY, ImageVisual::ReleasePolicy::DESTROYED);
+
+  VisualFactory factory     = VisualFactory::Get();
+  Visual::Base  imageVisual = factory.CreateVisual(propertyMapNPatchReleasePolicy);
+  DALI_TEST_CHECK(imageVisual);
+
+  // Setup debug trace
+  TestGlAbstraction& gl           = application.GetGlAbstraction();
+  TraceCallStack&    textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  tet_infoline("Register visual with control and ensure it has the only handle");
+  DummyControl        actor     = DummyControl::New(true);
+  Impl::DummyControl& dummyImpl = static_cast<Impl::DummyControl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual(DummyControl::Property::TEST_VISUAL, imageVisual);
+  imageVisual.Reset(); // reduce ref count so only the control keeps the visual alive.
+
+  actor.SetProperty(Actor::Property::SIZE, Vector2(200.f, 200.f));
+
+  application.SendNotification();
+  application.Render(0);
+  DALI_TEST_CHECK(actor.GetRendererCount() == 0u);
+  DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), false, TEST_LOCATION);
+
+  application.GetScene().Add(actor);
+
+  // Wait for image to load
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
+
+  application.SendNotification();
+  application.Render(0);
+  // Test renderer and texture created
+  DALI_TEST_EQUALS(actor.GetRendererCount(), 1u, TEST_LOCATION);
+  DALI_TEST_EQUALS(textureTrace.FindMethod("GenTextures"), true, TEST_LOCATION);
+
+  DALI_TEST_CHECK(actor.GetRendererCount() == 1u);
+  tet_infoline("Destroy visual by UnRegistering visual with control, check renderer is destroyed");
+  dummyImpl.UnregisterVisual(DummyControl::Property::TEST_VISUAL);
+  DALI_TEST_CHECK(actor.GetRendererCount() == 0u);
+  application.SendNotification();
+  application.Render();
+
+  // Test texture removed after visual destroyed.
+  tet_infoline("Ensure texture is deleted after visual destroyed");
+  DALI_TEST_EQUALS(textureTrace.CountMethod("DeleteTextures"), 2, TEST_LOCATION);
+
+  END_TEST;
+}
+
 int UtcDaliImageVisualLoadPolicy01(void)
 {
   ToolkitTestApplication application;
index ae3963f..e2081c4 100644 (file)
@@ -1412,7 +1412,7 @@ int UtcDaliNPatchVisualAuxiliaryImage02(void)
   imageView2[ImageView::Property::IMAGE] = NPATCH_TEST;
   application.GetScene().Add(imageView2);
 
-  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(3), true, TEST_LOCATION);
+  DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(2), true, TEST_LOCATION);
 
   application.SendNotification();
   application.Render();
index 6b85462..626a3ff 100644 (file)
@@ -14,10 +14,24 @@ void main()
   // where mask is translucent, less of background should be shown.
   // auxiliaryImageAlpha controls how much of mask is visible
 
-  mediump vec4 color = texture2D( sTexture, vTexCoord );
-  mediump vec4 mask= texture2D( sMask, vMaskTexCoord );
+  mediump vec4 color = texture2D(sTexture, vTexCoord);
+  mediump vec4 mask = texture2D(sMask, vMaskTexCoord);
 
-  mediump vec3 mixedColor = color.rgb * mix( 1.0-mask.a, 1.0, 1.0-auxiliaryImageAlpha)
-                            + mask.rgb*mask.a * auxiliaryImageAlpha;
-  gl_FragColor = vec4(mixedColor,1.0) * uColor * vec4( mixColor, 1.0 );
+  mediump float maskAlpha = mask.a * auxiliaryImageAlpha;
+
+  lowp vec3 preMultipliedMaskRGB = mask.rgb * mix(mask.a, 1.0, preMultipliedAlpha) * auxiliaryImageAlpha;
+  lowp vec3 preMultipliedTextureRGB = color.rgb * mix(color.a, 1.0, preMultipliedAlpha);
+
+  // Manual blend operation with premultiplied colors.
+  // Final alpha = maskAlpha + (1.0 - maskAlpha) * color.a.
+  // (Final rgb * alpha) =  preMultipliedMaskRGB + (1.0 - maskAlpha) * preMultipliedTextureRGB
+  // If preMultipliedAlpha == 1.0, just return vec4(rgb*alpha, alpha)
+  // Else, return vec4((rgb*alpha) / alpha, alpha)
+
+  lowp float finalAlpha = mix(color.a, 1.0, maskAlpha);
+  lowp vec3  finalMultipliedRGB = preMultipliedMaskRGB + (1.0 - maskAlpha) * preMultipliedTextureRGB;
+
+  // TODO : Need to find some way without division
+  lowp vec4 finalColor = vec4(finalMultipliedRGB * mix(1.0 / finalAlpha, 1.0, preMultipliedAlpha), finalAlpha);
+  gl_FragColor = finalColor * uColor * vec4(mixColor, 1.0);
 }
index a4cdc64..1e59c2d 100644 (file)
@@ -37,6 +37,18 @@ TextureUploadObserver::TextureInformation::TextureInformation(ReturnType returnT
 {
 }
 
+TextureUploadObserver::TextureInformation::TextureInformation(ReturnType returnType, int32_t textureId, TextureSet textureSet, const std::string& url, bool preMultiplied)
+: returnType(returnType),
+  textureId(textureId),
+  textureSet(textureSet),
+  useAtlasing(false),
+  atlasRect(Vector4::ZERO),
+  preMultiplied(preMultiplied),
+  pixelBuffer(),
+  url(url)
+{
+}
+
 TextureUploadObserver::TextureInformation::TextureInformation(ReturnType returnType, Devel::PixelBuffer pixelBuffer, const std::string& url, bool preMultiplied)
 : returnType(returnType),
   textureId(Internal::TextureManagerType::INVALID_TEXTURE_ID),
index 5848654..4180d20 100644 (file)
@@ -52,6 +52,7 @@ public:
   struct TextureInformation
   {
     TextureInformation(ReturnType returnType, int32_t textureId, TextureSet textureSet, bool useAtlasing, const Vector4& atlasRect, bool preMultiplied);
+    TextureInformation(ReturnType returnType, int32_t textureId, TextureSet textureSet, const std::string& url, bool preMultiplied);
     TextureInformation(ReturnType returnType, Devel::PixelBuffer pixelBuffer, const std::string& url, bool preMultiplied);
     TextureInformation(ReturnType returnType, int32_t textureId, uint32_t frameCount, uint32_t interval);
 
index cbc038a..dc0a055 100644 (file)
@@ -232,8 +232,7 @@ void NPatchData::NotifyObserver(TextureUploadObserver* observer, const bool& loa
       TextureUploadObserver::ReturnType::TEXTURE,
       static_cast<TextureManager::TextureId>(mId), ///< Note : until end of NPatchLoader::Load, npatch-visual don't know the id of data.
       mTextureSet,
-      false,     // UseAtlas
-      Vector4(), // AtlasRect
+      mUrl.GetUrl(),
       mPreMultiplyOnLoad));
 }
 
index b5c9b51..f95a796 100644 (file)
@@ -28,6 +28,7 @@
 #include <dali-toolkit/devel-api/utility/npatch-helper.h>
 #include <dali-toolkit/devel-api/visuals/image-visual-properties-devel.h>
 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
+#include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
 #include <dali-toolkit/internal/visuals/npatch-loader.h>
 #include <dali-toolkit/internal/visuals/rendering-addon.h>
@@ -85,16 +86,28 @@ void NPatchVisual::LoadImages()
     }
   }
 
-  if(!mAuxiliaryPixelBuffer && mAuxiliaryUrl.IsValid() && (mAuxiliaryUrl.IsLocalResource() || mAuxiliaryUrl.IsBufferResource()))
+  if(mAuxiliaryTextureId == TextureManager::INVALID_TEXTURE_ID && mAuxiliaryUrl.IsValid() && (mAuxiliaryUrl.IsLocalResource() || mAuxiliaryUrl.IsBufferResource()))
   {
+    auto preMultiplyOnLoad = IsPreMultipliedAlphaEnabled() && !mImpl->mCustomShader
+                               ? TextureManager::MultiplyOnLoad::MULTIPLY_ON_LOAD
+                               : TextureManager::MultiplyOnLoad::LOAD_WITHOUT_MULTIPLY;
+
+    TextureManager::MaskingDataPointer maskingDataPtr       = nullptr;
+    ImageAtlasManagerPtr               imageAtlasManagerPtr = nullptr;
+
+    bool atlasing      = false;
+    auto atlasRect     = Vector4::ZERO;
+    auto atlasRectSize = Dali::ImageDimensions();
+
+    bool loadingStatus = false;
+
     // 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);
+    mAuxiliaryTextureSet = textureManager.LoadTexture(mAuxiliaryUrl, Dali::ImageDimensions(), FittingMode::DEFAULT, SamplingMode::BOX_THEN_LINEAR, maskingDataPtr, synchronousLoading, mAuxiliaryTextureId, atlasRect, atlasRectSize, atlasing, loadingStatus, WrapMode::DEFAULT, WrapMode::DEFAULT, this, nullptr, imageAtlasManagerPtr, true, TextureManager::ReloadPolicy::CACHED, preMultiplyOnLoad);
 
     // If synchronousLoading is true, we can check the auxiliaryResource's status now.
     if(synchronousLoading)
     {
-      mAuxiliaryResourceStatus = mAuxiliaryPixelBuffer ? Toolkit::Visual::ResourceStatus::READY : Toolkit::Visual::ResourceStatus::FAILED;
+      mAuxiliaryResourceStatus = (mAuxiliaryTextureSet && mAuxiliaryTextureSet.GetTextureCount() > 0u) ? Toolkit::Visual::ResourceStatus::READY : Toolkit::Visual::ResourceStatus::FAILED;
     }
   }
 }
@@ -124,10 +137,10 @@ void NPatchVisual::GetNaturalSize(Vector2& naturalSize)
     }
   }
 
-  if(mAuxiliaryPixelBuffer)
+  if(mAuxiliaryTextureSet && mAuxiliaryTextureSet.GetTextureCount() > 0u)
   {
-    naturalSize.x = std::max(naturalSize.x, float(mAuxiliaryPixelBuffer.GetWidth()));
-    naturalSize.y = std::max(naturalSize.y, float(mAuxiliaryPixelBuffer.GetHeight()));
+    naturalSize.x = std::max(naturalSize.x, float(mAuxiliaryTextureSet.GetTexture(0u).GetWidth()));
+    naturalSize.y = std::max(naturalSize.y, float(mAuxiliaryTextureSet.GetTexture(0u).GetHeight()));
   }
 }
 
@@ -215,11 +228,22 @@ void NPatchVisual::DoSetOnScene(Actor& actor)
 
 void NPatchVisual::DoSetOffScene(Actor& actor)
 {
-  if((mId != NPatchData::INVALID_NPATCH_DATA_ID) && mReleasePolicy == Toolkit::ImageVisual::ReleasePolicy::DETACHED)
+  if(mReleasePolicy == Toolkit::ImageVisual::ReleasePolicy::DETACHED)
   {
-    mLoader.Remove(mId, this);
-    mImpl->mResourceStatus = Toolkit::Visual::ResourceStatus::PREPARING;
-    mId                    = NPatchData::INVALID_NPATCH_DATA_ID;
+    if(mId != NPatchData::INVALID_NPATCH_DATA_ID)
+    {
+      mLoader.Remove(mId, this);
+      mImpl->mResourceStatus = Toolkit::Visual::ResourceStatus::PREPARING;
+      mId                    = NPatchData::INVALID_NPATCH_DATA_ID;
+    }
+    if(mAuxiliaryTextureId != TextureManager::INVALID_TEXTURE_ID)
+    {
+      TextureManager& textureManager = mFactoryCache.GetTextureManager();
+      textureManager.Remove(mAuxiliaryTextureId, this);
+      mAuxiliaryTextureId      = TextureManager::INVALID_TEXTURE_ID;
+      mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::PREPARING;
+      mAuxiliaryTextureSet.Reset();
+    }
   }
 
   actor.RemoveRenderer(mImpl->mRenderer);
@@ -269,6 +293,8 @@ NPatchVisual::NPatchVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFa
   mImageUrl(),
   mAuxiliaryUrl(),
   mId(NPatchData::INVALID_NPATCH_DATA_ID),
+  mAuxiliaryTextureSet(),
+  mAuxiliaryTextureId(TextureManager::INVALID_TEXTURE_ID),
   mAuxiliaryResourceStatus(Toolkit::Visual::ResourceStatus::PREPARING),
   mBorderOnly(false),
   mBorder(),
@@ -280,10 +306,23 @@ NPatchVisual::NPatchVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFa
 
 NPatchVisual::~NPatchVisual()
 {
-  if(Stage::IsInstalled() && (mId != NPatchData::INVALID_NPATCH_DATA_ID) && (mReleasePolicy != Toolkit::ImageVisual::ReleasePolicy::NEVER))
+  if(Stage::IsInstalled())
   {
-    mLoader.Remove(mId, this);
-    mId = NPatchData::INVALID_NPATCH_DATA_ID;
+    if(mReleasePolicy != Toolkit::ImageVisual::ReleasePolicy::NEVER)
+    {
+      if(mId != NPatchData::INVALID_NPATCH_DATA_ID)
+      {
+        mLoader.Remove(mId, this);
+        mId = NPatchData::INVALID_NPATCH_DATA_ID;
+      }
+      if(mAuxiliaryTextureId != TextureManager::INVALID_TEXTURE_ID)
+      {
+        TextureManager& textureManager = mFactoryCache.GetTextureManager();
+        textureManager.Remove(mAuxiliaryTextureId, this);
+        mAuxiliaryTextureId = TextureManager::INVALID_TEXTURE_ID;
+        mAuxiliaryTextureSet.Reset();
+      }
+    }
   }
 }
 
@@ -366,10 +405,10 @@ Shader NPatchVisual::CreateShader()
   NPatchUtility::StretchRanges::SizeType xStretchCount = 0;
   NPatchUtility::StretchRanges::SizeType yStretchCount = 0;
 
-  auto fragmentShader = mAuxiliaryPixelBuffer ? SHADER_NPATCH_VISUAL_MASK_SHADER_FRAG
-                                              : SHADER_NPATCH_VISUAL_SHADER_FRAG;
-  auto shaderType = mAuxiliaryPixelBuffer ? VisualFactoryCache::NINE_PATCH_MASK_SHADER
-                                          : VisualFactoryCache::NINE_PATCH_SHADER;
+  auto fragmentShader = mAuxiliaryResourceStatus == Toolkit::Visual::ResourceStatus::READY ? SHADER_NPATCH_VISUAL_MASK_SHADER_FRAG
+                                                                                           : SHADER_NPATCH_VISUAL_SHADER_FRAG;
+  auto shaderType = mAuxiliaryResourceStatus == Toolkit::Visual::ResourceStatus::READY ? VisualFactoryCache::NINE_PATCH_MASK_SHADER
+                                                                                       : VisualFactoryCache::NINE_PATCH_SHADER;
 
   // ask loader for the regions
   if(mLoader.GetNPatchData(mId, data))
@@ -447,32 +486,17 @@ void NPatchVisual::ApplyTextureAndUniforms()
     textureSet = data->GetTextures();
     NPatchHelper::ApplyTextureAndUniforms(mImpl->mRenderer, data);
 
-    if(mAuxiliaryPixelBuffer)
+    if(mAuxiliaryResourceStatus == Toolkit::Visual::ResourceStatus::READY)
     {
-      // If the auxiliary image is smaller than the un-stretched NPatch, use CPU resizing to enlarge it to the
-      // same size as the unstretched NPatch. This will give slightly higher quality results than just relying
-      // on GL interpolation alone.
-      if(mAuxiliaryPixelBuffer.GetWidth() < data->GetCroppedWidth() &&
-         mAuxiliaryPixelBuffer.GetHeight() < data->GetCroppedHeight())
-      {
-        mAuxiliaryPixelBuffer.Resize(data->GetCroppedWidth(), data->GetCroppedHeight());
-      }
-
-      // Note, this resets mAuxiliaryPixelBuffer handle
-      auto auxiliaryPixelData = Devel::PixelBuffer::Convert(mAuxiliaryPixelBuffer);
-
-      auto texture = Texture::New(TextureType::TEXTURE_2D,
-                                  auxiliaryPixelData.GetPixelFormat(),
-                                  auxiliaryPixelData.GetWidth(),
-                                  auxiliaryPixelData.GetHeight());
-      texture.Upload(auxiliaryPixelData);
+      DALI_ASSERT_ALWAYS(mAuxiliaryTextureId != TextureManager::INVALID_TEXTURE_ID);
+      DALI_ASSERT_ALWAYS(mAuxiliaryTextureSet && mAuxiliaryTextureSet.GetTextureCount() > 0u);
 
       // TODO : This code exist due to the texture cache manager hold TextureSet, not Texture.
       // If we call textureSet.SetTexture(1, texture) directly, the cached TextureSet also be changed.
       // We should make pass utc-Dali-VisualFactory.cpp UtcDaliNPatchVisualAuxiliaryImage02().
       TextureSet tempTextureSet = TextureSet::New();
       tempTextureSet.SetTexture(0, textureSet.GetTexture(0));
-      tempTextureSet.SetTexture(1, texture);
+      tempTextureSet.SetTexture(1, mAuxiliaryTextureSet.GetTexture(0));
       textureSet = tempTextureSet;
 
       mImpl->mRenderer.RegisterProperty(DevelImageVisual::Property::AUXILIARY_IMAGE_ALPHA,
@@ -552,27 +576,30 @@ void NPatchVisual::SetResource()
 
 void NPatchVisual::LoadComplete(bool loadSuccess, TextureInformation textureInformation)
 {
-  if(textureInformation.returnType == TextureUploadObserver::ReturnType::TEXTURE) // For the Url.
+  if(textureInformation.url.length() > 0) // For the Url.
   {
-    if(textureInformation.textureId != TextureManager::INVALID_TEXTURE_ID)
+    if(DALI_UNLIKELY(mId == NPatchData::INVALID_NPATCH_DATA_ID))
     {
-      if(mId == NPatchData::INVALID_NPATCH_DATA_ID)
-      {
-        // Special case when mLoader.Load call LoadComplete function before mId setup.
-        // We can overwrite mId.
-        mId = static_cast<NPatchData::NPatchDataId>(textureInformation.textureId);
-      }
+      // Special case when mLoader.Load call LoadComplete function before mId setup.
+      // We can overwrite mId.
+      mId = static_cast<NPatchData::NPatchDataId>(textureInformation.textureId);
     }
     if(loadSuccess)
     {
       EnablePreMultipliedAlpha(textureInformation.preMultiplied);
     }
   }
-  else // For the AuxiliaryUrl : ReturnType::PIXEL_BUFFER
+  else // For the AuxiliaryUrl
   {
-    if(loadSuccess && textureInformation.url == mAuxiliaryUrl.GetUrl())
+    if(DALI_UNLIKELY(mAuxiliaryTextureId == TextureManager::INVALID_TEXTURE_ID))
+    {
+      // Special case when TextureManager.LoadTexture call LoadComplete function before mAuxiliaryTextureId setup.
+      // We can overwrite mAuxiliaryTextureId.
+      mAuxiliaryTextureId = textureInformation.textureId;
+    }
+    if(loadSuccess)
     {
-      mAuxiliaryPixelBuffer    = textureInformation.pixelBuffer;
+      mAuxiliaryTextureSet     = textureInformation.textureSet;
       mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::READY;
     }
     else
@@ -580,6 +607,7 @@ void NPatchVisual::LoadComplete(bool loadSuccess, TextureInformation textureInfo
       mAuxiliaryResourceStatus = Toolkit::Visual::ResourceStatus::FAILED;
     }
   }
+
   // If auxiliaryUrl didn't required OR auxiliaryUrl load done.
   if(!mAuxiliaryUrl.IsValid() || mAuxiliaryResourceStatus != Toolkit::Visual::ResourceStatus::PREPARING)
   {
index b86dc41..c94e5b4 100644 (file)
@@ -221,7 +221,8 @@ private:
   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
   NPatchData::NPatchDataId                  mId;                      ///< id of the N patch (from loader/cache)
-  Devel::PixelBuffer                        mAuxiliaryPixelBuffer;    ///< pixel buffer of the auxiliary mask image
+  TextureSet                                mAuxiliaryTextureSet;     ///< TextureSet of the auxiliary mask image
+  TextureManager::TextureId                 mAuxiliaryTextureId;      ///< id of the auxiliary mask image (from TextureManager)
   Toolkit::Visual::ResourceStatus           mAuxiliaryResourceStatus; ///< resource status for auxiliary mask image
   bool                                      mBorderOnly;              ///< if only border is desired
   Rect<int>                                 mBorder;                  ///< The size of the border