X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fadaptor%2Fcommon%2Fcombined-update-render-controller.cpp;h=5c11f022ccf340450b2df2a8cb66c0ab8ffd4516;hb=6206c977d8ec33445d0fa948886b214bee02214d;hp=31cf0fd49e7ea3f5c59e0a6a802a2a0e5c4bbcc5;hpb=4ea6bcbe439574eca6e79a074236411a530ca34b;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/dali/internal/adaptor/common/combined-update-render-controller.cpp b/dali/internal/adaptor/common/combined-update-render-controller.cpp index 31cf0fd..5c11f02 100644 --- a/dali/internal/adaptor/common/combined-update-render-controller.cpp +++ b/dali/internal/adaptor/common/combined-update-render-controller.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2019 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. @@ -28,6 +28,10 @@ #include #include #include +#include +#include +#include +#include namespace Dali { @@ -40,6 +44,7 @@ namespace Adaptor namespace { + const unsigned int CREATED_THREAD_COUNT = 1u; const int CONTINUOUS = -1; @@ -85,7 +90,6 @@ const unsigned int MAXIMUM_UPDATE_REQUESTS = 2; CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalServices& adaptorInterfaces, const EnvironmentOptions& environmentOptions ) : mFpsTracker( environmentOptions ), mUpdateStatusLogger( environmentOptions ), - mRenderHelper( adaptorInterfaces ), mEventThreadSemaphore(), mUpdateRenderThreadWaitCondition(), mAdaptorInterfaces( adaptorInterfaces ), @@ -94,6 +98,7 @@ CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalS mEnvironmentOptions( environmentOptions ), mNotificationTrigger( adaptorInterfaces.GetProcessCoreEventsTrigger() ), mSleepTrigger( NULL ), + mPreRenderCallback( NULL ), mUpdateRenderThread( NULL ), mDefaultFrameDelta( 0.0f ), mDefaultFrameDurationMilliseconds( 0u ), @@ -117,7 +122,7 @@ CombinedUpdateRenderController::CombinedUpdateRenderController( AdaptorInternalS SetRenderRefreshRate( environmentOptions.GetRenderRefreshRate() ); // Set the thread-synchronization interface on the render-surface - RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); + Dali::RenderSurfaceInterface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); if( currentSurface ) { currentSurface->SetThreadSynchronization( *this ); @@ -135,6 +140,7 @@ CombinedUpdateRenderController::~CombinedUpdateRenderController() Stop(); + delete mPreRenderCallback; delete mSleepTrigger; } @@ -150,7 +156,7 @@ void CombinedUpdateRenderController::Initialize() int error = pthread_create( mUpdateRenderThread, NULL, InternalUpdateRenderThreadEntryFunc, this ); DALI_ASSERT_ALWAYS( !error && "Return code from pthread_create() when creating UpdateRenderThread" ); - // The Update/Render thread will now run and initialise EGL etc. and will then wait for Start to be called + // The Update/Render thread will now run and initialise the graphics interface etc. and will then wait for Start to be called // When this function returns, the application initialisation on the event thread should occur } @@ -166,13 +172,19 @@ void CombinedUpdateRenderController::Start() sem_wait( &mEventThreadSemaphore ); } - mRenderHelper.Start(); + Integration::RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); + if( currentSurface ) + { + currentSurface->StartRender(); + } mRunning = TRUE; LOG_EVENT( "Startup Complete, starting Update/Render Thread" ); RunUpdateRenderThread( CONTINUOUS, false /* No animation progression */ ); + + DALI_LOG_RELEASE_INFO( "CombinedUpdateRenderController::Start\n" ); } void CombinedUpdateRenderController::Pause() @@ -184,6 +196,8 @@ void CombinedUpdateRenderController::Pause() PauseUpdateRenderThread(); AddPerformanceMarker( PerformanceInterface::PAUSED ); + + DALI_LOG_RELEASE_INFO( "CombinedUpdateRenderController::Pause\n" ); } void CombinedUpdateRenderController::Resume() @@ -201,6 +215,8 @@ void CombinedUpdateRenderController::Resume() mRunning = TRUE; mForceClear = TRUE; } + + DALI_LOG_RELEASE_INFO( "CombinedUpdateRenderController::Resume\n" ); } void CombinedUpdateRenderController::Stop() @@ -208,7 +224,11 @@ void CombinedUpdateRenderController::Stop() LOG_EVENT_TRACE; // Stop Rendering and the Update/Render Thread - mRenderHelper.Stop(); + Integration::RenderSurface* currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); + if( currentSurface ) + { + currentSurface->StopRender(); + } StopUpdateRenderThread(); @@ -224,6 +244,8 @@ void CombinedUpdateRenderController::Stop() } mRunning = FALSE; + + DALI_LOG_RELEASE_INFO( "CombinedUpdateRenderController::Stop\n" ); } void CombinedUpdateRenderController::RequestUpdate() @@ -264,7 +286,7 @@ void CombinedUpdateRenderController::RequestUpdateOnce() } } -void CombinedUpdateRenderController::ReplaceSurface( RenderSurface* newSurface ) +void CombinedUpdateRenderController::ReplaceSurface( Dali::RenderSurfaceInterface* newSurface ) { LOG_EVENT_TRACE; @@ -291,20 +313,14 @@ void CombinedUpdateRenderController::ResizeSurface() { LOG_EVENT_TRACE; - LOG_EVENT( "Starting to resize the surface, event-thread blocked" ); + LOG_EVENT( "Resize the surface" ); - // Start resizing the surface. { ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); mPostRendering = FALSE; // Clear the post-rendering flag as Update/Render thread will resize the surface now mSurfaceResized = TRUE; mUpdateRenderThreadWaitCondition.Notify( lock ); } - - // Wait until the surface has been resized - sem_wait( &mEventThreadSemaphore ); - - LOG_EVENT( "Surface resized, event-thread continuing" ); } void CombinedUpdateRenderController::SetRenderRefreshRate( unsigned int numberOfFramesPerRender ) @@ -318,6 +334,19 @@ void CombinedUpdateRenderController::SetRenderRefreshRate( unsigned int numberOf LOG_EVENT( "mDefaultFrameDelta(%.6f), mDefaultFrameDurationMilliseconds(%lld), mDefaultFrameDurationNanoseconds(%lld)", mDefaultFrameDelta, mDefaultFrameDurationMilliseconds, mDefaultFrameDurationNanoseconds ); } +void CombinedUpdateRenderController::SetPreRenderCallback( CallbackBase* callback ) +{ + LOG_EVENT_TRACE; + LOG_EVENT( "Set PreRender Callback" ); + + ConditionalWait::ScopedLock updateLock( mUpdateRenderThreadWaitCondition ); + if( mPreRenderCallback ) + { + delete mPreRenderCallback; + } + mPreRenderCallback = callback; +} + /////////////////////////////////////////////////////////////////////////////////////////////////// // EVENT THREAD /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -379,14 +408,61 @@ void CombinedUpdateRenderController::ProcessSleepRequest() void CombinedUpdateRenderController::UpdateRenderThread() { + SetThreadName("RenderThread\0"); + // Install a function for logging mEnvironmentOptions.InstallLogFunction(); + // Install a function for tracing + mEnvironmentOptions.InstallTraceFunction(); + LOG_UPDATE_RENDER( "THREAD CREATED" ); - mRenderHelper.InitializeEgl(); + // Initialize EGL & OpenGL + Dali::DisplayConnection& displayConnection = mAdaptorInterfaces.GetDisplayConnectionInterface(); + displayConnection.Initialize(); + + RenderSurfaceInterface* currentSurface = nullptr; + + GraphicsInterface& graphics = mAdaptorInterfaces.GetGraphicsInterface(); + EglGraphics* eglGraphics = static_cast(&graphics); + + // This will only be created once + EglInterface* eglInterface = &eglGraphics->GetEglInterface(); + + Internal::Adaptor::EglImplementation& eglImpl = static_cast( *eglInterface ); - // tell core it has a context + // Try to use OpenGL es 3.0 + // ChooseConfig returns false here when the device only support gles 2.0. + // Because eglChooseConfig with gles 3.0 setting fails when the device only support gles 2.0 and Our default setting is gles 3.0. + if( !eglImpl.ChooseConfig( true, COLOR_DEPTH_32 ) ) + { + // Retry to use OpenGL es 2.0 + eglGraphics->SetGlesVersion( 20 ); + eglImpl.ChooseConfig( true, COLOR_DEPTH_32 ); + } + + // Check whether surfaceless context is supported + bool isSurfacelessContextSupported = eglImpl.IsSurfacelessContextSupported(); + eglGraphics->SetIsSurfacelessContextSupported( isSurfacelessContextSupported ); + + if ( isSurfacelessContextSupported ) + { + // Create a surfaceless OpenGL context for shared resources + eglImpl.CreateContext(); + eglImpl.MakeContextCurrent( EGL_NO_SURFACE, eglImpl.GetContext() ); + } + else + { + currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); + if( currentSurface ) + { + currentSurface->InitializeGraphics(); + currentSurface->MakeContextCurrent(); + } + } + + // Tell core it has a context mCore.ContextCreated(); NotifyThreadInitialised(); @@ -431,30 +507,25 @@ void CombinedUpdateRenderController::UpdateRenderThread() // REPLACE SURFACE ////////////////////////////// - RenderSurface* newSurface = ShouldSurfaceBeReplaced(); + Integration::RenderSurface* newSurface = ShouldSurfaceBeReplaced(); if( DALI_UNLIKELY( newSurface ) ) { LOG_UPDATE_RENDER_TRACE_FMT( "Replacing Surface" ); - mRenderHelper.ReplaceSurface( newSurface ); + + // This is designed for replacing pixmap surfaces, but should work for window as well + // we need to delete the surface and renderable (pixmap / window) + // 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->ReplaceGraphicsSurface(); SurfaceReplaced(); } - ////////////////////////////// - // RESIZE SURFACE - ////////////////////////////// - const bool isRenderingToFbo = renderToFboEnabled && ( ( 0u == frameCount ) || ( 0u != frameCount % renderToFboInterval ) ); ++frameCount; - // The resizing will be applied in the next loop - bool surfaceResized = ShouldSurfaceBeResized(); - if( DALI_UNLIKELY( surfaceResized ) ) - { - LOG_UPDATE_RENDER_TRACE_FMT( "Resizing Surface" ); - mRenderHelper.ResizeSurface(); - SurfaceResized(); - } - ////////////////////////////// // UPDATE ////////////////////////////// @@ -493,6 +564,17 @@ void CombinedUpdateRenderController::UpdateRenderThread() LOG_UPDATE_RENDER( "Notification Triggered" ); } + // Check resize + bool shouldSurfaceBeResized = ShouldSurfaceBeResized(); + if( DALI_UNLIKELY( shouldSurfaceBeResized ) ) + { + if( updateStatus.SurfaceRectChanged() ) + { + LOG_UPDATE_RENDER_TRACE_FMT( "Resizing Surface" ); + SurfaceResized(); + } + } + // Optional logging of update/render status mUpdateStatusLogger.Log( keepUpdatingStatus ); @@ -500,8 +582,23 @@ void CombinedUpdateRenderController::UpdateRenderThread() // RENDER ////////////////////////////// - mRenderHelper.ConsumeEvents(); - mRenderHelper.PreRender(); + mAdaptorInterfaces.GetDisplayConnectionInterface().ConsumeEvents(); + + if( mPreRenderCallback != NULL ) + { + bool keepCallback = CallbackBase::ExecuteReturn(*mPreRenderCallback); + if( ! keepCallback ) + { + delete mPreRenderCallback; + mPreRenderCallback = NULL; + } + } + + if( eglImpl.IsSurfacelessContextSupported() ) + { + // Make the shared surfaceless context as current before rendering + eglImpl.MakeContextCurrent( EGL_NO_SURFACE, eglImpl.GetContext() ); + } Integration::RenderStatus renderStatus; @@ -511,14 +608,8 @@ void CombinedUpdateRenderController::UpdateRenderThread() mForceClear = false; - if( renderStatus.NeedsPostRender() ) - { - mRenderHelper.PostRender( isRenderingToFbo ); - } - // Trigger event thread to request Update/Render thread to sleep if update not required - if( ( Integration::KeepUpdating::NOT_REQUESTED == keepUpdatingStatus ) && - ! renderStatus.NeedsUpdate() ) + if( ( Integration::KeepUpdating::NOT_REQUESTED == keepUpdatingStatus ) && !renderStatus.NeedsUpdate() ) { mSleepTrigger->Trigger(); updateRequired = false; @@ -575,7 +666,12 @@ void CombinedUpdateRenderController::UpdateRenderThread() // Inform core of context destruction & shutdown EGL mCore.ContextDestroyed(); - mRenderHelper.ShutdownEgl(); + currentSurface = mAdaptorInterfaces.GetRenderSurfaceInterface(); + if( currentSurface ) + { + currentSurface->DestroySurface(); + currentSurface = nullptr; + } LOG_UPDATE_RENDER( "THREAD DESTROYED" ); @@ -634,11 +730,11 @@ bool CombinedUpdateRenderController::UpdateRenderReady( bool& useElapsedTime, bo return ! mDestroyUpdateRenderThread; } -RenderSurface* CombinedUpdateRenderController::ShouldSurfaceBeReplaced() +Integration::RenderSurface* CombinedUpdateRenderController::ShouldSurfaceBeReplaced() { ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); - RenderSurface* newSurface = mNewSurface; + Integration::RenderSurface* newSurface = mNewSurface; mNewSurface = NULL; return newSurface; @@ -653,17 +749,13 @@ void CombinedUpdateRenderController::SurfaceReplaced() bool CombinedUpdateRenderController::ShouldSurfaceBeResized() { ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); - - bool surfaceSized = mSurfaceResized; - mSurfaceResized = FALSE; - - return surfaceSized; + return mSurfaceResized; } void CombinedUpdateRenderController::SurfaceResized() { - // Just increment the semaphore - sem_post( &mEventThreadSemaphore ); + ConditionalWait::ScopedLock lock( mUpdateRenderThreadWaitCondition ); + mSurfaceResized = FALSE; } ///////////////////////////////////////////////////////////////////////////////////////////////////