/*
- * 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.
#include "dali/public-api/common/dali-common.h"
// INTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/thread-settings.h>
#include <dali/integration-api/adaptor-framework/trigger-event-factory.h>
#include <dali/internal/adaptor/common/adaptor-internal-services.h>
#include <dali/internal/adaptor/common/combined-update-render-controller-debug.h>
#include <dali/internal/graphics/gles/egl-implementation.h>
#include <dali/internal/system/common/environment-options.h>
#include <dali/internal/system/common/time-service.h>
+#include <dali/internal/thread/common/thread-settings-impl.h>
#include <dali/internal/window-system/common/window-impl.h>
namespace Dali
mEventThreadSemaphore(0),
mSurfaceSemaphore(0),
mUpdateRenderThreadWaitCondition(),
+ mPostRenderWaitCondition(),
mAdaptorInterfaces(adaptorInterfaces),
mPerformanceInterface(adaptorInterfaces.GetPerformanceInterface()),
mCore(adaptorInterfaces.GetCore()),
mDefaultHalfFrameNanoseconds(0u),
mUpdateRequestCount(0u),
mRunning(FALSE),
+ mThreadId(0),
mThreadMode(threadMode),
mUpdateRenderRunCount(0),
mDestroyUpdateRenderThread(FALSE),
// Start replacing the surface.
{
ConditionalWait::ScopedLock lock(mUpdateRenderThreadWaitCondition);
- mPostRendering = FALSE; // Clear the post-rendering flag as Update/Render thread will replace the surface now
- mNewSurface = newSurface;
+ mNewSurface = newSurface;
mUpdateRenderThreadWaitCondition.Notify(lock);
}
// Start replacing the surface.
{
ConditionalWait::ScopedLock lock(mUpdateRenderThreadWaitCondition);
- mPostRendering = FALSE; // Clear the post-rendering flag as Update/Render thread will delete the surface now
mDeletedSurface = surface;
mUpdateRenderThreadWaitCondition.Notify(lock);
}
{
ConditionalWait::ScopedLock lock(mUpdateRenderThreadWaitCondition);
- mPostRendering = FALSE; // Clear the post-rendering flag as Update/Render thread will resize the surface now
// Surface is resized and the surface resized count is increased.
mSurfaceResized++;
mUpdateRenderThreadWaitCondition.Notify(lock);
}
}
+int32_t CombinedUpdateRenderController::GetThreadId() const
+{
+ return mThreadId;
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////////
// EVENT THREAD
///////////////////////////////////////////////////////////////////////////////////////////////////
void CombinedUpdateRenderController::UpdateRenderThread()
{
- SetThreadName("RenderThread\0");
+ ThreadSettings::SetThreadName("RenderThread\0");
+ mThreadId = ThreadSettings::GetThreadId();
// Install a function for logging
mEnvironmentOptions.InstallLogFunction();
{
LOG_UPDATE_RENDER_TRACE;
+ // For thread safe
+ bool uploadOnly = mUploadWithoutRendering;
+ unsigned int surfaceResized = mSurfaceResized;
+
// Performance statistics are logged upon a VSYNC tick so use this point for a VSync marker
AddPerformanceMarker(PerformanceInterface::VSYNC);
// Then create a new pixmap/window and new surface
// If the new surface has a different display connection, then the context will be lost
mAdaptorInterfaces.GetDisplayConnectionInterface().Initialize();
- newSurface->InitializeGraphics();
- newSurface->MakeContextCurrent();
+ graphics.ActivateSurfaceContext(newSurface);
// TODO: ReplaceGraphicsSurface doesn't work, InitializeGraphics()
// already creates new surface window, the surface and the context.
// We probably don't need ReplaceGraphicsSurface at all.
Integration::UpdateStatus updateStatus;
AddPerformanceMarker(PerformanceInterface::UPDATE_START);
+ TRACE_UPDATE_RENDER_BEGIN("DALI_UPDATE");
mCore.Update(frameDelta,
currentTime,
nextFrameTime,
updateStatus,
renderToFboEnabled,
- isRenderingToFbo);
+ isRenderingToFbo,
+ uploadOnly);
+ TRACE_UPDATE_RENDER_END("DALI_UPDATE");
AddPerformanceMarker(PerformanceInterface::UPDATE_END);
unsigned int keepUpdatingStatus = updateStatus.KeepUpdating();
Integration::RenderStatus renderStatus;
AddPerformanceMarker(PerformanceInterface::RENDER_START);
+ TRACE_UPDATE_RENDER_BEGIN("DALI_RENDER");
// Upload shared resources
- mCore.PreRender(renderStatus, mForceClear, mUploadWithoutRendering);
+ mCore.PreRender(renderStatus, mForceClear);
- if(!mUploadWithoutRendering)
+ if(!uploadOnly || surfaceResized)
{
// Go through each window
WindowContainer windows;
mAdaptorInterfaces.GetWindowContainerInterface(windows);
- bool sceneSurfaceResized;
-
for(auto&& window : windows)
{
Dali::Integration::Scene scene = window->GetScene();
{
Integration::RenderStatus windowRenderStatus;
- // Get Surface Resized flag
- sceneSurfaceResized = scene.IsSurfaceRectChanged();
-
- windowSurface->InitializeGraphics();
+ const bool sceneSurfaceResized = scene.IsSurfaceRectChanged();
// clear previous frame damaged render items rects, buffer history is tracked on surface level
mDamagedRects.clear();
// Switch to the context of the surface, merge damaged areas for previous frames
windowSurface->PreRender(sceneSurfaceResized, mDamagedRects, clippingRect); // Switch GL context
- if(clippingRect.IsEmpty())
- {
- mDamagedRects.clear();
- }
-
// Render the surface
mCore.RenderScene(windowRenderStatus, scene, false, clippingRect);
- if(windowRenderStatus.NeedsPostRender())
- {
- windowSurface->PostRender(false, false, sceneSurfaceResized, mDamagedRects); // Swap Buffer with damage
- }
+ // Buffer swapping now happens when the surface render target is presented.
// If surface is resized, the surface resized count is decreased.
if(DALI_UNLIKELY(sceneSurfaceResized))
}
}
- mCore.PostRender(mUploadWithoutRendering);
+ if(!uploadOnly)
+ {
+ graphics.PostRender();
+ }
+
+ mCore.PostRender();
//////////////////////////////
// DELETE SURFACE
SurfaceDeleted();
}
+ TRACE_UPDATE_RENDER_END("DALI_RENDER");
AddPerformanceMarker(PerformanceInterface::RENDER_END);
mForceClear = false;
void CombinedUpdateRenderController::PostRenderComplete()
{
- ConditionalWait::ScopedLock lock(mUpdateRenderThreadWaitCondition);
+ ConditionalWait::ScopedLock lock(mPostRenderWaitCondition);
mPostRendering = FALSE;
- mUpdateRenderThreadWaitCondition.Notify(lock);
+ mPostRenderWaitCondition.Notify(lock);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void CombinedUpdateRenderController::PostRenderStarted()
{
- ConditionalWait::ScopedLock lock(mUpdateRenderThreadWaitCondition);
+ ConditionalWait::ScopedLock lock(mPostRenderWaitCondition);
mPostRendering = TRUE;
}
void CombinedUpdateRenderController::PostRenderWaitForCompletion()
{
- ConditionalWait::ScopedLock lock(mUpdateRenderThreadWaitCondition);
+ ConditionalWait::ScopedLock lock(mPostRenderWaitCondition);
while(mPostRendering &&
!mNewSurface && // We should NOT wait if we're replacing the surface
!mDeletedSurface && // We should NOT wait if we're deleting the surface
!mDestroyUpdateRenderThread)
{
- mUpdateRenderThreadWaitCondition.Wait(lock);
+ mPostRenderWaitCondition.Wait(lock);
}
}