/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
return true;
}
+uint32_t TestGlAbstraction::GetShaderLanguageVersion()
+{
+ return mShaderLanguageVersion;
+}
+
std::string TestGlAbstraction::GetShaderVersionPrefix()
{
return std::string("");
#define TEST_GL_ABSTRACTION_H
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
bool IsBlendEquationSupported(DevelBlendEquation::Type blendEquation) override;
+ uint32_t GetShaderLanguageVersion();
+
std::string GetShaderVersionPrefix();
std::string GetVertexShaderPrefix();
TraceCallStack mViewportTrace;
// Shaders & Uniforms
+ uint32_t mShaderLanguageVersion{320u};
+
GLuint mLastShaderIdUsed;
GLuint mLastProgramIdUsed{0u};
GLuint mLastUniformIdUsed;
return synced;
}
+void TestSyncObject::Wait()
+{
+ mTrace.PushCall("SyncObject::Wait", ""); // Trace the method
+}
+
+void TestSyncObject::ClientWait()
+{
+ mTrace.PushCall("SyncObject::ClientWait", ""); // Trace the method
+}
+
TestGraphicsSyncImplementation::TestGraphicsSyncImplementation()
{
Initialize();
#define TEST_SYNC_IMPLEMENTATION_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
public:
TestSyncObject(TraceCallStack& trace);
~TestSyncObject() override;
- bool IsSynced() override;
+ bool IsSynced() override;
+ void Wait() override;
+ void ClientWait() override;
+
bool synced;
TraceCallStack& mTrace;
};
#define DALI_TEST_GRAPHICS_SYNC_OBJECT_H_
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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/graphics-api/graphics-sync-object-create-info.h>
#include <dali/graphics-api/graphics-sync-object.h>
-
-#include <test-graphics-sync-impl.h>
+#include "test-graphics-sync-impl.h"
namespace Dali
{
#define DALI_INTEGRATION_SHADER_PRECOMPILER_H
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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 HEADER
-#include <dali/public-api/common/dali-common.h>
-#include <dali/public-api/object/base-handle.h>
-#include <dali/public-api/common/vector-wrapper.h>
#include <dali/devel-api/threading/conditional-wait.h>
#include <dali/devel-api/threading/mutex.h>
+#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/object/base-handle.h>
// EXTERNAL HEDAER
-#include <string_view>
-#include <memory>
-#include <mutex>
#include <dali/graphics-api/graphics-program.h>
#include <dali/graphics-api/graphics-types.h>
+#include <memory>
+#include <mutex>
+#include <string_view>
namespace Dali
{
struct RawShaderData
{
- int shaderCount;
+ int shaderCount;
std::vector<std::string_view> vertexPrefix;
std::vector<std::string_view> fragmentPrefix;
- std::string_view vertexShader;
- std::string_view fragmentShader;
+ std::vector<std::string_view> shaderName;
+ std::string_view vertexShader;
+ std::string_view fragmentShader;
};
/**
private:
std::vector<Graphics::UniquePtr<Dali::Graphics::Program>> mProgram;
- static std::unique_ptr<ShaderPreCompiler> mInstance;
- static std::once_flag mOnceFlag;
- std::vector<RawShaderData> mRawShaderList;
- ConditionalWait mConditionalWait;
- Dali::Mutex mMutex;
- bool mPrecompiled;
- bool mEnabled;
- bool mNeedsSleep{true};
+ static std::unique_ptr<ShaderPreCompiler> mInstance;
+ static std::once_flag mOnceFlag;
+ std::vector<RawShaderData> mRawShaderList;
+ ConditionalWait mConditionalWait;
+ Dali::Mutex mMutex;
+ bool mPrecompiled;
+ bool mEnabled;
+ bool mNeedsSleep{true};
};
} // namespace Dali
{
auto vertexShader = graphics.GetController().GetGraphicsConfig().GetVertexShaderPrefix() + std::string(precompiledShader->vertexPrefix[i].data()) + std::string(precompiledShader->vertexShader.data());
auto fragmentShader = graphics.GetController().GetGraphicsConfig().GetFragmentShaderPrefix() + std::string(precompiledShader->fragmentPrefix[i].data()) + std::string(precompiledShader->fragmentShader.data());
- PreCompileShader(std::move(vertexShader), std::move(fragmentShader));
+ PreCompileShader(std::move(vertexShader), std::move(fragmentShader), static_cast<uint32_t>(i) < precompiledShader->shaderName.size() ? std::string(precompiledShader->shaderName[i]) : "");
}
DALI_LOG_RELEASE_INFO("ShaderPreCompiler[ENABLE], shader count :%d \n", numberOfPrecompiledShader);
}
}
}
-void CombinedUpdateRenderController::PreCompileShader(std::string vertexShader, std::string fragmentShader)
+void CombinedUpdateRenderController::PreCompileShader(std::string vertexShader, std::string fragmentShader, std::string shaderName)
{
GraphicsInterface& graphics = mAdaptorInterfaces.GetGraphicsInterface();
auto createInfo = Graphics::ProgramCreateInfo();
createInfo.SetShaderState(shaderStates);
+ createInfo.SetName(shaderName);
auto graphicsProgram = graphics.GetController().CreateProgram(createInfo, nullptr);
ShaderPreCompiler::Get().AddPreCompiledProgram(std::move(graphicsProgram));
*
* @param[in] vertexShader vertexShader need to precompile
* @param[in] fragmentShader fragmentShader need to precompile
+ * @param[in] shaderName the name of precompile shader (option)
*/
- void PreCompileShader(std::string vertexShader, std::string fragmentShader);
+ void PreCompileShader(std::string vertexShader, std::string fragmentShader, std::string shaderName = "");
/**
* Cancel the precompile
--- /dev/null
+/*
+ * Copyright (c) 2024 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/graphics/gles/egl-sync-implementation.h>
+
+// EXTERNAL INCLUDES
+
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/graphics/gles/egl-debug.h>
+#include <dali/internal/graphics/gles/egl-implementation.h>
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogSyncFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_FENCE_SYNC");
+#endif
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+EglSyncObject::EglSyncObject(EglImplementation& eglImpl)
+: mPollCounter(3),
+ mEglImplementation(eglImpl)
+{
+}
+
+EglSyncObject::~EglSyncObject()
+{
+}
+
+bool EglSyncObject::IsSynced()
+{
+ return true;
+}
+
+void EglSyncObject::Wait()
+{
+}
+
+void EglSyncObject::ClientWait()
+{
+}
+
+EglSyncImplementation::EglSyncImplementation()
+: mEglImplementation(NULL),
+ mSyncInitialized(false),
+ mSyncInitializeFailed(false)
+{
+}
+
+EglSyncImplementation::~EglSyncImplementation()
+{
+}
+
+void EglSyncImplementation::Initialize(EglImplementation* eglImpl)
+{
+ mEglImplementation = eglImpl;
+}
+
+Integration::GraphicsSyncAbstraction::SyncObject* EglSyncImplementation::CreateSyncObject()
+{
+ DALI_ASSERT_ALWAYS(mEglImplementation && "Sync Implementation not initialized");
+ return new EglSyncObject(*mEglImplementation);
+}
+
+void EglSyncImplementation::DestroySyncObject(Integration::GraphicsSyncAbstraction::SyncObject* syncObject)
+{
+ DALI_ASSERT_ALWAYS(mEglImplementation && "Sync Implementation not initialized");
+ delete static_cast<EglSyncObject*>(syncObject);
+}
+
+void EglSyncImplementation::InitializeEglSync()
+{
+}
+
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
#include <EGL/egl.h>
// Undef unneded symbols that fail to compile on MS Windows
+#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) /* Win32 and WinCE */
+
#undef ERROR
#undef OPAQUE
#undef max
#undef DIFFERENCE
+#endif
#include <EGL/eglext.h>
SET( adaptor_graphics_gles_src_files
${adaptor_graphics_dir}/gles/egl-debug.cpp
${adaptor_graphics_dir}/gles/egl-implementation.cpp
- ${adaptor_graphics_dir}/gles/egl-sync-implementation.cpp
${adaptor_graphics_dir}/gles/gl-extensions.cpp
${adaptor_graphics_dir}/gles/gl-extensions-support.cpp
${adaptor_graphics_dir}/gles/gl-implementation.cpp
# module: graphics, backend: tizen
SET( adaptor_graphics_tizen_src_files
${adaptor_graphics_dir}/tizen/egl-image-extensions-tizen.cpp
+ ${adaptor_graphics_dir}/tizen/egl-sync-implementation-tizen.cpp
)
# module: graphics, backend: ubuntu
SET( adaptor_graphics_ubuntu_src_files
${adaptor_graphics_dir}/generic/egl-image-extensions-generic.cpp
+ ${adaptor_graphics_dir}/generic/egl-sync-implementation.cpp
)
# module: graphics, backend: libuv-x11
SET( adaptor_graphics_x11_src_files
${adaptor_graphics_dir}/generic/egl-image-extensions-generic.cpp
+ ${adaptor_graphics_dir}/generic/egl-sync-implementation.cpp
)
# module: graphics, backend: android
SET( adaptor_graphics_android_src_files
${adaptor_graphics_dir}/android/egl-image-extensions-android.cpp
+ ${adaptor_graphics_dir}/android/egl-sync-implementation-android.cpp
)
# module: graphics, backend: windows
SET( adaptor_graphics_windows_src_files
${adaptor_graphics_dir}/windows-gl/egl-image-extensions.cpp
+ ${adaptor_graphics_dir}/windows/egl-sync-implementation-windows.cpp
)
# module: graphics, backend: macos
SET( adaptor_graphics_macos_src_files
${adaptor_graphics_dir}/macos/egl-image-extensions.cpp
+ ${adaptor_graphics_dir}/macos/egl-sync-implementation-macos.cpp
)
# include GLES implementation
--- /dev/null
+/*
+ * Copyright (c) 2024 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/graphics/gles/egl-sync-implementation.h>
+
+// EXTERNAL INCLUDES
+
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/graphics/gles/egl-debug.h>
+#include <dali/internal/graphics/gles/egl-implementation.h>
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogSyncFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_FENCE_SYNC");
+#endif
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+EglSyncObject::EglSyncObject(EglImplementation& eglImpl)
+: mPollCounter(3),
+ mEglImplementation(eglImpl)
+{
+ EGLDisplay display = mEglImplementation.GetDisplay();
+ mEglSync = eglCreateSync(display, EGL_SYNC_FENCE, NULL);
+}
+
+EglSyncObject::~EglSyncObject()
+{
+ if(mEglSync && mEglImplementation.IsGlesInitialized())
+ {
+ EGLDisplay display = mEglImplementation.GetDisplay();
+ eglDestroySync(display, mEglSync);
+ }
+}
+
+bool EglSyncObject::IsSynced()
+{
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglClientWaitSync\n");
+ auto result = eglClientWaitSync(mEglImplementation.GetDisplay(), mEglSync, 0 | EGL_SYNC_FLUSH_COMMANDS_BIT, 0);
+
+ if(result == EGL_FALSE)
+ {
+ EGLint error = eglGetError();
+ if(EGL_SUCCESS != error)
+ {
+ DALI_LOG_ERROR("eglClientSyncWait failed: %#0.4x\n", error);
+ }
+ }
+ else if(result == EGL_CONDITION_SATISFIED)
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglClientWaitSync Synced!\n");
+ return true;
+ }
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglClientWaitSync not synced :(\n");
+ return false;
+}
+
+void EglSyncObject::Wait()
+{
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglWaitSync\n");
+ if(!eglWaitSync(mEglImplementation.GetDisplay(), mEglSync, 0))
+ {
+ EGLint error = eglGetError();
+ if(EGL_SUCCESS != error)
+ {
+ DALI_LOG_ERROR("eglSyncWait failed: %#0.4x\n", error);
+ }
+ }
+}
+
+void EglSyncObject::ClientWait()
+{
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglWaitSync (blocking)\n");
+ auto result = eglClientWaitSync(mEglImplementation.GetDisplay(), mEglSync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER);
+ if(result == EGL_FALSE)
+ {
+ EGLint error = eglGetError();
+ if(EGL_SUCCESS != error)
+ {
+ DALI_LOG_ERROR("eglSyncWait failed: %#0.4x\n", error);
+ }
+ }
+ else if(result == EGL_CONDITION_SATISFIED)
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglClientWaitSync Synced!\n");
+ }
+}
+
+EglSyncImplementation::EglSyncImplementation()
+: mEglImplementation(NULL),
+ mSyncInitialized(false),
+ mSyncInitializeFailed(false)
+{
+}
+
+EglSyncImplementation::~EglSyncImplementation()
+{
+}
+
+void EglSyncImplementation::Initialize(EglImplementation* eglImpl)
+{
+ mEglImplementation = eglImpl;
+}
+
+Integration::GraphicsSyncAbstraction::SyncObject* EglSyncImplementation::CreateSyncObject()
+{
+ DALI_ASSERT_ALWAYS(mEglImplementation && "Sync Implementation not initialized");
+ return new EglSyncObject(*mEglImplementation);
+}
+
+void EglSyncImplementation::DestroySyncObject(Integration::GraphicsSyncAbstraction::SyncObject* syncObject)
+{
+ DALI_ASSERT_ALWAYS(mEglImplementation && "Sync Implementation not initialized");
+ delete static_cast<EglSyncObject*>(syncObject);
+}
+
+void EglSyncImplementation::InitializeEglSync()
+{
+}
+
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
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
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
#define DALI_GRAPHICS_EGL_SYNC_OBJECT_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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/internal/graphics/gles-impl/gles-graphics-resource.h>
+//#include <dali/internal/graphics/gles/egl-sync-implementation.h>
namespace Dali::Internal::Adaptor
{
class EglSyncImplementation;
{
using SyncObjectResource = GLES::Resource<Graphics::SyncObject, Graphics::SyncObjectCreateInfo>;
+/**
+ * Proxy to EglSyncObject that also implements a graphics resource
+ */
class SyncObject : public SyncObjectResource
{
public:
texture->InitializeResource();
}
- // Warning, this may cause glWaitSync to occur on the GPU.
- dependencyChecker.CheckNeedsSync(this, texture);
+ // Warning, this may cause glWaitSync to occur on the GPU, or glClientWaitSync to block the CPU.
+ dependencyChecker.CheckNeedsSync(this, texture, true);
texture->Bind(binding);
texture->Prepare();
{
createInfo.shaderState = new std::vector<ShaderState>(*info.shaderState);
}
+
+ // Create new reference of std::string_view.
+ name = std::string(info.name);
+ createInfo.name = name;
}
~Impl()
EglGraphicsController& controller;
ProgramCreateInfo createInfo;
+ std::string name;
uint32_t glProgram{};
uint32_t refCount{0u};
auto program = gl->CreateProgram();
+ DALI_LOG_INFO(gGraphicsProgramLogFilter, Debug::Verbose, "Program[%s] create program id : %u\n", mImpl->name.c_str(), program);
+
const auto& info = mImpl->createInfo;
for(const auto& state : *info.shaderState)
{
// Compile shader first (ignored when compiled)
if(shader->GetImplementation()->Compile())
{
- gl->AttachShader(program, shader->GetImplementation()->GetGLShader());
+ auto shaderId = shader->GetImplementation()->GetGLShader();
+ DALI_LOG_INFO(gGraphicsProgramLogFilter, Debug::Verbose, "Program[%s] attach shader : %u\n", mImpl->name.c_str(), shaderId);
+ gl->AttachShader(program, shaderId);
}
}
+
+ DALI_LOG_INFO(gGraphicsProgramLogFilter, Debug::Verbose, "Program[%s] call glLinkProgram\n", mImpl->name.c_str());
gl->LinkProgram(program);
GLint status{0};
gl->GetProgramInfoLog(program, 4096, &size, output);
// log on error
- DALI_LOG_ERROR("glLinkProgam failed:\n%s\n", output);
+ DALI_LOG_ERROR("glLinkProgam[%s] failed:\n%s\n", mImpl->name.c_str(), output);
gl->DeleteProgram(program);
return false;
}
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
#define DALI_GRAPHICS_GLES_SYNC_OBJECT_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
{
using SyncObjectResource = Resource<Graphics::SyncObject, Graphics::SyncObjectCreateInfo>;
+/**
+ * Class that maintains a glFenceSync object.
+ */
class SyncObject : public SyncObjectResource
{
public:
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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 Headers
#include <dali/internal/graphics/gles-impl/egl-graphics-controller.h>
+#include <dali/internal/graphics/gles/egl-sync-implementation.h>
+
+#if defined(DEBUG_ENABLED)
+extern Debug::Filter* gLogSyncFilter;
+#endif
namespace Dali::Graphics::GLES
{
-AgingSyncObject::AgingSyncObject(Graphics::EglGraphicsController& controller, const Context* writeContext)
+AgingSyncObject::AgingSyncObject(Graphics::EglGraphicsController& controller, const Context* writeContext, bool _egl)
: controller(controller),
- writeContext(writeContext)
+ writeContext(writeContext),
+ egl(_egl)
{
- auto gl = controller.GetGL();
- if(gl)
+ if(egl)
+ {
+ eglSyncObject = static_cast<Internal::Adaptor::EglSyncObject*>(controller.GetEglSyncImplementation().CreateSyncObject());
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::cons; EGL::CreateSyncObject: %p\n", eglSyncObject);
+ }
+ else
{
- glSyncObject = gl->FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ auto gl = controller.GetGL();
+ if(gl)
+ {
+ glSyncObject = gl->FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ }
}
}
AgingSyncObject::~AgingSyncObject()
{
- auto gl = controller.GetGL();
- if(gl && glSyncObject != nullptr)
+ if(!controller.IsShuttingDown())
{
- gl->DeleteSync(glSyncObject);
+ if(egl)
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::dstr; EGL::DestroySyncObject: %p\n", eglSyncObject);
+ controller.GetEglSyncImplementation().DestroySyncObject(eglSyncObject);
+ }
+ else
+ {
+ auto gl = controller.GetGL();
+ if(gl && glSyncObject != nullptr)
+ {
+ gl->DeleteSync(glSyncObject);
+ }
+ }
+ }
+}
+
+bool AgingSyncObject::ClientWait()
+{
+ bool synced = false;
+ if(egl)
+ {
+ if(eglSyncObject)
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::ClientWait(); EGL::ClientWaitSync\n");
+ eglSyncObject->ClientWait();
+ synced = true;
+ }
+ }
+ else
+ {
+ auto gl = controller.GetGL();
+ if(gl && glSyncObject)
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::ClientWait(); glClientWaitSync 1ms\n");
+ const GLuint64 TIMEOUT = 1000000; //1ms!
+ GLenum result = gl->ClientWaitSync(glSyncObject, GL_SYNC_FLUSH_COMMANDS_BIT, TIMEOUT);
+
+ synced = (result == GL_ALREADY_SIGNALED || result == GL_CONDITION_SATISFIED);
+ }
+ }
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::ClientWait(); Result: %s\n", synced ? "Synced" : "NOT SYNCED");
+ return synced;
+}
+
+void AgingSyncObject::Wait()
+{
+ if(egl)
+ {
+ if(eglSyncObject)
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::Wait(); EGL::WaitSync\n");
+ eglSyncObject->Wait();
+ }
+ }
+ else
+ {
+ auto gl = controller.GetGL();
+ if(gl && glSyncObject)
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgingSyncObject::Wait(); glWaitSync\n");
+ gl->WaitSync(glSyncObject, 0, 0ull);
+ }
}
}
SyncPool::~SyncPool() = default;
-AgingSyncObject* SyncPool::AllocateSyncObject(const Context* writeContext)
+AgingSyncObject* SyncPool::AllocateSyncObject(const Context* writeContext, SyncPool::SyncContext syncContext)
{
- std::unique_ptr<AgingSyncObject> syncObject = std::make_unique<AgingSyncObject>(mController, writeContext);
+ std::unique_ptr<AgingSyncObject> syncObject = std::make_unique<AgingSyncObject>(mController, writeContext, (syncContext == SyncContext::EGL));
mSyncObjects.push_back(std::move(syncObject));
return mSyncObjects.back().get();
}
void SyncPool::Wait(AgingSyncObject* syncPoolObject)
{
- auto gl = mController.GetGL();
- if(gl && syncPoolObject->glSyncObject != nullptr)
+ if(syncPoolObject != nullptr)
{
syncPoolObject->syncing = true;
- gl->WaitSync(syncPoolObject->glSyncObject, 0, GL_TIMEOUT_IGNORED);
+ syncPoolObject->Wait();
+ }
+}
+
+bool SyncPool::ClientWait(AgingSyncObject* syncPoolObject)
+{
+ if(syncPoolObject)
+ {
+ return syncPoolObject->ClientWait();
}
+ return false;
}
void SyncPool::FreeSyncObject(AgingSyncObject* agingSyncObject)
*/
void SyncPool::AgeSyncObjects()
{
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgeSyncObjects: count: %d\n", mSyncObjects.size());
+
if(!mSyncObjects.empty())
{
// Age the remaining sync objects.
for(auto& agingSyncObject : mSyncObjects)
{
- if(agingSyncObject != nullptr && agingSyncObject->glSyncObject != 0)
+ if(agingSyncObject != nullptr && (agingSyncObject->glSyncObject != 0 || agingSyncObject->eglSyncObject != nullptr))
{
if(agingSyncObject->age > 0)
{
// Move any old sync objects to the end of the list, and then remove them all.
mSyncObjects.erase(std::remove_if(mSyncObjects.begin(), mSyncObjects.end(), [&](std::unique_ptr<AgingSyncObject>& agingSyncObject) { return agingSyncObject == nullptr; }),
mSyncObjects.end());
+
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "AgeSyncObjects: count after erase: %d\n", mSyncObjects.size());
}
} // namespace Dali::Graphics::GLES
#define DALI_GRAPHICS_GLES_SYNC_POOL_H
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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/integration-api/gl-abstraction.h>
#include <dali/public-api/common/vector-wrapper.h>
-namespace Dali::Graphics
+namespace Dali
+{
+namespace Internal::Adaptor
+{
+class EglSyncObject;
+}
+
+namespace Graphics
{
class EglGraphicsController;
struct AgingSyncObject
{
- AgingSyncObject(Graphics::EglGraphicsController& controller, const Context* writeContext);
+ AgingSyncObject(Graphics::EglGraphicsController& controller, const Context* writeContext, bool egl = false);
~AgingSyncObject();
EglGraphicsController& controller;
const Context* writeContext;
- GLsync glSyncObject{0};
- uint8_t age{2};
- bool syncing{false};
+ union
+ {
+ GLsync glSyncObject;
+ Internal::Adaptor::EglSyncObject* eglSyncObject;
+ };
+ uint8_t age{2};
+ bool syncing{false};
+ bool egl{false};
+
+ void Wait();
+ bool ClientWait();
};
using AgingSyncPtrRef = std::unique_ptr<AgingSyncObject>&;
class SyncPool
{
public:
+ enum class SyncContext
+ {
+ EGL, ///< Use EGL sync when syncing between multiple contexts
+ GL ///< Use GL sync when syncing in the same context
+ };
+
explicit SyncPool(Graphics::EglGraphicsController& graphicsController)
: mController(graphicsController)
{
* @param writeContext
* @return An owned ptr to a sync object
*/
- AgingSyncObject* AllocateSyncObject(const Context* writeContext);
+ AgingSyncObject* AllocateSyncObject(const Context* writeContext, SyncContext syncContext);
/**
- * Wait on a sync object in any context
+ * Wait on a sync object in any context in the GPU
* @param syncPoolObject The object to wait on.
*/
void Wait(AgingSyncObject* syncPoolObject);
/**
+ * Wait on a sync object in any context in the CPU
+ * @param syncPoolObject The object to wait on.
+ * @return true if the sync object was signaled, false if it timed out
+ */
+ bool ClientWait(AgingSyncObject* syncPoolObject);
+
+ /**
* Delete the sync object if it's not needed.
- *
+ * @param syncPoolObject The object to delete.
*/
- void FreeSyncObject(AgingSyncObject* agingSyncObject);
+ void FreeSyncObject(AgingSyncObject* syncPoolObject);
/**
* Age outstanding sync objects. Call at the end of each frame.
};
} // namespace GLES
-} // namespace Dali::Graphics
+} // namespace Graphics
+} // namespace Dali
#endif //DALI_GRAPHICS_GLES_SYNC_POOL_H
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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 "gles-texture-dependency-checker.h"
// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
#include <dali/internal/graphics/gles-impl/egl-graphics-controller.h>
+#if defined(DEBUG_ENABLED)
+extern Debug::Filter* gLogSyncFilter;
+#endif
+
namespace Dali::Graphics::GLES
{
void TextureDependencyChecker::Reset()
texture->SetDependencyIndex(index);
}
}
- textureDependency.writeContext = const_cast<GLES::Context*>(writeContext);
- textureDependency.framebuffer = const_cast<GLES::Framebuffer*>(framebuffer);
- textureDependency.agingSyncObject = mController.GetSyncPool().AllocateSyncObject(writeContext);
+ textureDependency.writeContext = const_cast<GLES::Context*>(writeContext);
+ textureDependency.framebuffer = const_cast<GLES::Framebuffer*>(framebuffer);
+
+ // We have to check on different EGL contexts: The shared resource context is used to write to fbos,
+ // but they are usually drawn onto separate scene context.
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "TextureDependencyChecker::AddTextures() Allocating sync object\n");
+ textureDependency.agingSyncObject = mController.GetSyncPool().AllocateSyncObject(writeContext, SyncPool::SyncContext::EGL);
}
-void TextureDependencyChecker::CheckNeedsSync(const GLES::Context* readContext, const GLES::Texture* texture)
+void TextureDependencyChecker::CheckNeedsSync(const GLES::Context* readContext, const GLES::Texture* texture, bool cpu)
{
uint32_t dependencyIndex = texture->GetDependencyIndex();
if(dependencyIndex < mTextureDependencies.size())
// Needs syncing!
textureDependency.syncing = true;
- // Wait on the sync object in GPU. This will ensure that the writeContext completes its tasks prior
- // to the sync point.
- mController.GetSyncPool().Wait(textureDependency.agingSyncObject);
+ if(cpu)
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "TextureDependencyChecker::CheckNeedsSync Insert CPU WAIT");
+ mController.GetSyncPool().ClientWait(textureDependency.agingSyncObject);
+ }
+ else
+ {
+ // Wait on the sync object in GPU. This will ensure that the writeContext completes its tasks prior
+ // to the sync point.
+ // However, this may instead timeout, and we can't tell the difference (at least, for glFenceSync)
+ DALI_LOG_INFO(gLogSyncFilter, Debug::Verbose, "TextureDependencyChecker::CheckNeedsSync Insert GPU WAIT");
+ mController.GetSyncPool().Wait(textureDependency.agingSyncObject);
+ }
}
}
}
#define DALI_GLES_TEXTURE_DEPENDENCY_CHECKER_H
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
/**
* Check if the given texture needs syncing before being read. This
- * will perform a glWaitSync() (GPU side semaphore) if the texture
- * needs syncing.
+ * will perform either a glWaitSync() (GPU side semaphore), or a
+ * glClientWaitSync(CPU fence) if the texture needs syncing.
* @param[in] readContext The context that the texture is being read (drawn with)
* @param[in] texture The texture being read
+ * @param[in] cpuSync True if glClientWaitSync should be used instead of glWaitSync
*/
- void CheckNeedsSync(const Context* readContext, const Texture* texture);
+ void CheckNeedsSync(const Context* readContext, const Texture* texture, bool cpuSync = false);
+
+ /**
+ * Get the number of (offscreen) textures for dependency checking
+ */
+ size_t GetTextureCount() const
+ {
+ return mTextureDependencies.size();
+ }
private:
struct TextureDependency
#define DALI_INTERNAL_ADAPTOR_EGL_SYNC_IMPLEMENTATION_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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.
bool IsSynced() override;
+ /**
+ * Set up a GPU wait (returns immediately on CPU) for this sync. Can work across
+ * EGL contexts.
+ */
+ void Wait() override;
+
+ /**
+ * Wait on the CPU until the GPU executes this sync. Warning: could be a long time!
+ * Can work across EGL contexts.
+ */
+ void ClientWait() override;
+
private:
#ifdef _ARCH_ARM_
EGLSyncKHR mEglSync;
#else
- int mPollCounter; // Implementations without fence sync use a 3 frame counter
+ EGLSync mEglSync;
+ int mPollCounter; // Implementations without fence sync use a 3 frame counter
#endif
EglImplementation& mEglImplementation;
};
return false;
}
+ uint32_t GetShaderLanguageVersion() override
+ {
+ return static_cast<uint32_t>(GetShadingLanguageVersion());
+ }
+
std::string GetShaderVersionPrefix() override
{
if(mShaderVersionPrefix == "")
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
--- /dev/null
+/*
+ * Copyright (c) 2024 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/graphics/gles/egl-sync-implementation.h>
+
+// EXTERNAL INCLUDES
+
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/graphics/gles/egl-debug.h>
+#include <dali/internal/graphics/gles/egl-implementation.h>
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogSyncFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_FENCE_SYNC");
+#endif
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+EglSyncObject::EglSyncObject(EglImplementation& eglImpl)
+: mPollCounter(3),
+ mEglImplementation(eglImpl)
+{
+}
+
+EglSyncObject::~EglSyncObject()
+{
+}
+
+bool EglSyncObject::IsSynced()
+{
+ return true;
+}
+
+void EglSyncObject::Wait()
+{
+}
+
+void EglSyncObject::ClientWait()
+{
+}
+
+EglSyncImplementation::EglSyncImplementation()
+: mEglImplementation(NULL),
+ mSyncInitialized(false),
+ mSyncInitializeFailed(false)
+{
+}
+
+EglSyncImplementation::~EglSyncImplementation()
+{
+}
+
+void EglSyncImplementation::Initialize(EglImplementation* eglImpl)
+{
+ mEglImplementation = eglImpl;
+}
+
+Integration::GraphicsSyncAbstraction::SyncObject* EglSyncImplementation::CreateSyncObject()
+{
+ DALI_ASSERT_ALWAYS(mEglImplementation && "Sync Implementation not initialized");
+ return new EglSyncObject(*mEglImplementation);
+}
+
+void EglSyncImplementation::DestroySyncObject(Integration::GraphicsSyncAbstraction::SyncObject* syncObject)
+{
+ DALI_ASSERT_ALWAYS(mEglImplementation && "Sync Implementation not initialized");
+ delete static_cast<EglSyncObject*>(syncObject);
+}
+
+void EglSyncImplementation::InitializeEglSync()
+{
+}
+
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 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/integration-api/debug.h>
// INTERNAL INCLUDES
+#include <dali/internal/graphics/gles/egl-debug.h>
#include <dali/internal/graphics/gles/egl-implementation.h>
#ifdef _ARCH_ARM_
static PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR = NULL;
static PFNEGLCLIENTWAITSYNCKHRPROC eglClientWaitSyncKHR = NULL;
static PFNEGLDESTROYSYNCKHRPROC eglDestroySyncKHR = NULL;
+static PFNEGLWAITSYNCKHRPROC eglWaitSyncKHR = NULL;
#endif
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogSyncFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_FENCE_SYNC");
+#endif
+
namespace Dali
{
namespace Internal
{
#ifdef _ARCH_ARM_
-EglSyncObject::EglSyncObject(EglImplementation& eglSyncImpl)
+EglSyncObject::EglSyncObject(EglImplementation& eglImpl)
: mEglSync(NULL),
- mEglImplementation(eglSyncImpl)
+ mEglImplementation(eglImpl)
{
EGLDisplay display = mEglImplementation.GetDisplay();
mEglSync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, NULL);
DALI_LOG_ERROR("eglCreateSyncKHR failed %#0.4x\n", eglGetError());
mEglSync = NULL;
}
+ else
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglCreateSyncKHR Success: %p\n", mEglSync);
+ }
}
EglSyncObject::~EglSyncObject()
{
DALI_LOG_ERROR("eglDestroySyncKHR failed %#0.4x\n", error);
}
+ else
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglDestroySyncKHR Success: %p\n", mEglSync);
+ }
}
}
if(mEglSync != NULL)
{
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglClientWaitSync no timeout\n");
EGLint result = eglClientWaitSyncKHR(mEglImplementation.GetDisplay(), mEglSync, 0, 0ull);
EGLint error = eglGetError();
if(EGL_SUCCESS != error)
}
}
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglClientWaitSync(%p, 0, 0) %s\n", mEglSync, synced ? "Synced" : "NOT SYNCED");
return synced;
}
+void EglSyncObject::ClientWait()
+{
+ bool synced = false;
+ if(mEglSync != nullptr)
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglClientWaitSync FOREVER\n");
+ auto result = eglClientWaitSyncKHR(mEglImplementation.GetDisplay(), mEglSync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR);
+ if(result == EGL_FALSE)
+ {
+ Egl::PrintError(eglGetError());
+ }
+ else if(result == EGL_CONDITION_SATISFIED_KHR)
+ {
+ synced = true;
+ }
+ }
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglClientWaitSync(%p, 0, FOREVER) %s\n", mEglSync, synced ? "Synced" : "NOT SYNCED");
+}
+
+void EglSyncObject::Wait()
+{
+ if(mEglSync != nullptr)
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglWaitSync\n");
+ auto result = eglWaitSyncKHR(mEglImplementation.GetDisplay(), mEglSync, 0);
+ if(EGL_FALSE == result)
+ {
+ Egl::PrintError(eglGetError());
+ }
+ else
+ {
+ DALI_LOG_INFO(gLogSyncFilter, Debug::General, "eglWaitSync() %p synced!\n", mEglSync);
+ }
+ }
+}
+
EglSyncImplementation::EglSyncImplementation()
: mEglImplementation(NULL),
mSyncInitialized(false),
{
eglCreateSyncKHR = reinterpret_cast<PFNEGLCREATESYNCKHRPROC>(eglGetProcAddress("eglCreateSyncKHR"));
eglClientWaitSyncKHR = reinterpret_cast<PFNEGLCLIENTWAITSYNCKHRPROC>(eglGetProcAddress("eglClientWaitSyncKHR"));
+ eglWaitSyncKHR = reinterpret_cast<PFNEGLWAITSYNCKHRPROC>(eglGetProcAddress("eglWaitSyncKHR"));
eglDestroySyncKHR = reinterpret_cast<PFNEGLDESTROYSYNCKHRPROC>(eglGetProcAddress("eglDestroySyncKHR"));
}
- if(eglCreateSyncKHR && eglClientWaitSyncKHR && eglDestroySyncKHR)
+ if(eglCreateSyncKHR && eglClientWaitSyncKHR && eglWaitSyncKHR && eglDestroySyncKHR)
{
mSyncInitialized = true;
}
bool EglSyncObject::IsSynced()
{
- if(mPollCounter <= 0)
- {
- return true;
- }
- --mPollCounter;
- return false;
+ return true;
+}
+
+void EglSyncObject::Wait()
+{
+}
+
+void EglSyncObject::ClientWait()
+{
}
EglSyncImplementation::EglSyncImplementation()
--- /dev/null
+/*
+ * Copyright (c) 2024 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/internal/graphics/gles/egl-sync-implementation.h>
+
+// EXTERNAL INCLUDES
+
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/graphics/gles/egl-debug.h>
+#include <dali/internal/graphics/gles/egl-implementation.h>
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogSyncFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_FENCE_SYNC");
+#endif
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Adaptor
+{
+EglSyncObject::EglSyncObject(EglImplementation& eglImpl)
+: mPollCounter(3),
+ mEglImplementation(eglImpl)
+{
+}
+
+EglSyncObject::~EglSyncObject()
+{
+}
+
+bool EglSyncObject::IsSynced()
+{
+ return true;
+}
+
+void EglSyncObject::Wait()
+{
+}
+
+void EglSyncObject::ClientWait()
+{
+}
+
+EglSyncImplementation::EglSyncImplementation()
+: mEglImplementation(NULL),
+ mSyncInitialized(false),
+ mSyncInitializeFailed(false)
+{
+}
+
+EglSyncImplementation::~EglSyncImplementation()
+{
+}
+
+void EglSyncImplementation::Initialize(EglImplementation* eglImpl)
+{
+ mEglImplementation = eglImpl;
+}
+
+Integration::GraphicsSyncAbstraction::SyncObject* EglSyncImplementation::CreateSyncObject()
+{
+ DALI_ASSERT_ALWAYS(mEglImplementation && "Sync Implementation not initialized");
+ return new EglSyncObject(*mEglImplementation);
+}
+
+void EglSyncImplementation::DestroySyncObject(Integration::GraphicsSyncAbstraction::SyncObject* syncObject)
+{
+ DALI_ASSERT_ALWAYS(mEglImplementation && "Sync Implementation not initialized");
+ delete static_cast<EglSyncObject*>(syncObject);
+}
+
+void EglSyncImplementation::InitializeEglSync()
+{
+}
+
+} // namespace Adaptor
+} // namespace Internal
+} // namespace Dali
{
const unsigned int ADAPTOR_MAJOR_VERSION = 2;
const unsigned int ADAPTOR_MINOR_VERSION = 3;
-const unsigned int ADAPTOR_MICRO_VERSION = 10;
+const unsigned int ADAPTOR_MICRO_VERSION = 11;
const char* const ADAPTOR_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-adaptor
Summary: The DALi Tizen Adaptor
-Version: 2.3.10
+Version: 2.3.11
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT