/*
- * Copyright (c) 2021 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.
void (*pConversionWriteFunc)(const void*, uint32_t, uint32_t, uint32_t, uint32_t, void*);
};
-inline void WriteRGB32ToRGBA32(const void* pData, uint32_t sizeInBytes, uint32_t width, uint32_t height, uint32_t rowStride, void* pOutput)
+inline void WriteRGB32ToRGBA32(const void* __restrict__ pData, uint32_t sizeInBytes, uint32_t width, uint32_t height, uint32_t rowStride, void* __restrict__ pOutput)
{
- auto inData = reinterpret_cast<const uint8_t*>(pData);
- auto outData = reinterpret_cast<uint8_t*>(pOutput);
- auto outIdx = 0u;
- for(auto i = 0u; i < sizeInBytes; i += 3)
+ const uint8_t* __restrict__ inData = reinterpret_cast<const uint8_t*>(pData);
+ uint8_t* __restrict__ outData = reinterpret_cast<uint8_t*>(pOutput);
+ if(rowStride == 0u)
{
- outData[outIdx] = inData[i];
- outData[outIdx + 1] = inData[i + 1];
- outData[outIdx + 2] = inData[i + 2];
- outData[outIdx + 3] = 0xff;
- outIdx += 4;
+ rowStride = width;
+ }
+ for(auto y = 0u; y < height; ++y)
+ {
+ auto inIdx = 0u;
+ auto outIdx = 0u;
+ for(auto x = 0u; x < width; ++x)
+ {
+ outData[outIdx] = inData[inIdx];
+ outData[outIdx + 1] = inData[inIdx + 1];
+ outData[outIdx + 2] = inData[inIdx + 2];
+ outData[outIdx + 3] = 0xff;
+ outIdx += 4;
+ inIdx += 3;
+ }
+ inData += rowStride * 3u;
+ outData += width * 4u;
}
}
/**
* Format conversion table
*/
-static const std::vector<ColorConversion> COLOR_CONVERSION_TABLE = {
- {Format::R8G8B8_UNORM, Format::R8G8B8A8_UNORM, ConvertRGB32ToRGBA32, WriteRGB32ToRGBA32}};
+const std::vector<ColorConversion>& GetColorConversionTable()
+{
+ static const std::vector<ColorConversion> COLOR_CONVERSION_TABLE = {
+ {Format::R8G8B8_UNORM, Format::R8G8B8A8_UNORM, ConvertRGB32ToRGBA32, WriteRGB32ToRGBA32}};
+ return COLOR_CONVERSION_TABLE;
+}
/**
* Constructor
gl->GenTextures(1, &texture);
context->BindTexture(GL_TEXTURE_2D, GetTextureTypeId(), texture);
- // Allocate memory for the texture
- if(!mIsCompressed)
+ if(mCreateInfo.allocationPolicy == Graphics::TextureAllocationPolicy::CREATION || mCreateInfo.data)
{
- gl->TexImage2D(GL_TEXTURE_2D,
- 0,
- format.internalFormat,
- mCreateInfo.size.width,
- mCreateInfo.size.height,
- 0,
- format.format,
- format.type,
- (mCreateInfo.data ? mStagingBuffer.data() : nullptr));
- }
- else
- {
- gl->CompressedTexImage2D(GL_TEXTURE_2D,
- 0,
- format.internalFormat,
- mCreateInfo.size.width,
- mCreateInfo.size.height,
- 0,
- mCreateInfo.dataSize,
- (mCreateInfo.data ? mStagingBuffer.data() : nullptr));
+ // Allocate memory for the texture
+ if(!mIsCompressed)
+ {
+ gl->TexImage2D(GL_TEXTURE_2D,
+ 0,
+ format.internalFormat,
+ mCreateInfo.size.width,
+ mCreateInfo.size.height,
+ 0,
+ format.format,
+ format.type,
+ (mCreateInfo.data ? mStagingBuffer.data() : nullptr));
+ }
+ else
+ {
+ gl->CompressedTexImage2D(GL_TEXTURE_2D,
+ 0,
+ format.internalFormat,
+ mCreateInfo.size.width,
+ mCreateInfo.size.height,
+ 0,
+ mCreateInfo.dataSize,
+ (mCreateInfo.data ? mStagingBuffer.data() : nullptr));
+ }
}
// Clear staging buffer if there was any
SetSamplerParameter(GL_TEXTURE_WRAP_S, mDefaultSamplerState.wrapS, GL_WRAP_DEFAULT);
SetSamplerParameter(GL_TEXTURE_WRAP_T, mDefaultSamplerState.wrapT, GL_WRAP_DEFAULT);
- // Allocate memory for the texture
- for(uint32_t i = 0; i < 6; ++i)
+ if(mCreateInfo.allocationPolicy == Graphics::TextureAllocationPolicy::CREATION || mCreateInfo.data)
{
- if(!mIsCompressed)
+ // Allocate memory for the texture
+ for(uint32_t i = 0; i < 6; ++i)
{
- gl->TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
- 0,
- format.internalFormat,
- mCreateInfo.size.width,
- mCreateInfo.size.height,
- 0,
- format.format,
- format.type,
- (mCreateInfo.data ? mStagingBuffer.data() : nullptr));
- }
- else
- {
- gl->CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
- 0,
- format.internalFormat,
- mCreateInfo.size.width,
- mCreateInfo.size.height,
- 0,
- mCreateInfo.dataSize,
- (mCreateInfo.data ? mStagingBuffer.data() : nullptr));
+ if(!mIsCompressed)
+ {
+ gl->TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
+ 0,
+ format.internalFormat,
+ mCreateInfo.size.width,
+ mCreateInfo.size.height,
+ 0,
+ format.format,
+ format.type,
+ (mCreateInfo.data ? mStagingBuffer.data() : nullptr));
+ }
+ else
+ {
+ gl->CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
+ 0,
+ format.internalFormat,
+ mCreateInfo.size.width,
+ mCreateInfo.size.height,
+ 0,
+ mCreateInfo.dataSize,
+ (mCreateInfo.data ? mStagingBuffer.data() : nullptr));
+ }
}
}
NativeImageInterfacePtr nativeImage = mCreateInfo.nativeImagePtr;
if(nativeImage)
{
- if(nativeImage->SourceChanged())
- {
- // Update size
- uint32_t width = mCreateInfo.nativeImagePtr->GetWidth();
- uint32_t height = mCreateInfo.nativeImagePtr->GetHeight();
- mCreateInfo.SetSize({width, height}); // Size may change
- }
-
nativeImage->PrepareTexture();
}
}
* This function tests whether format is supported by the driver. If possible it applies
* format conversion to suitable supported pixel format.
*/
-bool Texture::TryConvertPixelData(const void* pData, Graphics::Format srcFormat, Graphics::Format destFormat, uint32_t sizeInBytes, uint32_t width, uint32_t height, std::vector<uint8_t>& outputBuffer)
+bool Texture::TryConvertPixelData(const void* pData, Graphics::Format srcFormat, Graphics::Format destFormat, uint32_t sizeInBytes, uint32_t inStride, uint32_t width, uint32_t height, std::vector<uint8_t>& outputBuffer)
{
// No need to convert
if(srcFormat == destFormat)
return false;
}
- auto it = std::find_if(COLOR_CONVERSION_TABLE.begin(), COLOR_CONVERSION_TABLE.end(), [&](auto& item) {
+ auto it = std::find_if(GetColorConversionTable().begin(), GetColorConversionTable().end(), [&](auto& item) {
return item.srcFormat == srcFormat && item.destFormat == destFormat;
});
// No suitable format, return empty array
- if(it == COLOR_CONVERSION_TABLE.end())
+ if(it == GetColorConversionTable().end())
{
return false;
}
auto begin = reinterpret_cast<const uint8_t*>(pData);
- outputBuffer = std::move(it->pConversionFunc(begin, sizeInBytes, width, height, 0u));
+ outputBuffer = std::move(it->pConversionFunc(begin, sizeInBytes, width, height, inStride));
return !outputBuffer.empty();
}