/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
// INTERNAL INCLUDES
#include <dali/integration-api/debug.h>
+#include <dali/internal/common/memory-pool-object-allocator.h>
namespace Dali
{
Debug::Filter* gTextureFilter = Debug::Filter::New(Debug::Concise, false, "LOG_TEXTURE");
#endif
+// Memory pool used to allocate new textures. Memory used by this pool will be released when shutting down DALi
+MemoryPoolObjectAllocator<Texture> gTextureMemoryPool;
+
/**
* Converts DALi pixel format to Graphics::Format
* @param format
} //Unnamed namespace
+TextureKey Texture::NewKey(Type type, Pixel::Format format, ImageDimensions size)
+{
+ void* ptr = gTextureMemoryPool.AllocateRawThreadSafe();
+ auto key = gTextureMemoryPool.GetKeyFromPtr(static_cast<Texture*>(ptr));
+ new(ptr) Texture(type, format, size);
+
+ return TextureKey(key);
+}
+
+TextureKey Texture::NewKey(NativeImageInterfacePtr nativeImageInterface)
+{
+ void* ptr = gTextureMemoryPool.AllocateRawThreadSafe();
+ auto key = gTextureMemoryPool.GetKeyFromPtr(static_cast<Texture*>(ptr));
+ new(ptr) Texture(nativeImageInterface);
+
+ return TextureKey(key);
+}
+
Texture::Texture(Type type, Pixel::Format format, ImageDimensions size)
: mGraphicsController(nullptr),
mGraphicsTexture(nullptr),
mWidth(size.GetWidth()),
mHeight(size.GetHeight()),
mType(type),
- mHasAlpha(HasAlpha(format))
+ mHasAlpha(HasAlpha(format)),
+ mUpdated(true)
{
}
mWidth(static_cast<uint16_t>(nativeImageInterface->GetWidth())), // ignoring overflow, not happening in practice
mHeight(static_cast<uint16_t>(nativeImageInterface->GetHeight())), // ignoring overflow, not happening in practice
mType(TextureType::TEXTURE_2D),
- mHasAlpha(nativeImageInterface->RequiresBlending())
+ mHasAlpha(nativeImageInterface->RequiresBlending()),
+ mUpdated(true)
{
}
Texture::~Texture() = default;
+void Texture::operator delete(void* ptr)
+{
+ gTextureMemoryPool.FreeThreadSafe(static_cast<Texture*>(ptr));
+}
+
+Render::Texture* Texture::Get(TextureKey::KeyType key)
+{
+ return gTextureMemoryPool.GetPtrFromKey(key);
+}
+
void Texture::Initialize(Graphics::Controller& graphicsController)
{
mGraphicsController = &graphicsController;
}
Graphics::TextureUpdateInfo info{};
+
+ const uint32_t srcStride = pixelData->GetStride();
+ uint32_t srcOffset = 0u;
+ uint32_t srcSize = pixelData->GetBufferSize();
+
+ const bool requiredSubPixelData = (!Pixel::IsCompressed(pixelData->GetPixelFormat())) &&
+ ((params.dataXOffset != 0) ||
+ (params.dataYOffset != 0) ||
+ (params.dataWidth != pixelData->GetWidth()) ||
+ (params.dataHeight != pixelData->GetHeight()));
+
+ if(requiredSubPixelData)
+ {
+ /**
+ * TextureUpdateInfo use byte scaled offset / size.
+ *
+ * To make we only use sub-data of inputed PixelData, make srcOffset as 'start of SubPixelData.
+ *
+ * |---- dataStrideByte -----|
+ * |-----| <-- dataXOffsetByte
+ * ...........................
+ * ......A-----------+........
+ * ......| |........
+ * ......| |........
+ * ......+-----------+C.......
+ * ......B....................
+ *
+ * A) Start of SubPixelData. offsetByte = dataStrideByte * dataYOffset + dataXOffsetByte.
+ * B) offsetByte = A).offsetByte + dataStrideByte * dataHeight. Note, It can be out of original PixelData boundary.
+ * C) End of SubPixelData. offsetByte = B).offsetByte - dataStrideByte + dataWidthByte.
+ *
+ * srcOffset = A).offsetByte;
+ * srcSize = ( C).offsetByte - A).offsetByte );
+ */
+ const uint32_t bytePerPixel = Pixel::GetBytesPerPixel(pixelData->GetPixelFormat());
+ const uint32_t dataStrideByte = (srcStride ? srcStride : static_cast<uint32_t>(params.dataWidth)) * bytePerPixel;
+ const uint32_t dataXOffsetByte = params.dataXOffset * bytePerPixel;
+ const uint32_t dataWidthByte = static_cast<uint32_t>(params.dataWidth) * bytePerPixel;
+
+ srcOffset = params.dataYOffset * dataStrideByte + dataXOffsetByte;
+ srcSize = static_cast<uint32_t>(params.dataHeight) * dataStrideByte - (dataStrideByte - dataWidthByte);
+ }
+
info.dstTexture = mGraphicsTexture.get();
info.dstOffset2D = {params.xOffset, params.yOffset};
info.layer = params.layer;
info.level = params.mipmap;
info.srcReference = 0;
- info.srcExtent2D = {params.width, params.height};
- info.srcOffset = 0;
- info.srcSize = pixelData->GetBufferSize();
- info.srcStride = pixelData->GetStride();
+ info.srcExtent2D = {params.dataWidth, params.dataHeight};
+ info.srcOffset = srcOffset;
+ info.srcSize = srcSize;
+ info.srcStride = srcStride;
info.srcFormat = ConvertPixelFormat(pixelData->GetPixelFormat());
Graphics::TextureUpdateSourceInfo updateSourceInfo{};
updateSourceInfo.memorySource.memory = pixelData->GetBuffer();
mGraphicsController->UpdateTextures({info}, {updateSourceInfo});
+
+ SetUpdated(true);
}
bool Texture::HasAlphaChannel() const
mGraphicsController->GenerateTextureMipmaps(*mGraphicsTexture.get());
}
+void Texture::OnRenderFinished()
+{
+ SetUpdated(false);
+}
+
} // namespace Render
} // namespace Internal