DALI_TRACE_SCOPE(gTraceFilter, "DALI_EGL_CONTROLLER_DISCARD_QUEUE");
// Process textures
- ProcessDiscardQueue<GLES::Texture>(mDiscardTextureQueue);
+ ProcessDiscardSet<GLES::Texture>(mDiscardTextureSet);
// Process buffers
ProcessDiscardQueue<GLES::Buffer>(mDiscardBufferQueue);
sourceBufferReleaseRequired = Dali::Integration::IsPixelDataReleaseAfterUpload(source.pixelDataSource.pixelData) && info.srcOffset == 0u;
}
- auto sourceStride = info.srcStride;
- std::vector<uint8_t> tempBuffer;
-
- if(mGlAbstraction->TextureRequiresConverting(srcFormat, destFormat, isSubImage))
+ // Skip texture upload if given texture is already discarded for this render loop.
+ if(mDiscardTextureSet.find(texture) == mDiscardTextureSet.end())
{
- // Convert RGB to RGBA if necessary.
- if(texture->TryConvertPixelData(sourceBuffer, info.srcFormat, createInfo.format, info.srcSize, info.srcStride, info.srcExtent2D.width, info.srcExtent2D.height, tempBuffer))
+ auto sourceStride = info.srcStride;
+ std::vector<uint8_t> tempBuffer;
+
+ if(mGlAbstraction->TextureRequiresConverting(srcFormat, destFormat, isSubImage))
{
- sourceBuffer = &tempBuffer[0];
- sourceStride = 0u; // Converted buffer compacted. make stride as 0.
- srcFormat = destFormat;
- srcType = GLES::GLTextureFormatType(createInfo.format).type;
+ // Convert RGB to RGBA if necessary.
+ if(texture->TryConvertPixelData(sourceBuffer, info.srcFormat, createInfo.format, info.srcSize, info.srcStride, info.srcExtent2D.width, info.srcExtent2D.height, tempBuffer))
+ {
+ sourceBuffer = &tempBuffer[0];
+ sourceStride = 0u; // Converted buffer compacted. make stride as 0.
+ srcFormat = destFormat;
+ srcType = GLES::GLTextureFormatType(createInfo.format).type;
+ }
}
- }
- // Calculate the maximum mipmap level for the texture
- texture->SetMaxMipMapLevel(std::max(texture->GetMaxMipMapLevel(), info.level));
+ // Calculate the maximum mipmap level for the texture
+ texture->SetMaxMipMapLevel(std::max(texture->GetMaxMipMapLevel(), info.level));
- GLenum bindTarget{GL_TEXTURE_2D};
- GLenum target{GL_TEXTURE_2D};
+ GLenum bindTarget{GL_TEXTURE_2D};
+ GLenum target{GL_TEXTURE_2D};
- if(createInfo.textureType == Graphics::TextureType::TEXTURE_CUBEMAP)
- {
- bindTarget = GL_TEXTURE_CUBE_MAP;
- target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + info.layer;
- }
+ if(createInfo.textureType == Graphics::TextureType::TEXTURE_CUBEMAP)
+ {
+ bindTarget = GL_TEXTURE_CUBE_MAP;
+ target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + info.layer;
+ }
- mGlAbstraction->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
- mGlAbstraction->PixelStorei(GL_UNPACK_ROW_LENGTH, sourceStride);
+ mGlAbstraction->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ mGlAbstraction->PixelStorei(GL_UNPACK_ROW_LENGTH, sourceStride);
- mCurrentContext->BindTexture(bindTarget, texture->GetTextureTypeId(), texture->GetGLTexture());
+ mCurrentContext->BindTexture(bindTarget, texture->GetTextureTypeId(), texture->GetGLTexture());
- if(!isSubImage)
- {
- if(!texture->IsCompressed())
- {
- mGlAbstraction->TexImage2D(target,
- info.level,
- destInternalFormat,
- info.srcExtent2D.width,
- info.srcExtent2D.height,
- 0,
- srcFormat,
- srcType,
- sourceBuffer);
- }
- else
- {
- mGlAbstraction->CompressedTexImage2D(target,
- info.level,
- destInternalFormat,
- info.srcExtent2D.width,
- info.srcExtent2D.height,
- 0,
- info.srcSize,
- sourceBuffer);
- }
- }
- else
- {
- if(!texture->IsCompressed())
+ if(!isSubImage)
{
- mGlAbstraction->TexSubImage2D(target,
- info.level,
- info.dstOffset2D.x,
- info.dstOffset2D.y,
- info.srcExtent2D.width,
- info.srcExtent2D.height,
- srcFormat,
- srcType,
- sourceBuffer);
+ if(!texture->IsCompressed())
+ {
+ mGlAbstraction->TexImage2D(target,
+ info.level,
+ destInternalFormat,
+ info.srcExtent2D.width,
+ info.srcExtent2D.height,
+ 0,
+ srcFormat,
+ srcType,
+ sourceBuffer);
+ }
+ else
+ {
+ mGlAbstraction->CompressedTexImage2D(target,
+ info.level,
+ destInternalFormat,
+ info.srcExtent2D.width,
+ info.srcExtent2D.height,
+ 0,
+ info.srcSize,
+ sourceBuffer);
+ }
}
else
{
- mGlAbstraction->CompressedTexSubImage2D(target,
- info.level,
- info.dstOffset2D.x,
- info.dstOffset2D.y,
- info.srcExtent2D.width,
- info.srcExtent2D.height,
- srcFormat,
- info.srcSize,
- sourceBuffer);
+ if(!texture->IsCompressed())
+ {
+ mGlAbstraction->TexSubImage2D(target,
+ info.level,
+ info.dstOffset2D.x,
+ info.dstOffset2D.y,
+ info.srcExtent2D.width,
+ info.srcExtent2D.height,
+ srcFormat,
+ srcType,
+ sourceBuffer);
+ }
+ else
+ {
+ mGlAbstraction->CompressedTexSubImage2D(target,
+ info.level,
+ info.dstOffset2D.x,
+ info.dstOffset2D.y,
+ info.srcExtent2D.width,
+ info.srcExtent2D.height,
+ srcFormat,
+ info.srcSize,
+ sourceBuffer);
+ }
}
}
#include <dali/graphics-api/graphics-controller.h>
#include <queue>
#include <unordered_map>
+#include <unordered_set>
// INTERNAL INCLUDES
#include <dali/integration-api/graphics-sync-abstraction.h>
*/
void DiscardResource(GLES::Texture* texture)
{
- mDiscardTextureQueue.push(texture);
+ mDiscardTextureSet.insert(texture);
}
/**
}
/**
+ * @brief Processes a discard set for type specified
+ *
+ * @param[in,out] set Reference to the discard set
+ */
+ template<class U, class T>
+ void ProcessDiscardSet(T& set)
+ {
+ while(!set.empty())
+ {
+ auto iter = set.begin();
+ auto* object = const_cast<U*>(*iter);
+
+ // Destroy
+ object->DestroyResource();
+
+ // Free
+ auto* clbk = object->GetCreateInfo().allocationCallbacks;
+ if(clbk)
+ {
+ // Call destructor
+ object->~U();
+
+ // Free memory
+ clbk->freeCallback(object, clbk->userData);
+ }
+ else
+ {
+ delete object;
+ }
+ set.erase(iter);
+ }
+ }
+
+ /**
* @brief Processes all resource create queues
*/
void ProcessCreateQueues();
Internal::Adaptor::EglSyncImplementation* mEglSyncImplementation{nullptr};
Internal::Adaptor::GraphicsInterface* mGraphics{nullptr}; // Pointer to owning structure via interface.
- std::queue<GLES::Texture*> mCreateTextureQueue; ///< Create queue for texture resource
- std::queue<GLES::Texture*> mDiscardTextureQueue; ///< Discard queue for texture resource
+ std::queue<GLES::Texture*> mCreateTextureQueue; ///< Create queue for texture resource
+ std::unordered_set<GLES::Texture*> mDiscardTextureSet; ///< Discard queue for texture resource
std::queue<GLES::Buffer*> mCreateBufferQueue; ///< Create queue for buffer resource
std::queue<GLES::Buffer*> mDiscardBufferQueue; ///< Discard queue for buffer resource
glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
- FINISH_DURATION_CHECK_WITH_FORMAT("glTexImage2D", "size : %u x %u", width, height);
+ FINISH_DURATION_CHECK_WITH_FORMAT("glTexImage2D", "size : %u x %u, format : %d, type : %d", width, height, static_cast<int>(format), static_cast<int>(type));
}
void TexParameterf(GLenum target, GLenum pname, GLfloat param) override
glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
- FINISH_DURATION_CHECK_WITH_FORMAT("glTexSubImage2D", "size : %u x %u", width, height);
+ FINISH_DURATION_CHECK_WITH_FORMAT("glTexSubImage2D", "size : %u x %u, format : %d, type : %d", width, height, static_cast<int>(format), static_cast<int>(type));
}
void Uniform1f(GLint location, GLfloat x) override